extzstd 0.3.2 → 0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (112) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +4 -3
  3. data/contrib/zstd/CHANGELOG +225 -1
  4. data/contrib/zstd/CONTRIBUTING.md +158 -75
  5. data/contrib/zstd/LICENSE +4 -4
  6. data/contrib/zstd/Makefile +106 -69
  7. data/contrib/zstd/Package.swift +36 -0
  8. data/contrib/zstd/README.md +64 -36
  9. data/contrib/zstd/SECURITY.md +15 -0
  10. data/contrib/zstd/TESTING.md +2 -3
  11. data/contrib/zstd/lib/BUCK +5 -7
  12. data/contrib/zstd/lib/Makefile +117 -199
  13. data/contrib/zstd/lib/README.md +37 -7
  14. data/contrib/zstd/lib/common/allocations.h +55 -0
  15. data/contrib/zstd/lib/common/bits.h +200 -0
  16. data/contrib/zstd/lib/common/bitstream.h +80 -86
  17. data/contrib/zstd/lib/common/compiler.h +225 -63
  18. data/contrib/zstd/lib/common/cpu.h +37 -1
  19. data/contrib/zstd/lib/common/debug.c +7 -1
  20. data/contrib/zstd/lib/common/debug.h +21 -12
  21. data/contrib/zstd/lib/common/entropy_common.c +15 -37
  22. data/contrib/zstd/lib/common/error_private.c +9 -2
  23. data/contrib/zstd/lib/common/error_private.h +93 -5
  24. data/contrib/zstd/lib/common/fse.h +12 -87
  25. data/contrib/zstd/lib/common/fse_decompress.c +37 -117
  26. data/contrib/zstd/lib/common/huf.h +97 -172
  27. data/contrib/zstd/lib/common/mem.h +58 -58
  28. data/contrib/zstd/lib/common/pool.c +38 -17
  29. data/contrib/zstd/lib/common/pool.h +10 -4
  30. data/contrib/zstd/lib/common/portability_macros.h +158 -0
  31. data/contrib/zstd/lib/common/threading.c +74 -14
  32. data/contrib/zstd/lib/common/threading.h +5 -10
  33. data/contrib/zstd/lib/common/xxhash.c +6 -814
  34. data/contrib/zstd/lib/common/xxhash.h +6930 -195
  35. data/contrib/zstd/lib/common/zstd_common.c +1 -36
  36. data/contrib/zstd/lib/common/zstd_deps.h +1 -1
  37. data/contrib/zstd/lib/common/zstd_internal.h +68 -154
  38. data/contrib/zstd/lib/common/zstd_trace.h +163 -0
  39. data/contrib/zstd/lib/compress/clevels.h +134 -0
  40. data/contrib/zstd/lib/compress/fse_compress.c +75 -155
  41. data/contrib/zstd/lib/compress/hist.c +1 -1
  42. data/contrib/zstd/lib/compress/hist.h +1 -1
  43. data/contrib/zstd/lib/compress/huf_compress.c +810 -259
  44. data/contrib/zstd/lib/compress/zstd_compress.c +2864 -919
  45. data/contrib/zstd/lib/compress/zstd_compress_internal.h +523 -192
  46. data/contrib/zstd/lib/compress/zstd_compress_literals.c +117 -40
  47. data/contrib/zstd/lib/compress/zstd_compress_literals.h +16 -6
  48. data/contrib/zstd/lib/compress/zstd_compress_sequences.c +28 -19
  49. data/contrib/zstd/lib/compress/zstd_compress_sequences.h +1 -1
  50. data/contrib/zstd/lib/compress/zstd_compress_superblock.c +251 -412
  51. data/contrib/zstd/lib/compress/zstd_compress_superblock.h +1 -1
  52. data/contrib/zstd/lib/compress/zstd_cwksp.h +284 -97
  53. data/contrib/zstd/lib/compress/zstd_double_fast.c +382 -133
  54. data/contrib/zstd/lib/compress/zstd_double_fast.h +14 -2
  55. data/contrib/zstd/lib/compress/zstd_fast.c +732 -260
  56. data/contrib/zstd/lib/compress/zstd_fast.h +3 -2
  57. data/contrib/zstd/lib/compress/zstd_lazy.c +1177 -390
  58. data/contrib/zstd/lib/compress/zstd_lazy.h +129 -14
  59. data/contrib/zstd/lib/compress/zstd_ldm.c +280 -210
  60. data/contrib/zstd/lib/compress/zstd_ldm.h +3 -2
  61. data/contrib/zstd/lib/compress/zstd_ldm_geartab.h +106 -0
  62. data/contrib/zstd/lib/compress/zstd_opt.c +516 -285
  63. data/contrib/zstd/lib/compress/zstd_opt.h +32 -8
  64. data/contrib/zstd/lib/compress/zstdmt_compress.c +202 -131
  65. data/contrib/zstd/lib/compress/zstdmt_compress.h +9 -6
  66. data/contrib/zstd/lib/decompress/huf_decompress.c +1149 -555
  67. data/contrib/zstd/lib/decompress/huf_decompress_amd64.S +595 -0
  68. data/contrib/zstd/lib/decompress/zstd_ddict.c +4 -4
  69. data/contrib/zstd/lib/decompress/zstd_ddict.h +1 -1
  70. data/contrib/zstd/lib/decompress/zstd_decompress.c +583 -106
  71. data/contrib/zstd/lib/decompress/zstd_decompress_block.c +1054 -379
  72. data/contrib/zstd/lib/decompress/zstd_decompress_block.h +14 -3
  73. data/contrib/zstd/lib/decompress/zstd_decompress_internal.h +56 -6
  74. data/contrib/zstd/lib/deprecated/zbuff.h +1 -1
  75. data/contrib/zstd/lib/deprecated/zbuff_common.c +1 -1
  76. data/contrib/zstd/lib/deprecated/zbuff_compress.c +24 -4
  77. data/contrib/zstd/lib/deprecated/zbuff_decompress.c +3 -1
  78. data/contrib/zstd/lib/dictBuilder/cover.c +60 -44
  79. data/contrib/zstd/lib/dictBuilder/cover.h +6 -11
  80. data/contrib/zstd/lib/dictBuilder/divsufsort.c +1 -1
  81. data/contrib/zstd/lib/dictBuilder/fastcover.c +26 -18
  82. data/contrib/zstd/lib/dictBuilder/zdict.c +100 -101
  83. data/contrib/zstd/lib/legacy/zstd_legacy.h +38 -1
  84. data/contrib/zstd/lib/legacy/zstd_v01.c +18 -53
  85. data/contrib/zstd/lib/legacy/zstd_v01.h +1 -1
  86. data/contrib/zstd/lib/legacy/zstd_v02.c +28 -85
  87. data/contrib/zstd/lib/legacy/zstd_v02.h +1 -1
  88. data/contrib/zstd/lib/legacy/zstd_v03.c +29 -88
  89. data/contrib/zstd/lib/legacy/zstd_v03.h +1 -1
  90. data/contrib/zstd/lib/legacy/zstd_v04.c +27 -80
  91. data/contrib/zstd/lib/legacy/zstd_v04.h +1 -1
  92. data/contrib/zstd/lib/legacy/zstd_v05.c +36 -85
  93. data/contrib/zstd/lib/legacy/zstd_v05.h +1 -1
  94. data/contrib/zstd/lib/legacy/zstd_v06.c +44 -96
  95. data/contrib/zstd/lib/legacy/zstd_v06.h +1 -1
  96. data/contrib/zstd/lib/legacy/zstd_v07.c +37 -92
  97. data/contrib/zstd/lib/legacy/zstd_v07.h +1 -1
  98. data/contrib/zstd/lib/libzstd.mk +237 -0
  99. data/contrib/zstd/lib/libzstd.pc.in +4 -3
  100. data/contrib/zstd/lib/module.modulemap +35 -0
  101. data/contrib/zstd/lib/{dictBuilder/zdict.h → zdict.h} +202 -33
  102. data/contrib/zstd/lib/zstd.h +1030 -332
  103. data/contrib/zstd/lib/{common/zstd_errors.h → zstd_errors.h} +27 -8
  104. data/ext/extconf.rb +26 -7
  105. data/ext/extzstd.c +51 -24
  106. data/ext/extzstd.h +33 -6
  107. data/ext/extzstd_stream.c +74 -31
  108. data/ext/libzstd_conf.h +0 -1
  109. data/ext/zstd_decompress_asm.S +1 -0
  110. metadata +17 -7
  111. data/contrib/zstd/appveyor.yml +0 -292
  112. data/ext/depend +0 -2
