source: asp3_tinet_ecnl_arm/trunk/wolfssl-3.12.2/wolfcrypt/src/memory.c@ 352

Last change on this file since 352 was 352, checked in by coas-nagasima, 6 years ago

arm向けASP3版ECNLを追加

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc;charset=UTF-8
File size: 25.7 KB
Line 
1/* memory.c
2 *
3 * Copyright (C) 2006-2017 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#ifdef USE_WOLFSSL_MEMORY
38
39#include <wolfssl/wolfcrypt/memory.h>
40#include <wolfssl/wolfcrypt/error-crypt.h>
41#include <wolfssl/wolfcrypt/logging.h>
42
43#if defined(WOLFSSL_MALLOC_CHECK) || defined(WOLFSSL_TRACK_MEMORY_FULL)
44 #include <stdio.h>
45#endif
46
47
48/* Set these to default values initially. */
49static wolfSSL_Malloc_cb malloc_function = 0;
50static wolfSSL_Free_cb free_function = 0;
51static wolfSSL_Realloc_cb realloc_function = 0;
52
53int wolfSSL_SetAllocators(wolfSSL_Malloc_cb mf,
54 wolfSSL_Free_cb ff,
55 wolfSSL_Realloc_cb rf)
56{
57 int res = 0;
58
59 if (mf)
60 malloc_function = mf;
61 else
62 res = BAD_FUNC_ARG;
63
64 if (ff)
65 free_function = ff;
66 else
67 res = BAD_FUNC_ARG;
68
69 if (rf)
70 realloc_function = rf;
71 else
72 res = BAD_FUNC_ARG;
73
74 return res;
75}
76
77int wolfSSL_GetAllocators(wolfSSL_Malloc_cb* mf,
78 wolfSSL_Free_cb* ff,
79 wolfSSL_Realloc_cb* rf)
80{
81 if (mf) *mf = malloc_function;
82 if (ff) *ff = free_function;
83 if (rf) *rf = realloc_function;
84 return 0;
85}
86
87#ifndef WOLFSSL_STATIC_MEMORY
88#ifdef WOLFSSL_DEBUG_MEMORY
89void* wolfSSL_Malloc(size_t size, const char* func, unsigned int line)
90#else
91void* wolfSSL_Malloc(size_t size)
92#endif
93{
94 void* res = 0;
95
96 if (malloc_function) {
97 #ifdef WOLFSSL_DEBUG_MEMORY
98 res = malloc_function(size, func, line);
99 #else
100 res = malloc_function(size);
101 #endif
102 }
103 else {
104 res = malloc(size);
105 }
106
107 #ifdef WOLFSSL_MALLOC_CHECK
108 if (res == NULL)
109 puts("wolfSSL_malloc failed");
110 #endif
111
112 return res;
113}
114
115#ifdef WOLFSSL_DEBUG_MEMORY
116void wolfSSL_Free(void *ptr, const char* func, unsigned int line)
117#else
118void wolfSSL_Free(void *ptr)
119#endif
120{
121 if (free_function) {
122 #ifdef WOLFSSL_DEBUG_MEMORY
123 free_function(ptr, func, line);
124 #else
125 free_function(ptr);
126 #endif
127 }
128 else {
129 free(ptr);
130 }
131}
132
133#ifdef WOLFSSL_DEBUG_MEMORY
134void* wolfSSL_Realloc(void *ptr, size_t size, const char* func, unsigned int line)
135#else
136void* wolfSSL_Realloc(void *ptr, size_t size)
137#endif
138{
139 void* res = 0;
140
141 if (realloc_function) {
142 #ifdef WOLFSSL_DEBUG_MEMORY
143 res = realloc_function(ptr, size, func, line);
144 #else
145 res = realloc_function(ptr, size);
146 #endif
147 }
148 else {
149 res = realloc(ptr, size);
150 }
151
152 return res;
153}
154#endif /* WOLFSSL_STATIC_MEMORY */
155
156#ifdef WOLFSSL_STATIC_MEMORY
157
158struct wc_Memory {
159 byte* buffer;
160 struct wc_Memory* next;
161 word32 sz;
162};
163
164
165/* returns amount of memory used on success. On error returns negative value
166 wc_Memory** list is the list that new buckets are prepended to
167 */
168static int create_memory_buckets(byte* buffer, word32 bufSz,
169 word32 buckSz, word32 buckNum, wc_Memory** list) {
170 word32 i;
171 byte* pt = buffer;
172 int ret = 0;
173 word32 memSz = (word32)sizeof(wc_Memory);
174 word32 padSz = -(int)memSz & (WOLFSSL_STATIC_ALIGN - 1);
175
176 /* if not enough space available for bucket size then do not try */
177 if (buckSz + memSz + padSz > bufSz) {
178 return ret;
179 }
180
181 for (i = 0; i < buckNum; i++) {
182 if ((buckSz + memSz + padSz) <= (bufSz - ret)) {
183 /* create a new struct and set its values */
184 wc_Memory* mem = (struct wc_Memory*)(pt);
185 mem->sz = buckSz;
186 mem->buffer = (byte*)pt + padSz + memSz;
187 mem->next = NULL;
188
189 /* add the newly created struct to front of list */
190 if (*list == NULL) {
191 *list = mem;
192 } else {
193 mem->next = *list;
194 *list = mem;
195 }
196
197 /* advance pointer and keep track of memory used */
198 ret += buckSz + padSz + memSz;
199 pt += buckSz + padSz + memSz;
200 }
201 else {
202 break; /* not enough space left for more buckets of this size */
203 }
204 }
205
206 return ret;
207}
208
209int wolfSSL_init_memory_heap(WOLFSSL_HEAP* heap)
210{
211 word32 wc_MemSz[WOLFMEM_DEF_BUCKETS] = { WOLFMEM_BUCKETS };
212 word32 wc_Dist[WOLFMEM_DEF_BUCKETS] = { WOLFMEM_DIST };
213
214 if (heap == NULL) {
215 return BAD_FUNC_ARG;
216 }
217
218 XMEMSET(heap, 0, sizeof(WOLFSSL_HEAP));
219
220 XMEMCPY(heap->sizeList, wc_MemSz, sizeof(wc_MemSz));
221 XMEMCPY(heap->distList, wc_Dist, sizeof(wc_Dist));
222
223 if (wc_InitMutex(&(heap->memory_mutex)) != 0) {
224 WOLFSSL_MSG("Error creating heap memory mutex");
225 return BAD_MUTEX_E;
226 }
227
228 return 0;
229}
230
231int wc_LoadStaticMemory(WOLFSSL_HEAP_HINT** pHint,
232 unsigned char* buf, unsigned int sz, int flag, int max)
233{
234 int ret;
235 WOLFSSL_HEAP* heap;
236 WOLFSSL_HEAP_HINT* hint;
237 word32 idx = 0;
238
239 if (pHint == NULL || buf == NULL) {
240 return BAD_FUNC_ARG;
241 }
242
243 if ((sizeof(WOLFSSL_HEAP) + sizeof(WOLFSSL_HEAP_HINT)) > sz - idx) {
244 return BUFFER_E; /* not enough memory for structures */
245 }
246
247 /* check if hint has already been assigned */
248 if (*pHint == NULL) {
249 heap = (WOLFSSL_HEAP*)buf;
250 idx += sizeof(WOLFSSL_HEAP);
251 hint = (WOLFSSL_HEAP_HINT*)(buf + idx);
252 idx += sizeof(WOLFSSL_HEAP_HINT);
253
254 ret = wolfSSL_init_memory_heap(heap);
255 if (ret != 0) {
256 return ret;
257 }
258
259 XMEMSET(hint, 0, sizeof(WOLFSSL_HEAP_HINT));
260 hint->memory = heap;
261 }
262 else {
263 #ifdef WOLFSSL_HEAP_TEST
264 /* do not load in memory if test has been set */
265 if (heap == (void*)WOLFSSL_HEAP_TEST) {
266 return 0;
267 }
268 #endif
269
270 hint = (WOLFSSL_HEAP_HINT*)(*pHint);
271 heap = hint->memory;
272 }
273
274 ret = wolfSSL_load_static_memory(buf + idx, sz - idx, flag, heap);
275 if (ret != 1) {
276 WOLFSSL_MSG("Error partitioning memory");
277 return -1;
278 }
279
280 /* determine what max applies too */
281 if ((flag & WOLFMEM_IO_POOL) || (flag & WOLFMEM_IO_POOL_FIXED)) {
282 heap->maxIO = max;
283 }
284 else { /* general memory used in handshakes */
285 heap->maxHa = max;
286 }
287
288 heap->flag |= flag;
289 *pHint = hint;
290
291 (void)max;
292
293 return 0;
294}
295
296int wolfSSL_load_static_memory(byte* buffer, word32 sz, int flag,
297 WOLFSSL_HEAP* heap)
298{
299 word32 ava = sz;
300 byte* pt = buffer;
301 int ret = 0;
302 word32 memSz = (word32)sizeof(wc_Memory);
303 word32 padSz = -(int)memSz & (WOLFSSL_STATIC_ALIGN - 1);
304
305 WOLFSSL_ENTER("wolfSSL_load_static_memory");
306
307 if (buffer == NULL) {
308 return BAD_FUNC_ARG;
309 }
310
311 /* align pt */
312 while ((wolfssl_word)pt % WOLFSSL_STATIC_ALIGN && pt < (buffer + sz)) {
313 *pt = 0x00;
314 pt++;
315 ava--;
316 }
317
318#ifdef WOLFSSL_DEBUG_MEMORY
319 printf("Allocated %d bytes for static memory @ %p\n", ava, pt);
320#endif
321
322 /* devide into chunks of memory and add them to available list */
323 while (ava >= (heap->sizeList[0] + padSz + memSz)) {
324 int i;
325 /* creating only IO buffers from memory passed in, max TLS is 16k */
326 if (flag & WOLFMEM_IO_POOL || flag & WOLFMEM_IO_POOL_FIXED) {
327 if ((ret = create_memory_buckets(pt, ava,
328 WOLFMEM_IO_SZ, 1, &(heap->io))) < 0) {
329 WOLFSSL_LEAVE("wolfSSL_load_static_memory", ret);
330 return ret;
331 }
332
333 /* check if no more room left for creating IO buffers */
334 if (ret == 0) {
335 break;
336 }
337
338 /* advance pointer in buffer for next buckets and keep track
339 of how much memory is left available */
340 pt += ret;
341 ava -= ret;
342 }
343 else {
344 /* start at largest and move to smaller buckets */
345 for (i = (WOLFMEM_MAX_BUCKETS - 1); i >= 0; i--) {
346 if ((heap->sizeList[i] + padSz + memSz) <= ava) {
347 if ((ret = create_memory_buckets(pt, ava, heap->sizeList[i],
348 heap->distList[i], &(heap->ava[i]))) < 0) {
349 WOLFSSL_LEAVE("wolfSSL_load_static_memory", ret);
350 return ret;
351 }
352
353 /* advance pointer in buffer for next buckets and keep track
354 of how much memory is left available */
355 pt += ret;
356 ava -= ret;
357 }
358 }
359 }
360 }
361
362 return 1;
363}
364
365
366/* returns the size of management memory needed for each bucket.
367 * This is memory that is used to keep track of and align memory buckets. */
368int wolfSSL_MemoryPaddingSz(void)
369{
370 word32 memSz = (word32)sizeof(wc_Memory);
371 word32 padSz = -(int)memSz & (WOLFSSL_STATIC_ALIGN - 1);
372 return memSz + padSz;
373}
374
375
376/* Used to calculate memory size for optimum use with buckets.
377 returns the suggested size rounded down to the nearest bucket. */
378int wolfSSL_StaticBufferSz(byte* buffer, word32 sz, int flag)
379{
380 word32 bucketSz[WOLFMEM_MAX_BUCKETS] = {WOLFMEM_BUCKETS};
381 word32 distList[WOLFMEM_MAX_BUCKETS] = {WOLFMEM_DIST};
382
383 word32 ava = sz;
384 byte* pt = buffer;
385 word32 memSz = (word32)sizeof(wc_Memory);
386 word32 padSz = -(int)memSz & (WOLFSSL_STATIC_ALIGN - 1);
387
388 WOLFSSL_ENTER("wolfSSL_static_size");
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++;
397 ava--;
398 }
399
400 /* creating only IO buffers from memory passed in, max TLS is 16k */
401 if (flag & WOLFMEM_IO_POOL || flag & WOLFMEM_IO_POOL_FIXED) {
402 if (ava < (memSz + padSz + WOLFMEM_IO_SZ)) {
403 return 0; /* not enough room for even one bucket */
404 }
405
406 ava = ava % (memSz + padSz + WOLFMEM_IO_SZ);
407 }
408 else {
409 int i, k;
410
411 if (ava < (bucketSz[0] + padSz + memSz)) {
412 return 0; /* not enough room for even one bucket */
413 }
414
415 while ((ava >= (bucketSz[0] + padSz + memSz)) && (ava > 0)) {
416 /* start at largest and move to smaller buckets */
417 for (i = (WOLFMEM_MAX_BUCKETS - 1); i >= 0; i--) {
418 for (k = distList[i]; k > 0; k--) {
419 if ((bucketSz[i] + padSz + memSz) <= ava) {
420 ava -= bucketSz[i] + padSz + memSz;
421 }
422 }
423 }
424 }
425 }
426
427 return sz - ava; /* round down */
428}
429
430
431int FreeFixedIO(WOLFSSL_HEAP* heap, wc_Memory** io)
432{
433 WOLFSSL_MSG("Freeing fixed IO buffer");
434
435 /* check if fixed buffer was set */
436 if (*io == NULL) {
437 return 1;
438 }
439
440 if (heap == NULL) {
441 WOLFSSL_MSG("No heap to return fixed IO too");
442 }
443 else {
444 /* put IO buffer back into IO pool */
445 (*io)->next = heap->io;
446 heap->io = *io;
447 *io = NULL;
448 }
449
450 return 1;
451}
452
453
454int SetFixedIO(WOLFSSL_HEAP* heap, wc_Memory** io)
455{
456 WOLFSSL_MSG("Setting fixed IO for SSL");
457 if (heap == NULL) {
458 return MEMORY_E;
459 }
460
461 *io = heap->io;
462
463 if (*io != NULL) {
464 heap->io = (*io)->next;
465 (*io)->next = NULL;
466 }
467 else { /* failed to grab an IO buffer */
468 return 0;
469 }
470
471 return 1;
472}
473
474
475int wolfSSL_GetMemStats(WOLFSSL_HEAP* heap, WOLFSSL_MEM_STATS* stats)
476{
477 word32 i;
478 wc_Memory* pt;
479
480 XMEMSET(stats, 0, sizeof(WOLFSSL_MEM_STATS));
481
482 stats->totalAlloc = heap->alloc;
483 stats->totalFr = heap->frAlc;
484 stats->curAlloc = stats->totalAlloc - stats->totalFr;
485 stats->maxHa = heap->maxHa;
486 stats->maxIO = heap->maxIO;
487 for (i = 0; i < WOLFMEM_MAX_BUCKETS; i++) {
488 stats->blockSz[i] = heap->sizeList[i];
489 for (pt = heap->ava[i]; pt != NULL; pt = pt->next) {
490 stats->avaBlock[i] += 1;
491 }
492 }
493
494 for (pt = heap->io; pt != NULL; pt = pt->next) {
495 stats->avaIO++;
496 }
497
498 stats->flag = heap->flag; /* flag used */
499
500 return 1;
501}
502
503
504#ifdef WOLFSSL_DEBUG_MEMORY
505void* wolfSSL_Malloc(size_t size, void* heap, int type, const char* func, unsigned int line)
506#else
507void* wolfSSL_Malloc(size_t size, void* heap, int type)
508#endif
509{
510 void* res = 0;
511 wc_Memory* pt = NULL;
512 int i;
513
514 /* check for testing heap hint was set */
515#ifdef WOLFSSL_HEAP_TEST
516 if (heap == (void*)WOLFSSL_HEAP_TEST) {
517 return malloc(size);
518 }
519#endif
520
521 /* if no heap hint then use dynamic memory*/
522 if (heap == NULL) {
523 #ifdef WOLFSSL_HEAP_TEST
524 /* allow using malloc for creating ctx and method */
525 if (type == DYNAMIC_TYPE_CTX || type == DYNAMIC_TYPE_METHOD ||
526 type == DYNAMIC_TYPE_CERT_MANAGER) {
527 WOLFSSL_MSG("ERROR allowing null heap hint for ctx/method\n");
528 res = malloc(size);
529 }
530 else {
531 WOLFSSL_MSG("ERROR null heap hint passed into XMALLOC\n");
532 res = NULL;
533 }
534 #else
535 #ifndef WOLFSSL_NO_MALLOC
536 res = malloc(size);
537 #else
538 WOLFSSL_MSG("No heap hint found to use and no malloc");
539 #ifdef WOLFSSL_DEBUG_MEMORY
540 printf("ERROR: at %s:%d\n", func, line);
541 #endif
542 #endif /* WOLFSSL_NO_MALLOC */
543 #endif /* WOLFSSL_HEAP_TEST */
544 }
545 else {
546 WOLFSSL_HEAP_HINT* hint = (WOLFSSL_HEAP_HINT*)heap;
547 WOLFSSL_HEAP* mem = hint->memory;
548
549 if (wc_LockMutex(&(mem->memory_mutex)) != 0) {
550 WOLFSSL_MSG("Bad memory_mutex lock");
551 return NULL;
552 }
553
554 /* case of using fixed IO buffers */
555 if (mem->flag & WOLFMEM_IO_POOL_FIXED &&
556 (type == DYNAMIC_TYPE_OUT_BUFFER ||
557 type == DYNAMIC_TYPE_IN_BUFFER)) {
558 if (type == DYNAMIC_TYPE_OUT_BUFFER) {
559 pt = hint->outBuf;
560 }
561 if (type == DYNAMIC_TYPE_IN_BUFFER) {
562 pt = hint->inBuf;
563 }
564 }
565 else {
566 /* check if using IO pool flag */
567 if (mem->flag & WOLFMEM_IO_POOL &&
568 (type == DYNAMIC_TYPE_OUT_BUFFER ||
569 type == DYNAMIC_TYPE_IN_BUFFER)) {
570 if (mem->io != NULL) {
571 pt = mem->io;
572 mem->io = pt->next;
573 }
574 }
575
576 /* general static memory */
577 if (pt == NULL) {
578 for (i = 0; i < WOLFMEM_MAX_BUCKETS; i++) {
579 if ((word32)size < mem->sizeList[i]) {
580 if (mem->ava[i] != NULL) {
581 pt = mem->ava[i];
582 mem->ava[i] = pt->next;
583 break;
584 }
585 }
586 }
587 }
588 }
589
590 if (pt != NULL) {
591 mem->inUse += pt->sz;
592 mem->alloc += 1;
593 res = pt->buffer;
594
595 #ifdef WOLFSSL_DEBUG_MEMORY
596 printf("Alloc: %p -> %u at %s:%d\n", pt->buffer, pt->sz, func, line);
597 #endif
598
599 /* keep track of connection statistics if flag is set */
600 if (mem->flag & WOLFMEM_TRACK_STATS) {
601 WOLFSSL_MEM_CONN_STATS* stats = hint->stats;
602 if (stats != NULL) {
603 stats->curMem += pt->sz;
604 if (stats->peakMem < stats->curMem) {
605 stats->peakMem = stats->curMem;
606 }
607 stats->curAlloc++;
608 if (stats->peakAlloc < stats->curAlloc) {
609 stats->peakAlloc = stats->curAlloc;
610 }
611 stats->totalAlloc++;
612 }
613 }
614 }
615 else {
616 WOLFSSL_MSG("ERROR ran out of static memory");
617 #ifdef WOLFSSL_DEBUG_MEMORY
618 printf("Looking for %lu bytes at %s:%d\n", size, func, line);
619 #endif
620 }
621
622 wc_UnLockMutex(&(mem->memory_mutex));
623 }
624
625 #ifdef WOLFSSL_MALLOC_CHECK
626 if ((wolfssl_word)res % WOLFSSL_STATIC_ALIGN) {
627 WOLFSSL_MSG("ERROR memory is not alligned");
628 res = NULL;
629 }
630 #endif
631
632
633 (void)i;
634 (void)pt;
635 (void)type;
636
637 return res;
638}
639
640
641#ifdef WOLFSSL_DEBUG_MEMORY
642void wolfSSL_Free(void *ptr, void* heap, int type, const char* func, unsigned int line)
643#else
644void wolfSSL_Free(void *ptr, void* heap, int type)
645#endif
646{
647 int i;
648 wc_Memory* pt;
649
650 if (ptr) {
651 /* check for testing heap hint was set */
652 #ifdef WOLFSSL_HEAP_TEST
653 if (heap == (void*)WOLFSSL_HEAP_TEST) {
654 return free(ptr);
655 }
656 #endif
657
658 if (heap == NULL) {
659 #ifdef WOLFSSL_HEAP_TEST
660 /* allow using malloc for creating ctx and method */
661 if (type == DYNAMIC_TYPE_CTX || type == DYNAMIC_TYPE_METHOD ||
662 type == DYNAMIC_TYPE_CERT_MANAGER) {
663 WOLFSSL_MSG("ERROR allowing null heap hint for ctx/method\n");
664 }
665 else {
666 WOLFSSL_MSG("ERROR null heap hint passed into XFREE\n");
667 }
668 #endif
669 #ifndef WOLFSSL_NO_MALLOC
670 free(ptr);
671 #else
672 WOLFSSL_MSG("Error trying to call free when turned off");
673 #endif /* WOLFSSL_NO_MALLOC */
674 }
675 else {
676 WOLFSSL_HEAP_HINT* hint = (WOLFSSL_HEAP_HINT*)heap;
677 WOLFSSL_HEAP* mem = hint->memory;
678 word32 padSz = -(int)sizeof(wc_Memory) & (WOLFSSL_STATIC_ALIGN - 1);
679
680 /* get memory struct and add it to available list */
681 pt = (wc_Memory*)((byte*)ptr - sizeof(wc_Memory) - padSz);
682 if (wc_LockMutex(&(mem->memory_mutex)) != 0) {
683 WOLFSSL_MSG("Bad memory_mutex lock");
684 return;
685 }
686
687 /* case of using fixed IO buffers */
688 if (mem->flag & WOLFMEM_IO_POOL_FIXED &&
689 (type == DYNAMIC_TYPE_OUT_BUFFER ||
690 type == DYNAMIC_TYPE_IN_BUFFER)) {
691 /* fixed IO pools are free'd at the end of SSL lifetime
692 using FreeFixedIO(WOLFSSL_HEAP* heap, wc_Memory** io) */
693 }
694 else if (mem->flag & WOLFMEM_IO_POOL && pt->sz == WOLFMEM_IO_SZ &&
695 (type == DYNAMIC_TYPE_OUT_BUFFER ||
696 type == DYNAMIC_TYPE_IN_BUFFER)) {
697 pt->next = mem->io;
698 mem->io = pt;
699 }
700 else { /* general memory free */
701 for (i = 0; i < WOLFMEM_MAX_BUCKETS; i++) {
702 if (pt->sz == mem->sizeList[i]) {
703 pt->next = mem->ava[i];
704 mem->ava[i] = pt;
705 break;
706 }
707 }
708 }
709 mem->inUse -= pt->sz;
710 mem->frAlc += 1;
711
712 #ifdef WOLFSSL_DEBUG_MEMORY
713 printf("Free: %p -> %u at %s:%d\n", pt->buffer, pt->sz, func, line);
714 #endif
715
716 /* keep track of connection statistics if flag is set */
717 if (mem->flag & WOLFMEM_TRACK_STATS) {
718 WOLFSSL_MEM_CONN_STATS* stats = hint->stats;
719 if (stats != NULL) {
720 /* avoid under flow */
721 if (stats->curMem > pt->sz) {
722 stats->curMem -= pt->sz;
723 }
724 else {
725 stats->curMem = 0;
726 }
727
728 if (stats->curAlloc > 0) {
729 stats->curAlloc--;
730 }
731 stats->totalFr++;
732 }
733 }
734 wc_UnLockMutex(&(mem->memory_mutex));
735 }
736 }
737
738 (void)i;
739 (void)pt;
740 (void)type;
741}
742
743#ifdef WOLFSSL_DEBUG_MEMORY
744void* wolfSSL_Realloc(void *ptr, size_t size, void* heap, int type, const char* func, unsigned int line)
745#else
746void* wolfSSL_Realloc(void *ptr, size_t size, void* heap, int type)
747#endif
748{
749 void* res = 0;
750 wc_Memory* pt = NULL;
751 word32 prvSz;
752 int i;
753
754 /* check for testing heap hint was set */
755#ifdef WOLFSSL_HEAP_TEST
756 if (heap == (void*)WOLFSSL_HEAP_TEST) {
757 return realloc(ptr, size);
758 }
759#endif
760
761 if (heap == NULL) {
762 #ifdef WOLFSSL_HEAP_TEST
763 WOLFSSL_MSG("ERROR null heap hint passed in to XREALLOC\n");
764 #endif
765 #ifndef WOLFSSL_NO_MALLOC
766 res = realloc(ptr, size);
767 #else
768 WOLFSSL_MSG("NO heap found to use for realloc");
769 #endif /* WOLFSSL_NO_MALLOC */
770 }
771 else {
772 WOLFSSL_HEAP_HINT* hint = (WOLFSSL_HEAP_HINT*)heap;
773 WOLFSSL_HEAP* mem = hint->memory;
774 word32 padSz = -(int)sizeof(wc_Memory) & (WOLFSSL_STATIC_ALIGN - 1);
775
776 if (wc_LockMutex(&(mem->memory_mutex)) != 0) {
777 WOLFSSL_MSG("Bad memory_mutex lock");
778 return NULL;
779 }
780
781 /* case of using fixed IO buffers or IO pool */
782 if (((mem->flag & WOLFMEM_IO_POOL)||(mem->flag & WOLFMEM_IO_POOL_FIXED))
783 && (type == DYNAMIC_TYPE_OUT_BUFFER ||
784 type == DYNAMIC_TYPE_IN_BUFFER)) {
785 /* no realloc, is fixed size */
786 pt = (wc_Memory*)((byte*)ptr - padSz - sizeof(wc_Memory));
787 if (pt->sz < size) {
788 WOLFSSL_MSG("Error IO memory was not large enough");
789 res = NULL; /* return NULL in error case */
790 }
791 res = pt->buffer;
792 }
793 else {
794 /* general memory */
795 for (i = 0; i < WOLFMEM_MAX_BUCKETS; i++) {
796 if ((word32)size < mem->sizeList[i]) {
797 if (mem->ava[i] != NULL) {
798 pt = mem->ava[i];
799 mem->ava[i] = pt->next;
800 break;
801 }
802 }
803 }
804
805 if (pt != NULL && res == NULL) {
806 res = pt->buffer;
807
808 /* copy over original information and free ptr */
809 prvSz = ((wc_Memory*)((byte*)ptr - padSz -
810 sizeof(wc_Memory)))->sz;
811 prvSz = (prvSz > pt->sz)? pt->sz: prvSz;
812 XMEMCPY(pt->buffer, ptr, prvSz);
813 mem->inUse += pt->sz;
814 mem->alloc += 1;
815
816 /* free memory that was previously being used */
817 wc_UnLockMutex(&(mem->memory_mutex));
818 wolfSSL_Free(ptr, heap, type
819 #ifdef WOLFSSL_DEBUG_MEMORY
820 , func, line
821 #endif
822 );
823 if (wc_LockMutex(&(mem->memory_mutex)) != 0) {
824 WOLFSSL_MSG("Bad memory_mutex lock");
825 return NULL;
826 }
827 }
828 }
829 wc_UnLockMutex(&(mem->memory_mutex));
830 }
831
832 #ifdef WOLFSSL_MALLOC_CHECK
833 if ((wolfssl_word)res % WOLFSSL_STATIC_ALIGN) {
834 WOLFSSL_MSG("ERROR memory is not alligned");
835 res = NULL;
836 }
837 #endif
838
839 (void)i;
840 (void)pt;
841 (void)type;
842
843 return res;
844}
845#endif /* WOLFSSL_STATIC_MEMORY */
846
847#endif /* USE_WOLFSSL_MEMORY */
848
849
850#ifdef HAVE_IO_POOL
851
852/* Example for user io pool, shared build may need definitions in lib proper */
853
854#include <wolfssl/wolfcrypt/types.h>
855#include <stdlib.h>
856
857#ifndef HAVE_THREAD_LS
858 #error "Oops, simple I/O pool example needs thread local storage"
859#endif
860
861
862/* allow simple per thread in and out pools */
863/* use 17k size since max record size is 16k plus overhead */
864static THREAD_LS_T byte pool_in[17*1024];
865static THREAD_LS_T byte pool_out[17*1024];
866
867
868void* XMALLOC(size_t n, void* heap, int type)
869{
870 (void)heap;
871
872 if (type == DYNAMIC_TYPE_IN_BUFFER) {
873 if (n < sizeof(pool_in))
874 return pool_in;
875 else
876 return NULL;
877 }
878
879 if (type == DYNAMIC_TYPE_OUT_BUFFER) {
880 if (n < sizeof(pool_out))
881 return pool_out;
882 else
883 return NULL;
884 }
885
886 return malloc(n);
887}
888
889void* XREALLOC(void *p, size_t n, void* heap, int type)
890{
891 (void)heap;
892
893 if (type == DYNAMIC_TYPE_IN_BUFFER) {
894 if (n < sizeof(pool_in))
895 return pool_in;
896 else
897 return NULL;
898 }
899
900 if (type == DYNAMIC_TYPE_OUT_BUFFER) {
901 if (n < sizeof(pool_out))
902 return pool_out;
903 else
904 return NULL;
905 }
906
907 return realloc(p, n);
908}
909
910void XFREE(void *p, void* heap, int type)
911{
912 (void)heap;
913
914 if (type == DYNAMIC_TYPE_IN_BUFFER)
915 return; /* do nothing, static pool */
916
917 if (type == DYNAMIC_TYPE_OUT_BUFFER)
918 return; /* do nothing, static pool */
919
920 free(p);
921}
922
923#endif /* HAVE_IO_POOL */
924
Note: See TracBrowser for help on using the repository browser.