]> git.proxmox.com Git - mirror_edk2.git/blobdiff - Tools/CCode/Source/PeiRebase/PeiRebaseExe.c
Correct TeImage file format and Clean up PeiRebase tool to remove unused code and...
[mirror_edk2.git] / Tools / CCode / Source / PeiRebase / PeiRebaseExe.c
index c234ccffaaed3173a04d676418a0a07893638953..93acb635f5c2c217a7299a15a82b928c684bd8e1 100644 (file)
@@ -279,6 +279,7 @@ Returns:
       break;\r
     }\r
   }\r
+\r
   //\r
   // Open the file containing the FV\r
   //\r
@@ -553,14 +554,18 @@ Returns:
   Version();\r
   \r
   printf (\r
-    "\nUsage: %s -I InputFileName -O OutputFileName -B BaseAddress\n",\r
+    "Usage: %s -I InputFileName -O OutputFileName -B BaseAddress [-F InputFvInfName]\n",\r
     UTILITY_NAME\r
     );\r
+  printf ("  [-D BootDriverBaseAddress] [-R RuntimeDriverBaseAddress]\n");\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 ("  Argument pair may be in any order.\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 rebase address for all drivers run in Flash.\n");\r
+  printf ("      InputFvInfName is the Fv.inf file that contains this FV base address to rebase against.\n");\r
+  printf ("      BootDriverBaseAddress is the rebase address for all boot drivers in this fv image.\n");\r
+  printf ("      RuntimeDriverBaseAddress is the rebase address for all runtime drivers in this fv image.\n");\r
+  printf ("  Argument pair may be in any order.\n\n");\r
 }\r
 \r
 EFI_STATUS\r
@@ -596,27 +601,18 @@ Returns:
 {\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
   EFI_PHYSICAL_ADDRESS                  NewPe32BaseAddress;\r
   UINTN                                 Index;\r
   EFI_FILE_SECTION_POINTER              CurrentPe32Section;\r
   EFI_FFS_FILE_STATE                    SavedState;\r
   EFI_IMAGE_NT_HEADERS32                *PeHdr;\r
-  EFI_IMAGE_NT_HEADERS64                *PePlusHdr;\r
-  UINT32                                *PeHdrSizeOfImage;\r
-  UINT32                                *PeHdrChecksum;\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
   EFI_PHYSICAL_ADDRESS                  *BaseToUpdate;\r
+  EFI_IMAGE_DEBUG_DIRECTORY_ENTRY       *DebugEntry;\r
+  \r
 \r
   //\r
   // Verify input parameters\r
@@ -668,7 +664,6 @@ Returns:
       break;\r
     }\r
 \r
-\r
     //\r
     // Initialize context\r
     //\r
@@ -681,6 +676,50 @@ Returns:
       return Status;\r
     }\r
 \r
+    //\r
+    // Don't Load PeImage, only to relocate current image.\r
+    //\r
+    ImageContext.ImageAddress = (UINTN) CurrentPe32Section.Pe32Section + sizeof (EFI_PE32_SECTION);\r
+\r
+    //\r
+    // Check if section-alignment and file-alignment match or not\r
+    //\r
+    PeHdr = (EFI_IMAGE_NT_HEADERS *)((UINTN)ImageContext.ImageAddress + ImageContext.PeCoffHeaderOffset);\r
+    if (PeHdr->OptionalHeader.SectionAlignment != PeHdr->OptionalHeader.FileAlignment) {\r
+      //\r
+      // Nor XIP module can be ignored. \r
+      //\r
+      if ((Flags & 1) == 0) {\r
+        continue;\r
+      }\r
+      Error (NULL, 0, 0, "Section-Alignment and File-Alignment does not match", FileGuidString);\r
+      return EFI_ABORTED;\r
+    } \r
+\r
+    //\r
+    // Update CodeView and PdbPointer in ImageContext\r
+    //\r
+    DebugEntry = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *)(UINTN)(\r
+                    ImageContext.ImageAddress +\r
+                    ImageContext.DebugDirectoryEntryRva\r
+                    );\r
+    ImageContext.CodeView = (VOID *)(UINTN)( \r
+                              ImageContext.ImageAddress + \r
+                              DebugEntry->RVA\r
+                              );\r
+    switch (*(UINT32 *) ImageContext.CodeView) {\r
+    case CODEVIEW_SIGNATURE_NB10:\r
+      ImageContext.PdbPointer = (CHAR8 *) ImageContext.CodeView + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY);\r
+      break;\r
+\r
+    case CODEVIEW_SIGNATURE_RSDS:\r
+      ImageContext.PdbPointer = (CHAR8 *) ImageContext.CodeView + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_RSDS_ENTRY);\r
+      break;\r
+\r
+    default:\r
+      break;\r
+    }\r
+\r
     //\r
     // Calculate the PE32 base address, based on file type\r
     //\r