@@ -1,5 +1,5 @@
1
1
  /*
2
- * Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
3
  * All rights reserved.
4
4
  *
5
5
  * This source code is licensed under both the BSD-style license (found in the
@@ -11,6 +11,10 @@
11
11
  #ifndef ZSTD_COMPILER_H
12
12
  #define ZSTD_COMPILER_H
13
13
 
14
+ #include <stddef.h>
15
+
16
+ #include "portability_macros.h"
17
+
14
18
  /*-*******************************************************
15
19
  * Compiler specifics
16
20
  *********************************************************/
@@ -40,7 +44,7 @@
40
44
 
41
45
  /**
42
46
  On MSVC qsort requires that functions passed into it use the __cdecl calling conversion(CC).
43
- This explictly marks such functions as __cdecl so that the code will still compile
47
+ This explicitly marks such functions as __cdecl so that the code will still compile
44
48
  if a CC other than __cdecl has been made the default.
45
49
  */
46
50
  #if defined(_MSC_VER)
@@ -49,12 +53,19 @@
49
53
  # define WIN_CDECL
50
54
  #endif
51
55
 
56
+ /* UNUSED_ATTR tells the compiler it is okay if the function is unused. */
57
+ #if defined(__GNUC__)
58
+ # define UNUSED_ATTR __attribute__((unused))
59
+ #else
60
+ # define UNUSED_ATTR
61
+ #endif
62
+
52
63
  /**
53
64
  * FORCE_INLINE_TEMPLATE is used to define C "templates", which take constant
54
65
  * parameters. They must be inlined for the compiler to eliminate the constant
55
66
  * branches.
56
67
  */
57
- #define FORCE_INLINE_TEMPLATE static INLINE_KEYWORD FORCE_INLINE_ATTR
68
+ #define FORCE_INLINE_TEMPLATE static INLINE_KEYWORD FORCE_INLINE_ATTR UNUSED_ATTR
58
69
  /**
59
70
  * HINT_INLINE is used to help the compiler generate better code. It is *not*
60
71
  * used for "templates", so it can be tweaked based on the compilers
@@ -69,14 +80,28 @@
69
80
  #if !defined(__clang__) && defined(__GNUC__) && __GNUC__ >= 4 && __GNUC_MINOR__ >= 8 && __GNUC__ < 5
70
81
  # define HINT_INLINE static INLINE_KEYWORD
71
82
  #else
72
- # define HINT_INLINE static INLINE_KEYWORD FORCE_INLINE_ATTR
83
+ # define HINT_INLINE FORCE_INLINE_TEMPLATE
73
84
  #endif
74
85
 
75
- /* UNUSED_ATTR tells the compiler it is okay if the function is unused. */
86
+ /* "soft" inline :
87
+ * The compiler is free to select if it's a good idea to inline or not.
88
+ * The main objective is to silence compiler warnings
89
+ * when a defined function in included but not used.
90
+ *
91
+ * Note : this macro is prefixed `MEM_` because it used to be provided by `mem.h` unit.
92
+ * Updating the prefix is probably preferable, but requires a fairly large codemod,
93
+ * since this name is used everywhere.
94
+ */
95
+ #ifndef MEM_STATIC /* already defined in Linux Kernel mem.h */
76
96
  #if defined(__GNUC__)
