28 #if defined(POLARSSL_MEMORY_C) && defined(POLARSSL_MEMORY_BUFFER_ALLOC_C)
34 #if defined(POLARSSL_MEMORY_DEBUG)
36 #if defined(POLARSSL_MEMORY_BACKTRACE)
41 #if defined(POLARSSL_THREADING_C)
45 #define MAGIC1 0xFF00AA55
46 #define MAGIC2 0xEE119966
49 typedef struct _memory_header memory_header;
57 memory_header *prev_free;
58 memory_header *next_free;
59 #if defined(POLARSSL_MEMORY_BACKTRACE)
71 memory_header *first_free;
72 size_t current_alloc_size;
74 #if defined(POLARSSL_MEMORY_DEBUG)
80 size_t maximum_header_count;
82 #if defined(POLARSSL_THREADING_C)
83 threading_mutex_t mutex;
88 static buffer_alloc_ctx heap;
90 #if defined(POLARSSL_MEMORY_DEBUG)
91 static void debug_header( memory_header *hdr )
93 #if defined(POLARSSL_MEMORY_BACKTRACE)
97 fprintf( stderr,
"HDR: PTR(%10u), PREV(%10u), NEXT(%10u), ALLOC(%u), SIZE(%10u)\n",
98 (
size_t) hdr, (
size_t) hdr->prev, (
size_t) hdr->next,
99 hdr->alloc, hdr->size );
100 fprintf( stderr,
" FPREV(%10u), FNEXT(%10u)\n",
101 (
size_t) hdr->prev_free, (
size_t) hdr->next_free );
103 #if defined(POLARSSL_MEMORY_BACKTRACE)
104 fprintf( stderr,
"TRACE: \n" );
105 for( i = 0; i < hdr->trace_count; i++ )
106 fprintf( stderr,
"%s\n", hdr->trace[i] );
107 fprintf( stderr,
"\n" );
111 static void debug_chain()
113 memory_header *cur = heap.first;
115 fprintf( stderr,
"\nBlock list\n" );
122 fprintf( stderr,
"Free list\n" );
123 cur = heap.first_free;
128 cur = cur->next_free;
133 static int verify_header( memory_header *hdr )
135 if( hdr->magic1 != MAGIC1 )
137 #if defined(POLARSSL_MEMORY_DEBUG)
138 fprintf( stderr,
"FATAL: MAGIC1 mismatch\n" );
143 if( hdr->magic2 != MAGIC2 )
145 #if defined(POLARSSL_MEMORY_DEBUG)
146 fprintf( stderr,
"FATAL: MAGIC2 mismatch\n" );
153 #if defined(POLARSSL_MEMORY_DEBUG)
154 fprintf( stderr,
"FATAL: alloc has illegal value\n" );
159 if( hdr->prev != NULL && hdr->prev == hdr->next )
161 #if defined(POLARSSL_MEMORY_DEBUG)
162 fprintf( stderr,
"FATAL: prev == next\n" );
167 if( hdr->prev_free != NULL && hdr->prev_free == hdr->next_free )
169 #if defined(POLARSSL_MEMORY_DEBUG)
170 fprintf( stderr,
"FATAL: prev_free == next_free\n" );
178 static int verify_chain()
180 memory_header *prv = heap.first, *cur = heap.first->next;
182 if( verify_header( heap.first ) != 0 )
184 #if defined(POLARSSL_MEMORY_DEBUG)
185 fprintf( stderr,
"FATAL: verification of first header failed\n" );
190 if( heap.first->prev != NULL )
192 #if defined(POLARSSL_MEMORY_DEBUG)
193 fprintf( stderr,
"FATAL: verification failed: first->prev != NULL\n" );
200 if( verify_header( cur ) != 0 )
202 #if defined(POLARSSL_MEMORY_DEBUG)
203 fprintf( stderr,
"FATAL: verification of header failed\n" );
208 if( cur->prev != prv )
210 #if defined(POLARSSL_MEMORY_DEBUG)
211 fprintf( stderr,
"FATAL: verification failed: cur->prev != prv\n" );
223 static void *buffer_alloc_malloc(
size_t len )
225 memory_header *
new, *cur = heap.first_free;
227 #if defined(POLARSSL_MEMORY_BACKTRACE)
228 void *trace_buffer[MAX_BT];
232 if( heap.buf == NULL || heap.first == NULL )
245 if( cur->size >= len )
248 cur = cur->next_free;
254 if( cur->alloc != 0 )
256 #if defined(POLARSSL_MEMORY_DEBUG)
257 fprintf( stderr,
"FATAL: block in free_list but allocated data\n" );
262 #if defined(POLARSSL_MEMORY_DEBUG)
268 if( cur->size - len <
sizeof(memory_header) + POLARSSL_MEMORY_ALIGN_MULTIPLE )
274 if( cur->prev_free != NULL )
275 cur->prev_free->next_free = cur->next_free;
277 heap.first_free = cur->next_free;
279 if( cur->next_free != NULL )
280 cur->next_free->prev_free = cur->prev_free;
282 cur->prev_free = NULL;
283 cur->next_free = NULL;
285 #if defined(POLARSSL_MEMORY_DEBUG)
286 heap.total_used += cur->size;
287 if( heap.total_used > heap.maximum_used)
288 heap.maximum_used = heap.total_used;
290 #if defined(POLARSSL_MEMORY_BACKTRACE)
291 trace_cnt = backtrace( trace_buffer, MAX_BT );
292 cur->trace = backtrace_symbols( trace_buffer, trace_cnt );
293 cur->trace_count = trace_cnt;
299 return ( (
unsigned char *) cur ) +
sizeof(memory_header);
302 p = ( (
unsigned char *) cur ) +
sizeof(memory_header) + len;
303 new = (memory_header *) p;
305 new->size = cur->size - len -
sizeof(memory_header);
308 new->next = cur->next;
309 #if defined(POLARSSL_MEMORY_BACKTRACE)
311 new->trace_count = 0;
313 new->magic1 = MAGIC1;
314 new->magic2 = MAGIC2;
316 if( new->next != NULL )
317 new->next->prev =
new;
321 new->prev_free = cur->prev_free;
322 new->next_free = cur->next_free;
323 if( new->prev_free != NULL )
324 new->prev_free->next_free =
new;
326 heap.first_free =
new;
328 if( new->next_free != NULL )
329 new->next_free->prev_free =
new;
334 cur->prev_free = NULL;
335 cur->next_free = NULL;
337 #if defined(POLARSSL_MEMORY_DEBUG)
339 if( heap.header_count > heap.maximum_header_count )
340 heap.maximum_header_count = heap.header_count;
341 heap.total_used += cur->size;
342 if( heap.total_used > heap.maximum_used)
343 heap.maximum_used = heap.total_used;
345 #if defined(POLARSSL_MEMORY_BACKTRACE)
346 trace_cnt = backtrace( trace_buffer, MAX_BT );
347 cur->trace = backtrace_symbols( trace_buffer, trace_cnt );
348 cur->trace_count = trace_cnt;
354 return ( (
unsigned char *) cur ) +
sizeof(memory_header);
357 static void buffer_alloc_free(
void *ptr )
359 memory_header *hdr, *old = NULL;
360 unsigned char *p = (
unsigned char *) ptr;
362 if( ptr == NULL || heap.buf == NULL || heap.first == NULL )
365 if( p < heap.buf || p > heap.buf + heap.len )
367 #if defined(POLARSSL_MEMORY_DEBUG)
368 fprintf( stderr,
"FATAL: polarssl_free() outside of managed space\n" );
373 p -=
sizeof(memory_header);
374 hdr = (memory_header *) p;
376 if( verify_header( hdr ) != 0 )
379 if( hdr->alloc != 1 )
381 #if defined(POLARSSL_MEMORY_DEBUG)
382 fprintf( stderr,
"FATAL: polarssl_free() on unallocated data\n" );
389 #if defined(POLARSSL_MEMORY_DEBUG)
391 heap.total_used -= hdr->size;
396 if( hdr->prev != NULL && hdr->prev->alloc == 0 )
398 #if defined(POLARSSL_MEMORY_DEBUG)
401 hdr->prev->size +=
sizeof(memory_header) + hdr->size;
402 hdr->prev->next = hdr->next;
406 if( hdr->next != NULL )
407 hdr->next->prev = hdr;
409 #if defined(POLARSSL_MEMORY_BACKTRACE)
412 memset( old, 0,
sizeof(memory_header) );
417 if( hdr->next != NULL && hdr->next->alloc == 0 )
419 #if defined(POLARSSL_MEMORY_DEBUG)
422 hdr->size +=
sizeof(memory_header) + hdr->next->size;
424 hdr->next = hdr->next->next;
426 if( hdr->prev_free != NULL || hdr->next_free != NULL )
428 if( hdr->prev_free != NULL )
429 hdr->prev_free->next_free = hdr->next_free;
431 heap.first_free = hdr->next_free;
433 if( hdr->next_free != NULL )
434 hdr->next_free->prev_free = hdr->prev_free;
437 hdr->prev_free = old->prev_free;
438 hdr->next_free = old->next_free;
440 if( hdr->prev_free != NULL )
441 hdr->prev_free->next_free = hdr;
443 heap.first_free = hdr;
445 if( hdr->next_free != NULL )
446 hdr->next_free->prev_free = hdr;
448 if( hdr->next != NULL )
449 hdr->next->prev = hdr;
451 #if defined(POLARSSL_MEMORY_BACKTRACE)
454 memset( old, 0,
sizeof(memory_header) );
462 hdr->next_free = heap.first_free;
463 heap.first_free->prev_free = hdr;
464 heap.first_free = hdr;
467 #if defined(POLARSSL_MEMORY_BACKTRACE)
469 hdr->trace_count = 0;
476 void memory_buffer_set_verify(
int verify )
478 heap.verify = verify;
481 int memory_buffer_alloc_verify()
483 return verify_chain();
486 #if defined(POLARSSL_MEMORY_DEBUG)
487 void memory_buffer_alloc_status()
490 "Current use: %u blocks / %u bytes, max: %u blocks / %u bytes (total %u bytes), malloc / free: %u / %u\n",
491 heap.header_count, heap.total_used,
492 heap.maximum_header_count, heap.maximum_used,
493 heap.maximum_header_count *
sizeof( memory_header )
495 heap.malloc_count, heap.free_count );
497 if( heap.first->next == NULL )
498 fprintf( stderr,
"All memory de-allocated in stack buffer\n" );
501 fprintf( stderr,
"Memory currently allocated:\n" );
507 #if defined(POLARSSL_THREADING_C)
508 static void *buffer_alloc_malloc_mutexed(
size_t len )
512 buf = buffer_alloc_malloc( len );
517 static void buffer_alloc_free_mutexed(
void *ptr )
520 buffer_alloc_free( ptr );
525 int memory_buffer_alloc_init(
unsigned char *buf,
size_t len )
527 memset( &heap, 0,
sizeof(buffer_alloc_ctx) );
528 memset( buf, 0, len );
530 #if defined(POLARSSL_THREADING_C)
542 heap.first = (memory_header *) buf;
543 heap.first->size = len -
sizeof(memory_header);
544 heap.first->magic1 = MAGIC1;
545 heap.first->magic2 = MAGIC2;
546 heap.first_free = heap.first;
550 void memory_buffer_alloc_free()
552 #if defined(POLARSSL_THREADING_C)
555 memset( &heap, 0,
sizeof(buffer_alloc_ctx) );
int(* polarssl_mutex_lock)(threading_mutex_t *mutex)
void *(* polarssl_malloc)(size_t len)
Configuration options (set of defines)
#define POLARSSL_MEMORY_ALIGN_MULTIPLE
Align on multiples of this value.
Threading abstraction layer.
void(* polarssl_free)(void *ptr)
#define MEMORY_VERIFY_ALLOC
int(* polarssl_mutex_free)(threading_mutex_t *mutex)
int(* polarssl_mutex_unlock)(threading_mutex_t *mutex)
#define MEMORY_VERIFY_FREE
int(* polarssl_mutex_init)(threading_mutex_t *mutex)