summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--Android.bp244
-rw-r--r--MODULE_LICENSE_BSD_LIKE0
-rw-r--r--arch/arm/crc32_acle.c40
-rw-r--r--arch/arm/insert_string_acle.c42
-rw-r--r--libz.map.txt151
-rw-r--r--zconf.h185
7 files changed, 660 insertions, 3 deletions
diff --git a/.gitignore b/.gitignore
index bf420e5..82bd204 100644
--- a/.gitignore
+++ b/.gitignore
@@ -55,7 +55,6 @@ Testing
/*.cmake
*.stackdump
*._h
-zconf.h
zconf.h.cmakein
zconf.h.included
zconf-ng.h
diff --git a/Android.bp b/Android.bp
new file mode 100644
index 0000000..a8444fb
--- /dev/null
+++ b/Android.bp
@@ -0,0 +1,244 @@
+package {
+ default_applicable_licenses: ["external_zlib_license"],
+}
+
+license {
+ name: "external_zlib_license",
+ visibility: [":__subpackages__"],
+ license_kinds: [
+ "SPDX-license-identifier-BSD",
+ "SPDX-license-identifier-Zlib",
+ ],
+ license_text: [
+ "LICENSE.md",
+ ],
+}
+
+srcs_arm = [
+ "arch/arm/adler32_neon.c",
+ "arch/arm/armfeature.c",
+ "arch/arm/chunkset_neon.c",
+ "arch/arm/crc32_acle.c",
+ "arch/arm/insert_string_acle.c",
+ "arch/arm/slide_neon.c",
+]
+
+// Not all CPUs will support these features, but compatibility is checked at runtime.
+cflags_arm = [
+ "-DARM_FEATURES",
+
+ // Runtime compatibility checks
+ "-DARM_AUXV_HAS_CRC32",
+ "-DARM_AUXV_HAS_NEON",
+
+ // Optional fatures
+ "-DARM_ACLE_CRC_HASH",
+ "-DARM_NEON_ADLER32",
+ "-DARM_NEON_CHUNKSET",
+ "-DARM_NEON_SLIDEHASH",
+]
+
+// The *device* x86 configuration (with *higher* CPU feature requirements).
+srcs_android_x86 = [
+ "arch/x86/adler32_avx.c",
+ "arch/x86/adler32_ssse3.c",
+ "arch/x86/chunkset_avx.c",
+ "arch/x86/chunkset_sse.c",
+ "arch/x86/compare258_avx.c",
+ "arch/x86/compare258_sse.c",
+ "arch/x86/crc_folding.c",
+ "arch/x86/insert_string_sse.c",
+ "arch/x86/slide_avx.c",
+ "arch/x86/slide_sse.c",
+ "arch/x86/x86.c",
+]
+cflags_android_x86 = [
+ "-DX86_AVX2",
+ "-DX86_AVX2_ADLER32",
+ "-DX86_AVX_CHUNKSET",
+ "-DX86_FEATURES",
+ "-DX86_PCLMULQDQ_CRC",
+ "-DX86_SSE2",
+ "-DX86_SSE2_CHUNKSET",
+ "-DX86_SSE2_SLIDEHASH",
+ "-DX86_SSE42_CMP_STR",
+ "-DX86_SSE42_CRC_HASH",
+ "-DX86_SSE42_CRC_INTRIN",
+ "-DX86_SSSE3",
+ "-DX86_SSSE3_ADLER32",
+ "-mavx2",
+ "-msse4",
+ "-mssse3",
+ "-mpclmul",
+]
+
+// This optimization is applicable to arm64 and x86-64.
+cflags_64 = ["-DUNALIGNED64_OK"]
+
+libz_srcs = [
+ "adler32.c",
+ "chunkset.c",
+ "compare258.c",
+ "compress.c",
+ "crc32_comb.c",
+ "crc32.c",
+ "deflate_fast.c",
+ "deflate_medium.c",
+ "deflate_quick.c",
+ "deflate_slow.c",
+ "deflate.c",
+ "functable.c",
+ "gzlib.c",
+ "gzread.c",
+ "gzwrite.c",
+ "infback.c",
+ "inffast.c",
+ "inflate.c",
+ "inftrees.c",
+ "insert_string.c",
+ "trees.c",
+ "uncompr.c",
+ "zutil.c",
+]
+
+cflags_common = [
+ "-DHAVE_BUILTIN_CTZ",
+ "-DHAVE_BUILTIN_CTZLL",
+ "-DHAVE_VISIBILITY_HIDDEN",
+ "-DHAVE_VISIBILITY_INTERNAL",
+ "-DZLIB_CONST",
+
+ "-DWITH_GZFILEOP",
+ "-DZLIB_COMPAT",
+ "-DZLIB_DLL",
+ "-D_LARGEFILE64_SOURCE=1",
+ "-D__USE_LARGEFILE64",
+ "-Wall",
+ "-Werror",
+ "-Wno-implicit-fallthrough",
+ "-O3",
+ "-DNDEBUG",
+ "-fno-semantic-interposition",
+ "-std=c99",
+ "-DUNALIGNED_OK",
+]
+
+cc_defaults {
+ name: "libz_defaults",
+
+ cflags: cflags_common,
+ stl: "none",
+ export_include_dirs: ["."],
+ srcs: libz_srcs,
+
+ arch: {
+ arm: {
+ // TODO: This is to work around b/24465209. Remove after root cause
+ // is fixed.
+ pack_relocations: false,
+ ldflags: ["-Wl,--hash-style=both"],
+
+ cflags: cflags_arm,
+ srcs: srcs_arm,
+ },
+ arm64: {
+ cflags: cflags_arm + cflags_64,
+ srcs: srcs_arm,
+ },
+ x86_64: {
+ cflags: cflags_64,
+ },
+ },
+ target: {
+ android_x86: {
+ srcs: srcs_android_x86,
+ cflags: cflags_android_x86,
+ },
+ android_x86_64: {
+ srcs: srcs_android_x86,
+ cflags: cflags_android_x86 + cflags_64,
+ },
+ },
+}
+
+cc_library {
+ name: "libz",
+ defaults: ["libz_defaults"],
+
+ host_supported: true,
+ unique_host_soname: true,
+ static_ndk_lib: true,
+
+ vendor_available: true,
+ product_available: true,
+ vndk: {
+ enabled: true,
+ support_system_process: true,
+ },
+ ramdisk_available: true,
+ vendor_ramdisk_available: true,
+ recovery_available: true,
+ native_bridge_supported: true,
+
+ target: {
+ linux_bionic: {
+ enabled: true,
+ },
+ windows: {
+ enabled: true,
+ },
+ },
+
+ stubs: {
+ versions: [
+ "29",
+ "30",
+ ],
+ symbol_file: "libz.map.txt",
+ },
+}
+
+// A more stable build of libz. Build configuration of this library should be
+// the same for different targets. This is only used by imgdiff.
+
+cc_library {
+ name: "libz_stable",
+ visibility: [
+ "//bootable/recovery/applypatch",
+ "//bootable/recovery/tests",
+ ],
+ cflags: cflags_common,
+ stl: "none",
+ export_include_dirs: ["."],
+ srcs: libz_srcs,
+
+ host_supported: true,
+ vendor_available: true,
+ recovery_available: true,
+}
+
+cc_binary_host {
+ name: "minigzip",
+ srcs: ["test/minigzip.c"],
+ cflags: cflags_common,
+ static_libs: ["libz"],
+ stl: "none",
+}
+
+ndk_headers {
+ name: "libz_headers",
+ from: "",
+ to: "",
+ srcs: [
+ "zconf.h",
+ "zlib.h",
+ ],
+ license: "LICENSE.md",
+}
+
+ndk_library {
+ name: "libz",
+ symbol_file: "libz.map.txt",
+ first_version: "9",
+ unversioned_until: "current",
+}
diff --git a/MODULE_LICENSE_BSD_LIKE b/MODULE_LICENSE_BSD_LIKE
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/MODULE_LICENSE_BSD_LIKE
diff --git a/arch/arm/crc32_acle.c b/arch/arm/crc32_acle.c
index 88ba6c3..99013e1 100644
--- a/arch/arm/crc32_acle.c
+++ b/arch/arm/crc32_acle.c
@@ -11,6 +11,46 @@
#endif
#include "../../zutil.h"
+#if defined(__clang__)
+/* CRC32 intrinsics are #ifdef'ed out of arm_acle.h unless we build with an
+ * armv8 target, which is incompatible with ThinLTO optimizations on Android.
+ * (Namely, mixing and matching different module-level targets makes ThinLTO
+ * warn, and Android defaults to armv7-a. This restriction does not apply to
+ * function-level `target`s, however.)
+ *
+ * Since we only need four crc intrinsics, and since clang's implementation of
+ * those are just wrappers around compiler builtins, it's simplest to #define
+ * those builtins directly. If this #define list grows too much (or we depend on
+ * an intrinsic that isn't a trivial wrapper), we may have to find a better way
+ * to go about this.
+ *
+ * NOTE: clang currently complains that "'+soft-float-abi' is not a recognized
+ * feature for this target (ignoring feature)." This appears to be a harmless
+ * bug in clang.
+ */
+#define __crc32b __builtin_arm_crc32b
+#define __crc32d __builtin_arm_crc32d
+#define __crc32w __builtin_arm_crc32w
+#define __crc32cw __builtin_arm_crc32cw
+#define __crc32h __builtin_arm_crc32h
+
+#if defined(__aarch64__)
+#define TARGET_ARMV8_WITH_CRC __attribute__((target("crc")))
+#else // !defined(__aarch64__)
+#define TARGET_ARMV8_WITH_CRC __attribute__((target("armv8-a,crc")))
+#endif // defined(__aarch64__)
+
+#elif defined(__GNUC__)
+/* For GCC, we are setting CRC extensions at module level, so ThinLTO is not
+ * allowed. We can just include arm_acle.h.
+ */
+#include <arm_acle.h>
+#define TARGET_ARMV8_WITH_CRC
+#else // !defined(__GNUC__) && !defined(_aarch64__)
+#error ARM CRC32 SIMD extensions only supported for Clang and GCC
+#endif
+
+TARGET_ARMV8_WITH_CRC
uint32_t crc32_acle(uint32_t crc, const unsigned char *buf, uint64_t len) {
Z_REGISTER uint32_t c;
Z_REGISTER const uint16_t *buf2;
diff --git a/arch/arm/insert_string_acle.c b/arch/arm/insert_string_acle.c
index 2daf9ba..4fd5fa7 100644
--- a/arch/arm/insert_string_acle.c
+++ b/arch/arm/insert_string_acle.c
@@ -12,11 +12,49 @@
#include "../../zbuild.h"
#include "../../deflate.h"
+#if defined(__clang__)
+/* CRC32 intrinsics are #ifdef'ed out of arm_acle.h unless we build with an
+ * armv8 target, which is incompatible with ThinLTO optimizations on Android.
+ * (Namely, mixing and matching different module-level targets makes ThinLTO
+ * warn, and Android defaults to armv7-a. This restriction does not apply to
+ * function-level `target`s, however.)
+ *
+ * Since we only need four crc intrinsics, and since clang's implementation of
+ * those are just wrappers around compiler builtins, it's simplest to #define
+ * those builtins directly. If this #define list grows too much (or we depend on
+ * an intrinsic that isn't a trivial wrapper), we may have to find a better way
+ * to go about this.
+ *
+ * NOTE: clang currently complains that "'+soft-float-abi' is not a recognized
+ * feature for this target (ignoring feature)." This appears to be a harmless
+ * bug in clang.
+ */
+#define __crc32b __builtin_arm_crc32b
+#define __crc32d __builtin_arm_crc32d
+#define __crc32w __builtin_arm_crc32w
+#define __crc32cw __builtin_arm_crc32cw
+
+#if defined(__aarch64__)
+#define TARGET_ARMV8_WITH_CRC __attribute__((target("crc")))
+#else // !defined(__aarch64__)
+#define TARGET_ARMV8_WITH_CRC __attribute__((target("armv8-a,crc")))
+#endif // defined(__aarch64__)
+
+#elif defined(__GNUC__)
+/* For GCC, we are setting CRC extensions at module level, so ThinLTO is not
+ * allowed. We can just include arm_acle.h.
+ */
+#include <arm_acle.h>
+#define TARGET_ARMV8_WITH_CRC
+#else // !defined(__GNUC__) && !defined(_aarch64__)
+#error ARM CRC32 SIMD extensions only supported for Clang and GCC
+#endif
+
#define UPDATE_HASH(s, h, val) \
h = __crc32w(0, val)
-#define INSERT_STRING insert_string_acle
-#define QUICK_INSERT_STRING quick_insert_string_acle
+#define INSERT_STRING TARGET_ARMV8_WITH_CRC insert_string_acle
+#define QUICK_INSERT_STRING TARGET_ARMV8_WITH_CRC quick_insert_string_acle
#include "../../insert_string_tpl.h"
#endif
diff --git a/libz.map.txt b/libz.map.txt
new file mode 100644
index 0000000..850bbf8
--- /dev/null
+++ b/libz.map.txt
@@ -0,0 +1,151 @@
+# This file is copied from src/zlib.map and annotated with comments for the NDK
+# stub library generation script.
+ZLIB_1.2.0 {
+ global:
+ compressBound;
+ deflateBound;
+ inflateBack;
+ inflateBackEnd;
+ inflateBackInit_;
+ inflateCopy;
+ local:
+ deflate_copyright; # var
+ inflate_copyright; # var
+ inflate_fast;
+ inflate_table;
+ zcalloc;
+ zcfree;
+ z_errmsg; # var
+ gz_error;
+ gz_intmax;
+ _*;
+};
+
+ZLIB_1.2.0.2 {
+ gzclearerr;
+ gzungetc;
+ zlibCompileFlags;
+} ZLIB_1.2.0;
+
+ZLIB_1.2.0.8 {
+ deflatePrime;
+} ZLIB_1.2.0.2;
+
+ZLIB_1.2.2 {
+ adler32_combine;
+ crc32_combine;
+ deflateSetHeader;
+ inflateGetHeader;
+} ZLIB_1.2.0.8;
+
+ZLIB_1.2.2.3 {
+ deflateTune;
+ gzdirect;
+} ZLIB_1.2.2;
+
+ZLIB_1.2.2.4 {
+ inflatePrime;
+} ZLIB_1.2.2.3;
+
+ZLIB_1.2.3.3 {
+ adler32_combine64;
+ crc32_combine64;
+ gzopen64;
+ gzseek64;
+ gztell64;
+ inflateUndermine;
+} ZLIB_1.2.2.4;
+
+ZLIB_1.2.3.4 {
+ inflateReset2;
+ inflateMark;
+} ZLIB_1.2.3.3;
+
+ZLIB_1.2.3.5 {
+ gzbuffer;
+ gzoffset;
+ gzoffset64;
+ gzclose_r;
+ gzclose_w;
+} ZLIB_1.2.3.4;
+
+ZLIB_1.2.5.1 {
+ deflatePending;
+} ZLIB_1.2.3.5;
+
+ZLIB_1.2.5.2 {
+ deflateResetKeep;
+ gzgetc_;
+ inflateResetKeep;
+} ZLIB_1.2.5.1;
+
+ZLIB_1.2.7.1 { # introduced=19
+ inflateGetDictionary;
+ gzvprintf;
+} ZLIB_1.2.5.2;
+
+ZLIB_1.2.9 { # introduced=28
+ inflateCodesUsed;
+ inflateValidate;
+ uncompress2;
+ gzfread;
+ gzfwrite;
+ deflateGetDictionary;
+ adler32_z;
+ crc32_z;
+} ZLIB_1.2.7.1;
+
+# These were all exposed by the old NDK stub library. Unclear if they still
+# should be, but at least some of them are marked as being exported in zlib.h
+# and the tree doesn't build without them.
+ZLIB_NDK {
+ _dist_code;
+ _length_code;
+ _tr_align;
+ _tr_flush_bits; # introduced=21
+ _tr_flush_block;
+ _tr_init;
+ _tr_stored_block;
+ _tr_tally;
+ adler32;
+ compress2;
+ compress;
+ crc32;
+ deflate;
+ deflateCopy;
+ deflateEnd;
+ deflateInit2_;
+ deflateInit_;
+ deflateParams;
+ deflateReset;
+ deflateSetDictionary;
+ get_crc_table;
+ gzclose;
+ gzdopen;
+ gzeof;
+ gzerror;
+ gzflush;
+ gzgetc;
+ gzgets;
+ gzopen;
+ gzprintf;
+ gzputc;
+ gzputs;
+ gzread;
+ gzrewind;
+ gzseek;
+ gzsetparams;
+ gztell;
+ gzwrite;
+ inflate;
+ inflateEnd;
+ inflateInit2_;
+ inflateInit_;
+ inflateReset;
+ inflateSetDictionary;
+ inflateSync;
+ inflateSyncPoint;
+ uncompress;
+ zError;
+ zlibVersion;
+};
diff --git a/zconf.h b/zconf.h
new file mode 100644
index 0000000..58255ed
--- /dev/null
+++ b/zconf.h
@@ -0,0 +1,185 @@
+/* zconf.h -- configuration of the zlib compression library
+ * Copyright (C) 1995-2016 Jean-loup Gailly, Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+#ifndef ZCONF_H
+#define ZCONF_H
+
+#if !defined(_WIN32) && defined(__WIN32__)
+# define _WIN32
+#endif
+
+#ifdef __STDC_VERSION__
+# if __STDC_VERSION__ >= 199901L
+# ifndef STDC99
+# define STDC99
+# endif
+# endif
+#endif
+
+/* Clang macro for detecting declspec support
+ * https://clang.llvm.org/docs/LanguageExtensions.html#has-declspec-attribute
+ */
+#ifndef __has_declspec_attribute
+# define __has_declspec_attribute(x) 0
+#endif
+
+#if defined(ZLIB_CONST) && !defined(z_const)
+# define z_const const
+#else
+# define z_const
+#endif
+
+/* Maximum value for memLevel in deflateInit2 */
+#ifndef MAX_MEM_LEVEL
+# define MAX_MEM_LEVEL 9
+#endif
+
+/* Maximum value for windowBits in deflateInit2 and inflateInit2.
+ * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files
+ * created by gzip. (Files created by minigzip can still be extracted by
+ * gzip.)
+ */
+#ifndef MAX_WBITS
+# define MAX_WBITS 15 /* 32K LZ77 window */
+#endif
+
+/* The memory requirements for deflate are (in bytes):
+ (1 << (windowBits+2)) + (1 << (memLevel+9))
+ that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values)
+ plus a few kilobytes for small objects. For example, if you want to reduce
+ the default memory requirements from 256K to 128K, compile with
+ make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7"
+ Of course this will generally degrade compression (there's no free lunch).
+
+ The memory requirements for inflate are (in bytes) 1 << windowBits
+ that is, 32K for windowBits=15 (default value) plus about 7 kilobytes
+ for small objects.
+*/
+
+/* Type declarations */
+
+
+#ifndef OF /* function prototypes */
+# define OF(args) args
+#endif
+
+#ifdef ZLIB_INTERNAL
+# define Z_INTERNAL ZLIB_INTERNAL
+#endif
+
+/* If building or using zlib as a DLL, define ZLIB_DLL.
+ * This is not mandatory, but it offers a little performance increase.
+ */
+#if defined(ZLIB_DLL) && (defined(_WIN32) || (__has_declspec_attribute(dllexport) && __has_declspec_attribute(dllimport)))
+# ifdef Z_INTERNAL
+# define Z_EXTERN extern __declspec(dllexport)
+# else
+# define Z_EXTERN extern __declspec(dllimport)
+# endif
+#endif
+
+/* If building or using zlib with the WINAPI/WINAPIV calling convention,
+ * define ZLIB_WINAPI.
+ * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI.
+ */
+#if defined(ZLIB_WINAPI) && defined(_WIN32)
+# include <windows.h>
+ /* No need for _export, use ZLIB.DEF instead. */
+ /* For complete Windows compatibility, use WINAPI, not __stdcall. */
+# define Z_EXPORT WINAPI
+# define Z_EXPORTVA WINAPIV
+#endif
+
+#ifndef Z_EXTERN
+# define Z_EXTERN extern
+#endif
+#ifndef Z_EXPORT
+# define Z_EXPORT
+#endif
+#ifndef Z_EXPORTVA
+# define Z_EXPORTVA
+#endif
+
+/* Fallback for something that includes us. */
+typedef unsigned char Byte;
+typedef Byte Bytef;
+
+typedef unsigned int uInt; /* 16 bits or more */
+typedef unsigned long uLong; /* 32 bits or more */
+
+typedef char charf;
+typedef int intf;
+typedef uInt uIntf;
+typedef uLong uLongf;
+
+typedef void const *voidpc;
+typedef void *voidpf;
+typedef void *voidp;
+
+#if 1 /* was set to #if 1 by configure/cmake/etc */
+# define Z_HAVE_UNISTD_H
+#endif
+
+#ifdef NEED_PTRDIFF_T /* may be set to #if 1 by configure/cmake/etc */
+typedef PTRDIFF_TYPE ptrdiff_t;
+#endif
+
+#include <sys/types.h> /* for off_t */
+#include <stdarg.h> /* for va_list */
+
+#include <stddef.h> /* for wchar_t and NULL */
+
+/* a little trick to accommodate both "#define _LARGEFILE64_SOURCE" and
+ * "#define _LARGEFILE64_SOURCE 1" as requesting 64-bit operations, (even
+ * though the former does not conform to the LFS document), but considering
+ * both "#undef _LARGEFILE64_SOURCE" and "#define _LARGEFILE64_SOURCE 0" as
+ * equivalently requesting no 64-bit operations
+ */
+#if defined(_LARGEFILE64_SOURCE) && -_LARGEFILE64_SOURCE - -1 == 1
+# undef _LARGEFILE64_SOURCE
+#endif
+
+#if defined(Z_HAVE_UNISTD_H) || defined(_LARGEFILE64_SOURCE)
+# include <unistd.h> /* for SEEK_*, off_t, and _LFS64_LARGEFILE */
+# ifndef z_off_t
+# define z_off_t off_t
+# endif
+#endif
+
+#if defined(_LFS64_LARGEFILE) && _LFS64_LARGEFILE-0
+# define Z_LFS64
+#endif
+
+#if defined(_LARGEFILE64_SOURCE) && defined(Z_LFS64)
+# define Z_LARGE64
+#endif
+
+#if defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS-0 == 64 && defined(Z_LFS64)
+# define Z_WANT64
+#endif
+
+#if !defined(SEEK_SET)
+# define SEEK_SET 0 /* Seek from beginning of file. */
+# define SEEK_CUR 1 /* Seek from current position. */
+# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */
+#endif
+
+#ifndef z_off_t
+# define z_off_t long
+#endif
+
+#if !defined(_WIN32) && defined(Z_LARGE64)
+# define z_off64_t off64_t
+#else
+# if defined(__MSYS__)
+# define z_off64_t _off64_t
+# elif defined(_WIN32) && !defined(__GNUC__)
+# define z_off64_t __int64
+# else
+# define z_off64_t z_off_t
+# endif
+#endif
+
+#endif /* ZCONF_H */