77
- # define UNUSED_ATTR __attribute__((unused))
97
+ # define MEM_STATIC static __inline UNUSED_ATTR
98
+ #elif defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */)
99
+ # define MEM_STATIC static inline
100
+ #elif defined(_MSC_VER)
101
+ # define MEM_STATIC static __inline
78
102
  #else
79
- # define UNUSED_ATTR
103
+ # define MEM_STATIC static /* this version may generate warnings for unused static functions; disable the relevant warning */
104
+ #endif
80
105
  #endif
81
106
 
82
107
  /* force no inlining */
@@ -90,38 +115,27 @@
90
115
  # endif
91
116
  #endif
92
117
 
118
+
93
119
  /* target attribute */
94
- #ifndef __has_attribute
95
- #define __has_attribute(x) 0 /* Compatibility with non-clang compilers. */
96
- #endif
97
120
  #if defined(__GNUC__) || defined(__ICCARM__)
98
121
  # define TARGET_ATTRIBUTE(target) __attribute__((__target__(target)))
99
122
  #else
100
123
  # define TARGET_ATTRIBUTE(target)
101
124
  #endif
102
125
 
103
- /* Enable runtime BMI2 dispatch based on the CPU.
104
- * Enabled for clang & gcc >=4.8 on x86 when BMI2 isn't enabled by default.
126
+ /* Target attribute for BMI2 dynamic dispatch.
127
+ * Enable lzcnt, bmi, and bmi2.
128
+ * We test for bmi1 & bmi2. lzcnt is included in bmi1.
105
129
  */
106
- #ifndef DYNAMIC_BMI2
107
- #if ((defined(__clang__) && __has_attribute(__target__)) \
108
- || (defined(__GNUC__) \
109
- && (__GNUC__ >= 5 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)))) \
110
- && (defined(__x86_64__) || defined(_M_X86)) \
111
- && !defined(__BMI2__)
112
- # define DYNAMIC_BMI2 1
113
- #else
114
- # define DYNAMIC_BMI2 0
115
- #endif
116
- #endif
130
+ #define BMI2_TARGET_ATTRIBUTE TARGET_ATTRIBUTE("lzcnt,bmi,bmi2")
117
131
 
118
132
  /* prefetch
119
133
  * can be disabled, by declaring NO_PREFETCH build macro */
120
134
  #if defined(NO_PREFETCH)
121
- # define PREFETCH_L1(ptr) (void)(ptr) /* disabled */
122
- # define PREFETCH_L2(ptr) (void)(ptr) /* disabled */
135
+ # define PREFETCH_L1(ptr) do { (void)(ptr); } while (0) /* disabled */
136
+ # define PREFETCH_L2(ptr) do { (void)(ptr); } while (0) /* disabled */
123
137
  #else
124
- # if defined(_MSC_VER) && (defined(_M_X64) || defined(_M_I86)) /* _mm_prefetch() is not defined outside of x86/x64 */
138
+ # if defined(_MSC_VER) && (defined(_M_X64) || defined(_M_I86)) && !defined(_M_ARM64EC) /* _mm_prefetch() is not defined outside of x86/x64 */
125
139
  # include <mmintrin.h> /* https://msdn.microsoft.com/fr-fr/library/84szxsww(v=vs.90).aspx */
126
140
  # define PREFETCH_L1(ptr) _mm_prefetch((const char*)(ptr), _MM_HINT_T0)
127
141
  # define PREFETCH_L2(ptr) _mm_prefetch((const char*)(ptr), _MM_HINT_T1)
@@ -129,28 +143,30 @@
129
143
  # define PREFETCH_L1(ptr) __builtin_prefetch((ptr), 0 /* rw==read */, 3 /* locality */)
130
144
  # define PREFETCH_L2(ptr) __builtin_prefetch((ptr), 0 /* rw==read */, 2 /* locality */)
131
145
  # elif defined(__aarch64__)
132
- # define PREFETCH_L1(ptr) __asm__ __volatile__("prfm pldl1keep, %0" ::"Q"(*(ptr)))
133
- # define PREFETCH_L2(ptr) __asm__ __volatile__("prfm pldl2keep, %0" ::"Q"(*(ptr)))
146
+ # define PREFETCH_L1(ptr) do { __asm__ __volatile__("prfm pldl1keep, %0" ::"Q"(*(ptr))); } while (0)
147
+ # define PREFETCH_L2(ptr) do { __asm__ __volatile__("prfm pldl2keep, %0" ::"Q"(*(ptr))); } while (0)
134
148
  # else
135
- # define PREFETCH_L1(ptr) (void)(ptr) /* disabled */
136
- # define PREFETCH_L2(ptr) (void)(ptr) /* disabled */
149
+ # define PREFETCH_L1(ptr) do { (void)(ptr); } while (0) /* disabled */
150
+ # define PREFETCH_L2(ptr) do { (void)(ptr); } while (0) /* disabled */
137
151
  # endif
