Knight KE / Mbed OS Game_Master
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers memory_buffer_alloc.c Source File

memory_buffer_alloc.c

00001 /*
00002  *  Buffer-based memory allocator
00003  *
00004  *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
00005  *  SPDX-License-Identifier: Apache-2.0
00006  *
00007  *  Licensed under the Apache License, Version 2.0 (the "License"); you may
00008  *  not use this file except in compliance with the License.
00009  *  You may obtain a copy of the License at
00010  *
00011  *  http://www.apache.org/licenses/LICENSE-2.0
00012  *
00013  *  Unless required by applicable law or agreed to in writing, software
00014  *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
00015  *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00016  *  See the License for the specific language governing permissions and
00017  *  limitations under the License.
00018  *
00019  *  This file is part of mbed TLS (https://tls.mbed.org)
00020  */
00021 
00022 #if !defined(MBEDTLS_CONFIG_FILE)
00023 #include "mbedtls/config.h"
00024 #else
00025 #include MBEDTLS_CONFIG_FILE
00026 #endif
00027 
00028 #if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C)
00029 #include "mbedtls/memory_buffer_alloc.h"
00030 
00031 /* No need for the header guard as MBEDTLS_MEMORY_BUFFER_ALLOC_C
00032    is dependent upon MBEDTLS_PLATFORM_C */
00033 #include "mbedtls/platform.h"
00034 #include "mbedtls/platform_util.h"
00035 
00036 #include <string.h>
00037 
00038 #if defined(MBEDTLS_MEMORY_BACKTRACE)
00039 #include <execinfo.h>
00040 #endif
00041 
00042 #if defined(MBEDTLS_THREADING_C)
00043 #include "mbedtls/threading.h"
00044 #endif
00045 
00046 #define MAGIC1       0xFF00AA55
00047 #define MAGIC2       0xEE119966
00048 #define MAX_BT 20
00049 
00050 typedef struct _memory_header memory_header;
00051 struct _memory_header
00052 {
00053     size_t          magic1;
00054     size_t          size;
00055     size_t          alloc;
00056     memory_header   *prev;
00057     memory_header   *next;
00058     memory_header   *prev_free;
00059     memory_header   *next_free;
00060 #if defined(MBEDTLS_MEMORY_BACKTRACE)
00061     char            **trace;
00062     size_t          trace_count;
00063 #endif
00064     size_t          magic2;
00065 };
00066 
00067 typedef struct
00068 {
00069     unsigned char   *buf;
00070     size_t          len;
00071     memory_header   *first;
00072     memory_header   *first_free;
00073     int             verify;
00074 #if defined(MBEDTLS_MEMORY_DEBUG)
00075     size_t          alloc_count;
00076     size_t          free_count;
00077     size_t          total_used;
00078     size_t          maximum_used;
00079     size_t          header_count;
00080     size_t          maximum_header_count;
00081 #endif
00082 #if defined(MBEDTLS_THREADING_C)
00083     mbedtls_threading_mutex_t   mutex;
00084 #endif
00085 }
00086 buffer_alloc_ctx;
00087 
00088 static buffer_alloc_ctx heap;
00089 
00090 #if defined(MBEDTLS_MEMORY_DEBUG)
00091 static void debug_header( memory_header *hdr )
00092 {
00093 #if defined(MBEDTLS_MEMORY_BACKTRACE)
00094     size_t i;
00095 #endif
00096 
00097     mbedtls_fprintf( stderr, "HDR:  PTR(%10zu), PREV(%10zu), NEXT(%10zu), "
00098                               "ALLOC(%zu), SIZE(%10zu)\n",
00099                       (size_t) hdr, (size_t) hdr->prev, (size_t) hdr->next,
00100                       hdr->alloc, hdr->size );
00101     mbedtls_fprintf( stderr, "      FPREV(%10zu), FNEXT(%10zu)\n",
00102                       (size_t) hdr->prev_free, (size_t) hdr->next_free );
00103 
00104 #if defined(MBEDTLS_MEMORY_BACKTRACE)
00105     mbedtls_fprintf( stderr, "TRACE: \n" );
00106     for( i = 0; i < hdr->trace_count; i++ )
00107         mbedtls_fprintf( stderr, "%s\n", hdr->trace[i] );
00108     mbedtls_fprintf( stderr, "\n" );
00109 #endif
00110 }
00111 
00112 static void debug_chain( void )
00113 {
00114     memory_header *cur = heap.first;
00115 
00116     mbedtls_fprintf( stderr, "\nBlock list\n" );
00117     while( cur != NULL )
00118     {
00119         debug_header( cur );
00120         cur = cur->next;
00121     }
00122 
00123     mbedtls_fprintf( stderr, "Free list\n" );
00124     cur = heap.first_free;
00125 
00126     while( cur != NULL )
00127     {
00128         debug_header( cur );
00129         cur = cur->next_free;
00130     }
00131 }
00132 #endif /* MBEDTLS_MEMORY_DEBUG */
00133 
00134 static int verify_header( memory_header *hdr )
00135 {
00136     if( hdr->magic1 != MAGIC1 )
00137     {
00138 #if defined(MBEDTLS_MEMORY_DEBUG)
00139         mbedtls_fprintf( stderr, "FATAL: MAGIC1 mismatch\n" );
00140 #endif
00141         return( 1 );
00142     }
00143 
00144     if( hdr->magic2 != MAGIC2 )
00145     {
00146 #if defined(MBEDTLS_MEMORY_DEBUG)
00147         mbedtls_fprintf( stderr, "FATAL: MAGIC2 mismatch\n" );
00148 #endif
00149         return( 1 );
00150     }
00151 
00152     if( hdr->alloc > 1 )
00153     {
00154 #if defined(MBEDTLS_MEMORY_DEBUG)
00155         mbedtls_fprintf( stderr, "FATAL: alloc has illegal value\n" );
00156 #endif
00157         return( 1 );
00158     }
00159 
00160     if( hdr->prev != NULL && hdr->prev == hdr->next )
00161     {
00162 #if defined(MBEDTLS_MEMORY_DEBUG)
00163         mbedtls_fprintf( stderr, "FATAL: prev == next\n" );
00164 #endif
00165         return( 1 );
00166     }
00167 
00168     if( hdr->prev_free != NULL && hdr->prev_free == hdr->next_free )
00169     {
00170 #if defined(MBEDTLS_MEMORY_DEBUG)
00171         mbedtls_fprintf( stderr, "FATAL: prev_free == next_free\n" );
00172 #endif
00173         return( 1 );
00174     }
00175 
00176     return( 0 );
00177 }
00178 
00179 static int verify_chain( void )
00180 {
00181     memory_header *prv = heap.first, *cur;
00182 
00183     if( prv == NULL || verify_header( prv ) != 0 )
00184     {
00185 #if defined(MBEDTLS_MEMORY_DEBUG)
00186         mbedtls_fprintf( stderr, "FATAL: verification of first header "
00187                                   "failed\n" );
00188 #endif
00189         return( 1 );
00190     }
00191 
00192     if( heap.first->prev != NULL )
00193     {
00194 #if defined(MBEDTLS_MEMORY_DEBUG)
00195         mbedtls_fprintf( stderr, "FATAL: verification failed: "
00196                                   "first->prev != NULL\n" );
00197 #endif
00198         return( 1 );
00199     }
00200 
00201     cur = heap.first->next;
00202 
00203     while( cur != NULL )
00204     {
00205         if( verify_header( cur ) != 0 )
00206         {
00207 #if defined(MBEDTLS_MEMORY_DEBUG)
00208             mbedtls_fprintf( stderr, "FATAL: verification of header "
00209                                       "failed\n" );
00210 #endif
00211             return( 1 );
00212         }
00213 
00214         if( cur->prev != prv )
00215         {
00216 #if defined(MBEDTLS_MEMORY_DEBUG)
00217             mbedtls_fprintf( stderr, "FATAL: verification failed: "
00218                                       "cur->prev != prv\n" );
00219 #endif
00220             return( 1 );
00221         }
00222 
00223         prv = cur;
00224         cur = cur->next;
00225     }
00226 
00227     return( 0 );
00228 }
00229 
00230 static void *buffer_alloc_calloc( size_t n, size_t size )
00231 {
00232     memory_header *new, *cur = heap.first_free;
00233     unsigned char *p;
00234     void *ret;
00235     size_t original_len, len;
00236 #if defined(MBEDTLS_MEMORY_BACKTRACE)
00237     void *trace_buffer[MAX_BT];
00238     size_t trace_cnt;
00239 #endif
00240 
00241     if( heap.buf == NULL || heap.first == NULL )
00242         return( NULL );
00243 
00244     original_len = len = n * size;
00245 
00246     if( n == 0 || size == 0 || len / n != size )
00247         return( NULL );
00248     else if( len > (size_t)-MBEDTLS_MEMORY_ALIGN_MULTIPLE )
00249         return( NULL );
00250 
00251     if( len % MBEDTLS_MEMORY_ALIGN_MULTIPLE )
00252     {
00253         len -= len % MBEDTLS_MEMORY_ALIGN_MULTIPLE;
00254         len += MBEDTLS_MEMORY_ALIGN_MULTIPLE;
00255     }
00256 
00257     // Find block that fits
00258     //
00259     while( cur != NULL )
00260     {
00261         if( cur->size >= len )
00262             break;
00263 
00264         cur = cur->next_free;
00265     }
00266 
00267     if( cur == NULL )
00268         return( NULL );
00269 
00270     if( cur->alloc != 0 )
00271     {
00272 #if defined(MBEDTLS_MEMORY_DEBUG)
00273         mbedtls_fprintf( stderr, "FATAL: block in free_list but allocated "
00274                                   "data\n" );
00275 #endif
00276         mbedtls_exit( 1 );
00277     }
00278 
00279 #if defined(MBEDTLS_MEMORY_DEBUG)
00280     heap.alloc_count++;
00281 #endif
00282 
00283     // Found location, split block if > memory_header + 4 room left
00284     //
00285     if( cur->size - len < sizeof(memory_header) +
00286                           MBEDTLS_MEMORY_ALIGN_MULTIPLE )
00287     {
00288         cur->alloc = 1;
00289 
00290         // Remove from free_list
00291         //
00292         if( cur->prev_free != NULL )
00293             cur->prev_free->next_free = cur->next_free;
00294         else
00295             heap.first_free = cur->next_free;
00296 
00297         if( cur->next_free != NULL )
00298             cur->next_free->prev_free = cur->prev_free;
00299 
00300         cur->prev_free = NULL;
00301         cur->next_free = NULL;
00302 
00303 #if defined(MBEDTLS_MEMORY_DEBUG)
00304         heap.total_used += cur->size;
00305         if( heap.total_used > heap.maximum_used )
00306             heap.maximum_used = heap.total_used;
00307 #endif
00308 #if defined(MBEDTLS_MEMORY_BACKTRACE)
00309         trace_cnt = backtrace( trace_buffer, MAX_BT );
00310         cur->trace = backtrace_symbols( trace_buffer, trace_cnt );
00311         cur->trace_count = trace_cnt;
00312 #endif
00313 
00314         if( ( heap.verify & MBEDTLS_MEMORY_VERIFY_ALLOC ) && verify_chain() != 0 )
00315             mbedtls_exit( 1 );
00316 
00317         ret = (unsigned char *) cur + sizeof( memory_header );
00318         memset( ret, 0, original_len );
00319 
00320         return( ret );
00321     }
00322 
00323     p = ( (unsigned char *) cur ) + sizeof(memory_header) + len;
00324     new = (memory_header *) p;
00325 
00326     new->size = cur->size - len - sizeof(memory_header);
00327     new->alloc = 0;
00328     new->prev = cur;
00329     new->next = cur->next;
00330 #if defined(MBEDTLS_MEMORY_BACKTRACE)
00331     new->trace = NULL;
00332     new->trace_count = 0;
00333 #endif
00334     new->magic1 = MAGIC1;
00335     new->magic2 = MAGIC2;
00336 
00337     if( new->next != NULL )
00338         new->next->prev = new;
00339 
00340     // Replace cur with new in free_list
00341     //
00342     new->prev_free = cur->prev_free;
00343     new->next_free = cur->next_free;
00344     if( new->prev_free != NULL )
00345         new->prev_free->next_free = new;
00346     else
00347         heap.first_free = new;
00348 
00349     if( new->next_free != NULL )
00350         new->next_free->prev_free = new;
00351 
00352     cur->alloc = 1;
00353     cur->size = len;
00354     cur->next = new;
00355     cur->prev_free = NULL;
00356     cur->next_free = NULL;
00357 
00358 #if defined(MBEDTLS_MEMORY_DEBUG)
00359     heap.header_count++;
00360     if( heap.header_count > heap.maximum_header_count )
00361         heap.maximum_header_count = heap.header_count;
00362     heap.total_used += cur->size;
00363     if( heap.total_used > heap.maximum_used )
00364         heap.maximum_used = heap.total_used;
00365 #endif
00366 #if defined(MBEDTLS_MEMORY_BACKTRACE)
00367     trace_cnt = backtrace( trace_buffer, MAX_BT );
00368     cur->trace = backtrace_symbols( trace_buffer, trace_cnt );
00369     cur->trace_count = trace_cnt;
00370 #endif
00371 
00372     if( ( heap.verify & MBEDTLS_MEMORY_VERIFY_ALLOC ) && verify_chain() != 0 )
00373         mbedtls_exit( 1 );
00374 
00375     ret = (unsigned char *) cur + sizeof( memory_header );
00376     memset( ret, 0, original_len );
00377 
00378     return( ret );
00379 }
00380 
00381 static void buffer_alloc_free( void *ptr )
00382 {
00383     memory_header *hdr, *old = NULL;
00384     unsigned char *p = (unsigned char *) ptr;
00385 
00386     if( ptr == NULL || heap.buf == NULL || heap.first == NULL )
00387         return;
00388 
00389     if( p < heap.buf || p >= heap.buf + heap.len )
00390     {
00391 #if defined(MBEDTLS_MEMORY_DEBUG)
00392         mbedtls_fprintf( stderr, "FATAL: mbedtls_free() outside of managed "
00393                                   "space\n" );
00394 #endif
00395         mbedtls_exit( 1 );
00396     }
00397 
00398     p -= sizeof(memory_header);
00399     hdr = (memory_header *) p;
00400 
00401     if( verify_header( hdr ) != 0 )
00402         mbedtls_exit( 1 );
00403 
00404     if( hdr->alloc != 1 )
00405     {
00406 #if defined(MBEDTLS_MEMORY_DEBUG)
00407         mbedtls_fprintf( stderr, "FATAL: mbedtls_free() on unallocated "
00408                                   "data\n" );
00409 #endif
00410         mbedtls_exit( 1 );
00411     }
00412 
00413     hdr->alloc = 0;
00414 
00415 #if defined(MBEDTLS_MEMORY_DEBUG)
00416     heap.free_count++;
00417     heap.total_used -= hdr->size;
00418 #endif
00419 
00420 #if defined(MBEDTLS_MEMORY_BACKTRACE)
00421     free( hdr->trace );
00422     hdr->trace = NULL;
00423     hdr->trace_count = 0;
00424 #endif
00425 
00426     // Regroup with block before
00427     //
00428     if( hdr->prev != NULL && hdr->prev->alloc == 0 )
00429     {
00430 #if defined(MBEDTLS_MEMORY_DEBUG)
00431         heap.header_count--;
00432 #endif
00433         hdr->prev->size += sizeof(memory_header) + hdr->size;
00434         hdr->prev->next = hdr->next;
00435         old = hdr;
00436         hdr = hdr->prev;
00437 
00438         if( hdr->next != NULL )
00439             hdr->next->prev = hdr;
00440 
00441         memset( old, 0, sizeof(memory_header) );
00442     }
00443 
00444     // Regroup with block after
00445     //
00446     if( hdr->next != NULL && hdr->next->alloc == 0 )
00447     {
00448 #if defined(MBEDTLS_MEMORY_DEBUG)
00449         heap.header_count--;
00450 #endif
00451         hdr->size += sizeof(memory_header) + hdr->next->size;
00452         old = hdr->next;
00453         hdr->next = hdr->next->next;
00454 
00455         if( hdr->prev_free != NULL || hdr->next_free != NULL )
00456         {
00457             if( hdr->prev_free != NULL )
00458                 hdr->prev_free->next_free = hdr->next_free;
00459             else
00460                 heap.first_free = hdr->next_free;
00461 
00462             if( hdr->next_free != NULL )
00463                 hdr->next_free->prev_free = hdr->prev_free;
00464         }
00465 
00466         hdr->prev_free = old->prev_free;
00467         hdr->next_free = old->next_free;
00468 
00469         if( hdr->prev_free != NULL )
00470             hdr->prev_free->next_free = hdr;
00471         else
00472             heap.first_free = hdr;
00473 
00474         if( hdr->next_free != NULL )
00475             hdr->next_free->prev_free = hdr;
00476 
00477         if( hdr->next != NULL )
00478             hdr->next->prev = hdr;
00479 
00480         memset( old, 0, sizeof(memory_header) );
00481     }
00482 
00483     // Prepend to free_list if we have not merged
00484     // (Does not have to stay in same order as prev / next list)
00485     //
00486     if( old == NULL )
00487     {
00488         hdr->next_free = heap.first_free;
00489         if( heap.first_free != NULL )
00490             heap.first_free->prev_free = hdr;
00491         heap.first_free = hdr;
00492     }
00493 
00494     if( ( heap.verify & MBEDTLS_MEMORY_VERIFY_FREE ) && verify_chain() != 0 )
00495         mbedtls_exit( 1 );
00496 }
00497 
00498 void mbedtls_memory_buffer_set_verify( int verify )
00499 {
00500     heap.verify = verify;
00501 }
00502 
00503 int mbedtls_memory_buffer_alloc_verify( void )
00504 {
00505     return verify_chain();
00506 }
00507 
00508 #if defined(MBEDTLS_MEMORY_DEBUG)
00509 void mbedtls_memory_buffer_alloc_status( void )
00510 {
00511     mbedtls_fprintf( stderr,
00512                       "Current use: %zu blocks / %zu bytes, max: %zu blocks / "
00513                       "%zu bytes (total %zu bytes), alloc / free: %zu / %zu\n",
00514                       heap.header_count, heap.total_used,
00515                       heap.maximum_header_count, heap.maximum_used,
00516                       heap.maximum_header_count * sizeof( memory_header )
00517                       + heap.maximum_used,
00518                       heap.alloc_count, heap.free_count );
00519 
00520     if( heap.first->next == NULL )
00521         mbedtls_fprintf( stderr, "All memory de-allocated in stack buffer\n" );
00522     else
00523     {
00524         mbedtls_fprintf( stderr, "Memory currently allocated:\n" );
00525         debug_chain();
00526     }
00527 }
00528 
00529 void mbedtls_memory_buffer_alloc_max_get( size_t *max_used, size_t *max_blocks )
00530 {
00531     *max_used   = heap.maximum_used;
00532     *max_blocks = heap.maximum_header_count;
00533 }
00534 
00535 void mbedtls_memory_buffer_alloc_max_reset( void )
00536 {
00537     heap.maximum_used = 0;
00538     heap.maximum_header_count = 0;
00539 }
00540 
00541 void mbedtls_memory_buffer_alloc_cur_get( size_t *cur_used, size_t *cur_blocks )
00542 {
00543     *cur_used   = heap.total_used;
00544     *cur_blocks = heap.header_count;
00545 }
00546 #endif /* MBEDTLS_MEMORY_DEBUG */
00547 
00548 #if defined(MBEDTLS_THREADING_C)
00549 static void *buffer_alloc_calloc_mutexed( size_t n, size_t size )
00550 {
00551     void *buf;
00552     if( mbedtls_mutex_lock( &heap.mutex ) != 0 )
00553         return( NULL );
00554     buf = buffer_alloc_calloc( n, size );
00555     if( mbedtls_mutex_unlock( &heap.mutex ) )
00556         return( NULL );
00557     return( buf );
00558 }
00559 
00560 static void buffer_alloc_free_mutexed( void *ptr )
00561 {
00562     /* We have to good option here, but corrupting the heap seems
00563      * worse than loosing memory. */
00564     if( mbedtls_mutex_lock( &heap.mutex ) )
00565         return;
00566     buffer_alloc_free( ptr );
00567     (void) mbedtls_mutex_unlock( &heap.mutex );
00568 }
00569 #endif /* MBEDTLS_THREADING_C */
00570 
00571 void mbedtls_memory_buffer_alloc_init( unsigned char *buf, size_t len )
00572 {
00573     memset( &heap, 0, sizeof( buffer_alloc_ctx ) );
00574 
00575 #if defined(MBEDTLS_THREADING_C)
00576     mbedtls_mutex_init( &heap.mutex );
00577     mbedtls_platform_set_calloc_free( buffer_alloc_calloc_mutexed,
00578                               buffer_alloc_free_mutexed );
00579 #else
00580     mbedtls_platform_set_calloc_free( buffer_alloc_calloc, buffer_alloc_free );
00581 #endif
00582 
00583     if( len < sizeof( memory_header ) + MBEDTLS_MEMORY_ALIGN_MULTIPLE )
00584         return;
00585     else if( (size_t)buf % MBEDTLS_MEMORY_ALIGN_MULTIPLE )
00586     {
00587         /* Adjust len first since buf is used in the computation */
00588         len -= MBEDTLS_MEMORY_ALIGN_MULTIPLE
00589              - (size_t)buf % MBEDTLS_MEMORY_ALIGN_MULTIPLE;
00590         buf += MBEDTLS_MEMORY_ALIGN_MULTIPLE
00591              - (size_t)buf % MBEDTLS_MEMORY_ALIGN_MULTIPLE;
00592     }
00593 
00594     memset( buf, 0, len );
00595 
00596     heap.buf = buf;
00597     heap.len = len;
00598 
00599     heap.first = (memory_header *)buf;
00600     heap.first->size = len - sizeof( memory_header );
00601     heap.first->magic1 = MAGIC1;
00602     heap.first->magic2 = MAGIC2;
00603     heap.first_free = heap.first;
00604 }
00605 
00606 void mbedtls_memory_buffer_alloc_free( void )
00607 {
00608 #if defined(MBEDTLS_THREADING_C)
00609     mbedtls_mutex_free( &heap.mutex );
00610 #endif
00611     mbedtls_platform_zeroize( &heap, sizeof(buffer_alloc_ctx) );
00612 }
00613 
00614 #if defined(MBEDTLS_SELF_TEST)
00615 static int check_pointer( void *p )
00616 {
00617     if( p == NULL )
00618         return( -1 );
00619 
00620     if( (size_t) p % MBEDTLS_MEMORY_ALIGN_MULTIPLE != 0 )
00621         return( -1 );
00622 
00623     return( 0 );
00624 }
00625 
00626 static int check_all_free( void )
00627 {
00628     if(
00629 #if defined(MBEDTLS_MEMORY_DEBUG)
00630         heap.total_used != 0 ||
00631 #endif
00632         heap.first != heap.first_free ||
00633         (void *) heap.first != (void *) heap.buf )
00634     {
00635         return( -1 );
00636     }
00637 
00638     return( 0 );
00639 }
00640 
00641 #define TEST_ASSERT( condition )            \
00642     if( ! (condition) )                     \
00643     {                                       \
00644         if( verbose != 0 )                  \
00645             mbedtls_printf( "failed\n" );  \
00646                                             \
00647         ret = 1;                            \
00648         goto cleanup;                       \
00649     }
00650 
00651 int mbedtls_memory_buffer_alloc_self_test( int verbose )
00652 {
00653     unsigned char buf[1024];
00654     unsigned char *p, *q, *r, *end;
00655     int ret = 0;
00656 
00657     if( verbose != 0 )
00658         mbedtls_printf( "  MBA test #1 (basic alloc-free cycle): " );
00659 
00660     mbedtls_memory_buffer_alloc_init( buf, sizeof( buf ) );
00661 
00662     p = mbedtls_calloc( 1, 1 );
00663     q = mbedtls_calloc( 1, 128 );
00664     r = mbedtls_calloc( 1, 16 );
00665 
00666     TEST_ASSERT( check_pointer( p ) == 0 &&
00667                  check_pointer( q ) == 0 &&
00668                  check_pointer( r ) == 0 );
00669 
00670     mbedtls_free( r );
00671     mbedtls_free( q );
00672     mbedtls_free( p );
00673 
00674     TEST_ASSERT( check_all_free( ) == 0 );
00675 
00676     /* Memorize end to compare with the next test */
00677     end = heap.buf + heap.len;
00678 
00679     mbedtls_memory_buffer_alloc_free( );
00680 
00681     if( verbose != 0 )
00682         mbedtls_printf( "passed\n" );
00683 
00684     if( verbose != 0 )
00685         mbedtls_printf( "  MBA test #2 (buf not aligned): " );
00686 
00687     mbedtls_memory_buffer_alloc_init( buf + 1, sizeof( buf ) - 1 );
00688 
00689     TEST_ASSERT( heap.buf + heap.len == end );
00690 
00691     p = mbedtls_calloc( 1, 1 );
00692     q = mbedtls_calloc( 1, 128 );
00693     r = mbedtls_calloc( 1, 16 );
00694 
00695     TEST_ASSERT( check_pointer( p ) == 0 &&
00696                  check_pointer( q ) == 0 &&
00697                  check_pointer( r ) == 0 );
00698 
00699     mbedtls_free( r );
00700     mbedtls_free( q );
00701     mbedtls_free( p );
00702 
00703     TEST_ASSERT( check_all_free( ) == 0 );
00704 
00705     mbedtls_memory_buffer_alloc_free( );
00706 
00707     if( verbose != 0 )
00708         mbedtls_printf( "passed\n" );
00709 
00710     if( verbose != 0 )
00711         mbedtls_printf( "  MBA test #3 (full): " );
00712 
00713     mbedtls_memory_buffer_alloc_init( buf, sizeof( buf ) );
00714 
00715     p = mbedtls_calloc( 1, sizeof( buf ) - sizeof( memory_header ) );
00716 
00717     TEST_ASSERT( check_pointer( p ) == 0 );
00718     TEST_ASSERT( mbedtls_calloc( 1, 1 ) == NULL );
00719 
00720     mbedtls_free( p );
00721 
00722     p = mbedtls_calloc( 1, sizeof( buf ) - 2 * sizeof( memory_header ) - 16 );
00723     q = mbedtls_calloc( 1, 16 );
00724 
00725     TEST_ASSERT( check_pointer( p ) == 0 && check_pointer( q ) == 0 );
00726     TEST_ASSERT( mbedtls_calloc( 1, 1 ) == NULL );
00727 
00728     mbedtls_free( q );
00729 
00730     TEST_ASSERT( mbedtls_calloc( 1, 17 ) == NULL );
00731 
00732     mbedtls_free( p );
00733 
00734     TEST_ASSERT( check_all_free( ) == 0 );
00735 
00736     mbedtls_memory_buffer_alloc_free( );
00737 
00738     if( verbose != 0 )
00739         mbedtls_printf( "passed\n" );
00740 
00741 cleanup:
00742     mbedtls_memory_buffer_alloc_free( );
00743 
00744     return( ret );
00745 }
00746 #endif /* MBEDTLS_SELF_TEST */
00747 
00748 #endif /* MBEDTLS_MEMORY_BUFFER_ALLOC_C */