wolfssl-sys 4.0.0

System bindings for WolfSSL
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
/* memory.h
 *
 * Copyright (C) 2006-2026 wolfSSL Inc.
 *
 * This file is part of wolfSSL.
 *
 * wolfSSL is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 *
 * wolfSSL is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
 */


/* submitted by eof */

/*!
    \file wolfssl/wolfcrypt/memory.h
*/

#ifndef WOLFSSL_MEMORY_H
#define WOLFSSL_MEMORY_H

#if !defined(STRING_USER) && !defined(NO_STDLIB_H)
#include <stdlib.h>
#endif

#ifndef WOLF_CRYPT_TYPES_H
#include <wolfssl/wolfcrypt/types.h>
#endif

#ifdef __cplusplus
    extern "C" {
#endif

#ifdef WOLFSSL_FORCE_MALLOC_FAIL_TEST
    WOLFSSL_API void wolfSSL_SetMemFailCount(int memFailCount);
#endif

#ifdef OPENSSL_EXTRA
    typedef void *(*wolfSSL_OSSL_Malloc_cb)(size_t, const char *, int);
    typedef void  (*wolfSSL_OSSL_Free_cb)(void *, const char *, int);
    typedef void *(*wolfSSL_OSSL_Realloc_cb)(void *, size_t, const char *, int);
#endif /* OPENSSL_EXTRA */

#ifdef WOLFSSL_STATIC_MEMORY
    #ifdef WOLFSSL_DEBUG_MEMORY
        typedef void *(*wolfSSL_Malloc_cb)(size_t size, void* heap, int type, const char* func, unsigned int line);
        typedef void (*wolfSSL_Free_cb)(void *ptr, void* heap, int type, const char* func, unsigned int line);
        typedef void *(*wolfSSL_Realloc_cb)(void *ptr, size_t size, void* heap, int type, const char* func, unsigned int line);
        WOLFSSL_API void* wolfSSL_Malloc(size_t size, void* heap, int type, const char* func, unsigned int line);
        WOLFSSL_API void  wolfSSL_Free(void *ptr, void* heap, int type, const char* func, unsigned int line);
        WOLFSSL_API void* wolfSSL_Realloc(void *ptr, size_t size, void* heap, int type, const char* func, unsigned int line);
    #else
        typedef void *(*wolfSSL_Malloc_cb)(size_t size, void* heap, int type);
        typedef void (*wolfSSL_Free_cb)(void *ptr, void* heap, int type);
        typedef void *(*wolfSSL_Realloc_cb)(void *ptr, size_t size, void* heap, int type);
        WOLFSSL_API void* wolfSSL_Malloc(size_t size, void* heap, int type);
        WOLFSSL_API void  wolfSSL_Free(void *ptr, void* heap, int type);
        WOLFSSL_API void* wolfSSL_Realloc(void *ptr, size_t size, void* heap, int type);
    #endif /* WOLFSSL_DEBUG_MEMORY */
#else
    #ifdef WOLFSSL_DEBUG_MEMORY
        typedef void *(*wolfSSL_Malloc_cb)(size_t size, const char* func, unsigned int line);
        typedef void (*wolfSSL_Free_cb)(void *ptr, const char* func, unsigned int line);
        typedef void *(*wolfSSL_Realloc_cb)(void *ptr, size_t size, const char* func, unsigned int line);

        /* Public in case user app wants to use XMALLOC/XFREE */
        WOLFSSL_API void* wolfSSL_Malloc(size_t size, const char* func, unsigned int line);
        WOLFSSL_API void  wolfSSL_Free(void *ptr, const char* func, unsigned int line);
        WOLFSSL_API void* wolfSSL_Realloc(void *ptr, size_t size, const char* func, unsigned int line);
    #else
        typedef void *(*wolfSSL_Malloc_cb)(size_t size);
        typedef void (*wolfSSL_Free_cb)(void *ptr);
        typedef void *(*wolfSSL_Realloc_cb)(void *ptr, size_t size);
        /* Public in case user app wants to use XMALLOC/XFREE */
        WOLFSSL_API void* wolfSSL_Malloc(size_t size);
        WOLFSSL_API void  wolfSSL_Free(void *ptr);
        WOLFSSL_API void* wolfSSL_Realloc(void *ptr, size_t size);
    #endif /* WOLFSSL_DEBUG_MEMORY */
#endif /* WOLFSSL_STATIC_MEMORY */

/* Public get/set functions */
WOLFSSL_API int wolfSSL_SetAllocators(wolfSSL_Malloc_cb mf,
                                      wolfSSL_Free_cb ff,
                                      wolfSSL_Realloc_cb rf);
WOLFSSL_API int wolfSSL_GetAllocators(wolfSSL_Malloc_cb* mf,
                                      wolfSSL_Free_cb* ff,
                                      wolfSSL_Realloc_cb* rf);

#ifdef WOLFSSL_STATIC_MEMORY
    #define WOLFSSL_STATIC_TIMEOUT 1
    #ifndef WOLFSSL_STATIC_ALIGN
        #define WOLFSSL_STATIC_ALIGN 16
    #endif
/* WOLFMEM_BUCKETS - list of the sizes of buckets in the pool
 * WOLFMEM_DIST - list of quantities of buffers in the buckets
 * WOLFMEM_DEF_BUCKETS - number of values in WOLFMEM_BUCKETS and WOLFMEM_DIST
 * WOLFMEM_MAX_BUCKETS - size of the arrays used to store the buckets and
 *     dists in the memory pool; defaults to WOLFMEM_DEF_BUCKETS
 *
 * The following defines provide a reasonable set of buckets in the memory
 * pool for running wolfSSL on a Linux box. The bucket and dist lists below
 * have nine items each, so WOLFMEM_DEF_BUCKETS is set to 9.
 *
 * If WOLFMEM_DEF_BUCKETS is less then WOLFMEM_MAX_BUCKETS, the unused values
 * are set to zero and ignored. If WOLFMEM_MAX_BUCKETS is less than
 * WOLFMEM_DEF_BUCKETS, not all the buckets will be created in the pool.
 */
    #ifndef WOLFMEM_DEF_BUCKETS
        #define WOLFMEM_DEF_BUCKETS  9  /* number of default memory blocks */
    #endif

    #ifndef WOLFMEM_MAX_BUCKETS
        #define WOLFMEM_MAX_BUCKETS  WOLFMEM_DEF_BUCKETS
    #endif

    #if WOLFMEM_MAX_BUCKETS < WOLFMEM_DEF_BUCKETS
        #warning "ignoring excess buckets, MAX_BUCKETS less than DEF_BUCKETS"
    #endif

    #ifndef WOLFMEM_IO_SZ
        #define WOLFMEM_IO_SZ        16992 /* 16 byte aligned */
    #endif

    #ifndef LARGEST_MEM_BUCKET
        #ifndef SESSION_CERTS
            #ifdef HAVE_DILITHIUM
                #if defined(WOLFSSL_DILITHIUM_VERIFY_SMALL_MEM) && \
                    defined(WOLFSSL_DILITHIUM_SIGN_SMALL_MEM) && \
                    defined(WOLFSSL_DILITHIUM_MAKE_KEY_SMALL_MEM) && \
                    defined(WOLFSSL_DILITHIUM_VERIFY_ONLY)
                    #define LARGEST_MEM_BUCKET 14000 /* Dilithium low mem */
                #else
                    #define LARGEST_MEM_BUCKET 131072 /* Dilithium full mem */
                #endif
            #else
                #define LARGEST_MEM_BUCKET 16128
            #endif
        #elif defined(OPENSSL_EXTRA)
            #ifdef WOLFSSL_TLS13
                #define LARGEST_MEM_BUCKET 30400
            #else
                #define LARGEST_MEM_BUCKET 25600
            #endif
        #elif defined(WOLFSSL_CERT_EXT)
            /* certificate extensions requires 24k for the SSL struct */
            #define LARGEST_MEM_BUCKET 24576
        #else
            /* increase 23k for object member of WOLFSSL_X509_NAME_ENTRY */
            #define LARGEST_MEM_BUCKET 23440
        #endif
    #endif

    #ifndef WOLFMEM_BUCKETS
        #ifndef SESSION_CERTS
            #ifdef HAVE_DILITHIUM
                #if defined(WOLFSSL_DILITHIUM_VERIFY_SMALL_MEM) && \
                    defined(WOLFSSL_DILITHIUM_SIGN_SMALL_MEM) && \
                    defined(WOLFSSL_DILITHIUM_MAKE_KEY_SMALL_MEM) && \
                    defined(WOLFSSL_DILITHIUM_VERIFY_ONLY)
                    /* default size of chunks of memory to separate into */
                    #define WOLFMEM_BUCKETS 64,128,256,512,1024,2048,4096,\
                                           8192,LARGEST_MEM_BUCKET
                #else
                    /* default size of chunks of memory to separate into */
                    #define WOLFMEM_BUCKETS 64,128,256,512,1024,8192,32768,\
                                            65536,LARGEST_MEM_BUCKET
                #endif
            #elif defined(WOLFSSL_HAVE_MLKEM)
                /* extra storage in structs for multiple attributes and order */
                #define WOLFMEM_BUCKETS 64,128,256,512,1024,2432,4096,8192,\
                                        LARGEST_MEM_BUCKET
            #else
                /* default size of chunks of memory to separate into */
                #define WOLFMEM_BUCKETS 64,128,256,512,1024,2432,3456,4544,\
                                        LARGEST_MEM_BUCKET
            #endif
        #elif defined(OPENSSL_EXTRA)
            #ifdef WOLFSSL_HAVE_MLKEM
                /* extra storage in structs for multiple attributes and order */
                #define WOLFMEM_BUCKETS 64,128,256,512,1024,2432,4096,8192,\
                                        LARGEST_MEM_BUCKET
            #else
                /* extra storage in structs for multiple attributes and order */
                #define WOLFMEM_BUCKETS 64,128,256,512,1024,2432,3360,4480,\
                                        LARGEST_MEM_BUCKET
            #endif
        #elif defined(WOLFSSL_CERT_EXT)
            #define WOLFMEM_BUCKETS 64,128,256,512,1024,2432,3456,4544,\
                                    LARGEST_MEM_BUCKET
        #else
            #define WOLFMEM_BUCKETS 64,128,256,512,1024,2432,3456,4544,\
                                    LARGEST_MEM_BUCKET
        #endif
    #endif

    #ifndef WOLFMEM_DIST
        #ifdef HAVE_DILITHIUM
            #if defined(WOLFSSL_DILITHIUM_VERIFY_SMALL_MEM) && \
                defined(WOLFSSL_DILITHIUM_SIGN_SMALL_MEM) && \
                defined(WOLFSSL_DILITHIUM_MAKE_KEY_SMALL_MEM) && \
                defined(WOLFSSL_DILITHIUM_VERIFY_ONLY)
                #define WOLFMEM_DIST    20,8,6,10,8,6,4,2,1
            #else
                #define WOLFMEM_DIST    30,10,8,15,8,10,8,5,1
            #endif
        #elif defined(WOLFSSL_HAVE_MLKEM)
            #define WOLFMEM_DIST    49,10,6,14,5,6,14,1,1
        #elif !defined(WOLFSSL_STATIC_MEMORY_SMALL)
            #define WOLFMEM_DIST    49,10,6,14,5,6,9,1,1
        #else
            /* Low resource and not RSA */
            #define WOLFMEM_DIST    29, 7,6, 9,4,4,0,0,0
        #endif
    #endif

    /* flags for loading static memory (one hot bit) */
    #define WOLFMEM_GENERAL       0x01
    #define WOLFMEM_IO_POOL       0x02
    #define WOLFMEM_IO_POOL_FIXED 0x04
    #define WOLFMEM_TRACK_STATS   0x08

    #ifndef WOLFSSL_MEM_GUARD
    #define WOLFSSL_MEM_GUARD
        typedef struct WOLFSSL_MEM_STATS      WOLFSSL_MEM_STATS;
        typedef struct WOLFSSL_MEM_CONN_STATS WOLFSSL_MEM_CONN_STATS;
    #endif

    struct WOLFSSL_MEM_CONN_STATS {
        word32 peakMem;   /* peak memory usage    */
        word32 curMem;    /* current memory usage */
        word32 peakAlloc; /* peak memory allocations */
        word32 curAlloc;  /* current memory allocations */
        word32 totalAlloc;/* total memory allocations for lifetime */
        word32 totalFr;   /* total frees for lifetime */
    };

    struct WOLFSSL_MEM_STATS {
        word32 curAlloc;  /* current memory allocations */
        word32 totalAlloc;/* total memory allocations for lifetime */
        word32 totalFr;   /* total frees for lifetime */
        word32 totalUse;  /* total amount of memory used in blocks */
        word32 avaIO;     /* available IO specific pools */
        word32 maxHa;     /* max number of concurrent handshakes allowed */
        word32 maxIO;     /* max number of concurrent IO connections allowed */
        word32 blockSz[WOLFMEM_MAX_BUCKETS]; /* block sizes in stacks */
        word32 avaBlock[WOLFMEM_MAX_BUCKETS];/* ava block sizes */
        word32 usedBlock[WOLFMEM_MAX_BUCKETS];
        int    flag; /* flag used */
    };

    typedef struct wc_Memory wc_Memory; /* internal structure for mem bucket */
    typedef struct WOLFSSL_HEAP {
        wc_Memory* ava[WOLFMEM_MAX_BUCKETS];
    #ifndef WOLFSSL_STATIC_MEMORY_LEAN
        wc_Memory* io;                  /* list of buffers to use for IO */
    #endif

    #ifdef WOLFSSL_STATIC_MEMORY_LEAN
        word32     sizeList[WOLFMEM_MAX_BUCKETS];/* memory sizes in ava list */
        word32     distList[WOLFMEM_MAX_BUCKETS];/* general distribution */
    #else
        word32     maxHa;               /* max concurrent handshakes */
        word32     curHa;
        word32     maxIO;               /* max concurrent IO connections */
        word32     curIO;
        word32     sizeList[WOLFMEM_MAX_BUCKETS];/* memory sizes in ava list */
        word32     distList[WOLFMEM_MAX_BUCKETS];/* general distribution */
        word32     inUse; /* amount of memory currently in use */
        word32     ioUse;
    #endif

    #ifndef WOLFSSL_STATIC_MEMORY_LEAN
        word32     alloc; /* total number of allocs */
        word32     frAlc; /* total number of frees  */
        int        flag;
    #endif
    #ifndef SINGLE_THREADED
        wolfSSL_Mutex memory_mutex;
    #endif
    } WOLFSSL_HEAP;

    /* structure passed into XMALLOC as heap hint
     * having this abstraction allows tracking statistics of individual ssl's
     */
    typedef struct WOLFSSL_HEAP_HINT {
        WOLFSSL_HEAP*           memory;
        WOLFSSL_MEM_CONN_STATS* stats;  /* hold individual connection stats */
    #ifndef WOLFSSL_STATIC_MEMORY_LEAN
        wc_Memory*  outBuf; /* set if using fixed io buffers */
        wc_Memory*  inBuf;
        byte        haFlag; /* flag used for checking handshake count */
    #endif
    } WOLFSSL_HEAP_HINT;

    WOLFSSL_API void* wolfSSL_SetGlobalHeapHint(void* heap);
    WOLFSSL_API void* wolfSSL_GetGlobalHeapHint(void);
    WOLFSSL_API int wc_LoadStaticMemory_ex(WOLFSSL_HEAP_HINT** pHint,
            unsigned int listSz, const word32 *sizeList,
            const word32 *distList, unsigned char* buf, unsigned int sz,
            int flag, int max);
#ifdef WOLFSSL_STATIC_MEMORY_DEBUG_CALLBACK
    #define WOLFSSL_DEBUG_MEMORY_ALLOC 0
    #define WOLFSSL_DEBUG_MEMORY_FAIL  1
    #define WOLFSSL_DEBUG_MEMORY_FREE  2
    #define WOLFSSL_DEBUG_MEMORY_INIT  3


    typedef void (*DebugMemoryCb)(size_t sz, int bucketSz, byte st, int type);
    WOLFSSL_API void wolfSSL_SetDebugMemoryCb(DebugMemoryCb cb);
#endif
    WOLFSSL_API int wc_LoadStaticMemory(WOLFSSL_HEAP_HINT** pHint,
            unsigned char* buf, unsigned int sz, int flag, int max);
    WOLFSSL_API void wc_UnloadStaticMemory(WOLFSSL_HEAP_HINT* heap);

    WOLFSSL_API int wolfSSL_GetMemStats(WOLFSSL_HEAP* heap,
                                                      WOLFSSL_MEM_STATS* stats);
    WOLFSSL_LOCAL int SetFixedIO(WOLFSSL_HEAP* heap, wc_Memory** io);
    WOLFSSL_LOCAL int FreeFixedIO(WOLFSSL_HEAP* heap, wc_Memory** io);

    WOLFSSL_API int wolfSSL_StaticBufferSz_ex(unsigned int listSz,
            const word32 *sizeList, const word32 *distList,
            byte* buffer, word32 sz, int flag);
    WOLFSSL_API int wolfSSL_StaticBufferSz(byte* buffer, word32 sz, int flag);
    WOLFSSL_API int wolfSSL_MemoryPaddingSz(void);
#endif /* WOLFSSL_STATIC_MEMORY */

#ifdef WOLFSSL_STACK_LOG
    WOLFSSL_API void __attribute__((no_instrument_function))
            __cyg_profile_func_enter(void *func,  void *caller);
    WOLFSSL_API void __attribute__((no_instrument_function))
            __cyg_profile_func_exit(void *func, void *caller);
#endif /* WOLFSSL_STACK_LOG */

#ifdef WOLFSSL_MEM_FAIL_COUNT
WOLFSSL_LOCAL void wc_MemFailCount_Init(void);
WOLFSSL_LOCAL void wc_MemFailCount_Free(void);
#endif

#ifdef WOLFSSL_CHECK_MEM_ZERO
WOLFSSL_LOCAL void wc_MemZero_Init(void);
WOLFSSL_LOCAL void wc_MemZero_Free(void);
WOLFSSL_LOCAL void wc_MemZero_Add(const char* name, const void* addr,
    size_t len);
WOLFSSL_LOCAL void wc_MemZero_Check(void* addr, size_t len);
#endif

#ifndef WOLFSSL_NO_FORCE_ZERO
WOLFSSL_API void wc_ForceZero(void *mem, size_t len);
#endif

#ifdef WC_DEBUG_CIPHER_LIFECYCLE
WOLFSSL_LOCAL int wc_debug_CipherLifecycleInit(void **CipherLifecycleTag,
                                               void *heap);
WOLFSSL_LOCAL int wc_debug_CipherLifecycleCheck(void *CipherLifecycleTag,
                                                int abort_p);
WOLFSSL_LOCAL int wc_debug_CipherLifecycleFree(void **CipherLifecycleTag,
                                               void *heap, int abort_p);
#else
#define wc_debug_CipherLifecycleInit(CipherLifecycleTag, heap) \
        ((void)(CipherLifecycleTag), (void)(heap), 0)
#define wc_debug_CipherLifecycleCheck(CipherLifecycleTag, abort_p) \
        ((void)(CipherLifecycleTag), (void)(abort_p), 0)
#define wc_debug_CipherLifecycleFree(CipherLifecycleTag, heap, abort_p) \
        ((void)(CipherLifecycleTag), (void)(heap), (void)(abort_p), 0)
#endif

#ifdef DEBUG_VECTOR_REGISTER_ACCESS_FUZZING
    WOLFSSL_LOCAL int SAVE_VECTOR_REGISTERS2_fuzzer(void);
    #ifndef WC_DEBUG_VECTOR_REGISTERS_FUZZING_SEED
        #define WC_DEBUG_VECTOR_REGISTERS_FUZZING_SEED 0
    #endif
    #ifndef CAN_SAVE_VECTOR_REGISTERS
        #define CAN_SAVE_VECTOR_REGISTERS() (SAVE_VECTOR_REGISTERS2_fuzzer() == 0)
    #endif
#endif

#ifdef DEBUG_VECTOR_REGISTER_ACCESS
    WOLFSSL_API extern THREAD_LS_T int wc_svr_count;
    WOLFSSL_API extern THREAD_LS_T const char *wc_svr_last_file;
    WOLFSSL_API extern THREAD_LS_T int wc_svr_last_line;

    #ifdef DEBUG_VECTOR_REGISTERS_ABORT_ON_FAIL
        #define DEBUG_VECTOR_REGISTERS_EXTRA_FAIL_CLAUSE abort();
    #elif defined(DEBUG_VECTOR_REGISTERS_EXIT_ON_FAIL)
        #define DEBUG_VECTOR_REGISTERS_EXTRA_FAIL_CLAUSE exit(1);
    #elif !defined(DEBUG_VECTOR_REGISTERS_EXTRA_FAIL_CLAUSE)
        #define DEBUG_VECTOR_REGISTERS_EXTRA_FAIL_CLAUSE
    #endif

    #define SAVE_VECTOR_REGISTERS(fail_clause) {                    \
        int _svr_ret = wc_debug_vector_registers_retval;            \
        if (_svr_ret != 0) { fail_clause }                          \
        else {                                                      \
          ++wc_svr_count;                                           \
          if (wc_svr_count > 5) {                                   \
              fprintf(stderr,                                       \
                      ("%s @ L%d : incr : "                         \
                       "wc_svr_count %d (last op %s L%d)\n"),       \
                      __FILE__,                                     \
                      __LINE__,                                     \
                      wc_svr_count,                                 \
                      wc_svr_last_file,                             \
                      wc_svr_last_line);                            \
              DEBUG_VECTOR_REGISTERS_EXTRA_FAIL_CLAUSE              \
          }                                                         \
          wc_svr_last_file = __FILE__;                              \
          wc_svr_last_line = __LINE__;                              \
        }                                                           \
    }

    WOLFSSL_API extern THREAD_LS_T int wc_debug_vector_registers_retval;