@@ -697,19 +736,12 @@ Returns:
         }\r
 \r
         NewPe32BaseAddress =\r
-          XipBase +\r
-          (UINTN)CurrentPe32Section.Pe32Section +\r
-          sizeof (EFI_COMMON_SECTION_HEADER) -\r
-          (UINTN)FfsFile;\r
+          XipBase + (UINTN)ImageContext.ImageAddress - (UINTN)FfsFile;\r
         BaseToUpdate = &XipBase;\r
         break;\r
 \r
       case EFI_FV_FILETYPE_DRIVER:\r
-        PeHdr = (EFI_IMAGE_NT_HEADERS32*)(\r
-          (UINTN)CurrentPe32Section.Pe32Section +\r
-          sizeof (EFI_COMMON_SECTION_HEADER) +\r
-          ImageContext.PeCoffHeaderOffset\r
-          );\r
+        PeHdr = (EFI_IMAGE_NT_HEADERS32*)(ImageContext.ImageAddress + ImageContext.PeCoffHeaderOffset);\r
         switch (PeHdr->OptionalHeader.Subsystem) {\r
           case EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER:\r
             if ((Flags & 4) == 0) {\r
@@ -759,72 +791,13 @@ Returns:
         return EFI_SUCCESS;\r
     }\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 + 0x100000));\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 + 0x100000);\r
-    MemoryImagePointerAligned = (MemoryImagePointer + 0x0FFFF) & (-1 << 16);\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
-    //\r
-    // Check if section-alignment and file-alignment match or not\r
-    //\r
-    if (!(ImageContext.IsTeImage)) {\r
-      PeHdr = (EFI_IMAGE_NT_HEADERS *)((UINTN)ImageContext.ImageAddress + \r
-                                              ImageContext.PeCoffHeaderOffset);\r
-      if (PeHdr->OptionalHeader.SectionAlignment != PeHdr->OptionalHeader.FileAlignment) {\r
-        Error (NULL, 0, 0, "Section-Alignment and File-Alignment does not match", FileGuidString);\r
-        free ((VOID *) MemoryImagePointer);\r
-        return EFI_ABORTED;\r
-      }\r
-    }\r
-    else {\r
-      //\r
-      // BUGBUG: TE Image Header lack section-alignment and file-alignment info\r
-      //\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
     //\r
     // Update BASE address\r
     //\r
@@ -837,47 +810,6 @@ Returns:
       );\r
     *BaseToUpdate += EFI_SIZE_TO_PAGES (ImageContext.ImageSize) * EFI_PAGE_SIZE;\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