138
152
  #endif /* NO_PREFETCH */
139
153
 
140
154
  #define CACHELINE_SIZE 64
141
155
 
142
- #define PREFETCH_AREA(p, s) { \
143
- const char* const _ptr = (const char*)(p); \
144
- size_t const _size = (size_t)(s); \
145
- size_t _pos; \
146
- for (_pos=0; _pos<_size; _pos+=CACHELINE_SIZE) { \
147
- PREFETCH_L2(_ptr + _pos); \
148
- } \
149
- }
156
+ #define PREFETCH_AREA(p, s) \
157
+ do { \
158
+ const char* const _ptr = (const char*)(p); \
159
+ size_t const _size = (size_t)(s); \
160
+ size_t _pos; \
161
+ for (_pos=0; _pos<_size; _pos+=CACHELINE_SIZE) { \
162
+ PREFETCH_L2(_ptr + _pos); \
163
+ } \
164
+ } while (0)
150
165
 
151
166
  /* vectorization
152
- * older GCC (pre gcc-4.3 picked as the cutoff) uses a different syntax */
153
- #if !defined(__INTEL_COMPILER) && !defined(__clang__) && defined(__GNUC__)
167
+ * older GCC (pre gcc-4.3 picked as the cutoff) uses a different syntax,
168
+ * and some compilers, like Intel ICC and MCST LCC, do not support it at all. */
169
+ #if !defined(__INTEL_COMPILER) && !defined(__clang__) && defined(__GNUC__) && !defined(__LCC__)
154
170
  # if (__GNUC__ == 4 && __GNUC_MINOR__ > 3) || (__GNUC__ >= 5)
155
171
  # define DONT_VECTORIZE __attribute__((optimize("no-tree-vectorize")))
156
172
  # else
@@ -173,6 +189,12 @@
173
189
  #define UNLIKELY(x) (x)
174
190
  #endif
175
191
 
192
+ #if __has_builtin(__builtin_unreachable) || (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)))
193
+ # define ZSTD_UNREACHABLE do { assert(0), __builtin_unreachable(); } while (0)
194
+ #else
195
+ # define ZSTD_UNREACHABLE do { assert(0); } while (0)
196
+ #endif
197
+
176
198
  /* disable warnings */
177
199
  #ifdef _MSC_VER /* Visual Studio */
178
200
  # include <intrin.h> /* For Visual 2005 */
@@ -189,6 +211,8 @@
189
211
  # ifdef __AVX2__ //MSVC does not have a BMI2 specific flag, but every CPU that supports AVX2 also supports BMI2
190
212
  # define STATIC_BMI2 1
191
213
  # endif
214
+ # elif defined(__BMI2__) && defined(__x86_64__) && defined(__GNUC__)
215
+ # define STATIC_BMI2 1
192
216
  # endif
193
217
  #endif
194
218
 
@@ -196,26 +220,171 @@
196
220
  #define STATIC_BMI2 0
197
221
  #endif
198
222
 
199
- /* compat. with non-clang compilers */
200
- #ifndef __has_builtin
201
- # define __has_builtin(x) 0
223
+ /* compile time determination of SIMD support */
224
+ #if !defined(ZSTD_NO_INTRINSICS)
225
+ # if defined(__SSE2__) || defined(_M_AMD64) || (defined (_M_IX86) && defined(_M_IX86_FP) && (_M_IX86_FP >= 2))
226
+ # define ZSTD_ARCH_X86_SSE2
227
+ # endif
228
+ # if defined(__ARM_NEON) || defined(_M_ARM64)
229
+ # define ZSTD_ARCH_ARM_NEON
230
+ # endif
231
+ #
232
+ # if defined(ZSTD_ARCH_X86_SSE2)
233
+ # include <emmintrin.h>
234
+ # elif defined(ZSTD_ARCH_ARM_NEON)
235
+ # include <arm_neon.h>
236
+ # endif
237
+ #endif
238
+
239
+ /* C-language Attributes are added in C23. */
240
+ #if defined(__STDC_VERSION__) && (__STDC_VERSION__ > 201710L) && defined(__has_c_attribute)
241
+ # define ZSTD_HAS_C_ATTRIBUTE(x) __has_c_attribute(x)
242
+ #else
243
+ # define ZSTD_HAS_C_ATTRIBUTE(x) 0
202
244
  #endif
203
245
 
204
- /* compat. with non-clang compilers */
205
- #ifndef __has_feature
206
- # define __has_feature(x) 0
246
+ /* Only use C++ attributes in C++. Some compilers report support for C++
247
+ * attributes when compiling with C.
248
+ */
249
+ #if defined(__cplusplus) && defined(__has_cpp_attribute)
250
+ # define ZSTD_HAS_CPP_ATTRIBUTE(x) __has_cpp_attribute(x)
251
+ #else
252
+ # define ZSTD_HAS_CPP_ATTRIBUTE(x) 0
207
253
  #endif
208
254
 
