mirror of
				https://github.com/acidanthera/audk.git
				synced 2025-10-25 17:23:53 +02:00 
			
		
		
		
	Move the documentation blocks from between the parameter list and function body to above the function. Convert all the documentation blocks to Doxygen format. Signed-off-by: Rebecca Cran <rebecca@bsdio.com> Reviewed-by: Liming Gao <gaoliming@byosoft.com.cn>
		
			
				
	
	
		
			490 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			490 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /** @file
 | |
| File for memory allocation tracking functions.
 | |
| 
 | |
| Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>
 | |
| SPDX-License-Identifier: BSD-2-Clause-Patent
 | |
| 
 | |
| **/
 | |
| 
 | |
| #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;
 | |
| 
 | |
| /**
 | |
|   Check for corruptions in the allocated memory chain.  If a corruption
 | |
|   is detection program operation stops w/ an exit(1) call.
 | |
| 
 | |
|   @param 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.
 | |
|   @param File Set to __FILE__ by macro expansion.
 | |
|   @param Line Set to __LINE__ by macro expansion.
 | |
| **/
 | |
| VOID
 | |
| MyCheck (
 | |
|   BOOLEAN      Final,
 | |
|   UINT8        File[],
 | |
|   UINTN        Line
 | |
|   )
 | |
| {
 | |
|   MY_ALLOC_STRUCT *Tmp;
 | |
| 
 | |
|   //
 | |
|   // Check parameters.
 | |
|   //
 | |
|   if (File == NULL) {
 | |
|     printf (
 | |
|       "\nMyCheck(Final=%u, File=NULL, Line=%u)"
 | |
|       "Invalid parameter(s).\n",
 | |
|       Final,
 | |
|       (unsigned)Line
 | |
|       );
 | |
| 
 | |
|     exit (1);
 | |
|   }
 | |
| 
 | |
|   if (Line == 0) {
 | |
|     printf (
 | |
|       "\nMyCheck(Final=%u, File=%s, Line=%u)"
 | |
|       "Invalid parameter(s).\n",
 | |
|       Final,
 | |
|       File,
 | |
|       (unsigned)Line
 | |
|       );
 | |
| 
 | |
|     exit (1);
 | |
|   }
 | |
| 
 | |
|   if (strlen ((CHAR8 *)File) == 0) {
 | |
|     printf (
 | |
|       "\nMyCheck(Final=%u, File=%s, Line=%u)"
 | |
|       "Invalid parameter.\n",
 | |
|       Final,
 | |
|       File,
 | |
|       (unsigned)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,
 | |
|       (unsigned)Line,
 | |
|       Tmp->File,
 | |
|       (unsigned) Tmp->Line,
 | |
|       (unsigned) Tmp->Size,
 | |
|       (unsigned) *(UINT32 *) (Tmp->Buffer),
 | |
|       (unsigned) *(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,
 | |
|         (unsigned)Line
 | |
|         );
 | |
| 
 | |
|       for (Tmp = MyAllocData; Tmp != NULL; Tmp = Tmp->Next) {
 | |
|         printf (
 | |
|           "File=%s, Line=%u, nSize=%u, Head=%xh, Tail=%xh\n",
 | |
|           Tmp->File,
 | |
|           (unsigned) Tmp->Line,
 | |
|           (unsigned) Tmp->Size,
 | |
|           (unsigned) *(UINT32 *) (Tmp->Buffer),
 | |
|           (unsigned) *(UINT32 *) (&Tmp->Buffer[Tmp->Size + sizeof (UINT32)])
 | |
|           );
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| }
 | |
| 
 | |
| /**
 | |
|   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.
 | |
| 
 | |
|   @param Size Number of bytes (UINT8) requested by the called.
 | |
|               Size cannot be zero.
 | |
|   @param File Set to __FILE__ by macro expansion.
 | |
|   @param Line Set to __LINE__ by macro expansion.
 | |
| 
 | |
|   @return Pointer to the caller's buffer.
 | |
| **/
 | |
| VOID *
 | |
| MyAlloc (
 | |
|   UINTN      Size,
 | |
|   UINT8 File[],
 | |
|   UINTN      Line
 | |
|   )
 | |
| {
 | |
|   MY_ALLOC_STRUCT *Tmp;
 | |
|   UINTN           Len;
 | |
| 
 | |
|   //
 | |
|   // Check for invalid parameters.
 | |
|   //
 | |
|   if (File == NULL) {
 | |
|     printf (
 | |
|       "\nMyAlloc(Size=%u, File=NULL, Line=%u)"
 | |
|       "\nInvalid parameter(s).\n",
 | |
|       (unsigned)Size,
 | |
|       (unsigned)Line
 | |
|       );
 | |
| 
 | |
|     exit (1);
 | |
|   }
 | |
| 
 | |
|   if (Size == 0 || Line == 0) {
 | |
|     printf (
 | |
|       "\nMyAlloc(Size=%u, File=%s, Line=%u)"
 | |
|       "\nInvalid parameter(s).\n",
 | |
|       (unsigned)Size,
 | |
|       File,
 | |
|       (unsigned)Line
 | |
|       );
 | |
| 
 | |
|     exit (1);
 | |
|   }
 | |
| 
 | |
|   Len = strlen ((CHAR8 *)File);
 | |
|   if (Len == 0) {
 | |
|     printf (
 | |
|       "\nMyAlloc(Size=%u, File=%s, Line=%u)"
 | |
|       "\nInvalid parameter.\n",
 | |
|       (unsigned)Size,
 | |
|       File,
 | |
|       (unsigned)Line
 | |
|       );
 | |
| 
 | |
|     exit (1);
 | |
|   }
 | |
|   //
 | |
|   // Check the allocation list for corruption.
 | |
|   //
 | |
|   MyCheck (0, (UINT8 *)__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",
 | |
|       (unsigned)Size,
 | |
|       File,
 | |
|       (unsigned)Line
 | |
|       );
 | |
| 
 | |
|     exit (1);
 | |
|   }
 | |
|   //
 | |
|   // Fill in the new entry.
 | |
|   //
 | |
|   Tmp->File = ((UINT8 *) Tmp) + sizeof (MY_ALLOC_STRUCT);
 | |
|   strcpy ((CHAR8 *)Tmp->File, (CHAR8 *)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);
 | |
| }
 | |
| 
 | |
| /**
 | |
|   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).
 | |
| 
 | |
|   @param Ptr Pointer to the caller's buffer to be re-allocated.
 | |
|   @param Size Size of new buffer.  Size cannot be zero.
 | |
|   @param File Set to __FILE__ by macro expansion.
 | |
|   @param Line Set to __LINE__ by macro expansion.
 | |
| 
 | |
|   @return Pointer to new caller's buffer.
 | |
| **/
 | |
| VOID *
 | |
| MyRealloc (
 | |
|   VOID       *Ptr,
 | |
|   UINTN      Size,
 | |
|   UINT8 File[],
 | |
|   UINTN      Line
 | |
|   )
 | |
| {
 | |
|   MY_ALLOC_STRUCT *Tmp;
 | |
|   VOID            *Buffer;
 | |
| 
 | |
|   //
 | |
|   // Check for invalid parameter(s).
 | |
|   //
 | |
|   if (File == NULL) {
 | |
|     printf (
 | |
|       "\nMyRealloc(Ptr=%p, Size=%u, File=NULL, Line=%u)"
 | |
|       "\nInvalid parameter(s).\n",
 | |
|       Ptr,
 | |
|       (unsigned)Size,
 | |
|       (unsigned)Line
 | |
|       );
 | |
| 
 | |
|     exit (1);
 | |
|   }
 | |
| 
 | |
|   if (Size == 0 || Line == 0) {
 | |
|     printf (
 | |
|       "\nMyRealloc(Ptr=%p, Size=%u, File=%s, Line=%u)"
 | |
|       "\nInvalid parameter(s).\n",
 | |
|       Ptr,
 | |
|       (unsigned)Size,
 | |
|       File,
 | |
|       (unsigned)Line
 | |
|       );
 | |
| 
 | |
|     exit (1);
 | |
|   }
 | |
| 
 | |
|   if (strlen ((CHAR8 *)File) == 0) {
 | |
|     printf (
 | |
|       "\nMyRealloc(Ptr=%p, Size=%u, File=%s, Line=%u)"
 | |
|       "\nInvalid parameter.\n",
 | |
|       Ptr,
 | |
|       (unsigned)Size,
 | |
|       File,
 | |
|       (unsigned)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=%p, Size=%u, File=%s, Line=%u)"
 | |
|           "\nCould not find buffer.\n",
 | |
|           Ptr,
 | |
|           (unsigned)Size,
 | |
|           File,
 | |
|           (unsigned)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, (UINT8 *)__FILE__, __LINE__);
 | |
|   }
 | |
| 
 | |
|   return Buffer;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Release a previously allocated buffer.  Invalid parameters will cause
 | |
|   MyFree() to fail with an exit(1) call.
 | |
| 
 | |
|   @param Ptr Pointer to the caller's buffer to be freed.
 | |
|              A NULL pointer will be ignored.
 | |
|   @param File Set to __FILE__ by macro expansion.
 | |
|   @param Line Set to __LINE__ by macro expansion.
 | |
| **/
 | |
| VOID
 | |
| MyFree (
 | |
|   VOID       *Ptr,
 | |
|   UINT8 File[],
 | |
|   UINTN      Line
 | |
|   )
 | |
| {
 | |
|   MY_ALLOC_STRUCT *Tmp;
 | |
|   MY_ALLOC_STRUCT *Tmp2;
 | |
| 
 | |
|   //
 | |
|   // Check for invalid parameter(s).
 | |
|   //
 | |
|   if (File == NULL) {
 | |
|     printf (
 | |
|       "\nMyFree(Ptr=%p, File=NULL, Line=%u)"
 | |
|       "\nInvalid parameter(s).\n",
 | |
|       Ptr,
 | |
|       (unsigned)Line
 | |
|       );
 | |
| 
 | |
|     exit (1);
 | |
|   }
 | |
| 
 | |
|   if (Line == 0) {
 | |
|     printf (
 | |
|       "\nMyFree(Ptr=%p, File=%s, Line=%u)"
 | |
|       "\nInvalid parameter(s).\n",
 | |
|       Ptr,
 | |
|       File,
 | |
|       (unsigned)Line
 | |
|       );
 | |
| 
 | |
|     exit (1);
 | |
|   }
 | |
| 
 | |
|   if (strlen ((CHAR8 *)File) == 0) {
 | |
|     printf (
 | |
|       "\nMyFree(Ptr=%p, File=%s, Line=%u)"
 | |
|       "\nInvalid parameter.\n",
 | |
|       Ptr,
 | |
|       File,
 | |
|       (unsigned)Line
 | |
|       );
 | |
| 
 | |
|     exit (1);
 | |
|   }
 | |
|   //
 | |
|   // Freeing NULL is always valid.
 | |
|   //
 | |
|   if (Ptr == NULL) {
 | |
|     return ;
 | |
|   }
 | |
|   //
 | |
|   // Fail if nothing is allocated.
 | |
|   //
 | |
|   if (MyAllocData == NULL) {
 | |
|     printf (
 | |
|       "\nMyFree(Ptr=%p, File=%s, Line=%u)"
 | |
|       "\nCalled before memory allocated.\n",
 | |
|       Ptr,
 | |
|       File,
 | |
|       (unsigned)Line
 | |
|       );
 | |
| 
 | |
|     exit (1);
 | |
|   }
 | |
|   //
 | |
|   // Check for corrupted allocation list.
 | |
|   //
 | |
|   MyCheck (0, (UINT8 *)__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=%p, File=%s, Line=%u)\n"
 | |
|           "\nNot found.\n",
 | |
|           Ptr,
 | |
|           File,
 | |
|           (unsigned)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 */
 |