47#if !defined(MBEDTLS_CONFIG_FILE)
50#include MBEDTLS_CONFIG_FILE
53#if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C)
63#if defined(MBEDTLS_MEMORY_BACKTRACE)
67#if defined(MBEDTLS_THREADING_C)
71#define MAGIC1 0xFF00AA55
72#define MAGIC2 0xEE119966
75typedef struct _memory_header memory_header;
83 memory_header *prev_free;
84 memory_header *next_free;
85#if defined(MBEDTLS_MEMORY_BACKTRACE)
97 memory_header *first_free;
99#if defined(MBEDTLS_MEMORY_DEBUG)
105 size_t maximum_header_count;
107#if defined(MBEDTLS_THREADING_C)
108 mbedtls_threading_mutex_t
mutex;
113static buffer_alloc_ctx
heap;
115#if defined(MBEDTLS_MEMORY_DEBUG)
116static void debug_header( memory_header *
hdr )
118#if defined(MBEDTLS_MEMORY_BACKTRACE)
123 "ALLOC(%zu), SIZE(%10zu)\n",
124 (
size_t)
hdr, (
size_t)
hdr->prev, (
size_t)
hdr->next,
127 (
size_t)
hdr->prev_free, (
size_t)
hdr->next_free );
129#if defined(MBEDTLS_MEMORY_BACKTRACE)
131 for(
i = 0;
i <
hdr->trace_count;
i++ )
137static void debug_chain(
void )
139 memory_header *
cur =
heap.first;
159static int verify_header( memory_header *
hdr )
161 if(
hdr->magic1 != MAGIC1 )
163#if defined(MBEDTLS_MEMORY_DEBUG)
169 if(
hdr->magic2 != MAGIC2 )
171#if defined(MBEDTLS_MEMORY_DEBUG)
179#if defined(MBEDTLS_MEMORY_DEBUG)
187#if defined(MBEDTLS_MEMORY_DEBUG)
193 if(
hdr->prev_free !=
NULL &&
hdr->prev_free ==
hdr->next_free )
195#if defined(MBEDTLS_MEMORY_DEBUG)
204static int verify_chain(
void )
206 memory_header *prv =
heap.first, *
cur;
208 if( prv ==
NULL || verify_header( prv ) != 0 )
210#if defined(MBEDTLS_MEMORY_DEBUG)
219#if defined(MBEDTLS_MEMORY_DEBUG)
221 "first->prev != NULL\n" );
230 if( verify_header(
cur ) != 0 )
232#if defined(MBEDTLS_MEMORY_DEBUG)
239 if(
cur->prev != prv )
241#if defined(MBEDTLS_MEMORY_DEBUG)
243 "cur->prev != prv\n" );
255static void *buffer_alloc_calloc(
size_t n,
size_t size )
257 memory_header *
new, *
cur =
heap.first_free;
260 size_t original_len,
len;
261#if defined(MBEDTLS_MEMORY_BACKTRACE)
262 void *trace_buffer[MAX_BT];
295 if(
cur->alloc != 0 )
297#if defined(MBEDTLS_MEMORY_DEBUG)
304#if defined(MBEDTLS_MEMORY_DEBUG)
310 if(
cur->size -
len <
sizeof(memory_header) +
318 cur->prev_free->next_free =
cur->next_free;
320 heap.first_free =
cur->next_free;
323 cur->next_free->prev_free =
cur->prev_free;
328#if defined(MBEDTLS_MEMORY_DEBUG)
330 if(
heap.total_used >
heap.maximum_used )
331 heap.maximum_used =
heap.total_used;
333#if defined(MBEDTLS_MEMORY_BACKTRACE)
334 trace_cnt = backtrace( trace_buffer, MAX_BT );
335 cur->trace = backtrace_symbols( trace_buffer, trace_cnt );
336 cur->trace_count = trace_cnt;
342 ret = (
unsigned char *)
cur +
sizeof( memory_header );
348 p = ( (
unsigned char *)
cur ) +
sizeof(memory_header) +
len;
349 new = (memory_header *)
p;
351 new->size =
cur->size -
len -
sizeof(memory_header);
354 new->next =
cur->next;
355#if defined(MBEDTLS_MEMORY_BACKTRACE)
357 new->trace_count = 0;
359 new->magic1 = MAGIC1;
360 new->magic2 = MAGIC2;
363 new->
next->prev =
new;
367 new->prev_free =
cur->prev_free;
368 new->next_free =
cur->next_free;
370 new->prev_free->next_free =
new;
372 heap.first_free =
new;
375 new->next_free->prev_free =
new;
383#if defined(MBEDTLS_MEMORY_DEBUG)
385 if(
heap.header_count >
heap.maximum_header_count )
386 heap.maximum_header_count =
heap.header_count;
388 if(
heap.total_used >
heap.maximum_used )
389 heap.maximum_used =
heap.total_used;
391#if defined(MBEDTLS_MEMORY_BACKTRACE)
392 trace_cnt = backtrace( trace_buffer, MAX_BT );
393 cur->trace = backtrace_symbols( trace_buffer, trace_cnt );
394 cur->trace_count = trace_cnt;
400 ret = (
unsigned char *)
cur +
sizeof( memory_header );
406static void buffer_alloc_free(
void *
ptr )
408 memory_header *
hdr, *old =
NULL;
409 unsigned char *
p = (
unsigned char *)
ptr;
414 if( p < heap.buf || p >=
heap.buf +
heap.len )
416#if defined(MBEDTLS_MEMORY_DEBUG)
423 p -=
sizeof(memory_header);
424 hdr = (memory_header *)
p;
426 if( verify_header(
hdr ) != 0 )
429 if(
hdr->alloc != 1 )
431#if defined(MBEDTLS_MEMORY_DEBUG)
440#if defined(MBEDTLS_MEMORY_DEBUG)
445#if defined(MBEDTLS_MEMORY_BACKTRACE)
448 hdr->trace_count = 0;
453 if(
hdr->prev !=
NULL &&
hdr->prev->alloc == 0 )
455#if defined(MBEDTLS_MEMORY_DEBUG)
458 hdr->prev->size +=
sizeof(memory_header) +
hdr->size;
459 hdr->prev->next =
hdr->next;
466 memset( old, 0,
sizeof(memory_header) );
471 if(
hdr->next !=
NULL &&
hdr->next->alloc == 0 )
473#if defined(MBEDTLS_MEMORY_DEBUG)
476 hdr->size +=
sizeof(memory_header) +
hdr->next->size;
478 hdr->next =
hdr->next->next;
483 hdr->prev_free->next_free =
hdr->next_free;
485 heap.first_free =
hdr->next_free;
488 hdr->next_free->prev_free =
hdr->prev_free;
491 hdr->prev_free = old->prev_free;
492 hdr->next_free = old->next_free;
495 hdr->prev_free->next_free =
hdr;
500 hdr->next_free->prev_free =
hdr;
505 memset( old, 0,
sizeof(memory_header) );
513 hdr->next_free =
heap.first_free;
515 heap.first_free->prev_free =
hdr;
525 heap.verify = verify;
530 return verify_chain();
533#if defined(MBEDTLS_MEMORY_DEBUG)
534void mbedtls_memory_buffer_alloc_status(
void )
537 "Current use: %zu blocks / %zu bytes, max: %zu blocks / "
538 "%zu bytes (total %zu bytes), alloc / free: %zu / %zu\n",
540 heap.maximum_header_count,
heap.maximum_used,
541 heap.maximum_header_count *
sizeof( memory_header )
543 heap.alloc_count,
heap.free_count );
556void mbedtls_memory_buffer_alloc_max_get(
size_t *max_used,
size_t *max_blocks )
558 *max_used =
heap.maximum_used;
559 *max_blocks =
heap.maximum_header_count;
562void mbedtls_memory_buffer_alloc_max_reset(
void )
564 heap.maximum_used = 0;
565 heap.maximum_header_count = 0;
568void mbedtls_memory_buffer_alloc_cur_get(
size_t *cur_used,
size_t *cur_blocks )
570 *cur_used =
heap.total_used;
571 *cur_blocks =
heap.header_count;
575#if defined(MBEDTLS_THREADING_C)
576static void *buffer_alloc_calloc_mutexed(
size_t n,
size_t size )
579 if( mbedtls_mutex_lock( &
heap.mutex ) != 0 )
581 buf = buffer_alloc_calloc(
n,
size );
582 if( mbedtls_mutex_unlock( &
heap.mutex ) )
587static void buffer_alloc_free_mutexed(
void *
ptr )
591 if( mbedtls_mutex_lock( &
heap.mutex ) )
593 buffer_alloc_free(
ptr );
594 (
void) mbedtls_mutex_unlock( &
heap.mutex );
600 memset( &
heap, 0,
sizeof( buffer_alloc_ctx ) );
602#if defined(MBEDTLS_THREADING_C)
603 mbedtls_mutex_init( &
heap.mutex );
604 mbedtls_platform_set_calloc_free( buffer_alloc_calloc_mutexed,
605 buffer_alloc_free_mutexed );
607 mbedtls_platform_set_calloc_free( buffer_alloc_calloc, buffer_alloc_free );
626 heap.first = (memory_header *)
buf;
627 heap.first->size =
len -
sizeof( memory_header );
628 heap.first->magic1 = MAGIC1;
629 heap.first->magic2 = MAGIC2;
635#if defined(MBEDTLS_THREADING_C)
636 mbedtls_mutex_free( &
heap.mutex );
641#if defined(MBEDTLS_SELF_TEST)
642static int check_pointer(
void *
p )
653static int check_all_free(
void )
656#
if defined(MBEDTLS_MEMORY_DEBUG)
657 heap.total_used != 0 ||
660 (
void *)
heap.first != (
void *)
heap.buf )
668#define TEST_ASSERT( condition ) \
669 if( ! (condition) ) \
672 mbedtls_printf( "failed\n" ); \
678int mbedtls_memory_buffer_alloc_self_test(
int verbose )
680 unsigned char buf[1024];
681 unsigned char *
p, *
q, *
r, *
end;
694 check_pointer(
q ) == 0 &&
695 check_pointer(
r ) == 0 );
723 check_pointer(
q ) == 0 &&
724 check_pointer(
r ) == 0 );
752 TEST_ASSERT( check_pointer(
p ) == 0 && check_pointer(
q ) == 0 );
static void cleanup(void)
GLdouble GLdouble GLdouble r
GLdouble GLdouble GLdouble GLdouble q
GLenum GLuint GLenum GLsizei const GLchar * buf
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Buffer-based memory allocator.
#define MBEDTLS_MEMORY_VERIFY_FREE
#define MBEDTLS_MEMORY_ALIGN_MULTIPLE
#define MBEDTLS_MEMORY_VERIFY_ALLOC
int mbedtls_memory_buffer_alloc_verify(void)
Verifies that all headers in the memory buffer are correct and contain sane values....
void mbedtls_memory_buffer_set_verify(int verify)
Determine when the allocator should automatically verify the state of the entire chain of headers / m...
void mbedtls_memory_buffer_alloc_init(unsigned char *buf, size_t len)
Initialize use of stack-based memory allocator. The stack-based allocator does memory management insi...
void mbedtls_memory_buffer_alloc_free(void)
Free the mutex for thread-safety and clear remaining memory.
static unsigned __int64 next
Configuration options (set of defines)
Threading abstraction layer.
#define new(TYPE, numElems)