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)
81 #if defined(POLARSSL_THREADING_C)
82 threading_mutex_t mutex;
87 static buffer_alloc_ctx heap;
89 #if defined(POLARSSL_MEMORY_DEBUG)
90 static void debug_header( memory_header *hdr )
92 #if defined(POLARSSL_MEMORY_BACKTRACE)
96 fprintf( stderr,
"HDR: PTR(%10u), PREV(%10u), NEXT(%10u), ALLOC(%u), SIZE(%10u)\n",
97 (
size_t) hdr, (
size_t) hdr->prev, (
size_t) hdr->next,
98 hdr->alloc, hdr->size );
99 fprintf( stderr,
" FPREV(%10u), FNEXT(%10u)\n",
100 (
size_t) hdr->prev_free, (
size_t) hdr->next_free );
102 #if defined(POLARSSL_MEMORY_BACKTRACE)
103 fprintf( stderr,
"TRACE: \n" );
104 for( i = 0; i < hdr->trace_count; i++ )
105 fprintf( stderr,
"%s\n", hdr->trace[i] );
106 fprintf( stderr,
"\n" );
110 static void debug_chain()
112 memory_header *cur = heap.first;
114 fprintf( stderr,
"\nBlock list\n" );
121 fprintf( stderr,
"Free list\n" );
122 cur = heap.first_free;
127 cur = cur->next_free;
132 static int verify_header( memory_header *hdr )
134 if( hdr->magic1 != MAGIC1 )
136 #if defined(POLARSSL_MEMORY_DEBUG)
137 fprintf( stderr,
"FATAL: MAGIC1 mismatch\n" );
142 if( hdr->magic2 != MAGIC2 )
144 #if defined(POLARSSL_MEMORY_DEBUG)
145 fprintf( stderr,
"FATAL: MAGIC2 mismatch\n" );
152 #if defined(POLARSSL_MEMORY_DEBUG)
153 fprintf( stderr,
"FATAL: alloc has illegal value\n" );
158 if( hdr->prev != NULL && hdr->prev == hdr->next )
160 #if defined(POLARSSL_MEMORY_DEBUG)
161 fprintf( stderr,
"FATAL: prev == next\n" );
166 if( hdr->prev_free != NULL && hdr->prev_free == hdr->next_free )
168 #if defined(POLARSSL_MEMORY_DEBUG)
169 fprintf( stderr,
"FATAL: prev_free == next_free\n" );
177 static int verify_chain()
179 memory_header *prv = heap.first, *cur = heap.first->next;
181 if( verify_header( heap.first ) != 0 )
183 #if defined(POLARSSL_MEMORY_DEBUG)
184 fprintf( stderr,
"FATAL: verification of first header failed\n" );
189 if( heap.first->prev != NULL )
191 #if defined(POLARSSL_MEMORY_DEBUG)
192 fprintf( stderr,
"FATAL: verification failed: first->prev != NULL\n" );
199 if( verify_header( cur ) != 0 )
201 #if defined(POLARSSL_MEMORY_DEBUG)
202 fprintf( stderr,
"FATAL: verification of header failed\n" );
207 if( cur->prev != prv )
209 #if defined(POLARSSL_MEMORY_DEBUG)
210 fprintf( stderr,
"FATAL: verification failed: cur->prev != prv\n" );
222 static void *buffer_alloc_malloc(
size_t len )
224 memory_header *
new, *cur = heap.first_free;
226 #if defined(POLARSSL_MEMORY_BACKTRACE)
227 void *trace_buffer[MAX_BT];
231 if( heap.buf == NULL || heap.first == NULL )
244 if( cur->size >= len )
247 cur = cur->next_free;
253 if( cur->alloc != 0 )
255 #if defined(POLARSSL_MEMORY_DEBUG)
256 fprintf( stderr,
"FATAL: block in free_list but allocated data\n" );
261 #if defined(POLARSSL_MEMORY_DEBUG)
267 if( cur->size - len <
sizeof(memory_header) + POLARSSL_MEMORY_ALIGN_MULTIPLE )
273 if( cur->prev_free != NULL )
274 cur->prev_free->next_free = cur->next_free;
276 heap.first_free = cur->next_free;
278 if( cur->next_free != NULL )
279 cur->next_free->prev_free = cur->prev_free;
281 cur->prev_free = NULL;
282 cur->next_free = NULL;
284 #if defined(POLARSSL_MEMORY_DEBUG)
285 heap.total_used += cur->size;
286 if( heap.total_used > heap.maximum_used)
287 heap.maximum_used = heap.total_used;
289 #if defined(POLARSSL_MEMORY_BACKTRACE)
290 trace_cnt = backtrace( trace_buffer, MAX_BT );
291 cur->trace = backtrace_symbols( trace_buffer, trace_cnt );
292 cur->trace_count = trace_cnt;
298 return ( (
unsigned char *) cur ) +
sizeof(memory_header);
301 p = ( (
unsigned char *) cur ) +
sizeof(memory_header) + len;
302 new = (memory_header *) p;
304 new->size = cur->size - len -
sizeof(memory_header);
307 new->next = cur->next;
308 #if defined(POLARSSL_MEMORY_BACKTRACE)
310 new->trace_count = 0;
312 new->magic1 = MAGIC1;
313 new->magic2 = MAGIC2;
315 if( new->next != NULL )
316 new->next->prev =
new;
320 new->prev_free = cur->prev_free;
321 new->next_free = cur->next_free;
322 if( new->prev_free != NULL )
323 new->prev_free->next_free =
new;
325 heap.first_free =
new;
327 if( new->next_free != NULL )
328 new->next_free->prev_free =
new;
333 cur->prev_free = NULL;
334 cur->next_free = NULL;
336 #if defined(POLARSSL_MEMORY_DEBUG)
338 heap.total_used += cur->size;
339 if( heap.total_used > heap.maximum_used)
340 heap.maximum_used = heap.total_used;
342 #if defined(POLARSSL_MEMORY_BACKTRACE)
343 trace_cnt = backtrace( trace_buffer, MAX_BT );
344 cur->trace = backtrace_symbols( trace_buffer, trace_cnt );
345 cur->trace_count = trace_cnt;
351 return ( (
unsigned char *) cur ) +
sizeof(memory_header);
354 static void buffer_alloc_free(
void *ptr )
356 memory_header *hdr, *old = NULL;
357 unsigned char *p = (
unsigned char *) ptr;
359 if( ptr == NULL || heap.buf == NULL || heap.first == NULL )
362 if( p < heap.buf || p > heap.buf + heap.len )
364 #if defined(POLARSSL_MEMORY_DEBUG)
365 fprintf( stderr,
"FATAL: polarssl_free() outside of managed space\n" );
370 p -=
sizeof(memory_header);
371 hdr = (memory_header *) p;
373 if( verify_header( hdr ) != 0 )
376 if( hdr->alloc != 1 )
378 #if defined(POLARSSL_MEMORY_DEBUG)
379 fprintf( stderr,
"FATAL: polarssl_free() on unallocated data\n" );
386 #if defined(POLARSSL_MEMORY_DEBUG)
388 heap.total_used -= hdr->size;
393 if( hdr->prev != NULL && hdr->prev->alloc == 0 )
395 #if defined(POLARSSL_MEMORY_DEBUG)
398 hdr->prev->size +=
sizeof(memory_header) + hdr->size;
399 hdr->prev->next = hdr->next;
403 if( hdr->next != NULL )
404 hdr->next->prev = hdr;
406 #if defined(POLARSSL_MEMORY_BACKTRACE)
409 memset( old, 0,
sizeof(memory_header) );
414 if( hdr->next != NULL && hdr->next->alloc == 0 )
416 #if defined(POLARSSL_MEMORY_DEBUG)
419 hdr->size +=
sizeof(memory_header) + hdr->next->size;
421 hdr->next = hdr->next->next;
423 if( hdr->prev_free != NULL || hdr->next_free != NULL )
425 if( hdr->prev_free != NULL )
426 hdr->prev_free->next_free = hdr->next_free;
428 heap.first_free = hdr->next_free;
430 if( hdr->next_free != NULL )
431 hdr->next_free->prev_free = hdr->prev_free;
434 hdr->prev_free = old->prev_free;
435 hdr->next_free = old->next_free;
437 if( hdr->prev_free != NULL )
438 hdr->prev_free->next_free = hdr;
440 heap.first_free = hdr;
442 if( hdr->next_free != NULL )
443 hdr->next_free->prev_free = hdr;
445 if( hdr->next != NULL )
446 hdr->next->prev = hdr;
448 #if defined(POLARSSL_MEMORY_BACKTRACE)
451 memset( old, 0,
sizeof(memory_header) );
459 hdr->next_free = heap.first_free;
460 heap.first_free->prev_free = hdr;
461 heap.first_free = hdr;
464 #if defined(POLARSSL_MEMORY_BACKTRACE)
466 hdr->trace_count = 0;
473 void memory_buffer_set_verify(
int verify )
475 heap.verify = verify;
478 int memory_buffer_alloc_verify()
480 return verify_chain();
483 #if defined(POLARSSL_MEMORY_DEBUG)
484 void memory_buffer_alloc_status()
487 "Current use: %u blocks / %u bytes, max: %u bytes, malloc / free: %u / %u\n",
488 heap.header_count, heap.total_used, heap.maximum_used,
489 heap.malloc_count, heap.free_count );
491 if( heap.first->next == NULL )
492 fprintf( stderr,
"All memory de-allocated in stack buffer\n" );
495 fprintf( stderr,
"Memory currently allocated:\n" );
501 #if defined(POLARSSL_THREADING_C)
502 static void *buffer_alloc_malloc_mutexed(
size_t len )
506 buf = buffer_alloc_malloc( len );
511 static void buffer_alloc_free_mutexed(
void *ptr )
514 buffer_alloc_free( ptr );
519 int memory_buffer_alloc_init(
unsigned char *buf,
size_t len )
521 memset( &heap, 0,
sizeof(buffer_alloc_ctx) );
522 memset( buf, 0, len );
524 #if defined(POLARSSL_THREADING_C)
536 heap.first = (memory_header *) buf;
537 heap.first->size = len -
sizeof(memory_header);
538 heap.first->magic1 = MAGIC1;
539 heap.first->magic2 = MAGIC2;
540 heap.first_free = heap.first;
544 void memory_buffer_alloc_free()
546 #if defined(POLARSSL_THREADING_C)
549 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)