#ifndef WC_DEBUG_VECTOR_REGISTERS_RETVAL_INITVAL
#define WC_DEBUG_VECTOR_REGISTERS_RETVAL_INITVAL 0
#endif
#define WC_DEBUG_SET_VECTOR_REGISTERS_RETVAL(x) do { \
            if (((x) != 0) && (wc_svr_count > 0)) {                 \
                fprintf(stderr,                                     \
                        ("%s @ L%d : incr : "                       \
                         "wc_svr_count %d (last op %s L%d)\n"),     \
                        __FILE__,                                   \
                        __LINE__,                                   \
                        wc_svr_count,                               \
                        wc_svr_last_file,                           \
                        wc_svr_last_line);                          \
                DEBUG_VECTOR_REGISTERS_EXTRA_FAIL_CLAUSE            \
            }                                                       \
        wc_debug_vector_registers_retval = (x);                     \
    } while (0)

#ifdef DEBUG_VECTOR_REGISTER_ACCESS_FUZZING
    #define SAVE_VECTOR_REGISTERS2(...) ({                          \
        int _svr2_val = SAVE_VECTOR_REGISTERS2_fuzzer();            \
        if (_svr2_val == 0) {                                       \
            ++wc_svr_count;                                         \
            if (wc_svr_count > 5) {                                 \
                fprintf(stderr,                                     \
                        ("%s @ L%d : incr : "                       \
                         "wc_svr_count %d (last op %s L%d)\n"),     \
                        __FILE__,                                   \
                        __LINE__,                                   \
                        wc_svr_count,                               \
                        wc_svr_last_file,                           \
                        wc_svr_last_line);                          \
                DEBUG_VECTOR_REGISTERS_EXTRA_FAIL_CLAUSE            \
            }                                                       \
            wc_svr_last_file = __FILE__;                            \
            wc_svr_last_line = __LINE__;                            \
            _svr2_val = 0;                                          \
        }                                                           \
        _svr2_val;                                                  \
    })

