Coverage Report

Created: 2026-01-10 06:45

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/zlib-ng/zbuild.h
Line
Count
Source
1
#ifndef _ZBUILD_H
2
#define _ZBUILD_H
3
4
#define _POSIX_SOURCE 1  /* fileno */
5
#ifndef _POSIX_C_SOURCE
6
#  define _POSIX_C_SOURCE 200809L /* snprintf, posix_memalign, strdup */
7
#endif
8
#ifndef _ISOC11_SOURCE
9
#  define _ISOC11_SOURCE 1 /* aligned_alloc */
10
#endif
11
#ifdef __OpenBSD__
12
#  define _BSD_SOURCE 1
13
#endif
14
15
#include <stddef.h>
16
#include <string.h>
17
#include <stdlib.h>
18
#include <stdint.h>
19
#include <stdio.h>
20
21
/* Determine compiler version of C Standard */
22
#ifdef __STDC_VERSION__
23
#  if __STDC_VERSION__ >= 199901L
24
#    ifndef STDC99
25
#      define STDC99
26
#    endif
27
#  endif
28
#  if __STDC_VERSION__ >= 201112L
29
#    ifndef STDC11
30
#      define STDC11
31
#    endif
32
#  endif
33
#endif
34
35
#ifndef Z_HAS_ATTRIBUTE
36
#  if defined(__has_attribute)
37
#    define Z_HAS_ATTRIBUTE(a) __has_attribute(a)
38
#  else
39
#    define Z_HAS_ATTRIBUTE(a) 0
40
#  endif
41
#endif
42
43
#ifndef Z_FALLTHROUGH
44
#  if Z_HAS_ATTRIBUTE(__fallthrough__) || (defined(__GNUC__) && (__GNUC__ >= 7))
45
33.1k
#    define Z_FALLTHROUGH __attribute__((__fallthrough__))
46
#  else
47
#    define Z_FALLTHROUGH do {} while(0) /* fallthrough */
48
#  endif
49
#endif
50
51
#ifndef Z_TARGET
52
#  if Z_HAS_ATTRIBUTE(__target__)
53
#    define Z_TARGET(x) __attribute__((__target__(x)))
54
#  else
55
#    define Z_TARGET(x)
56
#  endif
57
#endif
58
59
/* This has to be first include that defines any types */
60
#if defined(_MSC_VER)
61
#  if defined(_WIN64)
62
    typedef __int64 ssize_t;
63
#  else
64
    typedef long ssize_t;
65
#  endif
66
67
#  if defined(_WIN64)
68
    #define SSIZE_MAX _I64_MAX
69
#  else
70
    #define SSIZE_MAX LONG_MAX
71
#  endif
72
#endif
73
74
/* A forced inline decorator */
75
#if defined(_MSC_VER)
76
#  define Z_FORCEINLINE __forceinline
77
#elif defined(__GNUC__)
78
#  define Z_FORCEINLINE inline __attribute__((always_inline))
79
#else
80
    /* It won't actually force inlining but it will suggest it */
81
#  define Z_FORCEINLINE inline
82
#endif
83
84
/* MS Visual Studio does not allow inline in C, only C++.
85
   But it provides __inline instead, so use that. */
86
#if defined(_MSC_VER) && !defined(inline) && !defined(__cplusplus)
87
#  define inline __inline
88
#endif
89
90
#if defined(ZLIB_COMPAT)
91
#  define PREFIX(x) x
92
#  define PREFIX2(x) ZLIB_ ## x
93
#  define PREFIX3(x) z_ ## x
94
#  define PREFIX4(x) x ## 64
95
#  define zVersion zlibVersion
96
#else
97
2.94k
#  define PREFIX(x) zng_ ## x
98
0
#  define PREFIX2(x) ZLIBNG_ ## x
99
29.9k
#  define PREFIX3(x) zng_ ## x
100
#  define PREFIX4(x) zng_ ## x
101
#  define zVersion zlibng_version
102
#  define z_size_t size_t
103
#endif
104
105
/* In zlib-compat some functions and types use unsigned long, but zlib-ng use size_t */
106
#if defined(ZLIB_COMPAT)
107
#  define z_uintmax_t unsigned long
108
#else
109
#  define z_uintmax_t size_t
110
#endif
111
112
/* In zlib-compat headers some function return values and parameter types use int or unsigned, but zlib-ng headers use
113
   int32_t and uint32_t, which will cause type mismatch when compiling zlib-ng if int32_t is long and uint32_t is
114
   unsigned long */
