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
56 static 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
64 typedef 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;
103 static buffer_alloc_ctx heap;
105 #if defined(POLARSSL_MEMORY_DEBUG)
106 static 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++ )
127 static void debug_chain()
129 memory_header *cur = heap.first;
139 cur = heap.first_free;
144 cur = cur->next_free;
149 static 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)
194 static 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" );
243 static 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) +
290 POLARSSL_MEMORY_ALIGN_MULTIPLE )
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) );
379 static 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)
511 void 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)
533 static void *buffer_alloc_malloc_mutexed(
size_t len )
537 buf = buffer_alloc_malloc( len );
542 static 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 );
563 if( (
size_t) buf % POLARSSL_MEMORY_ALIGN_MULTIPLE )
565 buf += POLARSSL_MEMORY_ALIGN_MULTIPLE
566 - (size_t) buf % POLARSSL_MEMORY_ALIGN_MULTIPLE;
567 len -= (size_t) buf % POLARSSL_MEMORY_ALIGN_MULTIPLE;
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) );