#else

    #define SAVE_VECTOR_REGISTERS2(...) ({                          \
        int _svr2_val;                                              \
        if (wc_debug_vector_registers_retval != 0) {                \
            if (wc_svr_count > 0) {                                 \
                fprintf(stderr,                                     \
                        ("%s @ L%d : incr : "                       \
                        "wc_svr_count %d (last op %s L%d)\n"),      \
                        __FILE__,                                   \
                        __LINE__,                                   \
                        wc_svr_count,                               \
                        wc_svr_last_file,                           \
                        wc_svr_last_line);                          \
                DEBUG_VECTOR_REGISTERS_EXTRA_FAIL_CLAUSE            \
            }                                                       \
            _svr2_val = wc_debug_vector_registers_retval;           \
        } else {                                                    \
            ++wc_svr_count;                                         \
            if (wc_svr_count > 5) {                                 \
                fprintf(stderr,                                     \
                        ("%s @ L%d : incr : "                       \
                         "wc_svr_count %d (last op %s L%d)\n"),     \
                        __FILE__,                                   \
                        __LINE__,                                   \
                        wc_svr_count,                               \
                        wc_svr_last_file,                           \
                        wc_svr_last_line);                          \
                DEBUG_VECTOR_REGISTERS_EXTRA_FAIL_CLAUSE            \
            }                                                       \
            wc_svr_last_file = __FILE__;                            \
            wc_svr_last_line = __LINE__;                            \
            _svr2_val = 0;                                          \
        }                                                           \
        _svr2_val;                                                  \
    })

