26#if !defined(POLARSSL_CONFIG_FILE)
29#include POLARSSL_CONFIG_FILE
32#if defined(POLARSSL_MEMORY_BUFFER_ALLOC_C)
38#if defined(POLARSSL_MEMORY_DEBUG)
41#if defined(POLARSSL_MEMORY_BACKTRACE)
45#if defined(POLARSSL_THREADING_C)
49#if defined(POLARSSL_PLATFORM_C)
52#define polarssl_fprintf fprintf
56static void polarssl_zeroize(
void *v,
size_t n ) {
57 volatile unsigned char *p = v;
while( n-- ) *p++ = 0;
60#define MAGIC1 0xFF00AA55
61#define MAGIC2 0xEE119966
64typedef struct _memory_header memory_header;
72 memory_header *prev_free;
73 memory_header *next_free;
74#if defined(POLARSSL_MEMORY_BACKTRACE)
86 memory_header *first_free;
87 size_t current_alloc_size;
89#if defined(POLARSSL_MEMORY_DEBUG)
95 size_t maximum_header_count;
97#if defined(POLARSSL_THREADING_C)
98 threading_mutex_t mutex;
103static buffer_alloc_ctx heap;
105#if defined(POLARSSL_MEMORY_DEBUG)
106static void debug_header( memory_header *hdr )
108#if defined(POLARSSL_MEMORY_BACKTRACE)
113 "ALLOC(%zu), SIZE(%10zu)\n",
114 (
size_t) hdr, (
size_t) hdr->prev, (
size_t) hdr->next,
115 hdr->alloc, hdr->size );
117 (
size_t) hdr->prev_free, (
size_t) hdr->next_free );
119#if defined(POLARSSL_MEMORY_BACKTRACE)
121 for( i = 0; i < hdr->trace_count; i++ )
127static void debug_chain()
129 memory_header *cur = heap.first;
139 cur = heap.first_free;
144 cur = cur->next_free;
149static int verify_header( memory_header *hdr )
151 if( hdr->magic1 != MAGIC1 )
153#if defined(POLARSSL_MEMORY_DEBUG)
159 if( hdr->magic2 != MAGIC2 )
161#if defined(POLARSSL_MEMORY_DEBUG)
169#if defined(POLARSSL_MEMORY_DEBUG)
175 if( hdr->prev != NULL && hdr->prev == hdr->next )
177#if defined(POLARSSL_MEMORY_DEBUG)
183 if( hdr->prev_free != NULL && hdr->prev_free == hdr->next_free )
185#if defined(POLARSSL_MEMORY_DEBUG)
194static int verify_chain()
196 memory_header *prv = heap.first, *cur = heap.first->next;
198 if( verify_header( heap.first ) != 0 )
200#if defined(POLARSSL_MEMORY_DEBUG)
207 if( heap.first->prev != NULL )
209#if defined(POLARSSL_MEMORY_DEBUG)
211 "first->prev != NULL\n" );
218 if( verify_header( cur ) != 0 )
220#if defined(POLARSSL_MEMORY_DEBUG)
227 if( cur->prev != prv )
229#if defined(POLARSSL_MEMORY_DEBUG)
231 "cur->prev != prv\n" );
243static void *buffer_alloc_malloc(
size_t len )
245 memory_header *
new, *cur = heap.first_free;
247#if defined(POLARSSL_MEMORY_BACKTRACE)
248 void *trace_buffer[MAX_BT];
252 if( heap.buf == NULL || heap.first == NULL )
265 if( cur->size >= len )
268 cur = cur->next_free;
274 if( cur->alloc != 0 )
276#if defined(POLARSSL_MEMORY_DEBUG)
283#if defined(POLARSSL_MEMORY_DEBUG)
289 if( cur->size - len <
sizeof(memory_header) +
296 if( cur->prev_free != NULL )
297 cur->prev_free->next_free = cur->next_free;
299 heap.first_free = cur->next_free;
301 if( cur->next_free != NULL )
302 cur->next_free->prev_free = cur->prev_free;
304 cur->prev_free = NULL;
305 cur->next_free = NULL;
307#if defined(POLARSSL_MEMORY_DEBUG)
308 heap.total_used += cur->size;
309 if( heap.total_used > heap.maximum_used )
310 heap.maximum_used = heap.total_used;
312#if defined(POLARSSL_MEMORY_BACKTRACE)
313 trace_cnt = backtrace( trace_buffer, MAX_BT );
314 cur->trace = backtrace_symbols( trace_buffer, trace_cnt );
315 cur->trace_count = trace_cnt;
321 return( ( (
unsigned char *) cur ) +
sizeof(memory_header) );
324 p = ( (
unsigned char *) cur ) +
sizeof(memory_header) + len;
325 new = (memory_header *) p;
327 new->size = cur->size - len -
sizeof(memory_header);
330 new->next = cur->next;
331#if defined(POLARSSL_MEMORY_BACKTRACE)
333 new->trace_count = 0;
335 new->magic1 = MAGIC1;
336 new->magic2 = MAGIC2;
338 if( new->next != NULL )
339 new->next->prev =
new;
343 new->prev_free = cur->prev_free;
344 new->next_free = cur->next_free;
345 if( new->prev_free != NULL )
346 new->prev_free->next_free =
new;
348 heap.first_free =
new;
350 if( new->next_free != NULL )
351 new->next_free->prev_free =
new;
356 cur->prev_free = NULL;
357 cur->next_free = NULL;
359#if defined(POLARSSL_MEMORY_DEBUG)
361 if( heap.header_count > heap.maximum_header_count )
362 heap.maximum_header_count = heap.header_count;
363 heap.total_used += cur->size;
364 if( heap.total_used > heap.maximum_used )
365 heap.maximum_used = heap.total_used;
367#if defined(POLARSSL_MEMORY_BACKTRACE)
368 trace_cnt = backtrace( trace_buffer, MAX_BT );
369 cur->trace = backtrace_symbols( trace_buffer, trace_cnt );
370 cur->trace_count = trace_cnt;
376 return( ( (
unsigned char *) cur ) +
sizeof(memory_header) );
379static void buffer_alloc_free(
void *ptr )
381 memory_header *hdr, *old = NULL;
382 unsigned char *p = (
unsigned char *) ptr;
384 if( ptr == NULL || heap.buf == NULL || heap.first == NULL )
387 if( p < heap.buf || p > heap.buf + heap.len )
389#if defined(POLARSSL_MEMORY_DEBUG)
396 p -=
sizeof(memory_header);
397 hdr = (memory_header *) p;
399 if( verify_header( hdr ) != 0 )
402 if( hdr->alloc != 1 )
404#if defined(POLARSSL_MEMORY_DEBUG)
413#if defined(POLARSSL_MEMORY_DEBUG)
415 heap.total_used -= hdr->size;
420 if( hdr->prev != NULL && hdr->prev->alloc == 0 )
422#if defined(POLARSSL_MEMORY_DEBUG)
425 hdr->prev->size +=
sizeof(memory_header) + hdr->size;
426 hdr->prev->next = hdr->next;
430 if( hdr->next != NULL )
431 hdr->next->prev = hdr;
433#if defined(POLARSSL_MEMORY_BACKTRACE)
436 memset( old, 0,
sizeof(memory_header) );
441 if( hdr->next != NULL && hdr->next->alloc == 0 )
443#if defined(POLARSSL_MEMORY_DEBUG)
446 hdr->size +=
sizeof(memory_header) + hdr->next->size;
448 hdr->next = hdr->next->next;
450 if( hdr->prev_free != NULL || hdr->next_free != NULL )
452 if( hdr->prev_free != NULL )
453 hdr->prev_free->next_free = hdr->next_free;
455 heap.first_free = hdr->next_free;
457 if( hdr->next_free != NULL )
458 hdr->next_free->prev_free = hdr->prev_free;
461 hdr->prev_free = old->prev_free;
462 hdr->next_free = old->next_free;
464 if( hdr->prev_free != NULL )
465 hdr->prev_free->next_free = hdr;
467 heap.first_free = hdr;
469 if( hdr->next_free != NULL )
470 hdr->next_free->prev_free = hdr;
472 if( hdr->next != NULL )
473 hdr->next->prev = hdr;
475#if defined(POLARSSL_MEMORY_BACKTRACE)
478 memset( old, 0,
sizeof(memory_header) );
486 hdr->next_free = heap.first_free;
487 heap.first_free->prev_free = hdr;
488 heap.first_free = hdr;
491#if defined(POLARSSL_MEMORY_BACKTRACE)
493 hdr->trace_count = 0;
502 heap.verify = verify;
507 return verify_chain();
510#if defined(POLARSSL_MEMORY_DEBUG)
511void memory_buffer_alloc_status()
514 "Current use: %zu blocks / %zu bytes, max: %zu blocks / "
515 "%zu bytes (total %zu bytes), malloc / free: %zu / %zu\n",
516 heap.header_count, heap.total_used,
517 heap.maximum_header_count, heap.maximum_used,
518 heap.maximum_header_count *
sizeof( memory_header )
520 heap.malloc_count, heap.free_count );
522 if( heap.first->next == NULL )
532#if defined(POLARSSL_THREADING_C)
533static void *buffer_alloc_malloc_mutexed(
size_t len )
537 buf = buffer_alloc_malloc( len );
542static void buffer_alloc_free_mutexed(
void *ptr )
545 buffer_alloc_free( ptr );
552 memset( &heap, 0,
sizeof(buffer_alloc_ctx) );
553 memset( buf, 0, len );
555#if defined(POLARSSL_THREADING_C)
557 platform_set_malloc_free( buffer_alloc_malloc_mutexed,
558 buffer_alloc_free_mutexed );
560 platform_set_malloc_free( buffer_alloc_malloc, buffer_alloc_free );
573 heap.first = (memory_header *) buf;
574 heap.first->size = len -
sizeof(memory_header);
575 heap.first->magic1 = MAGIC1;
576 heap.first->magic2 = MAGIC2;
577 heap.first_free = heap.first;
583#if defined(POLARSSL_THREADING_C)
586 polarssl_zeroize( &heap,
sizeof(buffer_alloc_ctx) );
Configuration options (set of defines)
Buffer-based memory allocator.
void memory_buffer_set_verify(int verify)
Determine when the allocator should automatically verify the state of the entire chain of headers / m...
#define MEMORY_VERIFY_ALLOC
#define POLARSSL_MEMORY_ALIGN_MULTIPLE
Align on multiples of this value.
void memory_buffer_alloc_free(void)
Free the mutex for thread-safety and clear remaining memory.
int memory_buffer_alloc_verify(void)
Verifies that all headers in the memory buffer are correct and contain sane values.
#define MEMORY_VERIFY_FREE
int memory_buffer_alloc_init(unsigned char *buf, size_t len)
Initialize use of stack-based memory allocator.
Threading abstraction layer.
int(* polarssl_mutex_init)(threading_mutex_t *mutex)
int(* polarssl_mutex_free)(threading_mutex_t *mutex)
int(* polarssl_mutex_unlock)(threading_mutex_t *mutex)
int(* polarssl_mutex_lock)(threading_mutex_t *mutex)