115
#if defined(ZLIB_COMPAT)
116
#  define z_int32_t int
117
#  define z_uint32_t unsigned int
118
#else
119
#  define z_int32_t int32_t
120
#  define z_uint32_t uint32_t
121
#endif
122
123
/* Minimum of a and b. */
124
237k
#define MIN(a, b) ((a) > (b) ? (b) : (a))
125
/* Maximum of a and b. */
126
11.4k
#define MAX(a, b) ((a) < (b) ? (b) : (a))
127
/* Ignore unused variable warning */
128
1.79M
#define Z_UNUSED(var) (void)(var)
129
130
/* Force the compiler to treat variable as modified. Empty asm statement with a "+r" constraint prevents
131
   the compiler from reordering or eliminating loads into the variable. This can help keep critical latency
132
   chains in the hot path from being shortened or optimized away. */
133
#if (defined(__GNUC__) || defined(__clang__)) && (defined(__x86_64__) || defined(__i386__) || defined(__aarch64__))
134
3.36M
#  define Z_TOUCH(var) __asm__ ("" : "+r"(var))
135
#else
136
#  define Z_TOUCH(var) (void)(var)
137
#endif
138
139
#if defined(HAVE_VISIBILITY_INTERNAL)
140
#  define Z_INTERNAL __attribute__((visibility ("internal")))
141
#elif defined(HAVE_VISIBILITY_HIDDEN)
142
#  define Z_INTERNAL __attribute__((visibility ("hidden")))
143
#else
144
#  define Z_INTERNAL
145
#endif
146
147
/* Symbol versioning helpers, allowing multiple versions of a function to exist.
148
 * Functions using this must also be added to zlib-ng.map for each version.
149
 * Double @@ means this is the default for newly compiled applications to link against.
150
 * Single @ means this is kept for backwards compatibility.
151
 * This is only used for Zlib-ng native API, and only on platforms supporting this.
152
 */
153
#if defined(HAVE_SYMVER)
154
#  define ZSYMVER(func,alias,ver) __asm__(".symver " func ", " alias "@ZLIB_NG_" ver);
155
#  define ZSYMVER_DEF(func,alias,ver) __asm__(".symver " func ", " alias "@@ZLIB_NG_" ver);
156
#else
157
#  define ZSYMVER(func,alias,ver)
158
#  define ZSYMVER_DEF(func,alias,ver)
159
#endif
160
161
#ifndef __cplusplus
162
#  define Z_REGISTER register
163
#else
164
#  define Z_REGISTER
165
#endif
166
167
/* Reverse the bytes in a value. Use compiler intrinsics when
168
   possible to take advantage of hardware implementations. */
169
#if defined(_MSC_VER) && (_MSC_VER >= 1300)
170
#  include <stdlib.h>
171
#  pragma intrinsic(_byteswap_ulong)
172
#  define ZSWAP16(q) _byteswap_ushort(q)
173
#  define ZSWAP32(q) _byteswap_ulong(q)
174
#  define ZSWAP64(q) _byteswap_uint64(q)
175
176
#elif defined(__clang__) || (defined(__GNUC__) && \
177
        (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)))
178
1.47k
#  define ZSWAP16(q) __builtin_bswap16(q)
179
2.94k
#  define ZSWAP32(q) __builtin_bswap32(q)
180
#  define ZSWAP64(q) __builtin_bswap64(q)
181
182
#elif defined(__GNUC__) && (__GNUC__ >= 2) && defined(__linux__)
183
#  include <byteswap.h>
184
#  define ZSWAP16(q) bswap_16(q)
185
#  define ZSWAP32(q) bswap_32(q)
186
#  define ZSWAP64(q) bswap_64(q)
187
188
#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__DragonFly__)
189
#  include <sys/endian.h>
190
#  define ZSWAP16(q) bswap16(q)
191
#  define ZSWAP32(q) bswap32(q)
192
#  define ZSWAP64(q) bswap64(q)
193
#elif defined(__OpenBSD__)
194
#  include <sys/endian.h>
195
#  define ZSWAP16(q) swap16(q)
196
#  define ZSWAP32(q) swap32(q)
197
#  define ZSWAP64(q) swap64(q)
198
#elif defined(__INTEL_COMPILER)
199
/* ICC does not provide a two byte swap. */
200
#  define ZSWAP16(q) ((((q) & 0xff) << 8) | (((q) & 0xff00) >> 8))
201
#  define ZSWAP32(q) _bswap(q)
202
#  define ZSWAP64(q) _bswap64(q)
203
204
#else
205
#  define ZSWAP16(q) ((((q) & 0xff) << 8) | (((q) & 0xff00) >> 8))
206
#  define ZSWAP32(q) ((((q) >> 24) & 0xff) + (((q) >> 8) & 0xff00) + \
207
                     (((q) & 0xff00) << 8) + (((q) & 0xff) << 24))
