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