209
- /* detects whether we are being compiled under msan */
210
- #ifndef ZSTD_MEMORY_SANITIZER
211
- # if __has_feature(memory_sanitizer)
212
- # define ZSTD_MEMORY_SANITIZER 1
255
+ /* Define ZSTD_FALLTHROUGH macro for annotating switch case with the 'fallthrough' attribute.
256
+ * - C23: https://en.cppreference.com/w/c/language/attributes/fallthrough
257
+ * - CPP17: https://en.cppreference.com/w/cpp/language/attributes/fallthrough
258
+ * - Else: __attribute__((__fallthrough__))
259
+ */
260
+ #ifndef ZSTD_FALLTHROUGH
261
+ # if ZSTD_HAS_C_ATTRIBUTE(fallthrough)
262
+ # define ZSTD_FALLTHROUGH [[fallthrough]]
263
+ # elif ZSTD_HAS_CPP_ATTRIBUTE(fallthrough)
264
+ # define ZSTD_FALLTHROUGH [[fallthrough]]
265
+ # elif __has_attribute(__fallthrough__)
266
+ /* Leading semicolon is to satisfy gcc-11 with -pedantic. Without the semicolon
267
+ * gcc complains about: a label can only be part of a statement and a declaration is not a statement.
268
+ */
269
+ # define ZSTD_FALLTHROUGH ; __attribute__((__fallthrough__))
270
+ # else
271
+ # define ZSTD_FALLTHROUGH
272
+ # endif
273
+ #endif
274
+
275
+ /*-**************************************************************
276
+ * Alignment check
277
+ *****************************************************************/
278
+
279
+ /* this test was initially positioned in mem.h,
280
+ * but this file is removed (or replaced) for linux kernel
281
+ * so it's now hosted in compiler.h,
282
+ * which remains valid for both user & kernel spaces.
283
+ */
284
+
285
+ #ifndef ZSTD_ALIGNOF
286
+ # if defined(__GNUC__) || defined(_MSC_VER)
287
+ /* covers gcc, clang & MSVC */
288
+ /* note : this section must come first, before C11,
289
+ * due to a limitation in the kernel source generator */
290
+ # define ZSTD_ALIGNOF(T) __alignof(T)
291
+
292
+ # elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L)
293
+ /* C11 support */
294
+ # include <stdalign.h>
295
+ # define ZSTD_ALIGNOF(T) alignof(T)
296
+
297
+ # else
298
+ /* No known support for alignof() - imperfect backup */
299
+ # define ZSTD_ALIGNOF(T) (sizeof(void*) < sizeof(T) ? sizeof(void*) : sizeof(T))
300
+
301
+ # endif
302
+ #endif /* ZSTD_ALIGNOF */
303
+
304
+ /*-**************************************************************
305
+ * Sanitizer
306
+ *****************************************************************/
307
+
308
+ /**
309
+ * Zstd relies on pointer overflow in its decompressor.
310
+ * We add this attribute to functions that rely on pointer overflow.
311
+ */
312
+ #ifndef ZSTD_ALLOW_POINTER_OVERFLOW_ATTR
313
+ # if __has_attribute(no_sanitize)
314
+ # if !defined(__clang__) && defined(__GNUC__) && __GNUC__ < 8
315
+ /* gcc < 8 only has signed-integer-overlow which triggers on pointer overflow */
316
+ # define ZSTD_ALLOW_POINTER_OVERFLOW_ATTR __attribute__((no_sanitize("signed-integer-overflow")))
317
+ # else
318
+ /* older versions of clang [3.7, 5.0) will warn that pointer-overflow is ignored. */
319
+ # define ZSTD_ALLOW_POINTER_OVERFLOW_ATTR __attribute__((no_sanitize("pointer-overflow")))
320
+ # endif
213
321
  # else
214
- # define ZSTD_MEMORY_SANITIZER 0
322
+ # define ZSTD_ALLOW_POINTER_OVERFLOW_ATTR
215
323
  # endif
216
324
  #endif
217
325
 
218
- #if ZSTD_MEMORY_SANITIZER
326
+ /**
327
+ * Helper function to perform a wrapped pointer difference without trigging
328
+ * UBSAN.
329
+ *
330
+ * @returns lhs - rhs with wrapping
331
+ */
332
+ MEM_STATIC
333
+ ZSTD_ALLOW_POINTER_OVERFLOW_ATTR
334
+ ptrdiff_t ZSTD_wrappedPtrDiff(unsigned char const* lhs, unsigned char const* rhs)
335
+ {
336
+ return lhs - rhs;
337
+ }
338
+
339
+ /**
340
+ * Helper function to perform a wrapped pointer add without triggering UBSAN.
341
+ *
342
+ * @return ptr + add with wrapping
343
+ */
344
+ MEM_STATIC
345
+ ZSTD_ALLOW_POINTER_OVERFLOW_ATTR
346
+ unsigned char const* ZSTD_wrappedPtrAdd(unsigned char const* ptr, ptrdiff_t add)
347
+ {
348
+ return ptr + add;
349
+ }
350
+
351
+ /**
352
+ * Helper function to perform a wrapped pointer subtraction without triggering
353
+ * UBSAN.
354
+ *
355
+ * @return ptr - sub with wrapping
356
+ */
357
+ MEM_STATIC
358
+ ZSTD_ALLOW_POINTER_OVERFLOW_ATTR
359
+ unsigned char const* ZSTD_wrappedPtrSub(unsigned char const* ptr, ptrdiff_t sub)
360
+ {
361
+ return ptr - sub;
362
+ }
363
+
364
+ /**
365
+ * Helper function to add to a pointer that works around C's undefined behavior
366
+ * of adding 0 to NULL.
367
+ *
368
+ * @returns `ptr + add` except it defines `NULL + 0 == NULL`.
369
+ */
370
+ MEM_STATIC
371
+ unsigned char* ZSTD_maybeNullPtrAdd(unsigned char* ptr, ptrdiff_t add)
372
+ {
373
+ return add > 0 ? ptr + add : ptr;
374
+ }
375
+
376
+ /* Issue #3240 reports an ASAN failure on an llvm-mingw build. Out of an
377
+ * abundance of caution, disable our custom poisoning on mingw. */
378
+ #ifdef __MINGW32__
379
+ #ifndef ZSTD_ASAN_DONT_POISON_WORKSPACE
380
+ #define ZSTD_ASAN_DONT_POISON_WORKSPACE 1
381
+ #endif
382
+ #ifndef ZSTD_MSAN_DONT_POISON_WORKSPACE
383
+ #define ZSTD_MSAN_DONT_POISON_WORKSPACE 1
384
+ #endif
385
+ #endif
386
+
387
+ #if ZSTD_MEMORY_SANITIZER && !defined(ZSTD_MSAN_DONT_POISON_WORKSPACE)
219
388
  /* Not all platforms that support msan provide sanitizers/msan_interface.h.
220
389
  * We therefore declare the functions we need ourselves, rather than trying to
221
390
  * include the header file... */
