extzstd 0.3.2 → 0.4

Sign up to get free protection for your applications and to get access to all the features.
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
  }