]> git.proxmox.com Git - mirror_edk2.git/blobdiff - Tools/Source/TianoTools/PeiRebase/PeiRebaseExe.c
Restructuring for better separation of Tool packages.
[mirror_edk2.git] / Tools / Source / TianoTools / PeiRebase / PeiRebaseExe.c
diff --git a/Tools/Source/TianoTools/PeiRebase/PeiRebaseExe.c b/Tools/Source/TianoTools/PeiRebase/PeiRebaseExe.c
deleted file mode 100644 (file)
index 27c646e..0000000
+++ /dev/null
@@ -1,1059 +0,0 @@
-/*++\r
-\r
-Copyright (c)  1999-2006 Intel Corporation. All rights reserved\r
-This program and the accompanying materials are licensed and made available \r
-under the terms and conditions of the BSD License which accompanies this \r
-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
-\r
-Module Name:\r
-\r
-  PeiRebaseExe.c\r
-\r
-Abstract:\r
-\r
-  This contains all code necessary to build the PeiRebase.exe utility.\r
-  This utility relies heavily on the PeiRebase DLL.  Definitions for both\r
-  can be found in the PEI Rebase Utility Specification, review draft.\r
-\r
---*/\r
-\r
-#include <stdlib.h>\r
-#include <stdio.h>\r
-#include <string.h>\r
-\r
-#include <Common/UefiBaseTypes.h>\r
-#include <Common/FirmwareVolumeImageFormat.h>\r
-#include <Common/FirmwareFileSystem.h>\r
-#include <Library/PeCoffLib.h>\r
-\r
-#include "CommonLib.h"\r
-#include "ParseInf.h"\r
-#include "FvLib.h"\r
-#include "EfiUtilityMsgs.h"\r
-#include "PeiRebaseExe.h"\r
-\r
-EFI_STATUS\r
-ReadHeader (\r
-  IN FILE       *InputFile,\r
-  OUT UINT32    *FvSize,\r
-  OUT BOOLEAN   *ErasePolarity\r
-  );\r
-\r
-int\r
-main (\r
-  int  argc,\r
-  char **argv\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  This utility relocates PEI XIP PE32s in a FV.\r
-\r
-Arguments:\r
-\r
-  argc          - Number of command line arguments\r
-  argv[]:\r
-  BaseAddress     The base address to use for rebasing the FV.  The correct \r
-                  format is a hex number preceded by 0x.\r
-  InputFileName   The name of the input FV file.\r
-  OutputFileName  The name of the output FV file.\r
-  MapFileName     The name of the map file of relocation info.\r
-\r
-  Arguments come in pair in any order.\r
-    -I InputFileName \r
-    -O OutputFileName\r
-    -B BaseAddress \r
-    -M MapFileName \r
-\r
-Returns:\r
-\r
-  0   No error conditions detected.\r
-  1   One or more of the input parameters is invalid.\r
-  2   A resource required by the utility was unavailable.  \r
-      Most commonly this will be memory allocation or file creation.\r
-  3   PeiRebase.dll could not be loaded.\r
-  4   Error executing the PEI rebase.\r
-\r
---*/\r
-{\r
-  UINT8                       Index;\r
-  CHAR8                       InputFileName[_MAX_PATH];\r
-  CHAR8                       OutputFileName[_MAX_PATH];\r
-  CHAR8                       MapFileName[_MAX_PATH];\r
-  EFI_PHYSICAL_ADDRESS        BaseAddress;\r
-  BOOLEAN                     BaseAddressSet;\r
-  EFI_STATUS                  Status;\r
-  FILE                        *InputFile;\r
-  FILE                        *OutputFile;\r
-  FILE                        *MapFile;\r
-  UINT64                      FvOffset;\r
-  UINT32                      FileCount;\r
-  int                         BytesRead;\r
-  EFI_FIRMWARE_VOLUME_HEADER  *FvImage;\r
-  UINT32                      FvSize;\r
-  EFI_FFS_FILE_HEADER         *CurrentFile;\r
-  BOOLEAN                     ErasePolarity;\r
-  EFI_PHYSICAL_ADDRESS        CurrentFileBaseAddress;\r
-\r
-  ErasePolarity = FALSE;\r
-  //\r
-  // Set utility name for error/warning reporting purposes.\r
-  //\r
-  SetUtilityName (UTILITY_NAME);\r
-  //\r
-  // Verify the correct number of arguments\r
-  //\r
-  if (argc != MAX_ARGS) {\r
-    PrintUsage ();\r
-    return STATUS_ERROR;\r
-  }\r
-\r
-  //\r
-  // Initialize variables\r
-  //\r
-  InputFileName[0]  = 0;\r
-  OutputFileName[0] = 0;\r
-  MapFileName[0]    = 0;\r
-  BaseAddress       = 0;\r
-  BaseAddressSet    = FALSE;\r
-  FvOffset          = 0;\r
-  FileCount         = 0;\r
-  ErasePolarity     = FALSE;\r
-  InputFile         = NULL;\r
-  OutputFile        = NULL;\r
-  MapFile           = NULL;\r
-  FvImage           = NULL;\r
-\r
-  //\r
-  // Parse the command line arguments\r
-  //\r
-  for (Index = 1; Index < MAX_ARGS; Index += 2) {\r
-    //\r
-    // Make sure argument pair begin with - or /\r
-    //\r
-    if (argv[Index][0] != '-' && argv[Index][0] != '/') {\r
-      PrintUsage ();\r
-      Error (NULL, 0, 0, argv[Index], "unrecognized option");\r
-      return STATUS_ERROR;\r
-    }\r
-    //\r
-    // Make sure argument specifier is only one letter\r
-    //\r
-    if (argv[Index][2] != 0) {\r
-      PrintUsage ();\r
-      Error (NULL, 0, 0, argv[Index], "unrecognized option");\r
-      return STATUS_ERROR;\r
-    }    \r
-    //\r
-    // Determine argument to read\r
-    //\r
-    switch (argv[Index][1]) {\r
-    case 'I':\r
-    case 'i':\r
-      if (strlen (InputFileName) == 0) {\r
-        strcpy (InputFileName, argv[Index + 1]);\r
-      } else {\r
-        PrintUsage ();\r
-        Error (NULL, 0, 0, argv[Index + 1], "only one -i InputFileName may be specified");\r
-        return STATUS_ERROR;\r
-      }\r
-      break;\r
-\r
-    case 'O':\r
-    case 'o':\r
-      if (strlen (OutputFileName) == 0) {\r
-        strcpy (OutputFileName, argv[Index + 1]);\r
-      } else {\r
-        PrintUsage ();\r
-        Error (NULL, 0, 0, argv[Index + 1], "only one -o OutputFileName may be specified");\r
-        return STATUS_ERROR;\r
-      }\r
-      break;\r
-\r
-    case 'B':\r
-    case 'b':\r
-      if (!BaseAddressSet) {\r
-        Status = AsciiStringToUint64 (argv[Index + 1], FALSE, &BaseAddress);\r
-        if (EFI_ERROR (Status)) {\r
-          PrintUsage ();\r
-          Error (NULL, 0, 0, argv[Index + 1], "invalid hex digit given for the base address");\r
-          return STATUS_ERROR;\r
-        }\r
-\r
-        BaseAddressSet = TRUE;\r
-      } else {\r
-        PrintUsage ();\r
-        Error (NULL, 0, 0, argv[Index + 1], "-b BaseAddress may only be specified once");\r
-        return STATUS_ERROR;\r
-      }\r
-      break;\r
-\r
-    case 'M':\r
-    case 'm':\r
-      if (strlen (MapFileName) == 0) {\r
-        strcpy (MapFileName, argv[Index + 1]);\r
-      } else {\r
-        PrintUsage ();\r
-        Error (NULL, 0, 0, argv[Index + 1], "only one -m MapFileName may be specified");\r
-        return STATUS_ERROR;\r
-      }\r
-      break;\r
-\r
-    default:\r
-      PrintUsage ();\r
-      Error (NULL, 0, 0, argv[Index], "unrecognized argument");\r
-      return STATUS_ERROR;\r
-      break;\r
-    }\r
-  }\r
-\r
-  //\r
-  // Create the Map file if we need it\r
-  //\r
-  if (strlen (MapFileName) != 0) {\r
-    MapFile = fopen (MapFileName, "w");\r
-    if (MapFile == NULL) {\r
-      Error (NULL, 0, 0, MapFileName, "failed to open map file");\r
-      goto Finish;\r
-    }\r
-  } \r
-\r
-  //\r
-  // Open the file containing the FV\r
-  //\r
-  InputFile = fopen (InputFileName, "rb");\r
-  if (InputFile == NULL) {\r
-    Error (NULL, 0, 0, InputFileName, "could not open input file for reading");\r
-    return STATUS_ERROR;\r
-  }\r
-  //\r
-  // Determine size of FV\r
-  //\r
-  Status = ReadHeader (InputFile, &FvSize, &ErasePolarity);\r
-  if (EFI_ERROR (Status)) {\r
-    Error (NULL, 0, 0, "could not parse the FV header", NULL);\r
-    goto Finish;\r
-  }\r
-  //\r
-  // Allocate a buffer for the FV image\r
-  //\r
-  FvImage = malloc (FvSize);\r
-  if (FvImage == NULL) {\r
-    Error (NULL, 0, 0, "application error", "memory allocation failed");\r
-    goto Finish;\r
-  }\r
-  //\r
-  // Read the entire FV to the buffer\r
-  //\r
-  BytesRead = fread (FvImage, 1, FvSize, InputFile);\r
-  fclose (InputFile);\r
-  InputFile = NULL;\r
-  if ((unsigned int) BytesRead != FvSize) {\r
-    Error (NULL, 0, 0, InputFileName, "failed to read from file");\r
-    goto Finish;\r
-  }\r
-  //\r
-  // Prepare to walk the FV image\r
-  //\r
-  InitializeFvLib (FvImage, FvSize);\r
-  //\r
-  // Get the first file\r
-  //\r
-  Status = GetNextFile (NULL, &CurrentFile);\r
-  if (EFI_ERROR (Status)) {\r
-    Error (NULL, 0, 0, "cannot find the first file in the FV image", NULL);\r
-    goto Finish;\r
-  }\r
-  //\r
-  // Check if each file should be rebased\r
-  //\r
-  while (CurrentFile != NULL) {\r
-    //\r
-    // Rebase this file\r
-    //\r
-    CurrentFileBaseAddress  = BaseAddress + ((UINTN) CurrentFile - (UINTN) FvImage);\r
-    Status                  = FfsRebase (CurrentFile, CurrentFileBaseAddress, MapFile);\r
-\r
-    if (EFI_ERROR (Status)) {\r
-      switch (Status) {\r
-\r
-      case EFI_INVALID_PARAMETER:\r
-        Error (NULL, 0, 0, "invalid parameter passed to FfsRebase", NULL);\r
-        break;\r
-\r
-      case EFI_ABORTED:\r
-        Error (NULL, 0, 0, "error detected while rebasing -- aborted", NULL);\r
-        break;\r
-\r
-      case EFI_OUT_OF_RESOURCES:\r
-        Error (NULL, 0, 0, "FfsRebase could not allocate required resources", NULL);\r
-        break;\r
-\r
-      case EFI_NOT_FOUND:\r
-        Error (NULL, 0, 0, "FfsRebase could not locate a PE32 section", NULL);\r
-        break;\r
-\r
-      default:\r
-        Error (NULL, 0, 0, "FfsRebase returned unknown status", "status=0x%08X", Status);\r
-        break;\r
-      }\r
-\r
-      goto Finish;\r
-    }\r
-\r
-    //\r
-    // Get the next file\r
-    //\r
-    Status = GetNextFile (CurrentFile, &CurrentFile);\r
-    if (EFI_ERROR (Status)) {\r
-      Error (NULL, 0, 0, "cannot find the next file in the FV image", NULL);\r
-      goto Finish;\r
-    }\r
-  }\r
-  //\r
-  // Open the output file\r
-  //\r
-  OutputFile = fopen (OutputFileName, "wb");\r
-  if (OutputFile == NULL) {\r
-    Error (NULL, 0, 0, OutputFileName, "failed to open output file");\r
-    goto Finish;\r
-  }\r
-\r
-  if (fwrite (FvImage, 1, FvSize, OutputFile) != FvSize) {\r
-    Error (NULL, 0, 0, "failed to write to output file", 0);\r
-    goto Finish;\r
-  }\r
-\r
-Finish:\r
-  if (InputFile != NULL) {\r
-    fclose (InputFile);\r
-  }\r
-  //\r
-  // If we created an output file, and there was an error, remove it so\r
-  // subsequent builds will rebuild it.\r
-  //\r
-  if (OutputFile != NULL) {\r
-    if (GetUtilityStatus () == STATUS_ERROR) {\r
-      remove (OutputFileName);\r
-    }\r
-\r
-    fclose (OutputFile);\r
-  }\r
-\r
-  if (MapFile != NULL) {\r
-    fclose (MapFile);\r
-  }\r
-\r
-  if (FvImage != NULL) {\r
-    free (FvImage);\r
-  }\r
-\r
-  return GetUtilityStatus ();\r
-}\r
-\r
-EFI_STATUS\r
-ReadHeader (\r
-  IN FILE       *InputFile,\r
-  OUT UINT32    *FvSize,\r
-  OUT BOOLEAN   *ErasePolarity\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  This function determines the size of the FV and the erase polarity.  The \r
-  erase polarity is the FALSE value for file state.\r
-\r
-Arguments:\r
-\r
-  InputFile       The file that contains the FV image.\r
-  FvSize          The size of the FV.\r
-  ErasePolarity   The FV erase polarity.\r
-    \r
-Returns:\r
\r
-  EFI_SUCCESS             Function completed successfully.\r
-  EFI_INVALID_PARAMETER   A required parameter was NULL or is out of range.\r
-  EFI_ABORTED             The function encountered an error.\r
-\r
---*/\r
-{\r
-  EFI_FIRMWARE_VOLUME_HEADER  VolumeHeader;\r
-  EFI_FV_BLOCK_MAP_ENTRY      BlockMap;\r
-  UINTN                       Signature[2];\r
-  UINTN                       BytesRead;\r
-  UINT32                      Size;\r
-\r
-  BytesRead = 0;\r
-  Size      = 0;\r
-  //\r
-  // Check input parameters\r
-  //\r
-  if ((InputFile == NULL) || (FvSize == NULL) || (ErasePolarity == NULL)) {\r
-    Error (NULL, 0, 0, "ReadHeader()", "invalid input parameter");\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-  //\r
-  // Read the header\r
-  //\r
-  fread (&VolumeHeader, sizeof (EFI_FIRMWARE_VOLUME_HEADER) - sizeof (EFI_FV_BLOCK_MAP_ENTRY), 1, InputFile);\r
-  BytesRead     = sizeof (EFI_FIRMWARE_VOLUME_HEADER) - sizeof (EFI_FV_BLOCK_MAP_ENTRY);\r
-  Signature[0]  = VolumeHeader.Signature;\r
-  Signature[1]  = 0;\r
-\r
-  //\r
-  // Get erase polarity\r
-  //\r
-  if (VolumeHeader.Attributes & EFI_FVB_ERASE_POLARITY) {\r
-    *ErasePolarity = TRUE;\r
-  }\r
-\r
-  do {\r
-    fread (&BlockMap, sizeof (EFI_FV_BLOCK_MAP_ENTRY), 1, InputFile);\r
-    BytesRead += sizeof (EFI_FV_BLOCK_MAP_ENTRY);\r
-\r
-    if (BlockMap.NumBlocks != 0) {\r
-      Size += BlockMap.NumBlocks * BlockMap.BlockLength;\r
-    }\r
-\r
-  } while (!(BlockMap.NumBlocks == 0 && BlockMap.BlockLength == 0));\r
-\r
-  if (VolumeHeader.FvLength != Size) {\r
-    Error (NULL, 0, 0, "volume size not consistant with block maps", NULL);\r
-    return EFI_ABORTED;\r
-  }\r
-\r
-  *FvSize = Size;\r
-\r
-  rewind (InputFile);\r
-\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-VOID\r
-PrintUtilityInfo (\r
-  VOID\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  Displays the standard utility information to SDTOUT\r
-\r
-Arguments:\r
-\r
-  None\r
-\r
-Returns:\r
-\r
-  None\r
-\r
---*/\r
-{\r
-  printf (\r
-    "%s, PEI Rebase Utility. Version %i.%i, %s.\n\n",\r
-    UTILITY_NAME,\r
-    UTILITY_MAJOR_VERSION,\r
-    UTILITY_MINOR_VERSION,\r
-    UTILITY_DATE\r
-    );\r
-}\r
-\r
-VOID\r
-PrintUsage (\r
-  VOID\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  Displays the utility usage syntax to STDOUT\r
-\r
-Arguments:\r
-\r
-  None\r
-\r
-Returns:\r
-\r
-  None\r
-\r
---*/\r
-{\r
-  printf (\r
-    "Usage: %s -I InputFileName -O OutputFileName -B BaseAddress [-M MapFile]\n",\r
-    UTILITY_NAME\r
-    );\r
-  printf ("  Where:\n");\r
-  printf ("    InputFileName is the name of the EFI FV file to rebase.\n");\r
-  printf ("    OutputFileName is the desired output file name.\n");\r
-  printf ("    BaseAddress is the FV base address to rebase agains.\n");\r
-  printf ("    MapFileName is an optional map file of the relocations\n");\r
-  printf ("  Argument pair may be in any order.\n\n");\r
-}\r
-\r
-EFI_STATUS\r
-FfsRebase (\r
-  IN OUT EFI_FFS_FILE_HEADER    *FfsFile,\r
-  IN EFI_PHYSICAL_ADDRESS       BaseAddress,\r
-  IN FILE                       *MapFile      OPTIONAL\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  This function determines if a file is XIP and should be rebased.  It will \r
-  rebase any PE32 sections found in the file using the base address.\r
-  \r
-Arguments:\r
-\r
-  FfsFile           A pointer to Ffs file image.\r
-  BaseAddress       The base address to use for rebasing the file image.\r
-  MapFile           Optional file to dump relocation information into\r
-\r
-Returns:\r
-\r
-  EFI_SUCCESS             The image was properly rebased.\r
-  EFI_INVALID_PARAMETER   An input parameter is invalid.\r
-  EFI_ABORTED             An error occurred while rebasing the input file image.\r
-  EFI_OUT_OF_RESOURCES    Could not allocate a required resource.\r
-  EFI_NOT_FOUND           No compressed sections could be found.\r
-\r
---*/\r
-{\r
-  EFI_STATUS                            Status;\r
-  PE_COFF_LOADER_IMAGE_CONTEXT          ImageContext;\r
-  UINTN                                 MemoryImagePointer;\r
-  UINTN                                 MemoryImagePointerAligned;\r
-  EFI_PHYSICAL_ADDRESS                  ImageAddress;\r
-  UINT64                                ImageSize;\r
-  EFI_PHYSICAL_ADDRESS                  EntryPoint;\r
-  UINT32                                Pe32ImageSize;\r
-  UINT32                                NewPe32BaseAddress;\r
-  UINTN                                 Index;\r
-  EFI_FILE_SECTION_POINTER              CurrentPe32Section;\r
-  EFI_FFS_FILE_STATE                    SavedState;\r
-  EFI_IMAGE_NT_HEADERS                  *PeHdr;\r
-  UINT32                                *PeHdrSizeOfImage;\r
-  UINT32                                *PeHdrChecksum;\r
-  UINT32                                FoundCount;\r
-  EFI_TE_IMAGE_HEADER                   *TEImageHeader;\r
-  UINT8                                 *TEBuffer;\r
-  EFI_IMAGE_DOS_HEADER                  *DosHeader;\r
-  UINT8                                 FileGuidString[80];\r
-  UINT32                                TailSize;\r
-  EFI_FFS_FILE_TAIL                     TailValue;\r
-\r
-  //\r
-  // Verify input parameters\r
-  //\r
-  if (FfsFile == NULL) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-  \r
-  //\r
-  // Convert the GUID to a string so we can at least report which file\r
-  // if we find an error.\r
-  //\r
-  PrintGuidToBuffer (&FfsFile->Name, FileGuidString, sizeof (FileGuidString), TRUE);\r
-  if (FfsFile->Attributes & FFS_ATTRIB_TAIL_PRESENT) {\r
-    TailSize = sizeof (EFI_FFS_FILE_TAIL);\r
-  } else {\r
-    TailSize = 0;\r
-  }\r
-  \r
-  //\r
-  // Do some cursory checks on the FFS file contents\r
-  //\r
-  Status = VerifyFfsFile (FfsFile);\r
-  if (EFI_ERROR (Status)) {\r
-    Error (NULL, 0, 0, "file does not appear to be a valid FFS file, cannot be rebased", FileGuidString);\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  memset (&ImageContext, 0, sizeof (ImageContext));\r
-\r
-  //\r
-  // Check if XIP file type. If not XIP, don't rebase.\r
-  //\r
-  if (FfsFile->Type != EFI_FV_FILETYPE_PEI_CORE &&\r
-      FfsFile->Type != EFI_FV_FILETYPE_PEIM &&\r
-      FfsFile->Type != EFI_FV_FILETYPE_SECURITY_CORE &&\r
-      FfsFile->Type != EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER\r
-      ) {\r
-    return EFI_SUCCESS;\r
-  }\r
-\r
-  //\r
-  // Rebase each PE32 section\r
-  //\r
-  Status      = EFI_SUCCESS;\r
-  FoundCount  = 0;\r
-  for (Index = 1;; Index++) {\r
-    Status = GetSectionByType (FfsFile, EFI_SECTION_PE32, Index, &CurrentPe32Section);\r
-    if (EFI_ERROR (Status)) {\r
-      break;\r
-    }\r
-\r
-    FoundCount++;\r
-\r
-    //\r
-    // Calculate the PE32 base address, the FFS file base plus the offset of the PE32 section\r
-    //\r
-    NewPe32BaseAddress = ((UINT32) BaseAddress) + ((UINTN) CurrentPe32Section.Pe32Section + sizeof (EFI_COMMON_SECTION_HEADER) - (UINTN) FfsFile);\r
-\r
-    //\r
-    // Initialize context\r
-    //\r
-    memset (&ImageContext, 0, sizeof (ImageContext));\r
-    ImageContext.Handle     = (VOID *) ((UINTN) CurrentPe32Section.Pe32Section + sizeof (EFI_PE32_SECTION));\r
-    ImageContext.ImageRead  = (PE_COFF_LOADER_READ_FILE) FfsRebaseImageRead;\r
-\r
-    Status                  = PeCoffLoaderGetImageInfo (&ImageContext);\r
-\r
-    if (EFI_ERROR (Status)) {\r
-      Error (NULL, 0, 0, "GetImageInfo() call failed on rebase", FileGuidString);\r
-      return Status;\r
-    }\r
-    //\r
-    // Allocate a buffer for the image to be loaded into.\r
-    //\r
-    Pe32ImageSize       = GetLength (CurrentPe32Section.Pe32Section->CommonHeader.Size) - sizeof (EFI_PE32_SECTION);\r
-    MemoryImagePointer  = (UINTN) (malloc (Pe32ImageSize + 0x1000));\r
-    if (MemoryImagePointer == 0) {\r
-      Error (NULL, 0, 0, "memory allocation failure", NULL);\r
-      return EFI_OUT_OF_RESOURCES;\r
-    }\r
-    memset ((void *) MemoryImagePointer, 0, Pe32ImageSize + 0x1000);\r
-    MemoryImagePointerAligned = (MemoryImagePointer + 0x0FFF) & (-1 << 12);\r
-    \r
-\r
-    ImageContext.ImageAddress = MemoryImagePointerAligned;\r
-\r
-    Status                    = PeCoffLoaderLoadImage (&ImageContext);\r
-    if (EFI_ERROR (Status)) {\r
-      Error (NULL, 0, 0, "LoadImage() call failed on rebase", FileGuidString);\r
-      free ((VOID *) MemoryImagePointer);\r
-      return Status;\r
-    }\r
-\r
-    ImageContext.DestinationAddress = NewPe32BaseAddress;\r
-    Status                          = PeCoffLoaderRelocateImage (&ImageContext);\r
-    if (EFI_ERROR (Status)) {\r
-      Error (NULL, 0, 0, "RelocateImage() call failed on rebase", FileGuidString);\r
-      free ((VOID *) MemoryImagePointer);\r
-      return Status;\r
-    }\r
-\r
-    ImageAddress  = ImageContext.ImageAddress;\r
-    ImageSize     = ImageContext.ImageSize;\r
-    EntryPoint    = ImageContext.EntryPoint;\r
-\r
-    if (ImageSize > Pe32ImageSize) {\r
-      Error (\r
-        NULL,\r
-        0,\r
-        0,\r
-        "rebased image is larger than original PE32 image",\r
-        "0x%X > 0x%X, file %s",\r
-        ImageSize,\r
-        Pe32ImageSize,\r
-        FileGuidString\r
-        );\r
-      free ((VOID *) MemoryImagePointer);\r
-      return EFI_ABORTED;\r
-    }\r
-    //\r
-    // Since we may have updated the Codeview RVA, we need to insure the PE\r
-    // header indicates the image is large enough to contain the Codeview data\r
-    // so it will be loaded properly later if the PEIM is reloaded into memory...\r
-    //\r
-    PeHdr = (VOID *) ((UINTN) ImageAddress + ImageContext.PeCoffHeaderOffset);\r
-    if (PeHdr->FileHeader.Machine == EFI_IMAGE_MACHINE_IA32) {\r
-      PeHdrSizeOfImage     = (UINT32 *) (&(*(EFI_IMAGE_OPTIONAL_HEADER32 *) &PeHdr->OptionalHeader).SizeOfImage);\r
-      PeHdrChecksum        = (UINT32 *) (&(*(EFI_IMAGE_OPTIONAL_HEADER32 *) &PeHdr->OptionalHeader).CheckSum);\r
-    } else if (PeHdr->FileHeader.Machine == EFI_IMAGE_MACHINE_IA64) {\r
-      PeHdrSizeOfImage     = (UINT32 *) (&(*(EFI_IMAGE_OPTIONAL_HEADER64 *) &PeHdr->OptionalHeader).SizeOfImage);\r
-      PeHdrChecksum        = (UINT32 *) (&(*(EFI_IMAGE_OPTIONAL_HEADER64 *) &PeHdr->OptionalHeader).CheckSum);\r
-    } else if (PeHdr->FileHeader.Machine == EFI_IMAGE_MACHINE_X64) {\r
-      PeHdrSizeOfImage     = (UINT32 *) (&(*(EFI_IMAGE_OPTIONAL_HEADER64 *) &PeHdr->OptionalHeader).SizeOfImage);\r
-      PeHdrChecksum        = (UINT32 *) (&(*(EFI_IMAGE_OPTIONAL_HEADER64 *) &PeHdr->OptionalHeader).CheckSum);\r
-    } else {\r
-      Error (\r
-        NULL,\r
-        0,\r
-        0,\r
-        "unknown machine type in PE32 image",\r
-        "machine type=0x%X, file=%s",\r
-        (UINT32) PeHdr->FileHeader.Machine,\r
-        FileGuidString\r
-        );\r
-      free ((VOID *) MemoryImagePointer);\r
-      return EFI_ABORTED;\r
-    }\r
-\r
-    if (*PeHdrSizeOfImage != ImageContext.ImageSize) {\r
-      *PeHdrSizeOfImage = (UINT32) ImageContext.ImageSize;\r
-      if (*PeHdrChecksum) {\r
-        *PeHdrChecksum = 0;\r
-      }\r
-    }\r
-\r
-    memcpy (CurrentPe32Section.Pe32Section + 1, (VOID *) MemoryImagePointerAligned, (UINT32) ImageSize);\r
-    \r
-    //\r
-    // Get EntryPoint in Flash Region.\r
-    //\r
-    EntryPoint = NewPe32BaseAddress + EntryPoint - ImageAddress;\r
-\r
-    //\r
-    // If a map file was selected output mapping information for any file that\r
-    // was rebased.\r
-    //\r
-    if (MapFile != NULL) {\r
-      fprintf (MapFile, "PE32 File: %s Base:%08lx", FileGuidString, BaseAddress);\r
-      fprintf (MapFile, " EntryPoint:%08lx", EntryPoint);\r
-      if (ImageContext.PdbPointer != NULL) {\r
-        fprintf (MapFile, " FileName: %s", ImageContext.PdbPointer);\r
-      }\r
-      fprintf (MapFile, "\n");\r
-    }\r
-\r
-    free ((VOID *) MemoryImagePointer);\r
-\r
-    //\r
-    // Now update file checksum\r
-    //\r
-    if (FfsFile->Attributes & FFS_ATTRIB_TAIL_PRESENT) {\r
-      TailSize = sizeof (EFI_FFS_FILE_TAIL);\r
-    } else {\r
-      TailSize = 0;\r
-    }\r
-\r
-    if (FfsFile->Attributes & FFS_ATTRIB_CHECKSUM) {\r
-      SavedState  = FfsFile->State;\r
-      FfsFile->IntegrityCheck.Checksum.File = 0;\r
-      FfsFile->State                        = 0;\r
-      if (FfsFile->Attributes & FFS_ATTRIB_CHECKSUM) {\r
-        FfsFile->IntegrityCheck.Checksum.File = CalculateChecksum8 (\r
-                                                  (UINT8 *) FfsFile,\r
-                                                  GetLength (FfsFile->Size) - TailSize\r
-                                                  );\r
-      } else {\r
-        FfsFile->IntegrityCheck.Checksum.File = FFS_FIXED_CHECKSUM;\r
-      }\r
-\r
-      FfsFile->State = SavedState;\r
-    }\r
-    //\r
-    // Update tail if present\r
-    //\r
-    if (FfsFile->Attributes & FFS_ATTRIB_TAIL_PRESENT) {\r
-      TailValue = (EFI_FFS_FILE_TAIL) (~(FfsFile->IntegrityCheck.TailReference));\r
-      *(EFI_FFS_FILE_TAIL *) (((UINTN) FfsFile + GetLength (FfsFile->Size) - sizeof (EFI_FFS_FILE_TAIL))) = TailValue;\r
-    }\r
-  }\r
-  //\r
-  // Now process TE sections\r
-  //\r
-  for (Index = 1;; Index++) {\r
-    Status = GetSectionByType (FfsFile, EFI_SECTION_TE, Index, &CurrentPe32Section);\r
-    if (EFI_ERROR (Status)) {\r
-      break;\r
-    }\r
-\r
-    FoundCount++;\r
-\r
-    //\r
-    // Calculate the TE base address, the FFS file base plus the offset of the TE section less the size stripped off\r
-    // by GenTEImage\r
-    //\r
-    TEImageHeader = (EFI_TE_IMAGE_HEADER *) ((UINT8 *) CurrentPe32Section.Pe32Section + sizeof (EFI_COMMON_SECTION_HEADER));\r
-\r
-    NewPe32BaseAddress = ((UINT32) BaseAddress) +\r
-      (\r
-        (UINTN) CurrentPe32Section.Pe32Section +\r
-        sizeof (EFI_COMMON_SECTION_HEADER) +\r
-        sizeof (EFI_TE_IMAGE_HEADER) -\r
-        TEImageHeader->StrippedSize -\r
-        (UINTN) FfsFile\r
-      );\r
-\r
-    //\r
-    // Allocate a buffer to unshrink the image into.\r
-    //\r
-    Pe32ImageSize = GetLength (CurrentPe32Section.Pe32Section->CommonHeader.Size) - sizeof (EFI_PE32_SECTION) -\r
-    sizeof (EFI_TE_IMAGE_HEADER);\r
-    Pe32ImageSize += TEImageHeader->StrippedSize;\r
-    TEBuffer = (UINT8 *) malloc (Pe32ImageSize);\r
-    if (TEBuffer == NULL) {\r
-      Error (NULL, 0, 0, "failed to allocate memory", NULL);\r
-      return EFI_OUT_OF_RESOURCES;\r
-    }\r
-    //\r
-    // Expand the image into our buffer and fill in critical fields in the DOS header\r
-    // Fill in fields required by the loader.\r
-    // At offset 0x3C is the offset to the PE signature. We'll put it immediately following the offset value\r
-    // itself.\r
-    //\r
-    memset (TEBuffer, 0, Pe32ImageSize);\r
-    DosHeader = (EFI_IMAGE_DOS_HEADER *) TEBuffer;\r
-    DosHeader->e_magic = EFI_IMAGE_DOS_SIGNATURE;\r
-    *(UINT32 *) (TEBuffer + 0x3C) = 0x40;\r
-    PeHdr = (EFI_IMAGE_NT_HEADERS *) (TEBuffer + 0x40);\r
-    PeHdr->Signature = EFI_IMAGE_NT_SIGNATURE;\r
-    PeHdr->FileHeader.Machine = TEImageHeader->Machine;\r
-    PeHdr->FileHeader.NumberOfSections = TEImageHeader->NumberOfSections;\r
-\r
-    //\r
-    // Say the size of the optional header is the total we stripped off less the size of a PE file header and PE signature and\r
-    // the 0x40 bytes for our DOS header.\r
-    //\r
-    PeHdr->FileHeader.SizeOfOptionalHeader = (UINT16) (TEImageHeader->StrippedSize - 0x40 - sizeof (UINT32) - sizeof (EFI_IMAGE_FILE_HEADER));\r
-    PeHdr->OptionalHeader.ImageBase = (UINTN) (TEImageHeader->ImageBase - TEImageHeader->StrippedSize + sizeof (EFI_TE_IMAGE_HEADER));\r
-    PeHdr->OptionalHeader.AddressOfEntryPoint = TEImageHeader->AddressOfEntryPoint;\r
-    PeHdr->OptionalHeader.BaseOfCode  = TEImageHeader->BaseOfCode;\r
-    PeHdr->OptionalHeader.SizeOfImage = Pe32ImageSize;\r
-    PeHdr->OptionalHeader.Subsystem   = TEImageHeader->Subsystem;\r
-    PeHdr->OptionalHeader.SizeOfImage = Pe32ImageSize;\r
-    PeHdr->OptionalHeader.SizeOfHeaders = TEImageHeader->StrippedSize + TEImageHeader->NumberOfSections *\r
-    sizeof (EFI_IMAGE_SECTION_HEADER) - 12;\r
-\r
-    //\r
-    // Set NumberOfRvaAndSizes in the optional header to what we had available in the original image\r
-    //\r
-    if ((TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress != 0) ||\r
-        (TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size != 0)\r
-        ) {\r
-      PeHdr->OptionalHeader.NumberOfRvaAndSizes = EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC + 1;\r
-      PeHdr->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress = TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress;\r
-      PeHdr->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size = TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size;\r
-    }\r
-\r
-    if ((TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress != 0) ||\r
-        (TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].Size != 0)\r
-        ) {\r
-      PeHdr->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress = TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress;\r
-      PeHdr->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].Size = TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].Size;\r
-      if (PeHdr->OptionalHeader.NumberOfRvaAndSizes < EFI_IMAGE_DIRECTORY_ENTRY_DEBUG + 1) {\r
-        PeHdr->OptionalHeader.NumberOfRvaAndSizes = EFI_IMAGE_DIRECTORY_ENTRY_DEBUG + 1;\r
-      }\r
-    }\r
-    //\r
-    // NOTE: These values are defaults, and should be verified to be correct in the GenTE utility\r
-    //\r
-    PeHdr->OptionalHeader.SectionAlignment = 0x10;\r
-\r
-    //\r
-    // Copy the rest of the image to its original offset\r
-    //\r
-    memcpy (\r
-      TEBuffer + TEImageHeader->StrippedSize,\r
-      (UINT8 *) CurrentPe32Section.Pe32Section + sizeof (EFI_PE32_SECTION) + sizeof (EFI_TE_IMAGE_HEADER),\r
-      GetLength (CurrentPe32Section.Pe32Section->CommonHeader.Size) - sizeof (EFI_PE32_SECTION) -\r
-      sizeof (EFI_TE_IMAGE_HEADER)\r
-      );\r
-\r
-    //\r
-    // Initialize context\r
-    //\r
-    memset (&ImageContext, 0, sizeof (ImageContext));\r
-    ImageContext.Handle     = (VOID *) TEBuffer;\r
-    ImageContext.ImageRead  = (PE_COFF_LOADER_READ_FILE) FfsRebaseImageRead;\r
-\r
-    Status                  = PeCoffLoaderGetImageInfo (&ImageContext);\r
-\r
-    if (EFI_ERROR (Status)) {\r
-      Error (NULL, 0, 0, "GetImageInfo() call failed on rebase of TE image", FileGuidString);\r
-      free (TEBuffer);\r
-      return Status;\r
-    }\r
-    //\r
-    // Allocate a buffer for the image to be loaded into.\r
-    //\r
-    MemoryImagePointer = (UINTN) (malloc (Pe32ImageSize + 0x1000));\r
-    if (MemoryImagePointer == 0) {\r
-      Error (NULL, 0, 0, "memory allocation error on rebase of TE image", FileGuidString);\r
-      free (TEBuffer);\r
-      return EFI_OUT_OF_RESOURCES;\r
-    }\r
-    memset ((void *) MemoryImagePointer, 0, Pe32ImageSize + 0x1000);\r
-    MemoryImagePointerAligned = (MemoryImagePointer + 0x0FFF) & (-1 << 12);\r
-    \r
-\r
-    ImageContext.ImageAddress = MemoryImagePointerAligned;\r
-    Status                    = PeCoffLoaderLoadImage (&ImageContext);\r
-    if (EFI_ERROR (Status)) {\r
-      Error (NULL, 0, 0, "LoadImage() call failed on rebase of TE image", FileGuidString);\r
-      free (TEBuffer);\r
-      free ((VOID *) MemoryImagePointer);\r
-      return Status;\r
-    }\r
-\r
-    ImageContext.DestinationAddress = NewPe32BaseAddress;\r
-    Status                          = PeCoffLoaderRelocateImage (&ImageContext);\r
-    if (EFI_ERROR (Status)) {\r
-      Error (NULL, 0, 0, "RelocateImage() call failed on rebase of TE image", FileGuidString);\r
-      free ((VOID *) MemoryImagePointer);\r
-      free (TEBuffer);\r
-      return Status;\r
-    }\r
-\r
-    ImageAddress  = ImageContext.ImageAddress;\r
-    ImageSize     = ImageContext.ImageSize;\r
-    EntryPoint    = ImageContext.EntryPoint;\r
-\r
-    //\r
-    // Since we may have updated the Codeview RVA, we need to insure the PE\r
-    // header indicates the image is large enough to contain the Codeview data\r
-    // so it will be loaded properly later if the PEIM is reloaded into memory...\r
-    //\r
-    PeHdr = (VOID *) ((UINTN) ImageAddress + ImageContext.PeCoffHeaderOffset);\r
-    if (PeHdr->FileHeader.Machine == EFI_IMAGE_MACHINE_IA32) {\r
-      PeHdrSizeOfImage     = (UINT32 *) (&(*(EFI_IMAGE_OPTIONAL_HEADER32 *) &PeHdr->OptionalHeader).SizeOfImage);\r
-      PeHdrChecksum        = (UINT32 *) (&(*(EFI_IMAGE_OPTIONAL_HEADER32 *) &PeHdr->OptionalHeader).CheckSum);\r
-    } else if (PeHdr->FileHeader.Machine == EFI_IMAGE_MACHINE_IA64) {\r
-      PeHdrSizeOfImage     = (UINT32 *) (&(*(EFI_IMAGE_OPTIONAL_HEADER64 *) &PeHdr->OptionalHeader).SizeOfImage);\r
-      PeHdrChecksum        = (UINT32 *) (&(*(EFI_IMAGE_OPTIONAL_HEADER64 *) &PeHdr->OptionalHeader).CheckSum);\r
-    } else {\r
-      Error (\r
-        NULL,\r
-        0,\r
-        0,\r
-        "unknown machine type in TE image",\r
-        "machine type=0x%X, file=%s",\r
-        (UINT32) PeHdr->FileHeader.Machine,\r
-        FileGuidString\r
-        );\r
-      free ((VOID *) MemoryImagePointer);\r
-      free (TEBuffer);\r
-      return EFI_ABORTED;\r
-    }\r
-\r
-    if (*PeHdrSizeOfImage != ImageContext.ImageSize) {\r
-      *PeHdrSizeOfImage = (UINT32) ImageContext.ImageSize;\r
-      if (*PeHdrChecksum) {\r
-        *PeHdrChecksum = 0;\r
-      }\r
-    }\r
-\r
-    TEImageHeader->ImageBase = (UINT64) (NewPe32BaseAddress + TEImageHeader->StrippedSize - sizeof (EFI_TE_IMAGE_HEADER));\r
-    memcpy (\r
-      (UINT8 *) (CurrentPe32Section.Pe32Section + 1) + sizeof (EFI_TE_IMAGE_HEADER),\r
-      (VOID *) ((UINT8 *) MemoryImagePointerAligned + TEImageHeader->StrippedSize),\r
-      GetLength (CurrentPe32Section.Pe32Section->CommonHeader.Size) - sizeof (EFI_PE32_SECTION) -\r
-      sizeof (EFI_TE_IMAGE_HEADER)\r
-      );\r
-    \r
-    //\r
-    // Get EntryPoint in Flash Region.\r
-    //\r
-    EntryPoint = NewPe32BaseAddress + EntryPoint - ImageAddress;\r
-\r
-    //\r
-    // If a map file was selected output mapping information for any file that\r
-    // was rebased.\r
-    //\r
-    if (MapFile != NULL) {\r
-      fprintf (MapFile, "TE   File: %s Base:%08lx", FileGuidString, BaseAddress);\r
-      fprintf (MapFile, " EntryPoint:%08lx", EntryPoint);\r
-      if (ImageContext.PdbPointer != NULL) {\r
-        fprintf (MapFile, " FileName: %s", ImageContext.PdbPointer);\r
-      }\r
-      fprintf (MapFile, "\n");\r
-    }\r
-\r
-    free ((VOID *) MemoryImagePointer);\r
-    free (TEBuffer);\r
-    if (FfsFile->Attributes & FFS_ATTRIB_TAIL_PRESENT) {\r
-      TailSize = sizeof (EFI_FFS_FILE_TAIL);\r
-    } else {\r
-      TailSize = 0;\r
-    }\r
-    //\r
-    // Now update file checksum\r
-    //\r
-    if (FfsFile->Attributes & FFS_ATTRIB_CHECKSUM) {\r
-      SavedState  = FfsFile->State;\r
-      FfsFile->IntegrityCheck.Checksum.File = 0;\r
-      FfsFile->State                        = 0;\r
-      if (FfsFile->Attributes & FFS_ATTRIB_CHECKSUM) {\r
-        FfsFile->IntegrityCheck.Checksum.File = CalculateChecksum8 (\r
-                                                  (UINT8 *) FfsFile,\r
-                                                  GetLength (FfsFile->Size) - TailSize\r
-                                                  );\r
-      } else {\r
-        FfsFile->IntegrityCheck.Checksum.File = FFS_FIXED_CHECKSUM;\r
-      }\r
-\r
-      FfsFile->State = SavedState;\r
-    }\r
-    //\r
-    // Update tail if present\r
-    //\r
-    if (FfsFile->Attributes & FFS_ATTRIB_TAIL_PRESENT) {\r
-      TailValue = (EFI_FFS_FILE_TAIL) (~(FfsFile->IntegrityCheck.TailReference));\r
-      *(EFI_FFS_FILE_TAIL *) (((UINTN) FfsFile + GetLength (FfsFile->Size) - sizeof (EFI_FFS_FILE_TAIL))) = TailValue;\r
-    }\r
-  }\r
-  //\r
-  // If we found no files, then emit an error if no compressed sections either\r
-  //\r
-  if (FoundCount == 0) {\r
-    Status = GetSectionByType (FfsFile, EFI_SECTION_COMPRESSION, Index, &CurrentPe32Section);\r
-    if (EFI_ERROR (Status)) {\r
-      Error (NULL, 0, 0, "no PE32, TE, nor compressed section found in FV file", FileGuidString);\r
-      return EFI_NOT_FOUND;\r
-    }\r
-  }\r
-  \r
-  return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-FfsRebaseImageRead (\r
-  IN     VOID    *FileHandle,\r
-  IN     UINTN   FileOffset,\r
-  IN OUT UINT32  *ReadSize,\r
-  OUT    VOID    *Buffer\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  Support routine for the PE/COFF Loader that reads a buffer from a PE/COFF file\r
-\r
-Arguments:\r
-\r
-  FileHandle - The handle to the PE/COFF file\r
-\r
-  FileOffset - The offset, in bytes, into the file to read\r
-\r
-  ReadSize   - The number of bytes to read from the file starting at FileOffset\r
-\r
-  Buffer     - A pointer to the buffer to read the data into.\r
-\r
-Returns:\r
-\r
-  EFI_SUCCESS - ReadSize bytes of data were read into Buffer from the PE/COFF file starting at FileOffset\r
-\r
---*/\r
-{\r
-  CHAR8   *Destination8;\r
-  CHAR8   *Source8;\r
-  UINT32  Length;\r
-\r
-  Destination8  = Buffer;\r
-  Source8       = (CHAR8 *) ((UINTN) FileHandle + FileOffset);\r
-  Length        = *ReadSize;\r
-  while (Length--) {\r
-    *(Destination8++) = *(Source8++);\r
-  }\r
-\r
-  return EFI_SUCCESS;\r
-}\r