208
#  define ZSWAP64(q)                           \
209
         (((q & 0xFF00000000000000u) >> 56u) | \
210
          ((q & 0x00FF000000000000u) >> 40u) | \
211
          ((q & 0x0000FF0000000000u) >> 24u) | \
212
          ((q & 0x000000FF00000000u) >> 8u)  | \
213
          ((q & 0x00000000FF000000u) << 8u)  | \
214
          ((q & 0x0000000000FF0000u) << 24u) | \
215
          ((q & 0x000000000000FF00u) << 40u) | \
216
          ((q & 0x00000000000000FFu) << 56u))
217
#endif
218
219
/* Only enable likely/unlikely if the compiler is known to support it */
220
#if (defined(__GNUC__) && (__GNUC__ >= 3)) || defined(__INTEL_COMPILER) || defined(__clang__)
221
#  define LIKELY_NULL(x)        __builtin_expect((x) != 0, 0)
222
437M
#  define LIKELY(x)             __builtin_expect(!!(x), 1)
223
3.86M
#  define UNLIKELY(x)           __builtin_expect(!!(x), 0)
224
#else
225
#  define LIKELY_NULL(x)        x
226
#  define LIKELY(x)             x
227
#  define UNLIKELY(x)           x
228
#endif /* (un)likely */
229
230
#if defined(HAVE_ATTRIBUTE_ALIGNED)
231
0
#  define ALIGNED_(x) __attribute__ ((aligned(x)))
232
#elif defined(_MSC_VER)
233
#  define ALIGNED_(x) __declspec(align(x))
234
#else
235
/* TODO: Define ALIGNED_ for your compiler */
236
#  define ALIGNED_(x)
237
#endif
238
239
#ifdef HAVE_BUILTIN_ASSUME_ALIGNED
240
13.2k
#  define HINT_ALIGNED(p,n) __builtin_assume_aligned((void *)(p),(n))
241
#else
242
#  define HINT_ALIGNED(p,n) (p)
243
#endif
244
1.47k
#define HINT_ALIGNED_16(p) HINT_ALIGNED((p),16)
245
11.7k
#define HINT_ALIGNED_64(p) HINT_ALIGNED((p),64)
246
#define HINT_ALIGNED_4096(p) HINT_ALIGNED((p),4096)
247
248
/* Number of bytes needed to align ptr to the next alignment boundary */
249
#define ALIGN_DIFF(ptr, align) \
250
0
    (((uintptr_t)(align) - ((uintptr_t)(ptr) & ((align) - 1))) & ((align) - 1))
251
252
/* PADSZ returns needed bytes to pad bpos to pad size
253
 * PAD_NN calculates pad size and adds it to bpos, returning the result.
254
 * All take an integer or a pointer as bpos input.
255
 */
256
16.1k
#define PADSZ(bpos, pad) (((pad) - ((uintptr_t)(bpos) % (pad))) % (pad))
257
2.94k
#define PAD_16(bpos) ((bpos) + PADSZ((bpos),16))
258
13.2k
#define PAD_64(bpos) ((bpos) + PADSZ((bpos),64))
259
#define PAD_4096(bpos) ((bpos) + PADSZ((bpos),4096))
260
261
/* Diagnostic functions */
262
#ifdef ZLIB_DEBUG
263
   extern int Z_INTERNAL z_verbose;
264
   extern void Z_INTERNAL z_error(const char *m);
265
#  define Assert(cond, msg) {int _cond = (cond); if (!(_cond)) z_error(msg);}
266
#  define Trace(x) {if (z_verbose >= 0) fprintf x;}
267
#  define Tracev(x) {if (z_verbose > 0) fprintf x;}
268
#  define Tracevv(x) {if (z_verbose > 1) fprintf x;}
269
#  define Tracec(c, x) {if (z_verbose > 0 && (c)) fprintf x;}
270
#  define Tracecv(c, x) {if (z_verbose > 1 && (c)) fprintf x;}
271
#else
272
#  define Assert(cond, msg)
273
#  define Trace(x)
274
#  define Tracev(x)
275
#  define Tracevv(x)
276
#  define Tracec(c, x)
277
#  define Tracecv(c, x)
278
#endif
279
280
/* OPTIMAL_CMP values determine the comparison width:
281
 * 64: Best for 64-bit architectures with unaligned access
282
 * 32: Best for 32-bit architectures with unaligned access
283
 * 16: Safe default for unknown architectures
284
 * 8:  Safe fallback for architectures without unaligned access
285
 * Note: The unaligned access mentioned is cpu-support, this allows compiler or
286
 *       separate unaligned intrinsics to utilize safe unaligned access, without
287
 *       utilizing unaligned C pointers that are known to have undefined behavior.
288
 */