-    PePlusHdr = (EFI_IMAGE_NT_HEADERS64*)PeHdr;\r
-    if (PeHdr->FileHeader.Machine == EFI_IMAGE_MACHINE_IA32) {\r
-      PeHdrSizeOfImage  = (UINT32 *) (&(PeHdr->OptionalHeader).SizeOfImage);\r
-      PeHdrChecksum     = (UINT32 *) (&(PeHdr->OptionalHeader).CheckSum);\r
-    } else if (PeHdr->FileHeader.Machine == EFI_IMAGE_MACHINE_IA64) {\r
-      PeHdrSizeOfImage  = (UINT32 *) (&(PePlusHdr->OptionalHeader).SizeOfImage);\r
-      PeHdrChecksum     = (UINT32 *) (&(PePlusHdr->OptionalHeader).CheckSum);\r
-    } else if (PeHdr->FileHeader.Machine == EFI_IMAGE_MACHINE_X64) {\r
-      PeHdrSizeOfImage  = (UINT32 *) (&(PePlusHdr->OptionalHeader).SizeOfImage);\r
-      PeHdrChecksum     = (UINT32 *) (&(PePlusHdr->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
-    free ((VOID *) MemoryImagePointer);\r
-\r
     //\r
     // Now update file checksum\r
     //\r
@@ -923,7 +855,7 @@ Returns:
     //\r
     return EFI_SUCCESS;\r
   }\r
-\r
+  \r
   //\r
   // Now process TE sections\r
   //\r
@@ -939,235 +871,65 @@ Returns:
     //\r
     TEImageHeader = (EFI_TE_IMAGE_HEADER *) ((UINT8 *) CurrentPe32Section.Pe32Section + sizeof (EFI_COMMON_SECTION_HEADER));\r
 \r
-    NewPe32BaseAddress = ((UINT32) XipBase) +\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
-    PePlusHdr = (EFI_IMAGE_NT_HEADERS64*)PeHdr;\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
-    if (TEImageHeader->Machine == EFI_IMAGE_MACHINE_IA32) {\r
-      PeHdr->OptionalHeader.Magic = EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC;\r
-    } else if (TEImageHeader->Machine == EFI_IMAGE_MACHINE_IA64) {\r
-      PePlusHdr->OptionalHeader.Magic = EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC;\r
-    } else if (TEImageHeader->Machine == EFI_IMAGE_MACHINE_X64) {\r
-      PePlusHdr->OptionalHeader.Magic = EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC;\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) TEImageHeader->Machine,\r
-        FileGuidString\r
-        );\r
-      free (TEBuffer);\r
-      return EFI_ABORTED;\r
-    }\r
-\r
-    if (PeHdr->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
-      PeHdr->OptionalHeader.ImageBase     = (UINTN) (TEImageHeader->ImageBase - TEImageHeader->StrippedSize + sizeof (EFI_TE_IMAGE_HEADER));\r
-      PeHdr->OptionalHeader.SizeOfImage   = Pe32ImageSize;\r
-      PeHdr->OptionalHeader.Subsystem     = TEImageHeader->Subsystem;\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
-    } else {\r
-      PePlusHdr->OptionalHeader.ImageBase     = (UINTN) (TEImageHeader->ImageBase - TEImageHeader->StrippedSize + sizeof (EFI_TE_IMAGE_HEADER));\r
-      PePlusHdr->OptionalHeader.SizeOfImage   = Pe32ImageSize;\r
-      PePlusHdr->OptionalHeader.Subsystem     = TEImageHeader->Subsystem;\r
-      PePlusHdr->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
-        PePlusHdr->OptionalHeader.NumberOfRvaAndSizes = EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC + 1;\r
-        PePlusHdr->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress = TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress;\r
-        PePlusHdr->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
-        PePlusHdr->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress = TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress;\r
-        PePlusHdr->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].Size = TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].Size;\r
-        if (PePlusHdr->OptionalHeader.NumberOfRvaAndSizes < EFI_IMAGE_DIRECTORY_ENTRY_DEBUG + 1) {\r
-          PePlusHdr->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
-      PePlusHdr->OptionalHeader.SectionAlignment = 0x10;\r
-    }\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
+    // Initialize context, load image info.\r
     //\r
     memset (&ImageContext, 0, sizeof (ImageContext));\r
