]> git.proxmox.com Git - mirror_edk2.git/blobdiff - EdkCompatibilityPkg/Sample/Tools/Source/Common/MyAlloc.c
Add in the 1st version of ECP.
[mirror_edk2.git] / EdkCompatibilityPkg / Sample / Tools / Source / Common / MyAlloc.c
diff --git a/EdkCompatibilityPkg/Sample/Tools/Source/Common/MyAlloc.c b/EdkCompatibilityPkg/Sample/Tools/Source/Common/MyAlloc.c
new file mode 100644 (file)
index 0000000..39fddf7
--- /dev/null
@@ -0,0 +1,516 @@
+/*++\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