289
#if !defined(OPTIMAL_CMP)
290
#  if defined(__x86_64__) || defined(_M_X64) || defined(__amd64__) || defined(_M_AMD64)
291
#    define OPTIMAL_CMP 64
292
#  elif defined(__i386__) || defined(__i486__) || defined(__i586__) || \
293
        defined(__i686__) || defined(_X86_) || defined(_M_IX86)
294
#    define OPTIMAL_CMP 32
295
#  elif defined(__aarch64__) || defined(_M_ARM64) || defined(_M_ARM64EC)
296
#    if defined(__ARM_FEATURE_UNALIGNED) || defined(_WIN32)
297
#      define OPTIMAL_CMP 64
298
#    else
299
#      define OPTIMAL_CMP 8
300
#    endif
301
#  elif defined(__arm__) || defined(_M_ARM)
302
#    if defined(__ARM_FEATURE_UNALIGNED) || defined(_WIN32)
303
#      define OPTIMAL_CMP 32
304
#    else
305
#      define OPTIMAL_CMP 8
306
#    endif
307
#  elif defined(__powerpc64__) || defined(__ppc64__)
308
#    define OPTIMAL_CMP 64
309
#  elif defined(__powerpc__) || defined(__ppc__) || defined(__PPC__)
310
#    define OPTIMAL_CMP 32
311
#  endif
312
#endif
313
#if !defined(OPTIMAL_CMP)
314
#  define OPTIMAL_CMP 16
315
#endif
316
317
#if defined(__has_feature)
318
#  if __has_feature(address_sanitizer)
319
#    define Z_ADDRESS_SANITIZER 1
320
#  endif
321
#elif defined(__SANITIZE_ADDRESS__)
322
#  define Z_ADDRESS_SANITIZER 1
323
#endif
324
325
/*
326
 * __asan_loadN() and __asan_storeN() calls are inserted by compilers in order to check memory accesses.
327
 * They can be called manually too, with the following caveats:
328
 * gcc says: "warning: implicit declaration of function '...'"
329
 * g++ says: "error: new declaration '...' ambiguates built-in declaration '...'"
330
 * Accommodate both.
331
 */
332
#ifdef Z_ADDRESS_SANITIZER
333
#ifndef __cplusplus
334
void __asan_loadN(void *, long);
335
void __asan_storeN(void *, long);
336
#endif
337
#else
338
#  define __asan_loadN(a, size) do { Z_UNUSED(a); Z_UNUSED(size); } while (0)
339
#  define __asan_storeN(a, size) do { Z_UNUSED(a); Z_UNUSED(size); } while (0)
340
#endif
341
342
#if defined(__has_feature)
343
#  if __has_feature(memory_sanitizer)
344
#    define Z_MEMORY_SANITIZER 1
345
#    include <sanitizer/msan_interface.h>
346
#  endif
347
#endif
348
349
#ifndef Z_MEMORY_SANITIZER
350
#  define __msan_check_mem_is_initialized(a, size) do { Z_UNUSED(a); Z_UNUSED(size); } while (0)
351
0
#  define __msan_unpoison(a, size) do { Z_UNUSED(a); Z_UNUSED(size); } while (0)
352
#endif
353
354
/* Notify sanitizer runtime about an upcoming read access. */
355
#define instrument_read(a, size) do {             \
356
    void *__a = (void *)(a);                      \
357
    long __size = size;                           \
358
    __asan_loadN(__a, __size);                    \
359
    __msan_check_mem_is_initialized(__a, __size); \
360
} while (0)
361
362
/* Notify sanitizer runtime about an upcoming write access. */
363
#define instrument_write(a, size) do { \
364
   void *__a = (void *)(a);            \
365
   long __size = size;                 \
366
   __asan_storeN(__a, __size);         \
367
} while (0)
368
369
/* Notify sanitizer runtime about an upcoming read/write access. */
370
#define instrument_read_write(a, size) do {       \
371
    void *__a = (void *)(a);                      \
372
    long __size = size;                           \
373
    __asan_storeN(__a, __size);                   \
374
    __msan_check_mem_is_initialized(__a, __size); \
375
} while (0)
376
377
#endif