@@ -234,20 +403,13 @@ void __msan_poison(const volatile void *a, size_t size);
234
403
  /* Returns the offset of the first (at least partially) poisoned byte in the
235
404
  memory range, or -1 if the whole range is good. */
236
405
  intptr_t __msan_test_shadow(const volatile void *x, size_t size);
237
- #endif
238
406
 
239
- /* detects whether we are being compiled under asan */
240
- #ifndef ZSTD_ADDRESS_SANITIZER
241
- # if __has_feature(address_sanitizer)
242
- # define ZSTD_ADDRESS_SANITIZER 1
243
- # elif defined(__SANITIZE_ADDRESS__)
244
- # define ZSTD_ADDRESS_SANITIZER 1
245
- # else
246
- # define ZSTD_ADDRESS_SANITIZER 0
247
- # endif
407
+ /* Print shadow and origin for the memory range to stderr in a human-readable
408
+ format. */
409
+ void __msan_print_shadow(const volatile void *x, size_t size);
248
410
  #endif
249
411
 
250
- #if ZSTD_ADDRESS_SANITIZER
412
+ #if ZSTD_ADDRESS_SANITIZER && !defined(ZSTD_ASAN_DONT_POISON_WORKSPACE)
251
413
  /* Not all platforms that support asan provide sanitizers/asan_interface.h.
252
414
  * We therefore declare the functions we need ourselves, rather than trying to
253
415
  * include the header file... */
@@ -1,5 +1,5 @@
1
1
  /*
2
- * Copyright (c) 2018-2020, Facebook, Inc.
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
3
  * All rights reserved.
4
4
  *
5
5
  * This source code is licensed under both the BSD-style license (found in the
@@ -35,6 +35,7 @@ MEM_STATIC ZSTD_cpuid_t ZSTD_cpuid(void) {
35
35
  U32 f7b = 0;
36
36
  U32 f7c = 0;
37
37
  #if defined(_MSC_VER) && (defined(_M_X64) || defined(_M_IX86))
38
+ #if !defined(__clang__)
38
39
  int reg[4];
39
40
  __cpuid((int*)reg, 0);
40
41
  {
@@ -50,6 +51,41 @@ MEM_STATIC ZSTD_cpuid_t ZSTD_cpuid(void) {
50
51
  f7c = (U32)reg[2];
51
52
  }
52
53
  }
54
+ #else
55
+ /* Clang compiler has a bug (fixed in https://reviews.llvm.org/D101338) in
56
+ * which the `__cpuid` intrinsic does not save and restore `rbx` as it needs
57
+ * to due to being a reserved register. So in that case, do the `cpuid`
58
+ * ourselves. Clang supports inline assembly anyway.
59
+ */
60
+ U32 n;
61
+ __asm__(
62
+ "pushq %%rbx\n\t"
63
+ "cpuid\n\t"
64
+ "popq %%rbx\n\t"
65
+ : "=a"(n)
66
+ : "a"(0)
67
+ : "rcx", "rdx");
68
+ if (n >= 1) {
69
+ U32 f1a;
70
+ __asm__(
71
+ "pushq %%rbx\n\t"
72
+ "cpuid\n\t"
73
+ "popq %%rbx\n\t"
74
+ : "=a"(f1a), "=c"(f1c), "=d"(f1d)
75
+ : "a"(1)
76
+ :);
77
+ }
78
+ if (n >= 7) {
79
+ __asm__(
80
+ "pushq %%rbx\n\t"
81
+ "cpuid\n\t"
82
+ "movq %%rbx, %%rax\n\t"
83
+ "popq %%rbx"
84
+ : "=a"(f7b), "=c"(f7c)
85
+ : "a"(7), "c"(0)
86
+ : "rdx");
87
+ }
88
+ #endif
53
89
  #elif defined(__i386__) && defined(__PIC__) && !defined(__clang__) && defined(__GNUC__)
54
90
  /* The following block like the normal cpuid branch below, but gcc
55
91
  * reserves ebx for use of its pic register so we must specially
@@ -1,7 +1,7 @@
1
1
  /* ******************************************************************
2
2
  * debug
3
3
  * Part of FSE library
4
- * Copyright (c) 2013-2020, Yann Collet, Facebook, Inc.
4
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
5
5
  *
6
6
  * You can contact the author at :
7
7
  * - Source repository : https://github.com/Cyan4973/FiniteStateEntropy
@@ -21,4 +21,10 @@
21
21
 
22
22
  #include "debug.h"
23
23
 
24
+ #if !defined(ZSTD_LINUX_KERNEL) || (DEBUGLEVEL>=2)
25
+ /* We only use this when DEBUGLEVEL>=2, but we get -Werror=pedantic errors if a
26
+ * translation unit is empty. So remove this from Linux kernel builds, but
27
+ * otherwise just leave it in.
28
+ */
24
29
  int g_debuglevel = DEBUGLEVEL;
