1 /*++ 2 3 Copyright (c) 2004, Intel Corporation. All rights reserved.<BR> 4 This program and the accompanying materials 5 are licensed and made available under the terms and conditions of the BSD License 6 which accompanies this distribution. The full text of the license may be found at 7 http://opensource.org/licenses/bsd-license.php 8 9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 11 12 Module Name: 13 14 MyAlloc.c 15 16 Abstract: 17 18 File for memory allocation tracking functions. 19 20 --*/ 21 22 #include "MyAlloc.h" 23 24 #if USE_MYALLOC 25 // 26 // Get back to original alloc/free calls. 27 // 28 #undef malloc 29 #undef calloc 30 #undef realloc 31 #undef free 32 // 33 // Start of allocation list. 34 // 35 static MY_ALLOC_STRUCT *MyAllocData = NULL; 36 37 // 38 // 39 // 40 static UINT32 MyAllocHeadMagik = MYALLOC_HEAD_MAGIK; 41 static UINT32 MyAllocTailMagik = MYALLOC_TAIL_MAGIK; 42 43 // 44 // //////////////////////////////////////////////////////////////////////////// 45 // 46 // 47 VOID 48 MyCheck ( 49 BOOLEAN Final, 50 UINT8 File[], 51 UINTN Line 52 ) 53 // *++ 54 // Description: 55 // 56 // Check for corruptions in the allocated memory chain. If a corruption 57 // is detection program operation stops w/ an exit(1) call. 58 // 59 // Parameters: 60 // 61 // Final := When FALSE, MyCheck() returns if the allocated memory chain 62 // has not been corrupted. When TRUE, MyCheck() returns if there 63 // are no un-freed allocations. If there are un-freed allocations, 64 // they are displayed and exit(1) is called. 65 // 66 // 67 // File := Set to __FILE__ by macro expansion. 68 // 69 // Line := Set to __LINE__ by macro expansion. 70 // 71 // Returns: 72 // 73 // n/a 74 // 75 // --*/ 76 // 77 { 78 MY_ALLOC_STRUCT *Tmp; 79 80 // 81 // Check parameters. 82 // 83 if (File == NULL || Line == 0) { 84 printf ( 85 "\nMyCheck(Final=%u, File=%xh, Line=%u)" 86 "Invalid parameter(s).\n", 87 Final, 88 File, 89 Line 90 ); 91 92 exit (1); 93 } 94 95 if (strlen (File) == 0) { 96 printf ( 97 "\nMyCheck(Final=%u, File=%s, Line=%u)" 98 "Invalid parameter.\n", 99 Final, 100 File, 101 Line 102 ); 103 104 exit (1); 105 } 106 // 107 // Check structure contents. 108 // 109 for (Tmp = MyAllocData; Tmp != NULL; Tmp = Tmp->Next) { 110 if (memcmp(Tmp->Buffer, &MyAllocHeadMagik, sizeof MyAllocHeadMagik) || 111 memcmp(&Tmp->Buffer[Tmp->Size + sizeof(UINT32)], &MyAllocTailMagik, sizeof MyAllocTailMagik)) { 112 break; 113 } 114 } 115 // 116 // If Tmp is not NULL, the structure is corrupt. 117 // 118 if (Tmp != NULL) { 119 printf ( 120 "\nMyCheck(Final=%u, File=%s, Line=%u)""\nStructure corrupted!" 121 "\nFile=%s, Line=%u, nSize=%u, Head=%xh, Tail=%xh\n", 122 Final, 123 File, 124 Line, 125 Tmp->File, 126 Tmp->Line, 127 Tmp->Size, 128 *(UINT32 *) (Tmp->Buffer), 129 *(UINT32 *) (&Tmp->Buffer[Tmp->Size + sizeof (UINT32)]) 130 ); 131 132 exit (1); 133 } 134 // 135 // If Final is TRUE, display the state of the structure chain. 136 // 137 if (Final) { 138 if (MyAllocData != NULL) { 139 printf ( 140 "\nMyCheck(Final=%u, File=%s, Line=%u)" 141 "\nSome allocated items have not been freed.\n", 142 Final, 143 File, 144 Line 145 ); 146 147 for (Tmp = MyAllocData; Tmp != NULL; Tmp = Tmp->Next) { 148 printf ( 149 "File=%s, Line=%u, nSize=%u, Head=%xh, Tail=%xh\n", 150 Tmp->File, 151 Tmp->Line, 152 Tmp->Size, 153 *(UINT32 *) (Tmp->Buffer), 154 *(UINT32 *) (&Tmp->Buffer[Tmp->Size + sizeof (UINT32)]) 155 ); 156 } 157 } 158 } 159 } 160 // 161 // //////////////////////////////////////////////////////////////////////////// 162 // 163 // 164 VOID * 165 MyAlloc ( 166 UINTN Size, 167 UINT8 File[], 168 UINTN Line 169 ) 170 // *++ 171 // Description: 172 // 173 // Allocate a new link in the allocation chain along with enough storage 174 // for the File[] string, requested Size and alignment overhead. If 175 // memory cannot be allocated or the allocation chain has been corrupted, 176 // exit(1) will be called. 177 // 178 // Parameters: 179 // 180 // Size := Number of bytes (UINT8) requested by the called. 181 // Size cannot be zero. 182 // 183 // File := Set to __FILE__ by macro expansion. 184 // 185 // Line := Set to __LINE__ by macro expansion. 186 // 187 // Returns: 188 // 189 // Pointer to the caller's buffer. 190 // 191 // --*/ 192 // 193 { 194 MY_ALLOC_STRUCT *Tmp; 195 UINTN Len; 196 197 // 198 // Check for invalid parameters. 199 // 200 if (Size == 0 || File == NULL || Line == 0) { 201 printf ( 202 "\nMyAlloc(Size=%u, File=%xh, Line=%u)" 203 "\nInvalid parameter(s).\n", 204 Size, 205 File, 206 Line 207 ); 208 209 exit (1); 210 } 211 212 Len = strlen (File); 213 if (Len == 0) { 214 printf ( 215 "\nMyAlloc(Size=%u, File=%s, Line=%u)" 216 "\nInvalid parameter.\n", 217 Size, 218 File, 219 Line 220 ); 221 222 exit (1); 223 } 224 // 225 // Check the allocation list for corruption. 226 // 227 MyCheck (0, __FILE__, __LINE__); 228 229 // 230 // Allocate a new entry. 231 // 232 Tmp = calloc ( 233 1, 234 sizeof (MY_ALLOC_STRUCT) + Len + 1 + sizeof (UINT64) + Size + (sizeof MyAllocHeadMagik) + (sizeof MyAllocTailMagik) 235 ); 236 237 if (Tmp == NULL) { 238 printf ( 239 "\nMyAlloc(Size=%u, File=%s, Line=%u)" 240 "\nOut of memory.\n", 241 Size, 242 File, 243 Line 244 ); 245 246 exit (1); 247 } 248 // 249 // Fill in the new entry. 250 // 251 Tmp->File = ((UINT8 *) Tmp) + sizeof (MY_ALLOC_STRUCT); 252 strcpy (Tmp->File, File); 253 Tmp->Line = Line; 254 Tmp->Size = Size; 255 Tmp->Buffer = (UINT8 *) (((UINTN) Tmp + Len + 9) &~7); 256 257 memcpy (Tmp->Buffer, &MyAllocHeadMagik, sizeof MyAllocHeadMagik); 258 259 memcpy ( 260 &Tmp->Buffer[Size + sizeof (UINT32)], 261 &MyAllocTailMagik, 262 sizeof MyAllocTailMagik 263 ); 264 265 Tmp->Next = MyAllocData; 266 Tmp->Cksum = (UINTN) Tmp + (UINTN) (Tmp->Next) + Tmp->Line + Tmp->Size + (UINTN) (Tmp->File) + (UINTN) (Tmp->Buffer); 267 268 MyAllocData = Tmp; 269 270 return Tmp->Buffer + sizeof (UINT32); 271 } 272 // 273 // //////////////////////////////////////////////////////////////////////////// 274 // 275 // 276 VOID * 277 MyRealloc ( 278 VOID *Ptr, 279 UINTN Size, 280 UINT8 File[], 281 UINTN Line 282 ) 283 // *++ 284 // Description: 285 // 286 // This does a MyAlloc(), memcpy() and MyFree(). There is no optimization 287 // for shrinking or expanding buffers. An invalid parameter will cause 288 // MyRealloc() to fail with a call to exit(1). 289 // 290 // Parameters: 291 // 292 // Ptr := Pointer to the caller's buffer to be re-allocated. 293 // 294 // Size := Size of new buffer. Size cannot be zero. 295 // 296 // File := Set to __FILE__ by macro expansion. 297 // 298 // Line := Set to __LINE__ by macro expansion. 299 // 300 // Returns: 301 // 302 // Pointer to new caller's buffer. 303 // 304 // --*/ 305 // 306 { 307 MY_ALLOC_STRUCT *Tmp; 308 VOID *Buffer; 309 310 // 311 // Check for invalid parameter(s). 312 // 313 if (Size == 0 || File == NULL || Line == 0) { 314 printf ( 315 "\nMyRealloc(Ptr=%xh, Size=%u, File=%xh, Line=%u)" 316 "\nInvalid parameter(s).\n", 317 Ptr, 318 Size, 319 File, 320 Line 321 ); 322 323 exit (1); 324 } 325 326 if (strlen (File) == 0) { 327 printf ( 328 "\nMyRealloc(Ptr=%xh, Size=%u, File=%s, Line=%u)" 329 "\nInvalid parameter.\n", 330 Ptr, 331 Size, 332 File, 333 Line 334 ); 335 336 exit (1); 337 } 338 // 339 // Find existing buffer in allocation list. 340 // 341 if (Ptr == NULL) { 342 Tmp = NULL; 343 } else if (&MyAllocData->Buffer[sizeof (UINT32)] == Ptr) { 344 Tmp = MyAllocData; 345 } else { 346 for (Tmp = MyAllocData;; Tmp = Tmp->Next) { 347 if (Tmp->Next == NULL) { 348 printf ( 349 "\nMyRealloc(Ptr=%xh, Size=%u, File=%s, Line=%u)" 350 "\nCould not find buffer.\n", 351 Ptr, 352 Size, 353 File, 354 Line 355 ); 356 357 exit (1); 358 } 359 360 Tmp = Tmp->Next; 361 } 362 } 363 // 364 // Allocate new buffer, copy old data, free old buffer. 365 // 366 Buffer = MyAlloc (Size, File, Line); 367 368 if (Buffer != NULL && Tmp != NULL) { 369 memcpy ( 370 Buffer, 371 &Tmp->Buffer[sizeof (UINT32)], 372 ((Size <= Tmp->Size) ? Size : Tmp->Size) 373 ); 374 375 MyFree (Ptr, __FILE__, __LINE__); 376 } 377 378 return Buffer; 379 } 380 // 381 // //////////////////////////////////////////////////////////////////////////// 382 // 383 // 384 VOID 385 MyFree ( 386 VOID *Ptr, 387 UINT8 File[], 388 UINTN Line 389 ) 390 // *++ 391 // Description: 392 // 393 // Release a previously allocated buffer. Invalid parameters will cause 394 // MyFree() to fail with an exit(1) call. 395 // 396 // Parameters: 397 // 398 // Ptr := Pointer to the caller's buffer to be freed. 399 // A NULL pointer will be ignored. 400 // 401 // File := Set to __FILE__ by macro expansion. 402 // 403 // Line := Set to __LINE__ by macro expansion. 404 // 405 // Returns: 406 // 407 // n/a 408 // 409 // --*/ 410 // 411 { 412 MY_ALLOC_STRUCT *Tmp; 413 MY_ALLOC_STRUCT *Tmp2; 414 415 // 416 // Check for invalid parameter(s). 417 // 418 if (File == NULL || Line == 0) { 419 printf ( 420 "\nMyFree(Ptr=%xh, File=%xh, Line=%u)" 421 "\nInvalid parameter(s).\n", 422 Ptr, 423 File, 424 Line 425 ); 426 427 exit (1); 428 } 429 430 if (strlen (File) == 0) { 431 printf ( 432 "\nMyFree(Ptr=%xh, File=%s, Line=%u)" 433 "\nInvalid parameter.\n", 434 Ptr, 435 File, 436 Line 437 ); 438 439 exit (1); 440 } 441 // 442 // Freeing NULL is always valid. 443 // 444 if (Ptr == NULL) { 445 return ; 446 } 447 // 448 // Fail if nothing is allocated. 449 // 450 if (MyAllocData == NULL) { 451 printf ( 452 "\nMyFree(Ptr=%xh, File=%s, Line=%u)" 453 "\nCalled before memory allocated.\n", 454 Ptr, 455 File, 456 Line 457 ); 458 459 exit (1); 460 } 461 // 462 // Check for corrupted allocation list. 463 // 464 MyCheck (0, __FILE__, __LINE__); 465 466 // 467 // Need special check for first item in list. 468 // 469 if (&MyAllocData->Buffer[sizeof (UINT32)] == Ptr) { 470 // 471 // Unlink first item in list. 472 // 473 Tmp = MyAllocData; 474 MyAllocData = MyAllocData->Next; 475 } else { 476 // 477 // Walk list looking for matching item. 478 // 479 for (Tmp = MyAllocData;; Tmp = Tmp->Next) { 480 // 481 // Fail if end of list is reached. 482 // 483 if (Tmp->Next == NULL) { 484 printf ( 485 "\nMyFree(Ptr=%xh, File=%s, Line=%u)\n" 486 "\nNot found.\n", 487 Ptr, 488 File, 489 Line 490 ); 491 492 exit (1); 493 } 494 // 495 // Leave loop when match is found. 496 // 497 if (&Tmp->Next->Buffer[sizeof (UINT32)] == Ptr) { 498 break; 499 } 500 } 501 // 502 // Unlink item from list. 503 // 504 Tmp2 = Tmp->Next; 505 Tmp->Next = Tmp->Next->Next; 506 Tmp = Tmp2; 507 } 508 // 509 // Release item. 510 // 511 free (Tmp); 512 } 513 514 #endif /* USE_MYALLOC */ 515 516 /* eof - MyAlloc.c */ 517