Coverage Report

Created: 2026-02-26 06:53

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