BA / SerialCom

Fork of OmniWheels by Gustav Atmel

Committer:
gustavatmel
Date:
Tue May 01 15:47:08 2018 +0000
Revision:
1:9c5af431a1f1
sdf

Who changed what in which revision?

UserRevisionLine numberNew contents of line
gustavatmel 1:9c5af431a1f1 1 /*
gustavatmel 1:9c5af431a1f1 2 * Buffer-based memory allocator
gustavatmel 1:9c5af431a1f1 3 *
gustavatmel 1:9c5af431a1f1 4 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
gustavatmel 1:9c5af431a1f1 5 * SPDX-License-Identifier: Apache-2.0
gustavatmel 1:9c5af431a1f1 6 *
gustavatmel 1:9c5af431a1f1 7 * Licensed under the Apache License, Version 2.0 (the "License"); you may
gustavatmel 1:9c5af431a1f1 8 * not use this file except in compliance with the License.
gustavatmel 1:9c5af431a1f1 9 * You may obtain a copy of the License at
gustavatmel 1:9c5af431a1f1 10 *
gustavatmel 1:9c5af431a1f1 11 * http://www.apache.org/licenses/LICENSE-2.0
gustavatmel 1:9c5af431a1f1 12 *
gustavatmel 1:9c5af431a1f1 13 * Unless required by applicable law or agreed to in writing, software
gustavatmel 1:9c5af431a1f1 14 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
gustavatmel 1:9c5af431a1f1 15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
gustavatmel 1:9c5af431a1f1 16 * See the License for the specific language governing permissions and
gustavatmel 1:9c5af431a1f1 17 * limitations under the License.
gustavatmel 1:9c5af431a1f1 18 *
gustavatmel 1:9c5af431a1f1 19 * This file is part of mbed TLS (https://tls.mbed.org)
gustavatmel 1:9c5af431a1f1 20 */
gustavatmel 1:9c5af431a1f1 21
gustavatmel 1:9c5af431a1f1 22 #if !defined(MBEDTLS_CONFIG_FILE)
gustavatmel 1:9c5af431a1f1 23 #include "mbedtls/config.h"
gustavatmel 1:9c5af431a1f1 24 #else
gustavatmel 1:9c5af431a1f1 25 #include MBEDTLS_CONFIG_FILE
gustavatmel 1:9c5af431a1f1 26 #endif
gustavatmel 1:9c5af431a1f1 27
gustavatmel 1:9c5af431a1f1 28 #if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C)
gustavatmel 1:9c5af431a1f1 29 #include "mbedtls/memory_buffer_alloc.h"
gustavatmel 1:9c5af431a1f1 30
gustavatmel 1:9c5af431a1f1 31 /* No need for the header guard as MBEDTLS_MEMORY_BUFFER_ALLOC_C
gustavatmel 1:9c5af431a1f1 32 is dependent upon MBEDTLS_PLATFORM_C */
gustavatmel 1:9c5af431a1f1 33 #include "mbedtls/platform.h"
gustavatmel 1:9c5af431a1f1 34
gustavatmel 1:9c5af431a1f1 35 #include <string.h>
gustavatmel 1:9c5af431a1f1 36
gustavatmel 1:9c5af431a1f1 37 #if defined(MBEDTLS_MEMORY_BACKTRACE)
gustavatmel 1:9c5af431a1f1 38 #include <execinfo.h>
gustavatmel 1:9c5af431a1f1 39 #endif
gustavatmel 1:9c5af431a1f1 40
gustavatmel 1:9c5af431a1f1 41 #if defined(MBEDTLS_THREADING_C)
gustavatmel 1:9c5af431a1f1 42 #include "mbedtls/threading.h"
gustavatmel 1:9c5af431a1f1 43 #endif
gustavatmel 1:9c5af431a1f1 44
gustavatmel 1:9c5af431a1f1 45 /* Implementation that should never be optimized out by the compiler */
gustavatmel 1:9c5af431a1f1 46 static void mbedtls_zeroize( void *v, size_t n ) {
gustavatmel 1:9c5af431a1f1 47 volatile unsigned char *p = v; while( n-- ) *p++ = 0;
gustavatmel 1:9c5af431a1f1 48 }
gustavatmel 1:9c5af431a1f1 49
gustavatmel 1:9c5af431a1f1 50 #define MAGIC1 0xFF00AA55
gustavatmel 1:9c5af431a1f1 51 #define MAGIC2 0xEE119966
gustavatmel 1:9c5af431a1f1 52 #define MAX_BT 20
gustavatmel 1:9c5af431a1f1 53
gustavatmel 1:9c5af431a1f1 54 typedef struct _memory_header memory_header;
gustavatmel 1:9c5af431a1f1 55 struct _memory_header
gustavatmel 1:9c5af431a1f1 56 {
gustavatmel 1:9c5af431a1f1 57 size_t magic1;
gustavatmel 1:9c5af431a1f1 58 size_t size;
gustavatmel 1:9c5af431a1f1 59 size_t alloc;
gustavatmel 1:9c5af431a1f1 60 memory_header *prev;
gustavatmel 1:9c5af431a1f1 61 memory_header *next;
gustavatmel 1:9c5af431a1f1 62 memory_header *prev_free;
gustavatmel 1:9c5af431a1f1 63 memory_header *next_free;
gustavatmel 1:9c5af431a1f1 64 #if defined(MBEDTLS_MEMORY_BACKTRACE)
gustavatmel 1:9c5af431a1f1 65 char **trace;
gustavatmel 1:9c5af431a1f1 66 size_t trace_count;
gustavatmel 1:9c5af431a1f1 67 #endif
gustavatmel 1:9c5af431a1f1 68 size_t magic2;
gustavatmel 1:9c5af431a1f1 69 };
gustavatmel 1:9c5af431a1f1 70
gustavatmel 1:9c5af431a1f1 71 typedef struct
gustavatmel 1:9c5af431a1f1 72 {
gustavatmel 1:9c5af431a1f1 73 unsigned char *buf;
gustavatmel 1:9c5af431a1f1 74 size_t len;
gustavatmel 1:9c5af431a1f1 75 memory_header *first;
gustavatmel 1:9c5af431a1f1 76 memory_header *first_free;
gustavatmel 1:9c5af431a1f1 77 int verify;
gustavatmel 1:9c5af431a1f1 78 #if defined(MBEDTLS_MEMORY_DEBUG)
gustavatmel 1:9c5af431a1f1 79 size_t alloc_count;
gustavatmel 1:9c5af431a1f1 80 size_t free_count;
gustavatmel 1:9c5af431a1f1 81 size_t total_used;
gustavatmel 1:9c5af431a1f1 82 size_t maximum_used;
gustavatmel 1:9c5af431a1f1 83 size_t header_count;
gustavatmel 1:9c5af431a1f1 84 size_t maximum_header_count;
gustavatmel 1:9c5af431a1f1 85 #endif
gustavatmel 1:9c5af431a1f1 86 #if defined(MBEDTLS_THREADING_C)
gustavatmel 1:9c5af431a1f1 87 mbedtls_threading_mutex_t mutex;
gustavatmel 1:9c5af431a1f1 88 #endif
gustavatmel 1:9c5af431a1f1 89 }
gustavatmel 1:9c5af431a1f1 90 buffer_alloc_ctx;
gustavatmel 1:9c5af431a1f1 91
gustavatmel 1:9c5af431a1f1 92 static buffer_alloc_ctx heap;
gustavatmel 1:9c5af431a1f1 93
gustavatmel 1:9c5af431a1f1 94 #if defined(MBEDTLS_MEMORY_DEBUG)
gustavatmel 1:9c5af431a1f1 95 static void debug_header( memory_header *hdr )
gustavatmel 1:9c5af431a1f1 96 {
gustavatmel 1:9c5af431a1f1 97 #if defined(MBEDTLS_MEMORY_BACKTRACE)
gustavatmel 1:9c5af431a1f1 98 size_t i;
gustavatmel 1:9c5af431a1f1 99 #endif
gustavatmel 1:9c5af431a1f1 100
gustavatmel 1:9c5af431a1f1 101 mbedtls_fprintf( stderr, "HDR: PTR(%10zu), PREV(%10zu), NEXT(%10zu), "
gustavatmel 1:9c5af431a1f1 102 "ALLOC(%zu), SIZE(%10zu)\n",
gustavatmel 1:9c5af431a1f1 103 (size_t) hdr, (size_t) hdr->prev, (size_t) hdr->next,
gustavatmel 1:9c5af431a1f1 104 hdr->alloc, hdr->size );
gustavatmel 1:9c5af431a1f1 105 mbedtls_fprintf( stderr, " FPREV(%10zu), FNEXT(%10zu)\n",
gustavatmel 1:9c5af431a1f1 106 (size_t) hdr->prev_free, (size_t) hdr->next_free );
gustavatmel 1:9c5af431a1f1 107
gustavatmel 1:9c5af431a1f1 108 #if defined(MBEDTLS_MEMORY_BACKTRACE)
gustavatmel 1:9c5af431a1f1 109 mbedtls_fprintf( stderr, "TRACE: \n" );
gustavatmel 1:9c5af431a1f1 110 for( i = 0; i < hdr->trace_count; i++ )
gustavatmel 1:9c5af431a1f1 111 mbedtls_fprintf( stderr, "%s\n", hdr->trace[i] );
gustavatmel 1:9c5af431a1f1 112 mbedtls_fprintf( stderr, "\n" );
gustavatmel 1:9c5af431a1f1 113 #endif
gustavatmel 1:9c5af431a1f1 114 }
gustavatmel 1:9c5af431a1f1 115
gustavatmel 1:9c5af431a1f1 116 static void debug_chain()
gustavatmel 1:9c5af431a1f1 117 {
gustavatmel 1:9c5af431a1f1 118 memory_header *cur = heap.first;
gustavatmel 1:9c5af431a1f1 119
gustavatmel 1:9c5af431a1f1 120 mbedtls_fprintf( stderr, "\nBlock list\n" );
gustavatmel 1:9c5af431a1f1 121 while( cur != NULL )
gustavatmel 1:9c5af431a1f1 122 {
gustavatmel 1:9c5af431a1f1 123 debug_header( cur );
gustavatmel 1:9c5af431a1f1 124 cur = cur->next;
gustavatmel 1:9c5af431a1f1 125 }
gustavatmel 1:9c5af431a1f1 126
gustavatmel 1:9c5af431a1f1 127 mbedtls_fprintf( stderr, "Free list\n" );
gustavatmel 1:9c5af431a1f1 128 cur = heap.first_free;
gustavatmel 1:9c5af431a1f1 129
gustavatmel 1:9c5af431a1f1 130 while( cur != NULL )
gustavatmel 1:9c5af431a1f1 131 {
gustavatmel 1:9c5af431a1f1 132 debug_header( cur );
gustavatmel 1:9c5af431a1f1 133 cur = cur->next_free;
gustavatmel 1:9c5af431a1f1 134 }
gustavatmel 1:9c5af431a1f1 135 }
gustavatmel 1:9c5af431a1f1 136 #endif /* MBEDTLS_MEMORY_DEBUG */
gustavatmel 1:9c5af431a1f1 137
gustavatmel 1:9c5af431a1f1 138 static int verify_header( memory_header *hdr )
gustavatmel 1:9c5af431a1f1 139 {
gustavatmel 1:9c5af431a1f1 140 if( hdr->magic1 != MAGIC1 )
gustavatmel 1:9c5af431a1f1 141 {
gustavatmel 1:9c5af431a1f1 142 #if defined(MBEDTLS_MEMORY_DEBUG)
gustavatmel 1:9c5af431a1f1 143 mbedtls_fprintf( stderr, "FATAL: MAGIC1 mismatch\n" );
gustavatmel 1:9c5af431a1f1 144 #endif
gustavatmel 1:9c5af431a1f1 145 return( 1 );
gustavatmel 1:9c5af431a1f1 146 }
gustavatmel 1:9c5af431a1f1 147
gustavatmel 1:9c5af431a1f1 148 if( hdr->magic2 != MAGIC2 )
gustavatmel 1:9c5af431a1f1 149 {
gustavatmel 1:9c5af431a1f1 150 #if defined(MBEDTLS_MEMORY_DEBUG)
gustavatmel 1:9c5af431a1f1 151 mbedtls_fprintf( stderr, "FATAL: MAGIC2 mismatch\n" );
gustavatmel 1:9c5af431a1f1 152 #endif
gustavatmel 1:9c5af431a1f1 153 return( 1 );
gustavatmel 1:9c5af431a1f1 154 }
gustavatmel 1:9c5af431a1f1 155
gustavatmel 1:9c5af431a1f1 156 if( hdr->alloc > 1 )
gustavatmel 1:9c5af431a1f1 157 {
gustavatmel 1:9c5af431a1f1 158 #if defined(MBEDTLS_MEMORY_DEBUG)
gustavatmel 1:9c5af431a1f1 159 mbedtls_fprintf( stderr, "FATAL: alloc has illegal value\n" );
gustavatmel 1:9c5af431a1f1 160 #endif
gustavatmel 1:9c5af431a1f1 161 return( 1 );
gustavatmel 1:9c5af431a1f1 162 }
gustavatmel 1:9c5af431a1f1 163
gustavatmel 1:9c5af431a1f1 164 if( hdr->prev != NULL && hdr->prev == hdr->next )
gustavatmel 1:9c5af431a1f1 165 {
gustavatmel 1:9c5af431a1f1 166 #if defined(MBEDTLS_MEMORY_DEBUG)
gustavatmel 1:9c5af431a1f1 167 mbedtls_fprintf( stderr, "FATAL: prev == next\n" );
gustavatmel 1:9c5af431a1f1 168 #endif
gustavatmel 1:9c5af431a1f1 169 return( 1 );
gustavatmel 1:9c5af431a1f1 170 }
gustavatmel 1:9c5af431a1f1 171
gustavatmel 1:9c5af431a1f1 172 if( hdr->prev_free != NULL && hdr->prev_free == hdr->next_free )
gustavatmel 1:9c5af431a1f1 173 {
gustavatmel 1:9c5af431a1f1 174 #if defined(MBEDTLS_MEMORY_DEBUG)
gustavatmel 1:9c5af431a1f1 175 mbedtls_fprintf( stderr, "FATAL: prev_free == next_free\n" );
gustavatmel 1:9c5af431a1f1 176 #endif
gustavatmel 1:9c5af431a1f1 177 return( 1 );
gustavatmel 1:9c5af431a1f1 178 }
gustavatmel 1:9c5af431a1f1 179
gustavatmel 1:9c5af431a1f1 180 return( 0 );
gustavatmel 1:9c5af431a1f1 181 }
gustavatmel 1:9c5af431a1f1 182
gustavatmel 1:9c5af431a1f1 183 static int verify_chain()
gustavatmel 1:9c5af431a1f1 184 {
gustavatmel 1:9c5af431a1f1 185 memory_header *prv = heap.first, *cur = heap.first->next;
gustavatmel 1:9c5af431a1f1 186
gustavatmel 1:9c5af431a1f1 187 if( verify_header( heap.first ) != 0 )
gustavatmel 1:9c5af431a1f1 188 {
gustavatmel 1:9c5af431a1f1 189 #if defined(MBEDTLS_MEMORY_DEBUG)
gustavatmel 1:9c5af431a1f1 190 mbedtls_fprintf( stderr, "FATAL: verification of first header "
gustavatmel 1:9c5af431a1f1 191 "failed\n" );
gustavatmel 1:9c5af431a1f1 192 #endif
gustavatmel 1:9c5af431a1f1 193 return( 1 );
gustavatmel 1:9c5af431a1f1 194 }
gustavatmel 1:9c5af431a1f1 195
gustavatmel 1:9c5af431a1f1 196 if( heap.first->prev != NULL )
gustavatmel 1:9c5af431a1f1 197 {
gustavatmel 1:9c5af431a1f1 198 #if defined(MBEDTLS_MEMORY_DEBUG)
gustavatmel 1:9c5af431a1f1 199 mbedtls_fprintf( stderr, "FATAL: verification failed: "
gustavatmel 1:9c5af431a1f1 200 "first->prev != NULL\n" );
gustavatmel 1:9c5af431a1f1 201 #endif
gustavatmel 1:9c5af431a1f1 202 return( 1 );
gustavatmel 1:9c5af431a1f1 203 }
gustavatmel 1:9c5af431a1f1 204
gustavatmel 1:9c5af431a1f1 205 while( cur != NULL )
gustavatmel 1:9c5af431a1f1 206 {
gustavatmel 1:9c5af431a1f1 207 if( verify_header( cur ) != 0 )
gustavatmel 1:9c5af431a1f1 208 {
gustavatmel 1:9c5af431a1f1 209 #if defined(MBEDTLS_MEMORY_DEBUG)
gustavatmel 1:9c5af431a1f1 210 mbedtls_fprintf( stderr, "FATAL: verification of header "
gustavatmel 1:9c5af431a1f1 211 "failed\n" );
gustavatmel 1:9c5af431a1f1 212 #endif
gustavatmel 1:9c5af431a1f1 213 return( 1 );
gustavatmel 1:9c5af431a1f1 214 }
gustavatmel 1:9c5af431a1f1 215
gustavatmel 1:9c5af431a1f1 216 if( cur->prev != prv )
gustavatmel 1:9c5af431a1f1 217 {
gustavatmel 1:9c5af431a1f1 218 #if defined(MBEDTLS_MEMORY_DEBUG)
gustavatmel 1:9c5af431a1f1 219 mbedtls_fprintf( stderr, "FATAL: verification failed: "
gustavatmel 1:9c5af431a1f1 220 "cur->prev != prv\n" );
gustavatmel 1:9c5af431a1f1 221 #endif
gustavatmel 1:9c5af431a1f1 222 return( 1 );
gustavatmel 1:9c5af431a1f1 223 }
gustavatmel 1:9c5af431a1f1 224
gustavatmel 1:9c5af431a1f1 225 prv = cur;
gustavatmel 1:9c5af431a1f1 226 cur = cur->next;
gustavatmel 1:9c5af431a1f1 227 }
gustavatmel 1:9c5af431a1f1 228
gustavatmel 1:9c5af431a1f1 229 return( 0 );
gustavatmel 1:9c5af431a1f1 230 }
gustavatmel 1:9c5af431a1f1 231
gustavatmel 1:9c5af431a1f1 232 static void *buffer_alloc_calloc( size_t n, size_t size )
gustavatmel 1:9c5af431a1f1 233 {
gustavatmel 1:9c5af431a1f1 234 memory_header *new, *cur = heap.first_free;
gustavatmel 1:9c5af431a1f1 235 unsigned char *p;
gustavatmel 1:9c5af431a1f1 236 void *ret;
gustavatmel 1:9c5af431a1f1 237 size_t original_len, len;
gustavatmel 1:9c5af431a1f1 238 #if defined(MBEDTLS_MEMORY_BACKTRACE)
gustavatmel 1:9c5af431a1f1 239 void *trace_buffer[MAX_BT];
gustavatmel 1:9c5af431a1f1 240 size_t trace_cnt;
gustavatmel 1:9c5af431a1f1 241 #endif
gustavatmel 1:9c5af431a1f1 242
gustavatmel 1:9c5af431a1f1 243 if( heap.buf == NULL || heap.first == NULL )
gustavatmel 1:9c5af431a1f1 244 return( NULL );
gustavatmel 1:9c5af431a1f1 245
gustavatmel 1:9c5af431a1f1 246 original_len = len = n * size;
gustavatmel 1:9c5af431a1f1 247
gustavatmel 1:9c5af431a1f1 248 if( n != 0 && len / n != size )
gustavatmel 1:9c5af431a1f1 249 return( NULL );
gustavatmel 1:9c5af431a1f1 250
gustavatmel 1:9c5af431a1f1 251 if( len % MBEDTLS_MEMORY_ALIGN_MULTIPLE )
gustavatmel 1:9c5af431a1f1 252 {
gustavatmel 1:9c5af431a1f1 253 len -= len % MBEDTLS_MEMORY_ALIGN_MULTIPLE;
gustavatmel 1:9c5af431a1f1 254 len += MBEDTLS_MEMORY_ALIGN_MULTIPLE;
gustavatmel 1:9c5af431a1f1 255 }
gustavatmel 1:9c5af431a1f1 256
gustavatmel 1:9c5af431a1f1 257 // Find block that fits
gustavatmel 1:9c5af431a1f1 258 //
gustavatmel 1:9c5af431a1f1 259 while( cur != NULL )
gustavatmel 1:9c5af431a1f1 260 {
gustavatmel 1:9c5af431a1f1 261 if( cur->size >= len )
gustavatmel 1:9c5af431a1f1 262 break;
gustavatmel 1:9c5af431a1f1 263
gustavatmel 1:9c5af431a1f1 264 cur = cur->next_free;
gustavatmel 1:9c5af431a1f1 265 }
gustavatmel 1:9c5af431a1f1 266
gustavatmel 1:9c5af431a1f1 267 if( cur == NULL )
gustavatmel 1:9c5af431a1f1 268 return( NULL );
gustavatmel 1:9c5af431a1f1 269
gustavatmel 1:9c5af431a1f1 270 if( cur->alloc != 0 )
gustavatmel 1:9c5af431a1f1 271 {
gustavatmel 1:9c5af431a1f1 272 #if defined(MBEDTLS_MEMORY_DEBUG)
gustavatmel 1:9c5af431a1f1 273 mbedtls_fprintf( stderr, "FATAL: block in free_list but allocated "
gustavatmel 1:9c5af431a1f1 274 "data\n" );
gustavatmel 1:9c5af431a1f1 275 #endif
gustavatmel 1:9c5af431a1f1 276 mbedtls_exit( 1 );
gustavatmel 1:9c5af431a1f1 277 }
gustavatmel 1:9c5af431a1f1 278
gustavatmel 1:9c5af431a1f1 279 #if defined(MBEDTLS_MEMORY_DEBUG)
gustavatmel 1:9c5af431a1f1 280 heap.alloc_count++;
gustavatmel 1:9c5af431a1f1 281 #endif
gustavatmel 1:9c5af431a1f1 282
gustavatmel 1:9c5af431a1f1 283 // Found location, split block if > memory_header + 4 room left
gustavatmel 1:9c5af431a1f1 284 //
gustavatmel 1:9c5af431a1f1 285 if( cur->size - len < sizeof(memory_header) +
gustavatmel 1:9c5af431a1f1 286 MBEDTLS_MEMORY_ALIGN_MULTIPLE )
gustavatmel 1:9c5af431a1f1 287 {
gustavatmel 1:9c5af431a1f1 288 cur->alloc = 1;
gustavatmel 1:9c5af431a1f1 289
gustavatmel 1:9c5af431a1f1 290 // Remove from free_list
gustavatmel 1:9c5af431a1f1 291 //
gustavatmel 1:9c5af431a1f1 292 if( cur->prev_free != NULL )
gustavatmel 1:9c5af431a1f1 293 cur->prev_free->next_free = cur->next_free;
gustavatmel 1:9c5af431a1f1 294 else
gustavatmel 1:9c5af431a1f1 295 heap.first_free = cur->next_free;
gustavatmel 1:9c5af431a1f1 296
gustavatmel 1:9c5af431a1f1 297 if( cur->next_free != NULL )
gustavatmel 1:9c5af431a1f1 298 cur->next_free->prev_free = cur->prev_free;
gustavatmel 1:9c5af431a1f1 299
gustavatmel 1:9c5af431a1f1 300 cur->prev_free = NULL;
gustavatmel 1:9c5af431a1f1 301 cur->next_free = NULL;
gustavatmel 1:9c5af431a1f1 302
gustavatmel 1:9c5af431a1f1 303 #if defined(MBEDTLS_MEMORY_DEBUG)
gustavatmel 1:9c5af431a1f1 304 heap.total_used += cur->size;
gustavatmel 1:9c5af431a1f1 305 if( heap.total_used > heap.maximum_used )
gustavatmel 1:9c5af431a1f1 306 heap.maximum_used = heap.total_used;
gustavatmel 1:9c5af431a1f1 307 #endif
gustavatmel 1:9c5af431a1f1 308 #if defined(MBEDTLS_MEMORY_BACKTRACE)
gustavatmel 1:9c5af431a1f1 309 trace_cnt = backtrace( trace_buffer, MAX_BT );
gustavatmel 1:9c5af431a1f1 310 cur->trace = backtrace_symbols( trace_buffer, trace_cnt );
gustavatmel 1:9c5af431a1f1 311 cur->trace_count = trace_cnt;
gustavatmel 1:9c5af431a1f1 312 #endif
gustavatmel 1:9c5af431a1f1 313
gustavatmel 1:9c5af431a1f1 314 if( ( heap.verify & MBEDTLS_MEMORY_VERIFY_ALLOC ) && verify_chain() != 0 )
gustavatmel 1:9c5af431a1f1 315 mbedtls_exit( 1 );
gustavatmel 1:9c5af431a1f1 316
gustavatmel 1:9c5af431a1f1 317 ret = (unsigned char *) cur + sizeof( memory_header );
gustavatmel 1:9c5af431a1f1 318 memset( ret, 0, original_len );
gustavatmel 1:9c5af431a1f1 319
gustavatmel 1:9c5af431a1f1 320 return( ret );
gustavatmel 1:9c5af431a1f1 321 }
gustavatmel 1:9c5af431a1f1 322
gustavatmel 1:9c5af431a1f1 323 p = ( (unsigned char *) cur ) + sizeof(memory_header) + len;
gustavatmel 1:9c5af431a1f1 324 new = (memory_header *) p;
gustavatmel 1:9c5af431a1f1 325
gustavatmel 1:9c5af431a1f1 326 new->size = cur->size - len - sizeof(memory_header);
gustavatmel 1:9c5af431a1f1 327 new->alloc = 0;
gustavatmel 1:9c5af431a1f1 328 new->prev = cur;
gustavatmel 1:9c5af431a1f1 329 new->next = cur->next;
gustavatmel 1:9c5af431a1f1 330 #if defined(MBEDTLS_MEMORY_BACKTRACE)
gustavatmel 1:9c5af431a1f1 331 new->trace = NULL;
gustavatmel 1:9c5af431a1f1 332 new->trace_count = 0;
gustavatmel 1:9c5af431a1f1 333 #endif
gustavatmel 1:9c5af431a1f1 334 new->magic1 = MAGIC1;
gustavatmel 1:9c5af431a1f1 335 new->magic2 = MAGIC2;
gustavatmel 1:9c5af431a1f1 336
gustavatmel 1:9c5af431a1f1 337 if( new->next != NULL )
gustavatmel 1:9c5af431a1f1 338 new->next->prev = new;
gustavatmel 1:9c5af431a1f1 339
gustavatmel 1:9c5af431a1f1 340 // Replace cur with new in free_list
gustavatmel 1:9c5af431a1f1 341 //
gustavatmel 1:9c5af431a1f1 342 new->prev_free = cur->prev_free;
gustavatmel 1:9c5af431a1f1 343 new->next_free = cur->next_free;
gustavatmel 1:9c5af431a1f1 344 if( new->prev_free != NULL )
gustavatmel 1:9c5af431a1f1 345 new->prev_free->next_free = new;
gustavatmel 1:9c5af431a1f1 346 else
gustavatmel 1:9c5af431a1f1 347 heap.first_free = new;
gustavatmel 1:9c5af431a1f1 348
gustavatmel 1:9c5af431a1f1 349 if( new->next_free != NULL )
gustavatmel 1:9c5af431a1f1 350 new->next_free->prev_free = new;
gustavatmel 1:9c5af431a1f1 351
gustavatmel 1:9c5af431a1f1 352 cur->alloc = 1;
gustavatmel 1:9c5af431a1f1 353 cur->size = len;
gustavatmel 1:9c5af431a1f1 354 cur->next = new;
gustavatmel 1:9c5af431a1f1 355 cur->prev_free = NULL;
gustavatmel 1:9c5af431a1f1 356 cur->next_free = NULL;
gustavatmel 1:9c5af431a1f1 357
gustavatmel 1:9c5af431a1f1 358 #if defined(MBEDTLS_MEMORY_DEBUG)
gustavatmel 1:9c5af431a1f1 359 heap.header_count++;
gustavatmel 1:9c5af431a1f1 360 if( heap.header_count > heap.maximum_header_count )
gustavatmel 1:9c5af431a1f1 361 heap.maximum_header_count = heap.header_count;
gustavatmel 1:9c5af431a1f1 362 heap.total_used += cur->size;
gustavatmel 1:9c5af431a1f1 363 if( heap.total_used > heap.maximum_used )
gustavatmel 1:9c5af431a1f1 364 heap.maximum_used = heap.total_used;
gustavatmel 1:9c5af431a1f1 365 #endif
gustavatmel 1:9c5af431a1f1 366 #if defined(MBEDTLS_MEMORY_BACKTRACE)
gustavatmel 1:9c5af431a1f1 367 trace_cnt = backtrace( trace_buffer, MAX_BT );
gustavatmel 1:9c5af431a1f1 368 cur->trace = backtrace_symbols( trace_buffer, trace_cnt );
gustavatmel 1:9c5af431a1f1 369 cur->trace_count = trace_cnt;
gustavatmel 1:9c5af431a1f1 370 #endif
gustavatmel 1:9c5af431a1f1 371
gustavatmel 1:9c5af431a1f1 372 if( ( heap.verify & MBEDTLS_MEMORY_VERIFY_ALLOC ) && verify_chain() != 0 )
gustavatmel 1:9c5af431a1f1 373 mbedtls_exit( 1 );
gustavatmel 1:9c5af431a1f1 374
gustavatmel 1:9c5af431a1f1 375 ret = (unsigned char *) cur + sizeof( memory_header );
gustavatmel 1:9c5af431a1f1 376 memset( ret, 0, original_len );
gustavatmel 1:9c5af431a1f1 377
gustavatmel 1:9c5af431a1f1 378 return( ret );
gustavatmel 1:9c5af431a1f1 379 }
gustavatmel 1:9c5af431a1f1 380
gustavatmel 1:9c5af431a1f1 381 static void buffer_alloc_free( void *ptr )
gustavatmel 1:9c5af431a1f1 382 {
gustavatmel 1:9c5af431a1f1 383 memory_header *hdr, *old = NULL;
gustavatmel 1:9c5af431a1f1 384 unsigned char *p = (unsigned char *) ptr;
gustavatmel 1:9c5af431a1f1 385
gustavatmel 1:9c5af431a1f1 386 if( ptr == NULL || heap.buf == NULL || heap.first == NULL )
gustavatmel 1:9c5af431a1f1 387 return;
gustavatmel 1:9c5af431a1f1 388
gustavatmel 1:9c5af431a1f1 389 if( p < heap.buf || p > heap.buf + heap.len )
gustavatmel 1:9c5af431a1f1 390 {
gustavatmel 1:9c5af431a1f1 391 #if defined(MBEDTLS_MEMORY_DEBUG)
gustavatmel 1:9c5af431a1f1 392 mbedtls_fprintf( stderr, "FATAL: mbedtls_free() outside of managed "
gustavatmel 1:9c5af431a1f1 393 "space\n" );
gustavatmel 1:9c5af431a1f1 394 #endif
gustavatmel 1:9c5af431a1f1 395 mbedtls_exit( 1 );
gustavatmel 1:9c5af431a1f1 396 }
gustavatmel 1:9c5af431a1f1 397
gustavatmel 1:9c5af431a1f1 398 p -= sizeof(memory_header);
gustavatmel 1:9c5af431a1f1 399 hdr = (memory_header *) p;
gustavatmel 1:9c5af431a1f1 400
gustavatmel 1:9c5af431a1f1 401 if( verify_header( hdr ) != 0 )
gustavatmel 1:9c5af431a1f1 402 mbedtls_exit( 1 );
gustavatmel 1:9c5af431a1f1 403
gustavatmel 1:9c5af431a1f1 404 if( hdr->alloc != 1 )
gustavatmel 1:9c5af431a1f1 405 {
gustavatmel 1:9c5af431a1f1 406 #if defined(MBEDTLS_MEMORY_DEBUG)
gustavatmel 1:9c5af431a1f1 407 mbedtls_fprintf( stderr, "FATAL: mbedtls_free() on unallocated "
gustavatmel 1:9c5af431a1f1 408 "data\n" );
gustavatmel 1:9c5af431a1f1 409 #endif
gustavatmel 1:9c5af431a1f1 410 mbedtls_exit( 1 );
gustavatmel 1:9c5af431a1f1 411 }
gustavatmel 1:9c5af431a1f1 412
gustavatmel 1:9c5af431a1f1 413 hdr->alloc = 0;
gustavatmel 1:9c5af431a1f1 414
gustavatmel 1:9c5af431a1f1 415 #if defined(MBEDTLS_MEMORY_DEBUG)
gustavatmel 1:9c5af431a1f1 416 heap.free_count++;
gustavatmel 1:9c5af431a1f1 417 heap.total_used -= hdr->size;
gustavatmel 1:9c5af431a1f1 418 #endif
gustavatmel 1:9c5af431a1f1 419
gustavatmel 1:9c5af431a1f1 420 #if defined(MBEDTLS_MEMORY_BACKTRACE)
gustavatmel 1:9c5af431a1f1 421 free( hdr->trace );
gustavatmel 1:9c5af431a1f1 422 hdr->trace = NULL;
gustavatmel 1:9c5af431a1f1 423 hdr->trace_count = 0;
gustavatmel 1:9c5af431a1f1 424 #endif
gustavatmel 1:9c5af431a1f1 425
gustavatmel 1:9c5af431a1f1 426 // Regroup with block before
gustavatmel 1:9c5af431a1f1 427 //
gustavatmel 1:9c5af431a1f1 428 if( hdr->prev != NULL && hdr->prev->alloc == 0 )
gustavatmel 1:9c5af431a1f1 429 {
gustavatmel 1:9c5af431a1f1 430 #if defined(MBEDTLS_MEMORY_DEBUG)
gustavatmel 1:9c5af431a1f1 431 heap.header_count--;
gustavatmel 1:9c5af431a1f1 432 #endif
gustavatmel 1:9c5af431a1f1 433 hdr->prev->size += sizeof(memory_header) + hdr->size;
gustavatmel 1:9c5af431a1f1 434 hdr->prev->next = hdr->next;
gustavatmel 1:9c5af431a1f1 435 old = hdr;
gustavatmel 1:9c5af431a1f1 436 hdr = hdr->prev;
gustavatmel 1:9c5af431a1f1 437
gustavatmel 1:9c5af431a1f1 438 if( hdr->next != NULL )
gustavatmel 1:9c5af431a1f1 439 hdr->next->prev = hdr;
gustavatmel 1:9c5af431a1f1 440
gustavatmel 1:9c5af431a1f1 441 memset( old, 0, sizeof(memory_header) );
gustavatmel 1:9c5af431a1f1 442 }
gustavatmel 1:9c5af431a1f1 443
gustavatmel 1:9c5af431a1f1 444 // Regroup with block after
gustavatmel 1:9c5af431a1f1 445 //
gustavatmel 1:9c5af431a1f1 446 if( hdr->next != NULL && hdr->next->alloc == 0 )
gustavatmel 1:9c5af431a1f1 447 {
gustavatmel 1:9c5af431a1f1 448 #if defined(MBEDTLS_MEMORY_DEBUG)
gustavatmel 1:9c5af431a1f1 449 heap.header_count--;
gustavatmel 1:9c5af431a1f1 450 #endif
gustavatmel 1:9c5af431a1f1 451 hdr->size += sizeof(memory_header) + hdr->next->size;
gustavatmel 1:9c5af431a1f1 452 old = hdr->next;
gustavatmel 1:9c5af431a1f1 453 hdr->next = hdr->next->next;
gustavatmel 1:9c5af431a1f1 454
gustavatmel 1:9c5af431a1f1 455 if( hdr->prev_free != NULL || hdr->next_free != NULL )
gustavatmel 1:9c5af431a1f1 456 {
gustavatmel 1:9c5af431a1f1 457 if( hdr->prev_free != NULL )
gustavatmel 1:9c5af431a1f1 458 hdr->prev_free->next_free = hdr->next_free;
gustavatmel 1:9c5af431a1f1 459 else
gustavatmel 1:9c5af431a1f1 460 heap.first_free = hdr->next_free;
gustavatmel 1:9c5af431a1f1 461
gustavatmel 1:9c5af431a1f1 462 if( hdr->next_free != NULL )
gustavatmel 1:9c5af431a1f1 463 hdr->next_free->prev_free = hdr->prev_free;
gustavatmel 1:9c5af431a1f1 464 }
gustavatmel 1:9c5af431a1f1 465
gustavatmel 1:9c5af431a1f1 466 hdr->prev_free = old->prev_free;
gustavatmel 1:9c5af431a1f1 467 hdr->next_free = old->next_free;
gustavatmel 1:9c5af431a1f1 468
gustavatmel 1:9c5af431a1f1 469 if( hdr->prev_free != NULL )
gustavatmel 1:9c5af431a1f1 470 hdr->prev_free->next_free = hdr;
gustavatmel 1:9c5af431a1f1 471 else
gustavatmel 1:9c5af431a1f1 472 heap.first_free = hdr;
gustavatmel 1:9c5af431a1f1 473
gustavatmel 1:9c5af431a1f1 474 if( hdr->next_free != NULL )
gustavatmel 1:9c5af431a1f1 475 hdr->next_free->prev_free = hdr;
gustavatmel 1:9c5af431a1f1 476
gustavatmel 1:9c5af431a1f1 477 if( hdr->next != NULL )
gustavatmel 1:9c5af431a1f1 478 hdr->next->prev = hdr;
gustavatmel 1:9c5af431a1f1 479
gustavatmel 1:9c5af431a1f1 480 memset( old, 0, sizeof(memory_header) );
gustavatmel 1:9c5af431a1f1 481 }
gustavatmel 1:9c5af431a1f1 482
gustavatmel 1:9c5af431a1f1 483 // Prepend to free_list if we have not merged
gustavatmel 1:9c5af431a1f1 484 // (Does not have to stay in same order as prev / next list)
gustavatmel 1:9c5af431a1f1 485 //
gustavatmel 1:9c5af431a1f1 486 if( old == NULL )
gustavatmel 1:9c5af431a1f1 487 {
gustavatmel 1:9c5af431a1f1 488 hdr->next_free = heap.first_free;
gustavatmel 1:9c5af431a1f1 489 if( heap.first_free != NULL )
gustavatmel 1:9c5af431a1f1 490 heap.first_free->prev_free = hdr;
gustavatmel 1:9c5af431a1f1 491 heap.first_free = hdr;
gustavatmel 1:9c5af431a1f1 492 }
gustavatmel 1:9c5af431a1f1 493
gustavatmel 1:9c5af431a1f1 494 if( ( heap.verify & MBEDTLS_MEMORY_VERIFY_FREE ) && verify_chain() != 0 )
gustavatmel 1:9c5af431a1f1 495 mbedtls_exit( 1 );
gustavatmel 1:9c5af431a1f1 496 }
gustavatmel 1:9c5af431a1f1 497
gustavatmel 1:9c5af431a1f1 498 void mbedtls_memory_buffer_set_verify( int verify )
gustavatmel 1:9c5af431a1f1 499 {
gustavatmel 1:9c5af431a1f1 500 heap.verify = verify;
gustavatmel 1:9c5af431a1f1 501 }
gustavatmel 1:9c5af431a1f1 502
gustavatmel 1:9c5af431a1f1 503 int mbedtls_memory_buffer_alloc_verify()
gustavatmel 1:9c5af431a1f1 504 {
gustavatmel 1:9c5af431a1f1 505 return verify_chain();
gustavatmel 1:9c5af431a1f1 506 }
gustavatmel 1:9c5af431a1f1 507
gustavatmel 1:9c5af431a1f1 508 #if defined(MBEDTLS_MEMORY_DEBUG)
gustavatmel 1:9c5af431a1f1 509 void mbedtls_memory_buffer_alloc_status()
gustavatmel 1:9c5af431a1f1 510 {
gustavatmel 1:9c5af431a1f1 511 mbedtls_fprintf( stderr,
gustavatmel 1:9c5af431a1f1 512 "Current use: %zu blocks / %zu bytes, max: %zu blocks / "
gustavatmel 1:9c5af431a1f1 513 "%zu bytes (total %zu bytes), alloc / free: %zu / %zu\n",
gustavatmel 1:9c5af431a1f1 514 heap.header_count, heap.total_used,
gustavatmel 1:9c5af431a1f1 515 heap.maximum_header_count, heap.maximum_used,
gustavatmel 1:9c5af431a1f1 516 heap.maximum_header_count * sizeof( memory_header )
gustavatmel 1:9c5af431a1f1 517 + heap.maximum_used,
gustavatmel 1:9c5af431a1f1 518 heap.alloc_count, heap.free_count );
gustavatmel 1:9c5af431a1f1 519
gustavatmel 1:9c5af431a1f1 520 if( heap.first->next == NULL )
gustavatmel 1:9c5af431a1f1 521 mbedtls_fprintf( stderr, "All memory de-allocated in stack buffer\n" );
gustavatmel 1:9c5af431a1f1 522 else
gustavatmel 1:9c5af431a1f1 523 {
gustavatmel 1:9c5af431a1f1 524 mbedtls_fprintf( stderr, "Memory currently allocated:\n" );
gustavatmel 1:9c5af431a1f1 525 debug_chain();
gustavatmel 1:9c5af431a1f1 526 }
gustavatmel 1:9c5af431a1f1 527 }
gustavatmel 1:9c5af431a1f1 528
gustavatmel 1:9c5af431a1f1 529 void mbedtls_memory_buffer_alloc_max_get( size_t *max_used, size_t *max_blocks )
gustavatmel 1:9c5af431a1f1 530 {
gustavatmel 1:9c5af431a1f1 531 *max_used = heap.maximum_used;
gustavatmel 1:9c5af431a1f1 532 *max_blocks = heap.maximum_header_count;
gustavatmel 1:9c5af431a1f1 533 }
gustavatmel 1:9c5af431a1f1 534
gustavatmel 1:9c5af431a1f1 535 void mbedtls_memory_buffer_alloc_max_reset( void )
gustavatmel 1:9c5af431a1f1 536 {
gustavatmel 1:9c5af431a1f1 537 heap.maximum_used = 0;
gustavatmel 1:9c5af431a1f1 538 heap.maximum_header_count = 0;
gustavatmel 1:9c5af431a1f1 539 }
gustavatmel 1:9c5af431a1f1 540
gustavatmel 1:9c5af431a1f1 541 void mbedtls_memory_buffer_alloc_cur_get( size_t *cur_used, size_t *cur_blocks )
gustavatmel 1:9c5af431a1f1 542 {
gustavatmel 1:9c5af431a1f1 543 *cur_used = heap.total_used;
gustavatmel 1:9c5af431a1f1 544 *cur_blocks = heap.header_count;
gustavatmel 1:9c5af431a1f1 545 }
gustavatmel 1:9c5af431a1f1 546 #endif /* MBEDTLS_MEMORY_DEBUG */
gustavatmel 1:9c5af431a1f1 547
gustavatmel 1:9c5af431a1f1 548 #if defined(MBEDTLS_THREADING_C)
gustavatmel 1:9c5af431a1f1 549 static void *buffer_alloc_calloc_mutexed( size_t n, size_t size )
gustavatmel 1:9c5af431a1f1 550 {
gustavatmel 1:9c5af431a1f1 551 void *buf;
gustavatmel 1:9c5af431a1f1 552 if( mbedtls_mutex_lock( &heap.mutex ) != 0 )
gustavatmel 1:9c5af431a1f1 553 return( NULL );
gustavatmel 1:9c5af431a1f1 554 buf = buffer_alloc_calloc( n, size );
gustavatmel 1:9c5af431a1f1 555 if( mbedtls_mutex_unlock( &heap.mutex ) )
gustavatmel 1:9c5af431a1f1 556 return( NULL );
gustavatmel 1:9c5af431a1f1 557 return( buf );
gustavatmel 1:9c5af431a1f1 558 }
gustavatmel 1:9c5af431a1f1 559
gustavatmel 1:9c5af431a1f1 560 static void buffer_alloc_free_mutexed( void *ptr )
gustavatmel 1:9c5af431a1f1 561 {
gustavatmel 1:9c5af431a1f1 562 /* We have to good option here, but corrupting the heap seems
gustavatmel 1:9c5af431a1f1 563 * worse than loosing memory. */
gustavatmel 1:9c5af431a1f1 564 if( mbedtls_mutex_lock( &heap.mutex ) )
gustavatmel 1:9c5af431a1f1 565 return;
gustavatmel 1:9c5af431a1f1 566 buffer_alloc_free( ptr );
gustavatmel 1:9c5af431a1f1 567 (void) mbedtls_mutex_unlock( &heap.mutex );
gustavatmel 1:9c5af431a1f1 568 }
gustavatmel 1:9c5af431a1f1 569 #endif /* MBEDTLS_THREADING_C */
gustavatmel 1:9c5af431a1f1 570
gustavatmel 1:9c5af431a1f1 571 void mbedtls_memory_buffer_alloc_init( unsigned char *buf, size_t len )
gustavatmel 1:9c5af431a1f1 572 {
gustavatmel 1:9c5af431a1f1 573 memset( &heap, 0, sizeof(buffer_alloc_ctx) );
gustavatmel 1:9c5af431a1f1 574 memset( buf, 0, len );
gustavatmel 1:9c5af431a1f1 575
gustavatmel 1:9c5af431a1f1 576 #if defined(MBEDTLS_THREADING_C)
gustavatmel 1:9c5af431a1f1 577 mbedtls_mutex_init( &heap.mutex );
gustavatmel 1:9c5af431a1f1 578 mbedtls_platform_set_calloc_free( buffer_alloc_calloc_mutexed,
gustavatmel 1:9c5af431a1f1 579 buffer_alloc_free_mutexed );
gustavatmel 1:9c5af431a1f1 580 #else
gustavatmel 1:9c5af431a1f1 581 mbedtls_platform_set_calloc_free( buffer_alloc_calloc, buffer_alloc_free );
gustavatmel 1:9c5af431a1f1 582 #endif
gustavatmel 1:9c5af431a1f1 583
gustavatmel 1:9c5af431a1f1 584 if( (size_t) buf % MBEDTLS_MEMORY_ALIGN_MULTIPLE )
gustavatmel 1:9c5af431a1f1 585 {
gustavatmel 1:9c5af431a1f1 586 /* Adjust len first since buf is used in the computation */
gustavatmel 1:9c5af431a1f1 587 len -= MBEDTLS_MEMORY_ALIGN_MULTIPLE
gustavatmel 1:9c5af431a1f1 588 - (size_t) buf % MBEDTLS_MEMORY_ALIGN_MULTIPLE;
gustavatmel 1:9c5af431a1f1 589 buf += MBEDTLS_MEMORY_ALIGN_MULTIPLE
gustavatmel 1:9c5af431a1f1 590 - (size_t) buf % MBEDTLS_MEMORY_ALIGN_MULTIPLE;
gustavatmel 1:9c5af431a1f1 591 }
gustavatmel 1:9c5af431a1f1 592
gustavatmel 1:9c5af431a1f1 593 heap.buf = buf;
gustavatmel 1:9c5af431a1f1 594 heap.len = len;
gustavatmel 1:9c5af431a1f1 595
gustavatmel 1:9c5af431a1f1 596 heap.first = (memory_header *) buf;
gustavatmel 1:9c5af431a1f1 597 heap.first->size = len - sizeof(memory_header);
gustavatmel 1:9c5af431a1f1 598 heap.first->magic1 = MAGIC1;
gustavatmel 1:9c5af431a1f1 599 heap.first->magic2 = MAGIC2;
gustavatmel 1:9c5af431a1f1 600 heap.first_free = heap.first;
gustavatmel 1:9c5af431a1f1 601 }
gustavatmel 1:9c5af431a1f1 602
gustavatmel 1:9c5af431a1f1 603 void mbedtls_memory_buffer_alloc_free()
gustavatmel 1:9c5af431a1f1 604 {
gustavatmel 1:9c5af431a1f1 605 #if defined(MBEDTLS_THREADING_C)
gustavatmel 1:9c5af431a1f1 606 mbedtls_mutex_free( &heap.mutex );
gustavatmel 1:9c5af431a1f1 607 #endif
gustavatmel 1:9c5af431a1f1 608 mbedtls_zeroize( &heap, sizeof(buffer_alloc_ctx) );
gustavatmel 1:9c5af431a1f1 609 }
gustavatmel 1:9c5af431a1f1 610
gustavatmel 1:9c5af431a1f1 611 #if defined(MBEDTLS_SELF_TEST)
gustavatmel 1:9c5af431a1f1 612 static int check_pointer( void *p )
gustavatmel 1:9c5af431a1f1 613 {
gustavatmel 1:9c5af431a1f1 614 if( p == NULL )
gustavatmel 1:9c5af431a1f1 615 return( -1 );
gustavatmel 1:9c5af431a1f1 616
gustavatmel 1:9c5af431a1f1 617 if( (size_t) p % MBEDTLS_MEMORY_ALIGN_MULTIPLE != 0 )
gustavatmel 1:9c5af431a1f1 618 return( -1 );
gustavatmel 1:9c5af431a1f1 619
gustavatmel 1:9c5af431a1f1 620 return( 0 );
gustavatmel 1:9c5af431a1f1 621 }
gustavatmel 1:9c5af431a1f1 622
gustavatmel 1:9c5af431a1f1 623 static int check_all_free( )
gustavatmel 1:9c5af431a1f1 624 {
gustavatmel 1:9c5af431a1f1 625 if(
gustavatmel 1:9c5af431a1f1 626 #if defined(MBEDTLS_MEMORY_DEBUG)
gustavatmel 1:9c5af431a1f1 627 heap.total_used != 0 ||
gustavatmel 1:9c5af431a1f1 628 #endif
gustavatmel 1:9c5af431a1f1 629 heap.first != heap.first_free ||
gustavatmel 1:9c5af431a1f1 630 (void *) heap.first != (void *) heap.buf )
gustavatmel 1:9c5af431a1f1 631 {
gustavatmel 1:9c5af431a1f1 632 return( -1 );
gustavatmel 1:9c5af431a1f1 633 }
gustavatmel 1:9c5af431a1f1 634
gustavatmel 1:9c5af431a1f1 635 return( 0 );
gustavatmel 1:9c5af431a1f1 636 }
gustavatmel 1:9c5af431a1f1 637
gustavatmel 1:9c5af431a1f1 638 #define TEST_ASSERT( condition ) \
gustavatmel 1:9c5af431a1f1 639 if( ! (condition) ) \
gustavatmel 1:9c5af431a1f1 640 { \
gustavatmel 1:9c5af431a1f1 641 if( verbose != 0 ) \
gustavatmel 1:9c5af431a1f1 642 mbedtls_printf( "failed\n" ); \
gustavatmel 1:9c5af431a1f1 643 \
gustavatmel 1:9c5af431a1f1 644 ret = 1; \
gustavatmel 1:9c5af431a1f1 645 goto cleanup; \
gustavatmel 1:9c5af431a1f1 646 }
gustavatmel 1:9c5af431a1f1 647
gustavatmel 1:9c5af431a1f1 648 int mbedtls_memory_buffer_alloc_self_test( int verbose )
gustavatmel 1:9c5af431a1f1 649 {
gustavatmel 1:9c5af431a1f1 650 unsigned char buf[1024];
gustavatmel 1:9c5af431a1f1 651 unsigned char *p, *q, *r, *end;
gustavatmel 1:9c5af431a1f1 652 int ret = 0;
gustavatmel 1:9c5af431a1f1 653
gustavatmel 1:9c5af431a1f1 654 if( verbose != 0 )
gustavatmel 1:9c5af431a1f1 655 mbedtls_printf( " MBA test #1 (basic alloc-free cycle): " );
gustavatmel 1:9c5af431a1f1 656
gustavatmel 1:9c5af431a1f1 657 mbedtls_memory_buffer_alloc_init( buf, sizeof( buf ) );
gustavatmel 1:9c5af431a1f1 658
gustavatmel 1:9c5af431a1f1 659 p = mbedtls_calloc( 1, 1 );
gustavatmel 1:9c5af431a1f1 660 q = mbedtls_calloc( 1, 128 );
gustavatmel 1:9c5af431a1f1 661 r = mbedtls_calloc( 1, 16 );
gustavatmel 1:9c5af431a1f1 662
gustavatmel 1:9c5af431a1f1 663 TEST_ASSERT( check_pointer( p ) == 0 &&
gustavatmel 1:9c5af431a1f1 664 check_pointer( q ) == 0 &&
gustavatmel 1:9c5af431a1f1 665 check_pointer( r ) == 0 );
gustavatmel 1:9c5af431a1f1 666
gustavatmel 1:9c5af431a1f1 667 mbedtls_free( r );
gustavatmel 1:9c5af431a1f1 668 mbedtls_free( q );
gustavatmel 1:9c5af431a1f1 669 mbedtls_free( p );
gustavatmel 1:9c5af431a1f1 670
gustavatmel 1:9c5af431a1f1 671 TEST_ASSERT( check_all_free( ) == 0 );
gustavatmel 1:9c5af431a1f1 672
gustavatmel 1:9c5af431a1f1 673 /* Memorize end to compare with the next test */
gustavatmel 1:9c5af431a1f1 674 end = heap.buf + heap.len;
gustavatmel 1:9c5af431a1f1 675
gustavatmel 1:9c5af431a1f1 676 mbedtls_memory_buffer_alloc_free( );
gustavatmel 1:9c5af431a1f1 677
gustavatmel 1:9c5af431a1f1 678 if( verbose != 0 )
gustavatmel 1:9c5af431a1f1 679 mbedtls_printf( "passed\n" );
gustavatmel 1:9c5af431a1f1 680
gustavatmel 1:9c5af431a1f1 681 if( verbose != 0 )
gustavatmel 1:9c5af431a1f1 682 mbedtls_printf( " MBA test #2 (buf not aligned): " );
gustavatmel 1:9c5af431a1f1 683
gustavatmel 1:9c5af431a1f1 684 mbedtls_memory_buffer_alloc_init( buf + 1, sizeof( buf ) - 1 );
gustavatmel 1:9c5af431a1f1 685
gustavatmel 1:9c5af431a1f1 686 TEST_ASSERT( heap.buf + heap.len == end );
gustavatmel 1:9c5af431a1f1 687
gustavatmel 1:9c5af431a1f1 688 p = mbedtls_calloc( 1, 1 );
gustavatmel 1:9c5af431a1f1 689 q = mbedtls_calloc( 1, 128 );
gustavatmel 1:9c5af431a1f1 690 r = mbedtls_calloc( 1, 16 );
gustavatmel 1:9c5af431a1f1 691
gustavatmel 1:9c5af431a1f1 692 TEST_ASSERT( check_pointer( p ) == 0 &&
gustavatmel 1:9c5af431a1f1 693 check_pointer( q ) == 0 &&
gustavatmel 1:9c5af431a1f1 694 check_pointer( r ) == 0 );
gustavatmel 1:9c5af431a1f1 695
gustavatmel 1:9c5af431a1f1 696 mbedtls_free( r );
gustavatmel 1:9c5af431a1f1 697 mbedtls_free( q );
gustavatmel 1:9c5af431a1f1 698 mbedtls_free( p );
gustavatmel 1:9c5af431a1f1 699
gustavatmel 1:9c5af431a1f1 700 TEST_ASSERT( check_all_free( ) == 0 );
gustavatmel 1:9c5af431a1f1 701
gustavatmel 1:9c5af431a1f1 702 mbedtls_memory_buffer_alloc_free( );
gustavatmel 1:9c5af431a1f1 703
gustavatmel 1:9c5af431a1f1 704 if( verbose != 0 )
gustavatmel 1:9c5af431a1f1 705 mbedtls_printf( "passed\n" );
gustavatmel 1:9c5af431a1f1 706
gustavatmel 1:9c5af431a1f1 707 if( verbose != 0 )
gustavatmel 1:9c5af431a1f1 708 mbedtls_printf( " MBA test #3 (full): " );
gustavatmel 1:9c5af431a1f1 709
gustavatmel 1:9c5af431a1f1 710 mbedtls_memory_buffer_alloc_init( buf, sizeof( buf ) );
gustavatmel 1:9c5af431a1f1 711
gustavatmel 1:9c5af431a1f1 712 p = mbedtls_calloc( 1, sizeof( buf ) - sizeof( memory_header ) );
gustavatmel 1:9c5af431a1f1 713
gustavatmel 1:9c5af431a1f1 714 TEST_ASSERT( check_pointer( p ) == 0 );
gustavatmel 1:9c5af431a1f1 715 TEST_ASSERT( mbedtls_calloc( 1, 1 ) == NULL );
gustavatmel 1:9c5af431a1f1 716
gustavatmel 1:9c5af431a1f1 717 mbedtls_free( p );
gustavatmel 1:9c5af431a1f1 718
gustavatmel 1:9c5af431a1f1 719 p = mbedtls_calloc( 1, sizeof( buf ) - 2 * sizeof( memory_header ) - 16 );
gustavatmel 1:9c5af431a1f1 720 q = mbedtls_calloc( 1, 16 );
gustavatmel 1:9c5af431a1f1 721
gustavatmel 1:9c5af431a1f1 722 TEST_ASSERT( check_pointer( p ) == 0 && check_pointer( q ) == 0 );
gustavatmel 1:9c5af431a1f1 723 TEST_ASSERT( mbedtls_calloc( 1, 1 ) == NULL );
gustavatmel 1:9c5af431a1f1 724
gustavatmel 1:9c5af431a1f1 725 mbedtls_free( q );
gustavatmel 1:9c5af431a1f1 726
gustavatmel 1:9c5af431a1f1 727 TEST_ASSERT( mbedtls_calloc( 1, 17 ) == NULL );
gustavatmel 1:9c5af431a1f1 728
gustavatmel 1:9c5af431a1f1 729 mbedtls_free( p );
gustavatmel 1:9c5af431a1f1 730
gustavatmel 1:9c5af431a1f1 731 TEST_ASSERT( check_all_free( ) == 0 );
gustavatmel 1:9c5af431a1f1 732
gustavatmel 1:9c5af431a1f1 733 mbedtls_memory_buffer_alloc_free( );
gustavatmel 1:9c5af431a1f1 734
gustavatmel 1:9c5af431a1f1 735 if( verbose != 0 )
gustavatmel 1:9c5af431a1f1 736 mbedtls_printf( "passed\n" );
gustavatmel 1:9c5af431a1f1 737
gustavatmel 1:9c5af431a1f1 738 cleanup:
gustavatmel 1:9c5af431a1f1 739 mbedtls_memory_buffer_alloc_free( );
gustavatmel 1:9c5af431a1f1 740
gustavatmel 1:9c5af431a1f1 741 return( ret );
gustavatmel 1:9c5af431a1f1 742 }
gustavatmel 1:9c5af431a1f1 743 #endif /* MBEDTLS_SELF_TEST */
gustavatmel 1:9c5af431a1f1 744
gustavatmel 1:9c5af431a1f1 745 #endif /* MBEDTLS_MEMORY_BUFFER_ALLOC_C */