mirror of
				https://github.com/acidanthera/audk.git
				synced 2025-11-02 20:44:39 +01:00 
			
		
		
		
	git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@3 6f19259b-4bc3-4df7-8a09-765794883524
		
			
				
	
	
		
			517 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			517 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/*++
 | 
						|
 | 
						|
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 */
 |