X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=blobdiff_plain;f=EdkCompatibilityPkg%2FSample%2FTools%2FSource%2FCommon%2FMyAlloc.c;fp=EdkCompatibilityPkg%2FSample%2FTools%2FSource%2FCommon%2FMyAlloc.c;h=39fddf7428eb2f7c387c36ac35ea5fb412aa06a7;hp=0000000000000000000000000000000000000000;hb=3eb9473ea9a949badfe06ae61d2d3fcfa53651c7;hpb=30d4a0c7ec19938196b1308006b990e0945150da diff --git a/EdkCompatibilityPkg/Sample/Tools/Source/Common/MyAlloc.c b/EdkCompatibilityPkg/Sample/Tools/Source/Common/MyAlloc.c new file mode 100644 index 0000000000..39fddf7428 --- /dev/null +++ b/EdkCompatibilityPkg/Sample/Tools/Source/Common/MyAlloc.c @@ -0,0 +1,516 @@ +/*++ + +Copyright (c) 2004, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + MyAlloc.c + +Abstract: + + File for memory allocation tracking functions. + +--*/ + +#include "MyAlloc.h" + +#if USE_MYALLOC +// +// Get back to original alloc/free calls. +// +#undef malloc +#undef calloc +#undef realloc +#undef free +// +// Start of allocation list. +// +static MY_ALLOC_STRUCT *MyAllocData = NULL; + +// +// +// +static UINT32 MyAllocHeadMagik = MYALLOC_HEAD_MAGIK; +static UINT32 MyAllocTailMagik = MYALLOC_TAIL_MAGIK; + +// +// //////////////////////////////////////////////////////////////////////////// +// +// +VOID +MyCheck ( + BOOLEAN Final, + UINT8 File[], + UINTN Line + ) +// *++ +// Description: +// +// Check for corruptions in the allocated memory chain. If a corruption +// is detection program operation stops w/ an exit(1) call. +// +// Parameters: +// +// Final := When FALSE, MyCheck() returns if the allocated memory chain +// has not been corrupted. When TRUE, MyCheck() returns if there +// are no un-freed allocations. If there are un-freed allocations, +// they are displayed and exit(1) is called. +// +// +// File := Set to __FILE__ by macro expansion. +// +// Line := Set to __LINE__ by macro expansion. +// +// Returns: +// +// n/a +// +// --*/ +// +{ + MY_ALLOC_STRUCT *Tmp; + + // + // Check parameters. + // + if (File == NULL || Line == 0) { + printf ( + "\nMyCheck(Final=%u, File=%xh, Line=%u)" + "Invalid parameter(s).\n", + Final, + File, + Line + ); + + exit (1); + } + + if (strlen (File) == 0) { + printf ( + "\nMyCheck(Final=%u, File=%s, Line=%u)" + "Invalid parameter.\n", + Final, + File, + Line + ); + + exit (1); + } + // + // Check structure contents. + // + for (Tmp = MyAllocData; Tmp != NULL; Tmp = Tmp->Next) { + if (memcmp(Tmp->Buffer, &MyAllocHeadMagik, sizeof MyAllocHeadMagik) || + memcmp(&Tmp->Buffer[Tmp->Size + sizeof(UINT32)], &MyAllocTailMagik, sizeof MyAllocTailMagik)) { + break; + } + } + // + // If Tmp is not NULL, the structure is corrupt. + // + if (Tmp != NULL) { + printf ( + "\nMyCheck(Final=%u, File=%s, Line=%u)""\nStructure corrupted!" + "\nFile=%s, Line=%u, nSize=%u, Head=%xh, Tail=%xh\n", + Final, + File, + Line, + Tmp->File, + Tmp->Line, + Tmp->Size, + *(UINT32 *) (Tmp->Buffer), + *(UINT32 *) (&Tmp->Buffer[Tmp->Size + sizeof (UINT32)]) + ); + + exit (1); + } + // + // If Final is TRUE, display the state of the structure chain. + // + if (Final) { + if (MyAllocData != NULL) { + printf ( + "\nMyCheck(Final=%u, File=%s, Line=%u)" + "\nSome allocated items have not been freed.\n", + Final, + File, + Line + ); + + for (Tmp = MyAllocData; Tmp != NULL; Tmp = Tmp->Next) { + printf ( + "File=%s, Line=%u, nSize=%u, Head=%xh, Tail=%xh\n", + Tmp->File, + Tmp->Line, + Tmp->Size, + *(UINT32 *) (Tmp->Buffer), + *(UINT32 *) (&Tmp->Buffer[Tmp->Size + sizeof (UINT32)]) + ); + } + } + } +} +// +// //////////////////////////////////////////////////////////////////////////// +// +// +VOID * +MyAlloc ( + UINTN Size, + UINT8 File[], + UINTN Line + ) +// *++ +// Description: +// +// Allocate a new link in the allocation chain along with enough storage +// for the File[] string, requested Size and alignment overhead. If +// memory cannot be allocated or the allocation chain has been corrupted, +// exit(1) will be called. +// +// Parameters: +// +// Size := Number of bytes (UINT8) requested by the called. +// Size cannot be zero. +// +// File := Set to __FILE__ by macro expansion. +// +// Line := Set to __LINE__ by macro expansion. +// +// Returns: +// +// Pointer to the caller's buffer. +// +// --*/ +// +{ + MY_ALLOC_STRUCT *Tmp; + UINTN Len; + + // + // Check for invalid parameters. + // + if (Size == 0 || File == NULL || Line == 0) { + printf ( + "\nMyAlloc(Size=%u, File=%xh, Line=%u)" + "\nInvalid parameter(s).\n", + Size, + File, + Line + ); + + exit (1); + } + + Len = strlen (File); + if (Len == 0) { + printf ( + "\nMyAlloc(Size=%u, File=%s, Line=%u)" + "\nInvalid parameter.\n", + Size, + File, + Line + ); + + exit (1); + } + // + // Check the allocation list for corruption. + // + MyCheck (0, __FILE__, __LINE__); + + // + // Allocate a new entry. + // + Tmp = calloc ( + 1, + sizeof (MY_ALLOC_STRUCT) + Len + 1 + sizeof (UINT64) + Size + (sizeof MyAllocHeadMagik) + (sizeof MyAllocTailMagik) + ); + + if (Tmp == NULL) { + printf ( + "\nMyAlloc(Size=%u, File=%s, Line=%u)" + "\nOut of memory.\n", + Size, + File, + Line + ); + + exit (1); + } + // + // Fill in the new entry. + // + Tmp->File = ((UINT8 *) Tmp) + sizeof (MY_ALLOC_STRUCT); + strcpy (Tmp->File, File); + Tmp->Line = Line; + Tmp->Size = Size; + Tmp->Buffer = (UINT8 *) (((UINTN) Tmp + Len + 9) &~7); + + memcpy (Tmp->Buffer, &MyAllocHeadMagik, sizeof MyAllocHeadMagik); + + memcpy ( + &Tmp->Buffer[Size + sizeof (UINT32)], + &MyAllocTailMagik, + sizeof MyAllocTailMagik + ); + + Tmp->Next = MyAllocData; + Tmp->Cksum = (UINTN) Tmp + (UINTN) (Tmp->Next) + Tmp->Line + Tmp->Size + (UINTN) (Tmp->File) + (UINTN) (Tmp->Buffer); + + MyAllocData = Tmp; + + return Tmp->Buffer + sizeof (UINT32); +} +// +// //////////////////////////////////////////////////////////////////////////// +// +// +VOID * +MyRealloc ( + VOID *Ptr, + UINTN Size, + UINT8 File[], + UINTN Line + ) +// *++ +// Description: +// +// This does a MyAlloc(), memcpy() and MyFree(). There is no optimization +// for shrinking or expanding buffers. An invalid parameter will cause +// MyRealloc() to fail with a call to exit(1). +// +// Parameters: +// +// Ptr := Pointer to the caller's buffer to be re-allocated. +// +// Size := Size of new buffer. Size cannot be zero. +// +// File := Set to __FILE__ by macro expansion. +// +// Line := Set to __LINE__ by macro expansion. +// +// Returns: +// +// Pointer to new caller's buffer. +// +// --*/ +// +{ + MY_ALLOC_STRUCT *Tmp; + VOID *Buffer; + + // + // Check for invalid parameter(s). + // + if (Size == 0 || File == NULL || Line == 0) { + printf ( + "\nMyRealloc(Ptr=%xh, Size=%u, File=%xh, Line=%u)" + "\nInvalid parameter(s).\n", + Ptr, + Size, + File, + Line + ); + + exit (1); + } + + if (strlen (File) == 0) { + printf ( + "\nMyRealloc(Ptr=%xh, Size=%u, File=%s, Line=%u)" + "\nInvalid parameter.\n", + Ptr, + Size, + File, + Line + ); + + exit (1); + } + // + // Find existing buffer in allocation list. + // + if (Ptr == NULL) { + Tmp = NULL; + } else if (&MyAllocData->Buffer[sizeof (UINT32)] == Ptr) { + Tmp = MyAllocData; + } else { + for (Tmp = MyAllocData;; Tmp = Tmp->Next) { + if (Tmp->Next == NULL) { + printf ( + "\nMyRealloc(Ptr=%xh, Size=%u, File=%s, Line=%u)" + "\nCould not find buffer.\n", + Ptr, + Size, + File, + Line + ); + + exit (1); + } + + Tmp = Tmp->Next; + } + } + // + // Allocate new buffer, copy old data, free old buffer. + // + Buffer = MyAlloc (Size, File, Line); + + if (Buffer != NULL && Tmp != NULL) { + memcpy ( + Buffer, + &Tmp->Buffer[sizeof (UINT32)], + ((Size <= Tmp->Size) ? Size : Tmp->Size) + ); + + MyFree (Ptr, __FILE__, __LINE__); + } + + return Buffer; +} +// +// //////////////////////////////////////////////////////////////////////////// +// +// +VOID +MyFree ( + VOID *Ptr, + UINT8 File[], + UINTN Line + ) +// *++ +// Description: +// +// Release a previously allocated buffer. Invalid parameters will cause +// MyFree() to fail with an exit(1) call. +// +// Parameters: +// +// Ptr := Pointer to the caller's buffer to be freed. +// A NULL pointer will be ignored. +// +// File := Set to __FILE__ by macro expansion. +// +// Line := Set to __LINE__ by macro expansion. +// +// Returns: +// +// n/a +// +// --*/ +// +{ + MY_ALLOC_STRUCT *Tmp; + MY_ALLOC_STRUCT *Tmp2; + + // + // Check for invalid parameter(s). + // + if (File == NULL || Line == 0) { + printf ( + "\nMyFree(Ptr=%xh, File=%xh, Line=%u)" + "\nInvalid parameter(s).\n", + Ptr, + File, + Line + ); + + exit (1); + } + + if (strlen (File) == 0) { + printf ( + "\nMyFree(Ptr=%xh, File=%s, Line=%u)" + "\nInvalid parameter.\n", + Ptr, + File, + Line + ); + + exit (1); + } + // + // Freeing NULL is always valid. + // + if (Ptr == NULL) { + return ; + } + // + // Fail if nothing is allocated. + // + if (MyAllocData == NULL) { + printf ( + "\nMyFree(Ptr=%xh, File=%s, Line=%u)" + "\nCalled before memory allocated.\n", + Ptr, + File, + Line + ); + + exit (1); + } + // + // Check for corrupted allocation list. + // + MyCheck (0, __FILE__, __LINE__); + + // + // Need special check for first item in list. + // + if (&MyAllocData->Buffer[sizeof (UINT32)] == Ptr) { + // + // Unlink first item in list. + // + Tmp = MyAllocData; + MyAllocData = MyAllocData->Next; + } else { + // + // Walk list looking for matching item. + // + for (Tmp = MyAllocData;; Tmp = Tmp->Next) { + // + // Fail if end of list is reached. + // + if (Tmp->Next == NULL) { + printf ( + "\nMyFree(Ptr=%xh, File=%s, Line=%u)\n" + "\nNot found.\n", + Ptr, + File, + Line + ); + + exit (1); + } + // + // Leave loop when match is found. + // + if (&Tmp->Next->Buffer[sizeof (UINT32)] == Ptr) { + break; + } + } + // + // Unlink item from list. + // + Tmp2 = Tmp->Next; + Tmp->Next = Tmp->Next->Next; + Tmp = Tmp2; + } + // + // Release item. + // + free (Tmp); +} + +#endif /* USE_MYALLOC */ + +/* eof - MyAlloc.c */