Full Code of svoboda18/magiskboot for AI

master 2ae1419085bb cached
287 files
2.5 MB
662.0k tokens
1880 symbols
1 requests
Download .txt
Showing preview only (2,645K chars total). Download the full file or copy to clipboard to get everything.
Repository: svoboda18/magiskboot
Branch: master
Commit: 2ae1419085bb
Files: 287
Total size: 2.5 MB

Directory structure:
gitextract_0zejjrj1/

├── .gitignore
├── .gitmodules
├── Makefile
├── README.md
├── bin.rc
├── bootimg.cpp
├── bootimg.hpp
├── compress.cpp
├── compress.hpp
├── cpio.cpp
├── cpio.hpp
├── dll.rc
├── dtb.cpp
├── dtb.hpp
├── external/
│   ├── bzip2/
│   │   ├── blocksort.c
│   │   ├── bzlib.c
│   │   ├── bzlib.h
│   │   ├── bzlib_private.h
│   │   ├── compress.c
│   │   ├── crctable.c
│   │   ├── decompress.c
│   │   ├── huffman.c
│   │   └── randtable.c
│   ├── libfdt/
│   │   ├── fdt.c
│   │   ├── fdt.h
│   │   ├── fdt_addresses.c
│   │   ├── fdt_empty_tree.c
│   │   ├── fdt_overlay.c
│   │   ├── fdt_ro.c
│   │   ├── fdt_rw.c
│   │   ├── fdt_strerror.c
│   │   ├── fdt_sw.c
│   │   ├── fdt_wip.c
│   │   ├── libfdt.h
│   │   ├── libfdt_env.h
│   │   └── libfdt_internal.h
│   ├── lz4/
│   │   ├── lz4.c
│   │   ├── lz4.h
│   │   ├── lz4frame.c
│   │   ├── lz4frame.h
│   │   ├── lz4frame_static.h
│   │   ├── lz4hc.c
│   │   ├── lz4hc.h
│   │   ├── xxhash.c
│   │   └── xxhash.h
│   ├── mincrypt/
│   │   ├── dsa_sig.c
│   │   ├── include/
│   │   │   └── mincrypt/
│   │   │       ├── dsa_sig.h
│   │   │       ├── hash-internal.h
│   │   │       ├── p256.h
│   │   │       ├── p256_ecdsa.h
│   │   │       ├── rsa.h
│   │   │       ├── sha.h
│   │   │       └── sha256.h
│   │   ├── p256.c
│   │   ├── p256_ec.c
│   │   ├── p256_ecdsa.c
│   │   ├── rsa.c
│   │   ├── sha.c
│   │   └── sha256.c
│   ├── xz/
│   │   ├── common/
│   │   │   ├── mythread.h
│   │   │   ├── sysdefs.h
│   │   │   ├── tuklib_common.h
│   │   │   ├── tuklib_config.h
│   │   │   ├── tuklib_cpucores.c
│   │   │   ├── tuklib_cpucores.h
│   │   │   ├── tuklib_exit.c
│   │   │   ├── tuklib_exit.h
│   │   │   ├── tuklib_gettext.h
│   │   │   ├── tuklib_integer.h
│   │   │   ├── tuklib_mbstr.h
│   │   │   ├── tuklib_mbstr_fw.c
│   │   │   ├── tuklib_mbstr_width.c
│   │   │   ├── tuklib_open_stdxxx.c
│   │   │   ├── tuklib_open_stdxxx.h
│   │   │   ├── tuklib_physmem.c
│   │   │   ├── tuklib_physmem.h
│   │   │   ├── tuklib_progname.c
│   │   │   └── tuklib_progname.h
│   │   └── liblzma/
│   │       ├── api/
│   │       │   ├── lzma/
│   │       │   │   ├── base.h
│   │       │   │   ├── bcj.h
│   │       │   │   ├── block.h
│   │       │   │   ├── check.h
│   │       │   │   ├── container.h
│   │       │   │   ├── delta.h
│   │       │   │   ├── filter.h
│   │       │   │   ├── hardware.h
│   │       │   │   ├── index.h
│   │       │   │   ├── index_hash.h
│   │       │   │   ├── lzma12.h
│   │       │   │   ├── stream_flags.h
│   │       │   │   ├── version.h
│   │       │   │   └── vli.h
│   │       │   └── lzma.h
│   │       ├── check/
│   │       │   ├── check.c
│   │       │   ├── check.h
│   │       │   ├── crc32_fast.c
│   │       │   ├── crc32_small.c
│   │       │   ├── crc32_table.c
│   │       │   ├── crc32_table_be.h
│   │       │   ├── crc32_table_le.h
│   │       │   ├── crc32_tablegen.c
│   │       │   ├── crc32_x86.S
│   │       │   ├── crc64_fast.c
│   │       │   ├── crc64_small.c
│   │       │   ├── crc64_table.c
│   │       │   ├── crc64_table_be.h
│   │       │   ├── crc64_table_le.h
│   │       │   ├── crc64_tablegen.c
│   │       │   ├── crc64_x86.S
│   │       │   ├── crc_macros.h
│   │       │   └── sha256.c
│   │       ├── common/
│   │       │   ├── Makefile.inc
│   │       │   ├── alone_decoder.c
│   │       │   ├── alone_decoder.h
│   │       │   ├── alone_encoder.c
│   │       │   ├── auto_decoder.c
│   │       │   ├── block_buffer_decoder.c
│   │       │   ├── block_buffer_encoder.c
│   │       │   ├── block_buffer_encoder.h
│   │       │   ├── block_decoder.c
│   │       │   ├── block_decoder.h
│   │       │   ├── block_encoder.c
│   │       │   ├── block_encoder.h
│   │       │   ├── block_header_decoder.c
│   │       │   ├── block_header_encoder.c
│   │       │   ├── block_util.c
│   │       │   ├── common.c
│   │       │   ├── common.h
│   │       │   ├── easy_buffer_encoder.c
│   │       │   ├── easy_decoder_memusage.c
│   │       │   ├── easy_encoder.c
│   │       │   ├── easy_encoder_memusage.c
│   │       │   ├── easy_preset.c
│   │       │   ├── easy_preset.h
│   │       │   ├── filter_buffer_decoder.c
│   │       │   ├── filter_buffer_encoder.c
│   │       │   ├── filter_common.c
│   │       │   ├── filter_common.h
│   │       │   ├── filter_decoder.c
│   │       │   ├── filter_decoder.h
│   │       │   ├── filter_encoder.c
│   │       │   ├── filter_encoder.h
│   │       │   ├── filter_flags_decoder.c
│   │       │   ├── filter_flags_encoder.c
│   │       │   ├── hardware_cputhreads.c
│   │       │   ├── hardware_physmem.c
│   │       │   ├── index.c
│   │       │   ├── index.h
│   │       │   ├── index_decoder.c
│   │       │   ├── index_encoder.c
│   │       │   ├── index_encoder.h
│   │       │   ├── index_hash.c
│   │       │   ├── memcmplen.h
│   │       │   ├── outqueue.c
│   │       │   ├── outqueue.h
│   │       │   ├── stream_buffer_decoder.c
│   │       │   ├── stream_buffer_encoder.c
│   │       │   ├── stream_decoder.c
│   │       │   ├── stream_decoder.h
│   │       │   ├── stream_encoder.c
│   │       │   ├── stream_encoder_mt.c
│   │       │   ├── stream_flags_common.c
│   │       │   ├── stream_flags_common.h
│   │       │   ├── stream_flags_decoder.c
│   │       │   ├── stream_flags_encoder.c
│   │       │   ├── vli_decoder.c
│   │       │   ├── vli_encoder.c
│   │       │   └── vli_size.c
│   │       ├── delta/
│   │       │   ├── delta_common.c
│   │       │   ├── delta_common.h
│   │       │   ├── delta_decoder.c
│   │       │   ├── delta_decoder.h
│   │       │   ├── delta_encoder.c
│   │       │   ├── delta_encoder.h
│   │       │   └── delta_private.h
│   │       ├── lz/
│   │       │   ├── lz_decoder.c
│   │       │   ├── lz_decoder.h
│   │       │   ├── lz_encoder.c
│   │       │   ├── lz_encoder.h
│   │       │   ├── lz_encoder_hash.h
│   │       │   ├── lz_encoder_hash_table.h
│   │       │   └── lz_encoder_mf.c
│   │       ├── lzma/
│   │       │   ├── fastpos.h
│   │       │   ├── fastpos_table.c
│   │       │   ├── fastpos_tablegen.c
│   │       │   ├── lzma2_decoder.c
│   │       │   ├── lzma2_decoder.h
│   │       │   ├── lzma2_encoder.c
│   │       │   ├── lzma2_encoder.h
│   │       │   ├── lzma_common.h
│   │       │   ├── lzma_decoder.c
│   │       │   ├── lzma_decoder.h
│   │       │   ├── lzma_encoder.c
│   │       │   ├── lzma_encoder.h
│   │       │   ├── lzma_encoder_optimum_fast.c
│   │       │   ├── lzma_encoder_optimum_normal.c
│   │       │   ├── lzma_encoder_presets.c
│   │       │   └── lzma_encoder_private.h
│   │       ├── rangecoder/
│   │       │   ├── price.h
│   │       │   ├── price_table.c
│   │       │   ├── range_common.h
│   │       │   ├── range_decoder.h
│   │       │   └── range_encoder.h
│   │       └── simple/
│   │           ├── arm.c
│   │           ├── armthumb.c
│   │           ├── ia64.c
│   │           ├── powerpc.c
│   │           ├── simple_coder.c
│   │           ├── simple_coder.h
│   │           ├── simple_decoder.c
│   │           ├── simple_decoder.h
│   │           ├── simple_encoder.c
│   │           ├── simple_encoder.h
│   │           ├── simple_private.h
│   │           ├── sparc.c
│   │           └── x86.c
│   ├── xz_config/
│   │   └── config.h
│   ├── zlib/
│   │   ├── adler32.c
│   │   ├── compress.c
│   │   ├── crc32.c
│   │   ├── crc32.h
│   │   ├── deflate.c
│   │   ├── deflate.h
│   │   ├── gzclose.c
│   │   ├── gzguts.h
│   │   ├── gzlib.c
│   │   ├── gzread.c
│   │   ├── gzwrite.c
│   │   ├── infback.c
│   │   ├── inffast.c
│   │   ├── inffast.h
│   │   ├── inffixed.h
│   │   ├── inflate.c
│   │   ├── inflate.h
│   │   ├── inftrees.c
│   │   ├── inftrees.h
│   │   ├── trees.c
│   │   ├── trees.h
│   │   ├── uncompr.c
│   │   ├── zconf.h
│   │   ├── zlib.h
│   │   ├── zutil.c
│   │   └── zutil.h
│   └── zopfli/
│       ├── blocksplitter.c
│       ├── blocksplitter.h
│       ├── cache.c
│       ├── cache.h
│       ├── deflate.c
│       ├── deflate.h
│       ├── gzip_container.c
│       ├── gzip_container.h
│       ├── hash.c
│       ├── hash.h
│       ├── katajainen.c
│       ├── katajainen.h
│       ├── lz77.c
│       ├── lz77.h
│       ├── squeeze.c
│       ├── squeeze.h
│       ├── symbols.h
│       ├── tree.c
│       ├── tree.h
│       ├── util.c
│       ├── util.h
│       ├── zlib_container.c
│       ├── zlib_container.h
│       ├── zopfli.h
│       ├── zopfli_bin.c
│       └── zopfli_lib.c
├── format.cpp
├── format.hpp
├── hexpatch.cpp
├── magiskbase/
│   ├── files.cpp
│   ├── files.hpp
│   ├── include/
│   │   ├── base.hpp
│   │   └── stream.hpp
│   ├── misc.cpp
│   ├── misc.hpp
│   ├── stream.cpp
│   ├── xwrap.cpp
│   └── xwrap.hpp
├── magiskboot.hpp
├── main.cpp
├── pattern.cpp
├── ramdisk.cpp
└── scripts/
    ├── mkdir.sh
    └── strip.sh

================================================
FILE CONTENTS
================================================

================================================
FILE: .gitignore
================================================
out/*
NUL

================================================
FILE: .gitmodules
================================================
[submodule "libnt"]
	path = libnt
	url = https://github.com/svoboda18/libnt


================================================
FILE: Makefile
================================================
# env controlled
DEBUG ?= 0
CROSS_COMPILE ?=
SH ?= sh

# Build configuration (static only, shared are broken)
override TOPDIR ?= $(shell cygpath -m $(shell pwd))
override STATIC ?= 1
override SVB_MINGW ?= 1
override SVB_FLAGS ?= -DSVB_WIN32 -DANDROID
override BUILD_FLAGS ?= -fno-exceptions -fdiagnostics-absolute-paths -Wno-deprecated-non-prototype -DHOST
override BUILD_EXTRAS ?= 0
override BIN_EXT ?= .exe
override LIB_EXT ?= .a

ifeq ($(STATIC),0)
$(warning WARNING: Host libraries are statically linked)
override LIB_EXT ?= .dll
endif

ifeq ($(DEBUG),1)
override BUILD_FLAGS += -ggdb -ffunction-sections -Wall -Wextra -Wpedantic -Wconversion-null -Wno-gnu-include-next
override SVB_FLAGS += -DSVB_DEBUG
else
override BUILD_FLAGS += -Oz
endif
override LDFLAGS ?= -Wl,-gc-sections

ifeq ($(SVB_MINGW),1)
override SVB_FLAGS += -DSVB_MINGW -DHAVE_LIB_NT_H -I$(TOPDIR)/libnt/include
all:: svbnt magiskboot
else
all:: print_info init_out res magiskboot
endif

override CC := $(CROSS_COMPILE)clang
override CFLAGS ?= $(BUILD_FLAGS) $(SVB_FLAGS)
override CXX := $(CROSS_COMPILE)clang++
override CXXSTD ?= c++17
override CXXLIB ?= libc++
override CXXFLAGS ?= -std=$(CXXSTD) -stdlib=$(CXXLIB) $(BUILD_FLAGS) $(SVB_FLAGS)
# LD is set for shared libs
ifeq ($(STATIC),0)
override LD := $(CROSS_COMPILE)clang $(BUILD_FLAGS)
override LDXX := $(CROSS_COMPILE)clang++ -std=$(CXXSTD) -stdlib=$(CXXLIB) $(BUILD_FLAGS) -static-libstdc++
#override LDFLAGS += -Wl,--large-address-aware
endif
override STRIP_CMD ?= $(CROSS_COMPILE)strip
override STRIPFLAGS ?= --strip-all -R .comment -R .gnu.version --strip-unneeded
override AR := $(CROSS_COMPILE)ar
override ARFLAGS := rcsD

override DEPLOY ?= $(TOPDIR)/build
override OUT ?= $(TOPDIR)/out
override SRP ?= $(OUT)
override OBJ ?= $(OUT)/obj
override LIB ?= $(OBJ)/lib
override SLIB ?= $(LIB)/shared
override LIB_OUT ?= $(LIB)
ifeq ($(STATIC),0)
override LIB_OUT ?= $(SLIB)
endif

override STRIP ?= $(SH) $(TOPDIR)/scripts/strip.sh
override MKDIR ?= $(SH) $(TOPDIR)/scripts/mkdir.sh

override BIN_RES ?= $(OBJ)/bin.res
override DLL_RES ?= $(OBJ)/dll.res

ifeq ($(SVB_MINGW),1)
override LIBS ?= -lWs2_32 $(LIB)/libnt.a -limagehlp -lpthread
endif

override NTLIB ?= libnt

override GNUMAKEFLAGS += --output-sync=line --no-print-directory
override MAKEFLAGS ?= -$(MAKEFLAGS) $(GNUMAKEFLAGS) --warn-undefined-variables

MAGISKBOOT_SRC = \
    bootimg.cpp \
    hexpatch.cpp \
    compress.cpp \
    format.cpp \
    dtb.cpp \
    ramdisk.cpp \
    pattern.cpp \
    cpio.cpp \
    main.cpp
MAGISKBOOT_OBJ ?= $(patsubst %.cpp,$(OBJ)/magiskboot/%.o,$(MAGISKBOOT_SRC))

LIBBASE_SRC = \
    magiskbase/files.cpp \
    magiskbase/misc.cpp \
    magiskbase/xwrap.cpp \
    magiskbase/stream.cpp

LIBBASE_OBJ ?= $(patsubst %.cpp,$(OBJ)/%.o,$(LIBBASE_SRC))

LIBMINCRYPT_SRC = \
    external/mincrypt/dsa_sig.c \
    external/mincrypt/p256.c \
    external/mincrypt/p256_ec.c \
    external/mincrypt/p256_ecdsa.c \
    external/mincrypt/rsa.c \
    external/mincrypt/sha.c \
    external/mincrypt/sha256.c
LIBMINCRYPT_OBJ = $(patsubst %.c,$(OBJ)/%.o,$(LIBMINCRYPT_SRC))

LIBLZMA_SRC = \
    external/lzma/common/tuklib_cpucores.c \
    external/lzma/common/tuklib_exit.c \
    external/lzma/common/tuklib_mbstr_fw.c \
    external/lzma/common/tuklib_mbstr_width.c \
    external/lzma/common/tuklib_open_stdxxx.c \
    external/lzma/common/tuklib_physmem.c \
    external/lzma/common/tuklib_progname.c \
    external/lzma/liblzma/check/check.c \
    external/lzma/liblzma/check/crc32_fast.c \
    external/lzma/liblzma/check/crc32_table.c \
    external/lzma/liblzma/check/crc64_fast.c \
    external/lzma/liblzma/check/crc64_table.c \
    external/lzma/liblzma/check/sha256.c \
    external/lzma/liblzma/common/alone_decoder.c \
    external/lzma/liblzma/common/alone_encoder.c \
    external/lzma/liblzma/common/auto_decoder.c \
    external/lzma/liblzma/common/block_buffer_decoder.c \
    external/lzma/liblzma/common/block_buffer_encoder.c \
    external/lzma/liblzma/common/block_decoder.c \
    external/lzma/liblzma/common/block_encoder.c \
    external/lzma/liblzma/common/block_header_decoder.c \
    external/lzma/liblzma/common/block_header_encoder.c \
    external/lzma/liblzma/common/block_util.c \
    external/lzma/liblzma/common/common.c \
    external/lzma/liblzma/common/easy_buffer_encoder.c \
    external/lzma/liblzma/common/easy_decoder_memusage.c \
    external/lzma/liblzma/common/easy_encoder.c \
    external/lzma/liblzma/common/easy_encoder_memusage.c \
    external/lzma/liblzma/common/easy_preset.c \
    external/lzma/liblzma/common/filter_buffer_decoder.c \
    external/lzma/liblzma/common/filter_buffer_encoder.c \
    external/lzma/liblzma/common/filter_common.c \
    external/lzma/liblzma/common/filter_decoder.c \
    external/lzma/liblzma/common/filter_encoder.c \
    external/lzma/liblzma/common/filter_flags_decoder.c \
    external/lzma/liblzma/common/filter_flags_encoder.c \
    external/lzma/liblzma/common/hardware_cputhreads.c \
    external/lzma/liblzma/common/hardware_physmem.c \
    external/lzma/liblzma/common/index.c \
    external/lzma/liblzma/common/index_decoder.c \
    external/lzma/liblzma/common/index_encoder.c \
    external/lzma/liblzma/common/index_hash.c \
    external/lzma/liblzma/common/outqueue.c \
    external/lzma/liblzma/common/stream_buffer_decoder.c \
    external/lzma/liblzma/common/stream_buffer_encoder.c \
    external/lzma/liblzma/common/stream_decoder.c \
    external/lzma/liblzma/common/stream_encoder.c \
    external/lzma/liblzma/common/stream_encoder_mt.c \
    external/lzma/liblzma/common/stream_flags_common.c \
    external/lzma/liblzma/common/stream_flags_decoder.c \
    external/lzma/liblzma/common/stream_flags_encoder.c \
    external/lzma/liblzma/common/vli_decoder.c \
    external/lzma/liblzma/common/vli_encoder.c \
    external/lzma/liblzma/common/vli_size.c \
    external/lzma/liblzma/delta/delta_common.c \
    external/lzma/liblzma/delta/delta_decoder.c \
    external/lzma/liblzma/delta/delta_encoder.c \
    external/lzma/liblzma/lz/lz_decoder.c \
    external/lzma/liblzma/lz/lz_encoder.c \
    external/lzma/liblzma/lz/lz_encoder_mf.c \
    external/lzma/liblzma/lzma/fastpos_table.c \
    external/lzma/liblzma/lzma/lzma2_decoder.c \
    external/lzma/liblzma/lzma/lzma2_encoder.c \
    external/lzma/liblzma/lzma/lzma_decoder.c \
    external/lzma/liblzma/lzma/lzma_encoder.c \
    external/lzma/liblzma/lzma/lzma_encoder_optimum_fast.c \
    external/lzma/liblzma/lzma/lzma_encoder_optimum_normal.c \
    external/lzma/liblzma/lzma/lzma_encoder_presets.c \
    external/lzma/liblzma/rangecoder/price_table.c \
    external/lzma/liblzma/simple/arm.c \
    external/lzma/liblzma/simple/armthumb.c \
    external/lzma/liblzma/simple/ia64.c \
    external/lzma/liblzma/simple/powerpc.c \
    external/lzma/liblzma/simple/simple_coder.c \
    external/lzma/liblzma/simple/simple_decoder.c \
    external/lzma/liblzma/simple/simple_encoder.c \
    external/lzma/liblzma/simple/sparc.c \
    external/lzma/liblzma/simple/x86.c
LIBLZMA_INCLUDES = \
    -I$(TOPDIR)/external/xz_config \
    -I$(TOPDIR)/external/xz/common \
    -I$(TOPDIR)/external/xz/liblzma/api \
    -I$(TOPDIR)/external/xz/liblzma/check \
    -I$(TOPDIR)/external/xz/liblzma/common \
    -I$(TOPDIR)/external/xz/liblzma/delta \
    -I$(TOPDIR)/external/xz/liblzma/lz \
    -I$(TOPDIR)/external/xz/liblzma/lzma \
    -I$(TOPDIR)/external/xz/liblzma/rangecoder \
    -I$(TOPDIR)/external/xz/liblzma/simple \
    -I$(TOPDIR)/external/xz/liblzma
LIBLZMA_OBJ = $(patsubst %.c,$(OBJ)/%.o,$(LIBLZMA_SRC))

LIBBZ2_SRC = \
    external/bzip2/blocksort.c  \
    external/bzip2/huffman.c    \
    external/bzip2/crctable.c   \
    external/bzip2/randtable.c  \
    external/bzip2/compress.c   \
    external/bzip2/decompress.c \
    external/bzip2/bzlib.c
LIBBZ2_OBJ = $(patsubst %.c,$(OBJ)/%.o,$(LIBBZ2_SRC))

LIBLZ4_SRC = \
    external/lz4/lz4.c \
    external/lz4/lz4frame.c \
    external/lz4/lz4hc.c \
    external/lz4/xxhash.c
LIBLZ4_OBJ = $(patsubst %.c,$(OBJ)/%.o,$(LIBLZ4_SRC))

LIBZOPFLI_SRC = \
    external/zopfli/blocksplitter.c \
    external/zopfli/cache.c \
    external/zopfli/deflate.c \
    external/zopfli/gzip_container.c \
    external/zopfli/hash.c \
    external/zopfli/katajainen.c \
    external/zopfli/lz77.c \
    external/zopfli/squeeze.c \
    external/zopfli/tree.c \
    external/zopfli/util.c \
    external/zopfli/zlib_container.c \
    external/zopfli/zopfli_lib.c
LIBZOPFLI_OBJ = $(patsubst %.c,$(OBJ)/%.o,$(LIBZOPFLI_SRC))

LIBZ_SRC = \
    external/zlib/adler32.c \
    external/zlib/compress.c \
    external/zlib/crc32.c \
    external/zlib/deflate.c \
    external/zlib/gzclose.c \
    external/zlib/gzlib.c \
    external/zlib/gzread.c \
    external/zlib/gzwrite.c \
    external/zlib/infback.c \
    external/zlib/inflate.c \
    external/zlib/inftrees.c \
    external/zlib/inffast.c \
    external/zlib/trees.c \
    external/zlib/uncompr.c \
    external/zlib/zutil.c
LIBZ_OBJ = $(patsubst %.c,$(OBJ)/%.o,$(LIBZ_SRC))

LIBFDT_SRC = \
    external/libfdt/fdt.c \
    external/libfdt/fdt_addresses.c \
    external/libfdt/fdt_empty_tree.c \
    external/libfdt/fdt_overlay.c \
    external/libfdt/fdt_ro.c \
    external/libfdt/fdt_rw.c \
    external/libfdt/fdt_strerror.c \
    external/libfdt/fdt_sw.c \
    external/libfdt/fdt_wip.c
LIBFDT_OBJ = $(patsubst %.c,$(OBJ)/%.o,$(LIBFDT_SRC))

BUILD_SHARED ?= \
	$(SLIB)/svbmincrypt.dll \
	$(SLIB)/svbzopfli.dll \
	$(SLIB)/svbbase.dll \
	$(SLIB)/svblzma.dll \
	$(SLIB)/svblz4.dll \
	$(SLIB)/svbfdt.dll \
	$(SLIB)/svbbz2.dll \
	$(SLIB)/svbz.dll
BUILD_FILES ?= $(SRP)/magiskboot$(BIN_EXT)

BUILD_EXTRA ?=

ifeq (1,$(STATIC))
override BUILD_SHARED ?=
endif

ifeq (1,$(BUILD_EXTRAS))
override BUILD_FILES ?= $(BUILD_FILES) $(BUILD_EXTRAS)
endif

override MAKEFLAGS += -rsR

export TOPDIR DEBUG STATIC SVB_MINGW BUILD_FILES CROSS_COMPILE AR LIBS SVB_FLAGS CC CFLAGS CXX CXXSTD CXXLIB CXXFLAGS \
	LD LDXX LDFLAGS STRIP STRIP_CMD STRIPFLAGS AR ARFLAGS LIBS DEPLOY OUT OBJ LIB SRP SLIB BIN_RES DLL_RES BIN_EXT LIB_EXT LIB_OUT MKDIR \
	GNUMAKEFLAGS

.PHONY: all

print_info:
	$(info INFO: CXX STD VERSION '$(CXXSTD)')
	$(info INFO: CXX STD LIB '$(CXXLIB)')
	$(info INFO: CC '$(CC) $(CFLAGS)')
	$(info INFO: CXX '$(CXX) $(CXXFLAGS)')
	$(info INFO: LD '$(CXX) $(CXXFLAGS) $(LDFLAGS) $(BIN_RES) $(LIBS)')
	$(info INFO: AR '$(AR) $(ARFLAGS)')
	$(info INFO: STRIP '$(STRIP) $(STRIPFLAGS)')

init_out:
	@$(MKDIR) -p $(OUT)
	@$(MKDIR) -p $(OBJ)
	@$(MKDIR) -p $(LIB)
	@if [[ $(STATIC) -eq 0 ]]; then \
		$(MKDIR) -p $(SLIB); \
	fi

res: $(BIN_RES) $(DLL_RES)

svbnt: init_out print_info res
	@$(MAKE) $(MAKEFLAGS) -C $(NTLIB)

$(OBJ)/%.res: %.rc
	@echo -e "  WINDRES   `basename $@`"
	@windres --input=$< --output-format=coff --output=$@

clean:
	@echo -e "  RM\t    obj"
	@rm -rf $(OBJ)
	@echo -e "  RM\t    bin"
	@rm -rf $(OUT)

override INCLUDES ?= \
    -Iinclude \
    -I$(TOPDIR)/external \
    -I$(TOPDIR)/external/libfdt \
    -I$(TOPDIR)/external/mincrypt/include \
    -Imagiskbase/include \
    -I$(TOPDIR)/external/bzip2 \
    -I$(TOPDIR)/external/xz/liblzma/api \
    -I$(TOPDIR)/external/zlib \
    -I$(TOPDIR)/external/lz4

# libmagiskbase always static
extlib: $(LIB_OUT)/libmincrypt$(LIB_EXT) $(LIB_OUT)/libz$(LIB_EXT) $(LIB_OUT)/liblzma$(LIB_EXT) \
		$(LIB_OUT)/libbz2$(LIB_EXT) $(LIB_OUT)/liblz4$(LIB_EXT) $(LIB_OUT)/libzopfli$(LIB_EXT) $(LIB_OUT)/libfdt$(LIB_EXT)

magiskboot: extlib $(LIB)/libmagiskbase.a $(OUT)/magiskboot$(BIN_EXT)

$(OBJ)/external/zopfli/%.o: $(TOPDIR)/%.c
	@$(MKDIR) -p `dirname $@`
	@echo -e "  CC\t    `basename $@`"
	@$(CC) $(CFLAGS) -Wall -Werror -Wno-unused -Wno-unused-parameter $(INCLUDES) -c $< -o $@

$(OBJ)/external/lzma/%.o: $(TOPDIR)/external/xz/%.c
	@$(MKDIR) -p `dirname $@`
	@echo -e "  CC\t    `basename $@`"
	@$(CC) $(CFLAGS) -DHAVE_CONFIG_H -Wno-implicit-function-declaration $(INCLUDES) $(LIBLZMA_INCLUDES) -c $< -o $@

$(OBJ)/%.o: $(TOPDIR)/%.c
	@$(MKDIR) -p `dirname $@`
	@echo -e "  CC\t    `basename $@`"
	@$(CC) $(CFLAGS) $(INCLUDES) -c $< -o $@

$(OBJ)/%.o: %.cpp
	@$(MKDIR) -p `dirname $@`
	@echo -e "  CXX\t    `basename $@`"
	@$(CXX) -static $(CXXFLAGS) $(INCLUDES) -c $< -o $@

$(OBJ)/magiskboot/%.o: %.cpp
	@$(MKDIR) -p `dirname $@`
	@echo -e "  CXX\t    `basename $@`"
	@$(CXX) -static $(CXXFLAGS) $(INCLUDES) -c $< -o $@

MAGISKBOOT_LD ?= $(LIB)/libmincrypt.a $(LIB)/liblzma.a $(LIB)/libbz2.a \
		 $(LIB)/liblz4.a $(LIB)/libzopfli.a $(LIB)/libfdt.a $(LIB)/libz.a
ifeq ($(STATIC),0)
override MAGISKBOOT_LD ?= $(shell echo $(MAGISKBOOT_LD) | sed "s@\(obj/lib/\)lib\(\w\+\)\.a@\1shared/svb\2\.dll@g")
endif
$(OUT)/magiskboot$(BIN_EXT): $(MAGISKBOOT_OBJ) $(LIB)/libmagiskbase.a $(MAGISKBOOT_LD)
	@$(MKDIR) -p `dirname $@`
	@echo -e "  LD\t    `basename $@`"
	@$(CXX) $(CXXFLAGS) $^ -o $@ -static $(LDFLAGS) $(BIN_RES) $(LIBS)
	@$(STRIP) $(STRIPFLAGS) $@

$(LIB)/libmagiskbase.a: $(LIBBASE_OBJ)
	@$(MKDIR) -p `dirname $@`
	@echo -e "  AR\t    `basename $@`"
	@$(AR) $(ARFLAGS) $@ $^

$(SLIB)/lib%.dll: $(LIB)/lib%.a
	@echo -e "  LD\t    `basename $@`"
	@$(LD) -shared -o $(SLIB)/svb$*.dll \
	    -Wl,--export-all-symbols \
	    -Wl,--enable-auto-import \
	    -Wl,--whole-archive $^ \
	    -Wl,--no-whole-archive -lpthread $(DLL_RES)

$(LIB)/libmincrypt.a: $(LIBMINCRYPT_OBJ)
	@$(MKDIR) -p `dirname $@`
	@echo -e "  AR\t    `basename $@`"
	@$(AR) $(ARFLAGS) $@ $^

$(LIB)/liblzma.a: $(LIBLZMA_OBJ)
	@$(MKDIR) -p `dirname $@`
	@echo -e "  AR\t    `basename $@`"
	@$(AR) $(ARFLAGS) $@ $^

$(LIB)/libbz2.a: $(LIBBZ2_OBJ)
	@$(MKDIR) -p `dirname $@`
	@echo -e "  AR\t    `basename $@`"
	@$(AR) $(ARFLAGS) $@ $^

$(LIB)/liblz4.a: $(LIBLZ4_OBJ)
	@$(MKDIR) -p `dirname $@`
	@echo -e "  AR\t    `basename $@`"
	@$(AR) $(ARFLAGS) $@ $^

$(LIB)/libzopfli.a: $(LIBZOPFLI_OBJ)
	@$(MKDIR) -p `dirname $@`
	@echo -e "  AR\t    `basename $@`"
	@$(AR) $(ARFLAGS) $@ $^

$(LIB)/libz.a: $(LIBZ_OBJ)
	@$(MKDIR) -p `dirname $@`
	@echo -e "  AR\t    `basename $@`"
	@$(AR) $(ARFLAGS) $@ $^

$(LIB)/libfdt.a: $(LIBFDT_OBJ)
	@$(MKDIR) -p `dirname $@`
	@echo -e "  AR\t    `basename $@`"
	@$(AR) $(ARFLAGS) $@ $^

================================================
FILE: README.md
================================================
# MagiskBoot - Boot Image Modification Tool
The most complete tool for unpacking and repacking Android boot images.

**Note**: This is a minimal (dirty) copy of topjohnwu's [MagiskBoot](https://github.com/topjohnwu/Magisk/tree/master/native/src/boot).

## Documentation
- [MagiskBoot Documentation](https://topjohnwu.github.io/Magisk/tools.html#magiskboot)

## Build
- Using MSYS2 `clang64` environment with `mingw-w64-clang-x86_64-toolchain` packages group, LLVM version 14 and up, run `mingw32-make` command. (`magiskboot.exe` will appear in the `out` folder).
- if built a non-static variant, all DLLs in `out/obj/lib/shared` must be present in your PATH for successful execution. 

## What's changed:
- `cpio` action `extract` with no paramaters to `ramdisk` folder in current directory.
   * it creates `cpio` file to allow mode/uid/gid changes in Windows (with `sync` or `pack`)
- new `cpio` action `sync` that synchronize incpio entries with `ramdisk` directory (as new cpio). Any changes will be captured and dumped to `incpio`.
- new `cpio` action `pack` as follows: `cpio pack [-c <config>] <infolder> <outcpio>`
   * if `<config>` is undefined `cpio` is looked-up instead.

## For Windows
- There's some UBs/SFs that needs to be addressed (test and report).
- Tested and working operations are limited.

================================================
FILE: bin.rc
================================================
#include <windows.h>

VS_VERSION_INFO VERSIONINFO
FILEVERSION     1,0,0,0
PRODUCTVERSION  1,0,0,0
FILEFLAGSMASK      VS_FFI_FILEFLAGSMASK
#ifdef SVB_DEBUG
  FILEFLAGS        VS_FF_DEBUG | VS_FF_PRERELEASE
#else
  FILEFLAGS        0
#endif
FILEOS             VOS_NT_WINDOWS32
FILETYPE           VFT_APP
FILESUBTYPE        VFT2_UNKNOWN
BEGIN
  BLOCK "StringFileInfo"
  BEGIN
    BLOCK "040904E4"
    BEGIN
      VALUE "FileDescription", "magiskboot binary"
      VALUE "FileVersion", "1.0.0.0"
      VALUE "ProductVersion", "1.0.0.0"
    END
  END
  BLOCK "VarFileInfo"
  BEGIN
    VALUE "Translation", 0x409, 1252
  END
END

================================================
FILE: bootimg.cpp
================================================
#include <functional>
#include <memory>

#include <libfdt.h>
#include <mincrypt/sha.h>
#include <mincrypt/sha256.h>
#include <base.hpp>

#include "bootimg.hpp"
#include "magiskboot.hpp"
#include "compress.hpp"

#ifdef SVB_WIN32
#define off64_t off_t
#define lseek64 lseek
#define ftruncate64 ftruncate
#endif

using namespace std;

uint32_t dyn_img_hdr::j32 = 0;
uint64_t dyn_img_hdr::j64 = 0;

#define PADDING 15

static void decompress(format_t type, int fd, const void *in, size_t size) {
    auto ptr = get_decoder(type, make_unique<fd_stream>(fd));
    ptr->write(in, size, true);
}

static off_t compress(format_t type, int fd, const void *in, size_t size) {
    auto prev = lseek(fd, 0, SEEK_CUR);
    {
        auto strm = get_encoder(type, make_unique<fd_stream>(fd));
        strm->write(in, size, true);
    }
    auto now = lseek(fd, 0, SEEK_CUR);
    return now - prev;
}

static void dump(const void *buf, size_t size, const char *filename) {
    if (size == 0)
        return;
    int fd = creat(filename, 0644);
    xwrite(fd, buf, size);
    close(fd);
}

static size_t restore(int fd, const char *filename) {
    int ifd = xopen(filename, O_RDONLY);
    size_t size = lseek(ifd, 0, SEEK_END);
    lseek(ifd, 0, SEEK_SET);
    xsendfile(fd, ifd, nullptr, size);
    close(ifd);
    return size;
}

void dyn_img_hdr::print() {
    uint32_t ver = header_version();
    fprintf(stderr, "%-*s [%u]\n", PADDING, "HEADER_VER", ver);
    if (!is_vendor)
        fprintf(stderr, "%-*s [%u]\n", PADDING, "KERNEL_SZ", kernel_size());
    fprintf(stderr, "%-*s [%u]\n", PADDING, "RAMDISK_SZ", ramdisk_size());
    if (ver < 3)
        fprintf(stderr, "%-*s [%u]\n", PADDING, "SECOND_SZ", second_size());
    if (ver == 0)
        fprintf(stderr, "%-*s [%u]\n", PADDING, "EXTRA_SZ", extra_size());
    if (ver == 1 || ver == 2)
        fprintf(stderr, "%-*s [%u]\n", PADDING, "RECOV_DTBO_SZ", recovery_dtbo_size());
    if (ver == 2 || is_vendor)
        fprintf(stderr, "%-*s [%u]\n", PADDING, "DTB_SZ", dtb_size());

    if (uint32_t os_ver = os_version()) {
        int a,b,c,y,m = 0;
        int version = os_ver >> 11;
        int patch_level = os_ver & 0x7ff;

        a = (version >> 14) & 0x7f;
        b = (version >> 7) & 0x7f;
        c = version & 0x7f;
        fprintf(stderr, "%-*s [%d.%d.%d]\n", PADDING, "OS_VERSION", a, b, c);

        y = (patch_level >> 4) + 2000;
        m = patch_level & 0xf;
        fprintf(stderr, "%-*s [%d-%02d]\n", PADDING, "OS_PATCH_LEVEL", y, m);
    }

    fprintf(stderr, "%-*s [%u]\n", PADDING, "PAGESIZE", page_size());
    if (char *n = name()) {
        fprintf(stderr, "%-*s [%s]\n", PADDING, "NAME", n);
    }
    fprintf(stderr, "%-*s [%.*s%.*s]\n", PADDING, "CMDLINE",
            BOOT_ARGS_SIZE, cmdline(), BOOT_EXTRA_ARGS_SIZE, extra_cmdline());
    if (char *checksum = id()) {
        fprintf(stderr, "%-*s [", PADDING, "CHECKSUM");
        for (int i = 0; i < SHA256_DIGEST_SIZE; ++i)
            fprintf(stderr, "%02hhx", checksum[i]);
        fprintf(stderr, "]\n");
    }
}

void dyn_img_hdr::dump_hdr_file() {
    FILE *fp = xfopen(HEADER_FILE, "w");
    if (name())
        fprintf(fp, "name=%s\n", name());
    fprintf(fp, "cmdline=%.*s%.*s\n", BOOT_ARGS_SIZE, cmdline(), BOOT_EXTRA_ARGS_SIZE, extra_cmdline());
    uint32_t ver = os_version();
    if (ver) {
        int a, b, c, y, m;
        int version, patch_level;
        version = ver >> 11;
        patch_level = ver & 0x7ff;

        a = (version >> 14) & 0x7f;
        b = (version >> 7) & 0x7f;
        c = version & 0x7f;
        fprintf(fp, "os_version=%d.%d.%d\n", a, b, c);

        y = (patch_level >> 4) + 2000;
        m = patch_level & 0xf;
        fprintf(fp, "os_patch_level=%d-%02d\n", y, m);
    }
    fclose(fp);
}

void dyn_img_hdr::load_hdr_file() {
    parse_prop_file(HEADER_FILE, [=](string_view key, string_view value) -> bool {
        if (key == "name" && name()) {
            memset(name(), 0, 16);
            memcpy(name(), value.data(), value.length() > 15 ? 15 : value.length());
        } else if (key == "cmdline") {
            memset(cmdline(), 0, BOOT_ARGS_SIZE);
            memset(extra_cmdline(), 0, BOOT_EXTRA_ARGS_SIZE);
            if (value.length() > BOOT_ARGS_SIZE) {
                memcpy(cmdline(), value.data(), BOOT_ARGS_SIZE);
                auto len = std::min(value.length() - BOOT_ARGS_SIZE, (size_t) BOOT_EXTRA_ARGS_SIZE);
                memcpy(extra_cmdline(), &value[BOOT_ARGS_SIZE], len);
            } else {
                memcpy(cmdline(), value.data(), value.length());
            }
        } else if (key == "os_version") {
            int patch_level = os_version() & 0x7ff;
            int a, b, c;
            sscanf(value.data(), "%d.%d.%d", &a, &b, &c);
            os_version() = (((a << 14) | (b << 7) | c) << 11) | patch_level;
        } else if (key == "os_patch_level") {
            int os_ver = os_version() >> 11;
            int y, m;
            sscanf(value.data(), "%d-%d", &y, &m);
            y -= 2000;
            os_version() = (os_ver << 11) | (y << 4) | m;
        }
        return true;
    });
}

boot_img::boot_img(const char *image) : map(image) {
    fprintf(stderr, "Parsing image: [%s]\n", image);
    for (const uint8_t *addr = map.buf; addr < map.buf + map.sz; ++addr) {
        format_t fmt = check_fmt(addr, map.sz);
        switch (fmt) {
        case CHROMEOS:
            // chromeos require external signing
            flags[CHROMEOS_FLAG] = true;
            addr += 65535;
            break;
        case DHTB:
            flags[DHTB_FLAG] = true;
            flags[SEANDROID_FLAG] = true;
            fprintf(stderr, "DHTB_HDR\n");
            addr += sizeof(dhtb_hdr) - 1;
            break;
        case BLOB_FMT:
            flags[BLOB_FLAG] = true;
            fprintf(stderr, "TEGRA_BLOB\n");
            addr += sizeof(blob_hdr) - 1;
            break;
        case AOSP:
        case AOSP_VENDOR:
            parse_image(addr, fmt);
            return;
        default:
            break;
        }
    }
    exit(1);
}

boot_img::~boot_img() {
    delete hdr;
}

static int find_dtb_offset(const uint8_t *buf, unsigned sz) {
    const uint8_t * const end = buf + sz;

    for (auto curr = buf; curr < end; curr += sizeof(fdt_header)) {
        curr = static_cast<uint8_t*>(memmem(curr, end - curr, DTB_MAGIC, sizeof(fdt32_t)));
        if (curr == nullptr)
            return -1;

        auto fdt_hdr = reinterpret_cast<const fdt_header *>(curr);

        // Check that fdt_header.totalsize does not overflow kernel image size
        uint32_t totalsize = fdt32_to_cpu(fdt_hdr->totalsize);
        if (totalsize > end - curr)
            continue;

        // Check that fdt_header.off_dt_struct does not overflow kernel image size
        uint32_t off_dt_struct = fdt32_to_cpu(fdt_hdr->off_dt_struct);
        if (off_dt_struct > end - curr)
            continue;

        // Check that fdt_node_header.tag of first node is FDT_BEGIN_NODE
        auto fdt_node_hdr = reinterpret_cast<const fdt_node_header *>(curr + off_dt_struct);
        if (fdt32_to_cpu(fdt_node_hdr->tag) != FDT_BEGIN_NODE)
            continue;

        return curr - buf;
    }
    return -1;
}

static format_t check_fmt_lg(const uint8_t *buf, unsigned sz) {
    format_t fmt = check_fmt(buf, sz);
    if (fmt == LZ4_LEGACY) {
        // We need to check if it is LZ4_LG
        uint32_t off = 4;
        uint32_t block_sz;
        while (off + sizeof(block_sz) <= sz) {
            memcpy(&block_sz, buf + off, sizeof(block_sz));
            off += sizeof(block_sz);
            if (off + block_sz > sz)
                return LZ4_LG;
            off += block_sz;
        }
    }
    return fmt;
}

#define CMD_MATCH(s) BUFFER_MATCH(h->cmdline, s)

dyn_img_hdr *boot_img::create_hdr(const uint8_t *addr, format_t type) {
    if (type == AOSP_VENDOR) {
        fprintf(stderr, "VENDOR_BOOT_HDR\n");
        auto h = reinterpret_cast<const boot_img_hdr_vnd_v3*>(addr);
        hdr_addr = addr;
        switch (h->header_version) {
        case 4:
            return new dyn_img_vnd_v4(addr);
        default:
            return new dyn_img_vnd_v3(addr);
        }
    }

    auto h = reinterpret_cast<const boot_img_hdr_v0*>(addr);

    if (h->page_size >= 0x02000000) {
        fprintf(stderr, "PXA_BOOT_HDR\n");
        hdr_addr = addr;
        return new dyn_img_pxa(addr);
    }

    auto make_hdr = [](const uint8_t *ptr) -> dyn_img_hdr * {
        auto h = reinterpret_cast<const boot_img_hdr_v0*>(ptr);
        switch (h->header_version) {
        case 1:
            return new dyn_img_v1(ptr);
        case 2:
            return new dyn_img_v2(ptr);
        case 3:
            return new dyn_img_v3(ptr);
        case 4:
            return new dyn_img_v4(ptr);
        default:
            return new dyn_img_v0(ptr);
        }
    };

    // For NOOKHD and ACCLAIM, the entire boot image is shifted by a fixed offset.
    // For AMONET, only the header is internally shifted by a fixed offset.

    if (BUFFER_CONTAIN(addr, AMONET_MICROLOADER_SZ, AMONET_MICROLOADER_MAGIC) &&
        BUFFER_MATCH(addr + AMONET_MICROLOADER_SZ, BOOT_MAGIC)) {
        flags[AMONET_FLAG] = true;
        fprintf(stderr, "AMONET_MICROLOADER\n");

        // The real header is shifted, copy to temporary buffer
        h = reinterpret_cast<const boot_img_hdr_v0*>(addr + AMONET_MICROLOADER_SZ);
        auto real_hdr_sz = h->page_size - AMONET_MICROLOADER_SZ;
        auto buf = make_unique<uint8_t[]>(h->page_size);
        memcpy(buf.get(), h, real_hdr_sz);

        hdr_addr = addr;
        return make_hdr(buf.get());
    }

    if (CMD_MATCH(NOOKHD_RL_MAGIC) ||
        CMD_MATCH(NOOKHD_GL_MAGIC) ||
        CMD_MATCH(NOOKHD_GR_MAGIC) ||
        CMD_MATCH(NOOKHD_EB_MAGIC) ||
        CMD_MATCH(NOOKHD_ER_MAGIC)) {
        flags[NOOKHD_FLAG] = true;
        fprintf(stderr, "NOOKHD_LOADER\n");
        addr += NOOKHD_PRE_HEADER_SZ;
    } else if (BUFFER_MATCH(h->name, ACCLAIM_MAGIC)) {
        flags[ACCLAIM_FLAG] = true;
        fprintf(stderr, "ACCLAIM_LOADER\n");
        addr += ACCLAIM_PRE_HEADER_SZ;
    }

    // addr could be adjusted
    hdr_addr = addr;
    return make_hdr(addr);
}

#define get_block(name)                 \
name = hdr_addr + off;                  \
off += hdr->name##_size();              \
off = align_to(off, hdr->page_size());

#define get_ignore(name)                                            \
if (hdr->name##_size()) {                                           \
    auto blk_sz = align_to(hdr->name##_size(), hdr->page_size());   \
    ignore_size += blk_sz;                                          \
    off += blk_sz;                                                  \
}

void boot_img::parse_image(const uint8_t *addr, format_t type) {
    hdr = create_hdr(addr, type);

    if (char *id = hdr->id()) {
        for (int i = SHA_DIGEST_SIZE + 4; i < SHA256_DIGEST_SIZE; ++i) {
            if (id[i]) {
                flags[SHA256_FLAG] = true;
                break;
            }
        }
    }

    hdr->print();

    size_t off = hdr->hdr_space();
    get_block(kernel);
    get_block(ramdisk);
    get_block(second);
    get_block(extra);
    get_block(recovery_dtbo);
    get_block(dtb);

    ignore = hdr_addr + off;
    get_ignore(signature)
    get_ignore(vendor_ramdisk_table)
    get_ignore(bootconfig)

    if (auto size = hdr->kernel_size()) {
        if (int dtb_off = find_dtb_offset(kernel, size); dtb_off > 0) {
            kernel_dtb = kernel + dtb_off;
            hdr->kernel_dt_size = size - dtb_off;
            hdr->kernel_size() = dtb_off;
            fprintf(stderr, "%-*s [%u]\n", PADDING, "KERNEL_DTB_SZ", hdr->kernel_dt_size);
        }

        k_fmt = check_fmt_lg(kernel, hdr->kernel_size());
        if (k_fmt == MTK) {
            fprintf(stderr, "MTK_KERNEL_HDR\n");
            flags[MTK_KERNEL] = true;
            k_hdr = reinterpret_cast<const mtk_hdr *>(kernel);
            fprintf(stderr, "%-*s [%u]\n", PADDING, "SIZE", k_hdr->size);
            fprintf(stderr, "%-*s [%s]\n", PADDING, "NAME", k_hdr->name);
            kernel += sizeof(mtk_hdr);
            hdr->kernel_size() -= sizeof(mtk_hdr);
            k_fmt = check_fmt_lg(kernel, hdr->kernel_size());
        }
        if (k_fmt == ZIMAGE) {
            z_hdr = reinterpret_cast<const zimage_hdr *>(kernel);
            if (void *gzip_offset = memmem(kernel, hdr->kernel_size(), GZIP1_MAGIC "\x08\x00", 4)) {
                fprintf(stderr, "ZIMAGE_KERNEL\n");
                z_info.hdr_sz = (uint8_t *) gzip_offset - kernel;

                // Find end of piggy
                uint32_t zImage_size = z_hdr->end - z_hdr->start;
                uint32_t piggy_end = zImage_size;
                uint32_t offsets[16];
                memcpy(offsets, kernel + zImage_size - sizeof(offsets), sizeof(offsets));
                for (int i = 15; i >= 0; --i) {
                    if (offsets[i] > (zImage_size - 0xFF) && offsets[i] < zImage_size) {
                        piggy_end = offsets[i];
                        break;
                    }
                }

                if (piggy_end == zImage_size) {
                    fprintf(stderr, "! Could not find end of zImage piggy, keeping raw kernel\n");
                } else {
                    flags[ZIMAGE_KERNEL] = true;
                    z_info.tail = kernel + piggy_end;
                    z_info.tail_sz = hdr->kernel_size() - piggy_end;
                    kernel += z_info.hdr_sz;
                    hdr->kernel_size() = piggy_end - z_info.hdr_sz;
                    k_fmt = check_fmt_lg(kernel, hdr->kernel_size());
                }
            } else {
                fprintf(stderr, "! Could not find zImage gzip piggy, keeping raw kernel\n");
            }
        }
        fprintf(stderr, "%-*s [%s]\n", PADDING, "KERNEL_FMT", fmt2name[k_fmt]);
    }
    if (auto size = hdr->ramdisk_size()) {
        if (hdr->is_vendor && hdr->header_version() >= 4) {
            // v4 vendor boot contains multiple ramdisks
            // Do not try to mess with it for now
            r_fmt = UNKNOWN;
        } else {
            r_fmt = check_fmt_lg(ramdisk, size);
        }
        if (r_fmt == MTK) {
            fprintf(stderr, "MTK_RAMDISK_HDR\n");
            flags[MTK_RAMDISK] = true;
            r_hdr = reinterpret_cast<const mtk_hdr *>(ramdisk);
            fprintf(stderr, "%-*s [%u]\n", PADDING, "SIZE", r_hdr->size);
            fprintf(stderr, "%-*s [%s]\n", PADDING, "NAME", r_hdr->name);
            ramdisk += sizeof(mtk_hdr);
            hdr->ramdisk_size() -= sizeof(mtk_hdr);
            r_fmt = check_fmt_lg(ramdisk, hdr->ramdisk_size());
        }
        fprintf(stderr, "%-*s [%s]\n", PADDING, "RAMDISK_FMT", fmt2name[r_fmt]);
    }
    if (auto size = hdr->extra_size()) {
        e_fmt = check_fmt_lg(extra, size);
        fprintf(stderr, "%-*s [%s]\n", PADDING, "EXTRA_FMT", fmt2name[e_fmt]);
    }

    if (addr + off < map.buf + map.sz) {
        tail = addr + off;
        tail_size = map.buf + map.sz - tail;

        // Check special flags
        if (tail_size >= 16 && BUFFER_MATCH(tail, SEANDROID_MAGIC)) {
            fprintf(stderr, "SAMSUNG_SEANDROID\n");
            flags[SEANDROID_FLAG] = true;
        } else if (tail_size >= 16 && BUFFER_MATCH(tail, LG_BUMP_MAGIC)) {
            fprintf(stderr, "LG_BUMP_IMAGE\n");
            flags[LG_BUMP_FLAG] = true;
        }

        // Find AVB footer
        const void *footer = tail + tail_size - sizeof(AvbFooter);
        if (BUFFER_MATCH(footer, AVB_FOOTER_MAGIC)) {
            avb_footer = reinterpret_cast<const AvbFooter*>(footer);
            // Double check if meta header exists
            const void *meta = hdr_addr + __builtin_bswap64(avb_footer->vbmeta_offset);
            if (BUFFER_MATCH(meta, AVB_MAGIC)) {
                fprintf(stderr, "VBMETA\n");
                flags[AVB_FLAG] = true;
                vbmeta = reinterpret_cast<const AvbVBMetaImageHeader*>(meta);
            }
        }
    }
}

int split_image_dtb(const char *filename) {
    auto img = mmap_data(filename);

    if (int off = find_dtb_offset(img.buf, img.sz); off > 0) {
        format_t fmt = check_fmt_lg(img.buf, img.sz);
        if (COMPRESSED(fmt)) {
            int fd = creat(KERNEL_FILE, 0644);
            decompress(fmt, fd, img.buf, off);
            close(fd);
        } else {
            dump(img.buf, off, KERNEL_FILE);
        }
        dump(img.buf + off, img.sz - off, KER_DTB_FILE);
        return 0;
    } else {
        fprintf(stderr, "Cannot find DTB in %s\n", filename);
        return 1;
    }
}

int unpack(const char *image, bool skip_decomp, bool hdr) {
    boot_img boot(image);

    if (hdr)
        boot.hdr->dump_hdr_file();

    // Dump kernel
    if (!skip_decomp && COMPRESSED(boot.k_fmt)) {
        if (boot.hdr->kernel_size() != 0) {
            int fd = creat(KERNEL_FILE, 0644);
            decompress(boot.k_fmt, fd, boot.kernel, boot.hdr->kernel_size());
            close(fd);
        }
    } else {
        dump(boot.kernel, boot.hdr->kernel_size(), KERNEL_FILE);
    }

    // Dump kernel_dtb
    dump(boot.kernel_dtb, boot.hdr->kernel_dt_size, KER_DTB_FILE);

    // Dump ramdisk
    if (!skip_decomp && COMPRESSED(boot.r_fmt)) {
        if (boot.hdr->ramdisk_size() != 0) {
            int fd = creat(RAMDISK_FILE, 0644);
            decompress(boot.r_fmt, fd, boot.ramdisk, boot.hdr->ramdisk_size());
            close(fd);
        }
    } else {
        dump(boot.ramdisk, boot.hdr->ramdisk_size(), RAMDISK_FILE);
    }

    // Dump second
    dump(boot.second, boot.hdr->second_size(), SECOND_FILE);

    // Dump extra
    if (!skip_decomp && COMPRESSED(boot.e_fmt)) {
        if (boot.hdr->extra_size() != 0) {
            int fd = creat(EXTRA_FILE, 0644);
            decompress(boot.e_fmt, fd, boot.extra, boot.hdr->extra_size());
            close(fd);
        }
    } else {
        dump(boot.extra, boot.hdr->extra_size(), EXTRA_FILE);
    }

    // Dump recovery_dtbo
    dump(boot.recovery_dtbo, boot.hdr->recovery_dtbo_size(), RECV_DTBO_FILE);

    // Dump dtb
    dump(boot.dtb, boot.hdr->dtb_size(), DTB_FILE);

    return boot.flags[CHROMEOS_FLAG] ? 2 : 0;
}

#define file_align_with(page_size) \
write_zero(fd, align_padding(lseek(fd, 0, SEEK_CUR) - off.header, page_size))

#define file_align() file_align_with(boot.hdr->page_size())

void repack(const char *src_img, const char *out_img, bool skip_comp) {
    const boot_img boot(src_img);
    fprintf(stderr, "Repack to image: [%s]\n", out_img);

    struct {
        uint32_t header;
        uint32_t kernel;
        uint32_t ramdisk;
        uint32_t second;
        uint32_t extra;
        uint32_t dtb;
        uint32_t total;
        uint32_t vbmeta;
    } off{};

    // Create a new boot header and reset sizes
    auto hdr = boot.hdr->clone();
    hdr->kernel_size() = 0;
    hdr->ramdisk_size() = 0;
    hdr->second_size() = 0;
    hdr->dtb_size() = 0;
    hdr->kernel_dt_size = 0;

    if (access(HEADER_FILE, R_OK) == 0)
        hdr->load_hdr_file();

    /***************
     * Write blocks
     ***************/

    // Create new image
    int fd = creat(out_img, 0644);

    if (boot.flags[DHTB_FLAG]) {
        // Skip DHTB header
        write_zero(fd, sizeof(dhtb_hdr));
    } else if (boot.flags[BLOB_FLAG]) {
        xwrite(fd, boot.map.buf, sizeof(blob_hdr));
    } else if (boot.flags[NOOKHD_FLAG]) {
        xwrite(fd, boot.map.buf, NOOKHD_PRE_HEADER_SZ);
    } else if (boot.flags[ACCLAIM_FLAG]) {
        xwrite(fd, boot.map.buf, ACCLAIM_PRE_HEADER_SZ);
    }

    // Copy raw header
    off.header = lseek(fd, 0, SEEK_CUR);
    xwrite(fd, boot.hdr_addr, hdr->hdr_space());

    // kernel
    off.kernel = lseek(fd, 0, SEEK_CUR);
    if (boot.flags[MTK_KERNEL]) {
        // Copy MTK headers
        xwrite(fd, boot.k_hdr, sizeof(mtk_hdr));
    }
    if (boot.flags[ZIMAGE_KERNEL]) {
        // Copy zImage headers
        xwrite(fd, boot.z_hdr, boot.z_info.hdr_sz);
    }
    if (access(KERNEL_FILE, R_OK) == 0) {
        auto m = mmap_data(KERNEL_FILE);
        if (!skip_comp && !COMPRESSED_ANY(check_fmt(m.buf, m.sz)) && COMPRESSED(boot.k_fmt)) {
            // Always use zopfli for zImage compression
            auto fmt = (boot.flags[ZIMAGE_KERNEL] && boot.k_fmt == GZIP) ? ZOPFLI : boot.k_fmt;
            hdr->kernel_size() = compress(fmt, fd, m.buf, m.sz);
        } else {
            hdr->kernel_size() = xwrite(fd, m.buf, m.sz);
        }

        if (boot.flags[ZIMAGE_KERNEL]) {
            if (hdr->kernel_size() > boot.hdr->kernel_size()) {
                fprintf(stderr, "! Recompressed kernel is too large, using original kernel\n");
                ftruncate64(fd, lseek64(fd, - (off64_t) hdr->kernel_size(), SEEK_CUR));
                xwrite(fd, boot.kernel, boot.hdr->kernel_size());
            } else if (!skip_comp) {
                // Pad zeros to make sure the zImage file size does not change
                // Also ensure the last 4 bytes are the uncompressed vmlinux size
                uint32_t sz = m.sz;
                write_zero(fd, boot.hdr->kernel_size() - hdr->kernel_size() - sizeof(sz));
                xwrite(fd, &sz, sizeof(sz));
            }

            // zImage size shall remain the same
            hdr->kernel_size() = boot.hdr->kernel_size();
        }
    } else if (boot.hdr->kernel_size() != 0) {
        xwrite(fd, boot.kernel, boot.hdr->kernel_size());
        hdr->kernel_size() = boot.hdr->kernel_size();
    }
    if (boot.flags[ZIMAGE_KERNEL]) {
        // Copy zImage tail and adjust size accordingly
        hdr->kernel_size() += boot.z_info.hdr_sz;
        hdr->kernel_size() += xwrite(fd, boot.z_info.tail, boot.z_info.tail_sz);
    }

    // kernel dtb
    if (access(KER_DTB_FILE, R_OK) == 0)
        hdr->kernel_size() += restore(fd, KER_DTB_FILE);
    file_align();

    // ramdisk
    off.ramdisk = lseek(fd, 0, SEEK_CUR);
    if (boot.flags[MTK_RAMDISK]) {
        // Copy MTK headers
        xwrite(fd, boot.r_hdr, sizeof(mtk_hdr));
    }
    if (access(RAMDISK_FILE, R_OK) == 0) {
        auto m = mmap_data(RAMDISK_FILE);
        auto r_fmt = boot.r_fmt;
        if (!skip_comp && !hdr->is_vendor && hdr->header_version() == 4 && r_fmt != LZ4_LEGACY) {
            // A v4 boot image ramdisk will have to be merged with other vendor ramdisks,
            // and they have to use the exact same compression method. v4 GKIs are required to
            // use lz4 (legacy), so hardcode the format here.
            fprintf(stderr, "RAMDISK_FMT: [%s] -> [%s]\n", fmt2name[r_fmt], fmt2name[LZ4_LEGACY]);
            r_fmt = LZ4_LEGACY;
        }
        if (!skip_comp && !COMPRESSED_ANY(check_fmt(m.buf, m.sz)) && COMPRESSED(r_fmt)) {
            hdr->ramdisk_size() = compress(r_fmt, fd, m.buf, m.sz);
        } else {
            hdr->ramdisk_size() = xwrite(fd, m.buf, m.sz);
        }
        file_align();
    }

    // second
    off.second = lseek(fd, 0, SEEK_CUR);
    if (access(SECOND_FILE, R_OK) == 0) {
        hdr->second_size() = restore(fd, SECOND_FILE);
        file_align();
    }

    // extra
    off.extra = lseek(fd, 0, SEEK_CUR);
    if (access(EXTRA_FILE, R_OK) == 0) {
        auto m = mmap_data(EXTRA_FILE);
        if (!skip_comp && !COMPRESSED_ANY(check_fmt(m.buf, m.sz)) && COMPRESSED(boot.e_fmt)) {
            hdr->extra_size() = compress(boot.e_fmt, fd, m.buf, m.sz);
        } else {
            hdr->extra_size() = xwrite(fd, m.buf, m.sz);
        }
        file_align();
    }

    // recovery_dtbo
    if (access(RECV_DTBO_FILE, R_OK) == 0) {
        hdr->recovery_dtbo_offset() = lseek(fd, 0, SEEK_CUR);
        hdr->recovery_dtbo_size() = restore(fd, RECV_DTBO_FILE);
        file_align();
    }

    // dtb
    off.dtb = lseek(fd, 0, SEEK_CUR);
    if (access(DTB_FILE, R_OK) == 0) {
        hdr->dtb_size() = restore(fd, DTB_FILE);
        file_align();
    }

    // Directly copy ignored blobs
    if (boot.ignore_size) {
        // ignore_size should already be aligned
        xwrite(fd, boot.ignore, boot.ignore_size);
    }

    // Proprietary stuffs
    if (boot.flags[SEANDROID_FLAG]) {
        xwrite(fd, SEANDROID_MAGIC, 16);
        if (boot.flags[DHTB_FLAG]) {
            xwrite(fd, "\xFF\xFF\xFF\xFF", 4);
        }
    } else if (boot.flags[LG_BUMP_FLAG]) {
        xwrite(fd, LG_BUMP_MAGIC, 16);
    }

    off.total = lseek(fd, 0, SEEK_CUR);
    file_align();

    // vbmeta
    if (boot.flags[AVB_FLAG]) {
        // According to avbtool.py, if the input is not an Android sparse image
        // (which boot images are not), the default block size is 4096
        file_align_with(4096);
        off.vbmeta = lseek(fd, 0, SEEK_CUR);
        uint64_t vbmeta_size = __builtin_bswap64(boot.avb_footer->vbmeta_size);
        xwrite(fd, boot.vbmeta, vbmeta_size);
    }

    // Pad image to original size if not chromeos (as it requires post processing)
    if (!boot.flags[CHROMEOS_FLAG]) {
        off_t current = lseek(fd, 0, SEEK_CUR);
        if (current < boot.map.sz) {
            write_zero(fd, boot.map.sz - current);
        }
    }

    close(fd);

    /******************
     * Patch the image
     ******************/

    // Map output image as rw
    auto out = mmap_data(out_img, true);

    // MTK headers
    if (boot.flags[MTK_KERNEL]) {
        auto m_hdr = reinterpret_cast<mtk_hdr *>(out.buf + off.kernel);
        m_hdr->size = hdr->kernel_size();
        hdr->kernel_size() += sizeof(mtk_hdr);
    }
    if (boot.flags[MTK_RAMDISK]) {
        auto m_hdr = reinterpret_cast<mtk_hdr *>(out.buf + off.ramdisk);
        m_hdr->size = hdr->ramdisk_size();
        hdr->ramdisk_size() += sizeof(mtk_hdr);
    }

    // Make sure header size matches
    hdr->header_size() = hdr->hdr_size();

    // Update checksum
    if (char *id = hdr->id()) {
        HASH_CTX ctx;
        boot.flags[SHA256_FLAG] ? SHA256_init(&ctx) : SHA_init(&ctx);
        uint32_t size = hdr->kernel_size();
        HASH_update(&ctx, out.buf + off.kernel, size);
        HASH_update(&ctx, &size, sizeof(size));
        size = hdr->ramdisk_size();
        HASH_update(&ctx, out.buf + off.ramdisk, size);
        HASH_update(&ctx, &size, sizeof(size));
        size = hdr->second_size();
        HASH_update(&ctx, out.buf + off.second, size);
        HASH_update(&ctx, &size, sizeof(size));
        size = hdr->extra_size();
        if (size) {
            HASH_update(&ctx, out.buf + off.extra, size);
            HASH_update(&ctx, &size, sizeof(size));
        }
        uint32_t ver = hdr->header_version();
        if (ver == 1 || ver == 2) {
            size = hdr->recovery_dtbo_size();
            HASH_update(&ctx, out.buf + hdr->recovery_dtbo_offset(), size);
            HASH_update(&ctx, &size, sizeof(size));
        }
        if (ver == 2) {
            size = hdr->dtb_size();
            HASH_update(&ctx, out.buf + off.dtb, size);
            HASH_update(&ctx, &size, sizeof(size));
        }
        memset(id, 0, BOOT_ID_SIZE);
        memcpy(id, HASH_final(&ctx), boot.flags[SHA256_FLAG] ? SHA256_DIGEST_SIZE : SHA_DIGEST_SIZE);
    }

    // Print new header info
    hdr->print();

    // Copy main header
    if (boot.flags[AMONET_FLAG]) {
        auto real_hdr_sz = std::min(hdr->hdr_space() - AMONET_MICROLOADER_SZ, hdr->hdr_size());
        memcpy(out.buf + off.header + AMONET_MICROLOADER_SZ, hdr->raw_hdr(), real_hdr_sz);
    } else {
        memcpy(out.buf + off.header, hdr->raw_hdr(), hdr->hdr_size());
    }

    if (boot.flags[AVB_FLAG]) {
        // Copy and patch AVB structures
        auto footer = reinterpret_cast<AvbFooter*>(out.buf + out.sz - sizeof(AvbFooter));
        auto vbmeta = reinterpret_cast<AvbVBMetaImageHeader*>(out.buf + off.vbmeta);
        memcpy(footer, boot.avb_footer, sizeof(AvbFooter));
        footer->original_image_size = __builtin_bswap64(off.total);
        footer->vbmeta_offset = __builtin_bswap64(off.vbmeta);
        if (check_env("PATCHVBMETAFLAG")) {
            vbmeta->flags = __builtin_bswap32(3);
        }
    }

    if (boot.flags[DHTB_FLAG]) {
        // DHTB header
        auto d_hdr = reinterpret_cast<dhtb_hdr *>(out.buf);
        memcpy(d_hdr, DHTB_MAGIC, 8);
        d_hdr->size = off.total - sizeof(dhtb_hdr);
        SHA256_hash(out.buf + sizeof(dhtb_hdr), d_hdr->size, d_hdr->checksum);
    } else if (boot.flags[BLOB_FLAG]) {
        // Blob header
        auto b_hdr = reinterpret_cast<blob_hdr *>(out.buf);
        b_hdr->size = off.total - sizeof(blob_hdr);
    }
}


================================================
FILE: bootimg.hpp
================================================
#pragma once

#include <stdint.h>
#include <utility>
#include <bitset>
#include "format.hpp"

/******************
 * Special Headers
 *****************/

struct mtk_hdr {
    uint32_t magic;         /* MTK magic */
    uint32_t size;          /* Size of the content */
    char name[32];          /* The type of the header */

    char padding[472];      /* Padding to 512 bytes */
} __attribute__((packed));

struct dhtb_hdr {
    char magic[8];          /* DHTB magic */
    uint8_t checksum[40];   /* Payload SHA256, whole image + SEANDROIDENFORCE + 0xFFFFFFFF */
    uint32_t size;          /* Payload size, whole image + SEANDROIDENFORCE + 0xFFFFFFFF */

    char padding[460];      /* Padding to 512 bytes */
} __attribute__((packed));

struct blob_hdr {
    char secure_magic[20];  /* "-SIGNED-BY-SIGNBLOB-" */
    uint32_t datalen;       /* 0x00000000 */
    uint32_t signature;     /* 0x00000000 */
    char magic[16];         /* "MSM-RADIO-UPDATE" */
    uint32_t hdr_version;   /* 0x00010000 */
    uint32_t hdr_size;      /* Size of header */
    uint32_t part_offset;   /* Same as size */
    uint32_t num_parts;     /* Number of partitions */
    uint32_t unknown[7];    /* All 0x00000000 */
    char name[4];           /* Name of partition */
    uint32_t offset;        /* offset in blob where this partition starts */
    uint32_t size;          /* Size of data */
    uint32_t version;       /* 0x00000001 */
} __attribute__((packed));

struct zimage_hdr {
    uint32_t code[9];
    uint32_t magic;      /* zImage magic */
    uint32_t start;      /* absolute load/run zImage address */
    uint32_t end;        /* zImage end address */
    uint32_t endian;     /* endianness flag */
    // There could be more fields, but we don't care
} __attribute__((packed));

/**************
 * AVB Headers
 **************/

#define AVB_FOOTER_MAGIC_LEN 4
#define AVB_MAGIC_LEN 4
#define AVB_RELEASE_STRING_SIZE 48

// https://android.googlesource.com/platform/external/avb/+/refs/heads/android11-release/libavb/avb_footer.h
struct AvbFooter {
    uint8_t magic[AVB_FOOTER_MAGIC_LEN];
    uint32_t version_major;
    uint32_t version_minor;
    uint64_t original_image_size;
    uint64_t vbmeta_offset;
    uint64_t vbmeta_size;
    uint8_t reserved[28];
} __attribute__((packed));

// https://android.googlesource.com/platform/external/avb/+/refs/heads/android11-release/libavb/avb_vbmeta_image.h
struct AvbVBMetaImageHeader {
    uint8_t magic[AVB_MAGIC_LEN];
    uint32_t required_libavb_version_major;
    uint32_t required_libavb_version_minor;
    uint64_t authentication_data_block_size;
    uint64_t auxiliary_data_block_size;
    uint32_t algorithm_type;
    uint64_t hash_offset;
    uint64_t hash_size;
    uint64_t signature_offset;
    uint64_t signature_size;
    uint64_t public_key_offset;
    uint64_t public_key_size;
    uint64_t public_key_metadata_offset;
    uint64_t public_key_metadata_size;
    uint64_t descriptors_offset;
    uint64_t descriptors_size;
    uint64_t rollback_index;
    uint32_t flags;
    uint32_t rollback_index_location;
    uint8_t release_string[AVB_RELEASE_STRING_SIZE];
    uint8_t reserved[80];
} __attribute__((packed));

/*********************
 * Boot Image Headers
 *********************/

// https://android.googlesource.com/platform/system/tools/mkbootimg/+/refs/heads/android12-release/include/bootimg/bootimg.h

#define BOOT_MAGIC_SIZE 8
#define BOOT_NAME_SIZE 16
#define BOOT_ID_SIZE 32
#define BOOT_ARGS_SIZE 512
#define BOOT_EXTRA_ARGS_SIZE 1024
#define VENDOR_BOOT_ARGS_SIZE 2048
#define VENDOR_RAMDISK_NAME_SIZE 32
#define VENDOR_RAMDISK_TABLE_ENTRY_BOARD_ID_SIZE 16

/* When the boot image header has a version of 0 - 2, the structure of the boot
 * image is as follows:
 *
 * +-----------------+
 * | boot header     | 1 page
 * +-----------------+
 * | kernel          | n pages
 * +-----------------+
 * | ramdisk         | m pages
 * +-----------------+
 * | second stage    | o pages
 * +-----------------+
 * | extra blob      | x pages (non standard)
 * +-----------------+
 * | recovery dtbo   | p pages
 * +-----------------+
 * | dtb             | q pages
 * +-----------------+
 *
 * n = (kernel_size + page_size - 1) / page_size
 * m = (ramdisk_size + page_size - 1) / page_size
 * o = (second_size + page_size - 1) / page_size
 * p = (recovery_dtbo_size + page_size - 1) / page_size
 * q = (dtb_size + page_size - 1) / page_size
 * x = (extra_size + page_size - 1) / page_size
 */

struct boot_img_hdr_v0_common {
    char magic[BOOT_MAGIC_SIZE];

    uint32_t kernel_size;  /* size in bytes */
    uint32_t kernel_addr;  /* physical load addr */

    uint32_t ramdisk_size; /* size in bytes */
    uint32_t ramdisk_addr; /* physical load addr */

    uint32_t second_size;  /* size in bytes */
    uint32_t second_addr;  /* physical load addr */
} __attribute__((packed));

struct boot_img_hdr_v0 : public boot_img_hdr_v0_common {
    uint32_t tags_addr;    /* physical addr for kernel tags */

    // In AOSP headers, this field is used for page size.
    // For Samsung PXA headers, the use of this field is unknown;
    // however, its value is something unrealistic to be treated as page size.
    // We use this fact to determine whether this is an AOSP or PXA header.
    union {
        uint32_t unknown;
        uint32_t page_size;    /* flash page size we assume */
    };

    // In header v1, this field is used for header version
    // However, on some devices like Samsung, this field is used to store DTB
    // We treat this field differently based on its value
    union {
        uint32_t header_version;  /* the version of the header */
        uint32_t extra_size;      /* extra blob size in bytes */
    };

    // Operating system version and security patch level.
    // For version "A.B.C" and patch level "Y-M-D":
    //   (7 bits for each of A, B, C; 7 bits for (Y-2000), 4 bits for M)
    //   os_version = A[31:25] B[24:18] C[17:11] (Y-2000)[10:4] M[3:0]
    uint32_t os_version;

    char name[BOOT_NAME_SIZE];  /* asciiz product name */
    char cmdline[BOOT_ARGS_SIZE];
    char id[BOOT_ID_SIZE];      /* timestamp / checksum / sha1 / etc */

    // Supplemental command line data; kept here to maintain
    // binary compatibility with older versions of mkbootimg.
    char extra_cmdline[BOOT_EXTRA_ARGS_SIZE];
} __attribute__((packed));

struct boot_img_hdr_v1 : public boot_img_hdr_v0 {
    uint32_t recovery_dtbo_size;    /* size in bytes for recovery DTBO/ACPIO image */
    uint64_t recovery_dtbo_offset;  /* offset to recovery dtbo/acpio in boot image */
    uint32_t header_size;
} __attribute__((packed));

struct boot_img_hdr_v2 : public boot_img_hdr_v1 {
    uint32_t dtb_size;  /* size in bytes for DTB image */
    uint64_t dtb_addr;  /* physical load address for DTB image */
} __attribute__((packed));

// Special Samsung header
struct boot_img_hdr_pxa : public boot_img_hdr_v0_common {
    uint32_t extra_size;   /* extra blob size in bytes */
    uint32_t unknown;
    uint32_t tags_addr;    /* physical addr for kernel tags */
    uint32_t page_size;    /* flash page size we assume */

    char name[24];         /* asciiz product name */
    char cmdline[BOOT_ARGS_SIZE];
    char id[BOOT_ID_SIZE]; /* timestamp / checksum / sha1 / etc */

    char extra_cmdline[BOOT_EXTRA_ARGS_SIZE];
} __attribute__((packed));

/* When the boot image header has a version of 3 - 4, the structure of the boot
 * image is as follows:
 *
 * +---------------------+
 * | boot header         | 4096 bytes
 * +---------------------+
 * | kernel              | m pages
 * +---------------------+
 * | ramdisk             | n pages
 * +---------------------+
 * | boot signature      | g pages
 * +---------------------+
 *
 * m = (kernel_size + 4096 - 1) / 4096
 * n = (ramdisk_size + 4096 - 1) / 4096
 * g = (signature_size + 4096 - 1) / 4096
 *
 * Page size is fixed at 4096 bytes.
 *
 * The structure of the vendor boot image is as follows:
 *
 * +------------------------+
 * | vendor boot header     | o pages
 * +------------------------+
 * | vendor ramdisk section | p pages
 * +------------------------+
 * | dtb                    | q pages
 * +------------------------+
 * | vendor ramdisk table   | r pages
 * +------------------------+
 * | bootconfig             | s pages
 * +------------------------+
 *
 * o = (2128 + page_size - 1) / page_size
 * p = (vendor_ramdisk_size + page_size - 1) / page_size
 * q = (dtb_size + page_size - 1) / page_size
 * r = (vendor_ramdisk_table_size + page_size - 1) / page_size
 * s = (vendor_bootconfig_size + page_size - 1) / page_size
 *
 * Note that in version 4 of the vendor boot image, multiple vendor ramdisks can
 * be included in the vendor boot image. The bootloader can select a subset of
 * ramdisks to load at runtime. To help the bootloader select the ramdisks, each
 * ramdisk is tagged with a type tag and a set of hardware identifiers
 * describing the board, soc or platform that this ramdisk is intended for.
 *
 * The vendor ramdisk section is consist of multiple ramdisk images concatenated
 * one after another, and vendor_ramdisk_size is the size of the section, which
 * is the total size of all the ramdisks included in the vendor boot image.
 *
 * The vendor ramdisk table holds the size, offset, type, name and hardware
 * identifiers of each ramdisk. The type field denotes the type of its content.
 * The vendor ramdisk names are unique. The hardware identifiers are specified
 * in the board_id field in each table entry. The board_id field is consist of a
 * vector of unsigned integer words, and the encoding scheme is defined by the
 * hardware vendor.
 *
 * For the different type of ramdisks, there are:
 *    - VENDOR_RAMDISK_TYPE_NONE indicates the value is unspecified.
 *    - VENDOR_RAMDISK_TYPE_PLATFORM ramdisks contain platform specific bits, so
 *      the bootloader should always load these into memory.
 *    - VENDOR_RAMDISK_TYPE_RECOVERY ramdisks contain recovery resources, so
 *      the bootloader should load these when booting into recovery.
 *    - VENDOR_RAMDISK_TYPE_DLKM ramdisks contain dynamic loadable kernel
 *      modules.
 *
 * Version 4 of the vendor boot image also adds a bootconfig section to the end
 * of the image. This section contains Boot Configuration parameters known at
 * build time. The bootloader is responsible for placing this section directly
 * after the generic ramdisk, followed by the bootconfig trailer, before
 * entering the kernel.
 */

struct boot_img_hdr_v3 {
    uint8_t magic[BOOT_MAGIC_SIZE];

    uint32_t kernel_size;  /* size in bytes */
    uint32_t ramdisk_size; /* size in bytes */
    uint32_t os_version;
    uint32_t header_size;
    uint32_t reserved[4];

    uint32_t header_version;

    char cmdline[BOOT_ARGS_SIZE + BOOT_EXTRA_ARGS_SIZE];
} __attribute__((packed));

struct boot_img_hdr_vnd_v3 {
    // Must be VENDOR_BOOT_MAGIC.
    uint8_t magic[BOOT_MAGIC_SIZE];
    // Version of the vendor boot image header.
    uint32_t header_version;
    uint32_t page_size;     /* flash page size we assume */
    uint32_t kernel_addr;   /* physical load addr */
    uint32_t ramdisk_addr;  /* physical load addr */
    uint32_t ramdisk_size;  /* size in bytes */
    char cmdline[VENDOR_BOOT_ARGS_SIZE];
    uint32_t tags_addr;     /* physical addr for kernel tags (if required) */
    char name[BOOT_NAME_SIZE]; /* asciiz product name */
    uint32_t header_size;
    uint32_t dtb_size;      /* size in bytes for DTB image */
    uint64_t dtb_addr;      /* physical load address for DTB image */
} __attribute__((packed));

struct boot_img_hdr_v4 : public boot_img_hdr_v3 {
    uint32_t signature_size; /* size in bytes */
} __attribute__((packed));

struct boot_img_hdr_vnd_v4 : public boot_img_hdr_vnd_v3 {
    uint32_t vendor_ramdisk_table_size;       /* size in bytes for the vendor ramdisk table */
    uint32_t vendor_ramdisk_table_entry_num;  /* number of entries in the vendor ramdisk table */
    uint32_t vendor_ramdisk_table_entry_size; /* size in bytes for a vendor ramdisk table entry */
    uint32_t bootconfig_size; /* size in bytes for the bootconfig section */
} __attribute__((packed));

struct vendor_ramdisk_table_entry_v4 {
    uint32_t ramdisk_size;   /* size in bytes for the ramdisk image */
    uint32_t ramdisk_offset; /* offset to the ramdisk image in vendor ramdisk section */
    uint32_t ramdisk_type;   /* type of the ramdisk */
    uint8_t ramdisk_name[VENDOR_RAMDISK_NAME_SIZE]; /* asciiz ramdisk name */

    // Hardware identifiers describing the board, soc or platform which this
    // ramdisk is intended to be loaded on.
    uint32_t board_id[VENDOR_RAMDISK_TABLE_ENTRY_BOARD_ID_SIZE];
} __attribute__((packed));

/*******************************
 * Polymorphic Universal Header
 *******************************/

#define decl_var(name, len) \
virtual uint##len##_t &name() { j##len = 0; return j##len; }
#define decl_val(name, type) \
virtual type name() { return 0; }

struct dyn_img_hdr {

    const bool is_vendor;

    // Standard entries
    decl_var(kernel_size, 32)
    decl_var(ramdisk_size, 32)
    decl_var(second_size, 32)
    decl_val(page_size, uint32_t)
    decl_val(header_version, uint32_t)
    decl_var(extra_size, 32)
    decl_var(os_version, 32)
    decl_val(name, char *)
    decl_val(cmdline, char *)
    decl_val(id, char *)
    decl_val(extra_cmdline, char *)
    uint32_t kernel_dt_size = 0;

    // v1/v2 specific
    decl_var(recovery_dtbo_size, 32)
    decl_var(recovery_dtbo_offset, 64)
    decl_var(header_size, 32)
    decl_var(dtb_size, 32)

    // v4 specific
    decl_val(signature_size, uint32_t)
    decl_val(vendor_ramdisk_table_size, uint32_t)
    decl_val(bootconfig_size, uint32_t)

    virtual ~dyn_img_hdr() {
        free(raw);
    }

    virtual size_t hdr_size() = 0;
    virtual size_t hdr_space() { return page_size(); }
    virtual dyn_img_hdr *clone() = 0;

    const void *raw_hdr() const { return raw; }
    void print();
    void dump_hdr_file();
    void load_hdr_file();

protected:
    union {
        boot_img_hdr_v2 *v2_hdr;     /* AOSP v2 header */
        boot_img_hdr_v4 *v4_hdr;     /* AOSP v4 header */
        boot_img_hdr_vnd_v4 *v4_vnd; /* AOSP vendor v4 header */
        boot_img_hdr_pxa *hdr_pxa;   /* Samsung PXA header */
        void *raw;                   /* Raw pointer */
    };
    dyn_img_hdr(bool b) : is_vendor(b) {}

private:
    // Junk for references
    static uint32_t j32;
    static uint64_t j64;
};

#undef decl_var
#undef decl_val

#define __impl_cls(name, hdr)           \
protected: name() = default;            \
public:                                 \
name(const void *ptr) {                 \
    raw = malloc(sizeof(hdr));          \
    memcpy(raw, ptr, sizeof(hdr));      \
}                                       \
size_t hdr_size() override {            \
    return sizeof(hdr);                 \
}                                       \
dyn_img_hdr *clone() override {         \
    auto p = new name(raw);             \
    p->kernel_dt_size = kernel_dt_size; \
    return p;                           \
};

#define __impl_val(name, hdr_name) \
decltype(std::declval<dyn_img_hdr>().name()) name() override { return hdr_name->name; }

struct dyn_img_hdr_boot : public dyn_img_hdr {
protected:
    dyn_img_hdr_boot() : dyn_img_hdr(false) {}
};

#define impl_cls(ver)  __impl_cls(dyn_img_##ver, boot_img_hdr_##ver)
#define impl_val(name) __impl_val(name, v2_hdr)

struct dyn_img_common : public dyn_img_hdr_boot {
    impl_val(kernel_size)
    impl_val(ramdisk_size)
    impl_val(second_size)
};

struct dyn_img_v0 : public dyn_img_common {
    impl_cls(v0)

    impl_val(page_size)
    impl_val(extra_size)
    impl_val(os_version)
    impl_val(name)
    impl_val(cmdline)
    impl_val(id)
    impl_val(extra_cmdline)
};

struct dyn_img_v1 : public dyn_img_v0 {
    impl_cls(v1)

    impl_val(header_version)
    impl_val(recovery_dtbo_size)
    impl_val(recovery_dtbo_offset)
    impl_val(header_size)

    uint32_t &extra_size() override { return dyn_img_hdr::extra_size(); }
};

struct dyn_img_v2 : public dyn_img_v1 {
    impl_cls(v2)

    impl_val(dtb_size)
};

#undef impl_val
#define impl_val(name) __impl_val(name, hdr_pxa)

struct dyn_img_pxa : public dyn_img_common {
    impl_cls(pxa)

    impl_val(extra_size)
    impl_val(page_size)
    impl_val(name)
    impl_val(cmdline)
    impl_val(id)
    impl_val(extra_cmdline)
};

#undef impl_val
#define impl_val(name) __impl_val(name, v4_hdr)

struct dyn_img_v3 : public dyn_img_hdr_boot {
    impl_cls(v3)

    impl_val(kernel_size)
    impl_val(ramdisk_size)
    impl_val(os_version)
    impl_val(header_size)
    impl_val(header_version)
    impl_val(cmdline)

    // Make API compatible
    uint32_t page_size() override { return 4096; }
    char *extra_cmdline() override { return &v4_hdr->cmdline[BOOT_ARGS_SIZE]; }
};

struct dyn_img_v4 : public dyn_img_v3 {
    impl_cls(v4)

    impl_val(signature_size)
};

struct dyn_img_hdr_vendor : public dyn_img_hdr {
protected:
    dyn_img_hdr_vendor() : dyn_img_hdr(true) {}
};

#undef impl_val
#define impl_val(name) __impl_val(name, v4_vnd)

struct dyn_img_vnd_v3 : public dyn_img_hdr_vendor {
    impl_cls(vnd_v3)

    impl_val(header_version)
    impl_val(page_size)
    impl_val(ramdisk_size)
    impl_val(cmdline)
    impl_val(name)
    impl_val(header_size)
    impl_val(dtb_size)

    size_t hdr_space() override { return align_to(hdr_size(), page_size()); }

    // Make API compatible
    char *extra_cmdline() override { return &v4_vnd->cmdline[BOOT_ARGS_SIZE]; }
};

struct dyn_img_vnd_v4 : public dyn_img_vnd_v3 {
    impl_cls(vnd_v4)

    impl_val(vendor_ramdisk_table_size)
    impl_val(bootconfig_size)
};

#undef __impl_cls
#undef __impl_val
#undef impl_cls
#undef impl_val

/******************
 * Full Boot Image
 ******************/

enum {
    MTK_KERNEL,
    MTK_RAMDISK,
    CHROMEOS_FLAG,
    DHTB_FLAG,
    SEANDROID_FLAG,
    LG_BUMP_FLAG,
    SHA256_FLAG,
    BLOB_FLAG,
    NOOKHD_FLAG,
    ACCLAIM_FLAG,
    AMONET_FLAG,
    AVB_FLAG,
    ZIMAGE_KERNEL,
    BOOT_FLAGS_MAX
};

struct boot_img {
    // Memory map of the whole image
    mmap_data map;

    // Android image header
    dyn_img_hdr *hdr;

    // Flags to indicate the state of current boot image
    std::bitset<BOOT_FLAGS_MAX> flags;

    // The format of kernel, ramdisk and extra
    format_t k_fmt = UNKNOWN;
    format_t r_fmt = UNKNOWN;
    format_t e_fmt = UNKNOWN;

    /*************************************************************
     * Following pointers points within the read-only mmap region
     *************************************************************/

    // MTK headers
    const mtk_hdr *k_hdr;
    const mtk_hdr *r_hdr;

    // The pointers/values after parse_image
    // +---------------+
    // | z_hdr         | z_info.hdr_sz
    // +---------------+
    // | kernel        | hdr->kernel_size()
    // +---------------+
    // | z_info.tail   | z_info.tail_sz
    // +---------------+
    const zimage_hdr *z_hdr;
    struct {
        uint32_t hdr_sz;
        uint32_t tail_sz = 0;
        const uint8_t *tail = nullptr;
    } z_info;

    // Pointer to dtb that is embedded in kernel
    const uint8_t *kernel_dtb;

    // Pointer to end of image
    const uint8_t *tail;
    size_t tail_size = 0;

    // AVB structs
    const AvbFooter *avb_footer;
    const AvbVBMetaImageHeader *vbmeta;

    // Pointers to blocks defined in header
    const uint8_t *hdr_addr;
    const uint8_t *kernel;
    const uint8_t *ramdisk;
    const uint8_t *second;
    const uint8_t *extra;
    const uint8_t *recovery_dtbo;
    const uint8_t *dtb;

    // Pointer to blocks defined in header, but we do not care
    const uint8_t *ignore;
    size_t ignore_size = 0;

    boot_img(const char *);
    ~boot_img();

    void parse_image(const uint8_t *addr, format_t type);
    dyn_img_hdr *create_hdr(const uint8_t *addr, format_t type);
};

================================================
FILE: compress.cpp
================================================
#include <memory>
#include <functional>

#include <zlib.h>
#include <bzlib.h>
#include <lzma.h>
#include <lz4.h>
#include <lz4frame.h>
#include <lz4hc.h>
#include <zopfli/util.h>
#include <zopfli/deflate.h>

#include <base.hpp>

#include "magiskboot.hpp"
#include "compress.hpp"

using namespace std;

#define bwrite this->base->write
#ifdef SVB_WIN32
#define crc32_z crc32
#endif

constexpr size_t CHUNK = 0x40000;
constexpr size_t LZ4_UNCOMPRESSED = 0x800000;
constexpr size_t LZ4_COMPRESSED = LZ4_COMPRESSBOUND(LZ4_UNCOMPRESSED);

class out_stream : public filter_stream {
    using filter_stream::filter_stream;
    using stream::read;
};

class gz_strm : public out_stream {
public:
    bool write(const void *buf, size_t len) override {
        return len == 0 || do_write(buf, len, Z_NO_FLUSH);
    }

    ~gz_strm() override {
        do_write(nullptr, 0, Z_FINISH);
        switch(mode) {
        case DECODE:
            inflateEnd(&strm);
            break;
        case ENCODE:
            deflateEnd(&strm);
            break;
        default:
            break;
        }
    }

protected:
    enum mode_t {
        DECODE,
        ENCODE,
        WAIT,
        COPY
    } mode;

    gz_strm(mode_t mode, stream_ptr &&base) :
        out_stream(std::move(base)), mode(mode), strm{}, outbuf{0} {
        switch(mode) {
        case DECODE:
            inflateInit2(&strm, 15 | 16);
            break;
        case ENCODE:
            deflateInit2(&strm, 9, Z_DEFLATED, 15 | 16, 8, Z_DEFAULT_STRATEGY);
            break;
        default:
            break;
        }
    }

private:
    z_stream strm;
    uint8_t outbuf[CHUNK];

    bool do_write(const void *buf, size_t len, int flush) {
        if (mode == WAIT) {
            if (len == 0) return true;
            Bytef b[1] = {0x1f};
            if (*(Bytef *)buf == 0x8b) {
                mode = DECODE;
                inflateReset(&strm);
                strm.next_in = b;
                strm.avail_in = 1;
                inflate(&strm, flush);
            } else {
                mode = COPY;
                return true;
            }
        }
        strm.next_in = (Bytef *) buf;
        strm.avail_in = len;
        do {
            int code;
            strm.next_out = outbuf;
            strm.avail_out = sizeof(outbuf);
            switch(mode) {
                case DECODE:
                    code = inflate(&strm, flush);
                    break;
                case ENCODE:
                    code = deflate(&strm, flush);
                    break;
                case COPY:
                    return true;
                default:
                    // should have been handled
                    return false;
            }
            if (code == Z_STREAM_ERROR) {
                LOGW("gzip %s failed (%d)\n", mode ? "encode" : "decode", code);
                return false;
            }
            if (!bwrite(outbuf, sizeof(outbuf) - strm.avail_out))
                return false;
            if (mode == DECODE && code == Z_STREAM_END) {
                if (strm.avail_in > 1) {
                    if (strm.next_in[0] == 0x1f && strm.next_in[1] == 0x8b) {
                        // There is still data in the stream, we need to reset the stream
                        // and continue decoding
                        inflateReset(&strm);
                        strm.avail_out = 0;
                        continue;
                    }
                } else if (strm.avail_in == 1) {
                    if (strm.next_in[0] == 0x1f) {
                        // If there is only one byte left, we need to wait for the next byte
                        // to determine if it is a gzip header
                        mode = WAIT;
                        return true;
                    }
                } else {
                    // The next inflate won't consume any data but fallback
                    // to the previous two conditions
                    return true;
                }
                // There is still data in the stream, we need to copy it
                mode = COPY;
                return true;
            }
        } while (strm.avail_out == 0);
        return true;
    }
};

class gz_decoder : public gz_strm {
public:
    explicit gz_decoder(stream_ptr &&base) : gz_strm(DECODE, std::move(base)) {};
};

class gz_encoder : public gz_strm {
public:
    explicit gz_encoder(stream_ptr &&base) : gz_strm(ENCODE, std::move(base)) {};
};

class zopfli_encoder : public chunk_out_stream {
public:
    explicit zopfli_encoder(stream_ptr &&base) :
        chunk_out_stream(std::move(base), ZOPFLI_MASTER_BLOCK_SIZE),
        zo{}, out(nullptr), outsize(0), crc(crc32_z(0L, Z_NULL, 0)), in_total(0), bp(0) {
        ZopfliInitOptions(&zo);

        // This config is already better than gzip -9
        zo.numiterations = 1;
        zo.blocksplitting = 0;

        ZOPFLI_APPEND_DATA(31, &out, &outsize);  /* ID1 */
        ZOPFLI_APPEND_DATA(139, &out, &outsize); /* ID2 */
        ZOPFLI_APPEND_DATA(8, &out, &outsize);   /* CM */
        ZOPFLI_APPEND_DATA(0, &out, &outsize);   /* FLG */
        /* MTIME */
        ZOPFLI_APPEND_DATA(0, &out, &outsize);
        ZOPFLI_APPEND_DATA(0, &out, &outsize);
        ZOPFLI_APPEND_DATA(0, &out, &outsize);
        ZOPFLI_APPEND_DATA(0, &out, &outsize);

        ZOPFLI_APPEND_DATA(2, &out, &outsize);  /* XFL, 2 indicates best compression. */
        ZOPFLI_APPEND_DATA(3, &out, &outsize);  /* OS follows Unix conventions. */
    }

    ~zopfli_encoder() override {
        finalize();

        /* CRC */
        ZOPFLI_APPEND_DATA(crc % 256, &out, &outsize);
        ZOPFLI_APPEND_DATA((crc >> 8) % 256, &out, &outsize);
        ZOPFLI_APPEND_DATA((crc >> 16) % 256, &out, &outsize);
        ZOPFLI_APPEND_DATA((crc >> 24) % 256, &out, &outsize);

        /* ISIZE */
        ZOPFLI_APPEND_DATA(in_total % 256, &out, &outsize);
        ZOPFLI_APPEND_DATA((in_total >> 8) % 256, &out, &outsize);
        ZOPFLI_APPEND_DATA((in_total >> 16) % 256, &out, &outsize);
        ZOPFLI_APPEND_DATA((in_total >> 24) % 256, &out, &outsize);

        bwrite(out, outsize);
        free(out);
    }

protected:
    bool write_chunk(const void *buf, size_t len, bool final) override {
        if (len == 0)
            return true;

        auto in = static_cast<const unsigned char *>(buf);

        in_total += len;
        crc = crc32_z(crc, in, len);

        ZopfliDeflatePart(&zo, 2, final, in, 0, len, &bp, &out, &outsize);

        // ZOPFLI_APPEND_DATA is extremely dumb, so we always preserve the
        // last byte to make sure that realloc is used instead of malloc
        if (!bwrite(out, outsize - 1))
            return false;
        out[0] = out[outsize - 1];
        outsize = 1;

        return true;
    }

private:
    ZopfliOptions zo;
    unsigned char *out;
    size_t outsize;
    unsigned long crc;
    uint32_t in_total;
    unsigned char bp;
};

class bz_strm : public out_stream {
public:
    bool write(const void *buf, size_t len) override {
        return len == 0 || do_write(buf, len, BZ_RUN);
    }

    ~bz_strm() override {
        switch(mode) {
            case DECODE:
                BZ2_bzDecompressEnd(&strm);
                break;
            case ENCODE:
                do_write(nullptr, 0, BZ_FINISH);
                BZ2_bzCompressEnd(&strm);
                break;
        }
    }

protected:
    enum mode_t {
        DECODE,
        ENCODE
    } mode;

    bz_strm(mode_t mode, stream_ptr &&base) :
        out_stream(std::move(base)), mode(mode), strm{}, outbuf{0} {
        switch(mode) {
        case DECODE:
            BZ2_bzDecompressInit(&strm, 0, 0);
            break;
        case ENCODE:
            BZ2_bzCompressInit(&strm, 9, 0, 0);
            break;
        }
    }

private:
    bz_stream strm;
    char outbuf[CHUNK];

    bool do_write(const void *buf, size_t len, int flush) {
        strm.next_in = (char *) buf;
        strm.avail_in = len;
        do {
            int code;
            strm.avail_out = sizeof(outbuf);
            strm.next_out = outbuf;
            switch(mode) {
            case DECODE:
                code = BZ2_bzDecompress(&strm);
                break;
            case ENCODE:
                code = BZ2_bzCompress(&strm, flush);
                break;
            }
            if (code < 0) {
                LOGW("bzip2 %s failed (%d)\n", mode ? "encode" : "decode", code);
                return false;
            }
            if (!bwrite(outbuf, sizeof(outbuf) - strm.avail_out))
                return false;
        } while (strm.avail_out == 0);
        return true;
    }
};

class bz_decoder : public bz_strm {
public:
    explicit bz_decoder(stream_ptr &&base) : bz_strm(DECODE, std::move(base)) {};
};

class bz_encoder : public bz_strm {
public:
    explicit bz_encoder(stream_ptr &&base) : bz_strm(ENCODE, std::move(base)) {};
};

class lzma_strm : public out_stream {
public:
    bool write(const void *buf, size_t len) override {
        return len == 0 || do_write(buf, len, LZMA_RUN);
    }

    ~lzma_strm() override {
        do_write(nullptr, 0, LZMA_FINISH);
        lzma_end(&strm);
    }

protected:
    enum mode_t {
        DECODE,
        ENCODE_XZ,
        ENCODE_LZMA
    } mode;

    lzma_strm(mode_t mode, stream_ptr &&base) :
        out_stream(std::move(base)), mode(mode), strm(LZMA_STREAM_INIT), outbuf{0} {
        lzma_options_lzma opt;

        // Initialize preset
        lzma_lzma_preset(&opt, 9);
        lzma_filter filters[] = {
            { .id = LZMA_FILTER_LZMA2, .options = &opt },
            { .id = LZMA_VLI_UNKNOWN, .options = nullptr },
        };

        lzma_ret code;
        switch(mode) {
        case DECODE:
            code = lzma_auto_decoder(&strm, UINT64_MAX, 0);
            break;
        case ENCODE_XZ:
            code = lzma_stream_encoder(&strm, filters, LZMA_CHECK_CRC32);
            break;
        case ENCODE_LZMA:
            code = lzma_alone_encoder(&strm, &opt);
            break;
        }
        if (code != LZMA_OK) {
            LOGE("LZMA initialization failed (%d)\n", code);
        }
    }

private:
    lzma_stream strm;
    uint8_t outbuf[CHUNK];

    bool do_write(const void *buf, size_t len, lzma_action flush) {
        strm.next_in = (uint8_t *) buf;
        strm.avail_in = len;
        do {
            strm.avail_out = sizeof(outbuf);
            strm.next_out = outbuf;
            int code = lzma_code(&strm, flush);
            if (code != LZMA_OK && code != LZMA_STREAM_END) {
                LOGW("LZMA %s failed (%d)\n", mode ? "encode" : "decode", code);
                return false;
            }
            if (!bwrite(outbuf, sizeof(outbuf) - strm.avail_out))
                return false;
        } while (strm.avail_out == 0);
        return true;
    }
};

class lzma_decoder : public lzma_strm {
public:
    explicit lzma_decoder(stream_ptr &&base) : lzma_strm(DECODE, std::move(base)) {}
};

class xz_encoder : public lzma_strm {
public:
    explicit xz_encoder(stream_ptr &&base) : lzma_strm(ENCODE_XZ, std::move(base)) {}
};

class lzma_encoder : public lzma_strm {
public:
    explicit lzma_encoder(stream_ptr &&base) : lzma_strm(ENCODE_LZMA, std::move(base)) {}
};

class LZ4F_decoder : public out_stream {
public:
    explicit LZ4F_decoder(stream_ptr &&base) :
        out_stream(std::move(base)), ctx(nullptr), outbuf(nullptr), outCapacity(0) {
        LZ4F_createDecompressionContext(&ctx, LZ4F_VERSION);
    }

    ~LZ4F_decoder() override {
        LZ4F_freeDecompressionContext(ctx);
        delete[] outbuf;
    }

    bool write(const void *buf, size_t len) override {
        auto in = reinterpret_cast<const uint8_t *>(buf);
        if (!outbuf) {
            size_t read = len;
            LZ4F_frameInfo_t info;
            LZ4F_getFrameInfo(ctx, &info, in, &read);
            switch (info.blockSizeID) {
            case LZ4F_default:
            case LZ4F_max64KB:  outCapacity = 1 << 16; break;
            case LZ4F_max256KB: outCapacity = 1 << 18; break;
            case LZ4F_max1MB:   outCapacity = 1 << 20; break;
            case LZ4F_max4MB:   outCapacity = 1 << 22; break;
            }
            outbuf = new uint8_t[outCapacity];
            in += read;
            len -= read;
        }
        size_t read, write;
        LZ4F_errorCode_t code;
        do {
            read = len;
            write = outCapacity;
            code = LZ4F_decompress(ctx, outbuf, &write, in, &read, nullptr);
            if (LZ4F_isError(code)) {
                LOGW("LZ4F decode error: %s\n", LZ4F_getErrorName(code));
                return false;
            }
            len -= read;
            in += read;
            if (!bwrite(outbuf, write))
                return false;
        } while (len != 0 || write != 0);
        return true;
    }

private:
    LZ4F_decompressionContext_t ctx;
    uint8_t *outbuf;
    size_t outCapacity;
};

class LZ4F_encoder : public out_stream {
public:
    explicit LZ4F_encoder(stream_ptr &&base) :
        out_stream(std::move(base)), ctx(nullptr), out_buf(nullptr), outCapacity(0) {
        LZ4F_createCompressionContext(&ctx, LZ4F_VERSION);
    }

    bool write(const void *buf, size_t len) override {
        if (!out_buf) {
            LZ4F_preferences_t prefs {
                .frameInfo = {
                    .blockSizeID = LZ4F_max4MB,
                    .blockMode = LZ4F_blockIndependent,
                    .contentChecksumFlag = LZ4F_contentChecksumEnabled,
                    .blockChecksumFlag = LZ4F_noBlockChecksum,
                },
                .compressionLevel = 9,
                .autoFlush = 1,
            };
            outCapacity = LZ4F_compressBound(BLOCK_SZ, &prefs);
            out_buf = new uint8_t[outCapacity];
            size_t write = LZ4F_compressBegin(ctx, out_buf, outCapacity, &prefs);
            if (!bwrite(out_buf, write))
                return false;
        }
        if (len == 0)
            return true;

        auto in = reinterpret_cast<const uint8_t *>(buf);
        size_t read, write;
        do {
            read = len > BLOCK_SZ ? BLOCK_SZ : len;
            write = LZ4F_compressUpdate(ctx, out_buf, outCapacity, in, read, nullptr);
            if (LZ4F_isError(write)) {
                LOGW("LZ4F encode error: %s\n", LZ4F_getErrorName(write));
                return false;
            }
            len -= read;
            in += read;
            if (!bwrite(out_buf, write))
                return false;
        } while (len != 0);
        return true;
    }

    ~LZ4F_encoder() override {
        size_t len = LZ4F_compressEnd(ctx, out_buf, outCapacity, nullptr);
        if (LZ4F_isError(len)) {
            LOGE("LZ4F end of frame error: %s\n", LZ4F_getErrorName(len));
        } else if (!bwrite(out_buf, len)) {
            LOGE("LZ4F end of frame error: I/O error\n");
        }
        LZ4F_freeCompressionContext(ctx);
        delete[] out_buf;
    }

private:
    LZ4F_compressionContext_t ctx;
    uint8_t *out_buf;
    size_t outCapacity;

    static constexpr size_t BLOCK_SZ = 1 << 22;
};

class LZ4_decoder : public chunk_out_stream {
public:
    explicit LZ4_decoder(stream_ptr &&base) :
        chunk_out_stream(std::move(base), LZ4_COMPRESSED, sizeof(block_sz)),
        out_buf(new char[LZ4_UNCOMPRESSED]), block_sz(0) {}

    ~LZ4_decoder() override {
        finalize();
        delete[] out_buf;
    }

protected:
    bool write_chunk(const void *buf, size_t len, bool final) override {
        // This is an error
        if (len != chunk_sz)
            return false;

        auto in = reinterpret_cast<const char *>(buf);

        if (block_sz == 0) {
            memcpy(&block_sz, in, sizeof(block_sz));
            if (block_sz == 0x184C2102) {
                // This is actually the lz4 magic, read the next 4 bytes
                block_sz = 0;
                chunk_sz = sizeof(block_sz);
                return true;
            }
            // Read the next block chunk
            chunk_sz = block_sz;
            return true;
        } else {
            int r = LZ4_decompress_safe(in, out_buf, block_sz, LZ4_UNCOMPRESSED);
            chunk_sz = sizeof(block_sz);
            block_sz = 0;
            if (r < 0) {
                LOGW("LZ4HC decompression failure (%d)\n", r);
                return false;
            }
            return bwrite(out_buf, r);
        }
    }

private:
    char *out_buf;
    uint32_t block_sz;
};

class LZ4_encoder : public chunk_out_stream {
public:
    explicit LZ4_encoder(stream_ptr &&base, bool lg) :
        chunk_out_stream(std::move(base), LZ4_UNCOMPRESSED),
        out_buf(new char[LZ4_COMPRESSED]), lg(lg), in_total(0) {
        bwrite("\x02\x21\x4c\x18", 4);
    }

    ~LZ4_encoder() override {
        finalize();
        if (lg)
            bwrite(&in_total, sizeof(in_total));
        delete[] out_buf;
    }

protected:
    bool write_chunk(const void *buf, size_t len, bool final) override {
        auto in = static_cast<const char *>(buf);
        uint32_t block_sz = LZ4_compress_HC(in, out_buf, len, LZ4_COMPRESSED, LZ4HC_CLEVEL_MAX);
        if (block_sz == 0) {
            LOGW("LZ4HC compression failure\n");
            return false;
        }
        if (bwrite(&block_sz, sizeof(block_sz)) && bwrite(out_buf, block_sz)) {
            in_total += len;
            return true;
        }
        return false;
    }

private:
    char *out_buf;
    bool lg;
    uint32_t in_total;
};

filter_strm_ptr get_encoder(format_t type, stream_ptr &&base) {
    switch (type) {
        case XZ:
            return make_unique<xz_encoder>(std::move(base));
        case LZMA:
            return make_unique<lzma_encoder>(std::move(base));
        case BZIP2:
            return make_unique<bz_encoder>(std::move(base));
        case LZ4:
            return make_unique<LZ4F_encoder>(std::move(base));
        case LZ4_LEGACY:
            return make_unique<LZ4_encoder>(std::move(base), false);
        case LZ4_LG:
            return make_unique<LZ4_encoder>(std::move(base), true);
        case ZOPFLI:
            return make_unique<zopfli_encoder>(std::move(base));
        case GZIP:
        default:
            return make_unique<gz_encoder>(std::move(base));
    }
}

filter_strm_ptr get_decoder(format_t type, stream_ptr &&base) {
    switch (type) {
        case XZ:
        case LZMA:
            return make_unique<lzma_decoder>(std::move(base));
        case BZIP2:
            return make_unique<bz_decoder>(std::move(base));
        case LZ4:
            return make_unique<LZ4F_decoder>(std::move(base));
        case LZ4_LEGACY:
        case LZ4_LG:
            return make_unique<LZ4_decoder>(std::move(base));
        case ZOPFLI:
        case GZIP:
        default:
            return make_unique<gz_decoder>(std::move(base));
    }
}

void decompress(char *infile, const char *outfile) {
    bool in_std = infile == "-"sv;
    bool rm_in = false;

    FILE *in_fp = in_std ? stdin : xfopen(infile, "re");
    stream_ptr strm;

    char buf[4096];
    size_t len;
    while ((len = fread(buf, 1, sizeof(buf), in_fp))) {
        if (!strm) {
            format_t type = check_fmt(buf, len);

            fprintf(stderr, "Detected format: [%s]\n", fmt2name[type]);

            if (!COMPRESSED(type))
                LOGE("Input file is not a supported compressed type!\n");

            /* If user does not provide outfile, infile has to be either
            * <path>.[ext], or '-'. Outfile will be either <path> or '-'.
            * If the input does not have proper format, abort */

            char *ext = nullptr;
            if (outfile == nullptr) {
                outfile = infile;
                if (!in_std) {
                    ext = strrchr(infile, '.');
                    if (ext == nullptr || strcmp(ext, fmt2ext[type]) != 0)
                        LOGE("Input file is not a supported type!\n");

                    // Strip out extension and remove input
                    *ext = '\0';
                    rm_in = true;
                    fprintf(stderr, "Decompressing to [%s]\n", outfile);
                }
            }

            FILE *out_fp = outfile == "-"sv ? stdout : xfopen(outfile, "we");
            strm = get_decoder(type, make_unique<fp_stream>(out_fp));
            if (ext) *ext = '.';
        }
        if (!strm->write(buf, len))
            LOGE("Decompression error!\n");
    }

    strm.reset(nullptr);
    fclose(in_fp);

    if (rm_in)
        unlink(infile);
}

void compress(const char *method, const char *infile, const char *outfile) {
    format_t fmt = name2fmt[method];
    if (fmt == UNKNOWN)
        LOGE("Unknown compression method: [%s]\n", method);

    bool in_std = infile == "-"sv;
    bool rm_in = false;

    FILE *in_fp = in_std ? stdin : xfopen(infile, "re");
    FILE *out_fp;

    if (outfile == nullptr) {
        if (in_std) {
            out_fp = stdout;
        } else {
            /* If user does not provide outfile and infile is not
             * STDIN, output to <infile>.[ext] */
            string tmp(infile);
            tmp += fmt2ext[fmt];
            out_fp = xfopen(tmp.data(), "we");
            fprintf(stderr, "Compressing to [%s]\n", tmp.data());
            rm_in = true;
        }
    } else {
        out_fp = outfile == "-"sv ? stdout : xfopen(outfile, "we");
    }

    auto strm = get_encoder(fmt, make_unique<fp_stream>(out_fp));

    char buf[4096];
    size_t len;
    while ((len = fread(buf, 1, sizeof(buf), in_fp))) {
        if (!strm->write(buf, len))
            LOGE("Compression error!\n");
    }

    strm.reset(nullptr);
    fclose(in_fp);

    if (rm_in)
        unlink(infile);
}


================================================
FILE: compress.hpp
================================================
#pragma once

#include <stream.hpp>

#include "format.hpp"

filter_strm_ptr get_encoder(format_t type, stream_ptr &&base);

filter_strm_ptr get_decoder(format_t type, stream_ptr &&base);

void compress(const char *method, const char *infile, const char *outfile);

void decompress(char *infile, const char *outfile);


================================================
FILE: cpio.cpp
================================================
#include <unistd.h>
#include <fcntl.h>
#include <libgen.h>
#include <algorithm>

#include <base.hpp>

#include "cpio.hpp"

using namespace std;

struct cpio_newc_header {
    char magic[6];
    char ino[8];
    char mode[8];
    char uid[8];
    char gid[8];
    char nlink[8];
    char mtime[8];
    char filesize[8];
    char devmajor[8];
    char devminor[8];
    char rdevmajor[8];
    char rdevminor[8];
    char namesize[8];
    char check[8];
} __attribute__((packed));

static uint32_t x8u(const char *hex) {
    uint32_t val, inpos = 8, outpos;
    char pattern[6];

    while (*hex == '0') {
        hex++;
        if (!--inpos) return 0;
    }
    // Because scanf gratuitously treats %*X differently than printf does.
    sprintf(pattern, "%%%dx%%n", inpos);
    sscanf(hex, pattern, &val, &outpos);
    if (inpos != outpos)
        LOGE("bad cpio header\n");

    return val;
}

cpio_entry::cpio_entry(uint32_t mode) : mode(mode), uid(0), gid(0), filesize(0), data(nullptr) {}

cpio_entry::cpio_entry(uint32_t mode, uint32_t uid, uint32_t gid) : mode(mode), uid(uid), gid(gid), filesize(0), data(nullptr) {}

cpio_entry::cpio_entry(const cpio_newc_header *h) :
mode(x8u(h->mode)), uid(x8u(h->uid)), gid(x8u(h->gid)), filesize(x8u(h->filesize)), data(nullptr)
{}

static void recursive_dir_iterator(cpio::entry_map &entries, const char* root, const char *sub = nullptr) {
    auto path = sub ? sub : root;
    auto cur = opendir(path);

    if (errno || !cur)
        return;

    for (dirent *entry; (entry = xreaddir(cur));) {
        char *filename = (char *)malloc(strlen(path) + 2 +
#ifndef SVB_MINGW
        strlen(entry->name));
#else
        entry->d_namlen);
#endif
        struct stat st;

        if (sprintf(filename, "%s/%s", path, entry->d_name) < 0 ||
            xlstat(filename, &st)) {
            errno = EINVAL;
            break;
        }

        auto e = new cpio_entry(st.st_mode, st.st_uid, st.st_gid);
        auto name = filename + strlen(root) + 1;
        auto type = st.st_mode & S_IFMT;

        if (type == S_IFREG) {
            auto m = mmap_data(filename);
            e->filesize = m.sz;
            e->data = xmalloc(m.sz);
            memcpy(e->data, m.buf, m.sz);
        } else if (type == S_IFLNK) {
            char* ln_target = (char *)malloc(st.st_size + 1);
            int read_cnt = xreadlink(filename, ln_target, st.st_size);

            if (read_cnt == -1 || read_cnt > st.st_size) {
                errno = EINVAL;
                return;
            }
            e->filesize = st.st_size;
            e->data = ln_target;
        } else { // assume S_IFDIR
            recursive_dir_iterator(entries, root, filename);
        }

        entries.emplace(name, e);
        free(filename);
    }

    closedir(cur);
}

void cpio::dump(const char *file) {
    fprintf(stderr, "Dump cpio: [%s]\n", file);
    dump(xfopen(file, "we"));
}

void cpio::rm(entry_map::iterator it) {
    if (it == entries.end())
        return;
    fprintf(stderr, "Remove [%s]\n", it->first.data());
    entries.erase(it);
}

void cpio::rm(const char *name, bool r) {
    size_t len = strlen(name);
    for (auto it = entries.begin(); it != entries.end();) {
        if (it->first.compare(0, len, name) == 0 &&
            ((r && it->first[len] == '/') || it->first[len] == '\0')) {
            auto tmp = it;
            ++it;
            rm(tmp);
            if (!r) return;
        } else {
            ++it;
        }
    }
}

void cpio::extract_entry(const entry_map::value_type &e, const char *file) {
    fprintf(stderr, "Extract [%s] to [%s]\n", e.first.data(), file);
    unlink(file);
    rmdir(file);
    // Make sure parent folders exist
    char *parent = dirname(strdup(file));
    xmkdirs(parent, 0755);
    if (S_ISDIR(e.second->mode)) {
        xmkdir(file, e.second->mode & 0777);
    } else if (S_ISREG(e.second->mode)) {
        int fd = xopen(file, O_CREAT | O_WRONLY | O_TRUNC, e.second->mode & 0777);
        xwrite(fd, e.second->data, e.second->filesize);
#ifndef SVB_WIN32
        fchown(fd, e.second->uid, e.second->gid);
#endif
        close(fd);
    } else if (S_ISLNK(e.second->mode) && e.second->filesize < 4096) {
        char target[4096];
        memcpy(target, e.second->data, e.second->filesize);
        target[e.second->filesize] = '\0';
        symlink(target, file);
    }
#ifdef SVB_WIN32
    FILE *config = fopen("cpio", "a");
    fprintf(config, "%s %o %u %u\n", e.first.data(), e.second->mode & 0777, e.second->uid, e.second->gid);
    fclose(config);
#endif
}

void cpio::extract() {
    unlink("cpio");
    rmdir("ramdisk");
#ifdef SVB_MINGW
    ::mkdir("ramdisk");
#else
    ::mkdir("ramdisk", 0744);
#endif
    for (auto &e : entries)
        extract_entry(e, ("ramdisk/" + e.first).data());
}

void cpio::load_cpio(const char* dir, const char* config, bool sync) {
    entry_map dentries;

    recursive_dir_iterator(dentries, dir);

    if (errno) {
        PLOGE("%s [%s]", sync ? "Sync" : "Pack", dir);
        return;
    }

    file_readline(config, [&](string_view line) -> bool {
        if (line.empty() || line[0] == '#')
            return true;

        auto tokens = split(string(line), " ");

        if (tokens.size() < 4) {
            LOGE("Ill-formed line in [%s]\n", config);
        }

        auto it = dentries.find(tokens[0].data());
        if (it != dentries.end()) {
            it->second->mode &= S_IFMT;
            it->second->mode |= static_cast<unsigned int>(strtol(tokens[1].data(), nullptr, 8)) & 0777;
            it->second->uid = strtol(tokens[2].data(), nullptr, 10);
            it->second->gid = strtol(tokens[3].data(), nullptr, 10);
        }

        return true;
    });

    if (!sync) {
        entries = std::move(dentries);
        return;
    }

    auto rhs = entries.begin();
    auto lhs = dentries.begin();

    while (rhs != entries.end() || lhs != dentries.end()) {
        int res;
        if (lhs != dentries.end() && rhs != entries.end()) {
            res = rhs->first.compare(lhs->first);
        } else if (rhs == entries.end()) {
            res = 1;
        } else {
            res = -1;
        }

        bool is_new = res >= 0;

        if (res < 0) { // smh is removed
            rm(rhs++);
        } else if (res == 0) { // smh is same, maybe
            is_new = rhs->second->filesize != lhs->second->filesize ||
                     rhs->second->mode != lhs->second->mode ||
                     rhs->second->uid != lhs->second->uid ||
                     rhs->second->gid != lhs->second->gid ||
                     memcmp(lhs->second->data, rhs->second->data, lhs->second->filesize) != 0;
        } // smh is added

        if (is_new) {
            fprintf(stderr, "%s entry [%s] (%04o)\n", res > 0 ? "Add new" : "Updated", lhs->first.data(), lhs->second->mode & 0777);
            insert(lhs->first, lhs->second.release());
        }

        if (res > 0) {
            ++lhs;
        } else if (res == 0)  {
            ++lhs; ++rhs;
        }
    }
}

bool cpio::extract(const char *name, const char *file) {
    auto it = entries.find(name);
    if (it != entries.end()) {
        extract_entry(*it, file);
        return true;
    }
    fprintf(stderr, "Cannot find the file entry [%s]\n", name);
    return false;
}

bool cpio::exists(const char *name) {
    return entries.count(name) != 0;
}

#define do_out(buf, len) pos += fwrite(buf, 1, len, out);
#define out_align() do_out(zeros, align_padding(pos, 4))
void cpio::dump(FILE *out) {
    size_t pos = 0;
    unsigned inode = 300000;
    char header[111];
    char zeros[4] = {0};
    for (auto &e : entries) {
        sprintf(header, "070701%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x",
                inode++,    // e->ino
                e.second->mode,
                e.second->uid,
                e.second->gid,
                1,          // e->nlink
                0,          // e->mtime
                e.second->filesize,
                0,          // e->devmajor
                0,          // e->devminor
                0,          // e->rdevmajor
                0,          // e->rdevminor
                (uint32_t) e.first.size() + 1,
                0           // e->check
        );
        do_out(header, 110);
        do_out(e.first.data(), e.first.size() + 1);
        out_align();
        if (e.second->filesize) {
            do_out(e.second->data, e.second->filesize);
            out_align();
        }
    }
    // Write trailer
    sprintf(header, "070701%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x",
            inode++, 0755, 0, 0, 1, 0, 0, 0, 0, 0, 0, 11, 0);
    do_out(header, 110);
    do_out("TRAILER!!!\0", 11);
    out_align();
    fclose(out);
}

void cpio::load_cpio(const char *file) {
    fprintf(stderr, "Loading cpio: [%s]\n", file);
    auto m = mmap_data(file);
    load_cpio(reinterpret_cast<char *>(m.buf), m.sz);
}

void cpio::insert(string_view name, cpio_entry *e) {
    auto it = entries.find(name);
    if (it != entries.end()) {
        it->second.reset(e);
    } else {
        entries.emplace(name, e);
    }
}

void cpio::add(mode_t mode, const char *name, const char *file) {
    auto m = mmap_data(file);
    auto e = new cpio_entry(S_IFREG | mode);
    e->filesize = m.sz;
    e->data = xmalloc(m.sz);
    memcpy(e->data, m.buf, m.sz);
    insert(name, e);
    fprintf(stderr, "Add entry [%s] (%04o)\n", name, mode);
}

void cpio::mkdir(mode_t mode, const char *name) {
    insert(name, new cpio_entry(S_IFDIR | mode));
    fprintf(stderr, "Create directory [%s] (%04o)\n", name, mode);
}

void cpio::ln(const char *target, const char *name) {
    auto e = new cpio_entry(S_IFLNK);
    e->filesize = strlen(target);
    e->data = strdup(target);
    insert(name, e);
    fprintf(stderr, "Create symlink [%s] -> [%s]\n", name, target);
}

void cpio::mv(entry_map::iterator it, const char *name) {
    fprintf(stderr, "Move [%s] -> [%s]\n", it->first.data(), name);
    auto e = it->second.release();
    entries.erase(it);
    insert(name, e);
}

bool cpio::mv(const char *from, const char *to) {
    auto it = entries.find(from);
    if (it != entries.end()) {
        mv(it, to);
        return true;
    }
    fprintf(stderr, "Cannot find entry %s\n", from);
    return false;
}

#define pos_align(p) p = align_to(p, 4)

void cpio::load_cpio(const char *buf, size_t sz) {
    size_t pos = 0;
    while (pos < sz) {
        auto hdr = reinterpret_cast<const cpio_newc_header *>(buf + pos);
        if (memcmp(hdr->magic, "070701", 6) != 0)
            LOGE("bad cpio header\n");
        pos += sizeof(cpio_newc_header);
        string_view name(buf + pos);
        pos += x8u(hdr->namesize);
        pos_align(pos);
        if (name == "." || name == "..")
            continue;
        if (name == "TRAILER!!!") {
            // Android support multiple CPIO being concatenated
            // Search for the next cpio header
            auto next = static_cast<const char *>(memmem(buf + pos, sz - pos, "070701", 6));
            if (next == nullptr)
                break;
            pos = next - buf;
            continue;
        }
        auto entry = new cpio_entry(hdr);
        entry->data = xmalloc(entry->filesize);
        memcpy(entry->data, buf + pos, entry->filesize);
        pos += entry->filesize;
        insert(name, entry);
        pos_align(pos);
    }
}


================================================
FILE: cpio.hpp
================================================
#pragma once

#include <stdint.h>
#include <string>
#include <memory>
#include <map>
#include <string_view>

struct cpio_newc_header;

struct cpio_entry {
    uint32_t mode;
    uint32_t uid;
    uint32_t gid;
    uint32_t filesize;
    void *data;

    explicit cpio_entry(uint32_t mode = 0);
    explicit cpio_entry(uint32_t mode, uint32_t uid, uint32_t gid);
    explicit cpio_entry(const cpio_newc_header *h);
    ~cpio_entry() { free(data); }
};

class cpio {
public:
    struct StringCmp {
        using is_transparent = void;
        bool operator()(std::string_view a, std::string_view b) const {
            return a < b;
        }
    };
    using entry_map = std::map<std::string, std::unique_ptr<cpio_entry>, StringCmp>;

    void load_cpio(const char *file);
    void load_cpio(const char* dir, const char* config, bool sync);
    void dump(const char *file);
    void rm(const char *name, bool r = false);
    void extract();
    bool extract(const char *name, const char *file);
    bool exists(const char *name);
    void add(mode_t mode, const char *name, const char *file);
    void mkdir(mode_t mode, const char *name);
    void ln(const char *target, const char *name);
    bool mv(const char *from, const char *to);

protected:
    entry_map entries;

    static void extract_entry(const entry_map::value_type &e, const char *file);
    void rm(entry_map::iterator it);
    void mv(entry_map::iterator it, const char *name);

private:
    void dump(FILE *out);
    void insert(std::string_view name, cpio_entry *e);
    void load_cpio(const char *buf, size_t sz);
};


================================================
FILE: dll.rc
================================================
#include <windows.h>

VS_VERSION_INFO VERSIONINFO
FILEVERSION     1,0,0,0
PRODUCTVERSION  1,0,0,0
FILEFLAGSMASK      VS_FFI_FILEFLAGSMASK
#ifdef SVB_DEBUG
  FILEFLAGS        VS_FF_DEBUG | VS_FF_PRERELEASE
#else
  FILEFLAGS        0
#endif
FILEOS             VOS_NT_WINDOWS32
FILETYPE           VFT_DLL
FILESUBTYPE        VFT2_UNKNOWN
BEGIN
  BLOCK "StringFileInfo"
  BEGIN
    BLOCK "040904E4"
    BEGIN
      VALUE "FileDescription", "magiskboot library"
      VALUE "FileVersion", "1.0.0.0"
      VALUE "ProductVersion", "1.0.0.0"
    END
  END
  BLOCK "VarFileInfo"
  BEGIN
    VALUE "Translation", 0x809, 1200
  END
END

================================================
FILE: dtb.cpp
================================================
#include <bitset>
#include <vector>
#include <map>
#include <libfdt.h>

#include <base.hpp>

#include "magiskboot.hpp"
#include "dtb.hpp"
#include "format.hpp"

using namespace std;

constexpr int MAX_DEPTH = 32;
static bitset<MAX_DEPTH> depth_set;

static void pretty_node(int depth) {
    if (depth == 0)
        return;

    for (int i = 0; i < depth - 1; ++i)
        printf(depth_set[i] ? "│   " : "    ");

    printf(depth_set[depth - 1] ? "├── " : "└── ");
}

static void pretty_prop(int depth) {
    for (int i = 0; i < depth; ++i)
        printf(depth_set[i] ? "│   " : "    ");

    printf(depth_set[depth] ? "│  " : "   ");
}

static void print_node(const void *fdt, int node = 0, int depth = 0) {
    // Print node itself
    pretty_node(depth);
    printf("#%d: %s\n", node, fdt_get_name(fdt, node, nullptr));

    // Print properties
    depth_set[depth] = fdt_first_subnode(fdt, node) >= 0;
    int prop;
    fdt_for_each_property_offset(prop, fdt, node) {
        pretty_prop(depth);
        int size;
        const char *name;
        auto value = static_cast<const char *>(fdt_getprop_by_offset(fdt, prop, &name, &size));

        bool is_str = !(size > 1 && value[0] == 0);
        if (is_str) {
            // Scan through value to see if printable
            for (int i = 0; i < size; ++i) {
                char c = value[i];
                if (i == size - 1) {
                    // Make sure null terminate
                    is_str = c == '\0';
                } else if ((c > 0 && c < 32) || c >= 127) {
                    is_str = false;
                    break;
                }
            }
        }

        if (is_str) {
            printf("[%s]: [%s]\n", name, value);
        } else {
            printf("[%s]: <bytes>(%d)\n", name, size);
        }
    }

    // Recursive
    if (depth_set[depth]) {
        int child;
        int prev = -1;
        fdt_for_each_subnode(child, fdt, node) {
            if (prev >= 0)
                print_node(fdt, prev, depth + 1);
            prev = child;
        }
        depth_set[depth] = false;
        print_node(fdt, prev, depth + 1);
    }
}

static int find_fstab(const void *fdt, int node = 0) {
    if (auto name = fdt_get_name(fdt, node, nullptr); name && name == "fstab"sv)
        return node;
    int child;
    fdt_for_each_subnode(child, fdt, node) {
        int fstab = find_fstab(fdt, child);
        if (fstab >= 0)
            return fstab;
    }
    return -1;
}

template<typename Func>
static void for_each_fdt(const char *file, bool rw, Func fn) {
    auto m = mmap_data(file, rw);
    uint8_t *end = m.buf + m.sz;
    for (uint8_t *fdt = m.buf; fdt < end;) {
        fdt = static_cast<uint8_t*>(memmem(fdt, end - fdt, DTB_MAGIC, sizeof(fdt32_t)));
        if (fdt == nullptr)
            break;
        fn(fdt);
        fdt += fdt_totalsize(fdt);
    }
}

static void dtb_print(const char *file, bool fstab) {
    fprintf(stderr, "Loading dtbs from [%s]\n", file);
    int dtb_num = 0;
    for_each_fdt(file, false, [&](uint8_t *fdt) {
        if (fstab) {
            if (int node = find_fstab(fdt); node >= 0) {
                fprintf(stderr, "Found fstab in dtb.%04d\n", dtb_num);
                print_node(fdt, node);
            }
        } else {
            fprintf(stderr, "Printing dtb.%04d\n", dtb_num);
            print_node(fdt);
        }
        ++dtb_num;
    });
    fprintf(stderr, "\n");
}

static bool dtb_patch(const char *file) {
    fprintf(stderr, "Loading dtbs from [%s]\n", file);

    bool keep_verity = check_env("KEEPVERITY");
    bool patched = false;
    for_each_fdt(file, true, [&](uint8_t *fdt) {
        int node;
        // Patch the chosen node for bootargs
        fdt_for_each_subnode(node, fdt, 0) {
            if (auto name = fdt_get_name(fdt, node, nullptr); !name || name != "chosen"sv)
                continue;
            int len;
            if (auto value = fdt_getprop(fdt, node, "bootargs", &len)) {
                if (void *skip = memmem(value, len, "skip_initramfs", 14)) {
                    fprintf(stderr, "Patch [skip_initramfs] -> [want_initramfs]\n");
                    memcpy(skip, "want", 4);
                    patched = true;
                }
            }
            break;
        }
        if (!keep_verity) {
            if (int fstab = find_fstab(fdt); fstab >= 0) {
                fdt_for_each_subnode(node, fdt, fstab) {
                    int len;
                    char *value = (char *) fdt_getprop(fdt, node, "fsmgr_flags", &len);
                    patched |= patch_verity(value, len) != len;
                }
            }
        }
    });
    return patched;
}

[[noreturn]]
static void dtb_test(const char *file) {
    for_each_fdt(file, false, [&](uint8_t *fdt) {
        // Find the system node in fstab
        if (int fstab = find_fstab(fdt); fstab >= 0) {
            int node;
            fdt_for_each_subnode(node, fdt, fstab) {
                if (auto name = fdt_get_name(fdt, node, nullptr); !name || name != "system"sv)
                    continue;
                int len;
                if (auto value = fdt_getprop(fdt, node, "mnt_point", &len)) {
                    // If mnt_point is set to /system_root, abort!
                    if (strncmp(static_cast<const char *>(value), "/system_root", len) == 0) {
                        exit(1);
                    }
                }
            }
        }
    });
    exit(0);
}

int dtb_commands(int argc, char *argv[]) {
    char *dtb = argv[0];
    ++argv;
    --argc;

    if (argv[0] == "print"sv) {
        dtb_print(dtb, argc > 1 && argv[1] == "-f"sv);
        return 0;
    } else if (argv[0] == "patch"sv) {
        if (!dtb_patch(dtb))
            exit(1);
        return 0;
    } else if (argv[0] == "test"sv) {
        dtb_test(dtb);
    } else {
        return 1;
    }
}

// The following code is unused, left here for historical purpose. Since the code is
// extremely complicated, I won't want to rewrite this whole thing if somehow we need
// to use it in the future...

namespace {

struct fdt_blob {
    void *fdt;
    uint32_t offset;
    uint32_t len;
};

static bool fdt_patch(void *fdt) {
    int fstab = find_fstab(fdt);
    if (fstab < 0)
        return false;
    bool modified = false;
    int node;
    fdt_for_each_subnode(node, fdt, fstab) {
        const char *name = fdt_get_name(fdt, node, nullptr);
        // Force remove AVB for 2SI since it may bootloop some devices
        int len;
        auto value = (const char *) fdt_getprop(fdt, node, "fsmgr_flags", &len);
        string copy(value, len);
        uint32_t new_len = patch_verity(copy.data(), len);
        if (new_len != len) {
            modified = true;
            fdt_setprop(fdt, node, "fsmgr_flags", copy.data(), new_len);
        }
        if (name == "system"sv) {
            fprintf(stderr, "Setting [mnt_point] to [/system_root]\n");
            fdt_setprop_string(fdt, node, "mnt_point", "/system_root");
            modified = true;
        }
    }
    return modified;
}

#define MAX_FDT_GROWTH 256

template <class Table, class Header>
static bool dt_table_patch(const Header *hdr, const char *out) {
    map<uint32_t, fdt_blob> dtb_map;
    auto buf = reinterpret_cast<const uint8_t *>(hdr);
    auto tables = reinterpret_cast<const Table *>(buf + sizeof(Header));

    constexpr bool is_aosp = std::is_same_v<Header, dt_table_header>;

    // AOSP DTB store ints in big endian
    using endian_conv = uint32_t (*)(uint32_t);
    endian_conv be_to_le;
    endian_conv le_to_be;
    if constexpr (is_aosp) {
        be_to_le = fdt32_to_cpu;
        le_to_be = cpu_to_fdt32;
    } else {
        be_to_le = le_to_be = [](uint32_t x) { return x; };
    }

    // Collect all dtbs
    auto num_dtb = be_to_le(hdr->num_dtbs);
    for (int i = 0; i < num_dtb; ++i) {
        auto offset = be_to_le(tables[i].offset);
        if (dtb_map.count(offset) == 0) {
            auto blob = buf + offset;
            uint32_t size = fdt_totalsize(blob);
            auto fdt = xmalloc(size + MAX_FDT_GROWTH);
            memcpy(fdt, blob, size);
            fdt_open_into(fdt, fdt, size + MAX_FDT_GROWTH);
            dtb_map[offset] = { fdt, offset };
        }
    }
    if (dtb_map.empty())
        return false;

    // Patch fdt
    bool modified = false;
    for (auto &[_, blob] : dtb_map)
        modified |= fdt_patch(blob.fdt);
    if (!modified)
        return false;

    unlink(out);
    int fd = xopen(out, O_RDWR | O_CREAT | O_CLOEXEC, 0644);

    // This value is only used if AOSP DTB
    uint32_t total_size = 0;

    // Copy headers and tables
    total_size += xwrite(fd, buf, dtb_map.begin()->first);

    // mmap rw to patch table values retroactively
    auto mmap_sz = lseek(fd, 0, SEEK_CUR);
    auto addr = (uint8_t *) xmmap(nullptr, mmap_sz, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);

    // Guess alignment using gcd
    uint32_t align = 1;
    if constexpr (!is_aosp) {
        auto it = dtb_map.begin();
        align = (it++)->first;
        for (; it != dtb_map.end(); ++it)
            align = binary_gcd(align, it->first);
    }

    // Write dtbs
    for (auto &val : dtb_map) {
        val.second.offset = lseek(fd, 0, SEEK_CUR);
        auto fdt = val.second.fdt;
        fdt_pack(fdt);
        auto size = fdt_totalsize(fdt);
        total_size += xwrite(fd, fdt, size);
        if constexpr (!is_aosp) {
            val.second.len = align_to(size, align);
            write_zero(fd, align_padding(lseek(fd, 0, SEEK_CUR), align));
        }
        free(fdt);
    }

    // Patch headers
    if constexpr (is_aosp) {
        auto hdr_rw = reinterpret_cast<Header *>(addr);
        hdr_rw->total_size = le_to_be(total_size);
    }
    auto tables_rw = reinterpret_cast<Table *>(addr + sizeof(Header));
    for (int i = 0; i < num_dtb; ++i) {
        auto &blob = dtb_map[be_to_le(tables_rw[i].offset)];
        tables_rw[i].offset = le_to_be(blob.offset);
        tables_rw[i].len = le_to_be(blob.len);
    }

    munmap(addr, mmap_sz);
    close(fd);

    return true;
}

static bool blob_patch(uint8_t *dtb, size_t dtb_sz, const char *out) {
    vector<uint8_t *> fdt_list;
    vector<uint32_t> padding_list;

    uint8_t * const end = dtb + dtb_sz;
    for (uint8_t *curr = dtb; curr < end;) {
        curr = static_cast<uint8_t*>(memmem(curr, end - curr, DTB_MAGIC, sizeof(fdt32_t)));
        if (curr == nullptr)
            break;
        auto len = fdt_totalsize(curr);
        auto fdt = static_cast<uint8_t *>(xmalloc(len + MAX_FDT_GROWTH));
        memcpy(fdt, curr, len);
        fdt_pack(fdt);
        uint32_t padding = len - fdt_totalsize(fdt);
        padding_list.push_back(padding);
        fdt_open_into(fdt, fdt, len + MAX_FDT_GROWTH);
        fdt_list.push_back(fdt);
        curr += len;
    }

    bool modified = false;
    for (auto fdt : fdt_list)
        modified |= fdt_patch(fdt);
    if (!modified)
        return false;

    unlink(out);
    int fd = xopen(out, O_WRONLY | O_CREAT | O_CLOEXEC, 0644);

    for (int i = 0; i < fdt_list.size(); ++i) {
        auto fdt = fdt_list[i];
        fdt_pack(fdt);
        // Only add padding back if it is anything meaningful
        if (padding_list[i] > 4) {
            auto len = fdt_totalsize(fdt);
            fdt_set_totalsize(fdt, len + padding_list[i]);
        }
        xwrite(fd, fdt, fdt_totalsize(fdt));
        free(fdt);
    }
    close(fd);

    return true;
}

#define DTB_MATCH(s) BUFFER_MATCH(dtb, s)

[[maybe_unused]]
static bool dtb_patch_rebuild(uint8_t *dtb, size_t dtb_sz, const char *file) {
    if (DTB_MATCH(QCDT_MAGIC)) {
        auto hdr = reinterpret_cast<qcdt_hdr*>(dtb);
        switch (hdr->version) {
            case 1:
                fprintf(stderr, "QCDT v1\n");
                return dt_table_patch<qctable_v1>(hdr, file);
            case 2:
                fprintf(stderr, "QCDT v2\n");
                return dt_table_patch<qctable_v2>(hdr, file);
            case 3:
                fprintf(stderr, "QCDT v3\n");
                return dt_table_patch<qctable_v3>(hdr, file);
            default:
                return false;
        }
    } else if (DTB_MATCH(DTBH_MAGIC)) {
        auto hdr = reinterpret_cast<dtbh_hdr *>(dtb);
        switch (hdr->version) {
            case 2:
                fprintf(stderr, "DTBH v2\n");
                return dt_table_patch<bhtable_v2>(hdr, file);
            default:
                return false;
        }
    } else if (DTB_MATCH(PXADT_MAGIC)) {
        auto hdr = reinterpret_cast<pxadt_hdr *>(dtb);
        switch (hdr->version) {
            case 1:
                fprintf(stderr, "PXA-DT v1\n");
                return dt_table_patch<pxatable_v1>(hdr, file);
            default:
                return false;
        }
    } else if (DTB_MATCH(PXA19xx_MAGIC)) {
        auto hdr = reinterpret_cast<pxa19xx_hdr *>(dtb);
        switch (hdr->version) {
            case 1:
                fprintf(stderr, "PXA-19xx v1\n");
                return dt_table_patch<pxatable_v1>(hdr, file);
            default:
                return false;
        }
    } else if (DTB_MATCH(SPRD_MAGIC)) {
        auto hdr = reinterpret_cast<sprd_hdr *>(dtb);
        switch (hdr->version) {
            case 1:
                fprintf(stderr, "SPRD v1\n");
                return dt_table_patch<sprdtable_v1>(hdr, file);
            default:
                return false;
        }
    } else if (DTB_MATCH(DT_TABLE_MAGIC)) {
        auto hdr = reinterpret_cast<dt_table_header *>(dtb);
        switch (hdr->version) {
            case 0:
                fprintf(stderr, "DT_TABLE v0\n");
                return dt_table_patch<dt_table_entry>(hdr, file);
            default:
                return false;
        }
    } else {
        return blob_patch(dtb, dtb_sz, file);
    }
}

} // namespace


================================================
FILE: dtb.hpp
================================================
#pragma once

#include <stdint.h>

#define DT_TABLE_MAGIC  "\xd7\xb7\xab\x1e"
#define QCDT_MAGIC      "QCDT"
#define DTBH_MAGIC      "DTBH"
#define PXADT_MAGIC     "PXA-DT"
#define PXA19xx_MAGIC   "PXA-19xx"
#define SPRD_MAGIC      "SPRD"

struct qcdt_hdr {
    char magic[4];          /* "QCDT" */
    uint32_t version;       /* QCDT version */
    uint32_t num_dtbs;      /* Number of DTBs */
} __attribute__((packed));

struct qctable_v1 {
    uint32_t cpu_info[3];   /* Some CPU info */
    uint32_t offset;        /* DTB offset in QCDT */
    uint32_t len;           /* DTB size */
} __attribute__((packed));

struct qctable_v2 {
    uint32_t cpu_info[4];   /* Some CPU info */
    uint32_t offset;        /* DTB offset in QCDT */
    uint32_t len;           /* DTB size */
} __attribute__((packed));

struct qctable_v3 {
    uint32_t cpu_info[8];   /* Some CPU info */
    uint32_t offset;        /* DTB offset in QCDT */
    uint32_t len;           /* DTB size */
} __attribute__((packed));

struct dtbh_hdr {
    char magic[4];          /* "DTBH" */
    uint32_t version;       /* DTBH version */
    uint32_t num_dtbs;      /* Number of DTBs */
} __attribute__((packed));

struct bhtable_v2 {
    uint32_t cpu_info[5];   /* Some CPU info */
    uint32_t offset;        /* DTB offset in DTBH */
    uint32_t len;           /* DTB size */
    uint32_t space;         /* 0x00000020 */
} __attribute__((packed));

struct pxadt_hdr {
    char magic[6];          /* "PXA-DT" */
    uint32_t version;       /* PXA-* version */
    uint32_t num_dtbs;      /* Number of DTBs */
} __attribute__((packed));

struct pxa19xx_hdr {
    char magic[8];          /* "PXA-19xx" */
    uint32_t version;       /* PXA-* version */
    uint32_t num_dtbs;      /* Number of DTBs */
} __attribute__((packed));

struct pxatable_v1 {
    uint32_t cpu_info[2];   /* Some CPU info */
    uint32_t offset;        /* DTB offset in PXA-* */
    uint32_t len;           /* DTB size */
} __attribute__((packed));

struct sprd_hdr {
    char magic[4];          /* "SPRD" */
    uint32_t version;       /* SPRD version */
    uint32_t num_dtbs;      /* Number of DTBs */
} __attribute__((packed));

struct sprdtable_v1 {
    uint32_t cpu_info[3];   /* Some CPU info */
    uint32_t offset;        /* DTB offset in SPRD */
    uint32_t len;           /* DTB size */
} __attribute__((packed));

/* AOSP DTB/DTBO partition layout */

struct dt_table_header {
    uint32_t magic;             /* DT_TABLE_MAGIC */
    uint32_t total_size;        /* includes dt_table_header + all dt_table_entry */
    uint32_t header_size;       /* sizeof(dt_table_header) */

    uint32_t dt_entry_size;     /* sizeof(dt_table_entry) */
    uint32_t num_dtbs;          /* number of dt_table_entry */
    uint32_t dt_entries_offset; /* offset to the first dt_table_entry */

    uint32_t page_size;         /* flash page size we assume */
    uint32_t version;           /* DTBO image version */
} __attribute__((packed));

struct dt_table_entry {
    uint32_t len;           /* DTB size */
    uint32_t offset;

    uint32_t id;
    uint32_t rev;
    uint32_t flags;

    uint32_t custom[3];
} __attribute__((packed));


================================================
FILE: external/bzip2/blocksort.c
================================================

/*-------------------------------------------------------------*/
/*--- Block sorting machinery                               ---*/
/*---                                           blocksort.c ---*/
/*-------------------------------------------------------------*/

/* ------------------------------------------------------------------
   This file is part of bzip2/libbzip2, a program and library for
   lossless, block-sorting data compression.

   bzip2/libbzip2 version 1.0.6 of 6 September 2010
   Copyright (C) 1996-2010 Julian Seward <jseward@bzip.org>

   Please read the WARNING, DISCLAIMER and PATENTS sections in the 
   README file.

   This program is released under the terms of the license contained
   in the file LICENSE.
   ------------------------------------------------------------------ */


#include "bzlib_private.h"

/*---------------------------------------------*/
/*--- Fallback O(N log(N)^2) sorting        ---*/
/*--- algorithm, for repetitive blocks      ---*/
/*---------------------------------------------*/

/*---------------------------------------------*/
static 
__inline__
void fallbackSimpleSort ( UInt32* fmap, 
                          UInt32* eclass, 
                          Int32   lo, 
                          Int32   hi )
{
   Int32 i, j, tmp;
   UInt32 ec_tmp;

   if (lo == hi) return;

   if (hi - lo > 3) {
      for ( i = hi-4; i >= lo; i-- ) {
         tmp = fmap[i];
         ec_tmp = eclass[tmp];
         for ( j = i+4; j <= hi && ec_tmp > eclass[fmap[j]]; j += 4 )
            fmap[j-4] = fmap[j];
         fmap[j-4] = tmp;
      }
   }

   for ( i = hi-1; i >= lo; i-- ) {
      tmp = fmap[i];
      ec_tmp = eclass[tmp];
      for ( j = i+1; j <= hi && ec_tmp > eclass[fmap[j]]; j++ )
         fmap[j-1] = fmap[j];
      fmap[j-1] = tmp;
   }
}


/*---------------------------------------------*/
#define fswap(zz1, zz2) \
   { Int32 zztmp = zz1; zz1 = zz2; zz2 = zztmp; }

#define fvswap(zzp1, zzp2, zzn)       \
{                                     \
   Int32 yyp1 = (zzp1);               \
   Int32 yyp2 = (zzp2);               \
   Int32 yyn  = (zzn);                \
   while (yyn > 0) {                  \
      fswap(fmap[yyp1], fmap[yyp2]);  \
      yyp1++; yyp2++; yyn--;          \
   }                                  \
}


#define fmin(a,b) ((a) < (b)) ? (a) : (b)

#define fpush(lz,hz) { stackLo[sp] = lz; \
                       stackHi[sp] = hz; \
                       sp++; }

#define fpop(lz,hz) { sp--;              \
                      lz = stackLo[sp];  \
                      hz = stackHi[sp]; }

#define FALLBACK_QSORT_SMALL_THRESH 10
#define FALLBACK_QSORT_STACK_SIZE   100


static
void fallbackQSort3 ( UInt32* fmap, 
                      UInt32* eclass,
                      Int32   loSt, 
                      Int32   hiSt )
{
   Int32 unLo, unHi, ltLo, gtHi, n, m;
   Int32 sp, lo, hi;
   UInt32 med, r, r3;
   Int32 stackLo[FALLBACK_QSORT_STACK_SIZE];
   Int32 stackHi[FALLBACK_QSORT_STACK_SIZE];

   r = 0;

   sp = 0;
   fpush ( loSt, hiSt );

   while (sp > 0) {

      AssertH ( sp < FALLBACK_QSORT_STACK_SIZE - 1, 1004 );

      fpop ( lo, hi );
      if (hi - lo < FALLBACK_QSORT_SMALL_THRESH) {
         fallbackSimpleSort ( fmap, eclass, lo, hi );
         continue;
      }

      /* Random partitioning.  Median of 3 sometimes fails to
         avoid bad cases.  Median of 9 seems to help but 
         looks rather expensive.  This too seems to work but
         is cheaper.  Guidance for the magic constants 
         7621 and 32768 is taken from Sedgewick's algorithms
         book, chapter 35.
      */
      r = ((r * 7621) + 1) % 32768;
      r3 = r % 3;
      if (r3 == 0) med = eclass[fmap[lo]]; else
      if (r3 == 1) med = eclass[fmap[(lo+hi)>>1]]; else
                   med = eclass[fmap[hi]];

      unLo = ltLo = lo;
      unHi = gtHi = hi;

      while (1) {
         while (1) {
            if (unLo > unHi) break;
            n = (Int32)eclass[fmap[unLo]] - (Int32)med;
            if (n == 0) { 
               fswap(fmap[unLo], fmap[ltLo]); 
               ltLo++; unLo++; 
               continue; 
            };
            if (n > 0) break;
            unLo++;
         }
         while (1) {
            if (unLo > unHi) break;
            n = (Int32)eclass[fmap[unHi]] - (Int32)med;
            if (n == 0) { 
               fswap(fmap[unHi], fmap[gtHi]); 
               gtHi--; unHi--; 
               continue; 
            };
            if (n < 0) break;
            unHi--;
         }
         if (unLo > unHi) break;
         fswap(fmap[unLo], fmap[unHi]); unLo++; unHi--;
      }

      AssertD ( unHi == unLo-1, "fallbackQSort3(2)" );

      if (gtHi < ltLo) continue;

      n = fmin(ltLo-lo, unLo-ltLo); fvswap(lo, unLo-n, n);
      m = fmin(hi-gtHi, gtHi-unHi); fvswap(unLo, hi-m+1, m);

      n = lo + unLo - ltLo - 1;
      m = hi - (gtHi - unHi) + 1;

      if (n - lo > hi - m) {
         fpush ( lo, n );
         fpush ( m, hi );
      } else {
         fpush ( m, hi );
         fpush ( lo, n );
      }
   }
}

#undef fmin
#undef fpush
#undef fpop
#undef fswap
#undef fvswap
#undef FALLBACK_QSORT_SMALL_THRESH
#undef FALLBACK_QSORT_STACK_SIZE


/*---------------------------------------------*/
/* Pre:
      nblock > 0
      eclass exists for [0 .. nblock-1]
      ((UChar*)eclass) [0 .. nblock-1] holds block
      ptr exists for [0 .. nblock-1]

   Post:
      ((UChar*)eclass) [0 .. nblock-1] holds block
      All other areas of eclass destroyed
      fmap [0 .. nblock-1] holds sorted order
      bhtab [ 0 .. 2+(nblock/32) ] destroyed
*/

#define       SET_BH(zz)  bhtab[(zz) >> 5] |= (1 << ((zz) & 31))
#define     CLEAR_BH(zz)  bhtab[(zz) >> 5] &= ~(1 << ((zz) & 31))
#define     ISSET_BH(zz)  (bhtab[(zz) >> 5] & (1 << ((zz) & 31)))
#define      WORD_BH(zz)  bhtab[(zz) >> 5]
#define UNALIGNED_BH(zz)  ((zz) & 0x01f)

static
void fallbackSort ( UInt32* fmap, 
                    UInt32* eclass, 
                    UInt32* bhtab,
                    Int32   nblock,
                    Int32   verb )
{
   Int32 ftab[257];
   Int32 ftabCopy[256];
   Int32 H, i, j, k, l, r, cc, cc1;
   Int32 nNotDone;
   Int32 nBhtab;
   UChar* eclass8 = (UChar*)eclass;

   /*--
      Initial 1-char radix sort to generate
      initial fmap and initial BH bits.
   --*/
   if (verb >= 4)
      VPrintf0 ( "        bucket sorting ...\n" );
   for (i = 0; i < 257;    i++) ftab[i] = 0;
   for (i = 0; i < nblock; i++) ftab[eclass8[i]]++;
   for (i = 0; i < 256;    i++) ftabCopy[i] = ftab[i];
   for (i = 1; i < 257;    i++) ftab[i] += ftab[i-1];

   for (i = 0; i < nblock; i++) {
      j = eclass8[i];
      k = ftab[j] - 1;
      ftab[j] = k;
      fmap[k] = i;
   }

   nBhtab = 2 + (nblock / 32);
   for (i = 0; i < nBhtab; i++) bhtab[i] = 0;
   for (i = 0; i < 256; i++) SET_BH(ftab[i]);

   /*--
      Inductively refine the buckets.  Kind-of an
      "exponential radix sort" (!), inspired by the
      Manber-Myers suffix array construction algorithm.
   --*/

   /*-- set sentinel bits for block-end detection --*/
   for (i = 0; i < 32; i++) { 
      SET_BH(nblock + 2*i);
      CLEAR_BH(nblock + 2*i + 1);
   }

   /*-- the log(N) loop --*/
   H = 1;
   while (1) {

      if (verb >= 4) 
         VPrintf1 ( "        depth %6d has ", H );

      j = 0;
      for (i = 0; i < nblock; i++) {
         if (ISSET_BH(i)) j = i;
         k = fmap[i] - H; if (k < 0) k += nblock;
         eclass[k] = j;
      }

      nNotDone = 0;
      r = -1;
      while (1) {

	 /*-- find the next non-singleton bucket --*/
         k = r + 1;
         while (ISSET_BH(k) && UNALIGNED_BH(k)) k++;
         if (ISSET_BH(k)) {
            while (WORD_BH(k) == 0xffffffff) k += 32;
            while (ISSET_BH(k)) k++;
         }
         l = k - 1;
         if (l >= nblock) break;
         while (!ISSET_BH(k) && UNALIGNED_BH(k)) k++;
         if (!ISSET_BH(k)) {
            while (WORD_BH(k) == 0x00000000) k += 32;
            while (!ISSET_BH(k)) k++;
         }
         r = k - 1;
         if (r >= nblock) break;

         /*-- now [l, r] bracket current bucket --*/
         if (r > l) {
            nNotDone += (r - l + 1);
            fallbackQSort3 ( fmap, eclass, l, r );

            /*-- scan bucket and generate header bits-- */
            cc = -1;
            for (i = l; i <= r; i++) {
               cc1 = eclass[fmap[i]];
               if (cc != cc1) { SET_BH(i); cc = cc1; };
            }
         }
      }

      if (verb >= 4) 
         VPrintf1 ( "%6d unresolved strings\n", nNotDone );

      H *= 2;
      if (H > nblock || nNotDone == 0) break;
   }

   /*-- 
      Reconstruct the original block in
      eclass8 [0 .. nblock-1], since the
      previous phase destroyed it.
   --*/
   if (verb >= 4)
      VPrintf0 ( "        reconstructing block ...\n" );
   j = 0;
   for (i = 0; i < nblock; i++) {
      while (ftabCopy[j] == 0) j++;
      ftabCopy[j]--;
      eclass8[fmap[i]] = (UChar)j;
   }
   AssertH ( j < 256, 1005 );
}

#undef       SET_BH
#undef     CLEAR_BH
#undef     ISSET_BH
#undef      WORD_BH
#undef UNALIGNED_BH


/*---------------------------------------------*/
/*--- The main, O(N^2 log(N)) sorting       ---*/
/*--- algorithm.  Faster for "normal"       ---*/
/*--- non-repetitive blocks.                ---*/
/*---------------------------------------------*/

/*---------------------------------------------*/
static
__inline__
Bool mainGtU ( UInt32  i1, 
               UInt32  i2,
               UChar*  block, 
               UInt16* quadrant,
               UInt32  nblock,
               Int32*  budget )
{
   Int32  k;
   UChar  c1, c2;
   UInt16 s1, s2;

   AssertD ( i1 != i2, "mainGtU" );
   /* 1 */
   c1 = block[i1]; c2 = block[i2];
   if (c1 != c2) return (c1 > c2);
   i1++; i2++;
   /* 2 */
   c1 = block[i1]; c2 = block[i2];
   if (c1 != c2) return (c1 > c2);
   i1++; i2++;
   /* 3 */
   c1 = block[i1]; c2 = block[i2];
   if (c1 != c2) return (c1 > c2);
   i1++; i2++;
   /* 4 */
   c1 = block[i1]; c2 = block[i2];
   if (c1 != c2) return (c1 > c2);
   i1++; i2++;
   /* 5 */
   c1 = block[i1]; c2 = block[i2];
   if (c1 != c2) return (c1 > c2);
   i1++; i2++;
   /* 6 */
   c1 = block[i1]; c2 = block[i2];
   if (c1 != c2) return (c1 > c2);
   i1++; i2++;
   /* 7 */
   c1 = block[i1]; c2 = block[i2];
   if (c1 != c2) return (c1 > c2);
   i1++; i2++;
   /* 8 */
   c1 = block[i1]; c2 = block[i2];
   if (c1 != c2) return (c1 > c2);
   i1++; i2++;
   /* 9 */
   c1 = block[i1]; c2 = block[i2];
   if (c1 != c2) return (c1 > c2);
   i1++; i2++;
   /* 10 */
   c1 = block[i1]; c2 = block[i2];
   if (c1 != c2) return (c1 > c2);
   i1++; i2++;
   /* 11 */
   c1 = block[i1]; c2 = block[i2];
   if (c1 != c2) return (c1 > c2);
   i1++; i2++;
   /* 12 */
   c1 = block[i1]; c2 = block[i2];
   if (c1 != c2) return (c1 > c2);
   i1++; i2++;

   k = nblock + 8;

   do {
      /* 1 */
      c1 = block[i1]; c2 = block[i2];
      if (c1 != c2) return (c1 > c2);
      s1 = quadrant[i1]; s2 = quadrant[i2];
      if (s1 != s2) return (s1 > s2);
      i1++; i2++;
      /* 2 */
      c1 = block[i1]; c2 = block[i2];
      if (c1 != c2) return (c1 > c2);
      s1 = quadrant[i1]; s2 = quadrant[i2];
      if (s1 != s2) return (s1 > s2);
      i1++; i2++;
      /* 3 */
      c1 = block[i1]; c2 = block[i2];
      if (c1 != c2) return (c1 > c2);
      s1 = quadrant[i1]; s2 = quadrant[i2];
      if (s1 != s2) return (s1 > s2);
      i1++; i2++;
      /* 4 */
      c1 = block[i1]; c2 = block[i2];
      if (c1 != c2) return (c1 > c2);
      s1 = quadrant[i1]; s2 = quadrant[i2];
      if (s1 != s2) return (s1 > s2);
      i1++; i2++;
      /* 5 */
      c1 = block[i1]; c2 = block[i2];
      if (c1 != c2) return (c1 > c2);
      s1 = quadrant[i1]; s2 = quadrant[i2];
      if (s1 != s2) return (s1 > s2);
      i1++; i2++;
      /* 6 */
      c1 = block[i1]; c2 = block[i2];
      if (c1 != c2) return (c1 > c2);
      s1 = quadrant[i1]; s2 = quadrant[i2];
      if (s1 != s2) return (s1 > s2);
      i1++; i2++;
      /* 7 */
      c1 = block[i1]; c2 = block[i2];
      if (c1 != c2) return (c1 > c2);
      s1 = quadrant[i1]; s2 = quadrant[i2];
      if (s1 != s2) return (s1 > s2);
      i1++; i2++;
      /* 8 */
      c1 = block[i1]; c2 = block[i2];
      if (c1 != c2) return (c1 > c2);
      s1 = quadrant[i1]; s2 = quadrant[i2];
      if (s1 != s2) return (s1 > s2);
      i1++; i2++;

      if (i1 >= nblock) i1 -= nblock;
      if (i2 >= nblock) i2 -= nblock;

      k -= 8;
      (*budget)--;
   }
      while (k >= 0);

   return False;
}


/*---------------------------------------------*/
/*--
   Knuth's increments seem to work better
   than Incerpi-Sedgewick here.  Possibly
   because the number of elems to sort is
   usually small, typically <= 20.
--*/
static
Int32 incs[14] = { 1, 4, 13, 40, 121, 364, 1093, 3280,
                   9841, 29524, 88573, 265720,
                   797161, 2391484 };

static
void mainSimpleSort ( UInt32* ptr,
                      UChar*  block,
                      UInt16* quadrant,
                      Int32   nblock,
                      Int32   lo, 
                      Int32   hi, 
                      Int32   d,
                      Int32*  budget )
{
   Int32 i, j, h, bigN, hp;
   UInt32 v;

   bigN = hi - lo + 1;
   if (bigN < 2) return;

   hp = 0;
   while (incs[hp] < bigN) hp++;
   hp--;

   for (; hp >= 0; hp--) {
      h = incs[hp];

      i = lo + h;
      while (True) {

         /*-- copy 1 --*/
         if (i > hi) break;
         v = ptr[i];
         j = i;
         while ( mainGtU ( 
                    ptr[j-h]+d, v+d, block, quadrant, nblock, budget 
                 ) ) {
            ptr[j] = ptr[j-h];
            j = j - h;
            if (j <= (lo + h - 1)) break;
         }
         ptr[j] = v;
         i++;

         /*-- copy 2 --*/
         if (i > hi) break;
         v = ptr[i];
         j = i;
         while ( mainGtU ( 
                    ptr[j-h]+d, v+d, block, quadrant, nblock, budget 
                 ) ) {
            ptr[j] = ptr[j-h];
            j = j - h;
            if (j <= (lo + h - 1)) break;
         }
         ptr[j] = v;
         i++;

         /*-- copy 3 --*/
         if (i > hi) break;
         v = ptr[i];
         j = i;
         while ( mainGtU ( 
                    ptr[j-h]+d, v+d, block, quadrant, nblock, budget 
                 ) ) {
            ptr[j] = ptr[j-h];
            j = j - h;
            if (j <= (lo + h - 1)) break;
         }
         ptr[j] = v;
         i++;

         if (*budget < 0) return;
      }
   }
}


/*---------------------------------------------*/
/*--
   The following is an implementation of
   an elegant 3-way quicksort for strings,
   described in a paper "Fast Algorithms for
   Sorting and Searching Strings", by Robert
   Sedgewick and Jon L. Bentley.
--*/

#define mswap(zz1, zz2) \
   { Int32 zztmp = zz1; zz1 = zz2; zz2 = zztmp; }

#define mvswap(zzp1, zzp2, zzn)       \
{                                     \
   Int32 yyp1 = (zzp1);               \
   Int32 yyp2 = (zzp2);               \
   Int32 yyn  = (zzn);                \
   while (yyn > 0) {                  \
      mswap(ptr[yyp1], ptr[yyp2]);    \
      yyp1++; yyp2++; yyn--;          \
   }                                  \
}

static 
__inline__
UChar mmed3 ( UChar a, UChar b, UChar c )
{
   UChar t;
   if (a > b) { t = a; a = b; b = t; };
   if (b > c) { 
      b = c;
      if (a > b) b = a;
   }
   return b;
}

#define mmin(a,b) ((a) < (b)) ? (a) : (b)

#define mpush(lz,hz,dz) { stackLo[sp] = lz; \
                          stackHi[sp] = hz; \
                          stackD [sp] = dz; \
                          sp++; }

#define mpop(lz,hz,dz) { sp--;             \
                         lz = stackLo[sp]; \
                         hz = stackHi[sp]; \
                         dz = stackD [sp]; }


#define mnextsize(az) (nextHi[az]-nextLo[az])

#define mnextswap(az,bz)                                        \
   { Int32 tz;                                                  \
     tz = nextLo[az]; nextLo[az] = nextLo[bz]; nextLo[bz] = tz; \
     tz = nextHi[az]; nextHi[az] = nextHi[bz]; nextHi[bz] = tz; \
     tz = nextD [az]; nextD [az] = nextD [bz]; nextD [bz] = tz; }


#define MAIN_QSORT_SMALL_THRESH 20
#define MAIN_QSORT_DEPTH_THRESH (BZ_N_RADIX + BZ_N_QSORT)
#define MAIN_QSORT_STACK_SIZE 100

static
void mainQSort3 ( UInt32* ptr,
                  UChar*  block,
                  UInt16* quadrant,
                  Int32   nblock,
                  Int32   loSt, 
                  Int32   hiSt, 
                  Int32   dSt,
                  Int32*  budget )
{
   Int32 unLo, unHi, ltLo, gtHi, n, m, med;
   Int32 sp, lo, hi, d;

   Int32 stackLo[MAIN_QSORT_STACK_SIZE];
   Int32 stackHi[MAIN_QSORT_STACK_SIZE];
   Int32 stackD [MAIN_QSORT_STACK_SIZE];

   Int32 nextLo[3];
   Int32 nextHi[3];
   Int32 nextD [3];

   sp = 0;
   mpush ( loSt, hiSt, dSt );

   while (sp > 0) {

      AssertH ( sp < MAIN_QSORT_STACK_SIZE - 2, 1001 );

      mpop ( lo, hi, d );
      if (hi - lo < MAIN_QSORT_SMALL_THRESH || 
          d > MAIN_QSORT_DEPTH_THRESH) {
         mainSimpleSort ( ptr, block, quadrant, nblock, lo, hi, d, budget );
         if (*budget < 0) return;
         continue;
      }

      med = (Int32) 
            mmed3 ( block[ptr[ lo         ]+d],
                    block[ptr[ hi         ]+d],
                    block[ptr[ (lo+hi)>>1 ]+d] );

      unLo = ltLo = lo;
      unHi = gtHi = hi;

      while (True) {
         while (True) {
            if (unLo > unHi) break;
            n = ((Int32)block[ptr[unLo]+d]) - med;
            if (n == 0) { 
               mswap(ptr[unLo], ptr[ltLo]); 
               ltLo++; unLo++; continue; 
            };
            if (n >  0) break;
            unLo++;
         }
         while (True) {
            if (unLo > unHi) break;
            n = ((Int32)block[ptr[unHi]+d]) - med;
            if (n == 0) { 
               mswap(ptr[unHi], ptr[gtHi]); 
               gtHi--; unHi--; continue; 
            };
            if (n <  0) break;
            unHi--;
         }
         if (unLo > unHi) break;
         mswap(ptr[unLo], ptr[unHi]); unLo++; unHi--;
      }

      AssertD ( unHi == unLo-1, "mainQSort3(2)" );

      if (gtHi < ltLo) {
         mpush(lo, hi, d+1 );
         continue;
      }

      n = mmin(ltLo-lo, unLo-ltLo); mvswap(lo, unLo-n, n);
      m = mmin(hi-gtHi, gtHi-unHi); mvswap(unLo, hi-m+1, m);

      n = lo + unLo - ltLo - 1;
      m = hi - (gtHi - unHi) + 1;

      nextLo[0] = lo;  nextHi[0] = n;   nextD[0] = d;
      nextLo[1] = m;   nextHi[1] = hi;  nextD[1] = d;
      nextLo[2] = n+1; nextHi[2] = m-1; nextD[2] = d+1;

      if (mnextsize(0) < mnextsize(1)) mnextswap(0,1);
      if (mnextsize(1) < mnextsize(2)) mnextswap(1,2);
      if (mnextsize(0) < mnextsize(1)) mnextswap(0,1);

      AssertD (mnextsize(0) >= mnextsize(1), "mainQSort3(8)" );
      AssertD (mnextsize(1) >= mnextsize(2), "mainQSort3(9)" );

      mpush (nextLo[0], nextHi[0], nextD[0]);
      mpush (nextLo[1], nextHi[1], nextD[1]);
      mpush (nextLo[2], nextHi[2], nextD[2]);
   }
}

#undef mswap
#undef mvswap
#undef mpush
#undef mpop
#undef mmin
#undef mnextsize
#undef mnextswap
#undef MAIN_QSORT_SMALL_THRESH
#undef MAIN_QSORT_DEPTH_THRESH
#undef MAIN_QSORT_STACK_SIZE


/*---------------------------------------------*/
/* Pre:
      nblock > N_OVERSHOOT
      block32 exists for [0 .. nblock-1 +N_OVERSHOOT]
      ((UChar*)block32) [0 .. nblock-1] holds block
      ptr exists for [0 .. nblock-1]

   Post:
      ((UChar*)block32) [0 .. nblock-1] holds block
      All other areas of block32 destroyed
      ftab [0 .. 65536 ] destroyed
      ptr [0 .. nblock-1] holds sorted order
      if (*budget < 0), sorting was abandoned
*/

#define BIGFREQ(b) (ftab[((b)+1) << 8] - ftab[(b) << 8])
#define SETMASK (1 << 21)
#define CLEARMASK (~(SETMASK))

static
void mainSort ( UInt32* ptr, 
                UChar*  block,
                UInt16* quadrant, 
                UInt32* ftab,
                Int32   nblock,
                Int32   verb,
                Int32*  budget )
{
   Int32  i, j, k, ss, sb;
   Int32  runningOrder[256];
   Bool   bigDone[256];
   Int32  copyStart[256];
   Int32  copyEnd  [256];
   UChar  c1;
   Int32  numQSorted;
   UInt16 s;
   if (verb >= 4) VPrintf0 ( "        main sort initialise ...\n" );

   /*-- set up the 2-byte frequency table --*/
   for (i = 65536; i >= 0; i--) ftab[i] = 0;

   j = block[0] << 8;
   i = nblock-1;
   for (; i >= 3; i -= 4) {
      quadrant[i] = 0;
      j = (j >> 8) | ( ((UInt16)block[i]) << 8);
      ftab[j]++;
      quadrant[i-1] = 0;
      j = (j >> 8) | ( ((UInt16)block[i-1]) << 8);
      ftab[j]++;
      quadrant[i-2] = 0;
      j = (j >> 8) | ( ((UInt16)block[i-2]) << 8);
      ftab[j]++;
      quadrant[i-3] = 0;
      j = (j >> 8) | ( ((UInt16)block[i-3]) << 8);
      ftab[j]++;
   }
   for (; i >= 0; i--) {
      quadrant[i] = 0;
      j = (j >> 8) | ( ((UInt16)block[i]) << 8);
      ftab[j]++;
   }

   /*-- (emphasises close relationship of block & quadrant) --*/
   for (i = 0; i < BZ_N_OVERSHOOT; i++) {
      block   [nblock+i] = block[i];
      quadrant[nblock+i] = 0;
   }

   if (verb >= 4) VPrintf0 ( "        bucket sorting ...\n" );

   /*-- Complete the initial radix sort --*/
   for (i = 1; i <= 65536; i++) ftab[i] += ftab[i-1];

   s = block[0] << 8;
   i = nblock-1;
   for (; i >= 3; i -= 4) {
      s = (s >> 8) | (block[i] << 8);
      j = ftab[s] -1;
      ftab[s] = j;
      ptr[j] = i;
      s = (s >> 8) | (block[i-1] << 8);
      j = ftab[s] -1;
      ftab[s] = j;
      ptr[j] = i-1;
      s = (s >> 8) | (block[i-2] << 8);
      j = ftab[s] -1;
      ftab[s] = j;
      ptr[j] = i-2;
      s = (s >> 8) | (block[i-3] << 8);
      j = ftab[s] -1;
      ftab[s] = j;
      ptr[j] = i-3;
   }
   for (; i >= 0; i--) {
      s = (s >> 8) | (block[i] << 8);
      j = ftab[s] -1;
      ftab[s] = j;
      ptr[j] = i;
   }

   /*--
      Now ftab contains the first loc of every small bucket.
      Calculate the running order, from smallest to largest
      big bucket.
   --*/
   for (i = 0; i <= 255; i++) {
      bigDone     [i] = False;
      runningOrder[i] = i;
   }

   {
      Int32 vv;
      Int32 h = 1;
      do h = 3 * h + 1; while (h <= 256);
      do {
         h = h / 3;
         for (i = h; i <= 255; i++) {
            vv = runningOrder[i];
            j = i;
            while ( BIGFREQ(runningOrder[j-h]) > BIGFREQ(vv) ) {
               runningOrder[j] = runningOrder[j-h];
               j = j - h;
               if (j <= (h - 1)) goto zero;
            }
            zero:
            runningOrder[j] = vv;
         }
      } while (h != 1);
   }

   /*--
      The main sorting loop.
   --*/

   numQSorted = 0;

   for (i = 0; i <= 255; i++) {

      /*--
         Process big buckets, starting with the least full.
         Basically this is a 3-step process in which we call
         mainQSort3 to sort the small buckets [ss, j], but
         also make a big effort to avoid the calls if we can.
      --*/
      ss = runningOrder[i];

      /*--
         Step 1:
         Complete the big bucket [ss] by quicksorting
         any unsorted small buckets [ss, j], for j != ss.  
         Hopefully previous pointer-scanning phases have already
         completed many of the small buckets [ss, j], so
         we don't have to sort them at all.
      --*/
      for (j = 0; j <= 255; j++) {
         if (j != ss) {
            sb = (ss << 8) + j;
            if ( ! (ftab[sb] & SETMASK) ) {
               Int32 lo = ftab[sb]   & CLEARMASK;
               Int32 hi = (ftab[sb+1] & CLEARMASK) - 1;
               if (hi > lo) {
                  if (verb >= 4)
                     VPrintf4 ( "        qsort [0x%x, 0x%x]   "
                                "done %d   this %d\n",
                                ss, j, numQSorted, hi - lo + 1 );
                  mainQSort3 ( 
                     ptr, block, quadrant, nblock, 
                     lo, hi, BZ_N_RADIX, budget 
                  );   
                  numQSorted += (hi - lo + 1);
                  if (*budget < 0) return;
               }
            }
            ftab[sb] |= SETMASK;
         }
      }

      AssertH ( !bigDone[ss], 1006 );

      /*--
         Step 2:
         Now scan this big bucket [ss] so as to synthesise the
         sorted order for small buckets [t, ss] for all t,
         including, magically, the bucket [ss,ss] too.
         This will avoid doing Real Work in subsequent Step 1's.
      --*/
      {
         for (j = 0; j <= 255; j++) {
            copyStart[j] =  ftab[(j << 8) + ss]     & CLEARMASK;
            copyEnd  [j] = (ftab[(j << 8) + ss + 1] & CLEARMASK) - 1;
         }
         for (j = ftab[ss << 8] & CLEARMASK; j < copyStart[ss]; j++) {
            k = ptr[j]-1; if (k < 0) k += nblock;
            c1 = block[k];
            if (!bigDone[c1])
               ptr[ copyStart[c1]++ ] = k;
         }
         for (j = (ftab[(ss+1) << 8] & CLEARMASK) - 1; j > copyEnd[ss]; j--) {
            k = ptr[j]-1; if (k < 0) k += nblock;
            c1 = block[k];
            if (!bigDone[c1]) 
               ptr[ copyEnd[c1]-- ] = k;
         }
      }

      AssertH ( (copyStart[ss]-1 == copyEnd[ss])
                || 
                /* Extremely rare case missing in bzip2-1.0.0 and 1.0.1.
                   Necessity for this case is demonstrated by compressing 
                   a sequence of approximately 48.5 million of character 
                   251; 1.0.0/1.0.1 will then die here. */
                (copyStart[ss] == 0 && copyEnd[ss] == nblock-1),
                1007 )

      for (j = 0; j <= 255; j++) ftab[(j << 8) + ss] |= SETMASK;

      /*--
         Step 3:
         The [ss] big bucket is now done.  Record this fact,
         and update the quadrant descriptors.  Remember to
         update quadrants in the overshoot area too, if
         necessary.  The "if (i < 255)" test merely skips
         this updating for the last bucket processed, since
         updating for the last bucket is pointless.

         The quadrant array provides a way to incrementally
         cache sort orderings, as they appear, so as to 
         make subsequent comparisons in fullGtU() complete
         faster.  For repetitive blocks this makes a big
         difference (but not big enough to be able to avoid
         the fallback sorting mechanism, exponential radix sort).

         The precise meaning is: at all times:

            for 0 <= i < nblock and 0 <= j <= nblock

            if block[i] != block[j], 

               then the relative values of quadrant[i] and 
                    quadrant[j] are meaningless.

               else {
                  if quadrant[i] < quadrant[j]
                     then the string starting at i lexicographically
                     precedes the string starting at j

                  else if quadrant[i] > quadrant[j]
                     then the string starting at j lexicographically
                     precedes the string starting at i

                  else
                     the relative ordering of the strings starting
                     at i and j has not yet been determined.
               }
      --*/
      bigDone[ss] = True;

      if (i < 255) {
         Int32 bbStart  = ftab[ss << 8] & CLEARMASK;
         Int32 bbSize   = (ftab[(ss+1) << 8] & CLEARMASK) - bbStart;
         Int32 shifts   = 0;

         while ((bbSize >> shifts) > 65534) shifts++;

         for (j = bbSize-1; j >= 0; j--) {
            Int32 a2update     = ptr[bbStart + j];
            UInt16 qVal        = (UInt16)(j >> shifts);
            quadrant[a2update] = qVal;
            if (a2update < BZ_N_OVERSHOOT)
               quadrant[a2update + nblock] = qVal;
         }
         AssertH ( ((bbSize-1) >> shifts) <= 65535, 1002 );
      }

   }

   if (verb >= 4)
      VPrintf3 ( "        %d pointers, %d sorted, %d scanned\n",
                 nblock, numQSorted, nblock - numQSorted );
}

#undef BIGFREQ
#undef SETMASK
#undef CLEARMASK


/*---------------------------------------------*/
/* Pre:
      nblock > 0
      arr2 exists for [0 .. nblock-1 +N_OVERSHOOT]
      ((UChar*)arr2)  [0 .. nblock-1] holds block
      arr1 exists for [0 .. nblock-1]

   Post:
      ((UChar*)arr2) [0 .. nblock-1] holds block
      All other areas of block destroyed
      ftab [ 0 .. 65536 ] destroyed
      arr1 [0 .. nblock-1] holds sorted order
*/
void BZ2_blockSort ( EState* s )
{
   UInt32* ptr    = s->ptr; 
   UChar*  block  = s->block;
   UInt32* ftab   = s->ftab;
   Int32   nblock = s->nblock;
   Int32   verb   = s->verbosity;
   Int32   wfact  = s->workFactor;
   UInt16* quadrant;
   Int32   budget;
   Int32   budgetInit;
   Int32   i;

   if (nblock < 10000) {
      fallbackSort ( s->arr1, s->arr2, ftab, nblock, verb );
   } else {
      /* Calculate the location for quadrant, remembering to get
         the alignment right.  Assumes that &(block[0]) is at least
         2-byte aligned -- this should be ok since block is really
         the first section of arr2.
      */
      i = nblock+BZ_N_OVERSHOOT;
      if (i & 1) i++;
      quadrant = (UInt16*)(&(block[i]));

      /* (wfact-1) / 3 puts the default-factor-30
         transition point at very roughly the same place as 
         with v0.1 and v0.9.0.  
         Not that it particularly matters any more, since the
         resulting compressed stream is now the same regardless
         of whether or not we use the main sort or fallback sort.
      */
      if (wfact < 1  ) wfact = 1;
      if (wfact > 100) wfact = 100;
      budgetInit = nblock * ((wfact-1) / 3);
      budget = budgetInit;

      mainSort ( ptr, block, quadrant, ftab, nblock, verb, &budget );
      if (verb >= 3) 
         VPrintf3 ( "      %d work, %d block, ratio %5.2f\n",
                    budgetInit - budget,
                    nblock, 
                    (float)(budgetInit - budget) /
                    (float)(nblock==0 ? 1 : nblock) ); 
      if (budget < 0) {
         if (verb >= 2) 
            VPrintf0 ( "    too repetitive; using fallback"
                       " sorting algorithm\n" );
         fallbackSort ( s->arr1, s->arr2, ftab, nblock, verb );
      }
   }

   s->origPtr = -1;
   for (i = 0; i < s->nblock; i++)
      if (ptr[i] == 0)
         { s->origPtr = i; break; };

   AssertH( s->origPtr != -1, 1003 );
}


/*-------------------------------------------------------------*/
/*--- end                                       blocksort.c ---*/
/*-------------------------------------------------------------*/


================================================
FILE: external/bzip2/bzlib.c
================================================

/*-------------------------------------------------------------*/
/*--- Library top-level functions.                          ---*/
/*---                                               bzlib.c ---*/
/*-------------------------------------------------------------*/

/* ------------------------------------------------------------------
   This file is part of bzip2/libbzip2, a program and library for
   lossless, block-sorting data compression.

   bzip2/libbzip2 version 1.0.6 of 6 September 2010
   Copyright (C) 1996-2010 Julian Seward <jseward@bzip.org>

   Please read the WARNING, DISCLAIMER and PATENTS sections in the 
   README file.

   This program is released under the terms of the license contained
   in the file LICENSE.
   ------------------------------------------------------------------ */

/* CHANGES
   0.9.0    -- original version.
   0.9.0a/b -- no changes in this file.
   0.9.0c   -- made zero-length BZ_FLUSH work correctly in bzCompress().
     fixed bzWrite/bzRead to ignore zero-length requests.
     fixed bzread to correctly handle read requests after EOF.
     wrong parameter order in call to bzDecompressInit in
     bzBuffToBuffDecompress.  Fixed.
*/

#include "bzlib_private.h"


/*---------------------------------------------------*/
/*--- Compression stuff                           ---*/
/*---------------------------------------------------*/


/*---------------------------------------------------*/
#ifndef BZ_NO_STDIO
void BZ2_bz__AssertH__fail ( int errcode )
{
   fprintf(stderr, 
      "\n\nbzip2/libbzip2: internal error number %d.\n"
      "This is a bug in bzip2/libbzip2, %s.\n"
      "Please report it to me at: jseward@bzip.org.  If this happened\n"
      "when you were using some program which uses libbzip2 as a\n"
      "component, you should also report this bug to the author(s)\n"
      "of that program.  Please make an effort to report this bug;\n"
      "timely and accurate bug reports eventually lead to higher\n"
      "quality software.  Thanks.  Julian Seward, 10 December 2007.\n\n",
      errcode,
      BZ2_bzlibVersion()
   );

   if (errcode == 1007) {
   fprintf(stderr,
      "\n*** A special note about internal error number 1007 ***\n"
      "\n"
      "Experience suggests that a common cause of i.e. 1007\n"
      "is unreliable memory or other hardware.  The 1007 assertion\n"
      "just happens to cross-check the results of huge numbers of\n"
      "memory reads/writes, and so acts (unintendedly) as a stress\n"
      "test of your memory system.\n"
      "\n"
      "I suggest the following: try compressing the file again,\n"
      "possibly monitoring progress in detail with the -vv flag.\n"
      "\n"
      "* If the error cannot be reproduced, and/or happens at different\n"
      "  points in compression, you may have a flaky memory system.\n"
      "  Try a memory-test program.  I have used Memtest86\n"
      "  (www.memtest86.com).  At the time of writing it is free (GPLd).\n"
      "  Memtest86 tests memory much more thorougly than your BIOSs\n"
      "  power-on test, and may find failures that the BIOS doesn't.\n"
      "\n"
      "* If the error can be repeatably reproduced, this is a bug in\n"
      "  bzip2, and I would very much like to hear about it.  Please\n"
      "  let me know, and, ideally, save a copy of the file causing the\n"
      "  problem -- without which I will be unable to investigate it.\n"
      "\n"
   );
   }

   exit(3);
}
#endif


/*---------------------------------------------------*/
static
int bz_config_ok ( void )
{
   if (sizeof(int)   != 4) return 0;
   if (sizeof(short) != 2) return 0;
   if (sizeof(char)  != 1) return 0;
   return 1;
}


/*---------------------------------------------------*/
static
void* default_bzalloc ( void* opaque, Int32 items, Int32 size )
{
   void* v = malloc ( items * size );
   return v;
}

static
void default_bzfree ( void* opaque, void* addr )
{
   if (addr != NULL) free ( addr );
}


/*---------------------------------------------------*/
static
void prepare_new_block ( EState* s )
{
   Int32 i;
   s->nblock = 0;
   s->numZ = 0;
   s->state_out_pos = 0;
   BZ_INITIALISE_CRC ( s->blockCRC );
   for (i = 0; i < 256; i++) s->inUse[i] = False;
   s->blockNo++;
}


/*---------------------------------------------------*/
static
void init_RL ( EState* s )
{
   s->state_in_ch  = 256;
   s->state_in_len = 0;
}


static
Bool isempty_RL ( EState* s )
{
   if (s->state_in_ch < 256 && s->state_in_len > 0)
      return False; else
      return True;
}


/*---------------------------------------------------*/
int BZ_API(BZ2_bzCompressInit) 
                    ( bz_stream* strm, 
                     int        blockSize100k,
                     int        verbosity,
                     int        workFactor )
{
   Int32   n;
   EState* s;

   if (!bz_config_ok()) return BZ_CONFIG_ERROR;

   if (strm == NULL || 
       blockSize100k < 1 || blockSize100k > 9 ||
       workFactor < 0 || workFactor > 250)
     return BZ_PARAM_ERROR;

   if (workFactor == 0) workFactor = 30;
   if (strm->bzalloc == NULL) strm->bzalloc = default_bzalloc;
   if (strm->bzfree == NULL) strm->bzfree = default_bzfree;

   s = BZALLOC( sizeof(EState) );
   if (s == NULL) return BZ_MEM_ERROR;
   s->strm = strm;

   s->arr1 = NULL;
   s->arr2 = NULL;
   s->ftab = NULL;

   n       = 100000 * blockSize100k;
   s->arr1 = BZALLOC( n                  * sizeof(UInt32) );
   s->arr2 = BZALLOC( (n+BZ_N_OVERSHOOT) * sizeof(UInt32) );
   s->ftab = BZALLOC( 65537              * sizeof(UInt32) );

   if (s->arr1 == NULL || s->arr2 == NULL || s->ftab == NULL) {
      if (s->arr1 != NULL) BZFREE(s->arr1);
      if (s->arr2 != NULL) BZFREE(s->arr2);
      if (s->ftab != NULL) BZFREE(s->ftab);
      if (s       != NULL) BZFREE(s);
      return BZ_MEM_ERROR;
   }

   s->blockNo           = 0;
   s->state             = BZ_S_INPUT;
   s->mode              = BZ_M_RUNNING;
   s->combinedCRC       = 0;
   s->blockSize100k     = blockSize100k;
   s->nblockMAX         = 100000 * blockSize100k - 19;
   s->verbosity         = verbosity;
   s->workFactor        = workFactor;

   s->block             = (UChar*)s->arr2;
   s->mtfv              = (UInt16*)s->arr1;
   s->zbits             = NULL;
   s->ptr               = (UInt32*)s->arr1;

   strm->state          = s;
   strm->total_in_lo32  = 0;
   strm->total_in_hi32  = 0;
   strm->total_out_lo32 = 0;
   strm->total_out_hi32 = 0;
   init_RL ( s );
   prepare_new_block ( s );
   return BZ_OK;
}


/*---------------------------------------------------*/
static
void add_pair_to_block ( EState* s )
{
   Int32 i;
   UChar ch = (UChar)(s->state_in_ch);
   for (i = 0; i < s->state_in_len; i++) {
      BZ_UPDATE_CRC( s->blockCRC, ch );
   }
   s->inUse[s->state_in_ch] = True;
   switch (s->state_in_len) {
      case 1:
         s->block[s->nblock] = (UChar)ch; s->nblock++;
         break;
      case 2:
         s->block[s->nblock] = (UChar)ch; s->nblock++;
         s->block[s->nblock] = (UChar)ch; s->nblock++;
         break;
      case 3:
         s->block[s->nblock] = (UChar)ch; s->nblock++;
         s->block[s->nblock] = (UChar)ch; s->nblock++;
         s->block[s->nblock] = (UChar)ch; s->nblock++;
         break;
      default:
         s->inUse[s->state_in_len-4] = True;
         s->block[s->nblock] = (UChar)ch; s->nblock++;
         s->block[s->nblock] = (UChar)ch; s->nblock++;
         s->block[s->nblock] = (UChar)ch; s->nblock++;
         s->block[s->nblock] = (UChar)ch; s->nblock++;
         s->block[s->nblock] = ((UChar)(s->state_in_len-4));
         s->nblock++;
         break;
   }
}


/*---------------------------------------------------*/
static
void flush_RL ( EState* s )
{
   if (s->state_in_ch < 256) add_pair_to_block ( s );
   init_RL ( s );
}


/*---------------------------------------------------*/
#define ADD_CHAR_TO_BLOCK(zs,zchh0)               \
{                                                 \
   UInt32 zchh = (UInt32)(zchh0);                 \
   /*-- fast track the common case --*/           \
   if (zchh != zs->state_in_ch &&                 \
       zs->state_in_len == 1) {                   \
      UChar ch = (UChar)(zs->state_in_ch);        \
      BZ_UPDATE_CRC( zs->blockCRC, ch );          \
      zs->inUse[zs->state_in_ch] = True;          \
      zs->block[zs->nblock] = (UChar)ch;          \
      zs->nblock++;                               \
      zs->state_in_ch = zchh;                     \
   }                                              \
   else                                           \
   /*-- general, uncommon cases --*/              \
   if (zchh != zs->state_in_ch ||                 \
      zs->state_in_len == 255) {                  \
      if (zs->state_in_ch < 256)                  \
         add_pair_to_block ( zs );                \
      zs->state_in_ch = zchh;                     \
      zs->state_in_len = 1;                       \
   } else {                                       \
      zs->state_in_len++;                         \
   }                                              \
}


/*---------------------------------------------------*/
static
Bool copy_input_until_stop ( EState* s )
{
   Bool progress_in = False;

   if (s->mode == BZ_M_RUNNING) {

      /*-- fast track the common case --*/
      while (True) {
         /*-- block full? --*/
         if (s->nblock >= s->nblockMAX) break;
         /*-- no input? --*/
         if (s->strm->avail_in == 0) break;
         progress_in = True;
         ADD_CHAR_TO_BLOCK ( s, (UInt32)(*((UChar*)(s->strm->next_in))) ); 
         s->strm->next_in++;
         s->strm->avail_in--;
         s->strm->total_in_lo32++;
         if (s->strm->total_in_lo32 == 0) s->strm->total_in_hi32++;
      }

   } else {

      /*-- general, uncommon case --*/
      while (True) {
         /*-- block full? --*/
         if (s->nblock >= s->nblockMAX) break;
         /*-- no input? --*/
         if (s->strm->avail_in == 0) break;
         /*-- flush/finish end? --*/
         if (s->avail_in_expect == 0) break;
         progress_in = True;
         ADD_CHAR_TO_BLOCK ( s, (UInt32)(*((UChar*)(s->strm->next_in))) ); 
         s->strm->next_in++;
         s->strm->avail_in--;
         s->strm->total_in_lo32++;
         if (s->strm->total_in_lo32 == 0) s->strm->total_in_hi32++;
         s->avail_in_expect--;
      }
   }
   return progress_in;
}


/*---------------------------------------------------*/
static
Bool copy_output_until_stop ( EState* s )
{
   Bool progress_out = False;

   while (True) {

      /*-- no output space? --*/
      if (s->strm->avail_out == 0) break;

      /*-- block done? --*/
      if (s->state_out_pos >= s->numZ) break;

      progress_out = True;
      *(s->strm->next_out) = s->zbits[s->state_out_pos];
      s->state_out_pos++;
      s->strm->avail_out--;
      s->strm->next_out++;
      s->strm->total_out_lo32++;
      if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++;
   }

   return progress_out;
}


/*---------------------------------------------------*/
static
Bool handle_compress ( bz_stream* strm )
{
   Bool progress_in  = False;
   Bool progress_out = False;
   EState* s = strm->state;
   
   while (True) {

      if (s->state == BZ_S_OUTPUT) {
         progress_out |= copy_output_until_stop ( s );
         if (s->state_out_pos < s->numZ) break;
         if (s->mode == BZ_M_FINISHING && 
             s->avail_in_expect == 0 &&
             isempty_RL(s)) break;
         prepare_new_block ( s );
         s->state = BZ_S_INPUT;
         if (s->mode == BZ_M_FLUSHING && 
             s->avail_in_expect == 0 &&
             isempty_RL(s)) break;
      }

      if (s->state == BZ_S_INPUT) {
         progress_in |= copy_input_until_stop ( s );
         if (s->mode != BZ_M_RUNNING && s->avail_in_expect == 0) {
            flush_RL ( s );
            BZ2_compressBlock ( s, (Bool)(s->mode == BZ_M_FINISHING) );
            s->state = BZ_S_OUTPUT;
         }
         else
         if (s->nblock >= s->nblockMAX) {
            BZ2_compressBlock ( s, False );
            s->state = BZ_S_OUTPUT;
         }
         else
         if (s->strm->avail_in == 0) {
            break;
         }
      }

   }

   return progress_in || progress_out;
}


/*---------------------------------------------------*/
int BZ_API(BZ2_bzCompress) ( bz_stream *strm, int action )
{
   Bool progress;
   EState* s;
   if (strm == NULL) return BZ_PARAM_ERROR;
   s = strm->state;
   if (s == NULL) return BZ_PARAM_ERROR;
   if (s->strm != strm) return BZ_PARAM_ERROR;

   preswitch:
   switch (s->mode) {

      case BZ_M_IDLE:
         return BZ_SEQUENCE_ERROR;

      case BZ_M_RUNNING:
         if (action == BZ_RUN) {
            progress = handle_compress ( strm );
            return progress ? BZ_RUN_OK : BZ_PARAM_ERROR;
         } 
         else
	 if (action == BZ_FLUSH) {
            s->avail_in_expect = strm->avail_in;
            s->mode = BZ_M_FLUSHING;
            goto preswitch;
         }
         else
         if (action == BZ_FINISH) {
            s->avail_in_expect = strm->avail_in;
            s->mode = BZ_M_FINISHING;
            goto preswitch;
         }
         else 
            return BZ_PARAM_ERROR;

      case BZ_M_FLUSHING:
         if (action != BZ_FLUSH) return BZ_SEQUENCE_ERROR;
         if (s->avail_in_expect != s->strm->avail_in) 
            return BZ_SEQUENCE_ERROR;
         progress = handle_compress ( strm );
         if (s->avail_in_expect > 0 || !isempty_RL(s) ||
             s->state_out_pos < s->numZ) return BZ_FLUSH_OK;
         s->mode = BZ_M_RUNNING;
         return BZ_RUN_OK;

      case BZ_M_FINISHING:
         if (action != BZ_FINISH) return BZ_SEQUENCE_ERROR;
         if (s->avail_in_expect != s->strm->avail_in) 
            return BZ_SEQUENCE_ERROR;
         progress = handle_compress ( strm );
         if (!progress) return BZ_SEQUENCE_ERROR;
         if (s->avail_in_expect > 0 || !isempty_RL(s) ||
             s->state_out_pos < s->numZ) return BZ_FINISH_OK;
         s->mode = BZ_M_IDLE;
         return BZ_STREAM_END;
   }
   return BZ_OK; /*--not reached--*/
}


/*---------------------------------------------------*/
int BZ_API(BZ2_bzCompressEnd)  ( bz_stream *strm )
{
   EState* s;
   if (strm == NULL) return BZ_PARAM_ERROR;
   s = strm->state;
   if (s == NULL) return BZ_PARAM_ERROR;
   if (s->strm != strm) return BZ_PARAM_ERROR;

   if (s->arr1 != NULL) BZFREE(s->arr1);
   if (s->arr2 != NULL) BZFREE(s->arr2);
   if (s->ftab != NULL) BZFREE(s->ftab);
   BZFREE(strm->state);

   strm->state = NULL;   

   return BZ_OK;
}


/*---------------------------------------------------*/
/*--- Decompression stuff                         ---*/
/*---------------------------------------------------*/

/*---------------------------------------------------*/
int BZ_API(BZ2_bzDecompressInit) 
                     ( bz_stream* strm, 
                       int        verbosity,
                       int        small )
{
   DState* s;

   if (!bz_config_ok()) return BZ_CONFIG_ERROR;

   if (strm == NULL) return BZ_PARAM_ERROR;
   if (small != 0 && small != 1) return BZ_PARAM_ERROR;
   if (verbosity < 0 || verbosity > 4) return BZ_PARAM_ERROR;

   if (strm->bzalloc == NULL) strm->bzalloc = default_bzalloc;
   if (strm->bzfree == NULL) strm->bzfree = default_bzfree;

   s = BZALLOC( sizeof(DState) );
   if (s == NULL) return BZ_MEM_ERROR;
   s->strm                  = strm;
   strm->state              = s;
   s->state                 = BZ_X_MAGIC_1;
   s->bsLive                = 0;
   s->bsBuff                = 0;
   s->calculatedCombinedCRC = 0;
   strm->total_in_lo32      = 0;
   strm->total_in_hi32      = 0;
   strm->total_out_lo32     = 0;
   strm->total_out_hi32     = 0;
   s->smallDecompress       = (Bool)small;
   s->ll4                   = NULL;
   s->ll16                  = NULL;
   s->tt                    = NULL;
   s->currBlockNo           = 0;
   s->verbosity             = verbosity;

   return BZ_OK;
}


/*---------------------------------------------------*/
/* Return  True iff data corruption is discovered.
   Returns False if there is no problem.
*/
static
Bool unRLE_obuf_to_output_FAST ( DState* s )
{
   UChar k1;

   if (s->blockRandomised) {

      while (True) {
         /* try to finish existing run */
         while (True) {
            if (s->strm->avail_out == 0) return False;
            if (s->state_out_len == 0) break;
            *( (UChar*)(s->strm->next_out) ) = s->state_out_ch;
            BZ_UPDATE_CRC ( s->calculatedBlockCRC, s->state_out_ch );
            s->state_out_len--;
            s->strm->next_out++;
            s->strm->avail_out--;
            s->strm->total_out_lo32++;
            if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++;
         }

         /* can a new run be started? */
         if (s->nblock_used == s->save_nblock+1) return False;
               
         /* Only caused by corrupt data stream? */
         if (s->nblock_used > s->save_nblock+1)
            return True;
   
         s->state_out_len = 1;
         s->state_out_ch = s->k0;
         BZ_GET_FAST(k1); BZ_RAND_UPD_MASK; 
         k1 ^= BZ_RAND_MASK; s->nblock_used++;
         if (s->nblock_used == s->save_nblock+1) continue;
         if (k1 != s->k0) { s->k0 = k1; continue; };
   
         s->state_out_len = 2;
         BZ_GET_FAST(k1); BZ_RAND_UPD_MASK; 
         k1 ^= BZ_RAND_MASK; s->nblock_used++;
         if (s->nblock_used == s->save_nblock+1) continue;
         if (k1 != s->k0) { s->k0 = k1; continue; };
   
         s->state_out_len = 3;
         BZ_GET_FAST(k1); BZ_RAND_UPD_MASK; 
         k1 ^= BZ_RAND_MASK; s->nblock_used++;
         if (s->nblock_used == s->save_nblock+1) continue;
         if (k1 != s->k0) { s->k0 = k1; continue; };
   
         BZ_GET_FAST(k1); BZ_RAND_UPD_MASK; 
         k1 ^= BZ_RAND_MASK; s->nblock_used++;
         s->state_out_len = ((Int32)k1) + 4;
         BZ_GET_FAST(s->k0); BZ_RAND_UPD_MASK; 
         s->k0 ^= BZ_RAND_MASK; s->nblock_used++;
      }

   } else {

      /* restore */
      UInt32        c_calculatedBlockCRC = s->calculatedBlockCRC;
      UChar         c_state_out_ch       = s->state_out_ch;
      Int32         c_state_out_len      = s->state_out_len;
      Int32         c_nblock_used        = s->nblock_used;
      Int32         c_k0                 = s->k0;
      UInt32*       c_tt                 = s->tt;
      UInt32        c_tPos               = s->tPos;
      char*         cs_next_out          = s->strm->next_out;
      unsigned int  cs_avail_out         = s->strm->avail_out;
      Int32         ro_blockSize100k     = s->blockSize100k;
      /* end restore */

      UInt32       avail_out_INIT = cs_avail_out;
      Int32        s_save_nblockPP = s->save_nblock+1;
      unsigned int total_out_lo32_old;

      while (True) {

         /* try to finish existing run */
         if (c_state_out_len > 0) {
            while (True) {
               if (cs_avail_out == 0) goto return_notr;
               if (c_state_out_len == 1) break;
               *( (UChar*)(cs_next_out) ) = c_state_out_ch;
               BZ_UPDATE_CRC ( c_calculatedBlockCRC, c_state_out_ch );
               c_state_out_len--;
               cs_next_out++;
               cs_avail_out--;
            }
            s_state_out_len_eq_one:
            {
               if (cs_avail_out == 0) { 
                  c_state_out_len = 1; goto return_notr;
               };
               *( (UChar*)(cs_next_out) ) = c_state_out_ch;
               BZ_UPDATE_CRC ( c_calculatedBlockCRC, c_state_out_ch );
               cs_next_out++;
               cs_avail_out--;
            }
         }   
         /* Only caused by corrupt data stream? */
         if (c_nblock_used > s_save_nblockPP)
            return True;

         /* can a new run be started? */
         if (c_nblock_used == s_save_nblockPP) {
            c_state_out_len = 0; goto return_notr;
         };   
         c_state_out_ch = c_k0;
         BZ_GET_FAST_C(k1); c_nblock_used++;
         if (k1 != c_k0) { 
            c_k0 = k1; goto s_state_out_len_eq_one; 
         };
         if (c_nblock_used == s_save_nblockPP) 
            goto s_state_out_len_eq_one;
   
         c_state_out_len = 2;
         BZ_GET_FAST_C(k1); c_nblock_used++;
         if (c_nblock_used == s_save_nblockPP) continue;
         if (k1 != c_k0) { c_k0 = k1; continue; };
   
         c_state_out_len = 3;
         BZ_GET_FAST_C(k1); c_nblock_used++;
         if (c_nblock_used == s_save_nblockPP) continue;
         if (k1 != c_k0) { c_k0 = k1; continue; };
   
         BZ_GET_FAST_C(k1); c_nblock_used++;
         c_state_out_len = ((Int32)k1) + 4;
         BZ_GET_FAST_C(c_k0); c_nblock_used++;
      }

      return_notr:
      total_out_lo32_old = s->strm->total_out_lo32;
      s->strm->total_out_lo32 += (avail_out_INIT - cs_avail_out);
      if (s->strm->total_out_lo32 < total_out_lo32_old)
         s->strm->total_out_hi32++;

      /* save */
      s->calculatedBlockCRC = c_calculatedBlockCRC;
      s->state_out_ch       = c_state_out_ch;
      s->state_out_len      = c_state_out_len;
      s->nblock_used        = c_nblock_used;
      s->k0                 = c_k0;
      s->tt                 = c_tt;
      s->tPos               = c_tPos;
      s->strm->next_out     = cs_next_out;
      s->strm->avail_out    = cs_avail_out;
      /* end save */
   }
   return False;
}



/*---------------------------------------------------*/
__inline__ Int32 BZ2_indexIntoF ( Int32 indx, Int32 *cftab )
{
   Int32 nb, na, mid;
   nb = 0;
   na = 256;
   do {
      mid = (nb + na) >> 1;
      if (indx >= cftab[mid]) nb = mid; else na = mid;
   }
   while (na - nb != 1);
   return nb;
}


/*---------------------------------------------------*/
/* Return  True iff data corruption is discovered.
   Returns False if there is no problem.
*/
static
Bool unRLE_obuf_to_output_SMALL ( DState* s )
{
   UChar k1;

   if (s->blockRandomised) {

      while (True) {
         /* try to finish existing run */
         while (True) {
            if (s->strm->avail_out == 0) return False;
            if (s->state_out_len == 0) break;
            *( (UChar*)(s->strm->next_out) ) = s->state_out_ch;
            BZ_UPDATE_CRC ( s->calculatedBlockCRC, s->state_out_ch );
            s->state_out_len--;
            s->strm->next_out++;
            s->strm->avail_out--;
            s->strm->total_out_lo32++;
            if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++;
         }
   
         /* can a new run be started? */
         if (s->nblock_used == s->save_nblock+1) return False;

         /* Only caused by corrupt data stream? */
         if (s->nblock_used > s->save_nblock+1)
            return True;
   
         s->state_out_len = 1;
         s->state_out_ch = s->k0;
         BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK; 
         k1 ^= BZ_RAND_MASK; s->nblock_used++;
         if (s->nblock_used == s->save_nblock+1) continue;
         if (k1 != s->k0) { s->k0 = k1; continue; };
   
         s->state_out_len = 2;
         BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK; 
         k1 ^= BZ_RAND_MASK; s->nblock_used++;
         if (s->nblock_used == s->save_nblock+1) continue;
         if (k1 != s->k0) { s->k0 = k1; continue; };
   
         s->state_out_len = 3;
         BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK; 
         k1 ^= BZ_RAND_MASK; s->nblock_used++;
         if (s->nblock_used == s->save_nblock+1) continue;
         if (k1 != s->k0) { s->k0 = k1; continue; };
   
         BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK; 
         k1 ^= BZ_RAND_MASK; s->nblock_used++;
         s->state_out_len = ((Int32)k1) + 4;
         BZ_GET_SMALL(s->k0); BZ_RAND_UPD_MASK; 
         s->k0 ^= BZ_RAND_MASK; s->nblock_used++;
      }

   } else {

      while (True) {
         /* try to finish existing run */
         while (True) {
            if (s->strm->avail_out == 0) return False;
            if (s->state_out_len == 0) break;
            *( (UChar*)(s->strm->next_out) ) = s->state_out_ch;
            BZ_UPDATE_CRC ( s->calculatedBlockCRC, s->state_out_ch );
            s->state_out_len--;
            s->strm->next_out++;
            s->strm->avail_out--;
            s->strm->total_out_lo32++;
            if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++;
         }
   
         /* can a new run be started? */
         if (s->nblock_used == s->save_nblock+1) return False;

         /* Only caused by corrupt data stream? */
         if (s->nblock_used > s->save_nblock+1)
            return True;
   
         s->state_out_len = 1;
         s->state_out_ch = s->k0;
         BZ_GET_SMALL(k1); s->nblock_used++;
         if (s->nblock_used == s->save_nblock+1) continue;
         if (k1 != s->k0) { s->k0 = k1; continue; };
   
         s->state_out_len = 2;
         BZ_GET_SMALL(k1); s->nblock_used++;
         if (s->nblock_used == s->save_nblock+1) continue;
         if (k1 != s->k0) { s->k0 = k1; continue; };
   
         s->state_out_len = 3;
         BZ_GET_SMALL(k1); s->nblock_used++;
         if (s->nblock_used == s->save_nblock+1) continue;
         if (k1 != s->k0) { s->k0 = k1; continue; };
   
         BZ_GET_SMALL(k1); s->nblock_used++;
         s->state_out_len = ((Int32)k1) + 4;
         BZ_GET_SMALL(s->k0); s->nblock_used++;
      }

   }
}


/*---------------------------------------------------*/
int BZ_API(BZ2_bzDecompress) ( bz_stream *strm )
{
   Bool    corrupt;
   DState* s;
   if (strm == NULL) return BZ_PARAM_ERROR;
   s = strm->state;
   if (s == NULL) return BZ_PARAM_ERROR;
   if (s->strm != strm) return BZ_PARAM_ERROR;

   while (True) {
      if (s->state == BZ_X_IDLE) return BZ_SEQUENCE_ERROR;
      if (s->state == BZ_X_OUTPUT) {
         if (s->smallDecompress)
            corrupt = unRLE_obuf_to_output_SMALL ( s ); else
            corrupt = unRLE_obuf_to_output_FAST  ( s );
         if (corrupt) return BZ_DATA_ERROR;
         if (s->nblock_used == s->save_nblock+1 && s->state_out_len == 0) {
            BZ_FINALISE_CRC ( s->calculatedBlockCRC );
            if (s->verbosity >= 3) 
               VPrintf2 ( " {0x%08x, 0x%08x}", s->storedBlockCRC, 
                          s->calculatedBlockCRC );
            if (s->verbosity >= 2) VPrintf0 ( "]" );
            if (s->calculatedBlockCRC != s->storedBlockCRC)
               return BZ_DATA_ERROR;
            s->calculatedCombinedCRC 
               = (s->calculatedCombinedCRC << 1) | 
                    (s->calculatedCombinedCRC >> 31);
            s->calculatedCombinedCRC ^= s->calculatedBlockCRC;
            s->state = BZ_X_BLKHDR_1;
         } else {
            return BZ_OK;
         }
      }
      if (s->state >= BZ_X_MAGIC_1) {
         Int32 r = BZ2_decompress ( s );
         if (r == BZ_STREAM_END) {
            if (s->verbosity >= 3)
               VPrintf2 ( "\n    combined CRCs: stored = 0x%08x, computed = 0x%08x", 
                          s->storedCombinedCRC, s->calculatedCombinedCRC );
            if (s->calculatedCombinedCRC != s->storedCombinedCRC)
               return BZ_DATA_ERROR;
            return r;
         }
         if (s->state != BZ_X_OUTPUT) return r;
      }
   }

   AssertH ( 0, 6001 );

   return 0;  /*NOTREACHED*/
}


/*---------------------------------------------------*/
int BZ_API(BZ2_bzDecompressEnd)  ( bz_stream *strm )
{
   DState* s;
   if (strm == NULL) return BZ_PARAM_ERROR;
   s = strm->state;
   if (s == NULL) return BZ_PARAM_ERROR;
   if (s->strm != strm) return BZ_PARAM_ERROR;

   if (s->tt   != NULL) BZFREE(s->tt);
   if (s->ll16 != NULL) BZFREE(s->ll16);
   if (s->ll4  != NULL) BZFREE(s->ll4);

   BZFREE(strm->state);
   strm->state = NULL;

   return BZ_OK;
}


#ifndef BZ_NO_STDIO
/*---------------------------------------------------*/
/*--- File I/O stuff                              ---*/
/*---------------------------------------------------*/

#define BZ_SETERR(eee)                    \
{                                         \
   if (bzerror != NULL) *bzerror = eee;   \
   if (bzf != NULL) bzf->lastErr = eee;   \
}

typedef 
   struct {
      FILE*     handle;
      Char      buf[BZ_MAX_UNUSED];
      Int32     bufN;
      Bool      writing;
      bz_stream strm;
      Int32     lastErr;
      Bool      initialisedOk;
   }
   bzFile;


/*---------------------------------------------*/
static Bool myfeof ( FILE* f )
{
   Int32 c = fgetc ( f );
   if (c == EOF) return True;
   ungetc ( c, f );
   return False;
}


/*---------------------------------------------------*/
BZFILE* BZ_API(BZ2_bzWriteOpen) 
                    ( int*  bzerror,      
                      FILE* f, 
                      int   blockSize100k, 
                      int   verbosity,
                      int   workFactor )
{
   Int32   ret;
   bzFile* bzf = NULL;

   BZ_SETERR(BZ_OK);

   if (f == NULL ||
       (blockSize100k < 1 || blockSize100k > 9) ||
       (workFactor < 0 || workFactor > 250) ||
       (verbosity < 0 || verbosity > 4))
      { BZ_SETERR(BZ_PARAM_ERROR); return NULL; };

   if (ferror(f))
      { BZ_SETERR(BZ_IO_ERROR); return NULL; };

   bzf = malloc ( sizeof(bzFile) );
   if (bzf == NULL)
      { BZ_SETERR(BZ_MEM_ERROR); return NULL; };

   BZ_SETERR(BZ_OK);
   bzf->initialisedOk = False;
   bzf->bufN          = 0;
   bzf->handle        = f;
   bzf->writing       = True;
   bzf->strm.bzalloc  = NULL;
   bzf->strm.bzfree   = NULL;
   bzf->strm.opaque   = NULL;

   if (workFactor == 0) workFactor = 30;
   ret = BZ2_bzCompressInit ( &(bzf->strm), blockSize100k, 
                              verbosity, workFactor );
   if (ret != BZ_OK)
      { BZ_SETERR(ret); free(bzf); return NULL; };

   bzf->strm.avail_in = 0;
   bzf->initialisedOk = True;
   return bzf;   
}



/*---------------------------------------------------*/
void BZ_API(BZ2_bzWrite)
             ( int*    bzerror, 
               BZFILE* b, 
               void*   buf, 
               int     len )
{
   Int32 n, n2, ret;
   bzFile* bzf = (bzFile*)b;

   BZ_SETERR(BZ_OK);
   if (bzf == NULL || buf == NULL || len < 0)
      { BZ_SETERR(BZ_PARAM_ERROR); return; };
   if (!(bzf->writing))
      { BZ_SETERR(BZ_SEQUENCE_ERROR); return; };
   if (ferror(bzf->handle))
      { BZ_SETERR(BZ_IO_ERROR); return; };

   if (len == 0)
      { BZ_SETERR(BZ_OK); return; };

   bzf->strm.avail_in = len;
   bzf->strm.next_in  = buf;

   while (True) {
      bzf->strm.avail_out = BZ_MAX_UNUSED;
      bzf->strm.next_out = bzf->buf;
      ret = BZ2_bzCompress ( &(bzf->strm), BZ_RUN );
      if (ret != BZ_RUN_OK)
         { BZ_SETERR(ret); return; };

      if (bzf->strm.avail_out < BZ_MAX_UNUSED) {
         n = BZ_MAX_UNUSED - bzf->strm.avail_out;
         n2 = fwrite ( (void*)(bzf->buf), sizeof(UChar), 
                       n, bzf->handle );
         if (n != n2 || ferror(bzf->handle))
            { BZ_SETERR(BZ_IO_ERROR); return; };
      }

      if (bzf->strm.avail_in == 0)
         { BZ_SETERR(BZ_OK); return; };
   }
}


/*---------------------------------------------------*/
void BZ_API(BZ2_bzWriteClose)
                  ( int*          bzerror, 
                    BZFILE*       b, 
                    int           abandon,
                    unsigned int* nbytes_in,
                    unsigned int* nbytes_out )
{
   BZ2_bzWriteClose64 ( bzerror, b, abandon, 
                        nbytes_in, NULL, nbytes_out, NULL );
}


void BZ_API(BZ2_bzWriteClose64)
                  ( int*          bzerror, 
                    BZFILE*       b, 
                    int           abandon,
                    unsigned int* nbytes_in_lo32,
                    unsigned int* nbytes_in_hi32,
                    unsigned int* nbytes_out_lo32,
                    unsigned int* nbytes_out_hi32 )
{
   Int32   n, n2, ret;
   bzFile* bzf = (bzFile*)b;

   if (bzf == NULL)
      { BZ_SETERR(BZ_OK); return; };
   if (!(bzf->writing))
      { BZ_SETERR(BZ_SEQUENCE_ERROR); return; };
   if (ferror(bzf->handle))
      { BZ_SETERR(BZ_IO_ERROR); return; };

   if (nbytes_in_lo32 != NULL) *nbytes_in_lo32 = 0;
   if (nbytes_in_hi32 != NULL) *nbytes_in_hi32 = 0;
   if (nbytes_out_lo32 != NULL) *nbytes_out_lo32 = 0;
   if (nbytes_out_hi32 != NULL) *nbytes_out_hi32 = 0;

   if ((!abandon) && bzf->lastErr == BZ_OK) {
      while (True) {
         bzf->strm.avail_out = BZ_MAX_UNUSED;
         bzf->strm.next_out = bzf->buf;
         ret = BZ2_bzCompress ( &(bzf->strm), BZ_FINISH );
         if (ret != BZ_FINISH_OK && ret != BZ_STREAM_END)
            { BZ_SETERR(ret); return; };

         if (bzf->strm.avail_out < BZ_MAX_UNUSED) {
            n = BZ_MAX_UNUSED - bzf->strm.avail_out;
            n2 = fwrite ( (void*)(bzf->buf), sizeof(UChar), 
                          n, bzf->handle );
            if (n != n2 || ferror(bzf->handle))
               { BZ_SETERR(BZ_IO_ERROR); return; };
         }

         if (ret == BZ_STREAM_END) break;
      }
   }

   if ( !abandon && !ferror ( bzf->handle ) ) {
      fflush ( bzf->handle );
      if (ferror(bzf->handle))
         { BZ_SETERR(BZ_IO_ERROR); return; };
   }

   if (nbytes_in_lo32 != NULL)
      *nbytes_in_lo32 = bzf->strm.total_in_lo32;
   if (nbytes_in_hi32 != NULL)
      *nbytes_in_hi32 = bzf->strm.total_in_hi32;
   if (nbytes_out_lo32 != NULL)
      *nbytes_out_lo32 = bzf->strm.total_out_lo32;
   if (nbytes_out_hi32 != NULL)
      *nbytes_out_hi32 = bzf->strm.total_out_hi32;

   BZ_SETERR(BZ_OK);
   BZ2_bzCompressEnd ( &(bzf->strm) );
   free ( bzf );
}


/*---------------------------------------------------*/
BZFILE* BZ_API(BZ2_bzReadOpen) 
                   ( int*  bzerror, 
                     FILE* f, 
                     int   verbosity,
                     int   small,
                     void* unused,
                     int   nUnused )
{
   bzFile* bzf = NULL;
   int     ret;

   BZ_SETERR(BZ_OK);

   if (f == NULL || 
       (small != 0 && small != 1) ||
       (verbosity < 0 || verbosity > 4) ||
       (unused == NULL && nUnused != 0) ||
       (unused != NULL && (nUnused < 0 || nUnused > BZ_MAX_UNUSED)))
      { BZ_SETERR(BZ_PARAM_ERROR); return NULL; };

   if (ferror(f))
      { BZ_SETERR(BZ_IO_ERROR); return NULL; };

   bzf = malloc ( sizeof(bzFile) );
   if (bzf == NULL) 
      { BZ_SETERR(BZ_MEM_ERROR); return NULL; };

   BZ_SETERR(BZ_OK);

   bzf->initialisedOk = False;
   bzf->handle        = f;
   bzf->bufN          = 0;
   bzf->writing       = False;
   bzf->strm.bzalloc  = NULL;
   bzf->strm.bzfree   = NULL;
   bzf->strm.opaque   = NULL;
   
   while (nUnused > 0) {
      bzf->buf[bzf->bufN] = *((UChar*)(unused)); bzf->bufN++;
      unused = ((void*)( 1 + ((UChar*)(unused))  ));
      nUnused--;
   }

   ret = BZ2_bzDecompressInit ( &(bzf->strm), verbosity, small );
   if (ret != BZ_OK)
      { BZ_SETERR(ret); free(bzf); return NULL; };

   bzf->strm.avail_in = bzf->bufN;
   bzf->strm.next_in  = bzf->buf;

   bzf->initialisedOk = True;
   return bzf;   
}


/*---------------------------------------------------*/
void BZ_API(BZ2_bzReadClose) ( int *bzerror, BZFILE *b )
{
   bzFile* bzf = (bzFile*)b;

   BZ_SETERR(BZ_OK);
   if (bzf == NULL)
      { BZ_SETERR(BZ_OK); return; };

   if (bzf->writing)
      { BZ_SETERR(BZ_SEQUENCE_ERROR); return; };

   if (bzf->initialisedOk)
      (void)BZ2_bzDecompressEnd ( &(bzf->strm) );
   free ( bzf );
}


/*---------------------------------------------------*/
int BZ_API(BZ2_bzRead) 
           ( int*    bzerror, 
             BZFILE* b, 
             void*   buf, 
             int     len )
{
   Int32   n, ret;
   bzFile* bzf = (bzFile*)b;

   BZ_SETERR(BZ_OK);

   if (bzf == NULL || buf == NULL || len < 0)
      { BZ_SETERR(BZ_PARAM_ERROR); return 0; };

   if (bzf->writing)
      { BZ_SETERR(BZ_SEQUENCE_ERROR); return 0; };

   if (len == 0)
      { BZ_SETERR(BZ_OK); return 0; };

   bzf->strm.avail_out = len;
   bzf->strm.next_out = buf;

   while (True) {

      if (ferror(bzf->handle)) 
         { BZ_SETERR(BZ_IO_ERROR); return 0; };

      if (bzf->strm.avail_in == 0 && !myfeof(bzf->handle)) {
         n = fread ( bzf->buf, sizeof(UChar), 
                     BZ_MAX_UNUSED, bzf->handle );
         if (ferror(bzf->handle))
            { BZ_SETERR(BZ_IO_ERROR); return 0; };
         bzf->bufN = n;
         bzf->strm.avail_in = bzf->bufN;
         bzf->strm.next_in = bzf->buf;
      }

      ret = BZ2_bzDecompress ( &(bzf->strm) );

      if (ret != BZ_OK && ret != BZ_STREAM_END)
         { BZ_SETERR(ret); return 0; };

      if (ret == BZ_OK && myfeof(bzf->handle) && 
          bzf->strm.avail_in == 0 && bzf->strm.avail_out > 0)
         { BZ_SETERR(BZ_UNEXPECTED_EOF); return 0; };

      if (ret == BZ_STREAM_END)
         { BZ_SETERR(BZ_STREAM_END);
           return len - bzf->strm.avail_out; };
      if (bzf->strm.avail_out == 0)
         { BZ_SETERR(BZ_OK); return len; };
      
   }

   return 0; /*not reached*/
}


/*---------------------------------------------------*/
void BZ_API(BZ2_bzReadGetUnused) 
                     ( int*    bzerror, 
                       BZFILE* b, 
                       void**  unused, 
                       int*    nUnused )
{
   bzFile* bzf = (bzFile*)b;
   if (bzf == NULL)
      { BZ_SETERR(BZ_PARAM_ERROR); return; };
   if (bzf->lastErr != BZ_STREAM_END)
      { BZ_SETERR(BZ_SEQUENCE_ERROR); return; };
   if (unused == NULL || nUnused == NULL)
      { BZ_SETERR(BZ_PARAM_ERROR); return; };

   BZ_SETERR(BZ_OK);
   *nUnused = bzf->strm.avail_in;
   *unused = bzf->strm.next_in;
}
#endif


/*---------------------------------------------------*/
/*--- Misc convenience stuff                      ---*/
/*---------------------------------------------------*/

/*---------------------------------------------------*/
int BZ_API(BZ2_bzBuffToBuffCompress) 
                         ( char*         dest, 
                           unsigned int* destLen,
                           char*         source, 
                           unsigned int  sourceLen,
                           int           blockSize100k, 
                           int           verbosity, 
                           int           workFactor )
{
   bz_stream strm;
   int ret;

   if (dest == NULL || destLen == NULL || 
       source == NULL ||
       blockSize100k < 1 || blockSize100k > 9 ||
       verbosity < 0 || verbosity > 4 ||
       workFactor < 0 || workFactor > 250) 
      return BZ_PARAM_ERROR;

   if (workFactor == 0) workFactor = 30;
   strm.bzalloc = NULL;
   strm.bzfree = NULL;
   strm.opaque = NULL;
   ret = BZ2_bzCompressInit ( &strm, blockSize100k, 
                              verbosity, workFactor );
   if (ret != BZ_OK) return ret;

   strm.next_in = source;
   strm.next_out = dest;
   strm.avail_in = sourceLen;
   strm.avail_out = *destLen;

   ret = BZ2_bzCompress ( &strm, BZ_FINISH );
   if (ret == BZ_FINISH_OK) goto output_overflow;
   if (ret != BZ_STREAM_END) goto errhandler;

   /* normal termination */
   *destLen -= strm.avail_out;   
   BZ2_bzCompressEnd ( &strm );
   return BZ_OK;

   output_overflow:
   BZ2_bzCompressEnd ( &strm );
   return BZ_OUTBUFF_FULL;

   errhandler:
   BZ2_bzCompressEnd ( &strm );
   return ret;
}


/*---------------------------------------------------*/
int BZ_API(BZ2_bzBuffToBuffDecompress) 
                           ( char*         dest, 
                             unsigned int* destLen,
                             char*         source, 
                             unsigned int  sourceLen,
                             int           small,
                             int           verbosity )
{
   bz_stream strm;
   int ret;

   if (dest == NULL || destLen == NULL || 
       source == NULL ||
       (small != 0 && small != 1) ||
       verbosity < 0 || verbosity > 4) 
          return BZ_PARAM_ERROR;

   strm.bzalloc = NULL;
   strm.bzfree = NULL;
   strm.opaque = NULL;
   ret = BZ2_bzDecompressInit ( &strm, verbosity, small );
   if (ret != BZ_OK) return ret;

   strm.next_in = source;
   strm.next_out = dest;
   strm.avail_in = sourceLen;
   strm.avail_out = *destLen;

   ret = BZ2_bzDecompress ( &strm );
   if (ret == BZ_OK) goto output_overflow_or_eof;
   if (ret != BZ_STREAM_END) goto errhandler;

   /* normal termination */
   *destLen -= strm.avail_out;
   BZ2_bzDecompressEnd ( &strm );
   return BZ_OK;

   output_overflow_or_eof:
   if (strm.avail_out > 0) {
      BZ2_bzDecompressEnd ( &strm );
      return BZ_UNEXPECTED_EOF;
   } else {
      BZ2_bzDecompressEnd ( &strm );
      return BZ_OUTBUFF_FULL;
   };      

   errhandler:
   BZ2_bzDecompressEnd ( &strm );
   return ret; 
}


/*---------------------------------------------------*/
/*--
   Code contributed by Yoshioka Tsuneo (tsuneo@rr.iij4u.or.jp)
   to support better zlib compatibility.
   This code is not _officially_ part of libbzip2 (yet);
   I haven't tested it, documented it, or considered the
   threading-safeness of it.
   If this code breaks, please contact both Yoshioka and me.
--*/
/*---------------------------------------------------*/

/*---------------------------------------------------*/
/*--
   return version like "0.9.5d, 4-Sept-1999".
--*/
const char * BZ_API(BZ2_bzlibVersion)(void)
{
   return BZ_VERSION;
}


#ifndef BZ_NO_STDIO
/*---------------------------------------------------*/

#if defined(_WIN32) || defined(OS2) || defined(MSDOS)
#   include <fcntl.h>
#   include <io.h>
#   define SET_BINARY_MODE(file) setmode(fileno(file),O_BINARY)
#else
#   define SET_BINARY_MODE(file)
#endif
static
BZFILE * bzopen_or_bzdopen
               ( const char *path,   /* no use when bzdopen */
                 int fd,             /* no use when bzdopen */
                 const char *mode,
                 int open_mode)      /* bzopen: 0, bzdopen:1 */
{
   int    bzerr;
   char   unused[BZ_MAX_UNUSED];
   int    blockSize100k = 9;
   int    writing       = 0;
   char   mode2[10]     = "";
   FILE   *fp           = NULL;
   BZFILE *bzfp         = NULL;
   int    verbosity     = 0;
   int    workFactor    = 30;
   int    smallMode     = 0;
   int    nUnused       = 0; 

   if (mode == NULL) return NULL;
   while (*mode) {
      switch (*mode) {
      case 'r':
         writing = 0; break;
      case 'w':
         writing = 1; break;
      case 's':
         smallMode = 1; break;
      default:
         if (isdigit((int)(*mode))) {
            blockSize100k = *mode-BZ_HDR_0;
         }
      }
      mode++;
   }
   strcat(mode2, writing ? "w" : "r" );
   strcat(mode2,"b");   /* binary mode */

   if (open_mode==0) {
      if (path==NULL || strcmp(path,"")==0) {
        fp = (writing ? stdout : stdin);
        SET_BINARY_MODE(fp);
      } else {
        fp = fopen(path,mode2);
      }
   } else {
#ifdef BZ_STRICT_ANSI
      fp = NULL;
#else
      fp = fdopen(fd,mode2);
#endif
   }
   if (fp == NULL) return NULL;

   if (writing) {
      /* Guard against total chaos and anarchy -- JRS */
      if (blockSize100k < 1) blockSize100k = 1;
      if (blockSize100k > 9) blockSize100k = 9; 
      bzfp = BZ2_bzWriteOpen(&bzerr,fp,blockSize100k,
                             verbosity,workFactor);
   } else {
      bzfp = BZ2_bzReadOpen(&bzerr,fp,verbosity,smallMode,
                            unused,nUnused);
   }
   if (bzfp == NULL) {
      if (fp != stdin && fp != stdout) fclose(fp);
      return NULL;
   }
   return bzfp;
}


/*---------------------------------------------------*/
/*--
   open file for read or write.
      ex) bzopen("file","w9")
      case path="" or NULL => use stdin or stdout.
--*/
BZFILE * BZ_API(BZ2_bzopen)
               ( const char *path,
                 const char *mode )
{
   return bzopen_or_bzdopen(path,-1,mode,/*bzopen*/0);
}


/*---------------------------------------------------*/
BZFILE * BZ_API(BZ2_bzdopen)
               ( int fd,
                 const char *mode )
{
   return bzopen_or_bzdopen(NULL,fd,mode,/*bzdopen*/1);
}


/*---------------------------------------------------*/
int BZ_API(BZ2_bzread) (BZFILE* b, void* buf, int len )
{
   int bzerr, nread;
   if (((bzFile*)b)->lastErr == BZ_STREAM_END) return 0;
   nread = BZ2_bzRead(&bzerr,b,buf,len);
   if (bzerr == BZ_OK || bzerr == BZ_STREAM_END) {
      return nread;
   } else {
      return -1;
   }
}


/*---------------------------------------------------*/
int BZ_API(BZ2_bzwrite) (BZFILE* b, void* buf, int len )
{
   int bzerr;

   BZ2_bzWrite(&bzerr,b,buf,len);
   if(bzerr == BZ_OK){
      return len;
   }else{
      return -1;
   }
}


/*---------------------------------------------------*/
int BZ_API(BZ2_bzflush) (BZFILE *b)
{
   /* do nothing now... */
   return 0;
}


/*---------------------------------------------------*/
void BZ_API(BZ2_bzclose) (BZFILE* b)
{
   int bzerr;
   FILE *fp;
   
   if (b==NULL) {return;}
   fp = ((bzFile *)b)->handle;
   if(((bzFile*)b)->writing){
      BZ2_bzWriteClose(&bzerr,b,0,NULL,NULL);
      if(bzerr != BZ_OK){
         BZ2_bzWriteClose(NULL,b,1,NULL,NULL);
      }
   }else{
      BZ2_bzReadClose(&bzerr,b);
   }
   if(fp!=stdin && fp!=stdout){
      fclose(fp);
   }
}


/*---------------------------------------------------*/
/*--
   return last error code 
--*/
static const char *bzerrorstrings[] = {
       "OK"
      ,"SEQUENCE_ERROR"
      ,"PARAM_ERROR"
      ,"MEM_ERROR"
      ,"DATA_ERROR"
      ,"DATA_ERROR_MAGIC"
      ,"IO_ERROR"
      ,"UNEXPECTED_EOF"
      ,"OUTBUFF_FULL"
      ,"CONFIG_ERROR"
      ,"???"   /* for future */
      ,"???"   /* for future */
      ,"???"   /* for future */
      ,"???"   /* for future */
      ,"???"   /* for future */
      ,"???"   /* for future */
};


const char * BZ_API(BZ2_bzerror) (BZFILE *b, int *errnum)
{
   int err = ((bzFile *)b)->lastErr;

   if(err>0) err = 0;
   *errnum = err;
   return bzerrorstrings[err*-1];
}
#endif


/*-------------------------------------------------------------*/
/*--- end                                           bzlib.c ---*/
/*-------------------------------------------------------------*/


================================================
FILE: external/bzip2/bzlib.h
================================================

/*-------------------------------------------------------------*/
/*--- Public header file for the library.                   ---*/
/*---                                               bzlib.h ---*/
/*-------------------------------------------------------------*/

/* ------------------------------------------------------------------
   This file is part of bzip2/libbzip2, a program and library for
   lossless, block-sorting data compression.

   bzip2/libbzip2 version 1.0.6 of 6 September 2010
   Copyright (C) 1996-2010 Julian Seward <jseward@bzip.org>

   Please read the WARNING, DISCLAIMER and PATENTS sections in the 
   README file.

   This program is released under the terms of the license contained
   in the file LICENSE.
   ------------------------------------------------------------------ */


#ifndef _BZLIB_H
#define _BZLIB_H

#ifdef __cplusplus
extern "C" {
#endif

#define BZ_RUN               0
#define BZ_FLUSH             1
#define BZ_FINISH            2

#define BZ_OK                0
#define BZ_RUN_OK            1
#define BZ_FLUSH_OK          2
#define BZ_FINISH_OK         3
#define BZ_STREAM_END        4
#define BZ_SEQUENCE_ERROR    (-1)
#define BZ_PARAM_ERROR       (-2)
#define BZ_MEM_ERROR         (-3)
#define BZ_DATA_ERROR        (-4)
#define BZ_DATA_ERROR_MAGIC  (-5)
#define BZ_IO_ERROR          (-6)
#define BZ_UNEXPECTED_EOF    (-7)
#define BZ_OUTBUFF_FULL      (-8)
#define BZ_CONFIG_ERROR      (-9)

typedef 
   struct {
      char *next_in;
      unsigned int avail_in;
      unsigned int total_in_lo32;
      unsigned int total_in_hi32;

      char *next_out;
      unsigned int avail_out;
      unsigned int total_out_lo32;
      unsigned int total_out_hi32;

      void *state;

      void *(*bzalloc)(void *,int,int);
      void (*bzfree)(void *,void *);
      void *opaque;
   } 
   bz_stream;


#ifndef BZ_IMPORT
#define BZ_EXPORT
#endif

#ifndef BZ_NO_STDIO
/* Need a definitition for FILE */
#include <stdio.h>
#endif

#ifdef _WIN32
#   include <windows.h>
#   ifdef small
      /* windows.h define small to char */
#      undef small
#   endif
#   ifdef BZ_EXPORT
#   define BZ_API(func) WINAPI func
#   define BZ_EXTERN extern
#   else
   /* import windows dll dynamically */
#   define BZ_API(func) (WINAPI * func)
#   define BZ_EXTERN
#   endif
#else
#   define BZ_API(func) func
#   define BZ_EXTERN extern
#endif


/*-- Core (
Download .txt
gitextract_0zejjrj1/

├── .gitignore
├── .gitmodules
├── Makefile
├── README.md
├── bin.rc
├── bootimg.cpp
├── bootimg.hpp
├── compress.cpp
├── compress.hpp
├── cpio.cpp
├── cpio.hpp
├── dll.rc
├── dtb.cpp
├── dtb.hpp
├── external/
│   ├── bzip2/
│   │   ├── blocksort.c
│   │   ├── bzlib.c
│   │   ├── bzlib.h
│   │   ├── bzlib_private.h
│   │   ├── compress.c
│   │   ├── crctable.c
│   │   ├── decompress.c
│   │   ├── huffman.c
│   │   └── randtable.c
│   ├── libfdt/
│   │   ├── fdt.c
│   │   ├── fdt.h
│   │   ├── fdt_addresses.c
│   │   ├── fdt_empty_tree.c
│   │   ├── fdt_overlay.c
│   │   ├── fdt_ro.c
│   │   ├── fdt_rw.c
│   │   ├── fdt_strerror.c
│   │   ├── fdt_sw.c
│   │   ├── fdt_wip.c
│   │   ├── libfdt.h
│   │   ├── libfdt_env.h
│   │   └── libfdt_internal.h
│   ├── lz4/
│   │   ├── lz4.c
│   │   ├── lz4.h
│   │   ├── lz4frame.c
│   │   ├── lz4frame.h
│   │   ├── lz4frame_static.h
│   │   ├── lz4hc.c
│   │   ├── lz4hc.h
│   │   ├── xxhash.c
│   │   └── xxhash.h
│   ├── mincrypt/
│   │   ├── dsa_sig.c
│   │   ├── include/
│   │   │   └── mincrypt/
│   │   │       ├── dsa_sig.h
│   │   │       ├── hash-internal.h
│   │   │       ├── p256.h
│   │   │       ├── p256_ecdsa.h
│   │   │       ├── rsa.h
│   │   │       ├── sha.h
│   │   │       └── sha256.h
│   │   ├── p256.c
│   │   ├── p256_ec.c
│   │   ├── p256_ecdsa.c
│   │   ├── rsa.c
│   │   ├── sha.c
│   │   └── sha256.c
│   ├── xz/
│   │   ├── common/
│   │   │   ├── mythread.h
│   │   │   ├── sysdefs.h
│   │   │   ├── tuklib_common.h
│   │   │   ├── tuklib_config.h
│   │   │   ├── tuklib_cpucores.c
│   │   │   ├── tuklib_cpucores.h
│   │   │   ├── tuklib_exit.c
│   │   │   ├── tuklib_exit.h
│   │   │   ├── tuklib_gettext.h
│   │   │   ├── tuklib_integer.h
│   │   │   ├── tuklib_mbstr.h
│   │   │   ├── tuklib_mbstr_fw.c
│   │   │   ├── tuklib_mbstr_width.c
│   │   │   ├── tuklib_open_stdxxx.c
│   │   │   ├── tuklib_open_stdxxx.h
│   │   │   ├── tuklib_physmem.c
│   │   │   ├── tuklib_physmem.h
│   │   │   ├── tuklib_progname.c
│   │   │   └── tuklib_progname.h
│   │   └── liblzma/
│   │       ├── api/
│   │       │   ├── lzma/
│   │       │   │   ├── base.h
│   │       │   │   ├── bcj.h
│   │       │   │   ├── block.h
│   │       │   │   ├── check.h
│   │       │   │   ├── container.h
│   │       │   │   ├── delta.h
│   │       │   │   ├── filter.h
│   │       │   │   ├── hardware.h
│   │       │   │   ├── index.h
│   │       │   │   ├── index_hash.h
│   │       │   │   ├── lzma12.h
│   │       │   │   ├── stream_flags.h
│   │       │   │   ├── version.h
│   │       │   │   └── vli.h
│   │       │   └── lzma.h
│   │       ├── check/
│   │       │   ├── check.c
│   │       │   ├── check.h
│   │       │   ├── crc32_fast.c
│   │       │   ├── crc32_small.c
│   │       │   ├── crc32_table.c
│   │       │   ├── crc32_table_be.h
│   │       │   ├── crc32_table_le.h
│   │       │   ├── crc32_tablegen.c
│   │       │   ├── crc32_x86.S
│   │       │   ├── crc64_fast.c
│   │       │   ├── crc64_small.c
│   │       │   ├── crc64_table.c
│   │       │   ├── crc64_table_be.h
│   │       │   ├── crc64_table_le.h
│   │       │   ├── crc64_tablegen.c
│   │       │   ├── crc64_x86.S
│   │       │   ├── crc_macros.h
│   │       │   └── sha256.c
│   │       ├── common/
│   │       │   ├── Makefile.inc
│   │       │   ├── alone_decoder.c
│   │       │   ├── alone_decoder.h
│   │       │   ├── alone_encoder.c
│   │       │   ├── auto_decoder.c
│   │       │   ├── block_buffer_decoder.c
│   │       │   ├── block_buffer_encoder.c
│   │       │   ├── block_buffer_encoder.h
│   │       │   ├── block_decoder.c
│   │       │   ├── block_decoder.h
│   │       │   ├── block_encoder.c
│   │       │   ├── block_encoder.h
│   │       │   ├── block_header_decoder.c
│   │       │   ├── block_header_encoder.c
│   │       │   ├── block_util.c
│   │       │   ├── common.c
│   │       │   ├── common.h
│   │       │   ├── easy_buffer_encoder.c
│   │       │   ├── easy_decoder_memusage.c
│   │       │   ├── easy_encoder.c
│   │       │   ├── easy_encoder_memusage.c
│   │       │   ├── easy_preset.c
│   │       │   ├── easy_preset.h
│   │       │   ├── filter_buffer_decoder.c
│   │       │   ├── filter_buffer_encoder.c
│   │       │   ├── filter_common.c
│   │       │   ├── filter_common.h
│   │       │   ├── filter_decoder.c
│   │       │   ├── filter_decoder.h
│   │       │   ├── filter_encoder.c
│   │       │   ├── filter_encoder.h
│   │       │   ├── filter_flags_decoder.c
│   │       │   ├── filter_flags_encoder.c
│   │       │   ├── hardware_cputhreads.c
│   │       │   ├── hardware_physmem.c
│   │       │   ├── index.c
│   │       │   ├── index.h
│   │       │   ├── index_decoder.c
│   │       │   ├── index_encoder.c
│   │       │   ├── index_encoder.h
│   │       │   ├── index_hash.c
│   │       │   ├── memcmplen.h
│   │       │   ├── outqueue.c
│   │       │   ├── outqueue.h
│   │       │   ├── stream_buffer_decoder.c
│   │       │   ├── stream_buffer_encoder.c
│   │       │   ├── stream_decoder.c
│   │       │   ├── stream_decoder.h
│   │       │   ├── stream_encoder.c
│   │       │   ├── stream_encoder_mt.c
│   │       │   ├── stream_flags_common.c
│   │       │   ├── stream_flags_common.h
│   │       │   ├── stream_flags_decoder.c
│   │       │   ├── stream_flags_encoder.c
│   │       │   ├── vli_decoder.c
│   │       │   ├── vli_encoder.c
│   │       │   └── vli_size.c
│   │       ├── delta/
│   │       │   ├── delta_common.c
│   │       │   ├── delta_common.h
│   │       │   ├── delta_decoder.c
│   │       │   ├── delta_decoder.h
│   │       │   ├── delta_encoder.c
│   │       │   ├── delta_encoder.h
│   │       │   └── delta_private.h
│   │       ├── lz/
│   │       │   ├── lz_decoder.c
│   │       │   ├── lz_decoder.h
│   │       │   ├── lz_encoder.c
│   │       │   ├── lz_encoder.h
│   │       │   ├── lz_encoder_hash.h
│   │       │   ├── lz_encoder_hash_table.h
│   │       │   └── lz_encoder_mf.c
│   │       ├── lzma/
│   │       │   ├── fastpos.h
│   │       │   ├── fastpos_table.c
│   │       │   ├── fastpos_tablegen.c
│   │       │   ├── lzma2_decoder.c
│   │       │   ├── lzma2_decoder.h
│   │       │   ├── lzma2_encoder.c
│   │       │   ├── lzma2_encoder.h
│   │       │   ├── lzma_common.h
│   │       │   ├── lzma_decoder.c
│   │       │   ├── lzma_decoder.h
│   │       │   ├── lzma_encoder.c
│   │       │   ├── lzma_encoder.h
│   │       │   ├── lzma_encoder_optimum_fast.c
│   │       │   ├── lzma_encoder_optimum_normal.c
│   │       │   ├── lzma_encoder_presets.c
│   │       │   └── lzma_encoder_private.h
│   │       ├── rangecoder/
│   │       │   ├── price.h
│   │       │   ├── price_table.c
│   │       │   ├── range_common.h
│   │       │   ├── range_decoder.h
│   │       │   └── range_encoder.h
│   │       └── simple/
│   │           ├── arm.c
│   │           ├── armthumb.c
│   │           ├── ia64.c
│   │           ├── powerpc.c
│   │           ├── simple_coder.c
│   │           ├── simple_coder.h
│   │           ├── simple_decoder.c
│   │           ├── simple_decoder.h
│   │           ├── simple_encoder.c
│   │           ├── simple_encoder.h
│   │           ├── simple_private.h
│   │           ├── sparc.c
│   │           └── x86.c
│   ├── xz_config/
│   │   └── config.h
│   ├── zlib/
│   │   ├── adler32.c
│   │   ├── compress.c
│   │   ├── crc32.c
│   │   ├── crc32.h
│   │   ├── deflate.c
│   │   ├── deflate.h
│   │   ├── gzclose.c
│   │   ├── gzguts.h
│   │   ├── gzlib.c
│   │   ├── gzread.c
│   │   ├── gzwrite.c
│   │   ├── infback.c
│   │   ├── inffast.c
│   │   ├── inffast.h
│   │   ├── inffixed.h
│   │   ├── inflate.c
│   │   ├── inflate.h
│   │   ├── inftrees.c
│   │   ├── inftrees.h
│   │   ├── trees.c
│   │   ├── trees.h
│   │   ├── uncompr.c
│   │   ├── zconf.h
│   │   ├── zlib.h
│   │   ├── zutil.c
│   │   └── zutil.h
│   └── zopfli/
│       ├── blocksplitter.c
│       ├── blocksplitter.h
│       ├── cache.c
│       ├── cache.h
│       ├── deflate.c
│       ├── deflate.h
│       ├── gzip_container.c
│       ├── gzip_container.h
│       ├── hash.c
│       ├── hash.h
│       ├── katajainen.c
│       ├── katajainen.h
│       ├── lz77.c
│       ├── lz77.h
│       ├── squeeze.c
│       ├── squeeze.h
│       ├── symbols.h
│       ├── tree.c
│       ├── tree.h
│       ├── util.c
│       ├── util.h
│       ├── zlib_container.c
│       ├── zlib_container.h
│       ├── zopfli.h
│       ├── zopfli_bin.c
│       └── zopfli_lib.c
├── format.cpp
├── format.hpp
├── hexpatch.cpp
├── magiskbase/
│   ├── files.cpp
│   ├── files.hpp
│   ├── include/
│   │   ├── base.hpp
│   │   └── stream.hpp
│   ├── misc.cpp
│   ├── misc.hpp
│   ├── stream.cpp
│   ├── xwrap.cpp
│   └── xwrap.hpp
├── magiskboot.hpp
├── main.cpp
├── pattern.cpp
├── ramdisk.cpp
└── scripts/
    ├── mkdir.sh
    └── strip.sh
Download .txt
SYMBOL INDEX (1880 symbols across 216 files)

FILE: bootimg.cpp
  function decompress (line 26) | static void decompress(format_t type, int fd, const void *in, size_t siz...
  function off_t (line 31) | static off_t compress(format_t type, int fd, const void *in, size_t size) {
  function dump (line 41) | static void dump(const void *buf, size_t size, const char *filename) {
  function restore (line 49) | static size_t restore(int fd, const char *filename) {
  function find_dtb_offset (line 193) | static int find_dtb_offset(const uint8_t *buf, unsigned sz) {
  function format_t (line 223) | static format_t check_fmt_lg(const uint8_t *buf, unsigned sz) {
  function dyn_img_hdr (line 242) | dyn_img_hdr *boot_img::create_hdr(const uint8_t *addr, format_t type) {
  function split_image_dtb (line 461) | int split_image_dtb(const char *filename) {
  function unpack (line 481) | int unpack(const char *image, bool skip_decomp, bool hdr) {
  function repack (line 540) | void repack(const char *src_img, const char *out_img, bool skip_comp) {

FILE: bootimg.hpp
  type mtk_hdr (line 12) | struct mtk_hdr {
  type dhtb_hdr (line 20) | struct dhtb_hdr {
  type blob_hdr (line 28) | struct blob_hdr {
  type zimage_hdr (line 44) | struct zimage_hdr {
  type AvbFooter (line 62) | struct AvbFooter {
  type AvbVBMetaImageHeader (line 73) | struct AvbVBMetaImageHeader {
  type boot_img_hdr_v0_common (line 139) | struct boot_img_hdr_v0_common {
  type boot_img_hdr_v0 (line 152) | struct boot_img_hdr_v0 : public boot_img_hdr_v0_common {
  type boot_img_hdr_v1 (line 187) | struct boot_img_hdr_v1 : public boot_img_hdr_v0 {
  type boot_img_hdr_v2 (line 193) | struct boot_img_hdr_v2 : public boot_img_hdr_v1 {
  type boot_img_hdr_pxa (line 199) | struct boot_img_hdr_pxa : public boot_img_hdr_v0_common {
  type boot_img_hdr_v3 (line 284) | struct boot_img_hdr_v3 {
  type boot_img_hdr_vnd_v3 (line 298) | struct boot_img_hdr_vnd_v3 {
  type boot_img_hdr_v4 (line 315) | struct boot_img_hdr_v4 : public boot_img_hdr_v3 {
  type boot_img_hdr_vnd_v4 (line 319) | struct boot_img_hdr_vnd_v4 : public boot_img_hdr_vnd_v3 {
  type vendor_ramdisk_table_entry_v4 (line 326) | struct vendor_ramdisk_table_entry_v4 {
  type dyn_img_hdr (line 346) | struct dyn_img_hdr {
    method decl_var (line 351) | decl_var(kernel_size, 32)
  type dyn_img_hdr_boot (line 426) | struct dyn_img_hdr_boot : public dyn_img_hdr {
    method dyn_img_hdr_boot (line 428) | dyn_img_hdr_boot() : dyn_img_hdr(false) {}
  type dyn_img_v1 (line 452) | struct dyn_img_v1 : public dyn_img_v0 {
  type dyn_img_v3 (line 486) | struct dyn_img_v3 : public dyn_img_hdr_boot {
    method impl_cls (line 487) | impl_cls(v3)
  type dyn_img_hdr_vendor (line 507) | struct dyn_img_hdr_vendor : public dyn_img_hdr {
    method dyn_img_hdr_vendor (line 509) | dyn_img_hdr_vendor() : dyn_img_hdr(true) {}
  type dyn_img_vnd_v3 (line 515) | struct dyn_img_vnd_v3 : public dyn_img_hdr_vendor {
    method impl_cls (line 516) | impl_cls(vnd_v3)
  type boot_img (line 565) | struct boot_img {

FILE: compress.cpp
  class out_stream (line 29) | class out_stream : public filter_stream {
  class gz_strm (line 34) | class gz_strm : public out_stream {
    method write (line 36) | bool write(const void *buf, size_t len) override {
    type mode_t (line 55) | enum mode_t {
    method gz_strm (line 62) | gz_strm(mode_t mode, stream_ptr &&base) :
    method do_write (line 80) | bool do_write(const void *buf, size_t len, int flush) {
  class gz_decoder (line 150) | class gz_decoder : public gz_strm {
    method gz_decoder (line 152) | explicit gz_decoder(stream_ptr &&base) : gz_strm(DECODE, std::move(bas...
  class gz_encoder (line 155) | class gz_encoder : public gz_strm {
    method gz_encoder (line 157) | explicit gz_encoder(stream_ptr &&base) : gz_strm(ENCODE, std::move(bas...
  class zopfli_encoder (line 160) | class zopfli_encoder : public chunk_out_stream {
    method zopfli_encoder (line 162) | explicit zopfli_encoder(stream_ptr &&base) :
    method write_chunk (line 205) | bool write_chunk(const void *buf, size_t len, bool final) override {
  class bz_strm (line 235) | class bz_strm : public out_stream {
    method write (line 237) | bool write(const void *buf, size_t len) override {
    type mode_t (line 254) | enum mode_t {
    method bz_strm (line 259) | bz_strm(mode_t mode, stream_ptr &&base) :
    method do_write (line 275) | bool do_write(const void *buf, size_t len, int flush) {
  class bz_decoder (line 301) | class bz_decoder : public bz_strm {
    method bz_decoder (line 303) | explicit bz_decoder(stream_ptr &&base) : bz_strm(DECODE, std::move(bas...
  class bz_encoder (line 306) | class bz_encoder : public bz_strm {
    method bz_encoder (line 308) | explicit bz_encoder(stream_ptr &&base) : bz_strm(ENCODE, std::move(bas...
  class lzma_strm (line 311) | class lzma_strm : public out_stream {
    method write (line 313) | bool write(const void *buf, size_t len) override {
    type mode_t (line 323) | enum mode_t {
    method lzma_strm (line 329) | lzma_strm(mode_t mode, stream_ptr &&base) :
    method do_write (line 361) | bool do_write(const void *buf, size_t len, lzma_action flush) {
  class lzma_decoder (line 379) | class lzma_decoder : public lzma_strm {
    method lzma_decoder (line 381) | explicit lzma_decoder(stream_ptr &&base) : lzma_strm(DECODE, std::move...
  class xz_encoder (line 384) | class xz_encoder : public lzma_strm {
    method xz_encoder (line 386) | explicit xz_encoder(stream_ptr &&base) : lzma_strm(ENCODE_XZ, std::mov...
  class lzma_encoder (line 389) | class lzma_encoder : public lzma_strm {
    method lzma_encoder (line 391) | explicit lzma_encoder(stream_ptr &&base) : lzma_strm(ENCODE_LZMA, std:...
  class LZ4F_decoder (line 394) | class LZ4F_decoder : public out_stream {
    method LZ4F_decoder (line 396) | explicit LZ4F_decoder(stream_ptr &&base) :
    method write (line 406) | bool write(const void *buf, size_t len) override {
  class LZ4F_encoder (line 447) | class LZ4F_encoder : public out_stream {
    method LZ4F_encoder (line 449) | explicit LZ4F_encoder(stream_ptr &&base) :
    method write (line 454) | bool write(const void *buf, size_t len) override {
  class LZ4_decoder (line 511) | class LZ4_decoder : public chunk_out_stream {
    method LZ4_decoder (line 513) | explicit LZ4_decoder(stream_ptr &&base) :
    method write_chunk (line 523) | bool write_chunk(const void *buf, size_t len, bool final) override {
  class LZ4_encoder (line 558) | class LZ4_encoder : public chunk_out_stream {
    method LZ4_encoder (line 560) | explicit LZ4_encoder(stream_ptr &&base, bool lg) :
    method write_chunk (line 574) | bool write_chunk(const void *buf, size_t len, bool final) override {
  function filter_strm_ptr (line 594) | filter_strm_ptr get_encoder(format_t type, stream_ptr &&base) {
  function filter_strm_ptr (line 616) | filter_strm_ptr get_decoder(format_t type, stream_ptr &&base) {
  function decompress (line 635) | void decompress(char *infile, const char *outfile) {
  function compress (line 687) | void compress(const char *method, const char *infile, const char *outfil...

FILE: cpio.cpp
  type cpio_newc_header (line 12) | struct cpio_newc_header {
  function x8u (line 29) | static uint32_t x8u(const char *hex) {
  function recursive_dir_iterator (line 54) | static void recursive_dir_iterator(cpio::entry_map &entries, const char*...

FILE: cpio.hpp
  type cpio_newc_header (line 9) | struct cpio_newc_header
  type cpio_entry (line 11) | struct cpio_entry {
  class cpio (line 24) | class cpio {
    type StringCmp (line 26) | struct StringCmp {

FILE: dtb.cpp
  function pretty_node (line 17) | static void pretty_node(int depth) {
  function pretty_prop (line 27) | static void pretty_prop(int depth) {
  function print_node (line 34) | static void print_node(const void *fdt, int node = 0, int depth = 0) {
  function find_fstab (line 84) | static int find_fstab(const void *fdt, int node = 0) {
  function for_each_fdt (line 97) | static void for_each_fdt(const char *file, bool rw, Func fn) {
  function dtb_print (line 109) | static void dtb_print(const char *file, bool fstab) {
  function dtb_patch (line 127) | static bool dtb_patch(const char *file) {
  function dtb_test (line 161) | [[noreturn]]
  function dtb_commands (line 183) | int dtb_commands(int argc, char *argv[]) {
  type fdt_blob (line 208) | struct fdt_blob {
  function fdt_patch (line 214) | static bool fdt_patch(void *fdt) {
  function dt_table_patch (line 243) | static bool dt_table_patch(const Header *hdr, const char *out) {
  function blob_patch (line 338) | static bool blob_patch(uint8_t *dtb, size_t dtb_sz, const char *out) {
  function dtb_patch_rebuild (line 385) | [[maybe_unused]]

FILE: dtb.hpp
  type qcdt_hdr (line 12) | struct qcdt_hdr {
  type qctable_v1 (line 18) | struct qctable_v1 {
  type qctable_v2 (line 24) | struct qctable_v2 {
  type qctable_v3 (line 30) | struct qctable_v3 {
  type dtbh_hdr (line 36) | struct dtbh_hdr {
  type bhtable_v2 (line 42) | struct bhtable_v2 {
  type pxadt_hdr (line 49) | struct pxadt_hdr {
  type pxa19xx_hdr (line 55) | struct pxa19xx_hdr {
  type pxatable_v1 (line 61) | struct pxatable_v1 {
  type sprd_hdr (line 67) | struct sprd_hdr {
  type sprdtable_v1 (line 73) | struct sprdtable_v1 {
  type dt_table_header (line 81) | struct dt_table_header {
  type dt_table_entry (line 94) | struct dt_table_entry {

FILE: external/bzip2/blocksort.c
  function fallbackSimpleSort (line 30) | static
  function fallbackQSort3 (line 92) | static
  function fallbackSort (line 211) | static
  function Bool (line 345) | static
  function mainSimpleSort (line 484) | static
  function UChar (line 581) | static
  function mainQSort3 (line 620) | static
  function mainSort (line 750) | static
  function BZ2_blockSort (line 1031) | void BZ2_blockSort ( EState* s )

FILE: external/bzip2/bzlib.c
  function BZ2_bz__AssertH__fail (line 41) | void BZ2_bz__AssertH__fail ( int errcode )
  function bz_config_ok (line 90) | static
  function default_bzfree (line 108) | static
  function prepare_new_block (line 116) | static
  function init_RL (line 130) | static
  function Bool (line 138) | static
  function add_pair_to_block (line 215) | static
  function flush_RL (line 251) | static
  function Bool (line 288) | static
  function Bool (line 333) | static
  function Bool (line 360) | static
  function Bool (line 535) | static
  function Int32 (line 687) | __inline__ Int32 BZ2_indexIntoF ( Int32 indx, Int32 *cftab )
  function Bool (line 705) | static
  type bzFile (line 892) | typedef
  function Bool (line 906) | static Bool myfeof ( FILE* f )
  function BZFILE (line 916) | BZFILE* BZ_API(BZ2_bzWriteOpen)
  function BZFILE (line 1087) | BZFILE* BZ_API(BZ2_bzReadOpen)
  function BZFILE (line 1382) | static
  function BZFILE (line 1460) | BZFILE * BZ_API(BZ2_bzopen)
  function BZFILE (line 1469) | BZFILE * BZ_API(BZ2_bzdopen)

FILE: external/bzip2/bzlib.h
  type bz_stream (line 48) | typedef
  type BZFILE (line 137) | typedef void BZFILE;

FILE: external/bzip2/bzlib_private.h
  type Char (line 41) | typedef char            Char;
  type Bool (line 42) | typedef unsigned char   Bool;
  type UChar (line 43) | typedef unsigned char   UChar;
  type Int32 (line 44) | typedef int             Int32;
  type UInt32 (line 45) | typedef unsigned int    UInt32;
  type Int16 (line 46) | typedef short           Int16;
  type UInt16 (line 47) | typedef unsigned short  UInt16;
  type EState (line 196) | typedef
  type DState (line 347) | typedef

FILE: external/bzip2/compress.c
  function BZ2_bsInitWrite (line 37) | void BZ2_bsInitWrite ( EState* s )
  function bsFinishWrite (line 45) | static
  function bsW (line 71) | static
  function bsPutUInt32 (line 82) | static
  function bsPutUChar (line 93) | static
  function makeMaps_e (line 105) | static
  function generateMTFValues (line 119) | static
  function sendMTFValues (line 238) | static
  function BZ2_compressBlock (line 602) | void BZ2_compressBlock ( EState* s, Bool is_last_block )

FILE: external/bzip2/decompress.c
  function makeMaps_d (line 26) | static
  function Int32 (line 106) | Int32 BZ2_decompress ( DState* s )

FILE: external/bzip2/huffman.c
  function BZ2_hbMakeCodeLengths (line 63) | void BZ2_hbMakeCodeLengths ( UChar *len,
  function BZ2_hbAssignCodes (line 152) | void BZ2_hbAssignCodes ( Int32 *code,
  function BZ2_hbCreateDecodeTables (line 170) | void BZ2_hbCreateDecodeTables ( Int32 *limit,

FILE: external/libfdt/fdt.c
  function fdt_ro_probe_ (line 18) | int32_t fdt_ro_probe_(const void *fdt)
  function check_off_ (line 52) | static int check_off_(uint32_t hdrsize, uint32_t totalsize, uint32_t off)
  function check_block_ (line 57) | static int check_block_(uint32_t hdrsize, uint32_t totalsize,
  function fdt_header_size_ (line 69) | size_t fdt_header_size_(uint32_t version)
  function fdt_header_size (line 83) | size_t fdt_header_size(const void *fdt)
  function fdt_check_header (line 89) | int fdt_check_header(const void *fdt)
  function fdt_next_tag (line 165) | uint32_t fdt_next_tag(const void *fdt, int startoffset, int *nextoffset)
  function fdt_check_node_offset_ (line 219) | int fdt_check_node_offset_(const void *fdt, int offset)
  function fdt_check_prop_offset_ (line 231) | int fdt_check_prop_offset_(const void *fdt, int offset)
  function fdt_next_node (line 243) | int fdt_next_node(const void *fdt, int offset, int *depth)
  function fdt_first_subnode (line 283) | int fdt_first_subnode(const void *fdt, int offset)
  function fdt_next_subnode (line 294) | int fdt_next_subnode(const void *fdt, int offset)
  function fdt_move (line 323) | int fdt_move(const void *fdt, void *buf, int bufsize)

FILE: external/libfdt/fdt.h
  type fdt_header (line 12) | struct fdt_header {
  type fdt_reserve_entry (line 31) | struct fdt_reserve_entry {
  type fdt_node_header (line 36) | struct fdt_node_header {
  type fdt_property (line 41) | struct fdt_property {

FILE: external/libfdt/fdt_addresses.c
  function fdt_cells (line 14) | static int fdt_cells(const void *fdt, int nodeoffset, const char *name)
  function fdt_address_cells (line 34) | int fdt_address_cells(const void *fdt, int nodeoffset)
  function fdt_size_cells (line 46) | int fdt_size_cells(const void *fdt, int nodeoffset)
  function fdt_appendprop_addrrange (line 57) | int fdt_appendprop_addrrange(void *fdt, int parent, int nodeoffset,

FILE: external/libfdt/fdt_empty_tree.c
  function fdt_create_empty_tree (line 13) | int fdt_create_empty_tree(void *buf, int bufsize)

FILE: external/libfdt/fdt_overlay.c
  function overlay_get_target_phandle (line 28) | static uint32_t overlay_get_target_phandle(const void *fdto, int fragment)
  function fdt_overlay_target_offset (line 43) | int fdt_overlay_target_offset(const void *fdt, const void *fdto,
  function overlay_phandle_add_offset (line 101) | static int overlay_phandle_add_offset(void *fdt, int node,
  function overlay_adjust_node_phandles (line 141) | static int overlay_adjust_node_phandles(void *fdto, int node,
  function overlay_adjust_local_phandles (line 178) | static int overlay_adjust_local_phandles(void *fdto, uint32_t delta)
  function overlay_update_local_node_references (line 205) | static int overlay_update_local_node_references(void *fdto,
  function overlay_update_local_references (line 310) | static int overlay_update_local_references(void *fdto, uint32_t delta)
  function overlay_fixup_one_phandle (line 353) | static int overlay_fixup_one_phandle(void *fdt, void *fdto,
  function overlay_fixup_phandle (line 413) | static int overlay_fixup_phandle(void *fdt, void *fdto, int symbols_off,
  function overlay_fixup_phandles (line 495) | static int overlay_fixup_phandles(void *fdt, void *fdto)
  function overlay_apply_node (line 542) | static int overlay_apply_node(void *fdt, int target,
  function overlay_merge (line 604) | static int overlay_merge(void *fdt, void *fdto)
  function get_path_len (line 636) | static int get_path_len(const void *fdt, int nodeoffset)
  function overlay_symbol_update (line 680) | static int overlay_symbol_update(void *fdt, void *fdto)
  function fdt_overlay_apply (line 815) | int fdt_overlay_apply(void *fdt, void *fdto)

FILE: external/libfdt/fdt_ro.c
  function fdt_nodename_eq_ (line 13) | static int fdt_nodename_eq_(const void *fdt, int offset,
  function fdt_string_eq_ (line 105) | static int fdt_string_eq_(const void *fdt, int stroffset,
  function fdt_find_max_phandle (line 114) | int fdt_find_max_phandle(const void *fdt, uint32_t *phandle)
  function fdt_generate_phandle (line 142) | int fdt_generate_phandle(const void *fdt, uint32_t *phandle)
  type fdt_reserve_entry (line 160) | struct fdt_reserve_entry
  type fdt_reserve_entry (line 162) | struct fdt_reserve_entry
  type fdt_reserve_entry (line 169) | struct fdt_reserve_entry
  function fdt_get_mem_rsv (line 175) | int fdt_get_mem_rsv(const void *fdt, int n, uint64_t *address, uint64_t ...
  function fdt_num_mem_rsv (line 189) | int fdt_num_mem_rsv(const void *fdt)
  function nextprop_ (line 201) | static int nextprop_(const void *fdt, int offset)
  function fdt_subnode_offset_namelen (line 225) | int fdt_subnode_offset_namelen(const void *fdt, int offset,
  function fdt_subnode_offset (line 244) | int fdt_subnode_offset(const void *fdt, int parentoffset,
  function fdt_path_offset_namelen (line 250) | int fdt_path_offset_namelen(const void *fdt, const char *path, int namelen)
  function fdt_path_offset (line 295) | int fdt_path_offset(const void *fdt, const char *path)
  type fdt_node_header (line 302) | struct fdt_node_header
  function fdt_first_property_offset (line 338) | int fdt_first_property_offset(const void *fdt, int nodeoffset)
  function fdt_next_property_offset (line 348) | int fdt_next_property_offset(const void *fdt, int offset)
  type fdt_property (line 356) | struct fdt_property
  type fdt_property (line 361) | struct fdt_property
  type fdt_property (line 378) | struct fdt_property
  type fdt_property (line 394) | struct fdt_property
  type fdt_property (line 404) | struct fdt_property
  type fdt_property (line 425) | struct fdt_property
  type fdt_property (line 443) | struct fdt_property
  type fdt_property (line 455) | struct fdt_property
  type fdt_property (line 472) | struct fdt_property
  function fdt_get_phandle (line 508) | uint32_t fdt_get_phandle(const void *fdt, int nodeoffset)
  function fdt_get_path (line 542) | int fdt_get_path(const void *fdt, int nodeoffset, char *buf, int buflen)
  function fdt_supernode_atdepth_offset (line 594) | int fdt_supernode_atdepth_offset(const void *fdt, int nodeoffset,
  function fdt_node_depth (line 632) | int fdt_node_depth(const void *fdt, int nodeoffset)
  function fdt_parent_offset (line 644) | int fdt_parent_offset(const void *fdt, int nodeoffset)
  function fdt_node_offset_by_prop_value (line 654) | int fdt_node_offset_by_prop_value(const void *fdt, int startoffset,
  function fdt_node_offset_by_phandle (line 681) | int fdt_node_offset_by_phandle(const void *fdt, uint32_t phandle)
  function fdt_stringlist_contains (line 706) | int fdt_stringlist_contains(const char *strlist, int listlen, const char...
  function fdt_stringlist_count (line 723) | int fdt_stringlist_count(const void *fdt, int nodeoffset, const char *pr...
  function fdt_stringlist_search (line 748) | int fdt_stringlist_search(const void *fdt, int nodeoffset, const char *p...
  function fdt_node_check_compatible (line 823) | int fdt_node_check_compatible(const void *fdt, int nodeoffset,
  function fdt_node_offset_by_compatible (line 836) | int fdt_node_offset_by_compatible(const void *fdt, int startoffset,

FILE: external/libfdt/fdt_rw.c
  function fdt_blocks_misordered_ (line 13) | static int fdt_blocks_misordered_(const void *fdt,
  function fdt_rw_probe_ (line 25) | static int fdt_rw_probe_(void *fdt)
  function fdt_data_size_ (line 49) | static inline unsigned int fdt_data_size_(void *fdt)
  function fdt_splice_ (line 54) | static int fdt_splice_(void *fdt, void *splicepoint, int oldlen, int new...
  function fdt_splice_mem_rsv_ (line 70) | static int fdt_splice_mem_rsv_(void *fdt, struct fdt_reserve_entry *p,
  function fdt_splice_struct_ (line 83) | static int fdt_splice_struct_(void *fdt, void *p,
  function fdt_del_last_string_ (line 98) | static void fdt_del_last_string_(void *fdt, const char *s)
  function fdt_splice_string_ (line 105) | static int fdt_splice_string_(void *fdt, int newlen)
  function fdt_find_add_string_ (line 127) | static int fdt_find_add_string_(void *fdt, const char *s, int *allocated)
  function fdt_add_mem_rsv (line 155) | int fdt_add_mem_rsv(void *fdt, uint64_t address, uint64_t size)
  function fdt_del_mem_rsv (line 172) | int fdt_del_mem_rsv(void *fdt, int n)
  function fdt_resize_property_ (line 184) | static int fdt_resize_property_(void *fdt, int nodeoffset, const char *n...
  function fdt_add_property_ (line 202) | static int fdt_add_property_(void *fdt, int nodeoffset, const char *name,
  function fdt_set_name (line 235) | int fdt_set_name(void *fdt, int nodeoffset, const char *name)
  function fdt_setprop_placeholder (line 258) | int fdt_setprop_placeholder(void *fdt, int nodeoffset, const char *name,
  function fdt_setprop (line 276) | int fdt_setprop(void *fdt, int nodeoffset, const char *name,
  function fdt_appendprop (line 291) | int fdt_appendprop(void *fdt, int nodeoffset, const char *name,
  function fdt_delprop (line 318) | int fdt_delprop(void *fdt, int nodeoffset, const char *name)
  function fdt_add_subnode_namelen (line 333) | int fdt_add_subnode_namelen(void *fdt, int parentoffset,
  function fdt_add_subnode (line 377) | int fdt_add_subnode(void *fdt, int parentoffset, const char *name)
  function fdt_del_node (line 382) | int fdt_del_node(void *fdt, int nodeoffset)
  function fdt_packblocks_ (line 396) | static void fdt_packblocks_(const char *old, char *new,
  function fdt_open_into (line 419) | int fdt_open_into(const void *fdt, void *buf, int bufsize)
  function fdt_pack (line 487) | int fdt_pack(void *fdt)

FILE: external/libfdt/fdt_strerror.c
  type fdt_errtabent (line 14) | struct fdt_errtabent {
  type fdt_errtabent (line 21) | struct fdt_errtabent

FILE: external/libfdt/fdt_sw.c
  function fdt_sw_probe_ (line 13) | static int fdt_sw_probe_(void *fdt)
  function fdt_sw_probe_memrsv_ (line 38) | static int fdt_sw_probe_memrsv_(void *fdt)
  function fdt_sw_probe_struct_ (line 64) | static int fdt_sw_probe_struct_(void *fdt)
  function sw_flags (line 83) | static inline uint32_t sw_flags(void *fdt)
  function fdt_create_with_flags (line 109) | int fdt_create_with_flags(void *buf, int bufsize, uint32_t flags)
  function fdt_create (line 143) | int fdt_create(void *buf, int bufsize)
  function fdt_resize (line 148) | int fdt_resize(void *fdt, void *buf, int bufsize)
  function fdt_add_reservemap_entry (line 188) | int fdt_add_reservemap_entry(void *fdt, uint64_t addr, uint64_t size)
  function fdt_finish_reservemap (line 208) | int fdt_finish_reservemap(void *fdt)
  function fdt_begin_node (line 219) | int fdt_begin_node(void *fdt, const char *name)
  function fdt_end_node (line 236) | int fdt_end_node(void *fdt)
  function fdt_add_string_ (line 250) | static int fdt_add_string_(void *fdt, const char *s)
  function fdt_del_last_string_ (line 268) | static void fdt_del_last_string_(void *fdt, const char *s)
  function fdt_find_add_string_ (line 276) | static int fdt_find_add_string_(void *fdt, const char *s, int *allocated)
  function fdt_property_placeholder (line 293) | int fdt_property_placeholder(void *fdt, const char *name, int len, void ...
  function fdt_property (line 325) | int fdt_property(void *fdt, const char *name, const void *val, int len)
  function fdt_finish (line 337) | int fdt_finish(void *fdt)

FILE: external/libfdt/fdt_wip.c
  function fdt_setprop_inplace_namelen_partial (line 13) | int fdt_setprop_inplace_namelen_partial(void *fdt, int nodeoffset,
  function fdt_setprop_inplace (line 33) | int fdt_setprop_inplace(void *fdt, int nodeoffset, const char *name,
  function fdt_nop_region_ (line 51) | static void fdt_nop_region_(void *start, int len)
  function fdt_nop_property (line 59) | int fdt_nop_property(void *fdt, int nodeoffset, const char *name)
  function fdt_node_end_offset_ (line 73) | int fdt_node_end_offset_(void *fdt, int offset)
  function fdt_nop_node (line 83) | int fdt_nop_node(void *fdt, int nodeoffset)

FILE: external/libfdt/libfdt.h
  function fdt16_ld (line 134) | static inline uint16_t fdt16_ld(const fdt16_t *p)
  function fdt32_ld (line 141) | static inline uint32_t fdt32_ld(const fdt32_t *p)
  function fdt32_st (line 151) | static inline void fdt32_st(void *property, uint32_t value)
  function fdt64_ld (line 161) | static inline uint64_t fdt64_ld(const fdt64_t *p)
  function fdt64_st (line 175) | static inline void fdt64_st(void *property, uint64_t value)
  function fdt_get_max_phandle (line 398) | static inline uint32_t fdt_get_max_phandle(const void *fdt)
  type fdt_property (line 660) | struct fdt_property
  type fdt_property (line 679) | struct fdt_property
  type fdt_property (line 713) | struct fdt_property
  type fdt_property (line 715) | struct fdt_property
  type fdt_property (line 719) | struct fdt_property
  function fdt_setprop_inplace_u32 (line 1317) | static inline int fdt_setprop_inplace_u32(void *fdt, int nodeoffset,
  function fdt_setprop_inplace_u64 (line 1352) | static inline int fdt_setprop_inplace_u64(void *fdt, int nodeoffset,
  function fdt_setprop_inplace_cell (line 1369) | static inline int fdt_setprop_inplace_cell(void *fdt, int nodeoffset,
  function fdt_property_u32 (line 1473) | static inline int fdt_property_u32(void *fdt, const char *name, uint32_t...
  function fdt_property_u64 (line 1478) | static inline int fdt_property_u64(void *fdt, const char *name, uint64_t...
  function fdt_property_cell (line 1485) | static inline int fdt_property_cell(void *fdt, const char *name, uint32_...
  function fdt_setprop_u32 (line 1684) | static inline int fdt_setprop_u32(void *fdt, int nodeoffset, const char ...
  function fdt_setprop_u64 (line 1719) | static inline int fdt_setprop_u64(void *fdt, int nodeoffset, const char ...
  function fdt_setprop_cell (line 1737) | static inline int fdt_setprop_cell(void *fdt, int nodeoffset, const char...
  function fdt_appendprop_u32 (line 1862) | static inline int fdt_appendprop_u32(void *fdt, int nodeoffset,
  function fdt_appendprop_u64 (line 1897) | static inline int fdt_appendprop_u64(void *fdt, int nodeoffset,
  function fdt_appendprop_cell (line 1915) | static inline int fdt_appendprop_cell(void *fdt, int nodeoffset,

FILE: external/libfdt/libfdt_env.h
  type FDT_BITWISE (line 25) | typedef uint16_t FDT_BITWISE fdt16_t;
  type FDT_BITWISE (line 26) | typedef uint32_t FDT_BITWISE fdt32_t;
  type FDT_BITWISE (line 27) | typedef uint64_t FDT_BITWISE fdt64_t;
  function fdt16_to_cpu (line 38) | static inline uint16_t fdt16_to_cpu(fdt16_t x)
  function fdt16_t (line 42) | static inline fdt16_t cpu_to_fdt16(uint16_t x)
  function fdt32_to_cpu (line 47) | static inline uint32_t fdt32_to_cpu(fdt32_t x)
  function fdt32_t (line 51) | static inline fdt32_t cpu_to_fdt32(uint32_t x)
  function fdt64_to_cpu (line 56) | static inline uint64_t fdt64_to_cpu(fdt64_t x)
  function fdt64_t (line 60) | static inline fdt64_t cpu_to_fdt64(uint64_t x)
  function fdt_strnlen (line 85) | static inline size_t fdt_strnlen(const char *string, size_t max_count)

FILE: external/libfdt/libfdt_internal.h
  type fdt_reserve_entry (line 36) | struct fdt_reserve_entry
  type fdt_reserve_entry (line 38) | struct fdt_reserve_entry
  type fdt_reserve_entry (line 39) | struct fdt_reserve_entry
  type fdt_reserve_entry (line 44) | struct fdt_reserve_entry
  function fdt32_ld_ (line 58) | static inline uint32_t fdt32_ld_(const fdt32_t *p)
  function fdt64_ld_ (line 63) | static inline uint64_t fdt64_ld_(const fdt64_t *p)
  function can_assume_ (line 184) | static inline bool can_assume_(int mask)

FILE: external/lz4/lz4.c
  function LZ4_isAligned (line 264) | static int LZ4_isAligned(const void* ptr, size_t alignment)
  type BYTE (line 276) | typedef  uint8_t BYTE;
  type U16 (line 277) | typedef uint16_t U16;
  type U32 (line 278) | typedef uint32_t U32;
  type S32 (line 279) | typedef  int32_t S32;
  type U64 (line 280) | typedef uint64_t U64;
  type uptrval (line 281) | typedef uintptr_t uptrval;
  type BYTE (line 286) | typedef unsigned char       BYTE;
  type U16 (line 287) | typedef unsigned short      U16;
  type U32 (line 288) | typedef unsigned int        U32;
  type S32 (line 289) | typedef   signed int        S32;
  type U64 (line 290) | typedef unsigned long long  U64;
  type uptrval (line 291) | typedef size_t              uptrval;
  type U64 (line 295) | typedef U64    reg_t;
  type reg_t (line 297) | typedef size_t reg_t;
  type limitedOutput_directive (line 300) | typedef enum {
  function LZ4_isLittleEndian (line 325) | static unsigned LZ4_isLittleEndian(void)
  function U16 (line 335) | static U16 LZ4_read16(const void* memPtr) { return *(const U16*) memPtr; }
  function U32 (line 336) | static U32 LZ4_read32(const void* memPtr) { return *(const U32*) memPtr; }
  function reg_t (line 337) | static reg_t LZ4_read_ARCH(const void* memPtr) { return *(const reg_t*) ...
  function LZ4_write16 (line 339) | static void LZ4_write16(void* memPtr, U16 value) { *(U16*)memPtr = value; }
  function LZ4_write32 (line 340) | static void LZ4_write32(void* memPtr, U32 value) { *(U32*)memPtr = value; }
  type unalign (line 346) | typedef union { U16 u16; U32 u32; reg_t uArch; } __attribute__((packed))...
  function U16 (line 348) | static U16 LZ4_read16(const void* ptr) { return ((const unalign*)ptr)->u...
  function U32 (line 349) | static U32 LZ4_read32(const void* ptr) { return ((const unalign*)ptr)->u...
  function reg_t (line 350) | static reg_t LZ4_read_ARCH(const void* ptr) { return ((const unalign*)pt...
  function LZ4_write16 (line 352) | static void LZ4_write16(void* memPtr, U16 value) { ((unalign*)memPtr)->u...
  function LZ4_write32 (line 353) | static void LZ4_write32(void* memPtr, U32 value) { ((unalign*)memPtr)->u...
  function U16 (line 357) | static U16 LZ4_read16(const void* memPtr)
  function U32 (line 362) | static U32 LZ4_read32(const void* memPtr)
  function reg_t (line 367) | static reg_t LZ4_read_ARCH(const void* memPtr)
  function LZ4_write16 (line 372) | static void LZ4_write16(void* memPtr, U16 value)
  function LZ4_write32 (line 377) | static void LZ4_write32(void* memPtr, U32 value)
  function U16 (line 385) | static U16 LZ4_readLE16(const void* memPtr)
  function LZ4_writeLE16 (line 395) | static void LZ4_writeLE16(void* memPtr, U16 value)
  function LZ4_FORCE_INLINE (line 407) | LZ4_FORCE_INLINE
  function LZ4_FORCE_INLINE (line 436) | LZ4_FORCE_INLINE void
  function LZ4_FORCE_INLINE (line 462) | LZ4_FORCE_INLINE void
  function LZ4_FORCE_INLINE (line 475) | LZ4_FORCE_INLINE void
  function LZ4_NbCommonBytes (line 513) | static unsigned LZ4_NbCommonBytes (reg_t val)
  function LZ4_count (line 602) | LZ4_FORCE_INLINE
  type tableType_t (line 640) | typedef enum { clearedTable = 0, byPtr, byU32, byU16 } tableType_t;
  type dict_directive (line 665) | typedef enum { noDict = 0, withPrefix64k, usingExtDict, usingDictCtx } d...
  type dictIssue_directive (line 666) | typedef enum { noDictIssue = 0, dictSmall } dictIssue_directive;
  function LZ4_versionNumber (line 672) | int LZ4_versionNumber (void) { return LZ4_VERSION_NUMBER; }
  function LZ4_compressBound (line 674) | int LZ4_compressBound(int isize)  { return LZ4_COMPRESSBOUND(isize); }
  function LZ4_sizeofState (line 675) | int LZ4_sizeofState(void) { return LZ4_STREAMSIZE; }
  function LZ4_FORCE_INLINE (line 698) | LZ4_FORCE_INLINE U32 LZ4_hash4(U32 sequence, tableType_t const tableType)
  function LZ4_FORCE_INLINE (line 706) | LZ4_FORCE_INLINE U32 LZ4_hash5(U64 sequence, tableType_t const tableType)
  function LZ4_FORCE_INLINE (line 718) | LZ4_FORCE_INLINE U32 LZ4_hashPosition(const void* const p, tableType_t c...
  function LZ4_FORCE_INLINE (line 724) | LZ4_FORCE_INLINE void LZ4_clearHash(U32 h, void* tableBase, tableType_t ...
  function LZ4_FORCE_INLINE (line 736) | LZ4_FORCE_INLINE void LZ4_putIndexOnHash(U32 idx, U32 h, void* tableBase...
  function LZ4_FORCE_INLINE (line 748) | LZ4_FORCE_INLINE void LZ4_putPositionOnHash(const BYTE* p, U32 h,
  function LZ4_FORCE_INLINE (line 761) | LZ4_FORCE_INLINE void LZ4_putPosition(const BYTE* p, void* tableBase, ta...
  function LZ4_FORCE_INLINE (line 773) | LZ4_FORCE_INLINE U32 LZ4_getIndexOnHash(U32 h, const void* tableBase, ta...
  function BYTE (line 789) | static const BYTE* LZ4_getPositionOnHash(U32 h, const void* tableBase, t...
  function LZ4_FORCE_INLINE (line 796) | LZ4_FORCE_INLINE const BYTE*
  function LZ4_FORCE_INLINE (line 805) | LZ4_FORCE_INLINE void
  function LZ4_FORCE_INLINE (line 851) | LZ4_FORCE_INLINE int LZ4_compress_generic_validated(
  function LZ4_FORCE_INLINE (line 1246) | LZ4_FORCE_INLINE int LZ4_compress_generic(
  function LZ4_compress_fast_extState (line 1284) | int LZ4_compress_fast_extState(void* state, const char* source, char* de...
  function LZ4_compress_fast_extState_fastReset (line 1316) | int LZ4_compress_fast_extState_fastReset(void* state, const char* src, c...
  function LZ4_compress_fast (line 1354) | int LZ4_compress_fast(const char* source, char* dest, int inputSize, int...
  function LZ4_compress_default (line 1373) | int LZ4_compress_default(const char* src, char* dst, int srcSize, int ma...
  function LZ4_compress_destSize_extState (line 1382) | static int LZ4_compress_destSize_extState (LZ4_stream_t* state, const ch...
  function LZ4_compress_destSize (line 1399) | int LZ4_compress_destSize(const char* src, char* dst, int* srcSizePtr, i...
  function LZ4_stream_t (line 1423) | LZ4_stream_t* LZ4_createStream(void)
  function LZ4_stream_t_alignment (line 1433) | static size_t LZ4_stream_t_alignment(void)
  function LZ4_stream_t (line 1443) | LZ4_stream_t* LZ4_initStream (void* buffer, size_t size)
  function LZ4_resetStream (line 1455) | void LZ4_resetStream (LZ4_stream_t* LZ4_stream)
  function LZ4_resetStream_fast (line 1461) | void LZ4_resetStream_fast(LZ4_stream_t* ctx) {
  function LZ4_freeStream (line 1465) | int LZ4_freeStream (LZ4_stream_t* LZ4_stream)
  function LZ4_loadDict (line 1475) | int LZ4_loadDict (LZ4_stream_t* LZ4_dict, const char* dictionary, int di...
  function LZ4_attach_dictionary (line 1517) | void LZ4_attach_dictionary(LZ4_stream_t* workingStream, const LZ4_stream...
  function LZ4_renormDictT (line 1545) | static void LZ4_renormDictT(LZ4_stream_t_internal* LZ4_dict, int nextSize)
  function LZ4_compress_fast_continue (line 1565) | int LZ4_compress_fast_continue (LZ4_stream_t* LZ4_stream,
  function LZ4_compress_forceExtDict (line 1641) | int LZ4_compress_forceExtDict (LZ4_stream_t* LZ4_dict, const char* sourc...
  function LZ4_saveDict (line 1668) | int LZ4_saveDict (LZ4_stream_t* LZ4_dict, char* safeBuffer, int dictSize)
  type endCondition_directive (line 1692) | typedef enum { endOnOutputSize = 0, endOnInputSize = 1 } endCondition_di...
  type earlyEnd_directive (line 1693) | typedef enum { decode_full_block = 0, partial_decode = 1 } earlyEnd_dire...
  type variable_length_error (line 1706) | typedef enum { loop_error = -2, initial_error = -1, ok = 0 } variable_le...
  function read_variable_length (line 1707) | LZ4_FORCE_INLINE unsigned
  function LZ4_FORCE_O2 (line 2170) | LZ4_FORCE_O2
  function LZ4_FORCE_O2 (line 2178) | LZ4_FORCE_O2
  function LZ4_FORCE_O2 (line 2187) | LZ4_FORCE_O2
  function LZ4_FORCE_O2 (line 2197) | LZ4_FORCE_O2 /* Exported, an obsolete API function. */
  function LZ4_decompress_fast_withPrefix64k (line 2206) | int LZ4_decompress_fast_withPrefix64k(const char* source, char* dest, in...
  function LZ4_FORCE_O2 (line 2213) | LZ4_FORCE_O2
  function LZ4_FORCE_O2 (line 2222) | LZ4_FORCE_O2
  function LZ4_FORCE_O2 (line 2232) | LZ4_FORCE_O2
  function LZ4_FORCE_INLINE (line 2245) | LZ4_FORCE_INLINE
  function LZ4_FORCE_INLINE (line 2254) | LZ4_FORCE_INLINE
  function LZ4_streamDecode_t (line 2265) | LZ4_streamDecode_t* LZ4_createStreamDecode(void)
  function LZ4_freeStreamDecode (line 2272) | int LZ4_freeStreamDecode (LZ4_streamDecode_t* LZ4_stream)
  function LZ4_setStreamDecode (line 2285) | int LZ4_setStreamDecode (LZ4_streamDecode_t* LZ4_streamDecode, const cha...
  function LZ4_decoderRingBufferSize (line 2306) | int LZ4_decoderRingBufferSize(int maxBlockSize)
  function LZ4_FORCE_O2 (line 2321) | LZ4_FORCE_O2
  function LZ4_FORCE_O2 (line 2361) | LZ4_FORCE_O2
  function LZ4_decompress_safe_usingDict (line 2404) | int LZ4_decompress_safe_usingDict(const char* source, char* dest, int co...
  function LZ4_decompress_fast_usingDict (line 2419) | int LZ4_decompress_fast_usingDict(const char* source, char* dest, int or...
  function LZ4_compress_limitedOutput (line 2432) | int LZ4_compress_limitedOutput(const char* source, char* dest, int input...
  function LZ4_compress (line 2436) | int LZ4_compress(const char* src, char* dest, int srcSize)
  function LZ4_compress_limitedOutput_withState (line 2440) | int LZ4_compress_limitedOutput_withState (void* state, const char* src, ...
  function LZ4_compress_withState (line 2444) | int LZ4_compress_withState (void* state, const char* src, char* dst, int...
  function LZ4_compress_limitedOutput_continue (line 2448) | int LZ4_compress_limitedOutput_continue (LZ4_stream_t* LZ4_stream, const...
  function LZ4_compress_continue (line 2452) | int LZ4_compress_continue (LZ4_stream_t* LZ4_stream, const char* source,...
  function LZ4_uncompress (line 2463) | int LZ4_uncompress (const char* source, char* dest, int outputSize)
  function LZ4_uncompress_unknownOutputSize (line 2467) | int LZ4_uncompress_unknownOutputSize (const char* source, char* dest, in...
  function LZ4_sizeofStreamState (line 2474) | int LZ4_sizeofStreamState(void) { return LZ4_STREAMSIZE; }
  function LZ4_resetStreamState (line 2476) | int LZ4_resetStreamState(void* state, char* inputBuffer)

FILE: external/lz4/lz4.h
  type LZ4_stream_t (line 271) | typedef union LZ4_stream_u LZ4_stream_t;
  type LZ4_streamDecode_t (line 352) | typedef union LZ4_streamDecode_u LZ4_streamDecode_t;
  type LZ4_i8 (line 584) | typedef  int8_t  LZ4_i8;
  type LZ4_byte (line 585) | typedef uint8_t  LZ4_byte;
  type LZ4_u16 (line 586) | typedef uint16_t LZ4_u16;
  type LZ4_u32 (line 587) | typedef uint32_t LZ4_u32;
  type LZ4_i8 (line 589) | typedef   signed char  LZ4_i8;
  type LZ4_byte (line 590) | typedef unsigned char  LZ4_byte;
  type LZ4_u16 (line 591) | typedef unsigned short LZ4_u16;
  type LZ4_u32 (line 592) | typedef unsigned int   LZ4_u32;
  type LZ4_stream_t_internal (line 595) | typedef struct LZ4_stream_t_internal LZ4_stream_t_internal;
  type LZ4_stream_t_internal (line 596) | struct LZ4_stream_t_internal {
  type LZ4_streamDecode_t_internal (line 605) | typedef struct {

FILE: external/lz4/lz4frame.c
  type BYTE (line 132) | typedef  uint8_t BYTE;
  type U16 (line 133) | typedef uint16_t U16;
  type U32 (line 134) | typedef uint32_t U32;
  type S32 (line 135) | typedef  int32_t S32;
  type U64 (line 136) | typedef uint64_t U64;
  type BYTE (line 138) | typedef unsigned char       BYTE;
  type U16 (line 139) | typedef unsigned short      U16;
  type U32 (line 140) | typedef unsigned int        U32;
  type S32 (line 141) | typedef   signed int        S32;
  type U64 (line 142) | typedef unsigned long long  U64;
  function U32 (line 147) | static U32 LZ4F_readLE32 (const void* src)
  function LZ4F_writeLE32 (line 157) | static void LZ4F_writeLE32 (void* dst, U32 value32)
  function U64 (line 166) | static U64 LZ4F_readLE64 (const void* src)
  function LZ4F_writeLE64 (line 180) | static void LZ4F_writeLE64 (void* dst, U64 value64)
  type LZ4F_cctx_t (line 223) | typedef struct LZ4F_cctx_s
  function LZ4F_isError (line 249) | unsigned LZ4F_isError(LZ4F_errorCode_t code)
  function LZ4F_errorCodes (line 261) | LZ4F_errorCodes LZ4F_getErrorCode(size_t functionResult)
  function LZ4F_errorCode_t (line 267) | static LZ4F_errorCode_t err0r(LZ4F_errorCodes code)
  function LZ4F_getVersion (line 274) | unsigned LZ4F_getVersion(void) { return LZ4F_VERSION; }
  function LZ4F_compressionLevel_max (line 276) | int LZ4F_compressionLevel_max(void) { return LZ4HC_CLEVEL_MAX; }
  function LZ4F_getBlockSize (line 278) | size_t LZ4F_getBlockSize(unsigned blockSizeID)
  function BYTE (line 294) | static BYTE LZ4F_headerChecksum (const void* header, size_t length)
  function LZ4F_blockSizeID_t (line 304) | static LZ4F_blockSizeID_t LZ4F_optimalBSID(const LZ4F_blockSizeID_t requ...
  function LZ4F_compressBound_internal (line 324) | static size_t LZ4F_compressBound_internal(size_t srcSize,
  function LZ4F_compressFrameBound (line 351) | size_t LZ4F_compressFrameBound(size_t srcSize, const LZ4F_preferences_t*...
  function LZ4F_compressFrame_usingCDict (line 373) | size_t LZ4F_compressFrame_usingCDict(LZ4F_cctx* cctx,
  function LZ4F_compressFrame (line 429) | size_t LZ4F_compressFrame(void* dstBuffer, size_t dstCapacity,
  type LZ4F_CDict_s (line 478) | struct LZ4F_CDict_s {
  function LZ4F_CDict (line 490) | LZ4F_CDict* LZ4F_createCDict(const void* dictBuffer, size_t dictSize)
  function LZ4F_freeCDict (line 514) | void LZ4F_freeCDict(LZ4F_CDict* cdict)
  function LZ4F_errorCode_t (line 536) | LZ4F_errorCode_t LZ4F_createCompressionContext(LZ4F_cctx** LZ4F_compress...
  function LZ4F_errorCode_t (line 550) | LZ4F_errorCode_t LZ4F_freeCompressionContext(LZ4F_cctx* cctxPtr)
  function LZ4F_initStream (line 570) | static void LZ4F_initStream(void* ctx,
  function LZ4F_compressBegin_usingCDict (line 598) | size_t LZ4F_compressBegin_usingCDict(LZ4F_cctx* cctxPtr,
  function LZ4F_compressBegin (line 710) | size_t LZ4F_compressBegin(LZ4F_cctx* cctxPtr,
  function LZ4F_compressBound (line 724) | size_t LZ4F_compressBound(size_t srcSize, const LZ4F_preferences_t* pref...
  function LZ4F_makeBlock (line 740) | static size_t LZ4F_makeBlock(void* dst,
  function LZ4F_compressBlock (line 766) | static int LZ4F_compressBlock(void* ctx, const char* src, char* dst, int...
  function LZ4F_compressBlock_continue (line 777) | static int LZ4F_compressBlock_continue(void* ctx, const char* src, char*...
  function LZ4F_compressBlockHC (line 784) | static int LZ4F_compressBlockHC(void* ctx, const char* src, char* dst, i...
  function LZ4F_compressBlockHC_continue (line 793) | static int LZ4F_compressBlockHC_continue(void* ctx, const char* src, cha...
  function compressFunc_t (line 799) | static compressFunc_t LZ4F_selectCompression(LZ4F_blockMode_t blockMode,...
  function LZ4F_localSaveDict (line 809) | static int LZ4F_localSaveDict(LZ4F_cctx_t* cctxPtr)
  type LZ4F_lastBlockStatus (line 816) | typedef enum { notDone, fromTmpBuffer, fromSrcBuffer } LZ4F_lastBlockSta...
  function LZ4F_compressUpdate (line 825) | size_t LZ4F_compressUpdate(LZ4F_cctx* cctxPtr,
  function LZ4F_flush (line 938) | size_t LZ4F_flush(LZ4F_cctx* cctxPtr,
  function LZ4F_compressEnd (line 986) | size_t LZ4F_compressEnd(LZ4F_cctx* cctxPtr,
  type dStage_t (line 1029) | typedef enum {
  type LZ4F_dctx_s (line 1041) | struct LZ4F_dctx_s {
  function LZ4F_errorCode_t (line 1069) | LZ4F_errorCode_t LZ4F_createDecompressionContext(LZ4F_dctx** LZ4F_decomp...
  function LZ4F_errorCode_t (line 1082) | LZ4F_errorCode_t LZ4F_freeDecompressionContext(LZ4F_dctx* dctx)
  function LZ4F_resetDecompressionContext (line 1097) | void LZ4F_resetDecompressionContext(LZ4F_dctx* dctx)
  function LZ4F_decodeHeader (line 1113) | static size_t LZ4F_decodeHeader(LZ4F_dctx* dctx, const void* src, size_t...
  function LZ4F_headerSize (line 1212) | size_t LZ4F_headerSize(const void* src, size_t srcSize)
  function LZ4F_errorCode_t (line 1253) | LZ4F_errorCode_t LZ4F_getFrameInfo(LZ4F_dctx* dctx,
  function LZ4F_updateDict (line 1295) | static void LZ4F_updateDict(LZ4F_dctx* dctx,
  function LZ4F_decompress (line 1384) | size_t LZ4F_decompress(LZ4F_dctx* dctx,
  function LZ4F_decompress_usingDict (line 1886) | size_t LZ4F_decompress_usingDict(LZ4F_dctx* dctx,

FILE: external/lz4/lz4frame.h
  type LZ4F_errorCode_t (line 103) | typedef size_t LZ4F_errorCode_t;
  type LZ4F_blockSizeID_t (line 123) | typedef enum {
  type LZ4F_blockMode_t (line 138) | typedef enum {
  type LZ4F_contentChecksum_t (line 145) | typedef enum {
  type LZ4F_blockChecksum_t (line 152) | typedef enum {
  type LZ4F_frameType_t (line 157) | typedef enum {
  type LZ4F_blockSizeID_t (line 164) | typedef LZ4F_blockSizeID_t blockSizeID_t;
  type LZ4F_blockMode_t (line 165) | typedef LZ4F_blockMode_t blockMode_t;
  type LZ4F_frameType_t (line 166) | typedef LZ4F_frameType_t frameType_t;
  type LZ4F_contentChecksum_t (line 167) | typedef LZ4F_contentChecksum_t contentChecksum_t;
  type LZ4F_frameInfo_t (line 175) | typedef struct {
  type LZ4F_preferences_t (line 192) | typedef struct {
  type LZ4F_cctx (line 232) | typedef struct LZ4F_cctx_s LZ4F_cctx;
  type LZ4F_cctx (line 233) | typedef LZ4F_cctx* LZ4F_compressionContext_t;
  type LZ4F_compressOptions_t (line 235) | typedef struct {
  type LZ4F_dctx (line 346) | typedef struct LZ4F_dctx_s LZ4F_dctx;
  type LZ4F_dctx (line 347) | typedef LZ4F_dctx* LZ4F_decompressionContext_t;
  type LZ4F_decompressOptions_t (line 349) | typedef struct {
  type LZ4F_errorCodes (line 537) | typedef enum { LZ4F_LIST_ERRORS(LZ4F_GENERATE_ENUM)
  type LZ4F_CDict (line 565) | typedef struct LZ4F_CDict_s LZ4F_CDict;

FILE: external/lz4/lz4hc.c
  type dictCtx_directive (line 71) | typedef enum { noDictCtx, usingDictCtxHc } dictCtx_directive;
  function U32 (line 88) | static U32 LZ4HC_hashPtr(const void* ptr) { return HASH_FUNCTION(LZ4_rea...
  function LZ4HC_clearTables (line 94) | static void LZ4HC_clearTables (LZ4HC_CCtx_internal* hc4)
  function LZ4HC_init_internal (line 100) | static void LZ4HC_init_internal (LZ4HC_CCtx_internal* hc4, const BYTE* s...
  function LZ4_FORCE_INLINE (line 118) | LZ4_FORCE_INLINE void LZ4HC_Insert (LZ4HC_CCtx_internal* hc4, const BYTE...
  function LZ4_FORCE_INLINE (line 140) | LZ4_FORCE_INLINE
  function U32 (line 162) | static U32 LZ4HC_rotatePattern(size_t const rotate, U32 const pattern)
  function LZ4HC_countPattern (line 171) | static unsigned
  function LZ4HC_reverseCountPattern (line 205) | static unsigned
  function LZ4HC_protectDictEnd (line 227) | static int LZ4HC_protectDictEnd(U32 const dictLimit, U32 const matchIndex)
  type repeat_state_e (line 232) | typedef enum { rep_untested, rep_not, rep_confirmed } repeat_state_e;
  type HCfavor_e (line 233) | typedef enum { favorCompressionRatio=0, favorDecompressionSpeed } HCfavo...
  function LZ4_FORCE_INLINE (line 235) | LZ4_FORCE_INLINE int
  function LZ4_FORCE_INLINE (line 445) | LZ4_FORCE_INLINE
  function LZ4_FORCE_INLINE (line 463) | LZ4_FORCE_INLINE int LZ4HC_encodeSequence (
  function LZ4_FORCE_INLINE (line 549) | LZ4_FORCE_INLINE int LZ4HC_compress_hashChain (
  function LZ4_FORCE_INLINE (line 796) | LZ4_FORCE_INLINE int LZ4HC_compress_generic_internal (
  function LZ4HC_compress_generic_noDictCtx (line 861) | static int
  function LZ4HC_compress_generic_dictCtx (line 876) | static int
  function LZ4HC_compress_generic (line 902) | static int
  function LZ4_sizeofStateHC (line 921) | int LZ4_sizeofStateHC(void) { return (int)sizeof(LZ4_streamHC_t); }
  function LZ4_streamHC_t_alignment (line 923) | static size_t LZ4_streamHC_t_alignment(void)
  function LZ4_compress_HC_extStateHC_fastReset (line 935) | int LZ4_compress_HC_extStateHC_fastReset (void* state, const char* src, ...
  function LZ4_compress_HC_extStateHC (line 947) | int LZ4_compress_HC_extStateHC (void* state, const char* src, char* dst,...
  function LZ4_compress_HC (line 954) | int LZ4_compress_HC(const char* src, char* dst, int srcSize, int dstCapa...
  function LZ4_compress_HC_destSize (line 970) | int LZ4_compress_HC_destSize(void* state, const char* source, char* dest...
  function LZ4_streamHC_t (line 985) | LZ4_streamHC_t* LZ4_createStreamHC(void)
  function LZ4_freeStreamHC (line 994) | int LZ4_freeStreamHC (LZ4_streamHC_t* LZ4_streamHCPtr)
  function LZ4_streamHC_t (line 1003) | LZ4_streamHC_t* LZ4_initStreamHC (void* buffer, size_t size)
  function LZ4_resetStreamHC (line 1021) | void LZ4_resetStreamHC (LZ4_streamHC_t* LZ4_streamHCPtr, int compression...
  function LZ4_resetStreamHC_fast (line 1027) | void LZ4_resetStreamHC_fast (LZ4_streamHC_t* LZ4_streamHCPtr, int compre...
  function LZ4_setCompressionLevel (line 1041) | void LZ4_setCompressionLevel(LZ4_streamHC_t* LZ4_streamHCPtr, int compre...
  function LZ4_favorDecompressionSpeed (line 1049) | void LZ4_favorDecompressionSpeed(LZ4_streamHC_t* LZ4_streamHCPtr, int fa...
  function LZ4_loadDictHC (line 1056) | int LZ4_loadDictHC (LZ4_streamHC_t* LZ4_streamHCPtr,
  function LZ4_attach_HC_dictionary (line 1077) | void LZ4_attach_HC_dictionary(LZ4_streamHC_t *working_stream, const LZ4_...
  function LZ4HC_setExternalDict (line 1083) | static void LZ4HC_setExternalDict(LZ4HC_CCtx_internal* ctxPtr, const BYT...
  function LZ4_compressHC_continue_generic (line 1101) | static int
  function LZ4_compress_HC_continue (line 1138) | int LZ4_compress_HC_continue (LZ4_streamHC_t* LZ4_streamHCPtr, const cha...
  function LZ4_compress_HC_continue_destSize (line 1146) | int LZ4_compress_HC_continue_destSize (LZ4_streamHC_t* LZ4_streamHCPtr, ...
  function LZ4_saveDictHC (line 1158) | int LZ4_saveDictHC (LZ4_streamHC_t* LZ4_streamHCPtr, char* safeBuffer, i...
  function LZ4_compressHC (line 1189) | int LZ4_compressHC(const char* src, char* dst, int srcSize) { return LZ4...
  function LZ4_compressHC_limitedOutput (line 1190) | int LZ4_compressHC_limitedOutput(const char* src, char* dst, int srcSize...
  function LZ4_compressHC2 (line 1191) | int LZ4_compressHC2(const char* src, char* dst, int srcSize, int cLevel)...
  function LZ4_compressHC2_limitedOutput (line 1192) | int LZ4_compressHC2_limitedOutput(const char* src, char* dst, int srcSiz...
  function LZ4_compressHC_withStateHC (line 1193) | int LZ4_compressHC_withStateHC (void* state, const char* src, char* dst,...
  function LZ4_compressHC_limitedOutput_withStateHC (line 1194) | int LZ4_compressHC_limitedOutput_withStateHC (void* state, const char* s...
  function LZ4_compressHC2_withStateHC (line 1195) | int LZ4_compressHC2_withStateHC (void* state, const char* src, char* dst...
  function LZ4_compressHC2_limitedOutput_withStateHC (line 1196) | int LZ4_compressHC2_limitedOutput_withStateHC (void* state, const char* ...
  function LZ4_compressHC_continue (line 1197) | int LZ4_compressHC_continue (LZ4_streamHC_t* ctx, const char* src, char*...
  function LZ4_compressHC_limitedOutput_continue (line 1198) | int LZ4_compressHC_limitedOutput_continue (LZ4_streamHC_t* ctx, const ch...
  function LZ4_sizeofStreamStateHC (line 1202) | int LZ4_sizeofStreamStateHC(void) { return LZ4_STREAMHCSIZE; }
  function LZ4_resetStreamStateHC (line 1206) | int LZ4_resetStreamStateHC(void* state, char* inputBuffer)
  function LZ4_freeHC (line 1222) | int LZ4_freeHC (void* LZ4HC_Data)
  function LZ4_compressHC2_continue (line 1229) | int LZ4_compressHC2_continue (void* LZ4HC_Data, const char* src, char* d...
  function LZ4_compressHC2_limitedOutput_continue (line 1234) | int LZ4_compressHC2_limitedOutput_continue (void* LZ4HC_Data, const char...
  type LZ4HC_optimal_t (line 1252) | typedef struct {
  function LZ4_FORCE_INLINE (line 1260) | LZ4_FORCE_INLINE int LZ4HC_literalsPrice(int const litlen)
  function LZ4_FORCE_INLINE (line 1271) | LZ4_FORCE_INLINE int LZ4HC_sequencePrice(int litlen, int mlen)
  type LZ4HC_match_t (line 1286) | typedef struct {
  function LZ4_FORCE_INLINE (line 1291) | LZ4_FORCE_INLINE LZ4HC_match_t
  function LZ4HC_compress_optimal (line 1314) | static int LZ4HC_compress_optimal ( LZ4HC_CCtx_internal* ctx,

FILE: external/lz4/lz4hc.h
  type LZ4_streamHC_t (line 101) | typedef union LZ4_streamHC_u LZ4_streamHC_t;
  type LZ4HC_CCtx_internal (line 201) | typedef struct LZ4HC_CCtx_internal LZ4HC_CCtx_internal;
  type LZ4HC_CCtx_internal (line 202) | struct LZ4HC_CCtx_internal

FILE: external/lz4/xxhash.c
  function XXH_free (line 109) | static void  XXH_free  (void* p)  { free(p); }
  type BYTE (line 147) | typedef uint8_t  BYTE;
  type U16 (line 148) | typedef uint16_t U16;
  type U32 (line 149) | typedef uint32_t U32;
  type BYTE (line 151) | typedef unsigned char      BYTE;
  type U16 (line 152) | typedef unsigned short     U16;
  type U32 (line 153) | typedef unsigned int       U32;
  function U32 (line 160) | static U32 XXH_read32(const void* memPtr) { return *(const U32*) memPtr; }
  type unalign (line 166) | typedef union { U32 u32; } __attribute__((packed)) unalign;
  function U32 (line 167) | static U32 XXH_read32(const void* ptr) { return ((const unalign*)ptr)->u...
  function U32 (line 174) | static U32 XXH_read32(const void* memPtr)
  function U32 (line 203) | static U32 XXH_swap32 (U32 x)
  type XXH_endianess (line 216) | typedef enum { XXH_bigEndian=0, XXH_littleEndian=1 } XXH_endianess;
  function XXH_isLittleEndian (line 220) | static int XXH_isLittleEndian(void)
  type XXH_alignment (line 232) | typedef enum { XXH_aligned, XXH_unaligned } XXH_alignment;
  function FORCE_INLINE (line 234) | FORCE_INLINE U32 XXH_readLE32_align(const void* ptr, XXH_endianess endia...
  function FORCE_INLINE (line 242) | FORCE_INLINE U32 XXH_readLE32(const void* ptr, XXH_endianess endian)
  function U32 (line 247) | static U32 XXH_readBE32(const void* ptr)
  function XXH_versionNumber (line 257) | XXH_PUBLIC_API unsigned XXH_versionNumber (void) { return XXH_VERSION_NU...
  function U32 (line 269) | static U32 XXH32_round(U32 seed, U32 input)
  function U32 (line 278) | static U32 XXH32_avalanche(U32 h32)
  function U32 (line 290) | static U32
  function FORCE_INLINE (line 351) | FORCE_INLINE U32
  function XXH32 (line 392) | XXH_PUBLIC_API unsigned int XXH32 (const void* input, size_t len, unsign...
  function XXH_PUBLIC_API (line 422) | XXH_PUBLIC_API XXH32_state_t* XXH32_createState(void)
  function XXH_PUBLIC_API (line 426) | XXH_PUBLIC_API XXH_errorcode XXH32_freeState(XXH32_state_t* statePtr)
  function XXH_PUBLIC_API (line 432) | XXH_PUBLIC_API void XXH32_copyState(XXH32_state_t* dstState, const XXH32...
  function XXH_PUBLIC_API (line 437) | XXH_PUBLIC_API XXH_errorcode XXH32_reset(XXH32_state_t* statePtr, unsign...
  function FORCE_INLINE (line 451) | FORCE_INLINE XXH_errorcode
  function XXH_PUBLIC_API (line 515) | XXH_PUBLIC_API XXH_errorcode XXH32_update (XXH32_state_t* state_in, cons...
  function FORCE_INLINE (line 526) | FORCE_INLINE U32
  function XXH32_digest (line 546) | XXH_PUBLIC_API unsigned int XXH32_digest (const XXH32_state_t* state_in)
  function XXH_PUBLIC_API (line 565) | XXH_PUBLIC_API void XXH32_canonicalFromHash(XXH32_canonical_t* dst, XXH3...
  function XXH_PUBLIC_API (line 572) | XXH_PUBLIC_API XXH32_hash_t XXH32_hashFromCanonical(const XXH32_canonica...
  type U64 (line 592) | typedef uint64_t U64;
  type U64 (line 595) | typedef unsigned long long U64;
  function U64 (line 603) | static U64 XXH_read64(const void* memPtr) { return *(const U64*) memPtr; }
  type unalign64 (line 609) | typedef union { U32 u32; U64 u64; } __attribute__((packed)) unalign64;
  function U64 (line 610) | static U64 XXH_read64(const void* ptr) { return ((const unalign64*)ptr)-...
  function U64 (line 618) | static U64 XXH_read64(const void* memPtr)
  function U64 (line 632) | static U64 XXH_swap64 (U64 x)
  function FORCE_INLINE (line 645) | FORCE_INLINE U64 XXH_readLE64_align(const void* ptr, XXH_endianess endia...
  function FORCE_INLINE (line 653) | FORCE_INLINE U64 XXH_readLE64(const void* ptr, XXH_endianess endian)
  function U64 (line 658) | static U64 XXH_readBE64(const void* ptr)
  function U64 (line 672) | static U64 XXH64_round(U64 acc, U64 input)
  function U64 (line 680) | static U64 XXH64_mergeRound(U64 acc, U64 val)
  function U64 (line 688) | static U64 XXH64_avalanche(U64 h64)
  function U64 (line 701) | static U64
  function FORCE_INLINE (line 810) | FORCE_INLINE U64
  function XXH64 (line 855) | XXH_PUBLIC_API unsigned long long XXH64 (const void* input, size_t len, ...
  function XXH_PUBLIC_API (line 883) | XXH_PUBLIC_API XXH64_state_t* XXH64_createState(void)
  function XXH_PUBLIC_API (line 887) | XXH_PUBLIC_API XXH_errorcode XXH64_freeState(XXH64_state_t* statePtr)
  function XXH_PUBLIC_API (line 893) | XXH_PUBLIC_API void XXH64_copyState(XXH64_state_t* dstState, const XXH64...
  function XXH_PUBLIC_API (line 898) | XXH_PUBLIC_API XXH_errorcode XXH64_reset(XXH64_state_t* statePtr, unsign...
  function FORCE_INLINE (line 911) | FORCE_INLINE XXH_errorcode
  function XXH_PUBLIC_API (line 971) | XXH_PUBLIC_API XXH_errorcode XXH64_update (XXH64_state_t* state_in, cons...
  function FORCE_INLINE (line 981) | FORCE_INLINE U64 XXH64_digest_endian (const XXH64_state_t* state, XXH_en...
  function XXH64_digest (line 1005) | XXH_PUBLIC_API unsigned long long XXH64_digest (const XXH64_state_t* sta...
  function XXH_PUBLIC_API (line 1018) | XXH_PUBLIC_API void XXH64_canonicalFromHash(XXH64_canonical_t* dst, XXH6...
  function XXH_PUBLIC_API (line 1025) | XXH_PUBLIC_API XXH64_hash_t XXH64_hashFromCanonical(const XXH64_canonica...

FILE: external/lz4/xxhash.h
  type XXH_errorcode (line 79) | typedef enum { XXH_OK=0, XXH_ERROR } XXH_errorcode;
  type XXH32_hash_t (line 162) | typedef unsigned int XXH32_hash_t;
  type XXH32_state_t (line 172) | typedef struct XXH32_state_s XXH32_state_t;
  type XXH32_canonical_t (line 204) | typedef struct { unsigned char digest[4]; } XXH32_canonical_t;
  type XXH64_hash_t (line 219) | typedef unsigned long long XXH64_hash_t;
  type XXH64_state_t (line 229) | typedef struct XXH64_state_s XXH64_state_t;
  type XXH64_canonical_t (line 239) | typedef struct { unsigned char digest[8]; } XXH64_canonical_t;
  type XXH32_state_s (line 264) | struct XXH32_state_s {
  type XXH64_state_s (line 276) | struct XXH64_state_s {
  type XXH32_state_s (line 289) | struct XXH32_state_s {
  type XXH64_state_s (line 302) | struct XXH64_state_s {

FILE: external/mincrypt/dsa_sig.c
  function trim_to_p256_bytes (line 35) | static inline int trim_to_p256_bytes(unsigned char dst[P256_NBYTES], uns...
  function dsa_sig_unpack (line 54) | int dsa_sig_unpack(unsigned char* sig, int sig_len, p256_int* r_int, p25...

FILE: external/mincrypt/include/mincrypt/hash-internal.h
  type HASH_CTX (line 36) | struct HASH_CTX
  type HASH_VTAB (line 38) | typedef struct HASH_VTAB {
  type HASH_CTX (line 46) | typedef struct HASH_CTX {

FILE: external/mincrypt/include/mincrypt/p256.h
  type p256_err (line 43) | typedef int p256_err;
  type p256_digit (line 44) | typedef uint32_t p256_digit;
  type p256_sdigit (line 45) | typedef int32_t p256_sdigit;
  type p256_ddigit (line 46) | typedef uint64_t p256_ddigit;
  type p256_sddigit (line 47) | typedef int64_t p256_sddigit;
  type p256_int (line 50) | typedef struct {

FILE: external/mincrypt/include/mincrypt/rsa.h
  type RSAPublicKey (line 40) | typedef struct RSAPublicKey {

FILE: external/mincrypt/include/mincrypt/sha.h
  type HASH_CTX (line 36) | typedef HASH_CTX SHA_CTX;

FILE: external/mincrypt/include/mincrypt/sha256.h
  type HASH_CTX (line 37) | typedef HASH_CTX SHA256_CTX;

FILE: external/mincrypt/p256.c
  function p256_init (line 52) | void p256_init(p256_int* a) {
  function p256_clear (line 56) | void p256_clear(p256_int* a) { p256_init(a); }
  function p256_get_bit (line 58) | int p256_get_bit(const p256_int* scalar, int bit) {
  function p256_is_zero (line 63) | int p256_is_zero(const p256_int* a) {
  function p256_digit (line 71) | static p256_digit mulAdd(const p256_int* a,
  function p256_digit (line 88) | static p256_digit subTop(p256_digit top_a,
  function p256_digit (line 110) | static p256_digit subM(const p256_int* MOD,
  function p256_digit (line 127) | static p256_digit addM(const p256_int* MOD,
  function p256_modmul (line 143) | void p256_modmul(const p256_int* MOD,
  function p256_is_odd (line 191) | int p256_is_odd(const p256_int* a) { return P256_DIGIT(a, 0) & 1; }
  function p256_is_even (line 192) | int p256_is_even(const p256_int* a) { return !(P256_DIGIT(a, 0) & 1); }
  function p256_digit (line 194) | p256_digit p256_shl(const p256_int* a, int n, p256_int* b) {
  function p256_shr (line 211) | void p256_shr(const p256_int* a, int n, p256_int* b) {
  function p256_shr1 (line 223) | static void p256_shr1(const p256_int* a, int highbit, p256_int* b) {
  function p256_cmp (line 236) | int p256_cmp(const p256_int* a, const p256_int* b) {
  function p256_sub (line 252) | int p256_sub(const p256_int* a, const p256_int* b, p256_int* c) {
  function p256_add (line 265) | int p256_add(const p256_int* a, const p256_int* b, p256_int* c) {
  function p256_add_d (line 278) | int p256_add_d(const p256_int* a, p256_digit d, p256_int* b) {
  function p256_modinv_vartime (line 291) | void p256_modinv_vartime(const p256_int* MOD,
  function p256_mod (line 331) | void p256_mod(const p256_int* MOD,
  function p256_is_valid_point (line 340) | int p256_is_valid_point(const p256_int* x, const p256_int* y) {
  function p256_from_bin (line 361) | void p256_from_bin(const uint8_t src[P256_NBYTES], p256_int* dst) {

FILE: external/mincrypt/p256_ec.c
  type u8 (line 43) | typedef uint8_t u8;
  type u32 (line 44) | typedef uint32_t u32;
  type s32 (line 45) | typedef int32_t s32;
  type u64 (line 46) | typedef uint64_t u64;
  type u32 (line 64) | typedef u32 limb;
  type limb (line 66) | typedef limb felem[NLIMBS];
  function felem_reduce_carry (line 196) | static void felem_reduce_carry(felem inout, limb carry) {
  function felem_sum (line 218) | static void felem_sum(felem out, const felem in, const felem in2) {
  function felem_diff (line 256) | static void felem_diff(felem out, const felem in, const felem in2) {
  function felem_reduce_degree (line 291) | static void felem_reduce_degree(felem out, u64 tmp[17]) {
  function felem_square (line 480) | static void felem_square(felem out, const felem in) {
  function felem_mul (line 529) | static void felem_mul(felem out, const felem in, const felem in2) {
  function felem_assign (line 598) | static void felem_assign(felem out, const felem in) {
  function felem_inv (line 609) | static void felem_inv(felem out, const felem in) {
  function felem_scalar_3 (line 674) | static void felem_scalar_3(felem out) {
  function felem_scalar_4 (line 701) | static void felem_scalar_4(felem out) {
  function felem_scalar_8 (line 732) | static void felem_scalar_8(felem out) {
  function felem_is_zero_vartime (line 761) | static char felem_is_zero_vartime(const felem in) {
  function point_double (line 804) | static void point_double(felem x_out, felem y_out, felem z_out, const fe...
  function point_add_mixed (line 841) | static void point_add_mixed(felem x_out, felem y_out, felem z_out,
  function point_add (line 879) | static void point_add(felem x_out, felem y_out, felem z_out, const felem...
  function point_add_or_double_vartime (line 926) | static void point_add_or_double_vartime(
  function copy_conditional (line 977) | static void copy_conditional(felem out, const felem in, limb mask) {
  function select_affine_point (line 988) | static void select_affine_point(felem out_x, felem out_y, const limb* ta...
  function select_jacobian_point (line 1012) | static void select_jacobian_point(felem out_x, felem out_y, felem out_z,
  function scalar_base_mult (line 1046) | static void scalar_base_mult(felem nx, felem ny, felem nz,
  function point_to_affine (line 1103) | static void point_to_affine(felem x_out, felem y_out, const felem nx,
  function scalar_mult (line 1114) | static void scalar_mult(felem nx, felem ny, felem nz, const felem x,
  function to_montgomery (line 1179) | static void to_montgomery(felem out, const p256_int* in) {
  function from_montgomery (line 1200) | static void from_montgomery(p256_int* out, const felem in) {
  function p256_base_point_mul (line 1225) | void p256_base_point_mul(const p256_int* n, p256_int* out_x, p256_int* o...
  function p256_points_mul_vartime (line 1245) | void p256_points_mul_vartime(

FILE: external/mincrypt/p256_ecdsa.c
  function p256_ecdsa_verify (line 32) | int p256_ecdsa_verify(const p256_int* key_x, const p256_int* key_y,

FILE: external/mincrypt/rsa.c
  function subM (line 33) | static void subM(const RSAPublicKey* key,
  function geM (line 45) | static int geM(const RSAPublicKey* key,
  function montMulAdd (line 57) | static void montMulAdd(const RSAPublicKey* key,
  function montMul (line 82) | static void montMul(const RSAPublicKey* key,
  function modpow (line 97) | static void modpow(const RSAPublicKey* key,
  function RSA_verify (line 249) | int RSA_verify(const RSAPublicKey *key,

FILE: external/mincrypt/sha.c
  function SHA1_Transform (line 38) | static void SHA1_Transform(SHA_CTX* ctx) {
  function SHA_init (line 96) | void SHA_init(SHA_CTX* ctx) {
  function SHA_update (line 107) | void SHA_update(SHA_CTX* ctx, const void* data, int len) {

FILE: external/mincrypt/sha256.c
  function SHA256_Transform (line 57) | static void SHA256_Transform(SHA256_CTX* ctx) {
  function SHA256_init (line 122) | void SHA256_init(SHA256_CTX* ctx) {
  function SHA256_update (line 136) | void SHA256_update(SHA256_CTX* ctx, const void* data, int len) {

FILE: external/xz/common/mythread.h
  function mythread_sigmask (line 86) | static inline void
  type pthread_t (line 112) | typedef pthread_t mythread;
  type pthread_mutex_t (line 113) | typedef pthread_mutex_t mythread_mutex;
  type mythread_cond (line 115) | typedef struct {
  type mythread_condtime (line 124) | typedef struct timespec mythread_condtime;
  function mythread_sigmask (line 137) | static inline void
  function mythread_create (line 155) | static inline int
  function mythread_join (line 173) | static inline int
  function mythread_mutex_init (line 181) | static inline int
  function mythread_mutex_destroy (line 187) | static inline void
  function mythread_mutex_lock (line 195) | static inline void
  function mythread_mutex_unlock (line 203) | static inline void
  function mythread_cond_init (line 221) | static inline int
  function mythread_cond_destroy (line 259) | static inline void
  function mythread_cond_signal (line 267) | static inline void
  function mythread_cond_wait (line 275) | static inline void
  function mythread_cond_timedwait (line 285) | static inline int
  function mythread_condtime_set (line 296) | static inline void
  type HANDLE (line 346) | typedef HANDLE mythread;
  type CRITICAL_SECTION (line 347) | typedef CRITICAL_SECTION mythread_mutex;
  type HANDLE (line 350) | typedef HANDLE mythread_cond;
  type CONDITION_VARIABLE (line 352) | typedef CONDITION_VARIABLE mythread_cond;
  type mythread_condtime (line 355) | typedef struct {
  function mythread_create (line 388) | static inline int
  function mythread_join (line 400) | static inline int
  function mythread_mutex_init (line 415) | static inline int
  function mythread_mutex_destroy (line 422) | static inline void
  function mythread_mutex_lock (line 428) | static inline void
  function mythread_mutex_unlock (line 434) | static inline void
  function mythread_cond_init (line 441) | static inline int
  function mythread_cond_destroy (line 453) | static inline void
  function mythread_cond_signal (line 463) | static inline void
  function mythread_cond_wait (line 473) | static inline void
  function mythread_cond_timedwait (line 487) | static inline int
  function mythread_condtime_set (line 513) | static inline void

FILE: external/xz/common/sysdefs.h
  type _Bool (line 144) | typedef unsigned char _Bool;

FILE: external/xz/common/tuklib_cpucores.c
  function tuklib_cpucores (line 46) | extern uint32_t

FILE: external/xz/common/tuklib_exit.c
  function tuklib_exit (line 24) | extern void

FILE: external/xz/common/tuklib_integer.h
  function read16ne (line 207) | static inline uint16_t
  function read32ne (line 221) | static inline uint32_t
  function read64ne (line 235) | static inline uint64_t
  function write16ne (line 249) | static inline void
  function write32ne (line 262) | static inline void
  function write64ne (line 275) | static inline void
  function read16be (line 288) | static inline uint16_t
  function read16le (line 301) | static inline uint16_t
  function read32be (line 314) | static inline uint32_t
  function read32le (line 330) | static inline uint32_t
  function write16be (line 362) | static inline void
  function write16le (line 373) | static inline void
  function write32be (line 384) | static inline void
  function write32le (line 397) | static inline void
  function aligned_read16ne (line 445) | static inline uint16_t
  function aligned_read32ne (line 459) | static inline uint32_t
  function aligned_read64ne (line 473) | static inline uint64_t
  function aligned_write16ne (line 487) | static inline void
  function aligned_write32ne (line 499) | static inline void
  function aligned_write64ne (line 511) | static inline void
  function aligned_read16be (line 523) | static inline uint16_t
  function aligned_read16le (line 531) | static inline uint16_t
  function aligned_read32be (line 539) | static inline uint32_t
  function aligned_read32le (line 547) | static inline uint32_t
  function aligned_read64be (line 555) | static inline uint64_t
  function aligned_read64le (line 563) | static inline uint64_t
  function bsr32 (line 584) | static inline uint32_t
  function clz32 (line 639) | static inline uint32_t
  function ctz32 (line 691) | static inline uint32_t

FILE: external/xz/common/tuklib_mbstr_fw.c
  function tuklib_mbstr_fw (line 16) | extern int

FILE: external/xz/common/tuklib_mbstr_width.c
  function tuklib_mbstr_width (line 21) | extern size_t

FILE: external/xz/common/tuklib_open_stdxxx.c
  function tuklib_open_stdxxx (line 23) | extern void

FILE: external/xz/common/tuklib_physmem.c
  function tuklib_physmem (line 76) | extern uint64_t

FILE: external/xz/common/tuklib_progname.c
  function tuklib_progname_init (line 22) | extern void

FILE: external/xz/liblzma/api/lzma/base.h
  type lzma_bool (line 29) | typedef unsigned char lzma_bool;
  type lzma_reserved_enum (line 44) | typedef enum {
  type lzma_ret (line 57) | typedef enum {
  type lzma_action (line 250) | typedef enum {
  type lzma_allocator (line 372) | typedef struct {
  type lzma_internal (line 442) | typedef struct lzma_internal_s lzma_internal;
  type lzma_stream (line 485) | typedef struct {

FILE: external/xz/liblzma/api/lzma/bcj.h
  type lzma_options_bcj (line 73) | typedef struct {

FILE: external/xz/liblzma/api/lzma/block.h
  type lzma_block (line 30) | typedef struct {

FILE: external/xz/liblzma/api/lzma/check.h
  type lzma_check (line 27) | typedef enum {

FILE: external/xz/liblzma/api/lzma/container.h
  type lzma_mt (line 66) | typedef struct {

FILE: external/xz/liblzma/api/lzma/delta.h
  type lzma_delta_type (line 35) | typedef enum {
  type lzma_options_delta (line 45) | typedef struct {

FILE: external/xz/liblzma/api/lzma/filter.h
  type lzma_filter (line 43) | typedef struct {

FILE: external/xz/liblzma/api/lzma/index.h
  type lzma_index (line 37) | typedef struct lzma_index_s lzma_index;
  type lzma_index_iter (line 43) | typedef struct {
  type lzma_index_iter_mode (line 226) | typedef enum {

FILE: external/xz/liblzma/api/lzma/index_hash.h
  type lzma_index_hash (line 25) | typedef struct lzma_index_hash_s lzma_index_hash;

FILE: external/xz/liblzma/api/lzma/lzma12.h
  type lzma_match_finder (line 58) | typedef enum {
  type lzma_mode (line 138) | typedef enum {
  type lzma_options_lzma (line 185) | typedef struct {

FILE: external/xz/liblzma/api/lzma/stream_flags.h
  type lzma_stream_flags (line 33) | typedef struct {

FILE: external/xz/liblzma/api/lzma/vli.h
  type lzma_vli (line 63) | typedef uint64_t lzma_vli;

FILE: external/xz/liblzma/check/check.c
  function lzma_check_is_supported (line 16) | extern LZMA_API(lzma_bool)
  function lzma_check_size (line 63) | extern LZMA_API(uint32_t)
  function lzma_check_init (line 83) | extern void
  function lzma_check_update (line 116) | extern void
  function lzma_check_finish (line 147) | extern void

FILE: external/xz/liblzma/check/check.h
  type lzma_sha256_state (line 41) | typedef struct {
  type CC_SHA256_CTX (line 49) | typedef CC_SHA256_CTX lzma_sha256_state;
  type SHA256_CTX (line 51) | typedef SHA256_CTX lzma_sha256_state;
  type SHA2_CTX (line 53) | typedef SHA2_CTX lzma_sha256_state;
  type lzma_check_state (line 81) | typedef struct {
  function lzma_sha256_init (line 140) | static inline void
  function lzma_sha256_update (line 147) | static inline void
  function lzma_sha256_finish (line 164) | static inline void

FILE: external/xz/liblzma/check/crc32_fast.c
  function lzma_crc32 (line 26) | extern LZMA_API(uint32_t)

FILE: external/xz/liblzma/check/crc32_small.c
  function crc32_init (line 19) | static void
  function lzma_crc32_init (line 40) | extern void
  function lzma_crc32 (line 48) | extern LZMA_API(uint32_t)

FILE: external/xz/liblzma/check/crc32_tablegen.c
  function init_crc32_table (line 24) | static void
  function print_crc32_table (line 54) | static void
  function print_lz_table (line 82) | static void
  function main (line 105) | int

FILE: external/xz/liblzma/check/crc64_fast.c
  function lzma_crc64 (line 29) | extern LZMA_API(uint64_t)

FILE: external/xz/liblzma/check/crc64_small.c
  function crc64_init (line 19) | static void
  function lzma_crc64 (line 40) | extern LZMA_API(uint64_t)

FILE: external/xz/liblzma/check/crc64_tablegen.c
  function init_crc64_table (line 23) | extern void
  function print_crc64_table (line 53) | static void
  function main (line 82) | int

FILE: external/xz/liblzma/check/sha256.c
  function rotr_32 (line 28) | static inline uint32_t
  function transform (line 83) | static void
  function process (line 118) | static void
  function lzma_sha256_init (line 126) | extern void
  function lzma_sha256_update (line 141) | extern void
  function lzma_sha256_finish (line 168) | extern void

FILE: external/xz/liblzma/common/alone_decoder.c
  type lzma_alone_coder (line 18) | typedef struct {
  function lzma_ret (line 52) | static lzma_ret
  function alone_decoder_end (line 169) | static void
  function lzma_ret (line 179) | static lzma_ret
  function lzma_ret (line 199) | extern lzma_ret
  function lzma_alone_decoder (line 233) | extern LZMA_API(lzma_ret)

FILE: external/xz/liblzma/common/alone_encoder.c
  type lzma_alone_coder (line 20) | typedef struct {
  function lzma_ret (line 33) | static lzma_ret
  function alone_encoder_end (line 68) | static void
  function lzma_ret (line 79) | static lzma_ret
  function lzma_alone_encoder (line 153) | extern LZMA_API(lzma_ret)

FILE: external/xz/liblzma/common/auto_decoder.c
  type lzma_auto_coder (line 17) | typedef struct {
  function lzma_ret (line 32) | static lzma_ret
  function auto_decoder_end (line 104) | static void
  function lzma_check (line 114) | static lzma_check
  function lzma_ret (line 125) | static lzma_ret
  function lzma_ret (line 155) | static lzma_ret
  function lzma_auto_decoder (line 186) | extern LZMA_API(lzma_ret)

FILE: external/xz/liblzma/common/block_buffer_decoder.c
  function lzma_block_buffer_decode (line 16) | extern LZMA_API(lzma_ret)

FILE: external/xz/liblzma/common/block_buffer_encoder.c
  function lzma2_bound (line 32) | static uint64_t
  function lzma_block_buffer_bound64 (line 55) | extern uint64_t
  function lzma_block_buffer_bound (line 73) | extern LZMA_API(size_t)
  function lzma_ret (line 88) | static lzma_ret
  function lzma_ret (line 166) | static lzma_ret
  function lzma_ret (line 223) | static lzma_ret
  function lzma_block_buffer_encode (line 318) | extern LZMA_API(lzma_ret)
  function lzma_block_uncomp_encode (line 328) | extern LZMA_API(lzma_ret)

FILE: external/xz/liblzma/common/block_decoder.c
  type lzma_block_coder (line 18) | typedef struct {
  function update_size (line 54) | static inline bool
  function is_size_valid (line 69) | static inline bool
  function lzma_ret (line 76) | static lzma_ret
  function block_decoder_end (line 181) | static void
  function lzma_ret (line 191) | extern lzma_ret
  function lzma_block_decoder (line 248) | extern LZMA_API(lzma_ret)

FILE: external/xz/liblzma/common/block_encoder.c
  type lzma_block_coder (line 18) | typedef struct {
  function lzma_ret (line 47) | static lzma_ret
  function block_encoder_end (line 138) | static void
  function lzma_ret (line 148) | static lzma_ret
  function lzma_ret (line 163) | extern lzma_ret
  function lzma_block_encoder (line 214) | extern LZMA_API(lzma_ret)

FILE: external/xz/liblzma/common/block_header_decoder.c
  function free_properties (line 17) | static void
  function lzma_block_header_decode (line 33) | extern LZMA_API(lzma_ret)

FILE: external/xz/liblzma/common/block_header_encoder.c
  function lzma_block_header_size (line 17) | extern LZMA_API(lzma_ret)
  function lzma_block_header_encode (line 73) | extern LZMA_API(lzma_ret)

FILE: external/xz/liblzma/common/block_util.c
  function lzma_block_compressed_size (line 17) | extern LZMA_API(lzma_ret)
  function lzma_block_unpadded_size (line 45) | extern LZMA_API(lzma_vli)
  function lzma_block_total_size (line 81) | extern LZMA_API(lzma_vli)

FILE: external/xz/liblzma/common/common.c
  function lzma_version_number (line 20) | extern LZMA_API(uint32_t)
  function lzma_version_string (line 27) | extern LZMA_API(const char *)
  function lzma_free (line 77) | extern void
  function lzma_bufcpy (line 93) | extern size_t
  function lzma_ret (line 115) | extern lzma_ret
  function lzma_ret (line 126) | extern lzma_ret
  function lzma_next_end (line 144) | extern void
  function lzma_ret (line 169) | extern lzma_ret
  function lzma_code (line 196) | extern LZMA_API(lzma_ret)
  function lzma_end (line 356) | extern LZMA_API(void)
  function lzma_get_progress (line 369) | extern LZMA_API(void)
  function lzma_get_check (line 385) | extern LZMA_API(lzma_check)
  function lzma_memusage (line 397) | extern LZMA_API(uint64_t)
  function lzma_memlimit_get (line 414) | extern LZMA_API(uint64_t)
  function lzma_memlimit_set (line 431) | extern LZMA_API(lzma_ret)

FILE: external/xz/liblzma/common/common.h
  type lzma_next_coder (line 91) | typedef struct lzma_next_coder_s lzma_next_coder;
  type lzma_filter_info (line 93) | typedef struct lzma_filter_info_s lzma_filter_info;
  type lzma_ret (line 97) | typedef lzma_ret (*lzma_init_function)(
  type lzma_ret (line 105) | typedef lzma_ret (*lzma_code_function)(
  type lzma_filter_info_s (line 120) | struct lzma_filter_info_s {
  type lzma_next_coder_s (line 135) | struct lzma_next_coder_s {
  type lzma_internal_s (line 196) | struct lzma_internal_s {

FILE: external/xz/liblzma/common/easy_buffer_encoder.c
  function lzma_easy_buffer_encode (line 16) | extern LZMA_API(lzma_ret)

FILE: external/xz/liblzma/common/easy_decoder_memusage.c
  function lzma_easy_decoder_memusage (line 16) | extern LZMA_API(uint64_t)

FILE: external/xz/liblzma/common/easy_encoder.c
  function lzma_easy_encoder (line 16) | extern LZMA_API(lzma_ret)

FILE: external/xz/liblzma/common/easy_encoder_memusage.c
  function lzma_easy_encoder_memusage (line 16) | extern LZMA_API(uint64_t)

FILE: external/xz/liblzma/common/easy_preset.c
  function lzma_easy_preset (line 16) | extern bool

FILE: external/xz/liblzma/common/easy_preset.h
  type lzma_options_easy (line 16) | typedef struct {

FILE: external/xz/liblzma/common/filter_buffer_decoder.c
  function lzma_raw_buffer_decode (line 16) | extern LZMA_API(lzma_ret)

FILE: external/xz/liblzma/common/filter_buffer_encoder.c
  function lzma_raw_buffer_encode (line 16) | extern LZMA_API(lzma_ret)

FILE: external/xz/liblzma/common/filter_common.c
  function lzma_filters_copy (line 124) | extern LZMA_API(lzma_ret)
  function lzma_ret (line 193) | static lzma_ret
  function lzma_ret (line 241) | extern lzma_ret
  function lzma_raw_coder_memusage (line 294) | extern uint64_t

FILE: external/xz/liblzma/common/filter_common.h
  type lzma_filter_coder (line 20) | typedef struct {
  type lzma_filter_coder (line 35) | typedef const lzma_filter_coder *(*lzma_filter_find)(lzma_vli id);

FILE: external/xz/liblzma/common/filter_decoder.c
  type lzma_filter_decoder (line 21) | typedef struct {
  function lzma_filter_decoder (line 121) | static const lzma_filter_decoder *
  function lzma_filter_decoder_is_supported (line 132) | extern LZMA_API(lzma_bool)
  function lzma_ret (line 139) | extern lzma_ret
  function lzma_raw_decoder (line 148) | extern LZMA_API(lzma_ret)
  function lzma_raw_decoder_memusage (line 160) | extern LZMA_API(uint64_t)
  function lzma_properties_decode (line 168) | extern LZMA_API(lzma_ret)

FILE: external/xz/liblzma/common/filter_encoder.c
  type lzma_filter_encoder (line 21) | typedef struct {
  function lzma_filter_encoder (line 153) | static const lzma_filter_encoder *
  function lzma_filter_encoder_is_supported (line 164) | extern LZMA_API(lzma_bool)
  function lzma_filters_update (line 171) | extern LZMA_API(lzma_ret)
  function lzma_ret (line 198) | extern lzma_ret
  function lzma_raw_encoder (line 207) | extern LZMA_API(lzma_ret)
  function lzma_raw_encoder_memusage (line 221) | extern LZMA_API(uint64_t)
  function lzma_mt_block_size (line 229) | extern uint64_t
  function lzma_properties_size (line 252) | extern LZMA_API(lzma_ret)
  function lzma_properties_encode (line 275) | extern LZMA_API(lzma_ret)

FILE: external/xz/liblzma/common/filter_flags_decoder.c
  function lzma_filter_flags_decode (line 16) | extern LZMA_API(lzma_ret)

FILE: external/xz/liblzma/common/filter_flags_encoder.c
  function lzma_filter_flags_size (line 16) | extern LZMA_API(lzma_ret)
  function lzma_filter_flags_encode (line 30) | extern LZMA_API(lzma_ret)

FILE: external/xz/liblzma/common/hardware_cputhreads.c
  function lzma_cputhreads (line 18) | extern LZMA_API(uint32_t)

FILE: external/xz/liblzma/common/hardware_physmem.c
  function lzma_physmem (line 18) | extern LZMA_API(uint64_t)

FILE: external/xz/liblzma/common/index.c
  type index_tree_node (line 29) | typedef struct index_tree_node_s index_tree_node;
  type index_tree_node_s (line 30) | struct index_tree_node_s {
  type index_tree (line 46) | typedef struct {
  type index_record (line 65) | typedef struct {
  type index_group (line 71) | typedef struct {
  type index_stream (line 107) | typedef struct {
  type lzma_index_s (line 145) | struct lzma_index_s {
  function index_tree_init (line 181) | static void
  function index_tree_node_end (line 193) | static void
  function index_tree_end (line 214) | static void
  function index_tree_append (line 229) | static void
  function index_stream (line 339) | static index_stream *
  function index_stream_end (line 369) | static void
  function lzma_index (line 379) | static lzma_index *
  function lzma_index_init (line 397) | extern LZMA_API(lzma_index *)
  function lzma_index_end (line 416) | extern LZMA_API(void)
  function lzma_index_prealloc (line 430) | extern void
  function lzma_index_memusage (line 441) | extern LZMA_API(uint64_t)
  function lzma_index_memused (line 490) | extern LZMA_API(uint64_t)
  function lzma_index_block_count (line 497) | extern LZMA_API(lzma_vli)
  function lzma_index_stream_count (line 504) | extern LZMA_API(lzma_vli)
  function lzma_index_size (line 511) | extern LZMA_API(lzma_vli)
  function lzma_index_total_size (line 518) | extern LZMA_API(lzma_vli)
  function lzma_index_stream_size (line 525) | extern LZMA_API(lzma_vli)
  function lzma_vli (line 535) | static lzma_vli
  function lzma_index_file_size (line 559) | extern LZMA_API(lzma_vli)
  function lzma_index_uncompressed_size (line 571) | extern LZMA_API(lzma_vli)
  function lzma_index_checks (line 578) | extern LZMA_API(uint32_t)
  function lzma_index_padding_size (line 592) | extern uint32_t
  function lzma_index_stream_flags (line 600) | extern LZMA_API(lzma_ret)
  function lzma_index_stream_padding (line 617) | extern LZMA_API(lzma_ret)
  function lzma_index_append (line 639) | extern LZMA_API(lzma_ret)
  type index_cat_info (line 720) | typedef struct {
  function index_cat_helper (line 744) | static void
  function lzma_index_cat (line 766) | extern LZMA_API(lzma_ret)
  function index_stream (line 864) | static index_stream *
  function lzma_index_dup (line 925) | extern LZMA_API(lzma_index *)
  function iter_set_info (line 977) | static void
  function lzma_index_iter_init (line 1082) | extern LZMA_API(void)
  function lzma_index_iter_rewind (line 1091) | extern LZMA_API(void)
  function lzma_index_iter_next (line 1102) | extern LZMA_API(lzma_bool)
  function lzma_index_iter_locate (line 1209) | extern LZMA_API(lzma_bool)

FILE: external/xz/liblzma/common/index.h
  function lzma_vli (line 38) | static inline lzma_vli
  function lzma_vli (line 47) | static inline lzma_vli
  function lzma_vli (line 56) | static inline lzma_vli
  function lzma_vli (line 64) | static inline lzma_vli

FILE: external/xz/liblzma/common/index_decoder.c
  type lzma_index_coder (line 17) | typedef struct {
  function lzma_ret (line 56) | static lzma_ret
  function index_decoder_end (line 211) | static void
  function lzma_ret (line 221) | static lzma_ret
  function lzma_ret (line 241) | static lzma_ret
  function lzma_ret (line 268) | static lzma_ret
  function lzma_index_decoder (line 296) | extern LZMA_API(lzma_ret)
  function lzma_index_buffer_decode (line 308) | extern LZMA_API(lzma_ret)

FILE: external/xz/liblzma/common/index_encoder.c
  type lzma_index_coder (line 18) | typedef struct {
  function index_encoder_end (line 163) | static void
  function index_encoder_reset (line 171) | static void
  function lzma_ret (line 185) | extern lzma_ret
  function lzma_index_encoder (line 209) | extern LZMA_API(lzma_ret)
  function lzma_index_buffer_encode (line 221) | extern LZMA_API(lzma_ret)

FILE: external/xz/liblzma/common/index_hash.c
  type lzma_index_hash_info (line 18) | typedef struct {
  type lzma_index_hash_s (line 37) | struct lzma_index_hash_s {
  function lzma_index_hash_init (line 72) | extern LZMA_API(lzma_index_hash *)
  function lzma_index_hash_end (line 104) | extern LZMA_API(void)
  function lzma_index_hash_size (line 113) | extern LZMA_API(lzma_vli)
  function lzma_ret (line 125) | static lzma_ret
  function lzma_index_hash_append (line 143) | extern LZMA_API(lzma_ret)
  function lzma_index_hash_decode (line 174) | extern LZMA_API(lzma_ret)

FILE: external/xz/liblzma/common/memcmplen.h
  function lzma_attribute (line 42) | static inline uint32_t lzma_attribute((__always_inline__))

FILE: external/xz/liblzma/common/outqueue.c
  function lzma_ret (line 22) | static lzma_ret
  function lzma_outq_memusage (line 41) | extern uint64_t
  function lzma_ret (line 56) | extern lzma_ret
  function lzma_outq_end (line 100) | extern void
  function lzma_outbuf (line 113) | extern lzma_outbuf *
  function lzma_outq_is_readable (line 135) | extern bool
  function lzma_ret (line 146) | extern lzma_ret

FILE: external/xz/liblzma/common/outqueue.h
  type lzma_outbuf (line 17) | typedef struct {
  type lzma_outq (line 37) | typedef struct {
  function lzma_outq_has_buf (line 144) | static inline bool
  function lzma_outq_is_empty (line 152) | static inline bool

FILE: external/xz/liblzma/common/stream_buffer_decoder.c
  function lzma_stream_buffer_decode (line 16) | extern LZMA_API(lzma_ret)

FILE: external/xz/liblzma/common/stream_buffer_encoder.c
  function lzma_stream_buffer_bound (line 25) | extern LZMA_API(size_t)
  function lzma_stream_buffer_encode (line 43) | extern LZMA_API(lzma_ret)

FILE: external/xz/liblzma/common/stream_decoder.c
  type lzma_stream_coder (line 17) | typedef struct {
  function lzma_ret (line 86) | static lzma_ret
  function lzma_ret (line 102) | static lzma_ret
  function stream_decoder_end (line 379) | static void
  function lzma_check (line 390) | static lzma_check
  function lzma_ret (line 398) | static lzma_ret
  function lzma_ret (line 418) | extern lzma_ret
  function lzma_stream_decoder (line 458) | extern LZMA_API(lzma_ret)

FILE: external/xz/liblzma/common/stream_encoder.c
  type lzma_stream_coder (line 17) | typedef struct {
  function lzma_ret (line 61) | static lzma_ret
  function lzma_ret (line 80) | static lzma_ret
  function stream_encoder_end (line 213) | static void
  function lzma_ret (line 230) | static lzma_ret
  function lzma_ret (line 271) | static lzma_ret
  function lzma_stream_encoder (line 327) | extern LZMA_API(lzma_ret)

FILE: external/xz/liblzma/common/stream_encoder_mt.c
  type worker_state (line 26) | typedef enum {
  type lzma_stream_coder (line 47) | typedef struct lzma_stream_coder_s lzma_stream_coder;
  type worker_thread (line 49) | typedef struct worker_thread_s worker_thread;
  type worker_thread_s (line 50) | struct worker_thread_s {
  type lzma_stream_coder_s (line 100) | struct lzma_stream_coder_s {
  function worker_error (line 181) | static void
  function worker_state (line 198) | static worker_state
  function MYTHREAD_RET_TYPE (line 345) | static MYTHREAD_RET_TYPE
  function threads_stop (line 420) | static void
  function threads_end (line 449) | static void
  function lzma_ret (line 471) | static lzma_ret
  function lzma_ret (line 514) | static lzma_ret
  function lzma_ret (line 552) | static lzma_ret
  function wait_for_work (line 620) | static bool
  function lzma_ret (line 666) | static lzma_ret
  function stream_encoder_mt_end (line 840) | static void
  function lzma_ret (line 865) | static lzma_ret
  function get_progress (line 915) | static void
  function lzma_ret (line 939) | static lzma_ret
  function lzma_stream_encoder_mt (line 1078) | extern LZMA_API(lzma_ret)
  function lzma_stream_encoder_mt_memusage (line 1096) | extern LZMA_API(uint64_t)

FILE: external/xz/liblzma/common/stream_flags_common.c
  function lzma_stream_flags_compare (line 20) | extern LZMA_API(lzma_ret)

FILE: external/xz/liblzma/common/stream_flags_common.h
  function is_backward_size_valid (line 25) | static inline bool

FILE: external/xz/liblzma/common/stream_flags_decoder.c
  function stream_flags_decode (line 16) | static bool
  function lzma_stream_header_decode (line 30) | extern LZMA_API(lzma_ret)
  function lzma_stream_footer_decode (line 59) | extern LZMA_API(lzma_ret)

FILE: external/xz/liblzma/common/stream_flags_encoder.c
  function stream_flags_encode (line 16) | static bool
  function lzma_stream_header_encode (line 29) | extern LZMA_API(lzma_ret)
  function lzma_stream_footer_encode (line 56) | extern LZMA_API(lzma_ret)

FILE: external/xz/liblzma/common/vli_decoder.c
  function lzma_vli_decode (line 16) | extern LZMA_API(lzma_ret)

FILE: external/xz/liblzma/common/vli_encoder.c
  function lzma_vli_encode (line 16) | extern LZMA_API(lzma_ret)

FILE: external/xz/liblzma/common/vli_size.c
  function lzma_vli_size (line 16) | extern LZMA_API(uint32_t)

FILE: external/xz/liblzma/delta/delta_common.c
  function delta_coder_end (line 17) | static void
  function lzma_ret (line 27) | extern lzma_ret
  function lzma_delta_coder_memusage (line 62) | extern uint64_t

FILE: external/xz/liblzma/delta/delta_decoder.c
  function decode_buffer (line 17) | static void
  function lzma_ret (line 29) | static lzma_ret
  function lzma_ret (line 51) | extern lzma_ret
  function lzma_ret (line 60) | extern lzma_ret

FILE: external/xz/liblzma/delta/delta_encoder.c
  function copy_and_encode (line 20) | static void
  function encode_in_place (line 37) | static void
  function lzma_ret (line 51) | static lzma_ret
  function lzma_ret (line 88) | static lzma_ret
  function lzma_ret (line 103) | extern lzma_ret
  function lzma_ret (line 113) | extern lzma_ret

FILE: external/xz/liblzma/delta/delta_private.h
  type lzma_delta_coder (line 18) | typedef struct {

FILE: external/xz/liblzma/lz/lz_decoder.c
  type lzma_coder (line 23) | typedef struct {
  function lz_decoder_reset (line 54) | static void
  function lzma_ret (line 65) | static lzma_ret
  function lzma_ret (line 133) | static lzma_ret
  function lz_decoder_end (line 193) | static void
  function lzma_ret (line 211) | extern lzma_ret
  function lzma_lz_decoder_memusage (line 299) | extern uint64_t
  function lzma_lz_decoder_uncompressed (line 306) | extern void

FILE: external/xz/liblzma/lz/lz_decoder.h
  type lzma_dict (line 20) | typedef struct {
  type lzma_lz_options (line 47) | typedef struct {
  type lzma_lz_decoder (line 54) | typedef struct {
  function dict_get (line 102) | static inline uint8_t
  function dict_is_empty (line 111) | static inline bool
  function dict_is_distance_valid (line 119) | static inline bool
  function dict_repeat (line 127) | static inline bool
  function dict_put (line 186) | static inline bool
  function dict_write (line 202) | static inline void
  function dict_reset (line 227) | static inline void

FILE: external/xz/liblzma/lz/lz_encoder.c
  type lzma_coder (line 26) | typedef struct {
  function move_window (line 45) | static void
  function lzma_ret (line 80) | static lzma_ret
  function lzma_ret (line 159) | static lzma_ret
  function lz_encoder_prepare (line 192) | static bool
  function lz_encoder_init (line 370) | static bool
  function lzma_lz_encoder_memusage (line 463) | extern uint64_t
  function lz_encoder_end (line 485) | static void
  function lzma_ret (line 506) | static lzma_ret
  function lzma_ret (line 524) | extern lzma_ret
  function lzma_mf_is_supported (line 585) | extern LZMA_API(lzma_bool)

FILE: external/xz/liblzma/lz/lz_encoder.h
  type lzma_match (line 22) | typedef struct {
  type lzma_mf (line 28) | typedef struct lzma_mf_s lzma_mf;
  type lzma_mf_s (line 29) | struct lzma_mf_s {
  type lzma_lz_options (line 129) | typedef struct {
  type lzma_lz_encoder (line 192) | typedef struct {
  function mf_avail (line 228) | static inline uint32_t
  function mf_unencoded (line 237) | static inline uint32_t
  function mf_position (line 251) | static inline uint32_t
  function mf_skip (line 266) | static inline void
  function mf_read (line 278) | static inline void

FILE: external/xz/liblzma/lz/lz_encoder_mf.c
  function lzma_mf_find (line 22) | extern uint32_t
  function normalize (line 107) | static void
  function move_pos (line 149) | static void
  function move_pending (line 177) | static void
  function lzma_match (line 249) | static lzma_match *
  function lzma_mf_hc3_find (line 304) | extern uint32_t
  function lzma_mf_hc3_skip (line 337) | extern void
  function lzma_mf_hc4_find (line 365) | extern uint32_t
  function lzma_mf_hc4_skip (line 416) | extern void
  function lzma_match (line 449) | static lzma_match *
  function bt_skip_func (line 515) | static void
  function lzma_mf_bt2_find (line 586) | extern uint32_t
  function lzma_mf_bt2_skip (line 600) | extern void
  function lzma_mf_bt3_find (line 619) | extern uint32_t
  function lzma_mf_bt3_skip (line 652) | extern void
  function lzma_mf_bt4_find (line 674) | extern uint32_t
  function lzma_mf_bt4_skip (line 725) | extern void

FILE: external/xz/liblzma/lzma/fastpos.h
  function get_dist_slot_2 (line 82) | static inline uint32_t
  function get_dist_slot (line 108) | static inline uint32_t
  function get_dist_slot_2 (line 124) | static inline uint32_t

FILE: external/xz/liblzma/lzma/fastpos_tablegen.c
  function main (line 19) | int

FILE: external/xz/liblzma/lzma/lzma2_decoder.c
  type lzma_lzma2_coder (line 19) | typedef struct {
  function lzma_ret (line 56) | static lzma_ret
  function lzma2_decoder_end (line 213) | static void
  function lzma_ret (line 227) | static lzma_ret
  function lzma_ret (line 256) | extern lzma_ret
  function lzma_lzma2_decoder_memusage (line 269) | extern uint64_t
  function lzma_ret (line 277) | extern lzma_ret

FILE: external/xz/liblzma/lzma/lzma2_encoder.c
  type lzma_lzma2_coder (line 20) | typedef struct {
  function lzma2_header_lzma (line 54) | static void
  function lzma2_header_uncompressed (line 110) | static void
  function lzma_ret (line 135) | static lzma_ret
  function lzma2_encoder_end (line 266) | static void
  function lzma_ret (line 276) | static lzma_ret
  function lzma_ret (line 311) | static lzma_ret
  function lzma_ret (line 358) | extern lzma_ret
  function lzma_lzma2_encoder_memusage (line 367) | extern uint64_t
  function lzma_ret (line 378) | extern lzma_ret
  function lzma_lzma2_block_size (line 403) | extern uint64_t

FILE: external/xz/liblzma/lzma/lzma_common.h
  function is_lclppb_valid (line 32) | static inline bool
  type lzma_lzma_state (line 56) | typedef enum {
  function literal_init (line 129) | static inline void

FILE: external/xz/liblzma/lzma/lzma_decoder.c
  type lzma_length_decoder (line 161) | typedef struct {
  type lzma_lzma1_decoder (line 170) | typedef struct {
  function lzma_ret (line 289) | static lzma_ret
  function lzma_decoder_uncompressed (line 850) | static void
  function lzma_decoder_reset (line 858) | static void
  function lzma_ret (line 941) | extern lzma_ret
  function lzma_ret (line 969) | static lzma_ret
  function lzma_ret (line 986) | extern lzma_ret
  function lzma_lzma_lclppb_decode (line 999) | extern bool
  function lzma_lzma_decoder_memusage_nocheck (line 1015) | extern uint64_t
  function lzma_lzma_decoder_memusage (line 1024) | extern uint64_t
  function lzma_ret (line 1034) | extern lzma_ret

FILE: external/xz/liblzma/lzma/lzma_encoder.c
  function literal_matched (line 23) | static inline void
  function literal (line 45) | static inline void
  function length_update_prices (line 77) | static void
  function length (line 106) | static inline void
  function match (line 142) | static inline void
  function rep_match (line 189) | static inline void
  function encode_symbol (line 233) | static void
  function encode_init (line 267) | static bool
  function encode_eopm (line 295) | static void
  function lzma_ret (line 311) | extern lzma_ret
  function lzma_ret (line 404) | static lzma_ret
  function is_options_valid (line 421) | static bool
  function set_lz_options (line 434) | static void
  function length_encoder_reset (line 452) | static void
  function lzma_ret (line 475) | extern lzma_ret
  function lzma_ret (line 548) | extern lzma_ret
  function lzma_ret (line 608) | static lzma_ret
  function lzma_ret (line 618) | extern lzma_ret
  function lzma_lzma_encoder_memusage (line 627) | extern uint64_t
  function lzma_lzma_lclppb_encode (line 644) | extern bool
  function lzma_ret (line 658) | extern lzma_ret
  function lzma_mode_is_supported (line 673) | extern LZMA_API(lzma_bool)

FILE: external/xz/liblzma/lzma/lzma_encoder.h
  type lzma_lzma1_encoder (line 20) | typedef struct lzma_lzma1_encoder_s lzma_lzma1_encoder;

FILE: external/xz/liblzma/lzma/lzma_encoder_optimum_fast.c
  function lzma_lzma_optimum_fast (line 20) | extern void

FILE: external/xz/liblzma/lzma/lzma_encoder_optimum_normal.c
  function get_literal_price (line 21) | static uint32_t
  function get_len_price (line 57) | static inline uint32_t
  function get_short_rep_price (line 67) | static inline uint32_t
  function get_pure_rep_price (line 76) | static inline uint32_t
  function get_rep_price (line 101) | static inline uint32_t
  function get_dist_len_price (line 111) | static inline uint32_t
  function fill_dist_prices (line 132) | static void
  function fill_align_prices (line 187) | static void
  function make_literal (line 203) | static inline void
  function make_short_rep (line 211) | static inline void
  function backward (line 223) | static void
  function helper1 (line 271) | static inline uint32_t
  function helper2 (line 443) | static inline uint32_t
  function lzma_lzma_optimum_normal (line 803) | extern void

FILE: external/xz/liblzma/lzma/lzma_encoder_presets.c
  function lzma_lzma_preset (line 17) | extern LZMA_API(lzma_bool)

FILE: external/xz/liblzma/lzma/lzma_encoder_private.h
  type lzma_length_encoder (line 39) | typedef struct {
  type lzma_optimal (line 53) | typedef struct {
  type lzma_lzma1_encoder_s (line 71) | struct lzma_lzma1_encoder_s {

FILE: external/xz/liblzma/rangecoder/price.h
  function rc_bit_price (line 28) | static inline uint32_t
  function rc_bit_0_price (line 36) | static inline uint32_t
  function rc_bit_1_price (line 43) | static inline uint32_t
  function rc_bittree_price (line 51) | static inline uint32_t
  function rc_bittree_reverse_price (line 68) | static inline uint32_t
  function rc_direct_price (line 86) | static inline uint32_t

FILE: external/xz/liblzma/rangecoder/range_common.h
  type probability (line 69) | typedef uint16_t probability;

FILE: external/xz/liblzma/rangecoder/range_decoder.h
  type lzma_range_decoder (line 20) | typedef struct {
  function lzma_ret (line 28) | static inline lzma_ret

FILE: external/xz/liblzma/rangecoder/range_encoder.h
  type lzma_range_encoder (line 27) | typedef struct {
  function rc_reset (line 54) | static inline void
  function rc_bit (line 66) | static inline void
  function rc_bittree (line 75) | static inline void
  function rc_bittree_reverse (line 89) | static inline void
  function rc_direct (line 104) | static inline void
  function rc_flush (line 115) | static inline void
  function rc_shift_low (line 123) | static inline bool
  function rc_encode (line 149) | static inline bool
  function rc_pending (line 225) | static inline uint64_t

FILE: external/xz/liblzma/simple/arm.c
  function lzma_ret (line 47) | static lzma_ret
  function lzma_ret (line 56) | extern lzma_ret
  function lzma_ret (line 65) | extern lzma_ret

FILE: external/xz/liblzma/simple/armthumb.c
  function lzma_ret (line 52) | static lzma_ret
  function lzma_ret (line 61) | extern lzma_ret
  function lzma_ret (line 70) | extern lzma_ret

FILE: external/xz/liblzma/simple/ia64.c
  function lzma_ret (line 88) | static lzma_ret
  function lzma_ret (line 97) | extern lzma_ret
  function lzma_ret (line 106) | extern lzma_ret

FILE: external/xz/liblzma/simple/powerpc.c
  function lzma_ret (line 52) | static lzma_ret
  function lzma_ret (line 61) | extern lzma_ret
  function lzma_ret (line 70) | extern lzma_ret

FILE: external/xz/liblzma/simple/simple_coder.c
  function lzma_ret (line 20) | static lzma_ret
  function call_filter (line 57) | static size_t
  function lzma_ret (line 68) | static lzma_ret
  function simple_coder_end (line 210) | static void
  function lzma_ret (line 221) | static lzma_ret
  function lzma_ret (line 234) | extern lzma_ret

FILE: external/xz/liblzma/simple/simple_decoder.c
  function lzma_ret (line 16) | extern lzma_ret

FILE: external/xz/liblzma/simple/simple_encoder.c
  function lzma_ret (line 16) | extern lzma_ret
  function lzma_ret (line 25) | extern lzma_ret

FILE: external/xz/liblzma/simple/simple_private.h
  type lzma_simple_coder (line 19) | typedef struct {

FILE: external/xz/liblzma/simple/sparc.c
  function lzma_ret (line 59) | static lzma_ret
  function lzma_ret (line 68) | extern lzma_ret
  function lzma_ret (line 77) | extern lzma_ret

FILE: external/xz/liblzma/simple/x86.c
  type lzma_simple_x86 (line 20) | typedef struct {
  function x86_code (line 26) | static size_t
  function lzma_ret (line 126) | static lzma_ret
  function lzma_ret (line 144) | extern lzma_ret
  function lzma_ret (line 153) | extern lzma_ret

FILE: external/xz_config/config.h
  type sigset_t (line 10) | typedef unsigned long long sigset_t;

FILE: external/zlib/adler32.c
  function uLong (line 65) | uLong ZEXPORT adler32(adler, buf, len)
  function local (line 136) | local uLong adler32_combine_(adler1, adler2, len2)
  function uLong (line 165) | uLong ZEXPORT adler32_combine(adler1, adler2, len2)
  function uLong (line 173) | uLong ZEXPORT adler32_combine64(adler1, adler2, len2)

FILE: external/zlib/compress.c
  function compress2 (line 22) | int ZEXPORT compress2 (dest, destLen, source, sourceLen, level)
  function compress (line 62) | int ZEXPORT compress (dest, destLen, source, sourceLen)
  function uLong (line 75) | uLong ZEXPORT compressBound (sourceLen)

FILE: external/zlib/crc32.c
  function local (line 90) | local void make_crc_table()
  function local (line 167) | local void write_table(out, table)
  function z_crc_t (line 190) | const z_crc_t FAR * ZEXPORT get_crc_table()
  function crc32 (line 204) | unsigned long ZEXPORT crc32(crc, buf, len)
  function crc32_little (line 247) | local unsigned long crc32_little(crc, buf, len)
  function crc32_big (line 287) | local unsigned long crc32_big(crc, buf, len)
  function gf2_matrix_times (line 327) | local unsigned long gf2_matrix_times(mat, vec)
  function local (line 344) | local void gf2_matrix_square(square, mat)
  function local (line 355) | local uLong crc32_combine_(crc1, crc2, len2)
  function uLong (line 411) | uLong ZEXPORT crc32_combine(crc1, crc2, len2)
  function uLong (line 419) | uLong ZEXPORT crc32_combine64(crc1, crc2, len2)

FILE: external/zlib/deflate.c
  type block_state (line 66) | typedef enum {
  type block_state (line 73) | typedef block_state (*compress_func)
  type config (line 117) | typedef struct config_s {
  type static_tree_desc_s (line 155) | struct static_tree_desc_s {int dummy;}
  function deflateInit_ (line 201) | int ZEXPORT deflateInit_(strm, level, version, stream_size)
  function deflateInit2_ (line 213) | int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, str...
  function deflateSetDictionary (line 323) | int ZEXPORT deflateSetDictionary (strm, dictionary, dictLength)
  function deflateResetKeep (line 392) | int ZEXPORT deflateResetKeep (strm)
  function deflateReset (line 427) | int ZEXPORT deflateReset (strm)
  function deflateSetHeader (line 439) | int ZEXPORT deflateSetHeader (strm, head)
  function deflatePending (line 450) | int ZEXPORT deflatePending (strm, pending, bits)
  function deflatePrime (line 464) | int ZEXPORT deflatePrime (strm, bits, value)
  function deflateParams (line 490) | int ZEXPORT deflateParams(strm, level, strategy)
  function deflateTune (line 531) | int ZEXPORT deflateTune(strm, good_length, max_lazy, nice_length, max_ch...
  function uLong (line 566) | uLong ZEXPORT deflateBound(strm, sourceLen)
  function local (line 628) | local void putShortMSB (s, b)
  function local (line 642) | local void flush_pending(strm)
  function deflate (line 665) | int ZEXPORT deflate (strm, flush)
  function deflateEnd (line 979) | int ZEXPORT deflateEnd (strm)
  function deflateCopy (line 1014) | int ZEXPORT deflateCopy (dest, source)
  function local (line 1076) | local int read_buf(strm, buf, size)
  function local (line 1106) | local void lm_init (s)
  function local (line 1148) | local uInt longest_match(s, cur_match)
  function local (line 1297) | local uInt longest_match(s, cur_match)
  function local (line 1356) | local void check_match(s, start, match, length)
  function local (line 1390) | local void fill_window(s)
  function local (line 1564) | local block_state deflate_stored(s, flush)
  function local (line 1628) | local block_state deflate_fast(s, flush)
  function local (line 1730) | local block_state deflate_slow(s, flush)
  function local (line 1861) | local block_state deflate_rle(s, flush)
  function local (line 1934) | local block_state deflate_huff(s, flush)

FILE: external/zlib/deflate.h
  type ct_data (line 65) | typedef struct ct_data_s {
  type static_tree_desc (line 81) | typedef struct static_tree_desc_s  static_tree_desc;
  type tree_desc (line 83) | typedef struct tree_desc_s {
  type ush (line 89) | typedef ush Pos;
  type Pos (line 90) | typedef Pos FAR Posf;
  type IPos (line 91) | typedef unsigned IPos;
  type deflate_state (line 97) | typedef struct internal_state {

FILE: external/zlib/gzclose.c
  function gzclose (line 11) | int ZEXPORT gzclose(file)

FILE: external/zlib/gzguts.h
  type gz_state (line 161) | typedef struct {
  type gz_state (line 193) | typedef gz_state FAR *gz_statep;

FILE: external/zlib/gzlib.c
  function local (line 75) | local void gz_reset(state)
  function local (line 91) | local gzFile gz_open(path, fd, mode)
  function gzFile (line 268) | gzFile ZEXPORT gzopen(path, mode)
  function gzFile (line 276) | gzFile ZEXPORT gzopen64(path, mode)
  function gzFile (line 284) | gzFile ZEXPORT gzdopen(fd, mode)
  function gzFile (line 305) | gzFile ZEXPORT gzopen_w(path, mode)
  function gzbuffer (line 314) | int ZEXPORT gzbuffer(file, size)
  function gzrewind (line 339) | int ZEXPORT gzrewind(file)
  function z_off64_t (line 362) | z_off64_t ZEXPORT gzseek64(file, offset, whence)
  function z_off_t (line 439) | z_off_t ZEXPORT gzseek(file, offset, whence)
  function z_off64_t (line 451) | z_off64_t ZEXPORT gztell64(file)
  function z_off_t (line 468) | z_off_t ZEXPORT gztell(file)
  function z_off64_t (line 478) | z_off64_t ZEXPORT gzoffset64(file)
  function z_off_t (line 501) | z_off_t ZEXPORT gzoffset(file)
  function gzeof (line 511) | int ZEXPORT gzeof(file)
  function gzclearerr (line 549) | void ZEXPORT gzclearerr(file)
  function gz_error (line 575) | void ZLIB_INTERNAL gz_error(state, err, msg)
  function gz_intmax (line 622) | unsigned ZLIB_INTERNAL gz_intmax()

FILE: external/zlib/gzread.c
  function local (line 20) | local int gz_load(state, buf, len, have)
  function local (line 51) | local int gz_avail(state)
  function local (line 86) | local int gz_look(state)
  function local (line 172) | local int gz_decomp(state)
  function local (line 226) | local int gz_fetch(state)
  function local (line 256) | local int gz_skip(state, len)
  function gzread (line 288) | int ZEXPORT gzread(file, buf, len)
  function gzgetc (line 387) | int ZEXPORT gzgetc(file)
  function gzgetc_ (line 416) | int ZEXPORT gzgetc_(file)
  function gzungetc (line 423) | int ZEXPORT gzungetc(c, file)
  function gzdirect (line 547) | int ZEXPORT gzdirect(file)
  function gzclose_r (line 567) | int ZEXPORT gzclose_r(file)

FILE: external/zlib/gzwrite.c
  function local (line 15) | local int gz_init(state)
  function local (line 70) | local int gz_comp(state, flush)
  function local (line 133) | local int gz_zero(state, len)
  function gzwrite (line 165) | int ZEXPORT gzwrite(file, buf, len)
  function gzputc (line 245) | int ZEXPORT gzputc(file, c)
  function gzputs (line 293) | int ZEXPORT gzputs(file, str)
  function gzvprintf (line 310) | int ZEXPORTVA gzvprintf(gzFile file, const char *format, va_list va)
  function gzprintf (line 372) | int ZEXPORTVA gzprintf(gzFile file, const char *format, ...)
  function ZEXPORTVA (line 386) | int ZEXPORTVA gzprintf (file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9...
  function gzflush (line 465) | int ZEXPORT gzflush(file, flush)
  function gzsetparams (line 497) | int ZEXPORT gzsetparams(file, level, strategy)
  function gzclose_w (line 539) | int ZEXPORT gzclose_w(file)

FILE: external/zlib/infback.c
  type inflate_state (line 19) | struct inflate_state
  function inflateBackInit_ (line 28) | int ZEXPORT inflateBackInit_(strm, windowBits, window, version, stream_s...
  function local (line 82) | local void fixedtables(state)
  function inflateBack (line 250) | int ZEXPORT inflateBack(strm, in, in_desc, out, out_desc)
  function inflateBackEnd (line 631) | int ZEXPORT inflateBackEnd(strm)

FILE: external/zlib/inffast.c
  function inflate_fast (line 67) | void ZLIB_INTERNAL inflate_fast(strm, start)

FILE: external/zlib/inflate.c
  type inflate_state (line 95) | struct inflate_state
  function inflateResetKeep (line 104) | int ZEXPORT inflateResetKeep(strm)
  function inflateReset (line 129) | int ZEXPORT inflateReset(strm)
  function inflateReset2 (line 142) | int ZEXPORT inflateReset2(strm, windowBits)
  function inflateInit2_ (line 180) | int ZEXPORT inflateInit2_(strm, windowBits, version, stream_size)
  function inflateInit_ (line 222) | int ZEXPORT inflateInit_(strm, version, stream_size)
  function inflatePrime (line 230) | int ZEXPORT inflatePrime(strm, bits, value)
  function local (line 261) | local void fixedtables(state)
  function makefixed (line 325) | void makefixed()
  function local (line 379) | local int updatewindow(strm, end, copy)
  type inflate_state (line 609) | struct inflate_state
  type inflate_state (line 632) | struct inflate_state
  type inflate_state (line 1257) | struct inflate_state
  type inflate_state (line 1260) | struct inflate_state
  type inflate_state (line 1273) | struct inflate_state
  type inflate_state (line 1277) | struct inflate_state
  type inflate_state (line 1296) | struct inflate_state
  type inflate_state (line 1302) | struct inflate_state
  type inflate_state (line 1330) | struct inflate_state
  type inflate_state (line 1334) | struct inflate_state
  type inflate_state (line 1383) | struct inflate_state
  type inflate_state (line 1387) | struct inflate_state
  type inflate_state (line 1431) | struct inflate_state
  type inflate_state (line 1434) | struct inflate_state
  type inflate_state (line 1442) | struct inflate_state
  type inflate_state (line 1443) | struct inflate_state
  type inflate_state (line 1451) | struct inflate_state
  type inflate_state (line 1454) | struct inflate_state
  type inflate_state (line 1455) | struct inflate_state
  type inflate_state (line 1469) | struct inflate_state
  type internal_state (line 1481) | struct internal_state
  type inflate_state (line 1489) | struct inflate_state
  type inflate_state (line 1492) | struct inflate_state
  type inflate_state (line 1505) | struct inflate_state
  type inflate_state (line 1508) | struct inflate_state

FILE: external/zlib/inflate.h
  type inflate_mode (line 20) | typedef enum {
  type inflate_state (line 81) | struct inflate_state {

FILE: external/zlib/inftrees.c
  function inflate_table (line 32) | int ZLIB_INTERNAL inflate_table(type, lens, codes, table, bits, work)

FILE: external/zlib/inftrees.h
  type code (line 24) | typedef struct {
  type codetype (line 54) | typedef enum {

FILE: external/zlib/trees.c
  type static_tree_desc_s (line 117) | struct static_tree_desc_s {
  function local (line 188) | local void send_bits(s, value, length)
  function local (line 234) | local void tr_static_init()
  function gen_trees_header (line 328) | void gen_trees_header()
  function _tr_init (line 381) | void ZLIB_INTERNAL _tr_init(s)
  function local (line 409) | local void init_block(s)
  function local (line 453) | local void pqdownheap(s, tree, k)
  function local (line 488) | local void gen_bitlen(s, desc)
  function local (line 575) | local void gen_codes (tree, max_code, bl_count)
  function local (line 617) | local void build_tree(s, desc)
  function local (line 705) | local void scan_tree (s, tree, max_code)
  function local (line 750) | local void send_tree (s, tree, max_code)
  function local (line 801) | local int build_bl_tree(s)
  function local (line 836) | local void send_all_trees(s, lcodes, dcodes, blcodes)
  function _tr_stored_block (line 865) | void ZLIB_INTERNAL _tr_stored_block(s, buf, stored_len, last)
  function _tr_flush_bits (line 882) | void ZLIB_INTERNAL _tr_flush_bits(s)
  function _tr_align (line 892) | void ZLIB_INTERNAL _tr_align(s)
  function ZLIB_INTERNAL (line 1010) | int ZLIB_INTERNAL _tr_tally (s, dist, lc)
  function local (line 1060) | local void compress_block(s, ltree, dtree)
  function local (line 1120) | local int detect_data_type(s)
  function bi_reverse (line 1154) | local unsigned bi_reverse(code, len)
  function local (line 1169) | local void bi_flush(s)
  function local (line 1186) | local void bi_windup(s)
  function local (line 1205) | local void copy_block(s, buf, len, header)

FILE: external/zlib/uncompr.c
  function uncompress (line 24) | int ZEXPORT uncompress (dest, destLen, source, sourceLen)

FILE: external/zlib/zconf.h
  type Byte (line 368) | typedef unsigned char  Byte;
  type uInt (line 370) | typedef unsigned int   uInt;
  type uLong (line 371) | typedef unsigned long  uLong;
  type Byte (line 377) | typedef Byte  FAR Bytef;
  type charf (line 379) | typedef char  FAR charf;
  type intf (line 380) | typedef int   FAR intf;
  type uInt (line 381) | typedef uInt  FAR uIntf;
  type uLong (line 382) | typedef uLong FAR uLongf;
  type Byte (line 389) | typedef Byte const *voidpc;
  type Byte (line 390) | typedef Byte FAR   *voidpf;
  type Byte (line 391) | typedef Byte       *voidp;
  type Z_U4 (line 406) | typedef Z_U4 z_crc_t;
  type z_crc_t (line 408) | typedef unsigned long z_crc_t;

FILE: external/zlib/zlib.h
  type voidpf (line 80) | typedef voidpf (*alloc_func)
  type internal_state (line 83) | struct internal_state
  type z_stream (line 85) | typedef struct z_stream_s {
  type z_stream (line 106) | typedef z_stream FAR *z_streamp;
  type gz_header (line 112) | typedef struct gz_header_s {
  type gz_header (line 129) | typedef gz_header FAR *gz_headerp;
  type gzFile_s (line 1224) | struct gzFile_s
  type gzFile_s (line 1670) | struct gzFile_s {
  type internal_state (line 1742) | struct internal_state {int dummy;}

FILE: external/zlib/zutil.c
  type internal_state (line 14) | struct internal_state      {int dummy;}
  function uLong (line 35) | uLong ZEXPORT zlibCompileFlags()
  function ZLIB_INTERNAL (line 125) | void ZLIB_INTERNAL z_error (m)
  function zmemcpy (line 152) | void ZLIB_INTERNAL zmemcpy(dest, source, len)
  function zmemcmp (line 163) | int ZLIB_INTERNAL zmemcmp(s1, s2, len)
  function zmemzero (line 176) | void ZLIB_INTERNAL zmemzero(dest, len)
  type ptr_table (line 207) | typedef struct ptr_table_s {
  function voidpf (line 220) | voidpf ZLIB_INTERNAL zcalloc (voidpf opaque, unsigned items, unsigned size)
  function ZLIB_INTERNAL (line 244) | void ZLIB_INTERNAL zcfree (voidpf opaque, voidpf ptr)
  function voidpf (line 279) | voidpf ZLIB_INTERNAL zcalloc (voidpf opaque, uInt items, uInt size)
  function ZLIB_INTERNAL (line 285) | void ZLIB_INTERNAL zcfree (voidpf opaque, voidpf ptr)
  function voidpf (line 304) | voidpf ZLIB_INTERNAL zcalloc (opaque, items, size)
  function ZLIB_INTERNAL (line 314) | void ZLIB_INTERNAL zcfree (opaque, ptr)

FILE: external/zlib/zutil.h
  type uch (line 41) | typedef unsigned char  uch;
  type uch (line 42) | typedef uch FAR uchf;
  type ush (line 43) | typedef unsigned short ush;
  type ush (line 44) | typedef ush FAR ushf;
  type ulg (line 45) | typedef unsigned long  ulg;

FILE: external/zopfli/blocksplitter.c
  function FindMinimum (line 43) | static size_t FindMinimum(FindMinimumFun f, void* context,
  function EstimateCost (line 108) | static double EstimateCost(const ZopfliLZ77Store* lz77,
  type SplitCostContext (line 113) | typedef struct SplitCostContext {
  function SplitCost (line 125) | static double SplitCost(size_t i, void* context) {
  function AddSorted (line 130) | static void AddSorted(size_t value, size_t** out, size_t* outsize) {
  function PrintBlockSplitPoints (line 148) | static void PrintBlockSplitPoints(const ZopfliLZ77Store* lz77,
  function FindLargestSplittableBlock (line 195) | static int FindLargestSplittableBlock(
  function ZopfliBlockSplitLZ77 (line 215) | void ZopfliBlockSplitLZ77(const ZopfliOptions* options,
  function ZopfliBlockSplit (line 275) | void ZopfliBlockSplit(const ZopfliOptions* options,
  function ZopfliBlockSplitSimple (line 322) | void ZopfliBlockSplitSimple(const unsigned char* in,

FILE: external/zopfli/cache.c
  function ZopfliInitCache (line 28) | void ZopfliInitCache(size_t blocksize, ZopfliLongestMatchCache* lmc) {
  function ZopfliCleanCache (line 48) | void ZopfliCleanCache(ZopfliLongestMatchCache* lmc) {
  function ZopfliSublenToCache (line 54) | void ZopfliSublenToCache(const unsigned short* sublen,
  function ZopfliCacheToSublen (line 87) | void ZopfliCacheToSublen(const ZopfliLongestMatchCache* lmc,
  function ZopfliMaxCachedSublen (line 113) | unsigned ZopfliMaxCachedSublen(const ZopfliLongestMatchCache* lmc,

FILE: external/zopfli/cache.h
  type ZopfliLongestMatchCache (line 39) | typedef struct ZopfliLongestMatchCache {

FILE: external/zopfli/deflate.c
  function AddBit (line 38) | static void AddBit(int bit,
  function AddBits (line 45) | static void AddBits(unsigned symbol, unsigned length,
  function AddHuffmanBits (line 61) | static void AddHuffmanBits(unsigned symbol, unsigned length,
  function PatchDistanceCodesForBuggyDecoders (line 86) | static void PatchDistanceCodesForBuggyDecoders(unsigned* d_lengths) {
  function EncodeTree (line 105) | static size_t EncodeTree(const unsigned* ll_lengths,
  function AddDynamicTree (line 251) | static void AddDynamicTree(const unsigned* ll_lengths,
  function CalculateTreeSize (line 277) | static size_t CalculateTreeSize(const unsigned* ll_lengths,
  function AddLZ77Data (line 297) | static void AddLZ77Data(const ZopfliLZ77Store* lz77,
  function GetFixedTree (line 335) | static void GetFixedTree(unsigned* ll_lengths, unsigned* d_lengths) {
  function CalculateBlockSymbolSizeSmall (line 348) | static size_t CalculateBlockSymbolSizeSmall(const unsigned* ll_lengths,
  function CalculateBlockSymbolSizeGivenCounts (line 375) | static size_t CalculateBlockSymbolSizeGivenCounts(const size_t* ll_counts,
  function CalculateBlockSymbolSize (line 406) | static size_t CalculateBlockSymbolSize(const unsigned* ll_lengths,
  function AbsDiff (line 422) | static size_t AbsDiff(size_t x, size_t y) {
  function OptimizeHuffmanForRle (line 434) | void OptimizeHuffmanForRle(int length, size_t* counts) {
  function TryOptimizeHuffmanForRle (line 525) | static double TryOptimizeHuffmanForRle(
  function GetDynamicLengths (line 569) | static double GetDynamicLengths(const ZopfliLZ77Store* lz77,
  function ZopfliCalculateBlockSize (line 584) | double ZopfliCalculateBlockSize(const ZopfliLZ77Store* lz77,
  function ZopfliCalculateBlockSizeAutoType (line 610) | double ZopfliCalculateBlockSizeAutoType(const ZopfliLZ77Store* lz77,
  function AddNonCompressedBlock (line 625) | static void AddNonCompressedBlock(const ZopfliOptions* options, int final,
  function AddLZ77Block (line 682) | static void AddLZ77Block(const ZopfliOptions* options, int btype, int fi...
  function AddLZ77BlockAutoType (line 747) | static void AddLZ77BlockAutoType(const ZopfliOptions* options, int final,
  function ZopfliDeflatePart (line 811) | void ZopfliDeflatePart(const ZopfliOptions* options, int btype, int final,
  function ZopfliDeflate (line 908) | void ZopfliDeflate(const ZopfliOptions* options, int btype, int final,

FILE: external/zopfli/gzip_container.c
  function CRC (line 75) | static unsigned long CRC(const unsigned char* data, size_t size) {
  function ZopfliGzipCompress (line 84) | void ZopfliGzipCompress(const ZopfliOptions* options,

FILE: external/zopfli/hash.c
  function ZopfliAllocHash (line 29) | void ZopfliAllocHash(size_t window_size, ZopfliHash* h) {
  function ZopfliResetHash (line 45) | void ZopfliResetHash(size_t window_size, ZopfliHash* h) {
  function ZopfliCleanHash (line 75) | void ZopfliCleanHash(ZopfliHash* h) {
  function UpdateHashValue (line 96) | static void UpdateHashValue(ZopfliHash* h, unsigned char c) {
  function ZopfliUpdateHash (line 100) | void ZopfliUpdateHash(const unsigned char* array, size_t pos, size_t end,
  function ZopfliWarmupHash (line 139) | void ZopfliWarmupHash(const unsigned char* array, size_t pos, size_t end,

FILE: external/zopfli/hash.h
  type ZopfliHash (line 29) | typedef struct ZopfliHash {

FILE: external/zopfli/katajainen.c
  type Node (line 31) | typedef struct Node Node;
  type Node (line 36) | struct Node {
  type NodePool (line 45) | typedef struct NodePool {
  function InitNode (line 52) | static void InitNode(size_t weight, int count, Node* tail, Node* node) {
  function BoundaryPM (line 69) | static void BoundaryPM(Node* (*lists)[2], Node* leaves, int numsymbols,
  function BoundaryPMFinal (line 103) | static void BoundaryPMFinal(Node* (*lists)[2],
  function InitLists (line 125) | static void InitLists(
  function ExtractBitLengths (line 143) | static void ExtractBitLengths(Node* chain, Node* leaves, unsigned* bitle...
  function LeafComparator (line 168) | static int LeafComparator(const void* a, const void* b) {
  function ZopfliLengthLimitedCodeLengths (line 172) | int ZopfliLengthLimitedCodeLengths(

FILE: external/zopfli/lz77.c
  function ZopfliInitLZ77Store (line 28) | void ZopfliInitLZ77Store(const unsigned char* data, ZopfliLZ77Store* sto...
  function ZopfliCleanLZ77Store (line 40) | void ZopfliCleanLZ77Store(ZopfliLZ77Store* store) {
  function CeilDiv (line 50) | static size_t CeilDiv(size_t a, size_t b) {
  function ZopfliCopyLZ77Store (line 54) | void ZopfliCopyLZ77Store(
  function ZopfliStoreLitLenDist (line 98) | void ZopfliStoreLitLenDist(unsigned short length, unsigned short dist,
  function ZopfliAppendLZ77Store (line 151) | void ZopfliAppendLZ77Store(const ZopfliLZ77Store* store,
  function ZopfliLZ77GetByteRange (line 160) | size_t ZopfliLZ77GetByteRange(const ZopfliLZ77Store* lz77,
  function ZopfliLZ77GetHistogramAt (line 168) | static void ZopfliLZ77GetHistogramAt(const ZopfliLZ77Store* lz77, size_t...
  function ZopfliLZ77GetHistogram (line 189) | void ZopfliLZ77GetHistogram(const ZopfliLZ77Store* lz77,
  function ZopfliInitBlockState (line 219) | void ZopfliInitBlockState(const ZopfliOptions* options,
  function ZopfliCleanBlockState (line 235) | void ZopfliCleanBlockState(ZopfliBlockState* s) {
  function GetLengthScore (line 265) | static int GetLengthScore(int length, int distance) {
  function ZopfliVerifyLenDist (line 273) | void ZopfliVerifyLenDist(const unsigned char* data, size_t datasize, siz...
  function TryGetFromLongestMatchCache (line 340) | static int TryGetFromLongestMatchCache(ZopfliBlockState* s,
  function StoreInLongestMatchCache (line 384) | static void StoreInLongestMatchCache(ZopfliBlockState* s,
  function ZopfliFindLongestMatch (line 407) | void ZopfliFindLongestMatch(ZopfliBlockState* s, const ZopfliHash* h,
  function ZopfliLZ77Greedy (line 544) | void ZopfliLZ77Greedy(ZopfliBlockState* s, const unsigned char* in,

FILE: external/zopfli/lz77.h
  type ZopfliLZ77Store (line 44) | typedef struct ZopfliLZ77Store {
  type ZopfliBlockState (line 86) | typedef struct ZopfliBlockState {

FILE: external/zopfli/squeeze.c
  type SymbolStats (line 32) | typedef struct SymbolStats {
  function InitStats (line 45) | static void InitStats(SymbolStats* stats) {
  function CopyStats (line 53) | static void CopyStats(SymbolStats* source, SymbolStats* dest) {
  function AddWeighedStatFreqs (line 65) | static void AddWeighedStatFreqs(const SymbolStats* stats1, double w1,
  type RanState (line 80) | typedef struct RanState {
  function InitRanState (line 84) | static void InitRanState(RanState* state) {
  function Ran (line 90) | static unsigned int Ran(RanState* state) {
  function RandomizeFreqs (line 96) | static void RandomizeFreqs(RanState* state, size_t* freqs, int n) {
  function RandomizeStatFreqs (line 103) | static void RandomizeStatFreqs(RanState* state, SymbolStats* stats) {
  function ClearStatFreqs (line 109) | static void ClearStatFreqs(SymbolStats* stats) {
  function GetCostFixed (line 125) | static double GetCostFixed(unsigned litlen, unsigned dist, void* unused) {
  function GetCostStat (line 146) | static double GetCostStat(unsigned litlen, unsigned dist, void* context) {
  function GetCostModelMinCost (line 163) | static double GetCostModelMinCost(CostModelFun* costmodel, void* costcon...
  function zopfli_min (line 200) | static size_t zopfli_min(size_t a, size_t b) {
  function GetBestLengths (line 217) | static double GetBestLengths(ZopfliBlockState *s,
  function TraceBackwards (line 317) | static void TraceBackwards(size_t size, const unsigned short* length_array,
  function FollowPath (line 338) | static void FollowPath(ZopfliBlockState* s,
  function CalculateStatistics (line 392) | static void CalculateStatistics(SymbolStats* stats) {
  function GetStatistics (line 398) | static void GetStatistics(const ZopfliLZ77Store* store, SymbolStats* sta...
  function LZ77OptimalRun (line 429) | static double LZ77OptimalRun(ZopfliBlockState* s,
  function ZopfliLZ77Optimal (line 446) | void ZopfliLZ77Optimal(ZopfliBlockState *s,
  function ZopfliLZ77OptimalFixed (line 528) | void ZopfliLZ77OptimalFixed(ZopfliBlockState *s,

FILE: external/zopfli/symbols.h
  function ZopfliGetDistExtraBits (line 38) | static int ZopfliGetDistExtraBits(int dist) {
  function ZopfliGetDistExtraBitsValue (line 61) | static int ZopfliGetDistExtraBitsValue(int dist) {
  function ZopfliGetDistSymbol (line 88) | static int ZopfliGetDistSymbol(int dist) {
  function ZopfliGetLengthExtraBits (line 138) | static int ZopfliGetLengthExtraBits(int l) {
  function ZopfliGetLengthExtraBitsValue (line 161) | static int ZopfliGetLengthExtraBitsValue(int l) {
  function ZopfliGetLengthSymbol (line 183) | static int ZopfliGetLengthSymbol(int l) {
  function ZopfliGetLengthSymbolExtraBits (line 222) | static int ZopfliGetLengthSymbolExtraBits(int s) {
  function ZopfliGetDistSymbolExtraBits (line 231) | static int ZopfliGetDistSymbolExtraBits(int s) {

FILE: external/zopfli/tree.c
  function ZopfliLengthsToSymbols (line 30) | void ZopfliLengthsToSymbols(const unsigned* lengths, size_t n, unsigned ...
  function ZopfliCalculateEntropy (line 71) | void ZopfliCalculateEntropy(const size_t* count, size_t n, double* bitle...
  function ZopfliCalculateBitLengths (line 96) | void ZopfliCalculateBitLengths(const size_t* count, size_t n, int maxbits,

FILE: external/zopfli/util.c
  function ZopfliInitOptions (line 28) | void ZopfliInitOptions(ZopfliOptions* options) {

FILE: external/zopfli/zlib_container.c
  function adler32 (line 29) | static unsigned adler32(const unsigned char* data, size_t size)
  function ZopfliZlibCompress (line 50) | void ZopfliZlibCompress(const ZopfliOptions* options,

FILE: external/zopfli/zopfli.h
  type ZopfliOptions (line 33) | typedef struct ZopfliOptions {
  type ZopfliFormat (line 70) | typedef enum {

FILE: external/zopfli/zopfli_bin.c
  function LoadFile (line 45) | static int LoadFile(const char* filename,
  function SaveFile (line 84) | static void SaveFile(const char* filename,
  function CompressFile (line 99) | static void CompressFile(const ZopfliOptions* options,
  function StringsEqual (line 140) | static char StringsEqual(const char* str1, const char* str2) {
  function main (line 144) | int main(int argc, char* argv[]) {

FILE: external/zopfli/zopfli_lib.c
  function ZopfliCompress (line 28) | void ZopfliCompress(const ZopfliOptions* options, ZopfliFormat output_type,

FILE: format.cpp
  function format_t (line 9) | format_t check_fmt(const void *buf, size_t len) {
  function format_t (line 99) | format_t Name2Fmt::operator[](std::string_view name) {

FILE: format.hpp
  class Fmt2Name (line 67) | class Fmt2Name {
  class Fmt2Ext (line 72) | class Fmt2Ext {
  class Name2Fmt (line 77) | class Name2Fmt {

FILE: hexpatch.cpp
  function hex2byte (line 9) | static void hex2byte(const char *hex, uint8_t *buf) {
  function hexpatch (line 18) | int hexpatch(const char *file, const char *from, const char *to) {

FILE: magiskbase/files.cpp
  function fd_path (line 23) | ssize_t fd_path(int fd, char *path, size_t size) {
  function fd_pathat (line 28) | int fd_pathat(int dirfd, const char *name, char *path, size_t size) {
  function mkdirs (line 38) | int mkdirs(const char *path, mode_t mode) {
  function post_order_walk (line 61) | static void post_order_walk(int dirfd, const Func &fn) {
  type walk_result (line 72) | enum walk_result {
  function walk_result (line 77) | static walk_result pre_order_walk(int dirfd, const Func &fn) {
  function remove_at (line 102) | static void remove_at(int dirfd, struct dirent *entry) {
  function frm_rf (line 106) | void frm_rf(int dirfd) {
  function rm_rf (line 110) | void rm_rf(const char *path) {
  function mv_path (line 121) | void mv_path(const char *src, const char *dest) {
  function mv_dir (line 136) | void mv_dir(int src, int dest) {
  function cp_afc (line 159) | void cp_afc(const char *src, const char *dest) {
  function clone_dir (line 183) | void clone_dir(int src, int dest) {
  function link_path (line 218) | void link_path(const char *src, const char *dest) {
  function link_dir (line 222) | void link_dir(int src, int dest) {
  function getattr (line 240) | int getattr(const char *path, file_attr *a) {
  function getattrat (line 251) | int getattrat(int dirfd, const char *name, file_attr *a) {
  function fgetattr (line 257) | int fgetattr(int fd, file_attr *a) {
  function setattr (line 268) | int setattr(const char *path, file_attr *a) {
  function setattrat (line 278) | int setattrat(int dirfd, const char *name, file_attr *a) {
  function fsetattr (line 284) | int fsetattr(int fd, file_attr *a) {
  function clone_attr (line 294) | void clone_attr(const char *src, const char *dest) {
  function fclone_attr (line 300) | void fclone_attr(int src, int dest) {
  function full_read (line 307) | void full_read(int fd, string &str) {
  function full_read (line 313) | void full_read(const char *filename, string &str) {
  function string (line 320) | string full_read(int fd) {
  function string (line 326) | string full_read(const char *filename) {
  function write_zero (line 332) | void write_zero(int fd, size_t size) {
  function file_readline (line 342) | void file_readline(bool trim, FILE *fp, const function<bool(string_view)...
  function file_readline (line 362) | void file_readline(bool trim, const char *file, const function<bool(stri...
  function file_readline (line 367) | void file_readline(const char *file, const function<bool(string_view)> &...
  function parse_prop_file (line 371) | void parse_prop_file(FILE *fp, const function<bool(string_view, string_v...
  function parse_prop_file (line 384) | void parse_prop_file(const char *file, const function<bool(string_view, ...
  type mntent (line 392) | struct mntent
  type mntent (line 392) | struct mntent
  function parse_mnt (line 415) | void parse_mnt(const char *file, const function<bool(mntent*)> &fn) {
  function backup_folder (line 429) | void backup_folder(const char *dir, vector<raw_file> &files) {
  function restore_folder (line 455) | void restore_folder(const char *dir, vector<raw_file> &files) {
  function sDIR (line 473) | sDIR make_dir(DIR *dp) {
  function sFILE (line 481) | sFILE make_file(FILE *fp) {
  type stat (line 524) | struct stat
  function string (line 546) | string find_apk_path(const char *pkg) {

FILE: magiskbase/files.hpp
  function T (line 15) | static inline T align_to(T v, int a) {
  function T (line 21) | static inline T align_padding(T v, int a) {
  type file_attr (line 25) | struct file_attr {
    type stat (line 26) | struct stat
  type byte_data (line 30) | struct byte_data {
    method patch (line 36) | int patch(str_pairs list) { return patch(true, list); }
  type raw_file (line 43) | struct raw_file {
    method raw_file (line 48) | raw_file() : attr{} {}
    method raw_file (line 49) | raw_file(const raw_file&) = delete;
    method raw_file (line 50) | raw_file(raw_file &&o) : path(std::move(o.path)), attr(o.attr), conten...
  type mmap_data (line 53) | struct mmap_data : public byte_data {
    method mmap_data (line 54) | mmap_data() = default;
    method mmap_data (line 55) | mmap_data(const mmap_data&) = delete;
    method mmap_data (line 56) | mmap_data(mmap_data &&o) { swap(o); }
    method mmap_data (line 59) | mmap_data& operator=(mmap_data &&other) { swap(other); return *this; }
  type delDIR (line 101) | struct delDIR {
  function sDIR (line 117) | static inline sDIR open_dir(const char *path) {
  function sDIR (line 121) | static inline sDIR xopen_dir(const char *path) {
  function sDIR (line 126) | static inline sDIR xopen_dir(int dirfd) {
  function sFILE (line 131) | static inline sFILE open_file(const char *path, const char *mode) {
  function sFILE (line 135) | static inline sFILE xopen_file(const char *path, const char *mode) {
  function sFILE (line 139) | static inline sFILE xopen_file(int fd, const char *mode) {

FILE: magiskbase/include/stream.hpp
  class stream (line 11) | class stream {
  class filter_stream (line 25) | class filter_stream : public stream {
    method filter_stream (line 27) | filter_stream(stream_ptr &&base) : base(std::move(base)) {}
    method off_t (line 34) | off_t seek(off_t off, int whence) final { return stream::seek(off, whe...
  class chunk_out_stream (line 43) | class chunk_out_stream : public filter_stream {
    method chunk_out_stream (line 45) | chunk_out_stream(stream_ptr &&base, size_t buf_sz, size_t chunk_sz)
    method chunk_out_stream (line 48) | chunk_out_stream(stream_ptr &&base, size_t buf_sz = 4096)
    method read (line 54) | ssize_t read(void *buf, size_t len) final { return stream::read(buf, l...
  class byte_stream (line 72) | class byte_stream : public stream {
    method byte_stream (line 76) | byte_stream(Byte *&buf, size_t &len) : byte_stream(reinterpret_cast<ui...
  class file_stream (line 91) | class file_stream : public stream {
  class fd_stream (line 99) | class fd_stream : public file_stream {
    method fd_stream (line 101) | fd_stream(int fd) : fd(fd) {}
  class fp_stream (line 118) | class fp_stream final : public file_stream {
    method fp_stream (line 120) | fp_stream(FILE *fp = nullptr) : fp(fp, fclose) {}
    method fp_stream (line 121) | fp_stream(sFILE &&fp) : fp(std::move(fp)) {}
  function sFILE (line 134) | sFILE make_stream_fp(Args &&... args) {

FILE: magiskbase/misc.cpp
  function fork_dont_care (line 18) | int fork_dont_care() {
  function fork_no_orphan (line 28) | int fork_no_orphan() {
  function gen_rand_str (line 38) | int gen_rand_str(char *buf, int len, bool varlen) {
  function exec_command (line 59) | int exec_command(exec_t &exec) {
  function exec_command_sync (line 105) | int exec_command_sync(exec_t &exec) {
  function new_daemon_thread (line 114) | int new_daemon_thread(thread_entry entry, void *arg) {
  function init_argv0 (line 124) | void init_argv0(int argc, char **argv) {
  function set_nice_name (line 129) | void set_nice_name(const char *name) {
  function parse_int (line 139) | int parse_int(string_view s) {
  function binary_gcd (line 151) | uint32_t binary_gcd(uint32_t u, uint32_t v) {
  function switch_mnt_ns (line 168) | int switch_mnt_ns(int pid) {
  function string (line 182) | string &replace_all(string &str, string_view from, string_view to) {
  function split_impl (line 192) | static auto split_impl(T s, T delims) {
  function split (line 206) | vector<string> split(const string &s, const string &delims) {
  function split_ro (line 210) | vector<string_view> split_ro(string_view s, string_view delims) {

FILE: magiskbase/misc.hpp
  class mutex_guard (line 14) | class mutex_guard {
    method mutex_guard (line 17) | explicit mutex_guard(pthread_mutex_t &m): mutex(&m) {
    method unlock (line 20) | void unlock() {
  class run_finally (line 32) | class run_finally {
    method run_finally (line 35) | explicit run_finally(Func &&fn) : fn(std::move(fn)) {}
  class reversed_container (line 42) | class reversed_container {
    method reversed_container (line 44) | reversed_container(T &base) : base(base) {}
    method begin (line 45) | decltype(std::declval<T>().rbegin()) begin() { return base.rbegin(); }
    method begin (line 46) | decltype(std::declval<T>().crbegin()) begin() const { return base.crbe...
    method cbegin (line 47) | decltype(std::declval<T>().crbegin()) cbegin() const { return base.crb...
    method end (line 48) | decltype(std::declval<T>().rend()) end() { return base.rend(); }
    method end (line 49) | decltype(std::declval<T>().crend()) end() const { return base.crend(); }
    method cend (line 50) | decltype(std::declval<T>().crend()) cend() const { return base.crend(); }
  function reversed (line 56) | reversed_container<T> reversed(T &base) {
  function default_new (line 61) | static inline void default_new(T *&p) { p = new T(); }
  function default_new (line 64) | static inline void default_new(std::unique_ptr<T> &p) { p.reset(new T()); }
  class stateless_allocator (line 67) | class stateless_allocator {
    method T (line 70) | T *allocate(size_t num) { return static_cast<T*>(Impl::allocate(sizeof...
    method deallocate (line 71) | void deallocate(T *ptr, size_t num) { Impl::deallocate(ptr, sizeof(T) ...
    method stateless_allocator (line 72) | stateless_allocator()                           = default;
    method stateless_allocator (line 73) | stateless_allocator(const stateless_allocator&) = default;
    method stateless_allocator (line 74) | stateless_allocator(stateless_allocator&&)      = default;
    method stateless_allocator (line 76) | stateless_allocator(const stateless_allocator<U, Impl>&) {}
  class dynamic_bitset_impl (line 81) | class dynamic_bitset_impl {
    method slots (line 87) | size_t slots() const { return slot_list.size(); }
    method slot_type (line 88) | slot_type get_slot(size_t slot) const {
    method emplace_back (line 91) | void emplace_back(slot_type l) {
    method get (line 95) | slot_bits::reference get(size_t pos) {
    method get (line 103) | bool get(size_t pos) const {
  type dynamic_bitset (line 112) | struct dynamic_bitset : public dynamic_bitset_impl {
  type StringCmp (line 117) | struct StringCmp {
  function str_contains (line 127) | static inline bool str_contains(std::string_view s, std::string_view ss) {
  function str_starts (line 130) | static inline bool str_starts(std::string_view s, std::string_view ss) {
  function str_ends (line 133) | static inline bool str_ends(std::string_view s, std::string_view ss) {
  function ltrim (line 136) | static inline std::string ltrim(std::string &&s) {
  function rtrim (line 142) | static inline std::string rtrim(std::string &&s) {
  type exec_t (line 164) | struct exec_t {
  function exec_command (line 174) | int exec_command(exec_t &exec, Args &&...args) {
  function exec_command_sync (line 181) | int exec_command_sync(exec_t &exec, Args &&...args) {
  function exec_command_sync (line 187) | int exec_command_sync(Args &&...args) {
  function exec_command_async (line 192) | void exec_command_async(Args &&...args) {

FILE: magiskbase/stream.cpp
  function strm_read (line 9) | static int strm_read(void *v, char *buf, size_t len) {
  function strm_write (line 14) | static int strm_write(void *v, const char *buf, size_t len) {
  function fpos_t (line 21) | static fpos_t strm_seek(void *v, fpos_t off, int whence) {
  function strm_close (line 26) | static int strm_close(void *v) {
  function sFILE (line 33) | sFILE make_stream_fp(stream_ptr &&strm) {
  function off_t (line 86) | off_t stream::seek(off_t off, int whence) {
  function off_t (line 100) | off_t fp_stream::seek(off_t off, int whence) {
  function off_t (line 196) | off_t byte_stream::seek(off_t off, int whence) {
  function off_t (line 246) | off_t fd_stream::seek(off_t off, int whence) {

FILE: magiskbase/xwrap.cpp
  function FILE (line 22) | FILE *xfopen(const char *pathname, const char *mode) {
  function FILE (line 30) | FILE *xfdopen(int fd, const char *mode) {
  function xopen (line 38) | int xopen(const char *pathname, int flags) {
  function xopen (line 46) | int xopen(const char *pathname, int flags, mode_t mode) {
  function xopenat (line 55) | int xopenat(int dirfd, const char *pathname, int flags) {
  function xopenat (line 63) | int xopenat(int dirfd, const char *pathname, int flags, mode_t mode) {
  function xwrite (line 73) | ssize_t xwrite(int fd, const void *buf, size_t count) {
  function xread (line 93) | ssize_t xread(int fd, void *buf, size_t count) {
  function xxread (line 102) | ssize_t xxread(int fd, void *buf, size_t count) {
  function off_t (line 121) | off_t xlseek(int fd, off_t offset, int whence) {
  function xpipe2 (line 130) | int xpipe2(int pipefd[2], int flags) {
  function xsetns (line 140) | int xsetns(int fd, int nstype) {
  function xunshare (line 148) | int xunshare(int flags) {
  function DIR (line 157) | DIR *xopendir(const char *name) {
  function DIR (line 166) | DIR *xfdopendir(int fd) {
  type dirent (line 175) | struct dirent
  function pid_t (line 192) | pid_t xsetsid() {
  function xsocket (line 200) | int xsocket(int domain, int type, int protocol) {
  function xbind (line 208) | int xbind(int sockfd, const struct sockaddr *addr, socklen_t addrlen) {
  function xlisten (line 216) | int xlisten(int sockfd, int backlog) {
  function xaccept4 (line 224) | int xaccept4(int sockfd, struct sockaddr *addr, socklen_t *addrlen, int ...
  function xsendmsg (line 258) | ssize_t xsendmsg(int sockfd, const struct msghdr *msg, int flags) {
  function xrecvmsg (line 266) | ssize_t xrecvmsg(int sockfd, struct msghdr *msg, int flags) {
  function xpthread_create (line 274) | int xpthread_create(pthread_t *thread, const pthread_attr_t *attr,
  function xaccess (line 283) | int xaccess(const char *path, int mode) {
  function xstat (line 291) | int xstat(const char *pathname, struct stat *buf) {
  function xlstat (line 299) | int xlstat(const char *pathname, struct stat *buf) {
  function xfstat (line 307) | int xfstat(int fd, struct stat *buf) {
  function xfstatat (line 316) | int xfstatat(int dirfd, const char *pathname, struct stat *buf, int flag...
  function xdup (line 325) | int xdup(int fd) {
  function xdup2 (line 333) | int xdup2(int oldfd, int newfd) {
  function xdup3 (line 342) | int xdup3(int oldfd, int newfd, int flags) {
  function xreadlink (line 351) | ssize_t xreadlink(const char *pathname, char *buf, size_t bufsiz) {
  function xreadlinkat (line 362) | ssize_t xreadlinkat(int dirfd, const char *pathname, char *buf, size_t b...
  function xfaccessat (line 383) | int xfaccessat(int dirfd, const char *pathname) {
  function xsymlink (line 401) | int xsymlink(const char *target, const char *linkpath) {
  function xxsymlink (line 413) | int xxsymlink(const char *target, const char *file)
  function xsymlinkat (line 444) | int xsymlinkat(const char *target, int newdirfd, const char *linkpath) {
  function xlinkat (line 452) | int xlinkat(int olddirfd, const char *oldpath, int newdirfd, const char ...
  function xmount (line 462) | int xmount(const char *source, const char *target,
  function xumount (line 472) | int xumount(const char *target) {
  function xumount2 (line 480) | int xumount2(const char *target, int flags) {
  function xrename (line 489) | int xrename(const char *oldpath, const char *newpath) {
  function xmkdir (line 497) | int xmkdir(const char *pathname, mode_t mode) {
  function xmkdirs (line 508) | int xmkdirs(const char *pathname, mode_t mode) {
  function xmkdirat (line 517) | int xmkdirat(int dirfd, const char *pathname, mode_t mode) {
  function xsendfile (line 536) | ssize_t xsendfile(int out_fd, int in_fd, off_t *offset, size_t count) {
  function pid_t (line 545) | pid_t xfork() {
  function xpoll (line 553) | int xpoll(struct pollfd *fds, nfds_t nfds, int timeout) {
  function xinotify_init1 (line 561) | int xinotify_init1(int flags) {
  function xmknod (line 584) | int xmknod(const char *pathname, mode_t mode, dev_t dev) {
  function xptrace (line 592) | long xptrace(int request, pid_t pid, void *addr, void *data) {

FILE: magiskbase/xwrap.hpp
  function xptrace (line 29) | static inline long xptrace(int request, pid_t pid, void *addr, uintptr_t...
  type sockaddr (line 33) | struct sockaddr
  type sockaddr (line 34) | struct sockaddr
  type sockaddr (line 36) | struct sockaddr
  type msghdr (line 37) | struct msghdr
  type msghdr (line 38) | struct msghdr
  type pollfd (line 46) | struct pollfd
  type stat (line 58) | struct stat
  type dirent (line 72) | struct dirent
  type stat (line 78) | struct stat
  type stat (line 79) | struct stat
  type stat (line 80) | struct stat

FILE: main.cpp
  function print_formats (line 9) | static void print_formats() {
  function usage (line 15) | static void usage(char *arg0) {
  function main (line 141) | int main(int argc, char *argv[]) {

FILE: pattern.cpp
  function skip_verity_pattern (line 7) | static int skip_verity_pattern(const char *s) {
  function skip_encryption_pattern (line 26) | static int skip_encryption_pattern(const char *s) {
  function remove_pattern (line 42) | static uint32_t remove_pattern(char *src, uint32_t size, int(*pattern_sk...
  function patch_verity (line 58) | uint32_t patch_verity(void *buf, uint32_t size) {
  function patch_encryption (line 62) | uint32_t patch_encryption(void *buf, uint32_t size) {

FILE: ramdisk.cpp
  class magisk_cpio (line 17) | class magisk_cpio : public cpio {
  function check_env (line 26) | bool check_env(const char *name) {
  function cpio_commands (line 233) | int cpio_commands(int argc, char *argv[]) {
Condensed preview — 287 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (2,732K chars).
[
  {
    "path": ".gitignore",
    "chars": 10,
    "preview": "out/*\r\nNUL"
  },
  {
    "path": ".gitmodules",
    "chars": 76,
    "preview": "[submodule \"libnt\"]\n\tpath = libnt\n\turl = https://github.com/svoboda18/libnt\n"
  },
  {
    "path": "Makefile",
    "chars": 14539,
    "preview": "# env controlled\r\nDEBUG ?= 0\r\nCROSS_COMPILE ?=\r\nSH ?= sh\r\n\r\n# Build configuration (static only, shared are broken)\r\nover"
  },
  {
    "path": "README.md",
    "chars": 1334,
    "preview": "# MagiskBoot - Boot Image Modification Tool\r\nThe most complete tool for unpacking and repacking Android boot images.\r\n\r\n"
  },
  {
    "path": "bin.rc",
    "chars": 650,
    "preview": "#include <windows.h>\r\n\r\nVS_VERSION_INFO VERSIONINFO\r\nFILEVERSION     1,0,0,0\r\nPRODUCTVERSION  1,0,0,0\r\nFILEFLAGSMASK    "
  },
  {
    "path": "bootimg.cpp",
    "chars": 28540,
    "preview": "#include <functional>\n#include <memory>\n\n#include <libfdt.h>\n#include <mincrypt/sha.h>\n#include <mincrypt/sha256.h>\n#inc"
  },
  {
    "path": "bootimg.hpp",
    "chars": 20597,
    "preview": "#pragma once\r\n\r\n#include <stdint.h>\r\n#include <utility>\r\n#include <bitset>\r\n#include \"format.hpp\"\r\n\r\n/******************"
  },
  {
    "path": "compress.cpp",
    "chars": 21752,
    "preview": "#include <memory>\n#include <functional>\n\n#include <zlib.h>\n#include <bzlib.h>\n#include <lzma.h>\n#include <lz4.h>\n#includ"
  },
  {
    "path": "compress.hpp",
    "chars": 317,
    "preview": "#pragma once\n\n#include <stream.hpp>\n\n#include \"format.hpp\"\n\nfilter_strm_ptr get_encoder(format_t type, stream_ptr &&base"
  },
  {
    "path": "cpio.cpp",
    "chars": 11771,
    "preview": "#include <unistd.h>\r\n#include <fcntl.h>\r\n#include <libgen.h>\r\n#include <algorithm>\r\n\r\n#include <base.hpp>\r\n\r\n#include \"c"
  },
  {
    "path": "cpio.hpp",
    "chars": 1645,
    "preview": "#pragma once\r\n\r\n#include <stdint.h>\r\n#include <string>\r\n#include <memory>\r\n#include <map>\r\n#include <string_view>\r\n\r\nstr"
  },
  {
    "path": "dll.rc",
    "chars": 651,
    "preview": "#include <windows.h>\r\n\r\nVS_VERSION_INFO VERSIONINFO\r\nFILEVERSION     1,0,0,0\r\nPRODUCTVERSION  1,0,0,0\r\nFILEFLAGSMASK    "
  },
  {
    "path": "dtb.cpp",
    "chars": 13856,
    "preview": "#include <bitset>\n#include <vector>\n#include <map>\n#include <libfdt.h>\n\n#include <base.hpp>\n\n#include \"magiskboot.hpp\"\n#"
  },
  {
    "path": "dtb.hpp",
    "chars": 3174,
    "preview": "#pragma once\n\n#include <stdint.h>\n\n#define DT_TABLE_MAGIC  \"\\xd7\\xb7\\xab\\x1e\"\n#define QCDT_MAGIC      \"QCDT\"\n#define DTB"
  },
  {
    "path": "external/bzip2/blocksort.c",
    "chars": 30694,
    "preview": "\n/*-------------------------------------------------------------*/\n/*--- Block sorting machinery                        "
  },
  {
    "path": "external/bzip2/bzlib.c",
    "chars": 45995,
    "preview": "\n/*-------------------------------------------------------------*/\n/*--- Library top-level functions.                   "
  },
  {
    "path": "external/bzip2/bzlib.h",
    "chars": 6245,
    "preview": "\n/*-------------------------------------------------------------*/\n/*--- Public header file for the library.            "
  },
  {
    "path": "external/bzip2/bzlib_private.h",
    "chars": 13244,
    "preview": "\n/*-------------------------------------------------------------*/\n/*--- Private header file for the library.           "
  },
  {
    "path": "external/bzip2/compress.c",
    "chars": 20561,
    "preview": "\n/*-------------------------------------------------------------*/\n/*--- Compression machinery (not incl block sorting) "
  },
  {
    "path": "external/bzip2/crctable.c",
    "chars": 4818,
    "preview": "\n/*-------------------------------------------------------------*/\n/*--- Table for doing CRCs                           "
  },
  {
    "path": "external/bzip2/decompress.c",
    "chars": 20919,
    "preview": "\n/*-------------------------------------------------------------*/\n/*--- Decompression machinery                        "
  },
  {
    "path": "external/bzip2/huffman.c",
    "chars": 6991,
    "preview": "\n/*-------------------------------------------------------------*/\n/*--- Huffman coding low-level stuff                 "
  },
  {
    "path": "external/bzip2/randtable.c",
    "chars": 3860,
    "preview": "\n/*-------------------------------------------------------------*/\n/*--- Table for randomising repetitive blocks        "
  },
  {
    "path": "external/libfdt/fdt.c",
    "chars": 7762,
    "preview": "// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause)\n/*\n * libfdt - Flat Device Tree manipulation\n * Copyright"
  },
  {
    "path": "external/libfdt/fdt.h",
    "chars": 1761,
    "preview": "/* SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause) */\n#ifndef FDT_H\n#define FDT_H\n/*\n * libfdt - Flat Device"
  },
  {
    "path": "external/libfdt/fdt_addresses.c",
    "chars": 2193,
    "preview": "// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause)\n/*\n * libfdt - Flat Device Tree manipulation\n * Copyright"
  },
  {
    "path": "external/libfdt/fdt_empty_tree.c",
    "chars": 641,
    "preview": "// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause)\n/*\n * libfdt - Flat Device Tree manipulation\n * Copyright"
  },
  {
    "path": "external/libfdt/fdt_overlay.c",
    "chars": 21658,
    "preview": "// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause)\n/*\n * libfdt - Flat Device Tree manipulation\n * Copyright"
  },
  {
    "path": "external/libfdt/fdt_ro.c",
    "chars": 18552,
    "preview": "// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause)\n/*\n * libfdt - Flat Device Tree manipulation\n * Copyright"
  },
  {
    "path": "external/libfdt/fdt_rw.c",
    "chars": 12260,
    "preview": "// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause)\n/*\n * libfdt - Flat Device Tree manipulation\n * Copyright"
  },
  {
    "path": "external/libfdt/fdt_strerror.c",
    "chars": 1485,
    "preview": "// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause)\n/*\n * libfdt - Flat Device Tree manipulation\n * Copyright"
  },
  {
    "path": "external/libfdt/fdt_sw.c",
    "chars": 8671,
    "preview": "// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause)\n/*\n * libfdt - Flat Device Tree manipulation\n * Copyright"
  },
  {
    "path": "external/libfdt/fdt_wip.c",
    "chars": 1906,
    "preview": "// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause)\n/*\n * libfdt - Flat Device Tree manipulation\n * Copyright"
  },
  {
    "path": "external/libfdt/libfdt.h",
    "chars": 76475,
    "preview": "/* SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause) */\n#ifndef LIBFDT_H\n#define LIBFDT_H\n/*\n * libfdt - Flat "
  },
  {
    "path": "external/libfdt/libfdt_env.h",
    "chars": 2753,
    "preview": "/* SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause) */\n#ifndef LIBFDT_ENV_H\n#define LIBFDT_ENV_H\n/*\n * libfdt"
  },
  {
    "path": "external/libfdt/libfdt_internal.h",
    "chars": 6491,
    "preview": "/* SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause) */\n#ifndef LIBFDT_INTERNAL_H\n#define LIBFDT_INTERNAL_H\n/*"
  },
  {
    "path": "external/lz4/lz4.c",
    "chars": 105087,
    "preview": "/*\n   LZ4 - Fast LZ compression algorithm\n   Copyright (C) 2011-present, Yann Collet.\n\n   BSD 2-Clause License (http://w"
  },
  {
    "path": "external/lz4/lz4.h",
    "chars": 40861,
    "preview": "/*\n *  LZ4 - Fast LZ compression algorithm\n *  Header File\n *  Copyright (C) 2011-present, Yann Collet.\n\n   BSD 2-Clause"
  },
  {
    "path": "external/lz4/lz4frame.c",
    "chars": 79848,
    "preview": "/*\n * LZ4 auto-framing library\n * Copyright (C) 2011-2016, Yann Collet.\n *\n * BSD 2-Clause License (http://www.opensourc"
  },
  {
    "path": "external/lz4/lz4frame.h",
    "chars": 28899,
    "preview": "/*\n   LZ4 auto-framing library\n   Header File\n   Copyright (C) 2011-2017, Yann Collet.\n   BSD 2-Clause License (http://w"
  },
  {
    "path": "external/lz4/lz4frame_static.h",
    "chars": 2044,
    "preview": "/*\n   LZ4 auto-framing library\n   Header File for static linking only\n   Copyright (C) 2011-2016, Yann Collet.\n\n   BSD 2"
  },
  {
    "path": "external/lz4/lz4hc.c",
    "chars": 69010,
    "preview": "/*\n    LZ4 HC - High Compression Mode of LZ4\n    Copyright (C) 2011-2017, Yann Collet.\n\n    BSD 2-Clause License (http:/"
  },
  {
    "path": "external/lz4/lz4hc.h",
    "chars": 20165,
    "preview": "/*\n   LZ4 HC - High Compression Mode of LZ4\n   Header File\n   Copyright (C) 2011-2017, Yann Collet.\n   BSD 2-Clause Lice"
  },
  {
    "path": "external/lz4/xxhash.c",
    "chars": 34045,
    "preview": "/*\n*  xxHash - Fast Hash algorithm\n*  Copyright (C) 2012-2016, Yann Collet\n*\n*  BSD 2-Clause License (http://www.opensou"
  },
  {
    "path": "external/lz4/xxhash.h",
    "chars": 13466,
    "preview": "/*\n   xxHash - Extremely Fast Hash algorithm\n   Header File\n   Copyright (C) 2012-2016, Yann Collet.\n\n   BSD 2-Clause Li"
  },
  {
    "path": "external/mincrypt/dsa_sig.c",
    "chars": 4112,
    "preview": "/*\n * Copyright 2013 The Android Open Source Project\n *\n * Redistribution and use in source and binary forms, with or wi"
  },
  {
    "path": "external/mincrypt/include/mincrypt/dsa_sig.h",
    "chars": 1919,
    "preview": "/*\n * Copyright 2013 The Android Open Source Project\n *\n * Redistribution and use in source and binary forms, with or wi"
  },
  {
    "path": "external/mincrypt/include/mincrypt/hash-internal.h",
    "chars": 2520,
    "preview": "/*\n * Copyright 2007 The Android Open Source Project\n *\n * Redistribution and use in source and binary forms, with or wi"
  },
  {
    "path": "external/mincrypt/include/mincrypt/p256.h",
    "chars": 5044,
    "preview": "/*\n * Copyright 2013 The Android Open Source Project\n *\n * Redistribution and use in source and binary forms, with or wi"
  },
  {
    "path": "external/mincrypt/include/mincrypt/p256_ecdsa.h",
    "chars": 2306,
    "preview": "/*\n * Copyright 2013 The Android Open Source Project\n *\n * Redistribution and use in source and binary forms, with or wi"
  },
  {
    "path": "external/mincrypt/include/mincrypt/rsa.h",
    "chars": 2413,
    "preview": "/* rsa.h\n**\n** Copyright 2008, The Android Open Source Project\n**\n** Redistribution and use in source and binary forms, "
  },
  {
    "path": "external/mincrypt/include/mincrypt/sha.h",
    "chars": 2167,
    "preview": "/*\n * Copyright 2005 The Android Open Source Project\n *\n * Redistribution and use in source and binary forms, with or wi"
  },
  {
    "path": "external/mincrypt/include/mincrypt/sha256.h",
    "chars": 2147,
    "preview": "/*\n * Copyright 2011 The Android Open Source Project\n *\n * Redistribution and use in source and binary forms, with or wi"
  },
  {
    "path": "external/mincrypt/p256.c",
    "chars": 11249,
    "preview": "/*\n * Copyright 2013 The Android Open Source Project\n *\n * Redistribution and use in source and binary forms, with or wi"
  },
  {
    "path": "external/mincrypt/p256_ec.c",
    "chars": 47716,
    "preview": "/*\n * Copyright 2013 The Android Open Source Project\n *\n * Redistribution and use in source and binary forms, with or wi"
  },
  {
    "path": "external/mincrypt/p256_ecdsa.c",
    "chars": 2406,
    "preview": "/*\n * Copyright 2013 The Android Open Source Project\n *\n * Redistribution and use in source and binary forms, with or wi"
  },
  {
    "path": "external/mincrypt/rsa.c",
    "chars": 11069,
    "preview": "/* rsa.c\n**\n** Copyright 2012, The Android Open Source Project\n**\n** Redistribution and use in source and binary forms, "
  },
  {
    "path": "external/mincrypt/sha.c",
    "chars": 4281,
    "preview": "/* sha.c\n**\n** Copyright 2013, The Android Open Source Project\n**\n** Redistribution and use in source and binary forms, "
  },
  {
    "path": "external/mincrypt/sha256.c",
    "chars": 5684,
    "preview": "/* sha256.c\n**\n** Copyright 2013, The Android Open Source Project\n**\n** Redistribution and use in source and binary form"
  },
  {
    "path": "external/xz/common/mythread.h",
    "chars": 12095,
    "preview": "///////////////////////////////////////////////////////////////////////////////\n//\n/// \\file       mythread.h\n/// \\brief"
  },
  {
    "path": "external/xz/common/sysdefs.h",
    "chars": 4914,
    "preview": "///////////////////////////////////////////////////////////////////////////////\n//\n/// \\file       sysdefs.h\n/// \\brief "
  },
  {
    "path": "external/xz/common/tuklib_common.h",
    "chars": 1902,
    "preview": "///////////////////////////////////////////////////////////////////////////////\n//\n/// \\file       tuklib_common.h\n/// \\"
  },
  {
    "path": "external/xz/common/tuklib_config.h",
    "chars": 121,
    "preview": "#ifdef HAVE_CONFIG_H\n#\tinclude \"sysdefs.h\"\n#else\n#\tinclude <stddef.h>\n#\tinclude <inttypes.h>\n#\tinclude <limits.h>\n#endif"
  },
  {
    "path": "external/xz/common/tuklib_cpucores.c",
    "chars": 2357,
    "preview": "///////////////////////////////////////////////////////////////////////////////\n//\n/// \\file       tuklib_cpucores.c\n///"
  },
  {
    "path": "external/xz/common/tuklib_cpucores.h",
    "chars": 606,
    "preview": "///////////////////////////////////////////////////////////////////////////////\n//\n/// \\file       tuklib_cpucores.h\n///"
  },
  {
    "path": "external/xz/common/tuklib_exit.c",
    "chars": 1547,
    "preview": "///////////////////////////////////////////////////////////////////////////////\n//\n/// \\file       tuklib_exit.c\n/// \\br"
  },
  {
    "path": "external/xz/common/tuklib_exit.h",
    "chars": 706,
    "preview": "///////////////////////////////////////////////////////////////////////////////\n//\n/// \\file       tuklib_exit.h\n/// \\br"
  },
  {
    "path": "external/xz/common/tuklib_gettext.h",
    "chars": 1060,
    "preview": "///////////////////////////////////////////////////////////////////////////////\n//\n/// \\file       tuklib_gettext.h\n/// "
  },
  {
    "path": "external/xz/common/tuklib_integer.h",
    "chars": 17067,
    "preview": "///////////////////////////////////////////////////////////////////////////////\n//\n/// \\file       tuklib_integer.h\n/// "
  },
  {
    "path": "external/xz/common/tuklib_mbstr.h",
    "chars": 2881,
    "preview": "///////////////////////////////////////////////////////////////////////////////\n//\n/// \\file       tuklib_mbstr.h\n/// \\b"
  },
  {
    "path": "external/xz/common/tuklib_mbstr_fw.c",
    "chars": 745,
    "preview": "///////////////////////////////////////////////////////////////////////////////\n//\n/// \\file       tuklib_mbstr_fw.c\n///"
  },
  {
    "path": "external/xz/common/tuklib_mbstr_width.c",
    "chars": 1518,
    "preview": "///////////////////////////////////////////////////////////////////////////////\n//\n/// \\file       tuklib_mbstr_width.c\n"
  },
  {
    "path": "external/xz/common/tuklib_open_stdxxx.c",
    "chars": 1461,
    "preview": "///////////////////////////////////////////////////////////////////////////////\n//\n/// \\file       tuklib_open_stdxxx.c\n"
  },
  {
    "path": "external/xz/common/tuklib_open_stdxxx.h",
    "chars": 647,
    "preview": "///////////////////////////////////////////////////////////////////////////////\n//\n/// \\file       tuklib_open_stdxxx.h\n"
  },
  {
    "path": "external/xz/common/tuklib_physmem.c",
    "chars": 5786,
    "preview": "///////////////////////////////////////////////////////////////////////////////\n//\n/// \\file       tuklib_physmem.c\n/// "
  },
  {
    "path": "external/xz/common/tuklib_physmem.h",
    "chars": 763,
    "preview": "///////////////////////////////////////////////////////////////////////////////\n//\n/// \\file       tuklib_physmem.h\n/// "
  },
  {
    "path": "external/xz/common/tuklib_progname.c",
    "chars": 1136,
    "preview": "///////////////////////////////////////////////////////////////////////////////\n//\n/// \\file       tuklib_progname.c\n///"
  },
  {
    "path": "external/xz/common/tuklib_progname.h",
    "chars": 817,
    "preview": "///////////////////////////////////////////////////////////////////////////////\n//\n/// \\file       tuklib_progname.h\n///"
  },
  {
    "path": "external/xz/liblzma/api/lzma/base.h",
    "chars": 24858,
    "preview": "/**\n * \\file        lzma/base.h\n * \\brief       Data types and functions used in many places in liblzma API\n */\n\n/*\n * A"
  },
  {
    "path": "external/xz/liblzma/api/lzma/bcj.h",
    "chars": 2630,
    "preview": "/**\n * \\file        lzma/bcj.h\n * \\brief       Branch/Call/Jump conversion filters\n */\n\n/*\n * Author: Lasse Collin\n *\n *"
  },
  {
    "path": "external/xz/liblzma/api/lzma/block.h",
    "chars": 22107,
    "preview": "/**\n * \\file        lzma/block.h\n * \\brief       .xz Block handling\n */\n\n/*\n * Author: Lasse Collin\n *\n * This file has "
  },
  {
    "path": "external/xz/liblzma/api/lzma/check.h",
    "chars": 4255,
    "preview": "/**\n * \\file        lzma/check.h\n * \\brief       Integrity checks\n */\n\n/*\n * Author: Lasse Collin\n *\n * This file has be"
  },
  {
    "path": "external/xz/liblzma/api/lzma/container.h",
    "chars": 24844,
    "preview": "/**\n * \\file        lzma/container.h\n * \\brief       File formats\n */\n\n/*\n * Author: Lasse Collin\n *\n * This file has be"
  },
  {
    "path": "external/xz/liblzma/api/lzma/delta.h",
    "chars": 1865,
    "preview": "/**\n * \\file        lzma/delta.h\n * \\brief       Delta filter\n */\n\n/*\n * Author: Lasse Collin\n *\n * This file has been p"
  },
  {
    "path": "external/xz/liblzma/api/lzma/filter.h",
    "chars": 16520,
    "preview": "/**\n * \\file        lzma/filter.h\n * \\brief       Common filter related types and functions\n */\n\n/*\n * Author: Lasse Col"
  },
  {
    "path": "external/xz/liblzma/api/lzma/hardware.h",
    "chars": 2604,
    "preview": "/**\n * \\file        lzma/hardware.h\n * \\brief       Hardware information\n *\n * Since liblzma can consume a lot of system"
  },
  {
    "path": "external/xz/liblzma/api/lzma/index.h",
    "chars": 23491,
    "preview": "/**\n * \\file        lzma/index.h\n * \\brief       Handling of .xz Index and related information\n */\n\n/*\n * Author: Lasse "
  },
  {
    "path": "external/xz/liblzma/api/lzma/index_hash.h",
    "chars": 3914,
    "preview": "/**\n * \\file        lzma/index_hash.h\n * \\brief       Validate Index by using a hash function\n *\n * Hashing makes it pos"
  },
  {
    "path": "external/xz/liblzma/api/lzma/lzma12.h",
    "chars": 14744,
    "preview": "/**\n * \\file        lzma/lzma12.h\n * \\brief       LZMA1 and LZMA2 filters\n */\n\n/*\n * Author: Lasse Collin\n *\n * This fil"
  },
  {
    "path": "external/xz/liblzma/api/lzma/stream_flags.h",
    "chars": 8253,
    "preview": "/**\n * \\file        lzma/stream_flags.h\n * \\brief       .xz Stream Header and Stream Footer encoder and decoder\n */\n\n/*\n"
  },
  {
    "path": "external/xz/liblzma/api/lzma/version.h",
    "chars": 3497,
    "preview": "/**\n * \\file        lzma/version.h\n * \\brief       Version number\n */\n\n/*\n * Author: Lasse Collin\n *\n * This file has be"
  },
  {
    "path": "external/xz/liblzma/api/lzma/vli.h",
    "chars": 6546,
    "preview": "/**\n * \\file        lzma/vli.h\n * \\brief       Variable-length integer handling\n *\n * In the .xz format, most integers a"
  },
  {
    "path": "external/xz/liblzma/api/lzma.h",
    "chars": 9866,
    "preview": "/**\n * \\file        api/lzma.h\n * \\brief       The public API of liblzma data compression library\n *\n * liblzma is a pub"
  },
  {
    "path": "external/xz/liblzma/check/check.c",
    "chars": 2910,
    "preview": "///////////////////////////////////////////////////////////////////////////////\n//\n/// \\file       check.c\n/// \\brief   "
  },
  {
    "path": "external/xz/liblzma/check/check.h",
    "chars": 4718,
    "preview": "///////////////////////////////////////////////////////////////////////////////\n//\n/// \\file       check.h\n/// \\brief   "
  },
  {
    "path": "external/xz/liblzma/check/crc32_fast.c",
    "chars": 2277,
    "preview": "///////////////////////////////////////////////////////////////////////////////\n//\n/// \\file       crc32.c\n/// \\brief   "
  },
  {
    "path": "external/xz/liblzma/check/crc32_small.c",
    "chars": 1044,
    "preview": "///////////////////////////////////////////////////////////////////////////////\n//\n/// \\file       crc32_small.c\n/// \\br"
  },
  {
    "path": "external/xz/liblzma/check/crc32_table.c",
    "chars": 641,
    "preview": "///////////////////////////////////////////////////////////////////////////////\n//\n/// \\file       crc32_table.c\n/// \\br"
  },
  {
    "path": "external/xz/liblzma/check/crc32_table_be.h",
    "chars": 25758,
    "preview": "/* This file has been automatically generated by crc32_tablegen.c. */\n\nconst uint32_t lzma_crc32_table[8][256] = {\n\t{\n\t\t"
  },
  {
    "path": "external/xz/liblzma/check/crc32_table_le.h",
    "chars": 25758,
    "preview": "/* This file has been automatically generated by crc32_tablegen.c. */\n\nconst uint32_t lzma_crc32_table[8][256] = {\n\t{\n\t\t"
  },
  {
    "path": "external/xz/liblzma/check/crc32_tablegen.c",
    "chars": 2245,
    "preview": "///////////////////////////////////////////////////////////////////////////////\n//\n/// \\file       crc32_tablegen.c\n/// "
  },
  {
    "path": "external/xz/liblzma/check/crc32_x86.S",
    "chars": 7228,
    "preview": "/*\n * Speed-optimized CRC32 using slicing-by-eight algorithm\n *\n * This uses only i386 instructions, but it is optimized"
  },
  {
    "path": "external/xz/liblzma/check/crc64_fast.c",
    "chars": 1640,
    "preview": "///////////////////////////////////////////////////////////////////////////////\n//\n/// \\file       crc64.c\n/// \\brief   "
  },
  {
    "path": "external/xz/liblzma/check/crc64_small.c",
    "chars": 966,
    "preview": "///////////////////////////////////////////////////////////////////////////////\n//\n/// \\file       crc64_small.c\n/// \\br"
  },
  {
    "path": "external/xz/liblzma/check/crc64_table.c",
    "chars": 641,
    "preview": "///////////////////////////////////////////////////////////////////////////////\n//\n/// \\file       crc64_table.c\n/// \\br"
  },
  {
    "path": "external/xz/liblzma/check/crc64_table_be.h",
    "chars": 31882,
    "preview": "/* This file has been automatically generated by crc64_tablegen.c. */\n\nconst uint64_t lzma_crc64_table[4][256] = {\n\t{\n\t\t"
  },
  {
    "path": "external/xz/liblzma/check/crc64_table_le.h",
    "chars": 31882,
    "preview": "/* This file has been automatically generated by crc64_tablegen.c. */\n\nconst uint64_t lzma_crc64_table[4][256] = {\n\t{\n\t\t"
  },
  {
    "path": "external/xz/liblzma/check/crc64_tablegen.c",
    "chars": 1744,
    "preview": "///////////////////////////////////////////////////////////////////////////////\n//\n/// \\file       crc64_tablegen.c\n/// "
  },
  {
    "path": "external/xz/liblzma/check/crc64_x86.S",
    "chars": 6761,
    "preview": "/*\n * Speed-optimized CRC64 using slicing-by-four algorithm\n *\n * This uses only i386 instructions, but it is optimized "
  },
  {
    "path": "external/xz/liblzma/check/crc_macros.h",
    "chars": 787,
    "preview": "///////////////////////////////////////////////////////////////////////////////\n//\n/// \\file       crc_macros.h\n/// \\bri"
  },
  {
    "path": "external/xz/liblzma/check/sha256.c",
    "chars": 5405,
    "preview": "///////////////////////////////////////////////////////////////////////////////\n//\n/// \\file       sha256.c\n/// \\brief  "
  },
  {
    "path": "external/xz/liblzma/common/Makefile.inc",
    "chars": 1881,
    "preview": "##\n## Author: Lasse Collin\n##\n## This file has been put into the public domain.\n## You can do whatever you want with thi"
  },
  {
    "path": "external/xz/liblzma/common/alone_decoder.c",
    "chars": 5662,
    "preview": "///////////////////////////////////////////////////////////////////////////////\n//\n/// \\file       alone_decoder.c\n/// \\"
  },
  {
    "path": "external/xz/liblzma/common/alone_decoder.h",
    "chars": 601,
    "preview": "///////////////////////////////////////////////////////////////////////////////\n//\n/// \\file       alone_decoder.h\n/// \\"
  },
  {
    "path": "external/xz/liblzma/common/alone_encoder.c",
    "chars": 3751,
    "preview": "///////////////////////////////////////////////////////////////////////////////\n//\n/// \\file       alone_encoder.c\n/// \\"
  },
  {
    "path": "external/xz/liblzma/common/auto_decoder.c",
    "chars": 4902,
    "preview": "///////////////////////////////////////////////////////////////////////////////\n//\n/// \\file       auto_decoder.c\n/// \\b"
  },
  {
    "path": "external/xz/liblzma/common/block_buffer_decoder.c",
    "chars": 2368,
    "preview": "///////////////////////////////////////////////////////////////////////////////\n//\n/// \\file       block_buffer_decoder."
  },
  {
    "path": "external/xz/liblzma/common/block_buffer_encoder.c",
    "chars": 10123,
    "preview": "///////////////////////////////////////////////////////////////////////////////\n//\n/// \\file       block_buffer_encoder."
  },
  {
    "path": "external/xz/liblzma/common/block_buffer_encoder.h",
    "chars": 763,
    "preview": "///////////////////////////////////////////////////////////////////////////////\n//\n/// \\file       block_buffer_encoder."
  },
  {
    "path": "external/xz/liblzma/common/block_decoder.c",
    "chars": 6988,
    "preview": "///////////////////////////////////////////////////////////////////////////////\n//\n/// \\file       block_decoder.c\n/// \\"
  },
  {
    "path": "external/xz/liblzma/common/block_decoder.h",
    "chars": 576,
    "preview": "///////////////////////////////////////////////////////////////////////////////\n//\n/// \\file       block_decoder.h\n/// \\"
  },
  {
    "path": "external/xz/liblzma/common/block_encoder.c",
    "chars": 5766,
    "preview": "///////////////////////////////////////////////////////////////////////////////\n//\n/// \\file       block_encoder.c\n/// \\"
  },
  {
    "path": "external/xz/liblzma/common/block_encoder.h",
    "chars": 1890,
    "preview": "///////////////////////////////////////////////////////////////////////////////\n//\n/// \\file       block_encoder.h\n/// \\"
  },
  {
    "path": "external/xz/liblzma/common/block_header_decoder.c",
    "chars": 3710,
    "preview": "///////////////////////////////////////////////////////////////////////////////\n//\n/// \\file       block_header_decoder."
  },
  {
    "path": "external/xz/liblzma/common/block_header_encoder.c",
    "chars": 3346,
    "preview": "///////////////////////////////////////////////////////////////////////////////\n//\n/// \\file       block_header_encoder."
  },
  {
    "path": "external/xz/liblzma/common/block_util.c",
    "chars": 2640,
    "preview": "///////////////////////////////////////////////////////////////////////////////\n//\n/// \\file       block_util.c\n/// \\bri"
  },
  {
    "path": "external/xz/liblzma/common/common.c",
    "chars": 10652,
    "preview": "///////////////////////////////////////////////////////////////////////////////\n//\n/// \\file       common.c\n/// \\brief  "
  },
  {
    "path": "external/xz/liblzma/common/common.h",
    "chars": 10467,
    "preview": "///////////////////////////////////////////////////////////////////////////////\n//\n/// \\file       common.h\n/// \\brief  "
  },
  {
    "path": "external/xz/liblzma/common/easy_buffer_encoder.c",
    "chars": 840,
    "preview": "///////////////////////////////////////////////////////////////////////////////\n//\n/// \\file       easy_buffer_encoder.c"
  },
  {
    "path": "external/xz/liblzma/common/easy_decoder_memusage.c",
    "chars": 668,
    "preview": "///////////////////////////////////////////////////////////////////////////////\n//\n/// \\file       easy_decoder_memusage"
  },
  {
    "path": "external/xz/liblzma/common/easy_encoder.c",
    "chars": 678,
    "preview": "///////////////////////////////////////////////////////////////////////////////\n//\n/// \\file       easy_encoder.c\n/// \\b"
  },
  {
    "path": "external/xz/liblzma/common/easy_encoder_memusage.c",
    "chars": 654,
    "preview": "///////////////////////////////////////////////////////////////////////////////\n//\n/// \\file       easy_encoder_memusage"
  },
  {
    "path": "external/xz/liblzma/common/easy_preset.c",
    "chars": 727,
    "preview": "///////////////////////////////////////////////////////////////////////////////\n//\n/// \\file       easy_preset.c\n/// \\br"
  },
  {
    "path": "external/xz/liblzma/common/easy_preset.h",
    "chars": 921,
    "preview": "///////////////////////////////////////////////////////////////////////////////\n//\n/// \\file       easy_preset.h\n/// \\br"
  },
  {
    "path": "external/xz/liblzma/common/filter_buffer_decoder.c",
    "chars": 2510,
    "preview": "///////////////////////////////////////////////////////////////////////////////\n//\n/// \\file       filter_buffer_decoder"
  },
  {
    "path": "external/xz/liblzma/common/filter_buffer_encoder.c",
    "chars": 1537,
    "preview": "///////////////////////////////////////////////////////////////////////////////\n//\n/// \\file       filter_buffer_encoder"
  },
  {
    "path": "external/xz/liblzma/common/filter_common.c",
    "chars": 8706,
    "preview": "///////////////////////////////////////////////////////////////////////////////\n//\n/// \\file       filter_common.c\n/// \\"
  },
  {
    "path": "external/xz/liblzma/common/filter_common.h",
    "chars": 1258,
    "preview": "///////////////////////////////////////////////////////////////////////////////\n//\n/// \\file       filter_common.h\n/// \\"
  },
  {
    "path": "external/xz/liblzma/common/filter_decoder.c",
    "chars": 4424,
    "preview": "///////////////////////////////////////////////////////////////////////////////\n//\n/// \\file       filter_decoder.c\n/// "
  },
  {
    "path": "external/xz/liblzma/common/filter_decoder.h",
    "chars": 617,
    "preview": "///////////////////////////////////////////////////////////////////////////////\n//\n/// \\file       filter_decoder.h\n/// "
  },
  {
    "path": "external/xz/liblzma/common/filter_encoder.c",
    "chars": 7345,
    "preview": "///////////////////////////////////////////////////////////////////////////////\n//\n/// \\file       filter_decoder.c\n/// "
  },
  {
    "path": "external/xz/liblzma/common/filter_encoder.h",
    "chars": 732,
    "preview": "///////////////////////////////////////////////////////////////////////////////\n//\n/// \\file       filter_encoder.c\n/// "
  },
  {
    "path": "external/xz/liblzma/common/filter_flags_decoder.c",
    "chars": 1187,
    "preview": "///////////////////////////////////////////////////////////////////////////////\n//\n/// \\file       filter_flags_decoder."
  },
  {
    "path": "external/xz/liblzma/common/filter_flags_encoder.c",
    "chars": 1407,
    "preview": "///////////////////////////////////////////////////////////////////////////////\n//\n/// \\file       filter_flags_encoder."
  },
  {
    "path": "external/xz/liblzma/common/hardware_cputhreads.c",
    "chars": 526,
    "preview": "///////////////////////////////////////////////////////////////////////////////\n//\n/// \\file       hardware_cputhreads.c"
  },
  {
    "path": "external/xz/liblzma/common/hardware_physmem.c",
    "chars": 683,
    "preview": "///////////////////////////////////////////////////////////////////////////////\n//\n/// \\file       hardware_physmem.c\n//"
  },
  {
    "path": "external/xz/liblzma/common/index.c",
    "chars": 35440,
    "preview": "///////////////////////////////////////////////////////////////////////////////\n//\n/// \\file       index.c\n/// \\brief   "
  },
  {
    "path": "external/xz/liblzma/common/index.h",
    "chars": 1978,
    "preview": "///////////////////////////////////////////////////////////////////////////////\n//\n/// \\file       index.h\n/// \\brief   "
  },
  {
    "path": "external/xz/liblzma/common/index_decoder.c",
    "chars": 8605,
    "preview": "///////////////////////////////////////////////////////////////////////////////\n//\n/// \\file       index_decoder.c\n/// \\"
  },
  {
    "path": "external/xz/liblzma/common/index_encoder.c",
    "chars": 5853,
    "preview": "///////////////////////////////////////////////////////////////////////////////\n//\n/// \\file       index_encoder.c\n/// \\"
  },
  {
    "path": "external/xz/liblzma/common/index_encoder.h",
    "chars": 584,
    "preview": "///////////////////////////////////////////////////////////////////////////////\n//\n/// \\file       index_encoder.h\n/// \\"
  },
  {
    "path": "external/xz/liblzma/common/index_hash.c",
    "chars": 8981,
    "preview": "///////////////////////////////////////////////////////////////////////////////\n//\n/// \\file       index_hash.c\n/// \\bri"
  },
  {
    "path": "external/xz/liblzma/common/memcmplen.h",
    "chars": 4819,
    "preview": "///////////////////////////////////////////////////////////////////////////////\n//\n/// \\file       memcmplen.h\n/// \\brie"
  },
  {
    "path": "external/xz/liblzma/common/outqueue.c",
    "chars": 4586,
    "preview": "///////////////////////////////////////////////////////////////////////////////\n//\n/// \\file       outqueue.c\n/// \\brief"
  },
  {
    "path": "external/xz/liblzma/common/outqueue.h",
    "chars": 4998,
    "preview": "///////////////////////////////////////////////////////////////////////////////\n//\n/// \\file       outqueue.h\n/// \\brief"
  },
  {
    "path": "external/xz/liblzma/common/stream_buffer_decoder.c",
    "chars": 2785,
    "preview": "///////////////////////////////////////////////////////////////////////////////\n//\n/// \\file       stream_buffer_decoder"
  },
  {
    "path": "external/xz/liblzma/common/stream_buffer_encoder.c",
    "chars": 4056,
    "preview": "///////////////////////////////////////////////////////////////////////////////\n//\n/// \\file       stream_buffer_encoder"
  },
  {
    "path": "external/xz/liblzma/common/stream_decoder.c",
    "chars": 13001,
    "preview": "///////////////////////////////////////////////////////////////////////////////\n//\n/// \\file       stream_decoder.c\n/// "
  },
  {
    "path": "external/xz/liblzma/common/stream_decoder.h",
    "chars": 599,
    "preview": "///////////////////////////////////////////////////////////////////////////////\n//\n/// \\file       stream_decoder.h\n/// "
  },
  {
    "path": "external/xz/liblzma/common/stream_encoder.c",
    "chars": 9856,
    "preview": "///////////////////////////////////////////////////////////////////////////////\n//\n/// \\file       stream_encoder.c\n/// "
  },
  {
    "path": "external/xz/liblzma/common/stream_encoder_mt.c",
    "chars": 30356,
    "preview": "///////////////////////////////////////////////////////////////////////////////\n//\n/// \\file       stream_encoder_mt.c\n/"
  },
  {
    "path": "external/xz/liblzma/common/stream_flags_common.c",
    "chars": 1326,
    "preview": "///////////////////////////////////////////////////////////////////////////////\n//\n/// \\file       stream_flags_common.c"
  },
  {
    "path": "external/xz/liblzma/common/stream_flags_common.h",
    "chars": 883,
    "preview": "///////////////////////////////////////////////////////////////////////////////\n//\n/// \\file       stream_flags_common.h"
  },
  {
    "path": "external/xz/liblzma/common/stream_flags_decoder.c",
    "chars": 2279,
    "preview": "///////////////////////////////////////////////////////////////////////////////\n//\n/// \\file       stream_flags_decoder."
  },
  {
    "path": "external/xz/liblzma/common/stream_flags_encoder.c",
    "chars": 2059,
    "preview": "///////////////////////////////////////////////////////////////////////////////\n//\n/// \\file       stream_flags_encoder."
  },
  {
    "path": "external/xz/liblzma/common/vli_decoder.c",
    "chars": 2559,
    "preview": "///////////////////////////////////////////////////////////////////////////////\n//\n/// \\file       vli_decoder.c\n/// \\br"
  },
  {
    "path": "external/xz/liblzma/common/vli_encoder.c",
    "chars": 1935,
    "preview": "///////////////////////////////////////////////////////////////////////////////\n//\n/// \\file       vli_encoder.c\n/// \\br"
  },
  {
    "path": "external/xz/liblzma/common/vli_size.c",
    "chars": 630,
    "preview": "///////////////////////////////////////////////////////////////////////////////\n//\n/// \\file       vli_size.c\n/// \\brief"
  },
  {
    "path": "external/xz/liblzma/delta/delta_common.c",
    "chars": 1914,
    "preview": "///////////////////////////////////////////////////////////////////////////////\n//\n/// \\file       delta_common.c\n/// \\b"
  },
  {
    "path": "external/xz/liblzma/delta/delta_common.h",
    "chars": 542,
    "preview": "///////////////////////////////////////////////////////////////////////////////\n//\n/// \\file       delta_common.h\n/// \\b"
  },
  {
    "path": "external/xz/liblzma/delta/delta_decoder.c",
    "chars": 1910,
    "preview": "///////////////////////////////////////////////////////////////////////////////\n//\n/// \\file       delta_decoder.c\n/// \\"
  },
  {
    "path": "external/xz/liblzma/delta/delta_decoder.h",
    "chars": 736,
    "preview": "///////////////////////////////////////////////////////////////////////////////\n//\n/// \\file       delta_decoder.h\n/// \\"
  },
  {
    "path": "external/xz/liblzma/delta/delta_encoder.c",
    "chars": 3435,
    "preview": "///////////////////////////////////////////////////////////////////////////////\n//\n/// \\file       delta_encoder.c\n/// \\"
  },
  {
    "path": "external/xz/liblzma/delta/delta_encoder.h",
    "chars": 676,
    "preview": "///////////////////////////////////////////////////////////////////////////////\n//\n/// \\file       delta_encoder.h\n/// \\"
  },
  {
    "path": "external/xz/liblzma/delta/delta_private.h",
    "chars": 889,
    "preview": "///////////////////////////////////////////////////////////////////////////////\n//\n/// \\file       delta_private.h\n/// \\"
  },
  {
    "path": "external/xz/liblzma/lz/lz_decoder.c",
    "chars": 9130,
    "preview": "///////////////////////////////////////////////////////////////////////////////\n//\n/// \\file       lz_decoder.c\n/// \\bri"
  },
  {
    "path": "external/xz/liblzma/lz/lz_decoder.h",
    "chars": 5841,
    "preview": "///////////////////////////////////////////////////////////////////////////////\n//\n/// \\file       lz_decoder.h\n/// \\bri"
  },
  {
    "path": "external/xz/liblzma/lz/lz_encoder.c",
    "chars": 17392,
    "preview": "///////////////////////////////////////////////////////////////////////////////\n//\n/// \\file       lz_encoder.c\n/// \\bri"
  },
  {
    "path": "external/xz/liblzma/lz/lz_encoder.h",
    "chars": 10458,
    "preview": "///////////////////////////////////////////////////////////////////////////////\n//\n/// \\file       lz_encoder.h\n/// \\bri"
  },
  {
    "path": "external/xz/liblzma/lz/lz_encoder_hash.h",
    "chars": 3539,
    "preview": "///////////////////////////////////////////////////////////////////////////////\n//\n/// \\file       lz_encoder_hash.h\n///"
  },
  {
    "path": "external/xz/liblzma/lz/lz_encoder_hash_table.h",
    "chars": 3252,
    "preview": "/* This file has been automatically generated by crc32_tablegen.c. */\n\nconst uint32_t lzma_lz_hash_table[256] = {\n\t0x000"
  },
  {
    "path": "external/xz/liblzma/lz/lz_encoder_mf.c",
    "chars": 17379,
    "preview": "///////////////////////////////////////////////////////////////////////////////\n//\n/// \\file       lz_encoder_mf.c\n/// \\"
  },
  {
    "path": "external/xz/liblzma/lzma/fastpos.h",
    "chars": 3996,
    "preview": "///////////////////////////////////////////////////////////////////////////////\n//\n/// \\file       fastpos.h\n/// \\brief "
  },
  {
    "path": "external/xz/liblzma/lzma/fastpos_table.c",
    "chars": 33959,
    "preview": "/* This file has been automatically generated by fastpos_tablegen.c. */\n\n#include \"common.h\"\n#include \"fastpos.h\"\n\nconst"
  },
  {
    "path": "external/xz/liblzma/lzma/fastpos_tablegen.c",
    "chars": 1268,
    "preview": "///////////////////////////////////////////////////////////////////////////////\n//\n/// \\file       fastpos_tablegen.c\n//"
  },
  {
    "path": "external/xz/liblzma/lzma/lzma2_decoder.c",
    "chars": 7576,
    "preview": "///////////////////////////////////////////////////////////////////////////////\n//\n/// \\file       lzma2_decoder.c\n/// \\"
  },
  {
    "path": "external/xz/liblzma/lzma/lzma2_decoder.h",
    "chars": 819,
    "preview": "///////////////////////////////////////////////////////////////////////////////\n//\n/// \\file       lzma2_decoder.h\n/// \\"
  },
  {
    "path": "external/xz/liblzma/lzma/lzma2_encoder.c",
    "chars": 10500,
    "preview": "///////////////////////////////////////////////////////////////////////////////\n//\n/// \\file       lzma2_encoder.c\n/// \\"
  },
  {
    "path": "external/xz/liblzma/lzma/lzma2_encoder.h",
    "chars": 1186,
    "preview": "///////////////////////////////////////////////////////////////////////////////\n//\n/// \\file       lzma2_encoder.h\n/// \\"
  },
  {
    "path": "external/xz/liblzma/lzma/lzma_common.h",
    "chars": 6947,
    "preview": "///////////////////////////////////////////////////////////////////////////////\n//\n/// \\file       lzma_common.h\n/// \\br"
  },
  {
    "path": "external/xz/liblzma/lzma/lzma_decoder.c",
    "chars": 27321,
    "preview": "///////////////////////////////////////////////////////////////////////////////\n//\n/// \\file       lzma_decoder.c\n/// \\b"
  },
  {
    "path": "external/xz/liblzma/lzma/lzma_decoder.h",
    "chars": 1554,
    "preview": "///////////////////////////////////////////////////////////////////////////////\n//\n/// \\file       lzma_decoder.h\n/// \\b"
  },
  {
    "path": "external/xz/liblzma/lzma/lzma_encoder.c",
    "chars": 18518,
    "preview": "///////////////////////////////////////////////////////////////////////////////\n//\n/// \\file       lzma_encoder.c\n/// \\b"
  },
  {
    "path": "external/xz/liblzma/lzma/lzma_encoder.h",
    "chars": 1606,
    "preview": "///////////////////////////////////////////////////////////////////////////////\n//\n/// \\file       lzma_encoder.h\n/// \\b"
  },
  {
    "path": "external/xz/liblzma/lzma/lzma_encoder_optimum_fast.c",
    "chars": 4402,
    "preview": "///////////////////////////////////////////////////////////////////////////////\n//\n/// \\file       lzma_encoder_optimum_"
  },
  {
    "path": "external/xz/liblzma/lzma/lzma_encoder_optimum_normal.c",
    "chars": 23286,
    "preview": "///////////////////////////////////////////////////////////////////////////////\n//\n/// \\file       lzma_encoder_optimum_"
  },
  {
    "path": "external/xz/liblzma/lzma/lzma_encoder_presets.c",
    "chars": 1763,
    "preview": "///////////////////////////////////////////////////////////////////////////////\n//\n/// \\file       lzma_encoder_presets."
  },
  {
    "path": "external/xz/liblzma/lzma/lzma_encoder_private.h",
    "chars": 3911,
    "preview": "///////////////////////////////////////////////////////////////////////////////\n//\n/// \\file       lzma_encoder_private."
  },
  {
    "path": "external/xz/liblzma/rangecoder/price.h",
    "chars": 2013,
    "preview": "///////////////////////////////////////////////////////////////////////////////\n//\n/// \\file       price.h\n/// \\brief   "
  },
  {
    "path": "external/xz/liblzma/rangecoder/price_table.c",
    "chars": 827,
    "preview": "/* This file has been automatically generated by price_tablegen.c. */\n\n#include \"range_encoder.h\"\n\nconst uint8_t lzma_rc"
  }
]

// ... and 87 more files (download for full content)

About this extraction

This page contains the full source code of the svoboda18/magiskboot GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 287 files (2.5 MB), approximately 662.0k tokens, and a symbol index with 1880 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!