2 File for memory allocation tracking functions.
4 Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
13 // Get back to original alloc/free calls.
20 // Start of allocation list.
22 STATIC MY_ALLOC_STRUCT
*MyAllocData
= NULL
;
27 STATIC UINT32 MyAllocHeadMagik
= MYALLOC_HEAD_MAGIK
;
28 STATIC UINT32 MyAllocTailMagik
= MYALLOC_TAIL_MAGIK
;
31 // ////////////////////////////////////////////////////////////////////////////
43 // Check for corruptions in the allocated memory chain. If a corruption
44 // is detection program operation stops w/ an exit(1) call.
48 // Final := When FALSE, MyCheck() returns if the allocated memory chain
49 // has not been corrupted. When TRUE, MyCheck() returns if there
50 // are no un-freed allocations. If there are un-freed allocations,
51 // they are displayed and exit(1) is called.
54 // File := Set to __FILE__ by macro expansion.
56 // Line := Set to __LINE__ by macro expansion.
72 "\nMyCheck(Final=%u, File=NULL, Line=%u)"
73 "Invalid parameter(s).\n",
83 "\nMyCheck(Final=%u, File=%s, Line=%u)"
84 "Invalid parameter(s).\n",
93 if (strlen ((CHAR8
*)File
) == 0) {
95 "\nMyCheck(Final=%u, File=%s, Line=%u)"
96 "Invalid parameter.\n",
105 // Check structure contents.
107 for (Tmp
= MyAllocData
; Tmp
!= NULL
; Tmp
= Tmp
->Next
) {
108 if (memcmp(Tmp
->Buffer
, &MyAllocHeadMagik
, sizeof MyAllocHeadMagik
) ||
109 memcmp(&Tmp
->Buffer
[Tmp
->Size
+ sizeof(UINT32
)], &MyAllocTailMagik
, sizeof MyAllocTailMagik
)) {
114 // If Tmp is not NULL, the structure is corrupt.
118 "\nMyCheck(Final=%u, File=%s, Line=%u)""\nStructure corrupted!"
119 "\nFile=%s, Line=%u, nSize=%u, Head=%xh, Tail=%xh\n",
124 (unsigned) Tmp
->Line
,
125 (unsigned) Tmp
->Size
,
126 (unsigned) *(UINT32
*) (Tmp
->Buffer
),
127 (unsigned) *(UINT32
*) (&Tmp
->Buffer
[Tmp
->Size
+ sizeof (UINT32
)])
133 // If Final is TRUE, display the state of the structure chain.
136 if (MyAllocData
!= NULL
) {
138 "\nMyCheck(Final=%u, File=%s, Line=%u)"
139 "\nSome allocated items have not been freed.\n",
145 for (Tmp
= MyAllocData
; Tmp
!= NULL
; Tmp
= Tmp
->Next
) {
147 "File=%s, Line=%u, nSize=%u, Head=%xh, Tail=%xh\n",
149 (unsigned) Tmp
->Line
,
150 (unsigned) Tmp
->Size
,
151 (unsigned) *(UINT32
*) (Tmp
->Buffer
),
152 (unsigned) *(UINT32
*) (&Tmp
->Buffer
[Tmp
->Size
+ sizeof (UINT32
)])
159 // ////////////////////////////////////////////////////////////////////////////
171 // Allocate a new link in the allocation chain along with enough storage
172 // for the File[] string, requested Size and alignment overhead. If
173 // memory cannot be allocated or the allocation chain has been corrupted,
174 // exit(1) will be called.
178 // Size := Number of bytes (UINT8) requested by the called.
179 // Size cannot be zero.
181 // File := Set to __FILE__ by macro expansion.
183 // Line := Set to __LINE__ by macro expansion.
187 // Pointer to the caller's buffer.
192 MY_ALLOC_STRUCT
*Tmp
;
196 // Check for invalid parameters.
200 "\nMyAlloc(Size=%u, File=NULL, Line=%u)"
201 "\nInvalid parameter(s).\n",
209 if (Size
== 0 || Line
== 0) {
211 "\nMyAlloc(Size=%u, File=%s, Line=%u)"
212 "\nInvalid parameter(s).\n",
221 Len
= strlen ((CHAR8
*)File
);
224 "\nMyAlloc(Size=%u, File=%s, Line=%u)"
225 "\nInvalid parameter.\n",
234 // Check the allocation list for corruption.
236 MyCheck (0, (UINT8
*)__FILE__
, __LINE__
);
239 // Allocate a new entry.
243 sizeof (MY_ALLOC_STRUCT
) + Len
+ 1 + sizeof (UINT64
) + Size
+ (sizeof MyAllocHeadMagik
) + (sizeof MyAllocTailMagik
)
248 "\nMyAlloc(Size=%u, File=%s, Line=%u)"
249 "\nOut of memory.\n",
258 // Fill in the new entry.
260 Tmp
->File
= ((UINT8
*) Tmp
) + sizeof (MY_ALLOC_STRUCT
);
261 strcpy ((CHAR8
*)Tmp
->File
, (CHAR8
*)File
);
264 Tmp
->Buffer
= (UINT8
*) (((UINTN
) Tmp
+ Len
+ 9) &~7);
266 memcpy (Tmp
->Buffer
, &MyAllocHeadMagik
, sizeof MyAllocHeadMagik
);
269 &Tmp
->Buffer
[Size
+ sizeof (UINT32
)],
271 sizeof MyAllocTailMagik
274 Tmp
->Next
= MyAllocData
;
275 Tmp
->Cksum
= (UINTN
) Tmp
+ (UINTN
) (Tmp
->Next
) + Tmp
->Line
+ Tmp
->Size
+ (UINTN
) (Tmp
->File
) + (UINTN
) (Tmp
->Buffer
);
279 return Tmp
->Buffer
+ sizeof (UINT32
);
282 // ////////////////////////////////////////////////////////////////////////////
295 // This does a MyAlloc(), memcpy() and MyFree(). There is no optimization
296 // for shrinking or expanding buffers. An invalid parameter will cause
297 // MyRealloc() to fail with a call to exit(1).
301 // Ptr := Pointer to the caller's buffer to be re-allocated.
303 // Size := Size of new buffer. Size cannot be zero.
305 // File := Set to __FILE__ by macro expansion.
307 // Line := Set to __LINE__ by macro expansion.
311 // Pointer to new caller's buffer.
316 MY_ALLOC_STRUCT
*Tmp
;
320 // Check for invalid parameter(s).
324 "\nMyRealloc(Ptr=%p, Size=%u, File=NULL, Line=%u)"
325 "\nInvalid parameter(s).\n",
334 if (Size
== 0 || Line
== 0) {
336 "\nMyRealloc(Ptr=%p, Size=%u, File=%s, Line=%u)"
337 "\nInvalid parameter(s).\n",
347 if (strlen ((CHAR8
*)File
) == 0) {
349 "\nMyRealloc(Ptr=%p, Size=%u, File=%s, Line=%u)"
350 "\nInvalid parameter.\n",
360 // Find existing buffer in allocation list.
364 } else if (&MyAllocData
->Buffer
[sizeof (UINT32
)] == Ptr
) {
367 for (Tmp
= MyAllocData
;; Tmp
= Tmp
->Next
) {
368 if (Tmp
->Next
== NULL
) {
370 "\nMyRealloc(Ptr=%p, Size=%u, File=%s, Line=%u)"
371 "\nCould not find buffer.\n",
385 // Allocate new buffer, copy old data, free old buffer.
387 Buffer
= MyAlloc (Size
, File
, Line
);
389 if (Buffer
!= NULL
&& Tmp
!= NULL
) {
392 &Tmp
->Buffer
[sizeof (UINT32
)],
393 ((Size
<= Tmp
->Size
) ? Size
: Tmp
->Size
)
396 MyFree (Ptr
, (UINT8
*)__FILE__
, __LINE__
);
402 // ////////////////////////////////////////////////////////////////////////////
414 // Release a previously allocated buffer. Invalid parameters will cause
415 // MyFree() to fail with an exit(1) call.
419 // Ptr := Pointer to the caller's buffer to be freed.
420 // A NULL pointer will be ignored.
422 // File := Set to __FILE__ by macro expansion.
424 // Line := Set to __LINE__ by macro expansion.
433 MY_ALLOC_STRUCT
*Tmp
;
434 MY_ALLOC_STRUCT
*Tmp2
;
437 // Check for invalid parameter(s).
441 "\nMyFree(Ptr=%p, File=NULL, Line=%u)"
442 "\nInvalid parameter(s).\n",
452 "\nMyFree(Ptr=%p, File=%s, Line=%u)"
453 "\nInvalid parameter(s).\n",
462 if (strlen ((CHAR8
*)File
) == 0) {
464 "\nMyFree(Ptr=%p, File=%s, Line=%u)"
465 "\nInvalid parameter.\n",
474 // Freeing NULL is always valid.
480 // Fail if nothing is allocated.
482 if (MyAllocData
== NULL
) {
484 "\nMyFree(Ptr=%p, File=%s, Line=%u)"
485 "\nCalled before memory allocated.\n",
494 // Check for corrupted allocation list.
496 MyCheck (0, (UINT8
*)__FILE__
, __LINE__
);
499 // Need special check for first item in list.
501 if (&MyAllocData
->Buffer
[sizeof (UINT32
)] == Ptr
) {
503 // Unlink first item in list.
506 MyAllocData
= MyAllocData
->Next
;
509 // Walk list looking for matching item.
511 for (Tmp
= MyAllocData
;; Tmp
= Tmp
->Next
) {
513 // Fail if end of list is reached.
515 if (Tmp
->Next
== NULL
) {
517 "\nMyFree(Ptr=%p, File=%s, Line=%u)\n"
527 // Leave loop when match is found.
529 if (&Tmp
->Next
->Buffer
[sizeof (UINT32
)] == Ptr
) {
534 // Unlink item from list.
537 Tmp
->Next
= Tmp
->Next
->Next
;
546 #endif /* USE_MYALLOC */
548 /* eof - MyAlloc.c */