30
+ #endif
@@ -1,7 +1,7 @@
1
1
  /* ******************************************************************
2
2
  * debug
3
3
  * Part of FSE library
4
- * Copyright (c) 2013-2020, Yann Collet, Facebook, Inc.
4
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
5
5
  *
6
6
  * You can contact the author at :
7
7
  * - Source repository : https://github.com/Cyan4973/FiniteStateEntropy
@@ -85,18 +85,27 @@ extern int g_debuglevel; /* the variable is only declared,
85
85
  It's useful when enabling very verbose levels
86
86
  on selective conditions (such as position in src) */
87
87
 
88
- # define RAWLOG(l, ...) { \
89
- if (l<=g_debuglevel) { \
90
- ZSTD_DEBUG_PRINT(__VA_ARGS__); \
91
- } }
92
- # define DEBUGLOG(l, ...) { \
93
- if (l<=g_debuglevel) { \
94
- ZSTD_DEBUG_PRINT(__FILE__ ": " __VA_ARGS__); \
95
- ZSTD_DEBUG_PRINT(" \n"); \
96
- } }
88
+ # define RAWLOG(l, ...) \
89
+ do { \
90
+ if (l<=g_debuglevel) { \
91
+ ZSTD_DEBUG_PRINT(__VA_ARGS__); \
92
+ } \
93
+ } while (0)
94
+
95
+ #define STRINGIFY(x) #x
96
+ #define TOSTRING(x) STRINGIFY(x)
97
+ #define LINE_AS_STRING TOSTRING(__LINE__)
98
+
99
+ # define DEBUGLOG(l, ...) \
100
+ do { \
101
+ if (l<=g_debuglevel) { \
102
+ ZSTD_DEBUG_PRINT(__FILE__ ":" LINE_AS_STRING ": " __VA_ARGS__); \
103
+ ZSTD_DEBUG_PRINT(" \n"); \
104
+ } \
105
+ } while (0)
97
106
  #else
98
- # define RAWLOG(l, ...) {} /* disabled */
99
- # define DEBUGLOG(l, ...) {} /* disabled */
107
+ # define RAWLOG(l, ...) do { } while (0) /* disabled */
108
+ # define DEBUGLOG(l, ...) do { } while (0) /* disabled */
100
109
  #endif
101
110
 
102
111
 
@@ -1,6 +1,6 @@
1
1
  /* ******************************************************************
2
2
  * Common functions of New Generation Entropy library
3
- * Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
3
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
4
4
  *
5
5
  * You can contact the author at :
6
6
  * - FSE+HUF source repository : https://github.com/Cyan4973/FiniteStateEntropy
@@ -19,8 +19,8 @@
19
19
  #include "error_private.h" /* ERR_*, ERROR */
20
20
  #define FSE_STATIC_LINKING_ONLY /* FSE_MIN_TABLELOG */
21
21
  #include "fse.h"
22
- #define HUF_STATIC_LINKING_ONLY /* HUF_TABLELOG_ABSOLUTEMAX */
23
22
  #include "huf.h"
23
+ #include "bits.h" /* ZSDT_highbit32, ZSTD_countTrailingZeros32 */
24
24
 
25
25
 
26
26
  /*=== Version ===*/
@@ -38,28 +38,6 @@ const char* HUF_getErrorName(size_t code) { return ERR_getErrorName(code); }
38
38
  /*-**************************************************************
39
39
  * FSE NCount encoding-decoding
40
40
  ****************************************************************/
41
- static U32 FSE_ctz(U32 val)
42
- {
43
- assert(val != 0);
44
- {
45
- # if defined(_MSC_VER) /* Visual */
46
- unsigned long r=0;
47
- return _BitScanForward(&r, val) ? (unsigned)r : 0;
48
- # elif defined(__GNUC__) && (__GNUC__ >= 3) /* GCC Intrinsic */
49
- return __builtin_ctz(val);
50
- # elif defined(__ICCARM__) /* IAR Intrinsic */
51
- return __CTZ(val);
52
- # else /* Software version */
53
- U32 count = 0;
54
- while ((val & 1) == 0) {
55
- val >>= 1;
56
- ++count;
57
- }
58
- return count;
59
- # endif
60
- }
61
- }
62
-
63
41
  FORCE_INLINE_TEMPLATE
64
42
  size_t FSE_readNCount_body(short* normalizedCounter, unsigned* maxSVPtr, unsigned* tableLogPtr,
65
43
  const void* headerBuffer, size_t hbSize)
