1 | /* memory.c
|
---|
2 | *
|
---|
3 | * Copyright (C) 2006-2020 wolfSSL Inc.
|
---|
4 | *
|
---|
5 | * This file is part of wolfSSL.
|
---|
6 | *
|
---|
7 | * wolfSSL is free software; you can redistribute it and/or modify
|
---|
8 | * it under the terms of the GNU General Public License as published by
|
---|
9 | * the Free Software Foundation; either version 2 of the License, or
|
---|
10 | * (at your option) any later version.
|
---|
11 | *
|
---|
12 | * wolfSSL is distributed in the hope that it will be useful,
|
---|
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
---|
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
---|
15 | * GNU General Public License for more details.
|
---|
16 | *
|
---|
17 | * You should have received a copy of the GNU General Public License
|
---|
18 | * along with this program; if not, write to the Free Software
|
---|
19 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
|
---|
20 | */
|
---|
21 |
|
---|
22 |
|
---|
23 | #ifdef HAVE_CONFIG_H
|
---|
24 | #include <config.h>
|
---|
25 | #endif
|
---|
26 |
|
---|
27 | #include <wolfssl/wolfcrypt/settings.h>
|
---|
28 |
|
---|
29 | /* check old macros @wc_fips */
|
---|
30 | #if defined(USE_CYASSL_MEMORY) && !defined(USE_WOLFSSL_MEMORY)
|
---|
31 | #define USE_WOLFSSL_MEMORY
|
---|
32 | #endif
|
---|
33 | #if defined(CYASSL_MALLOC_CHECK) && !defined(WOLFSSL_MALLOC_CHECK)
|
---|
34 | #define WOLFSSL_MALLOC_CHECK
|
---|
35 | #endif
|
---|
36 |
|
---|
37 |
|
---|
38 | /*
|
---|
39 | Possible memory options:
|
---|
40 | * NO_WOLFSSL_MEMORY: Disables wolf memory callback support. When not defined settings.h defines USE_WOLFSSL_MEMORY.
|
---|
41 | * WOLFSSL_STATIC_MEMORY: Turns on the use of static memory buffers and functions.
|
---|
42 | This allows for using static memory instead of dynamic.
|
---|
43 | * WOLFSSL_STATIC_ALIGN: Define defaults to 16 to indicate static memory alignment.
|
---|
44 | * HAVE_IO_POOL: Enables use of static thread safe memory pool for input/output buffers.
|
---|
45 | * XMALLOC_OVERRIDE: Allows override of the XMALLOC, XFREE and XREALLOC macros.
|
---|
46 | * XMALLOC_USER: Allows custom XMALLOC, XFREE and XREALLOC functions to be defined.
|
---|
47 | * WOLFSSL_NO_MALLOC: Disables the fall-back case to use STDIO malloc/free when no callbacks are set.
|
---|
48 | * WOLFSSL_TRACK_MEMORY: Enables memory tracking for total stats and list of allocated memory.
|
---|
49 | * WOLFSSL_DEBUG_MEMORY: Enables extra function and line number args for memory callbacks.
|
---|
50 | * WOLFSSL_DEBUG_MEMORY_PRINT: Enables printing of each malloc/free.
|
---|
51 | * WOLFSSL_MALLOC_CHECK: Reports malloc or alignment failure using WOLFSSL_STATIC_ALIGN
|
---|
52 | * WOLFSSL_FORCE_MALLOC_FAIL_TEST: Used for internal testing to induce random malloc failures.
|
---|
53 | * WOLFSSL_HEAP_TEST: Used for internal testing of heap hint
|
---|
54 | */
|
---|
55 |
|
---|
56 | #ifdef WOLFSSL_ZEPHYR
|
---|
57 | #undef realloc
|
---|
58 | void *z_realloc(void *ptr, size_t size)
|
---|
59 | {
|
---|
60 | if (ptr == NULL)
|
---|
61 | ptr = malloc(size);
|
---|
62 | else
|
---|
63 | ptr = realloc(ptr, size);
|
---|
64 |
|
---|
65 | return ptr;
|
---|
66 | }
|
---|
67 | #define realloc z_realloc
|
---|
68 | #endif
|
---|
69 |
|
---|
70 | #ifdef USE_WOLFSSL_MEMORY
|
---|
71 |
|
---|
72 | #include <wolfssl/wolfcrypt/memory.h>
|
---|
73 | #include <wolfssl/wolfcrypt/error-crypt.h>
|
---|
74 | #include <wolfssl/wolfcrypt/logging.h>
|
---|
75 |
|
---|
76 | #if defined(WOLFSSL_DEBUG_MEMORY) && defined(WOLFSSL_DEBUG_MEMORY_PRINT)
|
---|
77 | #include <stdio.h>
|
---|
78 | #endif
|
---|
79 |
|
---|
80 | #ifdef WOLFSSL_FORCE_MALLOC_FAIL_TEST
|
---|
81 | static int gMemFailCountSeed;
|
---|
82 | static int gMemFailCount;
|
---|
83 | void wolfSSL_SetMemFailCount(int memFailCount)
|
---|
84 | {
|
---|
85 | if (gMemFailCountSeed == 0) {
|
---|
86 | gMemFailCountSeed = memFailCount;
|
---|
87 | gMemFailCount = memFailCount;
|
---|
88 | }
|
---|
89 | }
|
---|
90 | #endif
|
---|
91 | #if defined(WOLFSSL_MALLOC_CHECK) || defined(WOLFSSL_TRACK_MEMORY_FULL) || \
|
---|
92 | defined(WOLFSSL_MEMORY_LOG)
|
---|
93 | #include <stdio.h>
|
---|
94 | #endif
|
---|
95 |
|
---|
96 |
|
---|
97 | /* Set these to default values initially. */
|
---|
98 | static wolfSSL_Malloc_cb malloc_function = NULL;
|
---|
99 | static wolfSSL_Free_cb free_function = NULL;
|
---|
100 | static wolfSSL_Realloc_cb realloc_function = NULL;
|
---|
101 |
|
---|
102 | int wolfSSL_SetAllocators(wolfSSL_Malloc_cb mf,
|
---|
103 | wolfSSL_Free_cb ff,
|
---|
104 | wolfSSL_Realloc_cb rf)
|
---|
105 | {
|
---|
106 | malloc_function = mf;
|
---|
107 | free_function = ff;
|
---|
108 | realloc_function = rf;
|
---|
109 | return 0;
|
---|
110 | }
|
---|
111 |
|
---|
112 | int wolfSSL_GetAllocators(wolfSSL_Malloc_cb* mf,
|
---|
113 | wolfSSL_Free_cb* ff,
|
---|
114 | wolfSSL_Realloc_cb* rf)
|
---|
115 | {
|
---|
116 | if (mf) *mf = malloc_function;
|
---|
117 | if (ff) *ff = free_function;
|
---|
118 | if (rf) *rf = realloc_function;
|
---|
119 | return 0;
|
---|
120 | }
|
---|
121 |
|
---|
122 | #ifndef WOLFSSL_STATIC_MEMORY
|
---|
123 | #ifdef WOLFSSL_DEBUG_MEMORY
|
---|
124 | void* wolfSSL_Malloc(size_t size, const char* func, unsigned int line)
|
---|
125 | #else
|
---|
126 | void* wolfSSL_Malloc(size_t size)
|
---|
127 | #endif
|
---|
128 | {
|
---|
129 | void* res = 0;
|
---|
130 |
|
---|
131 | if (malloc_function) {
|
---|
132 | #ifdef WOLFSSL_DEBUG_MEMORY
|
---|
133 | res = malloc_function(size, func, line);
|
---|
134 | #else
|
---|
135 | res = malloc_function(size);
|
---|
136 | #endif
|
---|
137 | }
|
---|
138 | else {
|
---|
139 | #ifndef WOLFSSL_NO_MALLOC
|
---|
140 | res = malloc(size);
|
---|
141 | #else
|
---|
142 | WOLFSSL_MSG("No malloc available");
|
---|
143 | #endif
|
---|
144 | }
|
---|
145 |
|
---|
146 | #ifdef WOLFSSL_DEBUG_MEMORY
|
---|
147 | #if defined(WOLFSSL_DEBUG_MEMORY_PRINT) && !defined(WOLFSSL_TRACK_MEMORY)
|
---|
148 | printf("Alloc: %p -> %u at %s:%d\n", res, (word32)size, func, line);
|
---|
149 | #else
|
---|
150 | (void)func;
|
---|
151 | (void)line;
|
---|
152 | #endif
|
---|
153 | #endif
|
---|
154 |
|
---|
155 | #ifdef WOLFSSL_MALLOC_CHECK
|
---|
156 | if (res == NULL)
|
---|
157 | WOLFSSL_MSG("wolfSSL_malloc failed");
|
---|
158 | #endif
|
---|
159 |
|
---|
160 | #ifdef WOLFSSL_FORCE_MALLOC_FAIL_TEST
|
---|
161 | if (res && --gMemFailCount == 0) {
|
---|
162 | printf("\n---FORCED MEM FAIL TEST---\n");
|
---|
163 | if (free_function) {
|
---|
164 | #ifdef WOLFSSL_DEBUG_MEMORY
|
---|
165 | free_function(res, func, line);
|
---|
166 | #else
|
---|
167 | free_function(res);
|
---|
168 | #endif
|
---|
169 | }
|
---|
170 | else {
|
---|
171 | free(res); /* clear */
|
---|
172 | }
|
---|
173 | gMemFailCount = gMemFailCountSeed; /* reset */
|
---|
174 | return NULL;
|
---|
175 | }
|
---|
176 | #endif
|
---|
177 |
|
---|
178 | return res;
|
---|
179 | }
|
---|
180 |
|
---|
181 | #ifdef WOLFSSL_DEBUG_MEMORY
|
---|
182 | void wolfSSL_Free(void *ptr, const char* func, unsigned int line)
|
---|
183 | #else
|
---|
184 | void wolfSSL_Free(void *ptr)
|
---|
185 | #endif
|
---|
186 | {
|
---|
187 | #ifdef WOLFSSL_DEBUG_MEMORY
|
---|
188 | #if defined(WOLFSSL_DEBUG_MEMORY_PRINT) && !defined(WOLFSSL_TRACK_MEMORY)
|
---|
189 | printf("Free: %p at %s:%d\n", ptr, func, line);
|
---|
190 | #else
|
---|
191 | (void)func;
|
---|
192 | (void)line;
|
---|
193 | #endif
|
---|
194 | #endif
|
---|
195 |
|
---|
196 | if (free_function) {
|
---|
197 | #ifdef WOLFSSL_DEBUG_MEMORY
|
---|
198 | free_function(ptr, func, line);
|
---|
199 | #else
|
---|
200 | free_function(ptr);
|
---|
201 | #endif
|
---|
202 | }
|
---|
203 | else {
|
---|
204 | #ifndef WOLFSSL_NO_MALLOC
|
---|
205 | free(ptr);
|
---|
206 | #else
|
---|
207 | WOLFSSL_MSG("No free available");
|
---|
208 | #endif
|
---|
209 | }
|
---|
210 | }
|
---|
211 |
|
---|
212 | #ifdef WOLFSSL_DEBUG_MEMORY
|
---|
213 | void* wolfSSL_Realloc(void *ptr, size_t size, const char* func, unsigned int line)
|
---|
214 | #else
|
---|
215 | void* wolfSSL_Realloc(void *ptr, size_t size)
|
---|
216 | #endif
|
---|
217 | {
|
---|
218 | void* res = 0;
|
---|
219 |
|
---|
220 | if (realloc_function) {
|
---|
221 | #ifdef WOLFSSL_DEBUG_MEMORY
|
---|
222 | res = realloc_function(ptr, size, func, line);
|
---|
223 | #else
|
---|
224 | res = realloc_function(ptr, size);
|
---|
225 | #endif
|
---|
226 | }
|
---|
227 | else {
|
---|
228 | #ifndef WOLFSSL_NO_MALLOC
|
---|
229 | res = realloc(ptr, size);
|
---|
230 | #else
|
---|
231 | WOLFSSL_MSG("No realloc available");
|
---|
232 | #endif
|
---|
233 | }
|
---|
234 |
|
---|
235 | return res;
|
---|
236 | }
|
---|
237 | #endif /* WOLFSSL_STATIC_MEMORY */
|
---|
238 |
|
---|
239 | #ifdef WOLFSSL_STATIC_MEMORY
|
---|
240 |
|
---|
241 | struct wc_Memory {
|
---|
242 | byte* buffer;
|
---|
243 | struct wc_Memory* next;
|
---|
244 | word32 sz;
|
---|
245 | };
|
---|
246 |
|
---|
247 |
|
---|
248 | /* returns amount of memory used on success. On error returns negative value
|
---|
249 | wc_Memory** list is the list that new buckets are prepended to
|
---|
250 | */
|
---|
251 | static int create_memory_buckets(byte* buffer, word32 bufSz,
|
---|
252 | word32 buckSz, word32 buckNum, wc_Memory** list) {
|
---|
253 | word32 i;
|
---|
254 | byte* pt = buffer;
|
---|
255 | int ret = 0;
|
---|
256 | word32 memSz = (word32)sizeof(wc_Memory);
|
---|
257 | word32 padSz = -(int)memSz & (WOLFSSL_STATIC_ALIGN - 1);
|
---|
258 |
|
---|
259 | /* if not enough space available for bucket size then do not try */
|
---|
260 | if (buckSz + memSz + padSz > bufSz) {
|
---|
261 | return ret;
|
---|
262 | }
|
---|
263 |
|
---|
264 | for (i = 0; i < buckNum; i++) {
|
---|
265 | if ((buckSz + memSz + padSz) <= (bufSz - ret)) {
|
---|
266 | /* create a new struct and set its values */
|
---|
267 | wc_Memory* mem = (struct wc_Memory*)(pt);
|
---|
268 | mem->sz = buckSz;
|
---|
269 | mem->buffer = (byte*)pt + padSz + memSz;
|
---|
270 | mem->next = NULL;
|
---|
271 |
|
---|
272 | /* add the newly created struct to front of list */
|
---|
273 | if (*list == NULL) {
|
---|
274 | *list = mem;
|
---|
275 | } else {
|
---|
276 | mem->next = *list;
|
---|
277 | *list = mem;
|
---|
278 | }
|
---|
279 |
|
---|
280 | /* advance pointer and keep track of memory used */
|
---|
281 | ret += buckSz + padSz + memSz;
|
---|
282 | pt += buckSz + padSz + memSz;
|
---|
283 | }
|
---|
284 | else {
|
---|
285 | break; /* not enough space left for more buckets of this size */
|
---|
286 | }
|
---|
287 | }
|
---|
288 |
|
---|
289 | return ret;
|
---|
290 | }
|
---|
291 |
|
---|
292 | int wolfSSL_init_memory_heap(WOLFSSL_HEAP* heap)
|
---|
293 | {
|
---|
294 | word32 wc_MemSz[WOLFMEM_DEF_BUCKETS] = { WOLFMEM_BUCKETS };
|
---|
295 | word32 wc_Dist[WOLFMEM_DEF_BUCKETS] = { WOLFMEM_DIST };
|
---|
296 |
|
---|
297 | if (heap == NULL) {
|
---|
298 | return BAD_FUNC_ARG;
|
---|
299 | }
|
---|
300 |
|
---|
301 | XMEMSET(heap, 0, sizeof(WOLFSSL_HEAP));
|
---|
302 |
|
---|
303 | XMEMCPY(heap->sizeList, wc_MemSz, sizeof(wc_MemSz));
|
---|
304 | XMEMCPY(heap->distList, wc_Dist, sizeof(wc_Dist));
|
---|
305 |
|
---|
306 | if (wc_InitMutex(&(heap->memory_mutex)) != 0) {
|
---|
307 | WOLFSSL_MSG("Error creating heap memory mutex");
|
---|
308 | return BAD_MUTEX_E;
|
---|
309 | }
|
---|
310 |
|
---|
311 | return 0;
|
---|
312 | }
|
---|
313 |
|
---|
314 | int wc_LoadStaticMemory(WOLFSSL_HEAP_HINT** pHint,
|
---|
315 | unsigned char* buf, unsigned int sz, int flag, int max)
|
---|
316 | {
|
---|
317 | int ret;
|
---|
318 | WOLFSSL_HEAP* heap;
|
---|
319 | WOLFSSL_HEAP_HINT* hint;
|
---|
320 | word32 idx = 0;
|
---|
321 |
|
---|
322 | if (pHint == NULL || buf == NULL) {
|
---|
323 | return BAD_FUNC_ARG;
|
---|
324 | }
|
---|
325 |
|
---|
326 | if ((sizeof(WOLFSSL_HEAP) + sizeof(WOLFSSL_HEAP_HINT)) > sz - idx) {
|
---|
327 | return BUFFER_E; /* not enough memory for structures */
|
---|
328 | }
|
---|
329 |
|
---|
330 | /* check if hint has already been assigned */
|
---|
331 | if (*pHint == NULL) {
|
---|
332 | heap = (WOLFSSL_HEAP*)buf;
|
---|
333 | idx += sizeof(WOLFSSL_HEAP);
|
---|
334 | hint = (WOLFSSL_HEAP_HINT*)(buf + idx);
|
---|
335 | idx += sizeof(WOLFSSL_HEAP_HINT);
|
---|
336 |
|
---|
337 | ret = wolfSSL_init_memory_heap(heap);
|
---|
338 | if (ret != 0) {
|
---|
339 | return ret;
|
---|
340 | }
|
---|
341 |
|
---|
342 | XMEMSET(hint, 0, sizeof(WOLFSSL_HEAP_HINT));
|
---|
343 | hint->memory = heap;
|
---|
344 | }
|
---|
345 | else {
|
---|
346 | #ifdef WOLFSSL_HEAP_TEST
|
---|
347 | /* do not load in memory if test has been set */
|
---|
348 | if (heap == (void*)WOLFSSL_HEAP_TEST) {
|
---|
349 | return 0;
|
---|
350 | }
|
---|
351 | #endif
|
---|
352 |
|
---|
353 | hint = (WOLFSSL_HEAP_HINT*)(*pHint);
|
---|
354 | heap = hint->memory;
|
---|
355 | }
|
---|
356 |
|
---|
357 | ret = wolfSSL_load_static_memory(buf + idx, sz - idx, flag, heap);
|
---|
358 | if (ret != 1) {
|
---|
359 | WOLFSSL_MSG("Error partitioning memory");
|
---|
360 | return -1;
|
---|
361 | }
|
---|
362 |
|
---|
363 | /* determine what max applies too */
|
---|
364 | if ((flag & WOLFMEM_IO_POOL) || (flag & WOLFMEM_IO_POOL_FIXED)) {
|
---|
365 | heap->maxIO = max;
|
---|
366 | }
|
---|
367 | else { /* general memory used in handshakes */
|
---|
368 | heap->maxHa = max;
|
---|
369 | }
|
---|
370 |
|
---|
371 | heap->flag |= flag;
|
---|
372 | *pHint = hint;
|
---|
373 |
|
---|
374 | (void)max;
|
---|
375 |
|
---|
376 | return 0;
|
---|
377 | }
|
---|
378 |
|
---|
379 | int wolfSSL_load_static_memory(byte* buffer, word32 sz, int flag,
|
---|
380 | WOLFSSL_HEAP* heap)
|
---|
381 | {
|
---|
382 | word32 ava = sz;
|
---|
383 | byte* pt = buffer;
|
---|
384 | int ret = 0;
|
---|
385 | word32 memSz = (word32)sizeof(wc_Memory);
|
---|
386 | word32 padSz = -(int)memSz & (WOLFSSL_STATIC_ALIGN - 1);
|
---|
387 |
|
---|
388 | WOLFSSL_ENTER("wolfSSL_load_static_memory");
|
---|
389 |
|
---|
390 | if (buffer == NULL) {
|
---|
391 | return BAD_FUNC_ARG;
|
---|
392 | }
|
---|
393 |
|
---|
394 | /* align pt */
|
---|
395 | while ((wolfssl_word)pt % WOLFSSL_STATIC_ALIGN && pt < (buffer + sz)) {
|
---|
396 | *pt = 0x00;
|
---|
397 | pt++;
|
---|
398 | ava--;
|
---|
399 | }
|
---|
400 |
|
---|
401 | #ifdef WOLFSSL_DEBUG_MEMORY
|
---|
402 | printf("Allocated %d bytes for static memory @ %p\n", ava, pt);
|
---|
403 | #endif
|
---|
404 |
|
---|
405 | /* divide into chunks of memory and add them to available list */
|
---|
406 | while (ava >= (heap->sizeList[0] + padSz + memSz)) {
|
---|
407 | int i;
|
---|
408 | /* creating only IO buffers from memory passed in, max TLS is 16k */
|
---|
409 | if (flag & WOLFMEM_IO_POOL || flag & WOLFMEM_IO_POOL_FIXED) {
|
---|
410 | if ((ret = create_memory_buckets(pt, ava,
|
---|
411 | WOLFMEM_IO_SZ, 1, &(heap->io))) < 0) {
|
---|
412 | WOLFSSL_LEAVE("wolfSSL_load_static_memory", ret);
|
---|
413 | return ret;
|
---|
414 | }
|
---|
415 |
|
---|
416 | /* check if no more room left for creating IO buffers */
|
---|
417 | if (ret == 0) {
|
---|
418 | break;
|
---|
419 | }
|
---|
420 |
|
---|
421 | /* advance pointer in buffer for next buckets and keep track
|
---|
422 | of how much memory is left available */
|
---|
423 | pt += ret;
|
---|
424 | ava -= ret;
|
---|
425 | }
|
---|
426 | else {
|
---|
427 | /* start at largest and move to smaller buckets */
|
---|
428 | for (i = (WOLFMEM_MAX_BUCKETS - 1); i >= 0; i--) {
|
---|
429 | if ((heap->sizeList[i] + padSz + memSz) <= ava) {
|
---|
430 | if ((ret = create_memory_buckets(pt, ava, heap->sizeList[i],
|
---|
431 | heap->distList[i], &(heap->ava[i]))) < 0) {
|
---|
432 | WOLFSSL_LEAVE("wolfSSL_load_static_memory", ret);
|
---|
433 | return ret;
|
---|
434 | }
|
---|
435 |
|
---|
436 | /* advance pointer in buffer for next buckets and keep track
|
---|
437 | of how much memory is left available */
|
---|
438 | pt += ret;
|
---|
439 | ava -= ret;
|
---|
440 | }
|
---|
441 | }
|
---|
442 | }
|
---|
443 | }
|
---|
444 |
|
---|
445 | return 1;
|
---|
446 | }
|
---|
447 |
|
---|
448 |
|
---|
449 | /* returns the size of management memory needed for each bucket.
|
---|
450 | * This is memory that is used to keep track of and align memory buckets. */
|
---|
451 | int wolfSSL_MemoryPaddingSz(void)
|
---|
452 | {
|
---|
453 | word32 memSz = (word32)sizeof(wc_Memory);
|
---|
454 | word32 padSz = -(int)memSz & (WOLFSSL_STATIC_ALIGN - 1);
|
---|
455 | return memSz + padSz;
|
---|
456 | }
|
---|
457 |
|
---|
458 |
|
---|
459 | /* Used to calculate memory size for optimum use with buckets.
|
---|
460 | returns the suggested size rounded down to the nearest bucket. */
|
---|
461 | int wolfSSL_StaticBufferSz(byte* buffer, word32 sz, int flag)
|
---|
462 | {
|
---|
463 | word32 bucketSz[WOLFMEM_MAX_BUCKETS] = {WOLFMEM_BUCKETS};
|
---|
464 | word32 distList[WOLFMEM_MAX_BUCKETS] = {WOLFMEM_DIST};
|
---|
465 |
|
---|
466 | word32 ava = sz;
|
---|
467 | byte* pt = buffer;
|
---|
468 | word32 memSz = (word32)sizeof(wc_Memory);
|
---|
469 | word32 padSz = -(int)memSz & (WOLFSSL_STATIC_ALIGN - 1);
|
---|
470 |
|
---|
471 | WOLFSSL_ENTER("wolfSSL_static_size");
|
---|
472 |
|
---|
473 | if (buffer == NULL) {
|
---|
474 | return BAD_FUNC_ARG;
|
---|
475 | }
|
---|
476 |
|
---|
477 | /* align pt */
|
---|
478 | while ((wolfssl_word)pt % WOLFSSL_STATIC_ALIGN && pt < (buffer + sz)) {
|
---|
479 | pt++;
|
---|
480 | ava--;
|
---|
481 | }
|
---|
482 |
|
---|
483 | /* creating only IO buffers from memory passed in, max TLS is 16k */
|
---|
484 | if (flag & WOLFMEM_IO_POOL || flag & WOLFMEM_IO_POOL_FIXED) {
|
---|
485 | if (ava < (memSz + padSz + WOLFMEM_IO_SZ)) {
|
---|
486 | return 0; /* not enough room for even one bucket */
|
---|
487 | }
|
---|
488 |
|
---|
489 | ava = ava % (memSz + padSz + WOLFMEM_IO_SZ);
|
---|
490 | }
|
---|
491 | else {
|
---|
492 | int i, k;
|
---|
493 |
|
---|
494 | if (ava < (bucketSz[0] + padSz + memSz)) {
|
---|
495 | return 0; /* not enough room for even one bucket */
|
---|
496 | }
|
---|
497 |
|
---|
498 | while ((ava >= (bucketSz[0] + padSz + memSz)) && (ava > 0)) {
|
---|
499 | /* start at largest and move to smaller buckets */
|
---|
500 | for (i = (WOLFMEM_MAX_BUCKETS - 1); i >= 0; i--) {
|
---|
501 | for (k = distList[i]; k > 0; k--) {
|
---|
502 | if ((bucketSz[i] + padSz + memSz) <= ava) {
|
---|
503 | ava -= bucketSz[i] + padSz + memSz;
|
---|
504 | }
|
---|
505 | }
|
---|
506 | }
|
---|
507 | }
|
---|
508 | }
|
---|
509 |
|
---|
510 | return sz - ava; /* round down */
|
---|
511 | }
|
---|
512 |
|
---|
513 |
|
---|
514 | int FreeFixedIO(WOLFSSL_HEAP* heap, wc_Memory** io)
|
---|
515 | {
|
---|
516 | WOLFSSL_MSG("Freeing fixed IO buffer");
|
---|
517 |
|
---|
518 | /* check if fixed buffer was set */
|
---|
519 | if (*io == NULL) {
|
---|
520 | return 1;
|
---|
521 | }
|
---|
522 |
|
---|
523 | if (heap == NULL) {
|
---|
524 | WOLFSSL_MSG("No heap to return fixed IO too");
|
---|
525 | }
|
---|
526 | else {
|
---|
527 | /* put IO buffer back into IO pool */
|
---|
528 | (*io)->next = heap->io;
|
---|
529 | heap->io = *io;
|
---|
530 | *io = NULL;
|
---|
531 | }
|
---|
532 |
|
---|
533 | return 1;
|
---|
534 | }
|
---|
535 |
|
---|
536 |
|
---|
537 | int SetFixedIO(WOLFSSL_HEAP* heap, wc_Memory** io)
|
---|
538 | {
|
---|
539 | WOLFSSL_MSG("Setting fixed IO for SSL");
|
---|
540 | if (heap == NULL) {
|
---|
541 | return MEMORY_E;
|
---|
542 | }
|
---|
543 |
|
---|
544 | *io = heap->io;
|
---|
545 |
|
---|
546 | if (*io != NULL) {
|
---|
547 | heap->io = (*io)->next;
|
---|
548 | (*io)->next = NULL;
|
---|
549 | }
|
---|
550 | else { /* failed to grab an IO buffer */
|
---|
551 | return 0;
|
---|
552 | }
|
---|
553 |
|
---|
554 | return 1;
|
---|
555 | }
|
---|
556 |
|
---|
557 |
|
---|
558 | int wolfSSL_GetMemStats(WOLFSSL_HEAP* heap, WOLFSSL_MEM_STATS* stats)
|
---|
559 | {
|
---|
560 | word32 i;
|
---|
561 | wc_Memory* pt;
|
---|
562 |
|
---|
563 | XMEMSET(stats, 0, sizeof(WOLFSSL_MEM_STATS));
|
---|
564 |
|
---|
565 | stats->totalAlloc = heap->alloc;
|
---|
566 | stats->totalFr = heap->frAlc;
|
---|
567 | stats->curAlloc = stats->totalAlloc - stats->totalFr;
|
---|
568 | stats->maxHa = heap->maxHa;
|
---|
569 | stats->maxIO = heap->maxIO;
|
---|
570 | for (i = 0; i < WOLFMEM_MAX_BUCKETS; i++) {
|
---|
571 | stats->blockSz[i] = heap->sizeList[i];
|
---|
572 | for (pt = heap->ava[i]; pt != NULL; pt = pt->next) {
|
---|
573 | stats->avaBlock[i] += 1;
|
---|
574 | }
|
---|
575 | }
|
---|
576 |
|
---|
577 | for (pt = heap->io; pt != NULL; pt = pt->next) {
|
---|
578 | stats->avaIO++;
|
---|
579 | }
|
---|
580 |
|
---|
581 | stats->flag = heap->flag; /* flag used */
|
---|
582 |
|
---|
583 | return 1;
|
---|
584 | }
|
---|
585 |
|
---|
586 |
|
---|
587 | #ifdef WOLFSSL_DEBUG_MEMORY
|
---|
588 | void* wolfSSL_Malloc(size_t size, void* heap, int type, const char* func, unsigned int line)
|
---|
589 | #else
|
---|
590 | void* wolfSSL_Malloc(size_t size, void* heap, int type)
|
---|
591 | #endif
|
---|
592 | {
|
---|
593 | void* res = 0;
|
---|
594 | wc_Memory* pt = NULL;
|
---|
595 | int i;
|
---|
596 |
|
---|
597 | /* check for testing heap hint was set */
|
---|
598 | #ifdef WOLFSSL_HEAP_TEST
|
---|
599 | if (heap == (void*)WOLFSSL_HEAP_TEST) {
|
---|
600 | return malloc(size);
|
---|
601 | }
|
---|
602 | #endif
|
---|
603 |
|
---|
604 | /* if no heap hint then use dynamic memory*/
|
---|
605 | if (heap == NULL) {
|
---|
606 | #ifdef WOLFSSL_HEAP_TEST
|
---|
607 | /* allow using malloc for creating ctx and method */
|
---|
608 | if (type == DYNAMIC_TYPE_CTX || type == DYNAMIC_TYPE_METHOD ||
|
---|
609 | type == DYNAMIC_TYPE_CERT_MANAGER) {
|
---|
610 | WOLFSSL_MSG("ERROR allowing null heap hint for ctx/method\n");
|
---|
611 | res = malloc(size);
|
---|
612 | }
|
---|
613 | else {
|
---|
614 | WOLFSSL_MSG("ERROR null heap hint passed into XMALLOC\n");
|
---|
615 | res = NULL;
|
---|
616 | }
|
---|
617 | #else
|
---|
618 | #ifndef WOLFSSL_NO_MALLOC
|
---|
619 | #ifdef FREERTOS
|
---|
620 | res = pvPortMalloc(size);
|
---|
621 | #else
|
---|
622 | res = malloc(size);
|
---|
623 | #endif
|
---|
624 | #else
|
---|
625 | WOLFSSL_MSG("No heap hint found to use and no malloc");
|
---|
626 | #ifdef WOLFSSL_DEBUG_MEMORY
|
---|
627 | printf("ERROR: at %s:%d\n", func, line);
|
---|
628 | #endif
|
---|
629 | #endif /* WOLFSSL_NO_MALLOC */
|
---|
630 | #endif /* WOLFSSL_HEAP_TEST */
|
---|
631 | }
|
---|
632 | else {
|
---|
633 | WOLFSSL_HEAP_HINT* hint = (WOLFSSL_HEAP_HINT*)heap;
|
---|
634 | WOLFSSL_HEAP* mem = hint->memory;
|
---|
635 |
|
---|
636 | if (wc_LockMutex(&(mem->memory_mutex)) != 0) {
|
---|
637 | WOLFSSL_MSG("Bad memory_mutex lock");
|
---|
638 | return NULL;
|
---|
639 | }
|
---|
640 |
|
---|
641 | /* case of using fixed IO buffers */
|
---|
642 | if (mem->flag & WOLFMEM_IO_POOL_FIXED &&
|
---|
643 | (type == DYNAMIC_TYPE_OUT_BUFFER ||
|
---|
644 | type == DYNAMIC_TYPE_IN_BUFFER)) {
|
---|
645 | if (type == DYNAMIC_TYPE_OUT_BUFFER) {
|
---|
646 | pt = hint->outBuf;
|
---|
647 | }
|
---|
648 | if (type == DYNAMIC_TYPE_IN_BUFFER) {
|
---|
649 | pt = hint->inBuf;
|
---|
650 | }
|
---|
651 | }
|
---|
652 | else {
|
---|
653 | /* check if using IO pool flag */
|
---|
654 | if (mem->flag & WOLFMEM_IO_POOL &&
|
---|
655 | (type == DYNAMIC_TYPE_OUT_BUFFER ||
|
---|
656 | type == DYNAMIC_TYPE_IN_BUFFER)) {
|
---|
657 | if (mem->io != NULL) {
|
---|
658 | pt = mem->io;
|
---|
659 | mem->io = pt->next;
|
---|
660 | }
|
---|
661 | }
|
---|
662 |
|
---|
663 | /* general static memory */
|
---|
664 | if (pt == NULL) {
|
---|
665 | for (i = 0; i < WOLFMEM_MAX_BUCKETS; i++) {
|
---|
666 | if ((word32)size < mem->sizeList[i]) {
|
---|
667 | if (mem->ava[i] != NULL) {
|
---|
668 | pt = mem->ava[i];
|
---|
669 | mem->ava[i] = pt->next;
|
---|
670 | break;
|
---|
671 | }
|
---|
672 | #ifdef WOLFSSL_DEBUG_STATIC_MEMORY
|
---|
673 | else {
|
---|
674 | printf("Size: %ld, Empty: %d\n", size,
|
---|
675 | mem->sizeList[i]);
|
---|
676 | }
|
---|
677 | #endif
|
---|
678 | }
|
---|
679 | }
|
---|
680 | }
|
---|
681 | }
|
---|
682 |
|
---|
683 | if (pt != NULL) {
|
---|
684 | mem->inUse += pt->sz;
|
---|
685 | mem->alloc += 1;
|
---|
686 | res = pt->buffer;
|
---|
687 |
|
---|
688 | #ifdef WOLFSSL_DEBUG_MEMORY
|
---|
689 | printf("Alloc: %p -> %u at %s:%d\n", pt->buffer, pt->sz, func, line);
|
---|
690 | #endif
|
---|
691 |
|
---|
692 | /* keep track of connection statistics if flag is set */
|
---|
693 | if (mem->flag & WOLFMEM_TRACK_STATS) {
|
---|
694 | WOLFSSL_MEM_CONN_STATS* stats = hint->stats;
|
---|
695 | if (stats != NULL) {
|
---|
696 | stats->curMem += pt->sz;
|
---|
697 | if (stats->peakMem < stats->curMem) {
|
---|
698 | stats->peakMem = stats->curMem;
|
---|
699 | }
|
---|
700 | stats->curAlloc++;
|
---|
701 | if (stats->peakAlloc < stats->curAlloc) {
|
---|
702 | stats->peakAlloc = stats->curAlloc;
|
---|
703 | }
|
---|
704 | stats->totalAlloc++;
|
---|
705 | }
|
---|
706 | }
|
---|
707 | }
|
---|
708 | else {
|
---|
709 | WOLFSSL_MSG("ERROR ran out of static memory");
|
---|
710 | #ifdef WOLFSSL_DEBUG_MEMORY
|
---|
711 | printf("Looking for %lu bytes at %s:%d\n", size, func, line);
|
---|
712 | #endif
|
---|
713 | }
|
---|
714 |
|
---|
715 | wc_UnLockMutex(&(mem->memory_mutex));
|
---|
716 | }
|
---|
717 |
|
---|
718 | #ifdef WOLFSSL_MALLOC_CHECK
|
---|
719 | if ((wolfssl_word)res % WOLFSSL_STATIC_ALIGN) {
|
---|
720 | WOLFSSL_MSG("ERROR memory is not aligned");
|
---|
721 | res = NULL;
|
---|
722 | }
|
---|
723 | #endif
|
---|
724 |
|
---|
725 |
|
---|
726 | (void)i;
|
---|
727 | (void)pt;
|
---|
728 | (void)type;
|
---|
729 |
|
---|
730 | return res;
|
---|
731 | }
|
---|
732 |
|
---|
733 |
|
---|
734 | #ifdef WOLFSSL_DEBUG_MEMORY
|
---|
735 | void wolfSSL_Free(void *ptr, void* heap, int type, const char* func, unsigned int line)
|
---|
736 | #else
|
---|
737 | void wolfSSL_Free(void *ptr, void* heap, int type)
|
---|
738 | #endif
|
---|
739 | {
|
---|
740 | int i;
|
---|
741 | wc_Memory* pt;
|
---|
742 |
|
---|
743 | if (ptr) {
|
---|
744 | /* check for testing heap hint was set */
|
---|
745 | #ifdef WOLFSSL_HEAP_TEST
|
---|
746 | if (heap == (void*)WOLFSSL_HEAP_TEST) {
|
---|
747 | return free(ptr);
|
---|
748 | }
|
---|
749 | #endif
|
---|
750 |
|
---|
751 | if (heap == NULL) {
|
---|
752 | #ifdef WOLFSSL_HEAP_TEST
|
---|
753 | /* allow using malloc for creating ctx and method */
|
---|
754 | if (type == DYNAMIC_TYPE_CTX || type == DYNAMIC_TYPE_METHOD ||
|
---|
755 | type == DYNAMIC_TYPE_CERT_MANAGER) {
|
---|
756 | WOLFSSL_MSG("ERROR allowing null heap hint for ctx/method\n");
|
---|
757 | }
|
---|
758 | else {
|
---|
759 | WOLFSSL_MSG("ERROR null heap hint passed into XFREE\n");
|
---|
760 | }
|
---|
761 | #endif
|
---|
762 | #ifndef WOLFSSL_NO_MALLOC
|
---|
763 | #ifdef FREERTOS
|
---|
764 | vPortFree(ptr);
|
---|
765 | #else
|
---|
766 | free(ptr);
|
---|
767 | #endif
|
---|
768 | #else
|
---|
769 | WOLFSSL_MSG("Error trying to call free when turned off");
|
---|
770 | #endif /* WOLFSSL_NO_MALLOC */
|
---|
771 | }
|
---|
772 | else {
|
---|
773 | WOLFSSL_HEAP_HINT* hint = (WOLFSSL_HEAP_HINT*)heap;
|
---|
774 | WOLFSSL_HEAP* mem = hint->memory;
|
---|
775 | word32 padSz = -(int)sizeof(wc_Memory) & (WOLFSSL_STATIC_ALIGN - 1);
|
---|
776 |
|
---|
777 | /* get memory struct and add it to available list */
|
---|
778 | pt = (wc_Memory*)((byte*)ptr - sizeof(wc_Memory) - padSz);
|
---|
779 | if (wc_LockMutex(&(mem->memory_mutex)) != 0) {
|
---|
780 | WOLFSSL_MSG("Bad memory_mutex lock");
|
---|
781 | return;
|
---|
782 | }
|
---|
783 |
|
---|
784 | /* case of using fixed IO buffers */
|
---|
785 | if (mem->flag & WOLFMEM_IO_POOL_FIXED &&
|
---|
786 | (type == DYNAMIC_TYPE_OUT_BUFFER ||
|
---|
787 | type == DYNAMIC_TYPE_IN_BUFFER)) {
|
---|
788 | /* fixed IO pools are free'd at the end of SSL lifetime
|
---|
789 | using FreeFixedIO(WOLFSSL_HEAP* heap, wc_Memory** io) */
|
---|
790 | }
|
---|
791 | else if (mem->flag & WOLFMEM_IO_POOL && pt->sz == WOLFMEM_IO_SZ &&
|
---|
792 | (type == DYNAMIC_TYPE_OUT_BUFFER ||
|
---|
793 | type == DYNAMIC_TYPE_IN_BUFFER)) {
|
---|
794 | pt->next = mem->io;
|
---|
795 | mem->io = pt;
|
---|
796 | }
|
---|
797 | else { /* general memory free */
|
---|
798 | for (i = 0; i < WOLFMEM_MAX_BUCKETS; i++) {
|
---|
799 | if (pt->sz == mem->sizeList[i]) {
|
---|
800 | pt->next = mem->ava[i];
|
---|
801 | mem->ava[i] = pt;
|
---|
802 | break;
|
---|
803 | }
|
---|
804 | }
|
---|
805 | }
|
---|
806 | mem->inUse -= pt->sz;
|
---|
807 | mem->frAlc += 1;
|
---|
808 |
|
---|
809 | #ifdef WOLFSSL_DEBUG_MEMORY
|
---|
810 | printf("Free: %p -> %u at %s:%d\n", pt->buffer, pt->sz, func, line);
|
---|
811 | #endif
|
---|
812 |
|
---|
813 | /* keep track of connection statistics if flag is set */
|
---|
814 | if (mem->flag & WOLFMEM_TRACK_STATS) {
|
---|
815 | WOLFSSL_MEM_CONN_STATS* stats = hint->stats;
|
---|
816 | if (stats != NULL) {
|
---|
817 | /* avoid under flow */
|
---|
818 | if (stats->curMem > pt->sz) {
|
---|
819 | stats->curMem -= pt->sz;
|
---|
820 | }
|
---|
821 | else {
|
---|
822 | stats->curMem = 0;
|
---|
823 | }
|
---|
824 |
|
---|
825 | if (stats->curAlloc > 0) {
|
---|
826 | stats->curAlloc--;
|
---|
827 | }
|
---|
828 | stats->totalFr++;
|
---|
829 | }
|
---|
830 | }
|
---|
831 | wc_UnLockMutex(&(mem->memory_mutex));
|
---|
832 | }
|
---|
833 | }
|
---|
834 |
|
---|
835 | (void)i;
|
---|
836 | (void)pt;
|
---|
837 | (void)type;
|
---|
838 | }
|
---|
839 |
|
---|
840 | #ifdef WOLFSSL_DEBUG_MEMORY
|
---|
841 | void* wolfSSL_Realloc(void *ptr, size_t size, void* heap, int type, const char* func, unsigned int line)
|
---|
842 | #else
|
---|
843 | void* wolfSSL_Realloc(void *ptr, size_t size, void* heap, int type)
|
---|
844 | #endif
|
---|
845 | {
|
---|
846 | void* res = 0;
|
---|
847 | wc_Memory* pt = NULL;
|
---|
848 | word32 prvSz;
|
---|
849 | int i;
|
---|
850 |
|
---|
851 | /* check for testing heap hint was set */
|
---|
852 | #ifdef WOLFSSL_HEAP_TEST
|
---|
853 | if (heap == (void*)WOLFSSL_HEAP_TEST) {
|
---|
854 | return realloc(ptr, size);
|
---|
855 | }
|
---|
856 | #endif
|
---|
857 |
|
---|
858 | if (heap == NULL) {
|
---|
859 | #ifdef WOLFSSL_HEAP_TEST
|
---|
860 | WOLFSSL_MSG("ERROR null heap hint passed in to XREALLOC\n");
|
---|
861 | #endif
|
---|
862 | #ifndef WOLFSSL_NO_MALLOC
|
---|
863 | res = realloc(ptr, size);
|
---|
864 | #else
|
---|
865 | WOLFSSL_MSG("NO heap found to use for realloc");
|
---|
866 | #endif /* WOLFSSL_NO_MALLOC */
|
---|
867 | }
|
---|
868 | else {
|
---|
869 | WOLFSSL_HEAP_HINT* hint = (WOLFSSL_HEAP_HINT*)heap;
|
---|
870 | WOLFSSL_HEAP* mem = hint->memory;
|
---|
871 | word32 padSz = -(int)sizeof(wc_Memory) & (WOLFSSL_STATIC_ALIGN - 1);
|
---|
872 |
|
---|
873 | if (ptr == NULL) {
|
---|
874 | #ifdef WOLFSSL_DEBUG_MEMORY
|
---|
875 | return wolfSSL_Malloc(size, heap, type, func, line);
|
---|
876 | #else
|
---|
877 | return wolfSSL_Malloc(size, heap, type);
|
---|
878 | #endif
|
---|
879 | }
|
---|
880 |
|
---|
881 | if (wc_LockMutex(&(mem->memory_mutex)) != 0) {
|
---|
882 | WOLFSSL_MSG("Bad memory_mutex lock");
|
---|
883 | return NULL;
|
---|
884 | }
|
---|
885 |
|
---|
886 | /* case of using fixed IO buffers or IO pool */
|
---|
887 | if (((mem->flag & WOLFMEM_IO_POOL)||(mem->flag & WOLFMEM_IO_POOL_FIXED))
|
---|
888 | && (type == DYNAMIC_TYPE_OUT_BUFFER ||
|
---|
889 | type == DYNAMIC_TYPE_IN_BUFFER)) {
|
---|
890 | /* no realloc, is fixed size */
|
---|
891 | pt = (wc_Memory*)((byte*)ptr - padSz - sizeof(wc_Memory));
|
---|
892 | if (pt->sz < size) {
|
---|
893 | WOLFSSL_MSG("Error IO memory was not large enough");
|
---|
894 | res = NULL; /* return NULL in error case */
|
---|
895 | }
|
---|
896 | res = pt->buffer;
|
---|
897 | }
|
---|
898 | else {
|
---|
899 | /* general memory */
|
---|
900 | for (i = 0; i < WOLFMEM_MAX_BUCKETS; i++) {
|
---|
901 | if ((word32)size < mem->sizeList[i]) {
|
---|
902 | if (mem->ava[i] != NULL) {
|
---|
903 | pt = mem->ava[i];
|
---|
904 | mem->ava[i] = pt->next;
|
---|
905 | break;
|
---|
906 | }
|
---|
907 | }
|
---|
908 | }
|
---|
909 |
|
---|
910 | if (pt != NULL && res == NULL) {
|
---|
911 | res = pt->buffer;
|
---|
912 |
|
---|
913 | /* copy over original information and free ptr */
|
---|
914 | prvSz = ((wc_Memory*)((byte*)ptr - padSz -
|
---|
915 | sizeof(wc_Memory)))->sz;
|
---|
916 | prvSz = (prvSz > pt->sz)? pt->sz: prvSz;
|
---|
917 | XMEMCPY(pt->buffer, ptr, prvSz);
|
---|
918 | mem->inUse += pt->sz;
|
---|
919 | mem->alloc += 1;
|
---|
920 |
|
---|
921 | /* free memory that was previously being used */
|
---|
922 | wc_UnLockMutex(&(mem->memory_mutex));
|
---|
923 | wolfSSL_Free(ptr, heap, type
|
---|
924 | #ifdef WOLFSSL_DEBUG_MEMORY
|
---|
925 | , func, line
|
---|
926 | #endif
|
---|
927 | );
|
---|
928 | if (wc_LockMutex(&(mem->memory_mutex)) != 0) {
|
---|
929 | WOLFSSL_MSG("Bad memory_mutex lock");
|
---|
930 | return NULL;
|
---|
931 | }
|
---|
932 | }
|
---|
933 | }
|
---|
934 | wc_UnLockMutex(&(mem->memory_mutex));
|
---|
935 | }
|
---|
936 |
|
---|
937 | #ifdef WOLFSSL_MALLOC_CHECK
|
---|
938 | if ((wolfssl_word)res % WOLFSSL_STATIC_ALIGN) {
|
---|
939 | WOLFSSL_MSG("ERROR memory is not aligned");
|
---|
940 | res = NULL;
|
---|
941 | }
|
---|
942 | #endif
|
---|
943 |
|
---|
944 | (void)i;
|
---|
945 | (void)pt;
|
---|
946 | (void)type;
|
---|
947 |
|
---|
948 | return res;
|
---|
949 | }
|
---|
950 | #endif /* WOLFSSL_STATIC_MEMORY */
|
---|
951 |
|
---|
952 | #endif /* USE_WOLFSSL_MEMORY */
|
---|
953 |
|
---|
954 |
|
---|
955 | #ifdef HAVE_IO_POOL
|
---|
956 |
|
---|
957 | /* Example for user io pool, shared build may need definitions in lib proper */
|
---|
958 |
|
---|
959 | #include <wolfssl/wolfcrypt/types.h>
|
---|
960 | #include <stdlib.h>
|
---|
961 |
|
---|
962 | #ifndef HAVE_THREAD_LS
|
---|
963 | #error "Oops, simple I/O pool example needs thread local storage"
|
---|
964 | #endif
|
---|
965 |
|
---|
966 |
|
---|
967 | /* allow simple per thread in and out pools */
|
---|
968 | /* use 17k size since max record size is 16k plus overhead */
|
---|
969 | static THREAD_LS_T byte pool_in[17*1024];
|
---|
970 | static THREAD_LS_T byte pool_out[17*1024];
|
---|
971 |
|
---|
972 |
|
---|
973 | void* XMALLOC(size_t n, void* heap, int type)
|
---|
974 | {
|
---|
975 | (void)heap;
|
---|
976 |
|
---|
977 | if (type == DYNAMIC_TYPE_IN_BUFFER) {
|
---|
978 | if (n < sizeof(pool_in))
|
---|
979 | return pool_in;
|
---|
980 | else
|
---|
981 | return NULL;
|
---|
982 | }
|
---|
983 |
|
---|
984 | if (type == DYNAMIC_TYPE_OUT_BUFFER) {
|
---|
985 | if (n < sizeof(pool_out))
|
---|
986 | return pool_out;
|
---|
987 | else
|
---|
988 | return NULL;
|
---|
989 | }
|
---|
990 |
|
---|
991 | return malloc(n);
|
---|
992 | }
|
---|
993 |
|
---|
994 | void* XREALLOC(void *p, size_t n, void* heap, int type)
|
---|
995 | {
|
---|
996 | (void)heap;
|
---|
997 |
|
---|
998 | if (type == DYNAMIC_TYPE_IN_BUFFER) {
|
---|
999 | if (n < sizeof(pool_in))
|
---|
1000 | return pool_in;
|
---|
1001 | else
|
---|
1002 | return NULL;
|
---|
1003 | }
|
---|
1004 |
|
---|
1005 | if (type == DYNAMIC_TYPE_OUT_BUFFER) {
|
---|
1006 | if (n < sizeof(pool_out))
|
---|
1007 | return pool_out;
|
---|
1008 | else
|
---|
1009 | return NULL;
|
---|
1010 | }
|
---|
1011 |
|
---|
1012 | return realloc(p, n);
|
---|
1013 | }
|
---|
1014 |
|
---|
1015 | void XFREE(void *p, void* heap, int type)
|
---|
1016 | {
|
---|
1017 | (void)heap;
|
---|
1018 |
|
---|
1019 | if (type == DYNAMIC_TYPE_IN_BUFFER)
|
---|
1020 | return; /* do nothing, static pool */
|
---|
1021 |
|
---|
1022 | if (type == DYNAMIC_TYPE_OUT_BUFFER)
|
---|
1023 | return; /* do nothing, static pool */
|
---|
1024 |
|
---|
1025 | free(p);
|
---|
1026 | }
|
---|
1027 |
|
---|
1028 | #endif /* HAVE_IO_POOL */
|
---|
1029 |
|
---|
1030 | #ifdef WOLFSSL_MEMORY_LOG
|
---|
1031 | void *xmalloc(size_t n, void* heap, int type, const char* func,
|
---|
1032 | const char* file, unsigned int line)
|
---|
1033 | {
|
---|
1034 | void* p;
|
---|
1035 | word32* p32;
|
---|
1036 |
|
---|
1037 | if (malloc_function)
|
---|
1038 | p32 = malloc_function(n + sizeof(word32) * 4);
|
---|
1039 | else
|
---|
1040 | p32 = malloc(n + sizeof(word32) * 4);
|
---|
1041 |
|
---|
1042 | p32[0] = (word32)n;
|
---|
1043 | p = (void*)(p32 + 4);
|
---|
1044 |
|
---|
1045 | fprintf(stderr, "Alloc: %p -> %u (%d) at %s:%s:%u\n", p, (word32)n, type,
|
---|
1046 | func, file, line);
|
---|
1047 |
|
---|
1048 | (void)heap;
|
---|
1049 |
|
---|
1050 | return p;
|
---|
1051 | }
|
---|
1052 | void *xrealloc(void *p, size_t n, void* heap, int type, const char* func,
|
---|
1053 | const char* file, unsigned int line)
|
---|
1054 | {
|
---|
1055 | void* newp = NULL;
|
---|
1056 | word32* p32;
|
---|
1057 | word32* oldp32 = NULL;
|
---|
1058 | word32 oldLen;
|
---|
1059 |
|
---|
1060 | if (p != NULL) {
|
---|
1061 | oldp32 = (word32*)p;
|
---|
1062 | oldp32 -= 4;
|
---|
1063 | oldLen = oldp32[0];
|
---|
1064 | }
|
---|
1065 |
|
---|
1066 | if (realloc_function)
|
---|
1067 | p32 = realloc_function(oldp32, n + sizeof(word32) * 4);
|
---|
1068 | else
|
---|
1069 | p32 = realloc(oldp32, n + sizeof(word32) * 4);
|
---|
1070 |
|
---|
1071 | if (p32 != NULL) {
|
---|
1072 | p32[0] = (word32)n;
|
---|
1073 | newp = (void*)(p32 + 4);
|
---|
1074 |
|
---|
1075 | fprintf(stderr, "Alloc: %p -> %u (%d) at %s:%s:%u\n", newp, (word32)n,
|
---|
1076 | type, func, file, line);
|
---|
1077 | if (p != NULL) {
|
---|
1078 | fprintf(stderr, "Free: %p -> %u (%d) at %s:%s:%u\n", p, oldLen,
|
---|
1079 | type, func, file, line);
|
---|
1080 | }
|
---|
1081 | }
|
---|
1082 |
|
---|
1083 | (void)heap;
|
---|
1084 |
|
---|
1085 | return newp;
|
---|
1086 | }
|
---|
1087 | void xfree(void *p, void* heap, int type, const char* func, const char* file,
|
---|
1088 | unsigned int line)
|
---|
1089 | {
|
---|
1090 | word32* p32 = (word32*)p;
|
---|
1091 |
|
---|
1092 | if (p != NULL) {
|
---|
1093 | p32 -= 4;
|
---|
1094 |
|
---|
1095 | fprintf(stderr, "Free: %p -> %u (%d) at %s:%s:%u\n", p, p32[0], type,
|
---|
1096 | func, file, line);
|
---|
1097 |
|
---|
1098 | if (free_function)
|
---|
1099 | free_function(p32);
|
---|
1100 | else
|
---|
1101 | free(p32);
|
---|
1102 | }
|
---|
1103 |
|
---|
1104 | (void)heap;
|
---|
1105 | }
|
---|
1106 | #endif /* WOLFSSL_MEMORY_LOG */
|
---|
1107 |
|
---|
1108 | #ifdef WOLFSSL_STACK_LOG
|
---|
1109 | /* Note: this code only works with GCC using -finstrument-functions. */
|
---|
1110 | void __attribute__((no_instrument_function))
|
---|
1111 | __cyg_profile_func_enter(void *func, void *caller)
|
---|
1112 | {
|
---|
1113 | register void* sp asm("sp");
|
---|
1114 | fprintf(stderr, "ENTER: %016lx %p\n", (unsigned long)(size_t)func, sp);
|
---|
1115 | (void)caller;
|
---|
1116 | }
|
---|
1117 |
|
---|
1118 | void __attribute__((no_instrument_function))
|
---|
1119 | __cyg_profile_func_exit(void *func, void *caller)
|
---|
1120 | {
|
---|
1121 | register void* sp asm("sp");
|
---|
1122 | fprintf(stderr, "EXIT: %016lx %p\n", (unsigned long)(size_t)func, sp);
|
---|
1123 | (void)caller;
|
---|
1124 | }
|
---|
1125 | #endif
|
---|
1126 |
|
---|