#endif

    #define ASSERT_SAVED_VECTOR_REGISTERS() do {                    \
        if (wc_svr_count <= 0) {                                    \
            fprintf(stderr,                                         \
                    ("ASSERT_SAVED_VECTOR_REGISTERS : %s @ L%d : "  \
                    "wc_svr_count %d (last op %s L%d)\n"),          \
                    __FILE__,                                       \
                    __LINE__,                                       \
                    wc_svr_count,                                   \
                    wc_svr_last_file,                               \
                    wc_svr_last_line);                              \
            DEBUG_VECTOR_REGISTERS_EXTRA_FAIL_CLAUSE                \
        }                                                           \
    } while (0)
    #define ASSERT_RESTORED_VECTOR_REGISTERS(fail_clause) do {      \
        if (wc_svr_count != 0) {                                    \
            fprintf(stderr,                                         \
                    ("ASSERT_RESTORED_VECTOR_REGISTERS : %s @ L%d"  \
                     " : wc_svr_count %d (last op %s L%d)\n"),      \
                    __FILE__,                                       \
                    __LINE__,                                       \
                    wc_svr_count,                                   \
                    wc_svr_last_file,                               \
                    wc_svr_last_line);                              \
            DEBUG_VECTOR_REGISTERS_EXTRA_FAIL_CLAUSE                \
            { fail_clause }                                         \
        }                                                           \
    } while (0)
    #define RESTORE_VECTOR_REGISTERS() do {                         \
        --wc_svr_count;                                             \
        if ((wc_svr_count > 4) || (wc_svr_count < 0)) {             \
            fprintf(stderr,                                         \
                    ("%s @ L%d : decr : "                           \
                     "wc_svr_count %d (last op %s L%d)\n"),         \
                    __FILE__,                                       \
                    __LINE__,                                       \
                    wc_svr_count,                                   \
                    wc_svr_last_file,                               \
                    wc_svr_last_line);                              \
            DEBUG_VECTOR_REGISTERS_EXTRA_FAIL_CLAUSE                \
        }                                                           \
        wc_svr_last_file = __FILE__;                                \
        wc_svr_last_line = __LINE__;                                \
    } while(0)

#else /* !DEBUG_VECTOR_REGISTER_ACCESS */
    #if !defined(SAVE_VECTOR_REGISTERS2) && defined(DEBUG_VECTOR_REGISTER_ACCESS_FUZZING)
        #define SAVE_VECTOR_REGISTERS2(...) SAVE_VECTOR_REGISTERS2_fuzzer()
    #endif
#endif

#if defined(WOLFSSL_LINUXKM) || defined(WC_SYM_RELOC_TABLES) || \
    defined(WC_SYM_RELOC_TABLES_SUPPORT)
    #include "linuxkm/linuxkm_memory.h"
#endif

#ifdef __cplusplus
    }  /* extern "C" */
#endif

#endif /* WOLFSSL_MEMORY_H */