@@ -107,7 +85,7 @@ size_t FSE_readNCount_body(short* normalizedCounter, unsigned* maxSVPtr, unsigne
107
85
  * repeat.
108
86
  * Avoid UB by setting the high bit to 1.
109
87
  */
110
- int repeats = FSE_ctz(~bitStream | 0x80000000) >> 1;
88
+ int repeats = ZSTD_countTrailingZeros32(~bitStream | 0x80000000) >> 1;
111
89
  while (repeats >= 12) {
112
90
  charnum += 3 * 12;
113
91
  if (LIKELY(ip <= iend-7)) {
@@ -118,7 +96,7 @@ size_t FSE_readNCount_body(short* normalizedCounter, unsigned* maxSVPtr, unsigne
118
96
  ip = iend - 4;
119
97
  }
120
98
  bitStream = MEM_readLE32(ip) >> bitCount;
121
- repeats = FSE_ctz(~bitStream | 0x80000000) >> 1;
99
+ repeats = ZSTD_countTrailingZeros32(~bitStream | 0x80000000) >> 1;
122
100
  }
123
101
  charnum += 3 * repeats;
124
102
  bitStream >>= 2 * repeats;
@@ -183,7 +161,7 @@ size_t FSE_readNCount_body(short* normalizedCounter, unsigned* maxSVPtr, unsigne
183
161
  * know that threshold > 1.
184
162
  */
185
163
  if (remaining <= 1) break;
186
- nbBits = BIT_highbit32(remaining) + 1;
164
+ nbBits = ZSTD_highbit32(remaining) + 1;
187
165
  threshold = 1 << (nbBits - 1);
188
166
  }
189
167
  if (charnum >= maxSV1) break;
@@ -217,7 +195,7 @@ static size_t FSE_readNCount_body_default(
217
195
  }
218
196
 
219
197
  #if DYNAMIC_BMI2
220
- TARGET_ATTRIBUTE("bmi2") static size_t FSE_readNCount_body_bmi2(
198
+ BMI2_TARGET_ATTRIBUTE static size_t FSE_readNCount_body_bmi2(
221
199
  short* normalizedCounter, unsigned* maxSVPtr, unsigned* tableLogPtr,
222
200
  const void* headerBuffer, size_t hbSize)
223
201
  {
@@ -258,7 +236,7 @@ size_t HUF_readStats(BYTE* huffWeight, size_t hwSize, U32* rankStats,
258
236
  const void* src, size_t srcSize)
259
237
  {
260
238
  U32 wksp[HUF_READ_STATS_WORKSPACE_SIZE_U32];
261
- return HUF_readStats_wksp(huffWeight, hwSize, rankStats, nbSymbolsPtr, tableLogPtr, src, srcSize, wksp, sizeof(wksp), /* bmi2 */ 0);
239
+ return HUF_readStats_wksp(huffWeight, hwSize, rankStats, nbSymbolsPtr, tableLogPtr, src, srcSize, wksp, sizeof(wksp), /* flags */ 0);
262
240
  }
263
241
 
264
242
  FORCE_INLINE_TEMPLATE size_t
@@ -299,21 +277,21 @@ HUF_readStats_body(BYTE* huffWeight, size_t hwSize, U32* rankStats,
299
277
  ZSTD_memset(rankStats, 0, (HUF_TABLELOG_MAX + 1) * sizeof(U32));
300
278
  weightTotal = 0;
301
279
  { U32 n; for (n=0; n<oSize; n++) {
302
- if (huffWeight[n] >= HUF_TABLELOG_MAX) return ERROR(corruption_detected);
280
+ if (huffWeight[n] > HUF_TABLELOG_MAX) return ERROR(corruption_detected);
303
281
  rankStats[huffWeight[n]]++;
304
282
  weightTotal += (1 << huffWeight[n]) >> 1;
305
283
  } }
306
284
  if (weightTotal == 0) return ERROR(corruption_detected);
307
285
 
308
286
  /* get last non-null symbol weight (implied, total must be 2^n) */
309
- { U32 const tableLog = BIT_highbit32(weightTotal) + 1;
287
+ { U32 const tableLog = ZSTD_highbit32(weightTotal) + 1;
310
288
  if (tableLog > HUF_TABLELOG_MAX) return ERROR(corruption_detected);
311
289
  *tableLogPtr = tableLog;
312
290
  /* determine last weight */
313
291
  { U32 const total = 1 << tableLog;
314
292
  U32 const rest = total - weightTotal;
315
- U32 const verif = 1 << BIT_highbit32(rest);
316
- U32 const lastWeight = BIT_highbit32(rest) + 1;
293
+ U32 const verif = 1 << ZSTD_highbit32(rest);
294
+ U32 const lastWeight = ZSTD_highbit32(rest) + 1;
317
295
  if (verif != rest) return ERROR(corruption_detected); /* last value must be a clean power of 2 */
318
296
  huffWeight[oSize] = (BYTE)lastWeight;
319
297
  rankStats[lastWeight]++;
@@ -337,7 +315,7 @@ static size_t HUF_readStats_body_default(BYTE* huffWeight, size_t hwSize, U32* r
337
315
  }
338
316
 
339
317
  #if DYNAMIC_BMI2
340
- static TARGET_ATTRIBUTE("bmi2") size_t HUF_readStats_body_bmi2(BYTE* huffWeight, size_t hwSize, U32* rankStats,
318
+ static BMI2_TARGET_ATTRIBUTE size_t HUF_readStats_body_bmi2(BYTE* huffWeight, size_t hwSize, U32* rankStats,
341
319
  U32* nbSymbolsPtr, U32* tableLogPtr,
342
320
  const void* src, size_t srcSize,
343
321
  void* workSpace, size_t wkspSize)
@@ -350,13 +328,13 @@ size_t HUF_readStats_wksp(BYTE* huffWeight, size_t hwSize, U32* rankStats,
350
328
  U32* nbSymbolsPtr, U32* tableLogPtr,
351
329
  const void* src, size_t srcSize,
352
330
  void* workSpace, size_t wkspSize,
353
- int bmi2)
331
+ int flags)
354
332
  {
355
333
  #if DYNAMIC_BMI2
356
- if (bmi2) {
334
+ if (flags & HUF_flags_bmi2) {
357
335
  return HUF_readStats_body_bmi2(huffWeight, hwSize, rankStats, nbSymbolsPtr, tableLogPtr, src, srcSize, workSpace, wkspSize);
358
336
  }
359
337
  #endif
360
- (void)bmi2;
338
+ (void)flags;
361
339
  return HUF_readStats_body_default(huffWeight, hwSize, rankStats, nbSymbolsPtr, tableLogPtr, src, srcSize, workSpace, wkspSize);
362
340
  }