-    ImageContext.Handle     = (VOID *) TEBuffer;\r
+    ImageContext.Handle     = (VOID *) TEImageHeader;\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
+    // Don't reload TeImage\r
     //\r
-    MemoryImagePointer = (UINTN) (malloc (Pe32ImageSize + 0x100000));\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 + 0x100000);\r
-    MemoryImagePointerAligned = (MemoryImagePointer + 0x0FFFF) & (-1 << 16);\r
-    \r
+    ImageContext.ImageAddress = (UINTN) TEImageHeader;\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
+    // Update CodeView and PdbPointer in ImageContext\r
+    //\r
+    DebugEntry = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *)(UINTN)(\r
+                   ImageContext.ImageAddress +\r
+                   ImageContext.DebugDirectoryEntryRva +\r
+                   sizeof(EFI_TE_IMAGE_HEADER) -\r
+                   TEImageHeader->StrippedSize\r
+                   );\r
+\r
+    ImageContext.CodeView = (VOID *)(UINTN)(\r
+                              ImageContext.ImageAddress +\r
+                              DebugEntry->RVA +\r
+                              sizeof(EFI_TE_IMAGE_HEADER) -\r
+                              TEImageHeader->StrippedSize\r
+                              );\r
+\r
+    switch (*(UINT32 *) ImageContext.CodeView) {\r
+    case CODEVIEW_SIGNATURE_NB10:\r
+      ImageContext.PdbPointer = (CHAR8 *) ImageContext.CodeView + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY);\r
+      break;\r
+\r
+    case CODEVIEW_SIGNATURE_RSDS:\r
+      ImageContext.PdbPointer = (CHAR8 *) ImageContext.CodeView + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_RSDS_ENTRY);\r
+      break;\r
+\r
+    default:\r
+      break;\r
     }\r
 \r
-    ImageContext.DestinationAddress = NewPe32BaseAddress;\r
+    //\r
+    // Reloacate TeImage\r
+    // \r
+    ImageContext.DestinationAddress = XipBase + (UINTN) TEImageHeader + sizeof (EFI_TE_IMAGE_HEADER) \\r
+                                      - TEImageHeader->StrippedSize - (UINTN) FfsFile;\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
-    PePlusHdr = (EFI_IMAGE_NT_HEADERS64*)PeHdr;\r
-    if (PeHdr->FileHeader.Machine == EFI_IMAGE_MACHINE_IA32) {\r
-      PeHdrSizeOfImage  = (UINT32 *) (&(PeHdr->OptionalHeader).SizeOfImage);\r
-      PeHdrChecksum     = (UINT32 *) (&(PeHdr->OptionalHeader).CheckSum);\r
-    } else if (PeHdr->FileHeader.Machine == EFI_IMAGE_MACHINE_IA64) {\r
-      PeHdrSizeOfImage  = (UINT32 *) (&(PePlusHdr->OptionalHeader).SizeOfImage);\r
-      PeHdrChecksum     = (UINT32 *) (&(PePlusHdr->OptionalHeader).CheckSum);\r
-    } else if (PeHdr->FileHeader.Machine == EFI_IMAGE_MACHINE_X64) {\r
-      PeHdrSizeOfImage  = (UINT32 *) (&(PePlusHdr->OptionalHeader).SizeOfImage);\r
-      PeHdrChecksum     = (UINT32 *) (&(PePlusHdr->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
     if (FfsFile->Attributes & FFS_ATTRIB_TAIL_PRESENT) {\r
       TailSize = sizeof (EFI_FFS_FILE_TAIL);\r
     } else {\r
@@ -1206,14 +968,8 @@ Returns:
       ImageContext.DestinationAddress,\r
       ImageContext.PdbPointer == NULL ? "*" : ImageContext.PdbPointer\r
       );\r
-\r
-    //\r
-    // Free buffers\r
-    //\r
-    free ((VOID *) MemoryImagePointer);\r
-    free (TEBuffer);\r
   }\r
-\r
\r
   return EFI_SUCCESS;\r
 }\r
 \r