From 54c0f644f9d8d0f1d979dc52a4139c000f321f7f Mon Sep 17 00:00:00 2001
From: Mikhail Krichanov <mikhailkrichanov@gmail.com>
Date: Fri, 15 Dec 2023 15:07:47 +0300
Subject: [PATCH] BaseTools/C: Consume UefiImageLib and ImageToolEmit

---
 BaseTools/ImageTool/BinEmit.c                 |    3 +
 BaseTools/ImageTool/ElfScan.c                 |   15 +-
 BaseTools/Source/C/Common/BasePeCoff.c        | 1417 -----------------
 BaseTools/Source/C/Common/CommonLib.c         |   66 +
 BaseTools/Source/C/Common/CommonLib.h         |    6 +
 BaseTools/Source/C/Common/GNUmakefile         |   40 +-
 BaseTools/Source/C/Common/Makefile            |   40 +-
 BaseTools/Source/C/Common/PeCoffLib.h         |  213 ---
 BaseTools/Source/C/Common/PeCoffLoaderEx.c    |  385 -----
 BaseTools/Source/C/EfiRom/EfiRom.c            |  134 +-
 BaseTools/Source/C/EfiRom/EfiRom.h            |   13 +-
 BaseTools/Source/C/GenFfs/GenFfs.c            |  100 --
 BaseTools/Source/C/GenFv/GenFvInternalLib.c   |  573 +++----
 BaseTools/Source/C/GenFv/GenFvInternalLib.h   |    6 +-
 BaseTools/Source/C/GenSec/GenSec.c            |  100 --
 BaseTools/Source/C/Include/Common/AutoGen.h   |  272 ++--
 BaseTools/Source/C/Include/Common/PeImageEx.h |   59 -
 BaseTools/Source/C/Makefiles/header.makefile  |    2 +-
 BaseTools/Source/C/Makefiles/ms.common        |    2 +-
 BaseTools/Source/C/Makefiles/ms.rule          |   24 +
 BaseTools/Source/C/VolInfo/VolInfo.c          |  259 +--
 21 files changed, 697 insertions(+), 3032 deletions(-)
 delete mode 100644 BaseTools/Source/C/Common/BasePeCoff.c
 delete mode 100644 BaseTools/Source/C/Common/PeCoffLib.h
 delete mode 100644 BaseTools/Source/C/Common/PeCoffLoaderEx.c
 delete mode 100644 BaseTools/Source/C/Include/Common/PeImageEx.h

diff --git a/BaseTools/ImageTool/BinEmit.c b/BaseTools/ImageTool/BinEmit.c
index 51fbb6f5a7..828c357a7a 100644
--- a/BaseTools/ImageTool/BinEmit.c
+++ b/BaseTools/ImageTool/BinEmit.c
@@ -5,6 +5,9 @@
 
 #include "ImageTool.h"
 
+#include <Uefi/UefiBaseType.h>
+#include <Uefi/UefiSpec.h>
+
 static
 EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY *
 CreateEntry (
diff --git a/BaseTools/ImageTool/ElfScan.c b/BaseTools/ImageTool/ElfScan.c
index ca2a1010b2..60fd9184b5 100644
--- a/BaseTools/ImageTool/ElfScan.c
+++ b/BaseTools/ImageTool/ElfScan.c
@@ -52,13 +52,6 @@ typedef struct {
   bool            HasPieRelocs;
 } tool_elf_scan_context;
 
-#if defined (_MSC_EXTENSIONS)
-#define EFI_IMAGE_MACHINE_IA32            0x014C
-#define EFI_IMAGE_MACHINE_X64             0x8664
-#define EFI_IMAGE_MACHINE_ARMTHUMB_MIXED  0x01C2
-#define EFI_IMAGE_MACHINE_AARCH64         0xAA64
-#endif
-
 
 #define GetShrbyIndex  ELF_SUFFIX(GetShrbyIndex)
 static
@@ -687,17 +680,17 @@ ScanElf (
   switch (Ehdr->e_machine) {
 #if ELF_ARCH == 64
     case EM_X86_64:
-      ImageInfo->HeaderInfo.Machine = EFI_IMAGE_MACHINE_X64;
+      ImageInfo->HeaderInfo.Machine = IMAGE_FILE_MACHINE_X64;
       break;
     case EM_AARCH64:
-      ImageInfo->HeaderInfo.Machine = EFI_IMAGE_MACHINE_AARCH64;
+      ImageInfo->HeaderInfo.Machine = IMAGE_FILE_MACHINE_ARM64;
       break;
 #elif ELF_ARCH == 32
     case EM_386:
-      ImageInfo->HeaderInfo.Machine = EFI_IMAGE_MACHINE_IA32;
+      ImageInfo->HeaderInfo.Machine = IMAGE_FILE_MACHINE_I386;
       break;
     case EM_ARM:
-      ImageInfo->HeaderInfo.Machine = EFI_IMAGE_MACHINE_ARMTHUMB_MIXED;
+      ImageInfo->HeaderInfo.Machine = IMAGE_FILE_MACHINE_ARMTHUMB_MIXED;
       break;
 #endif
     default:
diff --git a/BaseTools/Source/C/Common/BasePeCoff.c b/BaseTools/Source/C/Common/BasePeCoff.c
deleted file mode 100644
index c38180af69..0000000000
--- a/BaseTools/Source/C/Common/BasePeCoff.c
+++ /dev/null
@@ -1,1417 +0,0 @@
-/** @file
-
-  Functions to get info and load PE/COFF image.
-
-Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>
-Portions Copyright (c) 2011 - 2013, ARM Ltd. All rights reserved.<BR>
-Portions Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
-Portions Copyright (c) 2022, Loongson Technology Corporation Limited. All rights reserved.<BR>
-SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#include <Common/UefiBaseTypes.h>
-#include <CommonLib.h>
-#include <Common/PeImageEx.h>
-#include "PeCoffLib.h"
-
-typedef union {
-  VOID                         *Header;
-  EFI_IMAGE_OPTIONAL_HEADER32  *Optional32;
-  EFI_IMAGE_OPTIONAL_HEADER64  *Optional64;
-} EFI_IMAGE_OPTIONAL_HEADER_POINTER;
-
-STATIC
-RETURN_STATUS
-PeCoffLoaderGetPeHeader (
-  IN OUT PE_COFF_LOADER_IMAGE_CONTEXT    *ImageContext,
-  OUT    EFI_IMAGE_OPTIONAL_HEADER_UNION **PeHdr,
-  OUT    EFI_TE_IMAGE_HEADER             **TeHdr
-  );
-
-STATIC
-RETURN_STATUS
-PeCoffLoaderCheckImageType (
-  IN OUT PE_COFF_LOADER_IMAGE_CONTEXT    *ImageContext,
-  IN     EFI_IMAGE_OPTIONAL_HEADER_UNION *PeHdr,
-  IN     EFI_TE_IMAGE_HEADER             *TeHdr
-  );
-
-STATIC
-VOID *
-PeCoffLoaderImageAddress (
-  IN OUT PE_COFF_LOADER_IMAGE_CONTEXT  *ImageContext,
-  IN     UINTN                         Address
-  );
-
-RETURN_STATUS
-PeCoffLoaderRelocateIa32Image (
-  IN UINT16      *Reloc,
-  IN OUT CHAR8   *Fixup,
-  IN OUT CHAR8   **FixupData,
-  IN UINT64      Adjust
-  );
-
-
-RETURN_STATUS
-PeCoffLoaderRelocateArmImage (
-  IN UINT16      **Reloc,
-  IN OUT CHAR8   *Fixup,
-  IN OUT CHAR8   **FixupData,
-  IN UINT64      Adjust
-  );
-
-RETURN_STATUS
-PeCoffLoaderRelocateRiscVImage (
-  IN UINT16      *Reloc,
-  IN OUT CHAR8   *Fixup,
-  IN OUT CHAR8   **FixupData,
-  IN UINT64      Adjust
-  );
-
-RETURN_STATUS
-PeCoffLoaderRelocateLoongArch64Image (
-  IN UINT16      *Reloc,
-  IN OUT CHAR8   *Fixup,
-  IN OUT CHAR8   **FixupData,
-  IN UINT64      Adjust
-  );
-
-/**
-  Retrieves the PE or TE Header from a PE/COFF or TE image
-
-  @param ImageContext  The context of the image being loaded
-  @param PeHdr         The buffer in which to return the PE header
-  @param TeHdr         The buffer in which to return the TE header
-
-  @return RETURN_SUCCESS if the PE or TE Header is read,
-  Otherwise, the error status from reading the PE/COFF or TE image using the ImageRead function.
-**/
-STATIC
-RETURN_STATUS
-PeCoffLoaderGetPeHeader (
-  IN OUT PE_COFF_LOADER_IMAGE_CONTEXT    *ImageContext,
-  OUT    EFI_IMAGE_OPTIONAL_HEADER_UNION **PeHdr,
-  OUT    EFI_TE_IMAGE_HEADER             **TeHdr
-  )
-{
-  RETURN_STATUS         Status;
-  EFI_IMAGE_DOS_HEADER  DosHdr;
-  UINTN                 Size;
-
-  ImageContext->IsTeImage = FALSE;
-  //
-  // Read the DOS image headers
-  //
-  Size = sizeof (EFI_IMAGE_DOS_HEADER);
-  Status = ImageContext->ImageRead (
-                          ImageContext->Handle,
-                          0,
-                          &Size,
-                          &DosHdr
-                          );
-  if (RETURN_ERROR (Status)) {
-    ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;
-    return Status;
-  }
-
-  ImageContext->PeCoffHeaderOffset = 0;
-  if (DosHdr.e_magic == EFI_IMAGE_DOS_SIGNATURE) {
-    //
-    // DOS image header is present, so read the PE header after the DOS image header
-    //
-    ImageContext->PeCoffHeaderOffset = DosHdr.e_lfanew;
-  }
-  //
-  // Get the PE/COFF Header pointer
-  //
-  *PeHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *) ((UINTN)ImageContext->Handle + ImageContext->PeCoffHeaderOffset);
-  if ((*PeHdr)->Pe32.Signature != EFI_IMAGE_NT_SIGNATURE) {
-    //
-    // Check the PE/COFF Header Signature. If not, then try to get a TE header
-    //
-    *TeHdr = (EFI_TE_IMAGE_HEADER *)*PeHdr;
-    if ((*TeHdr)->Signature != EFI_TE_IMAGE_HEADER_SIGNATURE) {
-      return RETURN_UNSUPPORTED;
-    }
-    ImageContext->IsTeImage = TRUE;
-  }
-
-  return RETURN_SUCCESS;
-}
-
-/**
-  Checks the PE or TE header of a PE/COFF or TE image to determine if it supported
-
-  @param ImageContext  The context of the image being loaded
-  @param PeHdr         The buffer in which to return the PE header
-  @param TeHdr         The buffer in which to return the TE header
-
-  @retval RETURN_SUCCESS if the PE/COFF or TE image is supported
-  @retval RETURN_UNSUPPORTED of the PE/COFF or TE image is not supported.
-
-**/
-STATIC
-RETURN_STATUS
-PeCoffLoaderCheckImageType (
-  IN OUT PE_COFF_LOADER_IMAGE_CONTEXT          *ImageContext,
-  IN     EFI_IMAGE_OPTIONAL_HEADER_UNION       *PeHdr,
-  IN     EFI_TE_IMAGE_HEADER                   *TeHdr
-  )
-{
-  //
-  // See if the machine type is supported.
-  // We support a native machine type (IA-32/Itanium-based)
-  //
-  if (ImageContext->IsTeImage == FALSE) {
-    ImageContext->Machine = PeHdr->Pe32.FileHeader.Machine;
-  } else {
-    ImageContext->Machine = TeHdr->Machine;
-  }
-
-  if (ImageContext->Machine != IMAGE_FILE_MACHINE_I386 && \
-      ImageContext->Machine != IMAGE_FILE_MACHINE_X64  && \
-      ImageContext->Machine != IMAGE_FILE_MACHINE_ARMTHUMB_MIXED && \
-      ImageContext->Machine != IMAGE_FILE_MACHINE_EBC  && \
-      ImageContext->Machine != IMAGE_FILE_MACHINE_ARM64 && \
-      ImageContext->Machine != IMAGE_FILE_MACHINE_RISCV64 && \
-      ImageContext->Machine != IMAGE_FILE_MACHINE_LOONGARCH64) {
-    //
-    // unsupported PeImage machine type
-    //
-    return RETURN_UNSUPPORTED;
-  }
-
-  //
-  // See if the image type is supported.  We support EFI Applications,
-  // EFI Boot Service Drivers, EFI Runtime Drivers and EFI SAL Drivers.
-  //
-  if (ImageContext->IsTeImage == FALSE) {
-    ImageContext->ImageType = PeHdr->Pe32.OptionalHeader.Subsystem;
-  } else {
-    ImageContext->ImageType = (UINT16) (TeHdr->Subsystem);
-  }
-
-  if (ImageContext->ImageType != EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION && \
-      ImageContext->ImageType != EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER && \
-      ImageContext->ImageType != EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER && \
-      ImageContext->ImageType != EFI_IMAGE_SUBSYSTEM_SAL_RUNTIME_DRIVER) {
-    //
-    // unsupported PeImage subsystem type
-    //
-    return RETURN_UNSUPPORTED;
-  }
-
-  return RETURN_SUCCESS;
-}
-
-/**
-  Retrieves information on a PE/COFF image
-
-  @param This         Calling context
-  @param ImageContext The context of the image being loaded
-
-  @retval RETURN_SUCCESS           The information on the PE/COFF image was collected.
-  @retval RETURN_INVALID_PARAMETER ImageContext is NULL.
-  @retval RETURN_UNSUPPORTED       The PE/COFF image is not supported.
-  @retval Otherwise                The error status from reading the PE/COFF image using the
-                                  ImageContext->ImageRead() function
-
-**/
-RETURN_STATUS
-EFIAPI
-PeCoffLoaderGetImageInfo (
-  IN OUT PE_COFF_LOADER_IMAGE_CONTEXT           *ImageContext
-  )
-{
-  RETURN_STATUS                   Status;
-  EFI_IMAGE_OPTIONAL_HEADER_UNION *PeHdr;
-  EFI_TE_IMAGE_HEADER             *TeHdr;
-  EFI_IMAGE_DATA_DIRECTORY        *DebugDirectoryEntry;
-  UINTN                           Size;
-  UINTN                           Index;
-  UINTN                           DebugDirectoryEntryRva;
-  UINTN                           DebugDirectoryEntryFileOffset;
-  UINTN                           SectionHeaderOffset;
-  EFI_IMAGE_SECTION_HEADER        SectionHeader;
-  EFI_IMAGE_DEBUG_DIRECTORY_ENTRY DebugEntry;
-  EFI_IMAGE_OPTIONAL_HEADER_POINTER OptionHeader;
-
-  PeHdr = NULL;
-  TeHdr = NULL;
-  DebugDirectoryEntry    = NULL;
-  DebugDirectoryEntryRva = 0;
-
-  if (NULL == ImageContext) {
-    return RETURN_INVALID_PARAMETER;
-  }
-  //
-  // Assume success
-  //
-  ImageContext->ImageError  = IMAGE_ERROR_SUCCESS;
-
-  Status                    = PeCoffLoaderGetPeHeader (ImageContext, &PeHdr, &TeHdr);
-  if (RETURN_ERROR (Status)) {
-    return Status;
-  }
-
-  //
-  // Verify machine type
-  //
-  Status = PeCoffLoaderCheckImageType (ImageContext, PeHdr, TeHdr);
-  if (RETURN_ERROR (Status)) {
-    return Status;
-  }
-  OptionHeader.Header = (VOID *) &(PeHdr->Pe32.OptionalHeader);
-
-  //
-  // Retrieve the base address of the image
-  //
-  if (!(ImageContext->IsTeImage)) {
-    if (PeHdr->Pe32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
-      ImageContext->ImageAddress = (PHYSICAL_ADDRESS) OptionHeader.Optional32->ImageBase;
-    } else {
-      ImageContext->ImageAddress = (PHYSICAL_ADDRESS) OptionHeader.Optional64->ImageBase;
-    }
-  } else {
-    ImageContext->ImageAddress = (PHYSICAL_ADDRESS) (TeHdr->ImageBase + TeHdr->StrippedSize - sizeof (EFI_TE_IMAGE_HEADER));
-  }
-  //
-  // Initialize the alternate destination address to 0 indicating that it
-  // should not be used.
-  //
-  ImageContext->DestinationAddress = 0;
-
-  //
-  // Initialize the codeview pointer.
-  //
-  ImageContext->CodeView    = NULL;
-  ImageContext->PdbPointer  = NULL;
-
-  //
-  // Three cases with regards to relocations:
-  // - Image has base relocs, RELOCS_STRIPPED==0    => image is relocatable
-  // - Image has no base relocs, RELOCS_STRIPPED==1 => Image is not relocatable
-  // - Image has no base relocs, RELOCS_STRIPPED==0 => Image is relocatable but
-  //   has no base relocs to apply
-  // Obviously having base relocations with RELOCS_STRIPPED==1 is invalid.
-  //
-  // Look at the file header to determine if relocations have been stripped, and
-  // save this info in the image context for later use.
-  //
-  if ((!(ImageContext->IsTeImage)) && ((PeHdr->Pe32.FileHeader.Characteristics & EFI_IMAGE_FILE_RELOCS_STRIPPED) != 0)) {
-    ImageContext->RelocationsStripped = TRUE;
-  } else if ((ImageContext->IsTeImage) && (TeHdr->DataDirectory[0].Size == 0) && (TeHdr->DataDirectory[0].VirtualAddress == 0)) {
-    ImageContext->RelocationsStripped = TRUE;
-  } else {
-    ImageContext->RelocationsStripped = FALSE;
-  }
-
-  if (!(ImageContext->IsTeImage)) {
-
-    if (PeHdr->Pe32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
-      ImageContext->ImageSize         = (UINT64) OptionHeader.Optional32->SizeOfImage;
-      ImageContext->SectionAlignment  = OptionHeader.Optional32->SectionAlignment;
-      ImageContext->SizeOfHeaders     = OptionHeader.Optional32->SizeOfHeaders;
-
-      //
-      // Modify ImageSize to contain .PDB file name if required and initialize
-      // PdbRVA field...
-      //
-      if (OptionHeader.Optional32->NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_DEBUG) {
-        DebugDirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *) &(OptionHeader.Optional32->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG]);
-        DebugDirectoryEntryRva = DebugDirectoryEntry->VirtualAddress;
-      }
-    } else {
-      ImageContext->ImageSize         = (UINT64) OptionHeader.Optional64->SizeOfImage;
-      ImageContext->SectionAlignment  = OptionHeader.Optional64->SectionAlignment;
-      ImageContext->SizeOfHeaders     = OptionHeader.Optional64->SizeOfHeaders;
-
-      //
-      // Modify ImageSize to contain .PDB file name if required and initialize
-      // PdbRVA field...
-      //
-      if (OptionHeader.Optional64->NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_DEBUG) {
-        DebugDirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *) &(OptionHeader.Optional64->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG]);
-        DebugDirectoryEntryRva = DebugDirectoryEntry->VirtualAddress;
-      }
-    }
-
-    if (DebugDirectoryEntryRva != 0) {
-      //
-      // Determine the file offset of the debug directory...  This means we walk
-      // the sections to find which section contains the RVA of the debug
-      // directory
-      //
-      DebugDirectoryEntryFileOffset = 0;
-
-      SectionHeaderOffset = (UINTN)(
-                               ImageContext->PeCoffHeaderOffset +
-                               sizeof (UINT32) +
-                               sizeof (EFI_IMAGE_FILE_HEADER) +
-                               PeHdr->Pe32.FileHeader.SizeOfOptionalHeader
-                               );
-
-      for (Index = 0; Index < PeHdr->Pe32.FileHeader.NumberOfSections; Index++) {
-        //
-        // Read section header from file
-        //
-        Size = sizeof (EFI_IMAGE_SECTION_HEADER);
-        Status = ImageContext->ImageRead (
-                                 ImageContext->Handle,
-                                 SectionHeaderOffset,
-                                 &Size,
-                                 &SectionHeader
-                                 );
-        if (RETURN_ERROR (Status)) {
-          ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;
-          return Status;
-        }
-
-        if (DebugDirectoryEntryRva >= SectionHeader.VirtualAddress &&
-            DebugDirectoryEntryRva < SectionHeader.VirtualAddress + SectionHeader.Misc.VirtualSize) {
-            DebugDirectoryEntryFileOffset =
-            DebugDirectoryEntryRva - SectionHeader.VirtualAddress + SectionHeader.PointerToRawData;
-          break;
-        }
-
-        SectionHeaderOffset += sizeof (EFI_IMAGE_SECTION_HEADER);
-      }
-
-      if (DebugDirectoryEntryFileOffset != 0) {
-        for (Index = 0; Index < DebugDirectoryEntry->Size; Index += sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY)) {
-          //
-          // Read next debug directory entry
-          //
-          Size = sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY);
-          Status = ImageContext->ImageRead (
-                                   ImageContext->Handle,
-                                   DebugDirectoryEntryFileOffset + Index,
-                                   &Size,
-                                   &DebugEntry
-                                   );
-          if (RETURN_ERROR (Status)) {
-            ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;
-            return Status;
-          }
-
-          if (DebugEntry.Type == EFI_IMAGE_DEBUG_TYPE_CODEVIEW) {
-            ImageContext->DebugDirectoryEntryRva = (UINT32) (DebugDirectoryEntryRva + Index);
-            if (DebugEntry.RVA == 0 && DebugEntry.FileOffset != 0) {
-              ImageContext->ImageSize += DebugEntry.SizeOfData;
-            }
-
-            return RETURN_SUCCESS;
-          }
-        }
-      }
-    }
-  } else {
-    ImageContext->ImageSize         = 0;
-    ImageContext->SectionAlignment  = 4096;
-    ImageContext->SizeOfHeaders     = sizeof (EFI_TE_IMAGE_HEADER) + (UINTN) TeHdr->BaseOfCode - (UINTN) TeHdr->StrippedSize;
-
-    DebugDirectoryEntry             = &TeHdr->DataDirectory[1];
-    DebugDirectoryEntryRva          = DebugDirectoryEntry->VirtualAddress;
-    SectionHeaderOffset             = (UINTN) (sizeof (EFI_TE_IMAGE_HEADER));
-
-    DebugDirectoryEntryFileOffset   = 0;
-
-    for (Index = 0; Index < TeHdr->NumberOfSections;) {
-      //
-      // Read section header from file
-      //
-      Size = sizeof (EFI_IMAGE_SECTION_HEADER);
-      Status = ImageContext->ImageRead (
-                               ImageContext->Handle,
-                               SectionHeaderOffset,
-                               &Size,
-                               &SectionHeader
-                               );
-      if (RETURN_ERROR (Status)) {
-        ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;
-        return Status;
-      }
-
-      if (DebugDirectoryEntryRva >= SectionHeader.VirtualAddress &&
-          DebugDirectoryEntryRva < SectionHeader.VirtualAddress + SectionHeader.Misc.VirtualSize) {
-        DebugDirectoryEntryFileOffset = DebugDirectoryEntryRva -
-          SectionHeader.VirtualAddress +
-          SectionHeader.PointerToRawData +
-          sizeof (EFI_TE_IMAGE_HEADER) -
-          TeHdr->StrippedSize;
-
-        //
-        // File offset of the debug directory was found, if this is not the last
-        // section, then skip to the last section for calculating the image size.
-        //
-        if (Index < (UINTN) TeHdr->NumberOfSections - 1) {
-          SectionHeaderOffset += (TeHdr->NumberOfSections - 1 - Index) * sizeof (EFI_IMAGE_SECTION_HEADER);
-          Index = TeHdr->NumberOfSections - 1;
-          continue;
-        }
-      }
-
-      //
-      // In Te image header there is not a field to describe the ImageSize.
-      // Actually, the ImageSize equals the RVA plus the VirtualSize of
-      // the last section mapped into memory (Must be rounded up to
-      // a multiple of Section Alignment). Per the PE/COFF specification, the
-      // section headers in the Section Table must appear in order of the RVA
-      // values for the corresponding sections. So the ImageSize can be determined
-      // by the RVA and the VirtualSize of the last section header in the
-      // Section Table.
-      //
-      if ((++Index) == (UINTN) TeHdr->NumberOfSections) {
-        ImageContext->ImageSize = (SectionHeader.VirtualAddress + SectionHeader.Misc.VirtualSize +
-                                   ImageContext->SectionAlignment - 1) & ~(ImageContext->SectionAlignment - 1);
-      }
-
-      SectionHeaderOffset += sizeof (EFI_IMAGE_SECTION_HEADER);
-    }
-
-    if (DebugDirectoryEntryFileOffset != 0) {
-      for (Index = 0; Index < DebugDirectoryEntry->Size; Index += sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY)) {
-        //
-        // Read next debug directory entry
-        //
-        Size = sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY);
-        Status = ImageContext->ImageRead (
-                                 ImageContext->Handle,
-                                 DebugDirectoryEntryFileOffset,
-                                 &Size,
-                                 &DebugEntry
-                                 );
-        if (RETURN_ERROR (Status)) {
-          ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;
-          return Status;
-        }
-
-        if (DebugEntry.Type == EFI_IMAGE_DEBUG_TYPE_CODEVIEW) {
-          ImageContext->DebugDirectoryEntryRva = (UINT32) (DebugDirectoryEntryRva + Index);
-          return RETURN_SUCCESS;
-        }
-      }
-    }
-  }
-
-  return RETURN_SUCCESS;
-}
-
-/**
-  Converts an image address to the loaded address
-
-  @param ImageContext  The context of the image being loaded
-  @param Address       The address to be converted to the loaded address
-
-  @return NULL if the address can not be converted, otherwise, the converted address
-
---*/
-STATIC
-VOID *
-PeCoffLoaderImageAddress (
-  IN OUT PE_COFF_LOADER_IMAGE_CONTEXT          *ImageContext,
-  IN     UINTN                                 Address
-  )
-{
-  if (Address >= ImageContext->ImageSize) {
-    ImageContext->ImageError = IMAGE_ERROR_INVALID_IMAGE_ADDRESS;
-    return NULL;
-  }
-
-  return (UINT8 *) ((UINTN) ImageContext->ImageAddress + Address);
-}
-
-/**
-  Relocates a PE/COFF image in memory
-
-  @param This         Calling context
-  @param ImageContext Contains information on the loaded image to relocate
-
-  @retval RETURN_SUCCESS      if the PE/COFF image was relocated
-  @retval RETURN_LOAD_ERROR   if the image is not a valid PE/COFF image
-  @retval RETURN_UNSUPPORTED  not support
-
-**/
-RETURN_STATUS
-EFIAPI
-PeCoffLoaderRelocateImage (
-  IN OUT PE_COFF_LOADER_IMAGE_CONTEXT  *ImageContext
-  )
-{
-  RETURN_STATUS                         Status;
-  EFI_IMAGE_OPTIONAL_HEADER_UNION       *PeHdr;
-  EFI_TE_IMAGE_HEADER                   *TeHdr;
-  EFI_IMAGE_DATA_DIRECTORY              *RelocDir;
-  UINT64                                Adjust;
-  EFI_IMAGE_BASE_RELOCATION             *RelocBase;
-  EFI_IMAGE_BASE_RELOCATION             *RelocBaseEnd;
-  UINT16                                *Reloc;
-  UINT16                                *RelocEnd;
-  CHAR8                                 *Fixup;
-  CHAR8                                 *FixupBase;
-  UINT16                                *F16;
-  UINT32                                *F32;
-  UINT64                                *F64;
-  CHAR8                                 *FixupData;
-  PHYSICAL_ADDRESS                      BaseAddress;
-  UINT16                                MachineType;
-  EFI_IMAGE_OPTIONAL_HEADER_POINTER     OptionHeader;
-
-  PeHdr = NULL;
-  TeHdr = NULL;
-  //
-  // Assume success
-  //
-  ImageContext->ImageError = IMAGE_ERROR_SUCCESS;
-
-  //
-  // If there are no relocation entries, then we are done
-  //
-  if (ImageContext->RelocationsStripped) {
-    return RETURN_SUCCESS;
-  }
-
-  //
-  // Use DestinationAddress field of ImageContext as the relocation address even if it is 0.
-  //
-  BaseAddress = ImageContext->DestinationAddress;
-
-  if (!(ImageContext->IsTeImage)) {
-    PeHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)((UINTN)ImageContext->ImageAddress +
-                                            ImageContext->PeCoffHeaderOffset);
-    OptionHeader.Header = (VOID *) &(PeHdr->Pe32.OptionalHeader);
-    if (PeHdr->Pe32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
-      Adjust = (UINT64) BaseAddress - OptionHeader.Optional32->ImageBase;
-      OptionHeader.Optional32->ImageBase = (UINT32) BaseAddress;
-      MachineType = ImageContext->Machine;
-      //
-      // Find the relocation block
-      //
-      // Per the PE/COFF spec, you can't assume that a given data directory
-      // is present in the image. You have to check the NumberOfRvaAndSizes in
-      // the optional header to verify a desired directory entry is there.
-      //
-      if (OptionHeader.Optional32->NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC) {
-        RelocDir  = &OptionHeader.Optional32->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC];
-        if ((RelocDir != NULL) && (RelocDir->Size > 0)) {
-          RelocBase = PeCoffLoaderImageAddress (ImageContext, RelocDir->VirtualAddress);
-          RelocBaseEnd = PeCoffLoaderImageAddress (
-                           ImageContext,
-                           RelocDir->VirtualAddress + RelocDir->Size - 1
-                           );
-          if (RelocBase == NULL || RelocBaseEnd == NULL || RelocBaseEnd < RelocBase) {
-            ImageContext->ImageError = IMAGE_ERROR_FAILED_RELOCATION;
-            return RETURN_LOAD_ERROR;
-          }
-        } else {
-          //
-          // Set base and end to bypass processing below.
-          //
-          RelocBase = RelocBaseEnd = 0;
-        }
-      } else {
-        //
-        // Set base and end to bypass processing below.
-        //
-        RelocBase = RelocBaseEnd = 0;
-      }
-    } else {
-      Adjust = (UINT64) BaseAddress - OptionHeader.Optional64->ImageBase;
-      OptionHeader.Optional64->ImageBase = BaseAddress;
-      MachineType = ImageContext->Machine;
-      //
-      // Find the relocation block
-      //
-      // Per the PE/COFF spec, you can't assume that a given data directory
-      // is present in the image. You have to check the NumberOfRvaAndSizes in
-      // the optional header to verify a desired directory entry is there.
-      //
-      if (OptionHeader.Optional64->NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC) {
-        RelocDir  = &OptionHeader.Optional64->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC];
-        if ((RelocDir != NULL) && (RelocDir->Size > 0)) {
-          RelocBase = PeCoffLoaderImageAddress (ImageContext, RelocDir->VirtualAddress);
-          RelocBaseEnd = PeCoffLoaderImageAddress (
-                           ImageContext,
-                           RelocDir->VirtualAddress + RelocDir->Size - 1
-                          );
-          if (RelocBase == NULL || RelocBaseEnd == NULL || RelocBaseEnd < RelocBase) {
-            ImageContext->ImageError = IMAGE_ERROR_FAILED_RELOCATION;
-            return RETURN_LOAD_ERROR;
-          }
-        } else {
-          //
-          // Set base and end to bypass processing below.
-          //
-          RelocBase = RelocBaseEnd = 0;
-        }
-      } else {
-        //
-        // Set base and end to bypass processing below.
-        //
-        RelocBase = RelocBaseEnd = 0;
-      }
-    }
-  } else {
-    TeHdr             = (EFI_TE_IMAGE_HEADER *) (UINTN) (ImageContext->ImageAddress);
-    Adjust            = (UINT64) (BaseAddress - TeHdr->ImageBase);
-    TeHdr->ImageBase  = (UINT64) (BaseAddress);
-    MachineType = TeHdr->Machine;
-
-    //
-    // Find the relocation block
-    //
-    RelocDir = &TeHdr->DataDirectory[0];
-    RelocBase = (EFI_IMAGE_BASE_RELOCATION *)(UINTN)(
-                                    ImageContext->ImageAddress +
-                                    RelocDir->VirtualAddress +
-                                    sizeof(EFI_TE_IMAGE_HEADER) -
-                                    TeHdr->StrippedSize
-                                    );
-    RelocBaseEnd = (EFI_IMAGE_BASE_RELOCATION *) ((UINTN) RelocBase + (UINTN) RelocDir->Size - 1);
-  }
-
-  //
-  // Run the relocation information and apply the fixups
-  //
-  FixupData = ImageContext->FixupData;
-  while (RelocBase < RelocBaseEnd) {
-
-    Reloc     = (UINT16 *) ((CHAR8 *) RelocBase + sizeof (EFI_IMAGE_BASE_RELOCATION));
-    RelocEnd  = (UINT16 *) ((CHAR8 *) RelocBase + RelocBase->SizeOfBlock);
-    if (!(ImageContext->IsTeImage)) {
-      FixupBase = PeCoffLoaderImageAddress (ImageContext, RelocBase->VirtualAddress);
-      if (FixupBase == NULL) {
-        ImageContext->ImageError = IMAGE_ERROR_FAILED_RELOCATION;
-        return RETURN_LOAD_ERROR;
-      }
-    } else {
-      FixupBase = (CHAR8 *)(UINTN)(ImageContext->ImageAddress +
-                    RelocBase->VirtualAddress +
-                    sizeof(EFI_TE_IMAGE_HEADER) -
-                    TeHdr->StrippedSize
-                    );
-    }
-
-    if ((CHAR8 *) RelocEnd < (CHAR8 *) ((UINTN) ImageContext->ImageAddress) ||
-        (CHAR8 *) RelocEnd > (CHAR8 *)((UINTN)ImageContext->ImageAddress +
-          (UINTN)ImageContext->ImageSize)) {
-      ImageContext->ImageError = IMAGE_ERROR_FAILED_RELOCATION;
-      return RETURN_LOAD_ERROR;
-    }
-
-    //
-    // Run this relocation record
-    //
-    while (Reloc < RelocEnd) {
-
-      Fixup = FixupBase + (*Reloc & 0xFFF);
-      switch ((*Reloc) >> 12) {
-      case EFI_IMAGE_REL_BASED_ABSOLUTE:
-        break;
-
-      case EFI_IMAGE_REL_BASED_HIGH:
-        F16   = (UINT16 *) Fixup;
-        *F16 = (UINT16) (*F16 + ((UINT16) ((UINT32) Adjust >> 16)));
-        if (FixupData != NULL) {
-          *(UINT16 *) FixupData = *F16;
-          FixupData             = FixupData + sizeof (UINT16);
-        }
-        break;
-
-      case EFI_IMAGE_REL_BASED_LOW:
-        F16   = (UINT16 *) Fixup;
-        *F16  = (UINT16) (*F16 + (UINT16) Adjust);
-        if (FixupData != NULL) {
-          *(UINT16 *) FixupData = *F16;
-          FixupData             = FixupData + sizeof (UINT16);
-        }
-        break;
-
-      case EFI_IMAGE_REL_BASED_HIGHLOW:
-        F32   = (UINT32 *) Fixup;
-        *F32  = *F32 + (UINT32) Adjust;
-        if (FixupData != NULL) {
-          FixupData             = ALIGN_POINTER (FixupData, sizeof (UINT32));
-          *(UINT32 *) FixupData = *F32;
-          FixupData             = FixupData + sizeof (UINT32);
-        }
-        break;
-
-      case EFI_IMAGE_REL_BASED_DIR64:
-        F64   = (UINT64 *) Fixup;
-        *F64  = *F64 + (UINT64) Adjust;
-        if (FixupData != NULL) {
-          FixupData             = ALIGN_POINTER (FixupData, sizeof (UINT64));
-          *(UINT64 *) FixupData = *F64;
-          FixupData             = FixupData + sizeof (UINT64);
-        }
-        break;
-
-      case EFI_IMAGE_REL_BASED_HIGHADJ:
-        //
-        // Return the same EFI_UNSUPPORTED return code as
-        // PeCoffLoaderRelocateImageEx() returns if it does not recognize
-        // the relocation type.
-        //
-        ImageContext->ImageError = IMAGE_ERROR_FAILED_RELOCATION;
-        return RETURN_UNSUPPORTED;
-
-      default:
-        switch (MachineType) {
-        case IMAGE_FILE_MACHINE_I386:
-          Status = PeCoffLoaderRelocateIa32Image (Reloc, Fixup, &FixupData, Adjust);
-          break;
-        case IMAGE_FILE_MACHINE_ARMTHUMB_MIXED:
-          Status = PeCoffLoaderRelocateArmImage (&Reloc, Fixup, &FixupData, Adjust);
-          break;
-        case IMAGE_FILE_MACHINE_RISCV64:
-          Status = PeCoffLoaderRelocateRiscVImage (Reloc, Fixup, &FixupData, Adjust);
-          break;
-        case IMAGE_FILE_MACHINE_LOONGARCH64:
-          Status = PeCoffLoaderRelocateLoongArch64Image (Reloc, Fixup, &FixupData, Adjust);
-          break;
-        default:
-          Status = RETURN_UNSUPPORTED;
-          break;
-        }
-        if (RETURN_ERROR (Status)) {
-          ImageContext->ImageError = IMAGE_ERROR_FAILED_RELOCATION;
-          return Status;
-        }
-      }
-
-      //
-      // Next relocation record
-      //
-      Reloc += 1;
-    }
-
-    //
-    // Next reloc block
-    //
-    RelocBase = (EFI_IMAGE_BASE_RELOCATION *) RelocEnd;
-  }
-
-  return RETURN_SUCCESS;
-}
-
-/**
-  Loads a PE/COFF image into memory
-
-  @param This         Calling context
-  @param ImageContext Contains information on image to load into memory
-
-  @retval RETURN_SUCCESS            if the PE/COFF image was loaded
-  @retval RETURN_BUFFER_TOO_SMALL   if the caller did not provide a large enough buffer
-  @retval RETURN_LOAD_ERROR         if the image is a runtime driver with no relocations
-  @retval RETURN_INVALID_PARAMETER  if the image address is invalid
-
-**/
-RETURN_STATUS
-EFIAPI
-PeCoffLoaderLoadImage (
-  IN OUT PE_COFF_LOADER_IMAGE_CONTEXT  *ImageContext
-  )
-{
-  RETURN_STATUS                         Status;
-  EFI_IMAGE_OPTIONAL_HEADER_UNION       *PeHdr;
-  EFI_TE_IMAGE_HEADER                   *TeHdr;
-  PE_COFF_LOADER_IMAGE_CONTEXT          CheckContext;
-  EFI_IMAGE_SECTION_HEADER              *FirstSection;
-  EFI_IMAGE_SECTION_HEADER              *Section;
-  UINTN                                 NumberOfSections;
-  UINTN                                 Index;
-  CHAR8                                 *Base;
-  CHAR8                                 *End;
-  CHAR8                                 *MaxEnd;
-  EFI_IMAGE_DATA_DIRECTORY              *DirectoryEntry;
-  EFI_IMAGE_DEBUG_DIRECTORY_ENTRY       *DebugEntry;
-  UINTN                                 Size;
-  UINT32                                TempDebugEntryRva;
-  EFI_IMAGE_OPTIONAL_HEADER_POINTER     OptionHeader;
-
-  PeHdr = NULL;
-  TeHdr = NULL;
-  OptionHeader.Header = NULL;
-  //
-  // Assume success
-  //
-  ImageContext->ImageError = IMAGE_ERROR_SUCCESS;
-
-  //
-  // Copy the provided context info into our local version, get what we
-  // can from the original image, and then use that to make sure everything
-  // is legit.
-  //
-  CopyMem (&CheckContext, ImageContext, sizeof (PE_COFF_LOADER_IMAGE_CONTEXT));
-
-  Status = PeCoffLoaderGetImageInfo (&CheckContext);
-  if (RETURN_ERROR (Status)) {
-    return Status;
-  }
-
-  //
-  // Make sure there is enough allocated space for the image being loaded
-  //
-  if (ImageContext->ImageSize < CheckContext.ImageSize) {
-    ImageContext->ImageError = IMAGE_ERROR_INVALID_IMAGE_SIZE;
-    return RETURN_BUFFER_TOO_SMALL;
-  }
-
-  //
-  // If there's no relocations, then make sure it's not a runtime driver,
-  // and that it's being loaded at the linked address.
-  //
-  if (CheckContext.RelocationsStripped) {
-    //
-    // If the image does not contain relocations and it is a runtime driver
-    // then return an error.
-    //
-    if (CheckContext.ImageType == EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER) {
-      ImageContext->ImageError = IMAGE_ERROR_INVALID_SUBSYSTEM;
-      return RETURN_LOAD_ERROR;
-    }
-    //
-    // If the image does not contain relocations, and the requested load address
-    // is not the linked address, then return an error.
-    //
-    if (CheckContext.ImageAddress != ImageContext->ImageAddress) {
-      ImageContext->ImageError = IMAGE_ERROR_INVALID_IMAGE_ADDRESS;
-      return RETURN_INVALID_PARAMETER;
-    }
-  }
-  //
-  // Make sure the allocated space has the proper section alignment
-  //
-  if (!(ImageContext->IsTeImage)) {
-    if ((ImageContext->ImageAddress & (CheckContext.SectionAlignment - 1)) != 0) {
-      ImageContext->ImageError = IMAGE_ERROR_INVALID_SECTION_ALIGNMENT;
-      return RETURN_INVALID_PARAMETER;
-    }
-  }
-  //
-  // Read the entire PE/COFF or TE header into memory
-  //
-  if (!(ImageContext->IsTeImage)) {
-    Status = ImageContext->ImageRead (
-                            ImageContext->Handle,
-                            0,
-                            &ImageContext->SizeOfHeaders,
-                            (VOID *) (UINTN) ImageContext->ImageAddress
-                            );
-
-    PeHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)
-      ((UINTN)ImageContext->ImageAddress + ImageContext->PeCoffHeaderOffset);
-
-    OptionHeader.Header = (VOID *) &(PeHdr->Pe32.OptionalHeader);
-
-    FirstSection = (EFI_IMAGE_SECTION_HEADER *) (
-                      (UINTN)ImageContext->ImageAddress +
-                      ImageContext->PeCoffHeaderOffset +
-                      sizeof(UINT32) +
-                      sizeof(EFI_IMAGE_FILE_HEADER) +
-                      PeHdr->Pe32.FileHeader.SizeOfOptionalHeader
-      );
-    NumberOfSections = (UINTN) (PeHdr->Pe32.FileHeader.NumberOfSections);
-  } else {
-    Status = ImageContext->ImageRead (
-                            ImageContext->Handle,
-                            0,
-                            &ImageContext->SizeOfHeaders,
-                            (VOID *) (UINTN) ImageContext->ImageAddress
-                            );
-
-    TeHdr             = (EFI_TE_IMAGE_HEADER *) (UINTN) (ImageContext->ImageAddress);
-
-    FirstSection = (EFI_IMAGE_SECTION_HEADER *) (
-          (UINTN)ImageContext->ImageAddress +
-          sizeof(EFI_TE_IMAGE_HEADER)
-          );
-    NumberOfSections  = (UINTN) (TeHdr->NumberOfSections);
-
-  }
-
-  if (RETURN_ERROR (Status)) {
-    ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;
-    return RETURN_LOAD_ERROR;
-  }
-
-  //
-  // Load each section of the image
-  //
-  Section = FirstSection;
-  for (Index = 0, MaxEnd = NULL; Index < NumberOfSections; Index++) {
-
-    //
-    // Compute sections address
-    //
-    Base = PeCoffLoaderImageAddress (ImageContext, Section->VirtualAddress);
-    End = PeCoffLoaderImageAddress (
-            ImageContext,
-            Section->VirtualAddress + Section->Misc.VirtualSize - 1
-            );
-
-    //
-    // If the base start or end address resolved to 0, then fail.
-    //
-    if ((Base == NULL) || (End == NULL)) {
-      ImageContext->ImageError = IMAGE_ERROR_SECTION_NOT_LOADED;
-      return RETURN_LOAD_ERROR;
-    }
-
-
-    if (ImageContext->IsTeImage) {
-      Base  = (CHAR8 *) ((UINTN) Base + sizeof (EFI_TE_IMAGE_HEADER) - (UINTN) TeHdr->StrippedSize);
-      End   = (CHAR8 *) ((UINTN) End + sizeof (EFI_TE_IMAGE_HEADER) - (UINTN) TeHdr->StrippedSize);
-    }
-
-    if (End > MaxEnd) {
-      MaxEnd = End;
-    }
-
-    //
-    // Read the section
-    //
-    Size = (UINTN) Section->Misc.VirtualSize;
-    if ((Size == 0) || (Size > Section->SizeOfRawData)) {
-      Size = (UINTN) Section->SizeOfRawData;
-    }
-
-    if (Section->SizeOfRawData) {
-      if (!(ImageContext->IsTeImage)) {
-        Status = ImageContext->ImageRead (
-                                ImageContext->Handle,
-                                Section->PointerToRawData,
-                                &Size,
-                                Base
-                                );
-      } else {
-        Status = ImageContext->ImageRead (
-                                ImageContext->Handle,
-                                Section->PointerToRawData + sizeof (EFI_TE_IMAGE_HEADER) - (UINTN) TeHdr->StrippedSize,
-                                &Size,
-                                Base
-                                );
-      }
-
-      if (RETURN_ERROR (Status)) {
-        ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;
-        return Status;
-      }
-    }
-
-    //
-    // If raw size is less then virt size, zero fill the remaining
-    //
-
-    if (Size < Section->Misc.VirtualSize) {
-      ZeroMem (Base + Size, Section->Misc.VirtualSize - Size);
-    }
-
-    //
-    // Next Section
-    //
-    Section += 1;
-  }
-
-  //
-  // Get image's entry point
-  //
-  if (!(ImageContext->IsTeImage)) {
-    ImageContext->EntryPoint = (PHYSICAL_ADDRESS) (UINTN) PeCoffLoaderImageAddress (
-                                                                ImageContext,
-                                                                PeHdr->Pe32.OptionalHeader.AddressOfEntryPoint
-                                                                );
-  } else {
-    ImageContext->EntryPoint = (UINTN)ImageContext->ImageAddress +
-                               (UINTN)TeHdr->AddressOfEntryPoint +
-                               (UINTN)sizeof(EFI_TE_IMAGE_HEADER) -
-                               (UINTN) TeHdr->StrippedSize;
-  }
-
-  //
-  // Determine the size of the fixup data
-  //
-  // Per the PE/COFF spec, you can't assume that a given data directory
-  // is present in the image. You have to check the NumberOfRvaAndSizes in
-  // the optional header to verify a desired directory entry is there.
-  //
-  if (!(ImageContext->IsTeImage)) {
-    if (PeHdr->Pe32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
-      if (OptionHeader.Optional32->NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC) {
-        DirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *)
-          &OptionHeader.Optional32->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC];
-        ImageContext->FixupDataSize = DirectoryEntry->Size / sizeof (UINT16) * sizeof (UINTN);
-      } else {
-        ImageContext->FixupDataSize = 0;
-      }
-    } else {
-      if (OptionHeader.Optional64->NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC) {
-        DirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *)
-          &OptionHeader.Optional64->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC];
-        ImageContext->FixupDataSize = DirectoryEntry->Size / sizeof (UINT16) * sizeof (UINTN);
-      } else {
-        ImageContext->FixupDataSize = 0;
-      }
-    }
-  } else {
-    DirectoryEntry              = &TeHdr->DataDirectory[0];
-    ImageContext->FixupDataSize = DirectoryEntry->Size / sizeof (UINT16) * sizeof (UINTN);
-  }
-  //
-  // Consumer must allocate a buffer for the relocation fixup log.
-  // Only used for runtime drivers.
-  //
-  ImageContext->FixupData = NULL;
-
-  //
-  // Load the Codeview info if present
-  //
-  if (ImageContext->DebugDirectoryEntryRva != 0) {
-    if (!(ImageContext->IsTeImage)) {
-      DebugEntry = PeCoffLoaderImageAddress (
-                    ImageContext,
-                    ImageContext->DebugDirectoryEntryRva
-                    );
-    } else {
-      DebugEntry = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *)(UINTN)(
-                                               ImageContext->ImageAddress +
-                                               ImageContext->DebugDirectoryEntryRva +
-                                               sizeof(EFI_TE_IMAGE_HEADER) -
-                                               TeHdr->StrippedSize
-                                               );
-    }
-
-    if (DebugEntry != NULL) {
-      TempDebugEntryRva = DebugEntry->RVA;
-      if (DebugEntry->RVA == 0 && DebugEntry->FileOffset != 0) {
-        Section--;
-        if ((UINTN) Section->SizeOfRawData < Section->Misc.VirtualSize) {
-          TempDebugEntryRva = Section->VirtualAddress + Section->Misc.VirtualSize;
-        } else {
-          TempDebugEntryRva = Section->VirtualAddress + Section->SizeOfRawData;
-        }
-      }
-
-      if (TempDebugEntryRva != 0) {
-        if (!(ImageContext->IsTeImage)) {
-          ImageContext->CodeView = PeCoffLoaderImageAddress (ImageContext, TempDebugEntryRva);
-        } else {
-          ImageContext->CodeView = (VOID *)(
-                      (UINTN)ImageContext->ImageAddress +
-                      (UINTN)TempDebugEntryRva +
-                      (UINTN)sizeof(EFI_TE_IMAGE_HEADER) -
-                (UINTN) TeHdr->StrippedSize
-            );
-        }
-
-        if (ImageContext->CodeView == NULL) {
-          ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;
-          return RETURN_LOAD_ERROR;
-        }
-
-        if (DebugEntry->RVA == 0) {
-          Size = DebugEntry->SizeOfData;
-          if (!(ImageContext->IsTeImage)) {
-            Status = ImageContext->ImageRead (
-                                    ImageContext->Handle,
-                                    DebugEntry->FileOffset,
-                                    &Size,
-                                    ImageContext->CodeView
-                                    );
-          } else {
-            Status = ImageContext->ImageRead (
-                                    ImageContext->Handle,
-                                    DebugEntry->FileOffset + sizeof (EFI_TE_IMAGE_HEADER) - TeHdr->StrippedSize,
-                                    &Size,
-                                    ImageContext->CodeView
-                                    );
-            //
-            // Should we apply fix up to this field according to the size difference between PE and TE?
-            // Because now we maintain TE header fields unfixed, this field will also remain as they are
-            // in original PE image.
-            //
-          }
-
-          if (RETURN_ERROR (Status)) {
-            ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;
-            return RETURN_LOAD_ERROR;
-          }
-
-          DebugEntry->RVA = TempDebugEntryRva;
-        }
-
-        switch (*(UINT32 *) ImageContext->CodeView) {
-        case CODEVIEW_SIGNATURE_NB10:
-          ImageContext->PdbPointer = (CHAR8 *) ImageContext->CodeView + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY);
-          break;
-
-        case CODEVIEW_SIGNATURE_RSDS:
-          ImageContext->PdbPointer = (CHAR8 *) ImageContext->CodeView + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_RSDS_ENTRY);
-          break;
-
-        case CODEVIEW_SIGNATURE_MTOC:
-          ImageContext->PdbPointer = (CHAR8 *) ImageContext->CodeView + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_MTOC_ENTRY);
-
-        default:
-          break;
-        }
-      }
-    }
-  }
-
-  return Status;
-}
-
-/**
-  Returns a pointer to the PDB file name for a raw PE/COFF image that is not
-  loaded into system memory with the PE/COFF Loader Library functions.
-
-  Returns the PDB file name for the PE/COFF image specified by Pe32Data.  If
-  the PE/COFF image specified by Pe32Data is not a valid, then NULL is
-  returned.  If the PE/COFF image specified by Pe32Data does not contain a
-  debug directory entry, then NULL is returned.  If the debug directory entry
-  in the PE/COFF image specified by Pe32Data does not contain a PDB file name,
-  then NULL is returned.
-  If Pe32Data is NULL, then return NULL.
-
-  @param  Pe32Data   Pointer to the PE/COFF image that is loaded in system
-                     memory.
-
-  @return The PDB file name for the PE/COFF image specified by Pe32Data or NULL
-          if it cannot be retrieved.
-
-**/
-VOID *
-EFIAPI
-PeCoffLoaderGetPdbPointer (
-  IN VOID  *Pe32Data
-  )
-{
-  EFI_IMAGE_DOS_HEADER                  *DosHdr;
-  EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION   Hdr;
-  EFI_IMAGE_DATA_DIRECTORY              *DirectoryEntry;
-  EFI_IMAGE_DEBUG_DIRECTORY_ENTRY       *DebugEntry;
-  UINTN                                 DirCount;
-  VOID                                  *CodeViewEntryPointer;
-  INTN                                  TEImageAdjust;
-  UINT32                                NumberOfRvaAndSizes;
-  UINT16                                Magic;
-  EFI_IMAGE_SECTION_HEADER              *SectionHeader;
-  UINT32                                Index, Index1;
-
-  if (Pe32Data == NULL) {
-    return NULL;
-  }
-
-  TEImageAdjust       = 0;
-  DirectoryEntry      = NULL;
-  DebugEntry          = NULL;
-  NumberOfRvaAndSizes = 0;
-  Index               = 0;
-  Index1              = 0;
-  SectionHeader       = NULL;
-
-  DosHdr = (EFI_IMAGE_DOS_HEADER *)Pe32Data;
-  if (EFI_IMAGE_DOS_SIGNATURE == DosHdr->e_magic) {
-    //
-    // DOS image header is present, so read the PE header after the DOS image header.
-    //
-    Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)((UINTN) Pe32Data + (UINTN) ((DosHdr->e_lfanew) & 0x0ffff));
-  } else {
-    //
-    // DOS image header is not present, so PE header is at the image base.
-    //
-    Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)Pe32Data;
-  }
-
-  if (EFI_TE_IMAGE_HEADER_SIGNATURE == Hdr.Te->Signature) {
-    if (Hdr.Te->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress != 0) {
-      DirectoryEntry  = &Hdr.Te->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG];
-      TEImageAdjust   = sizeof (EFI_TE_IMAGE_HEADER) - Hdr.Te->StrippedSize;
-
-      //
-      // Get the DebugEntry offset in the raw data image.
-      //
-      SectionHeader = (EFI_IMAGE_SECTION_HEADER *) (Hdr.Te + 1);
-      Index = Hdr.Te->NumberOfSections;
-      for (Index1 = 0; Index1 < Index; Index1 ++) {
-        if ((DirectoryEntry->VirtualAddress >= SectionHeader[Index1].VirtualAddress) &&
-           (DirectoryEntry->VirtualAddress < (SectionHeader[Index1].VirtualAddress + SectionHeader[Index1].Misc.VirtualSize))) {
-          DebugEntry = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *)((UINTN) Hdr.Te +
-                        DirectoryEntry->VirtualAddress -
-                        SectionHeader [Index1].VirtualAddress +
-                        SectionHeader [Index1].PointerToRawData +
-                        TEImageAdjust);
-          break;
-        }
-      }
-    }
-  } else if (EFI_IMAGE_NT_SIGNATURE == Hdr.Pe32->Signature) {
-    //
-    // NOTE: We use Machine field to identify PE32/PE32+, instead of Magic.
-    //       It is due to backward-compatibility, for some system might
-    //       generate PE32+ image with PE32 Magic.
-    //
-    switch (Hdr.Pe32->FileHeader.Machine) {
-    case IMAGE_FILE_MACHINE_I386:
-    case IMAGE_FILE_MACHINE_ARMTHUMB_MIXED:
-      //
-      // Assume PE32 image with IA32 Machine field.
-      //
-      Magic = EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC;
-      break;
-    case IMAGE_FILE_MACHINE_X64:
-      //
-      // Assume PE32+ image with X64 Machine field
-      //
-      Magic = EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC;
-      break;
-    default:
-      //
-      // For unknown Machine field, use Magic in optional Header
-      //
-      Magic = Hdr.Pe32->OptionalHeader.Magic;
-    }
-
-    SectionHeader = (EFI_IMAGE_SECTION_HEADER *) (
-                       (UINT8 *) Hdr.Pe32 +
-                       sizeof (UINT32) +
-                       sizeof (EFI_IMAGE_FILE_HEADER) +
-                       Hdr.Pe32->FileHeader.SizeOfOptionalHeader
-                       );
-    Index = Hdr.Pe32->FileHeader.NumberOfSections;
-
-    if (EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC == Magic) {
-      //
-      // Use PE32 offset get Debug Directory Entry
-      //
-      NumberOfRvaAndSizes = Hdr.Pe32->OptionalHeader.NumberOfRvaAndSizes;
-      DirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *)&(Hdr.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG]);
-    } else if (Hdr.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) {
-      //
-      // Use PE32+ offset get Debug Directory Entry
-      //
-      NumberOfRvaAndSizes = Hdr.Pe32Plus->OptionalHeader.NumberOfRvaAndSizes;
-      DirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *)&(Hdr.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG]);
-    }
-
-    if (NumberOfRvaAndSizes <= EFI_IMAGE_DIRECTORY_ENTRY_DEBUG || DirectoryEntry->VirtualAddress == 0) {
-      DirectoryEntry = NULL;
-      DebugEntry = NULL;
-    } else {
-      //
-      // Get the DebugEntry offset in the raw data image.
-      //
-      for (Index1 = 0; Index1 < Index; Index1 ++) {
-        if ((DirectoryEntry->VirtualAddress >= SectionHeader[Index1].VirtualAddress) &&
-           (DirectoryEntry->VirtualAddress < (SectionHeader[Index1].VirtualAddress + SectionHeader[Index1].Misc.VirtualSize))) {
-          DebugEntry = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *) (
-                       (UINTN) Pe32Data +
-                       DirectoryEntry->VirtualAddress -
-                       SectionHeader[Index1].VirtualAddress +
-                       SectionHeader[Index1].PointerToRawData);
-          break;
-        }
-      }
-    }
-  } else {
-    return NULL;
-  }
-
-  if (NULL == DebugEntry || NULL == DirectoryEntry) {
-    return NULL;
-  }
-
-  //
-  // Scan the directory to find the debug entry.
-  //
-  for (DirCount = 0; DirCount < DirectoryEntry->Size; DirCount += sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY), DebugEntry++) {
-    if (EFI_IMAGE_DEBUG_TYPE_CODEVIEW == DebugEntry->Type) {
-      if (DebugEntry->SizeOfData > 0) {
-        //
-        // Get the DebugEntry offset in the raw data image.
-        //
-        CodeViewEntryPointer = NULL;
-        for (Index1 = 0; Index1 < Index; Index1 ++) {
-          if ((DebugEntry->RVA >= SectionHeader[Index1].VirtualAddress) &&
-             (DebugEntry->RVA < (SectionHeader[Index1].VirtualAddress + SectionHeader[Index1].Misc.VirtualSize))) {
-            CodeViewEntryPointer = (VOID *) (
-                                   ((UINTN)Pe32Data) +
-                                   (UINTN) DebugEntry->RVA -
-                                   SectionHeader[Index1].VirtualAddress +
-                                   SectionHeader[Index1].PointerToRawData +
-                                   (UINTN)TEImageAdjust);
-            break;
-          }
-        }
-        if (Index1 >= Index) {
-          //
-          // Can't find CodeViewEntryPointer in raw PE/COFF image.
-          //
-          continue;
-        }
-        switch (* (UINT32 *) CodeViewEntryPointer) {
-        case CODEVIEW_SIGNATURE_NB10:
-          return (VOID *) ((CHAR8 *)CodeViewEntryPointer + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY));
-        case CODEVIEW_SIGNATURE_RSDS:
-          return (VOID *) ((CHAR8 *)CodeViewEntryPointer + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_RSDS_ENTRY));
-        case CODEVIEW_SIGNATURE_MTOC:
-          return (VOID *) ((CHAR8 *)CodeViewEntryPointer + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_MTOC_ENTRY));
-        default:
-          break;
-        }
-      }
-    }
-  }
-
-  return NULL;
-}
-
-
-RETURN_STATUS
-EFIAPI
-PeCoffLoaderGetEntryPoint (
-  IN  VOID  *Pe32Data,
-  OUT VOID  **EntryPoint,
-  OUT VOID  **BaseOfImage
-  )
-{
-  EFI_IMAGE_DOS_HEADER                  *DosHdr;
-  EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION   Hdr;
-
-  DosHdr = (EFI_IMAGE_DOS_HEADER *)Pe32Data;
-  if (DosHdr->e_magic == EFI_IMAGE_DOS_SIGNATURE) {
-    //
-    // DOS image header is present, so read the PE header after the DOS image header.
-    //
-    Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)((UINTN) Pe32Data + (UINTN) ((DosHdr->e_lfanew) & 0x0ffff));
-  } else {
-    //
-    // DOS image header is not present, so PE header is at the image base.
-    //
-    Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)Pe32Data;
-  }
-
-  //
-  // Calculate the entry point relative to the start of the image.
-  // AddressOfEntryPoint is common for PE32 & PE32+
-  //
-  if (Hdr.Te->Signature == EFI_TE_IMAGE_HEADER_SIGNATURE) {
-    *BaseOfImage = (VOID *)(UINTN)(Hdr.Te->ImageBase + Hdr.Te->StrippedSize - sizeof (EFI_TE_IMAGE_HEADER));
-    *EntryPoint = (VOID *)((UINTN)*BaseOfImage + (Hdr.Te->AddressOfEntryPoint & 0x0ffffffff) + sizeof(EFI_TE_IMAGE_HEADER) - Hdr.Te->StrippedSize);
-    return RETURN_SUCCESS;
-  } else if (Hdr.Pe32->Signature == EFI_IMAGE_NT_SIGNATURE) {
-    *EntryPoint = (VOID *)(UINTN)Hdr.Pe32->OptionalHeader.AddressOfEntryPoint;
-    if (Hdr.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
-      *BaseOfImage = (VOID *)(UINTN)Hdr.Pe32->OptionalHeader.ImageBase;
-    } else {
-      *BaseOfImage = (VOID *)(UINTN)Hdr.Pe32Plus->OptionalHeader.ImageBase;
-    }
-    *EntryPoint = (VOID *)(UINTN)((UINTN)*EntryPoint + (UINTN)*BaseOfImage);
-    return RETURN_SUCCESS;
-  }
-
-  return RETURN_UNSUPPORTED;
-}
diff --git a/BaseTools/Source/C/Common/CommonLib.c b/BaseTools/Source/C/Common/CommonLib.c
index 80b62897ca..d5f845b568 100644
--- a/BaseTools/Source/C/Common/CommonLib.c
+++ b/BaseTools/Source/C/Common/CommonLib.c
@@ -14,12 +14,17 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
 #include <unistd.h>
 #else
 #include <direct.h>
+#include <io.h>
 #endif
 #include "CommonLib.h"
 #include "EfiUtilityMsgs.h"
+#include "FvLib.h"
+
+#include <Common/PiFirmwareFile.h>
 
 #include <Uefi/UefiSpec.h>
 #include <Library/PhaseMemoryAllocationLib.h>
+#include <Library/UefiImageLib.h>
 
 GLOBAL_REMOVE_IF_UNREFERENCED CONST EFI_MEMORY_TYPE gPhaseDefaultDataType = EfiBootServicesData;
 GLOBAL_REMOVE_IF_UNREFERENCED CONST EFI_MEMORY_TYPE gPhaseDefaultCodeType = EfiBootServicesCode;
@@ -615,3 +620,64 @@ CpuDeadLoop (
 {
   abort ();
 }
+
+EFI_STATUS
+GetAlignmentFromFile (
+  IN  CHAR8   *InFile,
+  OUT UINT32  *Alignment
+  )
+  /*++
+    InFile is input file for getting alignment
+    return the alignment
+    --*/
+{
+  FILE                             *InFileHandle;
+  UINT8                            *ImageFileBuffer;
+  UINTN                            ImageFileSize;
+  UINT32                           CurSecHdrSize;
+  UEFI_IMAGE_LOADER_IMAGE_CONTEXT  ImageContext;
+  EFI_COMMON_SECTION_HEADER        *CommonHeader;
+  EFI_STATUS                       Status;
+
+  InFileHandle    = NULL;
+  ImageFileBuffer = NULL;
+  *Alignment      = 0;
+
+  InFileHandle = fopen(LongFilePath(InFile), "rb");
+  if (InFileHandle == NULL){
+    Error (NULL, 0, 0001, "Error opening file", InFile);
+    return EFI_ABORTED;
+  }
+  ImageFileSize   = _filelength (fileno(InFileHandle));
+  ImageFileBuffer = (UINT8 *) malloc (ImageFileSize);
+  if (ImageFileBuffer == NULL) {
+    fclose (InFileHandle);
+    Error(NULL, 0, 4001, "Resource", "memory cannot be allocated for %s", InFile);
+    return EFI_OUT_OF_RESOURCES;
+  }
+  fread (ImageFileBuffer, sizeof (UINT8), ImageFileSize, InFileHandle);
+  fclose (InFileHandle);
+
+  CommonHeader  = (EFI_COMMON_SECTION_HEADER *) ImageFileBuffer;
+  CurSecHdrSize = GetSectionHeaderLength(CommonHeader);
+
+  Status = UefiImageInitializeContext (
+             &ImageContext,
+             ImageFileBuffer + CurSecHdrSize,
+             ImageFileSize,
+             UEFI_IMAGE_SOURCE_FV
+             );
+  if (EFI_ERROR (Status)) {
+    Error (NULL, 0, 3000, "Invalid UefiImage", "The input file is %s and return status is %x", InFile, (int) Status);
+    return Status;
+   }
+
+  *Alignment = UefiImageGetSegmentAlignment (&ImageContext);
+  // Free the allocated memory resource
+  if (ImageFileBuffer != NULL) {
+    free (ImageFileBuffer);
+    ImageFileBuffer = NULL;
+  }
+
+  return EFI_SUCCESS;
+}
diff --git a/BaseTools/Source/C/Common/CommonLib.h b/BaseTools/Source/C/Common/CommonLib.h
index 6ac64897f1..02bb63e6ba 100644
--- a/BaseTools/Source/C/Common/CommonLib.h
+++ b/BaseTools/Source/C/Common/CommonLib.h
@@ -113,6 +113,12 @@ LongFilePath (
  IN CHAR8 *FileName
 );
 
+EFI_STATUS
+GetAlignmentFromFile (
+  IN  CHAR8   *InFile,
+  OUT UINT32  *Alignment
+  );
+
 /*++
 
 Routine Description:
diff --git a/BaseTools/Source/C/Common/GNUmakefile b/BaseTools/Source/C/Common/GNUmakefile
index c5a49ffe2f..1396c3f578 100644
--- a/BaseTools/Source/C/Common/GNUmakefile
+++ b/BaseTools/Source/C/Common/GNUmakefile
@@ -11,7 +11,6 @@ MAKEROOT ?= ..
 LIBNAME = Common
 
 OBJECTS = \
-  BasePeCoff.o \
   BinderFuncs.o \
   CommonLib.o \
   Crc32.o \
@@ -25,13 +24,26 @@ OBJECTS = \
   OsPath.o \
   ParseGuidedSectionTools.o \
   ParseInf.o \
-  PeCoffLoaderEx.o \
   SimpleFileParsing.o \
   StringFuncs.o \
   TianoCompress.o
 
 OBJECTS += AutoGen.o DebugLib.o
 
+OBJECTS += \
+  $(EDK2_OBJPATH)/BaseTools/ImageTool/ImageToolEmit.o \
+  $(EDK2_OBJPATH)/BaseTools/ImageTool/Image.o \
+  $(EDK2_OBJPATH)/BaseTools/ImageTool/ElfScan32.o \
+  $(EDK2_OBJPATH)/BaseTools/ImageTool/ElfScan64.o \
+  $(EDK2_OBJPATH)/BaseTools/ImageTool/ElfScanCommon.o \
+  $(EDK2_OBJPATH)/BaseTools/ImageTool/UefiImageScan.o \
+  $(EDK2_OBJPATH)/BaseTools/ImageTool/PeScan.o \
+  $(EDK2_OBJPATH)/BaseTools/ImageTool/PeEmit32.o \
+  $(EDK2_OBJPATH)/BaseTools/ImageTool/PeEmit64.o \
+  $(EDK2_OBJPATH)/BaseTools/ImageTool/PeEmitCommon.o \
+  $(EDK2_OBJPATH)/BaseTools/ImageTool/BinEmit.o \
+  $(EDK2_OBJPATH)/OpenCorePkg/User/Library/UserFile.o
+
 OBJECTS += \
   $(EDK2_OBJPATH)/MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.o
 
@@ -92,6 +104,30 @@ OBJECTS += \
   $(EDK2_OBJPATH)/MdePkg/Library/BasePrintLib/PrintLib.o \
   $(EDK2_OBJPATH)/MdePkg/Library/BasePrintLib/PrintLibInternal.o
 
+OBJECTS += \
+  $(EDK2_OBJPATH)/MdePkg/Library/BaseOverflowLib/BaseAlignment.o \
+  $(EDK2_OBJPATH)/MdePkg/Library/BaseOverflowLib/BaseBitOverflow.o \
+  $(EDK2_OBJPATH)/MdePkg/Library/BaseOverflowLib/BaseMath.o \
+  $(EDK2_OBJPATH)/MdePkg/Library/BaseOverflowLib/BaseNativeOverflow.o \
+  $(EDK2_OBJPATH)/MdePkg/Library/BaseOverflowLib/BaseTripleOverflow.o
+
+OBJECTS += \
+  $(EDK2_OBJPATH)/MdePkg/Library/BasePeCoffLib2/PeCoffDebug.o \
+  $(EDK2_OBJPATH)/MdePkg/Library/BasePeCoffLib2/PeCoffHash.o \
+  $(EDK2_OBJPATH)/MdePkg/Library/BasePeCoffLib2/PeCoffHii.o \
+  $(EDK2_OBJPATH)/MdePkg/Library/BasePeCoffLib2/PeCoffInfo.o \
+  $(EDK2_OBJPATH)/MdePkg/Library/BasePeCoffLib2/PeCoffInit.o \
+  $(EDK2_OBJPATH)/MdePkg/Library/BasePeCoffLib2/PeCoffLoad.o \
+  $(EDK2_OBJPATH)/MdePkg/Library/BasePeCoffLib2/PeCoffRelocate.o
+
+OBJECTS += \
+  $(EDK2_OBJPATH)/MdePkg/Library/BaseUefiImageLib/CommonSupport.o \
+  $(EDK2_OBJPATH)/MdePkg/Library/BaseUefiImageLib/PeCoffSupport.o \
+  $(EDK2_OBJPATH)/MdePkg/Library/BaseUefiImageLib/UefiImageLibPeCoff.o
+
+OBJECTS += \
+  $(EDK2_OBJPATH)/MdePkg/Library/BaseUefiImageExtraActionLibNull/UefiImageExtraActionLib.o
+
 OBJECTS += \
   $(EDK2_OBJPATH)/MdeModulePkg/Library/BaseMemoryProfileLibNull/BaseMemoryProfileLibNull.o
 
diff --git a/BaseTools/Source/C/Common/Makefile b/BaseTools/Source/C/Common/Makefile
index e4982cbff4..af704876dd 100644
--- a/BaseTools/Source/C/Common/Makefile
+++ b/BaseTools/Source/C/Common/Makefile
@@ -11,7 +11,6 @@
 LIBNAME = Common
 
 OBJECTS = \
-  BasePeCoff.obj \
   BinderFuncs.obj \
   CommonLib.obj \
   Crc32.obj \
@@ -25,13 +24,26 @@ OBJECTS = \
   OsPath.obj \
   ParseGuidedSectionTools.obj \
   ParseInf.obj \
-  PeCoffLoaderEx.obj \
   SimpleFileParsing.obj \
   StringFuncs.obj \
   TianoCompress.obj
 
 OBJECTS = $(OBJECTS) AutoGen.obj DebugLib.obj
 
+OBJECTS = $(OBJECTS) \
+  $(EDK2_OBJPATH)\BaseTools\ImageTool\ImageToolEmit.obj \
+  $(EDK2_OBJPATH)\BaseTools\ImageTool\Image.obj \
+  $(EDK2_OBJPATH)\BaseTools\ImageTool\ElfScan32.obj \
+  $(EDK2_OBJPATH)\BaseTools\ImageTool\ElfScan64.obj \
+  $(EDK2_OBJPATH)\BaseTools\ImageTool\ElfScanCommon.obj \
+  $(EDK2_OBJPATH)\BaseTools\ImageTool\UefiImageScan.obj \
+  $(EDK2_OBJPATH)\BaseTools\ImageTool\PeScan.obj \
+  $(EDK2_OBJPATH)\BaseTools\ImageTool\PeEmit32.obj \
+  $(EDK2_OBJPATH)\BaseTools\ImageTool\PeEmit64.obj \
+  $(EDK2_OBJPATH)\BaseTools\ImageTool\PeEmitCommon.obj \
+  $(EDK2_OBJPATH)\BaseTools\ImageTool\BinEmit.obj \
+  $(EDK2_OBJPATH)\OpenCorePkg\User\Library\UserFile.obj
+
 OBJECTS = $(OBJECTS) \
   $(EDK2_OBJPATH)\MdePkg\Library\BaseDebugPrintErrorLevelLib\BaseDebugPrintErrorLevelLib.obj
 
@@ -91,6 +103,30 @@ OBJECTS = $(OBJECTS) \
   $(EDK2_OBJPATH)\MdePkg\Library\BasePrintLib\PrintLib.obj \
   $(EDK2_OBJPATH)\MdePkg\Library\BasePrintLib\PrintLibInternal.obj
 
+OBJECTS = $(OBJECTS) \
+  $(EDK2_OBJPATH)\MdePkg\Library\BaseOverflowLib\BaseAlignment.obj \
+  $(EDK2_OBJPATH)\MdePkg\Library\BaseOverflowLib\BaseBitOverflow.obj \
+  $(EDK2_OBJPATH)\MdePkg\Library\BaseOverflowLib\BaseMath.obj \
+  $(EDK2_OBJPATH)\MdePkg\Library\BaseOverflowLib\BaseNativeOverflow.obj \
+  $(EDK2_OBJPATH)\MdePkg\Library\BaseOverflowLib\BaseTripleOverflow.obj
+
+OBJECTS = $(OBJECTS) \
+  $(EDK2_OBJPATH)\MdePkg\Library\BasePeCoffLib2\PeCoffDebug.obj \
+  $(EDK2_OBJPATH)\MdePkg\Library\BasePeCoffLib2\PeCoffHash.obj \
+  $(EDK2_OBJPATH)\MdePkg\Library\BasePeCoffLib2\PeCoffHii.obj \
+  $(EDK2_OBJPATH)\MdePkg\Library\BasePeCoffLib2\PeCoffInfo.obj \
+  $(EDK2_OBJPATH)\MdePkg\Library\BasePeCoffLib2\PeCoffInit.obj \
+  $(EDK2_OBJPATH)\MdePkg\Library\BasePeCoffLib2\PeCoffLoad.obj \
+  $(EDK2_OBJPATH)\MdePkg\Library\BasePeCoffLib2\PeCoffRelocate.obj
+
+OBJECTS = $(OBJECTS) \
+  $(EDK2_OBJPATH)\MdePkg\Library\BaseUefiImageLib\CommonSupport.obj \
+  $(EDK2_OBJPATH)\MdePkg\Library\BaseUefiImageLib\PeCoffSupport.obj \
+  $(EDK2_OBJPATH)\MdePkg\Library\BaseUefiImageLib\UefiImageLibPeCoff.obj
+
+OBJECTS = $(OBJECTS) \
+  $(EDK2_OBJPATH)\MdePkg\Library\BaseUefiImageExtraActionLibNull\UefiImageExtraActionLib.obj
+
 OBJECTS = $(OBJECTS) \
   $(EDK2_OBJPATH)\MdeModulePkg\Library\BaseMemoryProfileLibNull\BaseMemoryProfileLibNull.obj
 
diff --git a/BaseTools/Source/C/Common/PeCoffLib.h b/BaseTools/Source/C/Common/PeCoffLib.h
deleted file mode 100644
index dd38f442f9..0000000000
--- a/BaseTools/Source/C/Common/PeCoffLib.h
+++ /dev/null
@@ -1,213 +0,0 @@
-/** @file
-  Function prototypes and defines on Memory Only PE COFF loader
-
-  Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
-  Portion Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
-  SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#ifndef __BASE_PE_COFF_LIB_H__
-#define __BASE_PE_COFF_LIB_H__
-
-//
-// Return status codes from the PE/COFF Loader services
-// BUGBUG: Find where used and see if can be replaced by RETURN_STATUS codes
-//
-#define IMAGE_ERROR_SUCCESS                      0
-#define IMAGE_ERROR_IMAGE_READ                   1
-#define IMAGE_ERROR_INVALID_PE_HEADER_SIGNATURE  2
-#define IMAGE_ERROR_INVALID_MACHINE_TYPE         3
-#define IMAGE_ERROR_INVALID_SUBSYSTEM            4
-#define IMAGE_ERROR_INVALID_IMAGE_ADDRESS        5
-#define IMAGE_ERROR_INVALID_IMAGE_SIZE           6
-#define IMAGE_ERROR_INVALID_SECTION_ALIGNMENT    7
-#define IMAGE_ERROR_SECTION_NOT_LOADED           8
-#define IMAGE_ERROR_FAILED_RELOCATION            9
-#define IMAGE_ERROR_FAILED_ICACHE_FLUSH          10
-
-//
-// Macro definitions for RISC-V architecture.
-//
-#define RV_X(x, s, n) (((x) >> (s)) & ((1<<(n))-1))
-#define RISCV_IMM_BITS 12
-#define RISCV_IMM_REACH (1LL<<RISCV_IMM_BITS)
-#define RISCV_CONST_HIGH_PART(VALUE) \
-  (((VALUE) + (RISCV_IMM_REACH/2)) & ~(RISCV_IMM_REACH-1))
-
-//
-// PE/COFF Loader Read Function passed in by caller
-//
-typedef
-RETURN_STATUS
-(EFIAPI *PE_COFF_LOADER_READ_FILE) (
-  IN     VOID   *FileHandle,
-  IN     UINTN  FileOffset,
-  IN OUT UINTN  *ReadSize,
-  OUT    VOID   *Buffer
-  );
-
-//
-// Context structure used while PE/COFF image is being loaded and relocated
-//
-typedef struct {
-  PHYSICAL_ADDRESS                  ImageAddress;
-  UINT64                            ImageSize;
-  PHYSICAL_ADDRESS                  DestinationAddress;
-  PHYSICAL_ADDRESS                  EntryPoint;
-  PE_COFF_LOADER_READ_FILE          ImageRead;
-  VOID                              *Handle;
-  VOID                              *FixupData;
-  UINT32                            SectionAlignment;
-  UINT32                            PeCoffHeaderOffset;
-  UINT32                            DebugDirectoryEntryRva;
-  VOID                              *CodeView;
-  CHAR8                             *PdbPointer;
-  UINTN                             SizeOfHeaders;
-  UINT32                            ImageCodeMemoryType;
-  UINT32                            ImageDataMemoryType;
-  UINT32                            ImageError;
-  UINTN                             FixupDataSize;
-  UINT16                            Machine;
-  UINT16                            ImageType;
-  BOOLEAN                           RelocationsStripped;
-  BOOLEAN                           IsTeImage;
-} PE_COFF_LOADER_IMAGE_CONTEXT;
-
-
-/**
-  Retrieves information on a PE/COFF image
-
-  @param  ImageContext The context of the image being loaded
-
-  @retval  EFI_SUCCESS The information on the PE/COFF image was collected.
-  @retval  EFI_INVALID_PARAMETER ImageContext is NULL.
-  @retval  EFI_UNSUPPORTED The PE/COFF image is not supported.
-  @retval  Otherwise The error status from reading the PE/COFF image using the
-  ImageContext->ImageRead() function
-
-**/
-RETURN_STATUS
-EFIAPI
-PeCoffLoaderGetImageInfo (
-  IN OUT PE_COFF_LOADER_IMAGE_CONTEXT  *ImageContext
-  )
-;
-
-/**
-  Relocates a PE/COFF image in memory
-
-  @param  ImageContext Contains information on the loaded image to relocate
-
-  @retval EFI_SUCCESS      if the PE/COFF image was relocated
-  @retval EFI_LOAD_ERROR   if the image is not a valid PE/COFF image
-  @retval EFI_UNSUPPORTED  not support
-
-**/
-RETURN_STATUS
-EFIAPI
-PeCoffLoaderRelocateImage (
-  IN OUT PE_COFF_LOADER_IMAGE_CONTEXT  *ImageContext
-  )
-;
-
-/**
-  Loads a PE/COFF image into memory
-
-  @param  ImageContext Contains information on image to load into memory
-
-  @retval EFI_SUCCESS            if the PE/COFF image was loaded
-  @retval EFI_BUFFER_TOO_SMALL   if the caller did not provide a large enough buffer
-  @retval EFI_LOAD_ERROR         if the image is a runtime driver with no relocations
-  @retval EFI_INVALID_PARAMETER  if the image address is invalid
-
-**/
-RETURN_STATUS
-EFIAPI
-PeCoffLoaderLoadImage (
-  IN OUT PE_COFF_LOADER_IMAGE_CONTEXT  *ImageContext
-  )
-;
-
-VOID *
-EFIAPI
-PeCoffLoaderGetPdbPointer (
-  IN VOID  *Pe32Data
-  )
-;
-
-RETURN_STATUS
-EFIAPI
-PeCoffLoaderGetEntryPoint (
-  IN  VOID  *Pe32Data,
-  OUT VOID  **EntryPoint,
-  OUT VOID  **BaseOfImage
-  )
-;
-
-//
-// These functions are used by the ARM PE/COFF relocation code and by
-// the ELF to PE/COFF converter so that is why they are public
-//
-
-/**
-  Pass in a pointer to an ARM MOVT or MOVW immediate instruction and
-  return the immediate data encoded in the instruction
-
-  @param  Instruction   Pointer to ARM MOVT or MOVW immediate instruction
-
-  @return Immediate address encoded in the instruction
-
-**/
-UINT16
-EFIAPI
-ThumbMovtImmediateAddress (
-  IN UINT16 *Instruction
-  );
-
-/**
-  Update an ARM MOVT or MOVW immediate instruction immediate data.
-
-  @param  Instruction   Pointer to ARM MOVT or MOVW immediate instruction
-  @param  Address       New address to patch into the instruction
-
-**/
-VOID
-EFIAPI
-ThumbMovtImmediatePatch (
-  IN OUT UINT16 *Instruction,
-  IN     UINT16 Address
-  );
-
-
-/**
-  Pass in a pointer to an ARM MOVW/MOVT instruction pair and
-  return the immediate data encoded in the two` instruction
-
-  @param  Instructions  Pointer to ARM MOVW/MOVT instruction pair
-
-  @return Immediate address encoded in the instructions
-
-**/
-UINT32
-EFIAPI
-ThumbMovwMovtImmediateAddress (
-  IN UINT16 *Instructions
-  );
-
-/**
-  Update an ARM MOVW/MOVT immediate instruction instruction pair.
-
-  @param  Instructions  Pointer to ARM MOVW/MOVT instruction pair
-  @param  Address       New address to patch into the instructions
-**/
-VOID
-EFIAPI
-ThumbMovwMovtImmediatePatch (
-  IN OUT UINT16 *Instructions,
-  IN     UINT32 Address
-  );
-
-
-
-#endif
diff --git a/BaseTools/Source/C/Common/PeCoffLoaderEx.c b/BaseTools/Source/C/Common/PeCoffLoaderEx.c
deleted file mode 100644
index 088e470d17..0000000000
--- a/BaseTools/Source/C/Common/PeCoffLoaderEx.c
+++ /dev/null
@@ -1,385 +0,0 @@
-/** @file
-IA32 and X64 Specific relocation fixups
-
-Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>
-Portions Copyright (c) 2011 - 2013, ARM Ltd. All rights reserved.<BR>
-Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
-Copyright (c) 2022, Loongson Technology Corporation Limited. All rights reserved.<BR>
-SPDX-License-Identifier: BSD-2-Clause-Patent
-
---*/
-
-#include <Common/UefiBaseTypes.h>
-#include <Common/PeImageEx.h>
-#include "PeCoffLib.h"
-#include "CommonLib.h"
-#include "EfiUtilityMsgs.h"
-
-#define IMM64_IMM7B_INST_WORD_X         3
-#define IMM64_IMM7B_SIZE_X              7
-#define IMM64_IMM7B_INST_WORD_POS_X     4
-#define IMM64_IMM7B_VAL_POS_X           0
-
-#define IMM64_IMM9D_INST_WORD_X         3
-#define IMM64_IMM9D_SIZE_X              9
-#define IMM64_IMM9D_INST_WORD_POS_X     18
-#define IMM64_IMM9D_VAL_POS_X           7
-
-#define IMM64_IMM5C_INST_WORD_X         3
-#define IMM64_IMM5C_SIZE_X              5
-#define IMM64_IMM5C_INST_WORD_POS_X     13
-#define IMM64_IMM5C_VAL_POS_X           16
-
-#define IMM64_IC_INST_WORD_X            3
-#define IMM64_IC_SIZE_X                 1
-#define IMM64_IC_INST_WORD_POS_X        12
-#define IMM64_IC_VAL_POS_X              21
-
-#define IMM64_IMM41a_INST_WORD_X        1
-#define IMM64_IMM41a_SIZE_X             10
-#define IMM64_IMM41a_INST_WORD_POS_X    14
-#define IMM64_IMM41a_VAL_POS_X          22
-
-#define IMM64_IMM41b_INST_WORD_X        1
-#define IMM64_IMM41b_SIZE_X             8
-#define IMM64_IMM41b_INST_WORD_POS_X    24
-#define IMM64_IMM41b_VAL_POS_X          32
-
-#define IMM64_IMM41c_INST_WORD_X        2
-#define IMM64_IMM41c_SIZE_X             23
-#define IMM64_IMM41c_INST_WORD_POS_X    0
-#define IMM64_IMM41c_VAL_POS_X          40
-
-#define IMM64_SIGN_INST_WORD_X          3
-#define IMM64_SIGN_SIZE_X               1
-#define IMM64_SIGN_INST_WORD_POS_X      27
-#define IMM64_SIGN_VAL_POS_X            63
-
-UINT32 *RiscVHi20Fixup = NULL;
-
-/**
-  Performs an IA-32 specific relocation fixup
-
-  @param Reloc      Pointer to the relocation record
-  @param Fixup      Pointer to the address to fix up
-  @param FixupData  Pointer to a buffer to log the fixups
-  @param Adjust     The offset to adjust the fixup
-
-  @retval EFI_UNSUPPORTED   - Unsupported now
-**/
-RETURN_STATUS
-PeCoffLoaderRelocateIa32Image (
-  IN UINT16      *Reloc,
-  IN OUT CHAR8   *Fixup,
-  IN OUT CHAR8   **FixupData,
-  IN UINT64      Adjust
-  )
-{
-  return RETURN_UNSUPPORTED;
-}
-
-/**
-  Performs an RISC-V specific relocation fixup
-
-  @param Reloc      Pointer to the relocation record
-  @param Fixup      Pointer to the address to fix up
-  @param FixupData  Pointer to a buffer to log the fixups
-  @param Adjust     The offset to adjust the fixup
-
-  @return Status code
-**/
-RETURN_STATUS
-PeCoffLoaderRelocateRiscVImage (
-  IN UINT16      *Reloc,
-  IN OUT CHAR8   *Fixup,
-  IN OUT CHAR8   **FixupData,
-  IN UINT64      Adjust
-  )
-{
-  UINT32 Value;
-  UINT32 Value2;
-
-  switch ((*Reloc) >> 12) {
-  case EFI_IMAGE_REL_BASED_RISCV_HI20:
-      RiscVHi20Fixup = (UINT32 *) Fixup;
-      break;
-
-  case EFI_IMAGE_REL_BASED_RISCV_LOW12I:
-      if (RiscVHi20Fixup != NULL) {
-        Value = (UINT32)(RV_X(*RiscVHi20Fixup, 12, 20) << 12);
-        Value2 = (UINT32)(RV_X(*(UINT32 *)Fixup, 20, 12));
-        if (Value2 & (RISCV_IMM_REACH/2)) {
-          Value2 |= ~(RISCV_IMM_REACH-1);
-        }
-        Value += Value2;
-        Value += (UINT32)Adjust;
-        Value2 = RISCV_CONST_HIGH_PART (Value);
-        *(UINT32 *)RiscVHi20Fixup = (RV_X (Value2, 12, 20) << 12) | \
-                                           (RV_X (*(UINT32 *)RiscVHi20Fixup, 0, 12));
-        *(UINT32 *)Fixup = (RV_X (Value, 0, 12) << 20) | \
-                           (RV_X (*(UINT32 *)Fixup, 0, 20));
-      }
-      RiscVHi20Fixup = NULL;
-      break;
-
-  case EFI_IMAGE_REL_BASED_RISCV_LOW12S:
-      if (RiscVHi20Fixup != NULL) {
-        Value = (UINT32)(RV_X(*RiscVHi20Fixup, 12, 20) << 12);
-        Value2 = (UINT32)(RV_X(*(UINT32 *)Fixup, 7, 5) | (RV_X(*(UINT32 *)Fixup, 25, 7) << 5));
-        if (Value2 & (RISCV_IMM_REACH/2)) {
-          Value2 |= ~(RISCV_IMM_REACH-1);
-        }
-        Value += Value2;
-        Value += (UINT32)Adjust;
-        Value2 = RISCV_CONST_HIGH_PART (Value);
-        *(UINT32 *)RiscVHi20Fixup = (RV_X (Value2, 12, 20) << 12) | \
-                                           (RV_X (*(UINT32 *)RiscVHi20Fixup, 0, 12));
-        Value2 = *(UINT32 *)Fixup & 0x01fff07f;
-        Value &= RISCV_IMM_REACH - 1;
-        *(UINT32 *)Fixup = Value2 | (UINT32)(((RV_X(Value, 0, 5) << 7) | (RV_X(Value, 5, 7) << 25)));
-      }
-      RiscVHi20Fixup = NULL;
-      break;
-
-  default:
-      return EFI_UNSUPPORTED;
-
-  }
-  return RETURN_SUCCESS;
-}
-
-/**
-  Pass in a pointer to an ARM MOVT or MOVW immediate instruction and
-  return the immediate data encoded in the instruction
-
-  @param  Instruction   Pointer to ARM MOVT or MOVW immediate instruction
-
-  @return Immediate address encoded in the instruction
-
-**/
-UINT16
-EFIAPI
-ThumbMovtImmediateAddress (
-  IN UINT16 *Instruction
-  )
-{
-  UINT32  Movt;
-  UINT16  Address;
-
-  // Thumb2 is two 16-bit instructions working together. Not a single 32-bit instruction
-  // Example MOVT R0, #0 is 0x0000f2c0 or 0xf2c0 0x0000
-  Movt = (*Instruction << 16) | (*(Instruction + 1));
-
-  // imm16 = imm4:i:imm3:imm8
-  //         imm4 -> Bit19:Bit16
-  //         i    -> Bit26
-  //         imm3 -> Bit14:Bit12
-  //         imm8 -> Bit7:Bit0
-  Address  = (UINT16)(Movt & 0x000000ff);          // imm8
-  Address |= (UINT16)((Movt >> 4) &  0x0000f700);  // imm4 imm3
-  Address |= (((Movt & BIT26) != 0) ? BIT11 : 0);  // i
-  return Address;
-}
-
-
-/**
-  Update an ARM MOVT or MOVW immediate instruction immediate data.
-
-  @param  Instruction   Pointer to ARM MOVT or MOVW immediate instruction
-  @param  Address       New address to patch into the instruction
-**/
-VOID
-EFIAPI
-ThumbMovtImmediatePatch (
-  IN OUT UINT16 *Instruction,
-  IN     UINT16 Address
-  )
-{
-  UINT16  Patch;
-
-  // First 16-bit chunk of instruction
-  Patch  = ((Address >> 12) & 0x000f);             // imm4
-  Patch |= (((Address & BIT11) != 0) ? BIT10 : 0); // i
-  *Instruction = (*Instruction & ~0x040f) | Patch;
-
-  // Second 16-bit chunk of instruction
-  Patch  =  Address & 0x000000ff;          // imm8
-  Patch |=  ((Address << 4) & 0x00007000); // imm3
-  Instruction++;
-  *Instruction = (*Instruction & ~0x70ff) | Patch;
-}
-
-/**
-  Pass in a pointer to an ARM MOVW/MOVT instruction pair and
-  return the immediate data encoded in the two` instruction
-
-  @param  Instructions  Pointer to ARM MOVW/MOVT instruction pair
-
-  @return Immediate address encoded in the instructions
-
-**/
-UINT32
-EFIAPI
-ThumbMovwMovtImmediateAddress (
-  IN UINT16 *Instructions
-  )
-{
-  UINT16  *Word;
-  UINT16  *Top;
-
-  Word = Instructions;  // MOVW
-  Top  = Word + 2;      // MOVT
-
-  return (ThumbMovtImmediateAddress (Top) << 16) + ThumbMovtImmediateAddress (Word);
-}
-
-
-/**
-  Update an ARM MOVW/MOVT immediate instruction instruction pair.
-
-  @param  Instructions  Pointer to ARM MOVW/MOVT instruction pair
-  @param  Address       New address to patch into the instructions
-**/
-VOID
-EFIAPI
-ThumbMovwMovtImmediatePatch (
-  IN OUT UINT16 *Instructions,
-  IN     UINT32 Address
-  )
-{
-  UINT16  *Word;
-  UINT16  *Top;
-
-  Word = (UINT16 *)Instructions;  // MOVW
-  Top  = Word + 2;                // MOVT
-
-  ThumbMovtImmediatePatch (Word, (UINT16)(Address & 0xffff));
-  ThumbMovtImmediatePatch (Top, (UINT16)(Address >> 16));
-}
-
-
-/**
-  Performs an ARM-based specific relocation fixup and is a no-op on other
-  instruction sets.
-
-  @param  Reloc       Pointer to the relocation record.
-  @param  Fixup       Pointer to the address to fix up.
-  @param  FixupData   Pointer to a buffer to log the fixups.
-  @param  Adjust      The offset to adjust the fixup.
-
-  @return Status code.
-
-**/
-RETURN_STATUS
-PeCoffLoaderRelocateArmImage (
-  IN UINT16      **Reloc,
-  IN OUT CHAR8   *Fixup,
-  IN OUT CHAR8   **FixupData,
-  IN UINT64      Adjust
-  )
-{
-  UINT16      *Fixup16;
-  UINT32      FixupVal;
-
-  Fixup16   = (UINT16 *) Fixup;
-
-  switch ((**Reloc) >> 12) {
-
-  case EFI_IMAGE_REL_BASED_ARM_MOV32T:
-    FixupVal = ThumbMovwMovtImmediateAddress (Fixup16) + (UINT32)Adjust;
-    ThumbMovwMovtImmediatePatch (Fixup16, FixupVal);
-
-
-    if (*FixupData != NULL) {
-      *FixupData = ALIGN_POINTER(*FixupData, sizeof(UINT64));
-      CopyMem (*FixupData, Fixup16, sizeof (UINT64));
-      *FixupData = *FixupData + sizeof(UINT64);
-    }
-    break;
-
-  case EFI_IMAGE_REL_BASED_ARM_MOV32A:
-     // break omitted - ARM instruction encoding not implemented
-  default:
-    return RETURN_UNSUPPORTED;
-  }
-
-  return RETURN_SUCCESS;
-}
-
-/**
-  Performs a LoongArch specific relocation fixup.
-
-  @param[in]       Reloc       Pointer to the relocation record.
-  @param[in, out]  Fixup       Pointer to the address to fix up.
-  @param[in, out]  FixupData   Pointer to a buffer to log the fixups.
-  @param[in]       Adjust      The offset to adjust the fixup.
-
-  @return Status code.
-**/
-RETURN_STATUS
-PeCoffLoaderRelocateLoongArch64Image (
-  IN UINT16     *Reloc,
-  IN OUT CHAR8  *Fixup,
-  IN OUT CHAR8  **FixupData,
-  IN UINT64     Adjust
-  )
-{
-  UINT8  RelocType;
-  UINT64 Value;
-  UINT64 Tmp1;
-  UINT64 Tmp2;
-
-  RelocType = ((*Reloc) >> 12);
-  Value     = 0;
-  Tmp1      = 0;
-  Tmp2      = 0;
-
-  switch (RelocType) {
-    case EFI_IMAGE_REL_BASED_LOONGARCH64_MARK_LA:
-      // The next four instructions are used to load a 64 bit address, relocate all of them
-      Value = (*(UINT32 *)Fixup & 0x1ffffe0) << 7 |       // lu12i.w 20bits from bit5
-              (*((UINT32 *)Fixup + 1) & 0x3ffc00) >> 10;  // ori     12bits from bit10
-      Tmp1   = *((UINT32 *)Fixup + 2) & 0x1ffffe0;        // lu32i.d 20bits from bit5
-      Tmp2   = *((UINT32 *)Fixup + 3) & 0x3ffc00;         // lu52i.d 12bits from bit10
-      Value  = Value | (Tmp1 << 27) | (Tmp2 << 42);
-      Value += Adjust;
-
-      *(UINT32 *)Fixup = (*(UINT32 *)Fixup & ~0x1ffffe0) | (((Value >> 12) & 0xfffff) << 5);
-      if (*FixupData != NULL) {
-        *FixupData              = ALIGN_POINTER (*FixupData, sizeof (UINT32));
-        *(UINT32 *)(*FixupData) = *(UINT32 *)Fixup;
-        *FixupData              = *FixupData + sizeof (UINT32);
-      }
-
-      Fixup           += sizeof (UINT32);
-      *(UINT32 *)Fixup = (*(UINT32 *)Fixup & ~0x3ffc00) | ((Value & 0xfff) << 10);
-      if (*FixupData != NULL) {
-        *FixupData              = ALIGN_POINTER (*FixupData, sizeof (UINT32));
-        *(UINT32 *)(*FixupData) = *(UINT32 *)Fixup;
-        *FixupData              = *FixupData + sizeof (UINT32);
-      }
-
-      Fixup           += sizeof (UINT32);
-      *(UINT32 *)Fixup = (*(UINT32 *)Fixup & ~0x1ffffe0) | (((Value >> 32) & 0xfffff) << 5);
-      if (*FixupData != NULL) {
-        *FixupData              = ALIGN_POINTER (*FixupData, sizeof (UINT32));
-        *(UINT32 *)(*FixupData) = *(UINT32 *)Fixup;
-        *FixupData              = *FixupData + sizeof (UINT32);
-      }
-
-      Fixup           += sizeof (UINT32);
-      *(UINT32 *)Fixup = (*(UINT32 *)Fixup & ~0x3ffc00) | (((Value >> 52) & 0xfff) << 10);
-      if (*FixupData != NULL) {
-        *FixupData              = ALIGN_POINTER (*FixupData, sizeof (UINT32));
-        *(UINT32 *)(*FixupData) = *(UINT32 *)Fixup;
-        *FixupData              = *FixupData + sizeof (UINT32);
-      }
-
-      break;
-    default:
-      Error (NULL, 0, 3000, "", "PeCoffLoaderRelocateLoongArch64Image: Fixup[0x%x] Adjust[0x%llx] *Reloc[0x%x], type[0x%x].", *(UINT32 *)Fixup, Adjust, *Reloc, RelocType);
-      return RETURN_UNSUPPORTED;
-  }
-
-  return RETURN_SUCCESS;
-}
diff --git a/BaseTools/Source/C/EfiRom/EfiRom.c b/BaseTools/Source/C/EfiRom/EfiRom.c
index fa7bf0e62e..9a41a34baf 100644
--- a/BaseTools/Source/C/EfiRom/EfiRom.c
+++ b/BaseTools/Source/C/EfiRom/EfiRom.c
@@ -1,5 +1,5 @@
 /** @file
-Utility program to create an EFI option ROM image from binary and EFI PE32 files.
+Utility program to create an EFI option ROM image from binary and UEFI image files.
 
 Copyright (c) 1999 - 2018, Intel Corporation. All rights reserved.<BR>
 SPDX-License-Identifier: BSD-2-Clause-Patent
@@ -426,12 +426,12 @@ ProcessEfiFile (
 
 Routine Description:
 
-  Process a PE32 EFI file.
+  Process an UEFI image file.
 
 Arguments:
 
   OutFptr     - file pointer to output binary ROM image file we're creating
-  InFile      - structure contains information on the PE32 file to process
+  InFile      - structure contains information on the UEFI image file to process
   VendId      - vendor ID as required in the option ROM header
   DevId       - device ID as required in the option ROM header
   Size        - pointer to where to return the size added to the output file
@@ -471,22 +471,40 @@ Returns:
   //
   // Initialize our buffer pointers to null.
   //
-  Buffer            = NULL;
   CompressedBuffer  = NULL;
 
-  //
-  // Double-check the file to make sure it's what we expect it to be
-  //
-  Status = CheckPE32File (InFptr, &MachineType, &SubSystem);
-  if (Status != STATUS_SUCCESS) {
-    goto BailOut;
-  }
   //
   // Seek to the end of the input file and get the file size
   //
   fseek (InFptr, 0, SEEK_END);
   FileSize = ftell (InFptr);
 
+  //
+  // Allocate memory for the entire file (in case we have to compress), then
+  // seek back to the beginning of the file and read it into our buffer.
+  //
+  Buffer = (UINT8 *) malloc (FileSize);
+  if (Buffer == NULL) {
+    Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");
+    Status = STATUS_ERROR;
+    goto BailOut;
+  }
+
+  fseek (InFptr, 0, SEEK_SET);
+  if (fread (Buffer, FileSize, 1, InFptr) != 1) {
+    Error (NULL, 0, 0004, "Error reading file", "File %s", InFile->FileName);
+    Status = STATUS_ERROR;
+    goto BailOut;
+  }
+
+  //
+  // Double-check the file to make sure it's what we expect it to be
+  //
+  Status = CheckUefiImageFile (Buffer, FileSize, &MachineType, &SubSystem);
+  if (Status != STATUS_SUCCESS) {
+    goto BailOut;
+  }
+
   //
   // Get the size of the headers we're going to put in front of the image. The
   // EFI header must be aligned on a 4-byte boundary, so pad accordingly.
@@ -519,23 +537,6 @@ Returns:
     VerboseMsg("  File size   = 0x%X\n", (unsigned) FileSize);
   }
   //
-  // Allocate memory for the entire file (in case we have to compress), then
-  // seek back to the beginning of the file and read it into our buffer.
-  //
-  Buffer = (UINT8 *) malloc (FileSize);
-  if (Buffer == NULL) {
-    Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");
-    Status = STATUS_ERROR;
-    goto BailOut;
-  }
-
-  fseek (InFptr, 0, SEEK_SET);
-  if (fread (Buffer, FileSize, 1, InFptr) != 1) {
-    Error (NULL, 0, 0004, "Error reading file", "File %s", InFile->FileName);
-    Status = STATUS_ERROR;
-    goto BailOut;
-  }
-  //
   // Now determine the size of the final output file. It's either the header size
   // plus the file's size, or the header size plus the compressed file size.
   //
@@ -805,8 +806,9 @@ BailOut:
 
 static
 int
-CheckPE32File (
-  FILE      *Fptr,
+CheckUefiImageFile (
+  VOID      *FileBuffer,
+  UINT32    FileSize,
   UINT16    *MachineType,
   UINT16    *SubSystem
   )
@@ -814,13 +816,14 @@ CheckPE32File (
 
 Routine Description:
 
-  Given a file pointer to a supposed PE32 image file, verify that it is indeed a
-  PE32 image file, and then return the machine type in the supplied pointer.
+  Given a file pointer to a supposed UEFI image file, verify that it is indeed a
+  UEFI image file, and then return the machine type in the supplied pointer.
 
 Arguments:
 
-  Fptr          File pointer to the already-opened PE32 file
-  MachineType   Location to stuff the machine type of the PE32 file. This is needed
+  FileBuffer    File buffer of the UEFI image file
+  FileSize      File size, in bytes, of FileBuffer
+  MachineType   Location to stuff the machine type of the UEFI file. This is needed
                 because the image may be Itanium-based, IA32, or EBC.
 
 Returns:
@@ -830,67 +833,24 @@ Returns:
 
 --*/
 {
-  EFI_IMAGE_DOS_HEADER            DosHeader;
-  EFI_IMAGE_OPTIONAL_HEADER_UNION PeHdr;
+  RETURN_STATUS                    Status;
+  UEFI_IMAGE_LOADER_IMAGE_CONTEXT  Context;
 
-  //
-  // Position to the start of the file
-  //
-  fseek (Fptr, 0, SEEK_SET);
-
-  //
-  // Read the DOS header
-  //
-  if (fread (&DosHeader, sizeof (DosHeader), 1, Fptr) != 1) {
-    Error (NULL, 0, 0004, "Failed to read the DOS stub from the input file!", NULL);
-    return STATUS_ERROR;
-  }
-  //
-  // Check the magic number (0x5A4D)
-  //
-  if (DosHeader.e_magic != EFI_IMAGE_DOS_SIGNATURE) {
-    Error (NULL, 0, 2000, "Invalid parameter", "Input file does not appear to be a PE32 image (magic number)!");
-    return STATUS_ERROR;
-  }
-  //
-  // Position into the file and check the PE signature
-  //
-  fseek (Fptr, (long) DosHeader.e_lfanew, SEEK_SET);
-
-  //
-  // Read PE headers
-  //
-  if (fread (&PeHdr, sizeof (PeHdr), 1, Fptr) != 1) {
-    Error (NULL, 0, 0004, "Failed to read PE/COFF headers from input file!", NULL);
+  Status = UefiImageInitializeContext (&Context, FileBuffer, FileSize);
+  if (RETURN_ERROR (Status)) {
+    Error (NULL, 0, 2000, "Invalid parameter", "Input file does not appear to be an UEFI image - %llu!", Status);
     return STATUS_ERROR;
   }
 
-
-  //
-  // Check the PE signature in the header "PE\0\0"
-  //
-  if (PeHdr.Pe32.Signature != EFI_IMAGE_NT_SIGNATURE) {
-    Error (NULL, 0, 2000, "Invalid parameter", "Input file does not appear to be a PE32 image (signature)!");
-    return STATUS_ERROR;
-  }
-
-  memcpy ((char *) MachineType, &PeHdr.Pe32.FileHeader.Machine, 2);
-
-  if (PeHdr.Pe32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
-    *SubSystem = PeHdr.Pe32.OptionalHeader.Subsystem;
-  } else if (PeHdr.Pe32Plus.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) {
-    *SubSystem = PeHdr.Pe32Plus.OptionalHeader.Subsystem;
-  } else {
-    Error (NULL, 0, 2000, "Invalid parameter", "Unable to find subsystem type!");
-    return STATUS_ERROR;
-  }
+  *MachineType = UefiImageGetMachine (&Context);
+  *SubSystem   = UefiImageGetSubsystem (&Context);
 
   if (mOptions.Verbose) {
     VerboseMsg("  Got subsystem = 0x%X from image\n", *SubSystem);
   }
 
   //
-  // File was successfully identified as a PE32
+  // File was successfully identified as an UEFI image
   //
   return STATUS_SUCCESS;
 }
@@ -1354,9 +1314,9 @@ Returns:
   fprintf (stdout, "  -o FileName, --output FileName\n\
             File will be created to store the output content.\n");
   fprintf (stdout, "  -e EfiFileName\n\
-            EFI PE32 image files.\n");
+            UEFI image files.\n");
   fprintf (stdout, "  -ec EfiFileName\n\
-            EFI PE32 image files and will be compressed.\n");
+            UEFI image files and will be compressed.\n");
   fprintf (stdout, "  -b BinFileName\n\
             Legacy binary files.\n");
   fprintf (stdout, "  -l ClassCode\n\
diff --git a/BaseTools/Source/C/EfiRom/EfiRom.h b/BaseTools/Source/C/EfiRom/EfiRom.h
index f05198713e..c51bebb0fe 100644
--- a/BaseTools/Source/C/EfiRom/EfiRom.h
+++ b/BaseTools/Source/C/EfiRom/EfiRom.h
@@ -14,7 +14,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
 #include <stdlib.h>
 
 #include <Common/UefiBaseTypes.h>
-#include <Common/PeImageEx.h> // for PE32 structure definitions
+#include <IndustryStandard/PeImage2.h> // for PE32 structure definitions
 
 #include <IndustryStandard/Pci22.h>  // for option ROM header structures
 #include <IndustryStandard/Pci30.h>
@@ -22,6 +22,8 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
 #include "Compress.h"
 #include "CommonLib.h"
 
+#include <Library/UefiImageLib.h>
+
 //
 // Version of this utility
 //
@@ -203,8 +205,9 @@ Returns:
 
 static
 int
-CheckPE32File (
-  FILE      *Fptr,
+CheckUefiImageFile (
+  VOID      *FileBuffer,
+  UINT32    FileSize,
   UINT16    *MachineType,
   UINT16    *SubSystem
   )
@@ -242,12 +245,12 @@ ProcessEfiFile (
 
 Routine Description:
 
-  Process a PE32 EFI file.
+  Process a UEFI image file.
 
 Arguments:
 
   OutFptr     - file pointer to output binary ROM image file we're creating
-  InFile      - structure contains information on the PE32 file to process
+  InFile      - structure contains information on the UEFI image file to process
   VendId      - vendor ID as required in the option ROM header
   DevId       - device ID as required in the option ROM header
   Size        - pointer to where to return the size added to the output file
diff --git a/BaseTools/Source/C/GenFfs/GenFfs.c b/BaseTools/Source/C/GenFfs/GenFfs.c
index 857c5c294f..d38b39236a 100644
--- a/BaseTools/Source/C/GenFfs/GenFfs.c
+++ b/BaseTools/Source/C/GenFfs/GenFfs.c
@@ -27,14 +27,12 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
 
 #include <Common/UefiBaseTypes.h>
 #include <Common/PiFirmwareFile.h>
-#include <Common/PeImageEx.h>
 #include <Guid/FfsSectionAlignmentPadding.h>
 
 #include "CommonLib.h"
 #include "ParseInf.h"
 #include "EfiUtilityMsgs.h"
 #include "FvLib.h"
-#include "PeCoffLib.h"
 
 #define UTILITY_NAME            "GenFfs"
 #define UTILITY_MAJOR_VERSION   0
@@ -453,104 +451,6 @@ Returns:
   }
 }
 
-EFI_STATUS
-EFIAPI
-FfsRebaseImageRead (
-    IN      VOID    *FileHandle,
-    IN      UINTN   FileOffset,
-    IN OUT  UINT32  *ReadSize,
-    OUT     VOID    *Buffer
-    )
-  /*++
-
-    Routine Description:
-
-    Support routine for the PE/COFF Loader that reads a buffer from a PE/COFF file
-
-    Arguments:
-
-   FileHandle - The handle to the PE/COFF file
-
-   FileOffset - The offset, in bytes, into the file to read
-
-   ReadSize   - The number of bytes to read from the file starting at FileOffset
-
-   Buffer     - A pointer to the buffer to read the data into.
-
-   Returns:
-
-   EFI_SUCCESS - ReadSize bytes of data were read into Buffer from the PE/COFF file starting at FileOffset
-
-   --*/
-{
-  CHAR8   *Destination8;
-  CHAR8   *Source8;
-  UINT32  Length;
-
-  Destination8  = Buffer;
-  Source8       = (CHAR8 *) ((UINTN) FileHandle + FileOffset);
-  Length        = *ReadSize;
-  while (Length--) {
-    *(Destination8++) = *(Source8++);
-  }
-
-  return EFI_SUCCESS;
-}
-
-STATIC
-EFI_STATUS
-GetAlignmentFromFile(char *InFile, UINT32 *Alignment)
-  /*++
-    InFile is input file for getting alignment
-    return the alignment
-    --*/
-{
-  FILE                           *InFileHandle;
-  UINT8                          *PeFileBuffer;
-  UINTN                          PeFileSize;
-  UINT32                         CurSecHdrSize;
-  PE_COFF_LOADER_IMAGE_CONTEXT   ImageContext;
-  EFI_COMMON_SECTION_HEADER      *CommonHeader;
-  EFI_STATUS                     Status;
-
-  InFileHandle        = NULL;
-  PeFileBuffer        = NULL;
-  *Alignment          = 0;
-
-  memset (&ImageContext, 0, sizeof (ImageContext));
-
-  InFileHandle = fopen(LongFilePath(InFile), "rb");
-  if (InFileHandle == NULL){
-    Error (NULL, 0, 0001, "Error opening file", InFile);
-    return EFI_ABORTED;
-  }
-  PeFileSize = _filelength (fileno(InFileHandle));
-  PeFileBuffer = (UINT8 *) malloc (PeFileSize);
-  if (PeFileBuffer == NULL) {
-    fclose (InFileHandle);
-    Error(NULL, 0, 4001, "Resource", "memory cannot be allocated for %s", InFile);
-    return EFI_OUT_OF_RESOURCES;
-  }
-  fread (PeFileBuffer, sizeof (UINT8), PeFileSize, InFileHandle);
-  fclose (InFileHandle);
-  CommonHeader = (EFI_COMMON_SECTION_HEADER *) PeFileBuffer;
-  CurSecHdrSize = GetSectionHeaderLength(CommonHeader);
-  ImageContext.Handle = (VOID *) ((UINTN)PeFileBuffer + CurSecHdrSize);
-  ImageContext.ImageRead = (PE_COFF_LOADER_READ_FILE)FfsRebaseImageRead;
-  Status               = PeCoffLoaderGetImageInfo(&ImageContext);
-  if (EFI_ERROR (Status)) {
-    Error (NULL, 0, 3000, "Invalid PeImage", "The input file is %s and return status is %x", InFile, (int) Status);
-    return Status;
-   }
-  *Alignment = ImageContext.SectionAlignment;
-  // Free the allocated memory resource
-  if (PeFileBuffer != NULL) {
-    free (PeFileBuffer);
-    PeFileBuffer = NULL;
-  }
-  return EFI_SUCCESS;
-}
-
 int
 main (
   int   argc,
diff --git a/BaseTools/Source/C/GenFv/GenFvInternalLib.c b/BaseTools/Source/C/GenFv/GenFvInternalLib.c
index d5de8f732c..091d469890 100644
--- a/BaseTools/Source/C/GenFv/GenFvInternalLib.c
+++ b/BaseTools/Source/C/GenFv/GenFvInternalLib.c
@@ -31,12 +31,16 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
 #include <io.h>
 #endif
 #include <assert.h>
+#include <stdbool.h>
 
 #include <Guid/FfsSectionAlignmentPadding.h>
 
 #include "GenFvInternalLib.h"
 #include "FvLib.h"
-#include "PeCoffLib.h"
+#include <Library/PeCoffLib2.h>
+#include <Library/UefiImageLib.h>
+
+#include "../../../ImageTool/ImageToolEmit.h"
 
 #define ARM64_UNCONDITIONAL_JUMP_INSTRUCTION      0x14000000
 
@@ -727,24 +731,24 @@ Returns:
 EFI_STATUS
 WriteMapFile (
   IN OUT FILE                  *FvMapFile,
-  IN     CHAR8                 *FileName,
+  IN     CONST CHAR8           *FileName,
   IN     EFI_FFS_FILE_HEADER   *FfsFile,
   IN     EFI_PHYSICAL_ADDRESS  ImageBaseAddress,
-  IN     PE_COFF_LOADER_IMAGE_CONTEXT *pImageContext
+  IN     UEFI_IMAGE_LOADER_IMAGE_CONTEXT *pImageContext
   )
 /*++
 
 Routine Description:
 
   This function gets the basic debug information (entrypoint, baseaddress, .text, .data section base address)
-  from PE/COFF image and abstracts Pe Map file information and add them into FvMap file for Debug.
+  from UEFI image and abstracts UEFI image Map file information and add them into FvMap file for Debug.
 
 Arguments:
 
   FvMapFile             A pointer to FvMap File
   FileName              Ffs File PathName
   FfsFile               A pointer to Ffs file image.
-  ImageBaseAddress      PeImage Base Address.
+  ImageBaseAddress      UefiImage Base Address.
   pImageContext         Image Context Information.
 
 Returns:
@@ -764,9 +768,8 @@ Returns:
   EFI_PHYSICAL_ADDRESS                FunctionAddress;
   UINT32                              FunctionType;
   CHAR8                               FunctionTypeName [MAX_LINE_LEN];
+  UINT8                               Format;
   UINT32                              AddressOfEntryPoint;
-  UINT32                              Offset;
-  EFI_IMAGE_OPTIONAL_HEADER_UNION     *ImgHdr;
   long long                           TempLongAddress;
   EFI_PHYSICAL_ADDRESS                LinkTimeBaseAddress;
   BOOLEAN                             IsUseClang;
@@ -832,13 +835,9 @@ Returns:
   *Cptr2 = '.';
 
   //
-  // AddressOfEntryPoint and Offset in Image
+  // AddressOfEntryPoint in Image
   //
-  assert (!pImageContext->IsTeImage);
-
-  ImgHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *) ((UINT8 *) pImageContext->Handle + pImageContext->PeCoffHeaderOffset);
-  AddressOfEntryPoint = ImgHdr->Pe32.OptionalHeader.AddressOfEntryPoint;
-  Offset = 0;
+  AddressOfEntryPoint = UefiImageGetEntryPointAddress (pImageContext);
 
   //
   // module information output
@@ -848,11 +847,18 @@ Returns:
     fprintf (FvMapFile, "BaseAddress=%010llx, ", (unsigned long long) ImageBaseAddress);
   } else {
     fprintf (FvMapFile, "%s (Fixed Flash Address, ", KeyWord);
-    fprintf (FvMapFile, "BaseAddress=0x%010llx, ", (unsigned long long) (ImageBaseAddress + Offset));
+    fprintf (FvMapFile, "BaseAddress=0x%010llx, ", (unsigned long long) ImageBaseAddress);
   }
 
+  Format = UefiImageGetFormat (pImageContext);
+
   fprintf (FvMapFile, "EntryPoint=0x%010llx, ", (unsigned long long) (ImageBaseAddress + AddressOfEntryPoint));
-  fprintf (FvMapFile, "Type=PE");
+  if (Format == UefiImageFormatPe) {
+    fprintf (FvMapFile, "Type=PE");
+  } else {
+    assert (FALSE);
+    fprintf (FvMapFile, "Type=Unknown");
+  }
   fprintf (FvMapFile, ")\n");
 
   fprintf (FvMapFile, "(GUID=%s)\n\n", FileGuidName);
@@ -1269,7 +1275,7 @@ Returns:
         return EFI_ABORTED;
       }
       //
-      // Rebase the PE image in FileBuffer of FFS file for XIP
+      // Rebase the UEFI image in FileBuffer of FFS file for XIP
       // Rebase for the debug genfvmap tool
       //
       Status = FfsRebase (FvInfo, FvInfo->FvFiles[Index], (EFI_FFS_FILE_HEADER **)&FileBuffer, &FileSize, (UINTN) *VtfFileImage - (UINTN) FvImage->FileImage, FvMapFile);
@@ -1321,7 +1327,7 @@ Returns:
   //
   if ((UINTN) (FvImage->CurrentFilePointer + FileSize) <= (UINTN) (*VtfFileImage)) {
     //
-    // Rebase the PE image in FileBuffer of FFS file for XIP.
+    // Rebase the UEFI image in FileBuffer of FFS file for XIP.
     // Rebase Bs and Rt drivers for the debug genfvmap tool.
     //
     Status = FfsRebase (FvInfo, FvInfo->FvFiles[Index], (EFI_FFS_FILE_HEADER **)&FileBuffer, &FileSize, (UINTN) FvImage->CurrentFilePointer - (UINTN) FvImage->FileImage, FvMapFile);
@@ -1558,14 +1564,15 @@ Returns:
   }
 
   SecHeaderSize = GetSectionHeaderLength(Pe32Section.CommonHeader);
-  Status = GetPe32Info (
+  Status = GetUefiImageInfo (
             (VOID *) ((UINTN) Pe32Section.Pe32Section + SecHeaderSize),
+            GetSectionFileLength (Pe32Section.CommonHeader) - SecHeaderSize,
             &EntryPoint,
             &MachineType
             );
 
   if (EFI_ERROR (Status)) {
-    Error (NULL, 0, 3000, "Invalid", "could not get the PE32 entry point for the SEC core.");
+    Error (NULL, 0, 3000, "Invalid", "could not get the UEFI image entry point for the SEC core.");
     return EFI_ABORTED;
   }
 
@@ -1583,7 +1590,7 @@ Returns:
   }
 
   //
-  // Physical address is FV base + offset of PE32 + offset of the entry point
+  // Physical address is FV base + offset of UEFI image + offset of the entry point
   //
   SecCorePhysicalAddress = FvInfo->BaseAddress;
   SecCorePhysicalAddress += (UINTN) Pe32Section.Pe32Section + SecHeaderSize - (UINTN) FvImage->FileImage;
@@ -1606,18 +1613,19 @@ Returns:
     }
 
     SecHeaderSize = GetSectionHeaderLength(Pe32Section.CommonHeader);
-    Status = GetPe32Info (
+    Status = GetUefiImageInfo (
               (VOID *) ((UINTN) Pe32Section.Pe32Section + SecHeaderSize),
+              GetSectionFileLength (Pe32Section.CommonHeader) - SecHeaderSize,
               &EntryPoint,
               &MachineType
               );
 
     if (EFI_ERROR (Status)) {
-      Error (NULL, 0, 3000, "Invalid", "could not get the PE32 entry point for the PEI core.");
+      Error (NULL, 0, 3000, "Invalid", "could not get the UEFI image entry point for the PEI core.");
       return EFI_ABORTED;
     }
     //
-    // Physical address is FV base + offset of PE32 + offset of the entry point
+    // Physical address is FV base + offset of UEFI image + offset of the entry point
     //
     PeiCorePhysicalAddress = FvInfo->BaseAddress;
     PeiCorePhysicalAddress += (UINTN) Pe32Section.Pe32Section + SecHeaderSize - (UINTN) FvImage->FileImage;
@@ -1851,13 +1859,14 @@ Returns:
     return EFI_INVALID_PARAMETER;
   }
 
-  Status = GetPe32Info(
+  Status = GetUefiImageInfo(
     (VOID *)((UINTN)Pe32Section.Pe32Section + GetSectionHeaderLength(Pe32Section.CommonHeader)),
+    GetSectionFileLength (Pe32Section.CommonHeader) - GetSectionHeaderLength(Pe32Section.CommonHeader),
     &EntryPoint,
     CoreMachineType
     );
   if (EFI_ERROR(Status)) {
-    Error(NULL, 0, 3000, "Invalid", "could not get the PE32 machine type for the core.");
+    Error(NULL, 0, 3000, "Invalid", "could not get the UEFI image machine type for the core.");
     return EFI_ABORTED;
   }
 
@@ -1881,7 +1890,7 @@ Arguments:
 
   FvImageBuffer     Pointer to buffer containing FV data
   FvInfo            Info for the parent FV
-  Pe32Section       PE32 section data
+  Pe32Section       UEFI image section data
   CoreEntryAddress  The extracted core entry physical address
 
 Returns:
@@ -1901,18 +1910,19 @@ Returns:
     return EFI_INVALID_PARAMETER;
   }
 
-  Status = GetPe32Info(
+  Status = GetUefiImageInfo(
     (VOID *)((UINTN)Pe32Section.Pe32Section + GetSectionHeaderLength(Pe32Section.CommonHeader)),
+    GetSectionFileLength (Pe32Section.CommonHeader) - GetSectionHeaderLength(Pe32Section.CommonHeader),
     &EntryPoint,
     &MachineType
     );
   if (EFI_ERROR(Status)) {
-    Error(NULL, 0, 3000, "Invalid", "could not get the PE32 entry point for the core.");
+    Error(NULL, 0, 3000, "Invalid", "could not get the UEFI image entry point for the core.");
     return EFI_ABORTED;
   }
 
   //
-  // Physical address is FV base + offset of PE32 + offset of the entry point
+  // Physical address is FV base + offset of UEFI image + offset of the entry point
   //
   EntryPhysicalAddress = FvInfo->BaseAddress;
   EntryPhysicalAddress += (UINTN)Pe32Section.Pe32Section + GetSectionHeaderLength(Pe32Section.CommonHeader) - (UINTN)FvImageBuffer;
@@ -1998,13 +2008,13 @@ Returns:
 
     Status = GetCoreMachineType(SecPe32, &MachineType);
     if (EFI_ERROR(Status)) {
-      Error(NULL, 0, 3000, "Invalid", "Could not get the PE32 machine type for SEC Core.");
+      Error(NULL, 0, 3000, "Invalid", "Could not get the UEFI image machine type for SEC Core.");
       return EFI_ABORTED;
     }
 
     Status = GetCoreEntryPointAddress(FvImage->FileImage, FvInfo, SecPe32, &SecCoreEntryAddress);
     if (EFI_ERROR(Status)) {
-      Error(NULL, 0, 3000, "Invalid", "Could not get the PE32 entry point address for SEC Core.");
+      Error(NULL, 0, 3000, "Invalid", "Could not get the UEFI image entry point address for SEC Core.");
       return EFI_ABORTED;
     }
 
@@ -2020,13 +2030,13 @@ Returns:
 
     Status = GetCoreMachineType(PeiPe32, &PeiMachineType);
     if (EFI_ERROR(Status)) {
-      Error(NULL, 0, 3000, "Invalid", "Could not get the PE32 machine type for PEI Core.");
+      Error(NULL, 0, 3000, "Invalid", "Could not get the UEFI image machine type for PEI Core.");
       return EFI_ABORTED;
     }
 
     Status = GetCoreEntryPointAddress(FvImage->FileImage, FvInfo, PeiPe32, &PeiCoreEntryAddress);
     if (EFI_ERROR(Status)) {
-      Error(NULL, 0, 3000, "Invalid", "Could not get the PE32 entry point address for PEI Core.");
+      Error(NULL, 0, 3000, "Invalid", "Could not get the UEFI image entry point address for PEI Core.");
       return EFI_ABORTED;
     }
 
@@ -2217,7 +2227,7 @@ Returns:
 
   Status = GetCoreMachineType(SecPe32, &MachineType);
   if(EFI_ERROR(Status)) {
-    Error(NULL, 0, 3000, "Invalid", "Could not get the PE32 machine type for SEC core.");
+    Error(NULL, 0, 3000, "Invalid", "Could not get the UEFI image machine type for SEC core.");
     return EFI_ABORTED;
   }
 
@@ -2228,7 +2238,7 @@ Returns:
 
   Status = GetCoreEntryPointAddress(FvImage->FileImage, FvInfo, SecPe32, &SecCoreEntryAddress);
   if(EFI_ERROR(Status)) {
-    Error(NULL, 0, 3000, "Invalid", "Could not get the PE32 entry point address for SEC Core.");
+    Error(NULL, 0, 3000, "Invalid", "Could not get the UEFI image entry point address for SEC Core.");
     return EFI_ABORTED;
   }
 
@@ -2306,13 +2316,13 @@ Returns:
 
     Status = GetCoreMachineType(SecPe32, &MachineType);
     if (EFI_ERROR(Status)) {
-      Error(NULL, 0, 3000, "Invalid", "Could not get the PE32 machine type for SEC Core.");
+      Error(NULL, 0, 3000, "Invalid", "Could not get the UEFI image machine type for SEC Core.");
       return EFI_ABORTED;
     }
 
     Status = GetCoreEntryPointAddress(FvImage->FileImage, FvInfo, SecPe32, &SecCoreEntryAddress);
     if (EFI_ERROR(Status)) {
-      Error(NULL, 0, 3000, "Invalid", "Could not get the PE32 entry point address for SEC Core.");
+      Error(NULL, 0, 3000, "Invalid", "Could not get the UEFI image entry point address for SEC Core.");
       return EFI_ABORTED;
     }
 
@@ -2349,8 +2359,9 @@ Returns:
 }
 
 EFI_STATUS
-GetPe32Info (
-  IN UINT8                  *Pe32,
+GetUefiImageInfo (
+  IN UINT8                  *UefiImage,
+  IN  UINT32                UefiImageSize,
   OUT UINT32                *EntryPoint,
   OUT UINT16                *MachineType
   )
@@ -2358,14 +2369,15 @@ GetPe32Info (
 
 Routine Description:
 
-  Retrieves the PE32 entry point offset and machine type from PE image or TeImage.
+  Retrieves the UEFI image entry point offset and machine type from UEFI image.
   See EfiImage.h for machine types.  The entry point offset is from the beginning
-  of the PE32 buffer passed in.
+  of the UEFI image buffer passed in.
 
 Arguments:
 
-  Pe32          Beginning of the PE32.
-  EntryPoint    Offset from the beginning of the PE32 to the image entry point.
+  UefiImage     Beginning of the UEFI image.
+  UefiImageSize The size, in bytes, of UefiImage.
+  EntryPoint    Offset from the beginning of the UEFI image to the image entry point.
   MachineType   Magic number for the machine type.
 
 Returns:
@@ -2377,46 +2389,23 @@ Returns:
 
 --*/
 {
-  EFI_IMAGE_DOS_HEADER             *DosHeader;
-  EFI_IMAGE_OPTIONAL_HEADER_UNION  *ImgHdr;
+  UEFI_IMAGE_LOADER_IMAGE_CONTEXT Context;
 
   //
   // Verify input parameters
   //
-  if (Pe32 == NULL) {
+  if (UefiImage == NULL) {
     return EFI_INVALID_PARAMETER;
   }
 
-  //
-  // Check whether
-  // First is the DOS header
-  //
-  DosHeader = (EFI_IMAGE_DOS_HEADER *) Pe32;
-
-  //
-  // Verify DOS header is expected
-  //
-  if (DosHeader->e_magic != EFI_IMAGE_DOS_SIGNATURE) {
-    Error (NULL, 0, 3000, "Invalid", "Unknown magic number in the DOS header, 0x%04X.", DosHeader->e_magic);
-    return EFI_UNSUPPORTED;
+  RETURN_STATUS Status = UefiImageInitializeContext (&Context, UefiImage, UefiImageSize);
+  if (RETURN_ERROR (Status)) {
+    Error (NULL, 0, 3000, "Invalid", "Unrecognized UEFI image file.");
+    return Status;
   }
-  //
-  // Immediately following is the NT header.
-  //
-  ImgHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *) ((UINTN) Pe32 + DosHeader->e_lfanew);
 
-  //
-  // Verify NT header is expected
-  //
-  if (ImgHdr->Pe32.Signature != EFI_IMAGE_NT_SIGNATURE) {
-    Error (NULL, 0, 3000, "Invalid", "Unrecognized image signature 0x%08X.", (unsigned) ImgHdr->Pe32.Signature);
-    return EFI_UNSUPPORTED;
-  }
-  //
-  // Get output
-  //
-  *EntryPoint   = ImgHdr->Pe32.OptionalHeader.AddressOfEntryPoint;
-  *MachineType  = ImgHdr->Pe32.FileHeader.Machine;
+  *EntryPoint  = UefiImageGetEntryPointAddress (&Context);
+  *MachineType = UefiImageGetMachine (&Context);
 
   //
   // Verify machine type is supported
@@ -2424,7 +2413,7 @@ Returns:
   if ((*MachineType != IMAGE_FILE_MACHINE_I386) &&  (*MachineType != IMAGE_FILE_MACHINE_X64) && (*MachineType != IMAGE_FILE_MACHINE_EBC) &&
       (*MachineType != IMAGE_FILE_MACHINE_ARMTHUMB_MIXED) && (*MachineType != IMAGE_FILE_MACHINE_ARM64) &&
       (*MachineType != IMAGE_FILE_MACHINE_RISCV64) && (*MachineType != IMAGE_FILE_MACHINE_LOONGARCH64)) {
-    Error (NULL, 0, 3000, "Invalid", "Unrecognized machine type in the PE32 file.");
+    Error (NULL, 0, 3000, "Invalid", "Unrecognized machine type in the UEFI image file.");
     return EFI_UNSUPPORTED;
   }
 
@@ -3272,50 +3261,6 @@ Returns:
   return EFI_SUCCESS;
 }
 
-EFI_STATUS
-EFIAPI
-FfsRebaseImageRead (
-  IN     VOID    *FileHandle,
-  IN     UINTN   FileOffset,
-  IN OUT UINT32  *ReadSize,
-  OUT    VOID    *Buffer
-  )
-/*++
-
-Routine Description:
-
-  Support routine for the PE/COFF Loader that reads a buffer from a PE/COFF file
-
-Arguments:
-
-  FileHandle - The handle to the PE/COFF file
-
-  FileOffset - The offset, in bytes, into the file to read
-
-  ReadSize   - The number of bytes to read from the file starting at FileOffset
-
-  Buffer     - A pointer to the buffer to read the data into.
-
-Returns:
-
-  EFI_SUCCESS - ReadSize bytes of data were read into Buffer from the PE/COFF file starting at FileOffset
-
---*/
-{
-  CHAR8   *Destination8;
-  CHAR8   *Source8;
-  UINT32  Length;
-
-  Destination8  = Buffer;
-  Source8       = (CHAR8 *) ((UINTN) FileHandle + FileOffset);
-  Length        = *ReadSize;
-  while (Length--) {
-    *(Destination8++) = *(Source8++);
-  }
-
-  return EFI_SUCCESS;
-}
-
 EFI_STATUS
 GetChildFvFromFfs (
   IN      FV_INFO               *FvInfo,
@@ -3369,7 +3314,7 @@ Returns:
     if (!EFI_ERROR(Status)) {
       Status = GetCoreMachineType(CorePe32, &MachineType);
       if (EFI_ERROR(Status)) {
-        Error(NULL, 0, 3000, "Invalid", "Could not get the PE32 machine type for SEC/PEI Core.");
+        Error(NULL, 0, 3000, "Invalid", "Could not get the UEFI image machine type for SEC/PEI Core.");
         return EFI_ABORTED;
       }
 
@@ -3528,32 +3473,40 @@ Returns:
 --*/
 {
   EFI_STATUS                            Status;
-  PE_COFF_LOADER_IMAGE_CONTEXT          ImageContext;
-  PE_COFF_LOADER_IMAGE_CONTEXT          OrigImageContext;
+  UEFI_IMAGE_LOADER_IMAGE_CONTEXT       ImageContext;
+  UINT16                                Machine;
   EFI_PHYSICAL_ADDRESS                  XipBase;
-  EFI_PHYSICAL_ADDRESS                  NewPe32BaseAddress;
+  EFI_PHYSICAL_ADDRESS                  NewBaseAddress;
   UINTN                                 Index;
   EFI_FILE_SECTION_POINTER              CurrentPe32Section;
   EFI_FFS_FILE_STATE                    SavedState;
-  EFI_IMAGE_OPTIONAL_HEADER_UNION       *ImgHdr;
-  UINT8                                 *MemoryImagePointer;
-  EFI_IMAGE_SECTION_HEADER              *SectionHeader;
-  CHAR8                                 PeFileName [MAX_LONG_FILE_PATH];
+  CHAR8                                 UefiImageFileName [MAX_LONG_FILE_PATH];
   CHAR8                                 *Cptr;
-  FILE                                  *PeFile;
-  UINT8                                 *PeFileBuffer;
-  UINT32                                PeFileSize;
-  CHAR8                                 *PdbPointer;
+  FILE                                  *UefiImageFile;
+  UINT8                                 *UefiImageFileBuffer;
+  UINT32                                UefiImageFileSize;
+  BOOLEAN                               FreeUefiImageFile;
+  CONST CHAR8                           *SymbolsPath;
+  UINT32                                SymbolsPathSize;
+  CHAR8                                 *SymbolsPathCpy;
   UINT32                                FfsHeaderSize;
   UINT32                                CurSecHdrSize;
+  UINT32                                SectPeSize;
+  UINT32                                ImageSize;
+  UINT32                                DestinationPages;
+  UINT32                                DestinationSize;
+  UINT32                                ImageAlignment;
+  VOID                                  *Destination;
+  BOOLEAN                               Strip;
+  UINT8                                 ImageFormat;
+  UINT32                                RebasedImageSize;
+  VOID                                  *RebasedImage;
 
-  Index              = 0;
-  MemoryImagePointer = NULL;
-  ImgHdr             = NULL;
-  SectionHeader      = NULL;
-  Cptr               = NULL;
-  PeFile             = NULL;
-  PeFileBuffer       = NULL;
+  Index               = 0;
+  Cptr                = NULL;
+  UefiImageFile       = NULL;
+  UefiImageFileBuffer = NULL;
+  FreeUefiImageFile   = FALSE;
 
   //
   // Don't need to relocate image when BaseAddress is zero and no ForceRebase Flag specified.
@@ -3571,6 +3524,8 @@ Returns:
 
   XipBase = FvInfo->BaseAddress + XipOffset;
 
+  Strip = FALSE;
+
   //
   // We only process files potentially containing PE32 sections.
   //
@@ -3605,7 +3560,7 @@ Returns:
     //
     // Init Value
     //
-    NewPe32BaseAddress = 0;
+    NewBaseAddress = 0;
 
     //
     // Find Pe Image
@@ -3619,140 +3574,76 @@ Returns:
     //
     // Initialize context
     //
-    memset (&ImageContext, 0, sizeof (ImageContext));
-    ImageContext.Handle     = (VOID *) ((UINTN) CurrentPe32Section.Pe32Section + CurSecHdrSize);
-    ImageContext.ImageRead  = (PE_COFF_LOADER_READ_FILE) FfsRebaseImageRead;
-    Status                  = PeCoffLoaderGetImageInfo (&ImageContext);
+    SectPeSize = GetSectionFileLength (CurrentPe32Section.CommonHeader) - CurSecHdrSize;
+    Status = UefiImageInitializeContext (
+               &ImageContext,
+               (VOID *) ((UINTN) CurrentPe32Section.Pe32Section + CurSecHdrSize),
+               SectPeSize
+               );
     if (EFI_ERROR (Status)) {
-      Error (NULL, 0, 3000, "Invalid PeImage", "The input file is %s and the return status is %x", FileName, (int) Status);
+      Error (NULL, 0, 3000, "Invalid UefiImage", "The input file is %s and the return status is %x", FileName, (int) Status);
       return Status;
     }
 
-    if ( (ImageContext.Machine == IMAGE_FILE_MACHINE_ARMTHUMB_MIXED) ||
-         (ImageContext.Machine == IMAGE_FILE_MACHINE_ARM64) ) {
+    Machine = UefiImageGetMachine (&ImageContext);
+
+    if ( (Machine == IMAGE_FILE_MACHINE_ARMTHUMB_MIXED) ||
+         (Machine == IMAGE_FILE_MACHINE_AARCH64) ) {
       mArm = TRUE;
     }
 
-    if (ImageContext.Machine == IMAGE_FILE_MACHINE_RISCV64) {
+    if (Machine == IMAGE_FILE_MACHINE_RISCV64) {
       mRiscV = TRUE;
     }
 
-    if (ImageContext.Machine == IMAGE_FILE_MACHINE_LOONGARCH64) {
+    if (Machine == IMAGE_FILE_MACHINE_LOONGARCH64) {
       mLoongArch = TRUE;
     }
 
+    ImageFormat = UefiImageGetFormat (&ImageContext);
+
+    ImageSize        = UefiImageGetImageSize (&ImageContext);
+    DestinationPages = EFI_SIZE_TO_PAGES (ImageSize);
+    DestinationSize  = EFI_PAGES_TO_SIZE (DestinationPages);
+    ImageAlignment   = UefiImageGetSegmentAlignment (&ImageContext);
+    Destination      = AllocateAlignedCodePages (DestinationPages, ImageAlignment);
+    if (Destination == NULL) {
+      return EFI_OUT_OF_RESOURCES;
+    }
+
+    Status = UefiImageLoadImage (&ImageContext, Destination, DestinationSize);
+    if (EFI_ERROR (Status)) {
+      return Status;
+    }
+
+    SymbolsPathCpy = NULL;
     //
-    // Keep Image Context for PE image in FV
+    // Get File SymbolsPath
     //
-    memcpy (&OrigImageContext, &ImageContext, sizeof (ImageContext));
+    Status = UefiImageGetSymbolsPath (&ImageContext, &SymbolsPath, &SymbolsPathSize);
+    if (!RETURN_ERROR (Status)) {
+      SymbolsPathCpy = malloc (SymbolsPathSize);
+      if (SymbolsPathCpy == NULL) {
+        FreeAlignedPages (Destination, DestinationPages);
+        return EFI_OUT_OF_RESOURCES;
+      }
+
+      memmove (SymbolsPathCpy, SymbolsPath, SymbolsPathSize);
+    }
+
+    FreeAlignedPages (Destination, DestinationPages);
 
     //
-    // Get File PdbPointer
-    //
-    PdbPointer = PeCoffLoaderGetPdbPointer (ImageContext.Handle);
-
-    //
-    // Get PeHeader pointer
-    //
-    ImgHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)((UINTN) CurrentPe32Section.Pe32Section + CurSecHdrSize + ImageContext.PeCoffHeaderOffset);
-
-    //
-    // Calculate the PE32 base address, based on file type
+    // Calculate the UEFI image base address, based on file type
     //
     switch ((*FfsFile)->Type) {
       case EFI_FV_FILETYPE_SECURITY_CORE:
       case EFI_FV_FILETYPE_PEI_CORE:
       case EFI_FV_FILETYPE_PEIM:
       case EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER:
-        //
-        // Check if section-alignment and file-alignment match or not
-        //
-        if ((ImgHdr->Pe32.OptionalHeader.SectionAlignment != ImgHdr->Pe32.OptionalHeader.FileAlignment)) {
-          //
-          // Xip module has the same section alignment and file alignment.
-          //
-          Error (NULL, 0, 3000, "Invalid", "PE image Section-Alignment and File-Alignment do not match : %s.", FileName);
-          return EFI_ABORTED;
-        }
-        //
-        // PeImage has no reloc section. It will try to get reloc data from the original EFI image.
-        //
-        if (ImageContext.RelocationsStripped) {
-          //
-          // Construct the original efi file Name
-          //
-          if (strlen (FileName) >= MAX_LONG_FILE_PATH) {
-            Error (NULL, 0, 2000, "Invalid", "The file name %s is too long.", FileName);
-            return EFI_ABORTED;
-          }
-          strncpy (PeFileName, FileName, MAX_LONG_FILE_PATH - 1);
-          PeFileName[MAX_LONG_FILE_PATH - 1] = 0;
-          Cptr = PeFileName + strlen (PeFileName);
-          while (*Cptr != '.') {
-            Cptr --;
-          }
-          if (*Cptr != '.') {
-            Error (NULL, 0, 3000, "Invalid", "The file %s has no .reloc section.", FileName);
-            return EFI_ABORTED;
-          } else {
-            *(Cptr + 1) = 'e';
-            *(Cptr + 2) = 'f';
-            *(Cptr + 3) = 'i';
-            *(Cptr + 4) = '\0';
-          }
-          PeFile = fopen (LongFilePath (PeFileName), "rb");
-          if (PeFile == NULL) {
-            Warning (NULL, 0, 0, "Invalid", "The file %s has no .reloc section.", FileName);
-            //Error (NULL, 0, 3000, "Invalid", "The file %s has no .reloc section.", FileName);
-            //return EFI_ABORTED;
-            break;
-          }
-          //
-          // Get the file size
-          //
-          PeFileSize = _filelength (fileno (PeFile));
-          PeFileBuffer = (UINT8 *) malloc (PeFileSize);
-          if (PeFileBuffer == NULL) {
-            fclose (PeFile);
-            Error (NULL, 0, 4001, "Resource", "memory cannot be allocated on rebase of %s", FileName);
-            return EFI_OUT_OF_RESOURCES;
-          }
-          //
-          // Read Pe File
-          //
-          fread (PeFileBuffer, sizeof (UINT8), PeFileSize, PeFile);
-          //
-          // close file
-          //
-          fclose (PeFile);
-          //
-          // Handle pointer to the original efi image.
-          //
-          ImageContext.Handle = PeFileBuffer;
-          Status              = PeCoffLoaderGetImageInfo (&ImageContext);
-          if (EFI_ERROR (Status)) {
-            Error (NULL, 0, 3000, "Invalid PeImage", "The input file is %s and the return status is %x", FileName, (int) Status);
-            return Status;
-          }
-          ImageContext.RelocationsStripped = FALSE;
-        }
-
-        NewPe32BaseAddress = XipBase + (UINTN) CurrentPe32Section.Pe32Section + CurSecHdrSize - (UINTN)(*FfsFile);
-        break;
-
       case EFI_FV_FILETYPE_DRIVER:
       case EFI_FV_FILETYPE_DXE_CORE:
-        //
-        // Check if section-alignment and file-alignment match or not
-        //
-        if ((ImgHdr->Pe32.OptionalHeader.SectionAlignment != ImgHdr->Pe32.OptionalHeader.FileAlignment)) {
-          //
-          // Xip module has the same section alignment and file alignment.
-          //
-          Error (NULL, 0, 3000, "Invalid", "PE image Section-Alignment and File-Alignment do not match : %s.", FileName);
-          return EFI_ABORTED;
-        }
-        NewPe32BaseAddress = XipBase + (UINTN) CurrentPe32Section.Pe32Section + CurSecHdrSize - (UINTN)(*FfsFile);
+        NewBaseAddress = XipBase + (UINTN) CurrentPe32Section.Pe32Section + CurSecHdrSize - (UINTN)(*FfsFile);
         break;
 
       default:
@@ -3762,97 +3653,122 @@ Returns:
         return EFI_SUCCESS;
     }
 
-    //
-    // Relocation doesn't exist
-    //
-    if (ImageContext.RelocationsStripped) {
-      Warning (NULL, 0, 0, "Invalid", "The file %s has no .reloc section.", FileName);
-      continue;
-    }
+    Strip = UefiImageGetRelocsStripped (&ImageContext);
 
-    //
-    // Relocation exist and rebase
-    //
-    //
-    // Load and Relocate Image Data
-    //
-    MemoryImagePointer = (UINT8 *) calloc (1, (UINTN)ImageContext.ImageSize + ImageContext.SectionAlignment);
-    if (MemoryImagePointer == NULL) {
-      Error (NULL, 0, 4001, "Resource", "memory cannot be allocated on rebase of %s", FileName);
-      return EFI_OUT_OF_RESOURCES;
-    }
-    ImageContext.ImageAddress = ALIGN_VALUE ((UINTN)MemoryImagePointer, ImageContext.SectionAlignment);
-
-    if (!(IS_ALIGNED (NewPe32BaseAddress, ImageContext.SectionAlignment))) {
-      Status = AddPadSection (&NewPe32BaseAddress, ImageContext.SectionAlignment, FfsFile, FileSize, &CurrentPe32Section);
+    if (!(IS_ALIGNED (NewBaseAddress, ImageAlignment))) {
+      Status = AddPadSection (&NewBaseAddress, ImageAlignment, FfsFile, FileSize, &CurrentPe32Section);
       if (EFI_ERROR (Status)) {
-        free ((VOID *) MemoryImagePointer);
         return Status;
       }
 
-      CurSecHdrSize       = GetSectionHeaderLength (CurrentPe32Section.CommonHeader);
-      ImageContext.Handle = (VOID *) ((UINTN) CurrentPe32Section.Pe32Section + CurSecHdrSize);
-      PdbPointer          = PeCoffLoaderGetPdbPointer (ImageContext.Handle);
+      CurSecHdrSize = GetSectionHeaderLength (CurrentPe32Section.CommonHeader);
 
-      ImgHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)((UINTN) CurrentPe32Section.Pe32Section + CurSecHdrSize + ImageContext.PeCoffHeaderOffset);
+      SectPeSize = GetSectionFileLength (CurrentPe32Section.CommonHeader) - CurSecHdrSize;
     }
 
-    Status = PeCoffLoaderLoadImage (&ImageContext);
-    if (EFI_ERROR (Status)) {
-      Error (NULL, 0, 3000, "Invalid", "LocateImage() call failed on rebase of %s", FileName);
-      free ((VOID *) MemoryImagePointer);
-      return Status;
-    }
+    UefiImageFileBuffer = (VOID *) ((UINTN) CurrentPe32Section.Pe32Section + CurSecHdrSize);
+    UefiImageFileSize   = SectPeSize;
+    //
+    // UefiImage has no reloc section. It will try to get reloc data from the original UEFI image.
+    //
+    if (Strip) {
+      //
+      // Construct the original efi file Name
+      //
+      if (strlen (FileName) >= MAX_LONG_FILE_PATH) {
+        Error (NULL, 0, 2000, "Invalid", "The file name %s is too long.", FileName);
+        return EFI_ABORTED;
+      }
+      strncpy (UefiImageFileName, FileName, MAX_LONG_FILE_PATH - 1);
+      UefiImageFileName[MAX_LONG_FILE_PATH - 1] = 0;
+      Cptr = UefiImageFileName + strlen (UefiImageFileName);
+      while (*Cptr != '.') {
+        Cptr --;
+      }
+      if (*Cptr != '.') {
+        Error (NULL, 0, 3000, "Invalid", "The file %s has no .reloc section.", FileName);
+        return EFI_ABORTED;
+      } else {
+        *(Cptr + 1) = 'e';
+        *(Cptr + 2) = 'f';
+        *(Cptr + 3) = 'i';
+        *(Cptr + 4) = '\0';
+      }
+      UefiImageFile = fopen (LongFilePath (UefiImageFileName), "rb");
+      if (UefiImageFile == NULL) {
+        Warning (NULL, 0, 0, "Invalid", "The file %s has no .reloc section.", FileName);
+        //Error (NULL, 0, 3000, "Invalid", "The file %s has no .reloc section.", FileName);
+        //return EFI_ABORTED;
+        break;
+      }
+      //
+      // Get the file size
+      //
+      UefiImageFileSize = _filelength (fileno (UefiImageFile));
+      UefiImageFileBuffer = (UINT8 *) malloc (UefiImageFileSize);
+      if (UefiImageFileBuffer == NULL) {
+        fclose (UefiImageFile);
+        Error (NULL, 0, 4001, "Resource", "memory cannot be allocated on rebase of %s", FileName);
+        return EFI_OUT_OF_RESOURCES;
+      }
 
-    ImageContext.DestinationAddress = NewPe32BaseAddress;
-
-    Status = PeCoffLoaderRelocateImage (&ImageContext);
-    if (EFI_ERROR (Status)) {
-      Error (NULL, 0, 3000, "Invalid", "RelocateImage() call failed on rebase of %s Status=%d", FileName, Status);
-      free ((VOID *) MemoryImagePointer);
-      return Status;
+      FreeUefiImageFile = TRUE;
+      //
+      // Read Pe File
+      //
+      fread (UefiImageFileBuffer, sizeof (UINT8), UefiImageFileSize, UefiImageFile);
+      //
+      // close file
+      //
+      fclose (UefiImageFile);
     }
 
     //
-    // Copy Relocated data to raw image file.
+    // Load and Relocate Image Data
     //
-    SectionHeader = (EFI_IMAGE_SECTION_HEADER *) (
-                       (UINTN) ImgHdr +
-                       sizeof (UINT32) +
-                       sizeof (EFI_IMAGE_FILE_HEADER) +
-                       ImgHdr->Pe32.FileHeader.SizeOfOptionalHeader
-                       );
+    RebasedImage = ToolImageEmit (
+                     &RebasedImageSize,
+                     UefiImageFileBuffer,
+                     UefiImageFileSize,
+                     ImageFormat,
+                     -1,
+                     NULL,
+                     0,
+                     true,
+                     NewBaseAddress,
+                     NULL,
+                     Strip,
+                     FALSE
+                     );
 
-    for (Index = 0; Index < ImgHdr->Pe32.FileHeader.NumberOfSections; Index ++, SectionHeader ++) {
-      CopyMem (
-        (UINT8 *) CurrentPe32Section.Pe32Section + CurSecHdrSize + SectionHeader->PointerToRawData,
-        (VOID*) (UINTN) (ImageContext.ImageAddress + SectionHeader->VirtualAddress),
-        SectionHeader->SizeOfRawData
-        );
+    if (FreeUefiImageFile) {
+      free (UefiImageFileBuffer);
     }
 
-    free ((VOID *) MemoryImagePointer);
-    MemoryImagePointer = NULL;
-    if (PeFileBuffer != NULL) {
-      free (PeFileBuffer);
-      PeFileBuffer = NULL;
+    if (RebasedImage == NULL) {
+      Error (NULL, 0, 4001, "Invalid", "failed to rebase (%s)", FileName);
+      return EFI_UNSUPPORTED;
     }
 
-    //
-    // Update Image Base Address
-    //
-    if (ImgHdr->Pe32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
-      ImgHdr->Pe32.OptionalHeader.ImageBase = (UINT32) NewPe32BaseAddress;
-    } else if (ImgHdr->Pe32Plus.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) {
-      ImgHdr->Pe32Plus.OptionalHeader.ImageBase = NewPe32BaseAddress;
-    } else {
-      Error (NULL, 0, 3000, "Invalid", "unknown PE magic signature %X in PE32 image %s",
-        ImgHdr->Pe32.OptionalHeader.Magic,
-        FileName
-        );
-      return EFI_ABORTED;
+    UefiImageFileBuffer = NULL;
+    UefiImageFileSize   = 0;
+
+    if (RebasedImageSize > SectPeSize) {
+      Error (NULL, 0, 4001, "Invalid", "rebased file is too large (%s)", FileName);
+      return EFI_UNSUPPORTED;
     }
 
+    memmove (
+      (UINT8 *)CurrentPe32Section.Pe32Section + CurSecHdrSize,
+      RebasedImage,
+      RebasedImageSize
+      );
+    memset (
+      (UINT8 *)CurrentPe32Section.Pe32Section + CurSecHdrSize + RebasedImageSize,
+      0,
+      SectPeSize - RebasedImageSize
+      );
+
     //
     // Now update file checksum
     //
@@ -3871,14 +3787,25 @@ Returns:
     // Get this module function address from ModulePeMapFile and add them into FvMap file
     //
 
+    Status = UefiImageInitializeContext (
+      &ImageContext,
+      (VOID *) ((UINTN) CurrentPe32Section.Pe32Section + CurSecHdrSize),
+      RebasedImageSize
+      );
+    ASSERT_EFI_ERROR (Status);
+
     //
     // Default use FileName as map file path
     //
-    if (PdbPointer == NULL) {
-      PdbPointer = FileName;
-    }
+    WriteMapFile (
+      FvMapFile,
+      SymbolsPathCpy != NULL ? SymbolsPathCpy : FileName,
+      *FfsFile,
+      NewBaseAddress,
+      &ImageContext
+      );
 
-    WriteMapFile (FvMapFile, PdbPointer, *FfsFile, NewPe32BaseAddress, &ImageContext);
+    free (SymbolsPathCpy);
   }
 
   return EFI_SUCCESS;
diff --git a/BaseTools/Source/C/GenFv/GenFvInternalLib.h b/BaseTools/Source/C/GenFv/GenFvInternalLib.h
index dc6b2aca91..ff668f385b 100644
--- a/BaseTools/Source/C/GenFv/GenFvInternalLib.h
+++ b/BaseTools/Source/C/GenFv/GenFvInternalLib.h
@@ -22,7 +22,6 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
 #include <Common/PiFirmwareVolume.h>
 #include <Guid/FirmwareFileSystem2.h>
 #include <Guid/FirmwareFileSystem3.h>
-#include <Common/PeImageEx.h>
 
 #include "CommonLib.h"
 #include "ParseInf.h"
@@ -304,8 +303,9 @@ Returns:
 ;
 
 EFI_STATUS
-GetPe32Info (
-  IN UINT8                  *Pe32,
+GetUefiImageInfo (
+  IN UINT8                  *UefiImage,
+  IN  UINT32                UefiImageSize,
   OUT UINT32                *EntryPoint,
   OUT UINT16                *MachineType
   );
diff --git a/BaseTools/Source/C/GenSec/GenSec.c b/BaseTools/Source/C/GenSec/GenSec.c
index d585d10cd5..3965f9bdac 100644
--- a/BaseTools/Source/C/GenSec/GenSec.c
+++ b/BaseTools/Source/C/GenSec/GenSec.c
@@ -24,7 +24,6 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
 #include <Common/UefiBaseTypes.h>
 #include <Common/PiFirmwareFile.h>
 #include <Common/GuidedSectionExtractionEx.h>
-#include <Common/PeImageEx.h>
 
 #include "CommonLib.h"
 #include "Compress.h"
@@ -32,7 +31,6 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
 #include "EfiUtilityMsgs.h"
 #include "ParseInf.h"
 #include "FvLib.h"
-#include "PeCoffLib.h"
 
 //
 // GenSec Tool Information
@@ -1127,104 +1125,6 @@ Returns:
   return EFI_SUCCESS;
 }
 
-EFI_STATUS
-EFIAPI
-FfsRebaseImageRead (
-    IN      VOID    *FileHandle,
-    IN      UINTN   FileOffset,
-    IN OUT  UINT32  *ReadSize,
-    OUT     VOID    *Buffer
-    )
-  /*++
-
-    Routine Description:
-
-    Support routine for the PE/COFF Loader that reads a buffer from a PE/COFF file
-
-    Arguments:
-
-   FileHandle - The handle to the PE/COFF file
-
-   FileOffset - The offset, in bytes, into the file to read
-
-   ReadSize   - The number of bytes to read from the file starting at FileOffset
-
-   Buffer     - A pointer to the buffer to read the data into.
-
-   Returns:
-
-   EFI_SUCCESS - ReadSize bytes of data were read into Buffer from the PE/COFF file starting at FileOffset
-
-   --*/
-{
-  CHAR8   *Destination8;
-  CHAR8   *Source8;
-  UINT32  Length;
-
-  Destination8  = Buffer;
-  Source8       = (CHAR8 *) ((UINTN) FileHandle + FileOffset);
-  Length        = *ReadSize;
-  while (Length--) {
-    *(Destination8++) = *(Source8++);
-  }
-
-  return EFI_SUCCESS;
-}
-
-STATIC
-EFI_STATUS
-GetAlignmentFromFile(char *InFile, UINT32 *Alignment)
-  /*
-    InFile is input file for getting alignment
-    return the alignment
-    */
-{
-  FILE                           *InFileHandle;
-  UINT8                          *PeFileBuffer;
-  UINTN                          PeFileSize;
-  UINT32                         CurSecHdrSize;
-  PE_COFF_LOADER_IMAGE_CONTEXT   ImageContext;
-  EFI_COMMON_SECTION_HEADER      *CommonHeader;
-  EFI_STATUS                     Status;
-
-  InFileHandle        = NULL;
-  PeFileBuffer        = NULL;
-  *Alignment          = 0;
-
-  memset (&ImageContext, 0, sizeof (ImageContext));
-
-  InFileHandle = fopen(LongFilePath(InFile), "rb");
-  if (InFileHandle == NULL){
-    Error (NULL, 0, 0001, "Error opening file", InFile);
-    return EFI_ABORTED;
-  }
-  PeFileSize = _filelength (fileno(InFileHandle));
-  PeFileBuffer = (UINT8 *) malloc (PeFileSize);
-  if (PeFileBuffer == NULL) {
-    fclose (InFileHandle);
-    Error(NULL, 0, 4001, "Resource", "memory cannot be allocated for %s", InFile);
-    return EFI_OUT_OF_RESOURCES;
-  }
-  fread (PeFileBuffer, sizeof (UINT8), PeFileSize, InFileHandle);
-  fclose (InFileHandle);
-  CommonHeader = (EFI_COMMON_SECTION_HEADER *) PeFileBuffer;
-  CurSecHdrSize = GetSectionHeaderLength(CommonHeader);
-  ImageContext.Handle = (VOID *) ((UINTN)PeFileBuffer + CurSecHdrSize);
-  ImageContext.ImageRead = (PE_COFF_LOADER_READ_FILE)FfsRebaseImageRead;
-  Status               = PeCoffLoaderGetImageInfo(&ImageContext);
-  if (EFI_ERROR (Status)) {
-    Error (NULL, 0, 3000, "Invalid PeImage", "The input file is %s and return status is %x", InFile, (int) Status);
-    return Status;
-   }
-  *Alignment = ImageContext.SectionAlignment;
-  // Free the allocated memory resource
-  if (PeFileBuffer != NULL) {
-    free (PeFileBuffer);
-    PeFileBuffer = NULL;
-  }
-  return EFI_SUCCESS;
-}
-
 int
 main (
   int  argc,
diff --git a/BaseTools/Source/C/Include/Common/AutoGen.h b/BaseTools/Source/C/Include/Common/AutoGen.h
index 150994a7e1..bf5bc9a063 100644
--- a/BaseTools/Source/C/Include/Common/AutoGen.h
+++ b/BaseTools/Source/C/Include/Common/AutoGen.h
@@ -1,101 +1,171 @@
-/** @file
-  AutoGen definitions for edk2 package code consumption in BaseTools.
-
-  Copyright (c) 2023, Marvin Häuser. All rights reserved.<BR>
-  SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#ifndef _BT_AUTOGENH
-#define _BT_AUTOGENH
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <Base.h>
-#include <Library/PcdLib.h>
-
-extern GUID  gEfiCallerIdGuid;
-extern GUID  gEdkiiDscPlatformGuid;
-extern CHAR8 *gEfiCallerBaseName;
-
-#define EFI_CALLER_ID_GUID \
-  {0x00000000, 0x0000, 0x0000, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}
-#define EDKII_DSC_PLATFORM_GUID \
-  {0x00000000, 0x0000, 0x0000, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}
-
-// Definition of SkuId Array
-extern UINT64 _gPcd_SkuId_Array[];
-
-// Definition of PCDs used in this module
-
-#define _PCD_TOKEN_PcdMaximumAsciiStringLength  0U
-#define _PCD_SIZE_PcdMaximumAsciiStringLength 4
-#define _PCD_GET_MODE_SIZE_PcdMaximumAsciiStringLength  _PCD_SIZE_PcdMaximumAsciiStringLength
-#define _PCD_VALUE_PcdMaximumAsciiStringLength  0U
-#define _PCD_GET_MODE_32_PcdMaximumAsciiStringLength  _PCD_VALUE_PcdMaximumAsciiStringLength
-//#define _PCD_SET_MODE_32_PcdMaximumAsciiStringLength  ASSERT(FALSE)  // It is not allowed to set value for a FIXED_AT_BUILD PCD
-
-#define _PCD_TOKEN_PcdMaximumUnicodeStringLength  0U
-#define _PCD_SIZE_PcdMaximumUnicodeStringLength 4
-#define _PCD_GET_MODE_SIZE_PcdMaximumUnicodeStringLength  _PCD_SIZE_PcdMaximumUnicodeStringLength
-#define _PCD_VALUE_PcdMaximumUnicodeStringLength  0U
-#define _PCD_GET_MODE_32_PcdMaximumUnicodeStringLength  _PCD_VALUE_PcdMaximumUnicodeStringLength
-//#define _PCD_SET_MODE_32_PcdMaximumUnicodeStringLength  ASSERT(FALSE)  // It is not allowed to set value for a FIXED_AT_BUILD PCD
-
-#define _PCD_TOKEN_PcdMaximumLinkedListLength  0U
-#define _PCD_SIZE_PcdMaximumLinkedListLength 4
-#define _PCD_GET_MODE_SIZE_PcdMaximumLinkedListLength  _PCD_SIZE_PcdMaximumLinkedListLength
-#define _PCD_VALUE_PcdMaximumLinkedListLength  0U
-#define _PCD_GET_MODE_32_PcdMaximumLinkedListLength  _PCD_VALUE_PcdMaximumLinkedListLength
-//#define _PCD_SET_MODE_32_PcdMaximumLinkedListLength  ASSERT(FALSE)  // It is not allowed to set value for a FIXED_AT_BUILD PCD
-
-#define _PCD_TOKEN_PcdMaximumDevicePathNodeCount  0U
-#define _PCD_SIZE_PcdMaximumDevicePathNodeCount 4
-#define _PCD_GET_MODE_SIZE_PcdMaximumDevicePathNodeCount  _PCD_SIZE_PcdMaximumDevicePathNodeCount
-#define _PCD_VALUE_PcdMaximumDevicePathNodeCount  0U
-#define _PCD_GET_MODE_32_PcdMaximumDevicePathNodeCount  _PCD_VALUE_PcdMaximumDevicePathNodeCount
-//#define _PCD_SET_MODE_32_PcdMaximumDevicePathNodeCount  ASSERT(FALSE)  // It is not allowed to set value for a FIXED_AT_BUILD PCD
-
-#define _PCD_TOKEN_PcdVerifyNodeInList  0U
-#define _PCD_SIZE_PcdVerifyNodeInList 1
-#define _PCD_GET_MODE_SIZE_PcdVerifyNodeInList  _PCD_SIZE_PcdVerifyNodeInList
-#define _PCD_VALUE_PcdVerifyNodeInList  1U
-#define _PCD_GET_MODE_BOOL_PcdVerifyNodeInList  _PCD_VALUE_PcdVerifyNodeInList
-//#define _PCD_SET_MODE_BOOL_PcdVerifyNodeInList  ASSERT(FALSE)  // It is not allowed to set value for a FIXED_AT_BUILD PCD
-
-#define _PCD_TOKEN_PcdFixedDebugPrintErrorLevel  0U
-#define _PCD_SIZE_PcdFixedDebugPrintErrorLevel 4
-#define _PCD_GET_MODE_SIZE_PcdFixedDebugPrintErrorLevel  _PCD_SIZE_PcdFixedDebugPrintErrorLevel
-#define _PCD_VALUE_PcdFixedDebugPrintErrorLevel  0xFFFFFFFFU
-#define _PCD_GET_MODE_32_PcdFixedDebugPrintErrorLevel  _PCD_VALUE_PcdFixedDebugPrintErrorLevel
-//#define _PCD_SET_MODE_32_PcdFixedDebugPrintErrorLevel  ASSERT(FALSE)  // It is not allowed to set value for a FIXED_AT_BUILD PCD
-
-#define _PCD_TOKEN_PcdDebugPropertyMask  0U
-#define _PCD_SIZE_PcdDebugPropertyMask 1
-#define _PCD_GET_MODE_SIZE_PcdDebugPropertyMask  _PCD_SIZE_PcdDebugPropertyMask
-#define _PCD_VALUE_PcdDebugPropertyMask  0xFFU
-#define _PCD_GET_MODE_8_PcdDebugPropertyMask  _PCD_VALUE_PcdDebugPropertyMask
-//#define _PCD_SET_MODE_8_PcdDebugPropertyMask  ASSERT(FALSE)  // It is not allowed to set value for a FIXED_AT_BUILD PCD
-
-#define _PCD_TOKEN_PcdDebugClearMemoryValue  0U
-#define _PCD_SIZE_PcdDebugClearMemoryValue 1
-#define _PCD_GET_MODE_SIZE_PcdDebugClearMemoryValue  _PCD_SIZE_PcdDebugClearMemoryValue
-#define _PCD_VALUE_PcdDebugClearMemoryValue  0xAFU
-#define _PCD_GET_MODE_8_PcdDebugClearMemoryValue  _PCD_VALUE_PcdDebugClearMemoryValue
-//#define _PCD_SET_MODE_8_PcdDebugClearMemoryValue  ASSERT(FALSE)  // It is not allowed to set value for a FIXED_AT_BUILD PCD
-
-#define _PCD_TOKEN_PcdDebugPrintErrorLevel  0U
-#define _PCD_SIZE_PcdDebugPrintErrorLevel 4
-#define _PCD_GET_MODE_SIZE_PcdDebugPrintErrorLevel  _PCD_SIZE_PcdDebugPrintErrorLevel
-#define _PCD_VALUE_PcdDebugPrintErrorLevel  0x8000004F
-#define _PCD_GET_MODE_32_PcdDebugPrintErrorLevel  _PCD_VALUE_PcdDebugPrintErrorLevel
-//#define _PCD_SET_MODE_32_PcdDebugPrintErrorLevel  ASSERT(FALSE)  // It is not allowed to set value for a FIXED_AT_BUILD PCD
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
+/** @file
+  AutoGen definitions for edk2 package code consumption in BaseTools.
+
+  Copyright (c) 2023, Marvin Häuser. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _BT_AUTOGENH
+#define _BT_AUTOGENH
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <Base.h>
+#include <Library/PcdLib.h>
+
+extern GUID  gEfiCallerIdGuid;
+extern GUID  gEdkiiDscPlatformGuid;
+extern CHAR8 *gEfiCallerBaseName;
+
+#define EFI_CALLER_ID_GUID \
+  {0x00000000, 0x0000, 0x0000, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}
+#define EDKII_DSC_PLATFORM_GUID \
+  {0x00000000, 0x0000, 0x0000, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}
+
+// Definition of SkuId Array
+extern UINT64 _gPcd_SkuId_Array[];
+
+// Definition of PCDs used in this module
+
+#define _PCD_TOKEN_PcdMaximumAsciiStringLength  0U
+#define _PCD_SIZE_PcdMaximumAsciiStringLength 4
+#define _PCD_GET_MODE_SIZE_PcdMaximumAsciiStringLength  _PCD_SIZE_PcdMaximumAsciiStringLength
+#define _PCD_VALUE_PcdMaximumAsciiStringLength  0U
+#define _PCD_GET_MODE_32_PcdMaximumAsciiStringLength  _PCD_VALUE_PcdMaximumAsciiStringLength
+//#define _PCD_SET_MODE_32_PcdMaximumAsciiStringLength  ASSERT(FALSE)  // It is not allowed to set value for a FIXED_AT_BUILD PCD
+
+#define _PCD_TOKEN_PcdMaximumUnicodeStringLength  0U
+#define _PCD_SIZE_PcdMaximumUnicodeStringLength 4
+#define _PCD_GET_MODE_SIZE_PcdMaximumUnicodeStringLength  _PCD_SIZE_PcdMaximumUnicodeStringLength
+#define _PCD_VALUE_PcdMaximumUnicodeStringLength  0U
+#define _PCD_GET_MODE_32_PcdMaximumUnicodeStringLength  _PCD_VALUE_PcdMaximumUnicodeStringLength
+//#define _PCD_SET_MODE_32_PcdMaximumUnicodeStringLength  ASSERT(FALSE)  // It is not allowed to set value for a FIXED_AT_BUILD PCD
+
+#define _PCD_TOKEN_PcdMaximumLinkedListLength  0U
+#define _PCD_SIZE_PcdMaximumLinkedListLength 4
+#define _PCD_GET_MODE_SIZE_PcdMaximumLinkedListLength  _PCD_SIZE_PcdMaximumLinkedListLength
+#define _PCD_VALUE_PcdMaximumLinkedListLength  0U
+#define _PCD_GET_MODE_32_PcdMaximumLinkedListLength  _PCD_VALUE_PcdMaximumLinkedListLength
+//#define _PCD_SET_MODE_32_PcdMaximumLinkedListLength  ASSERT(FALSE)  // It is not allowed to set value for a FIXED_AT_BUILD PCD
+
+#define _PCD_TOKEN_PcdMaximumDevicePathNodeCount  0U
+#define _PCD_SIZE_PcdMaximumDevicePathNodeCount 4
+#define _PCD_GET_MODE_SIZE_PcdMaximumDevicePathNodeCount  _PCD_SIZE_PcdMaximumDevicePathNodeCount
+#define _PCD_VALUE_PcdMaximumDevicePathNodeCount  0U
+#define _PCD_GET_MODE_32_PcdMaximumDevicePathNodeCount  _PCD_VALUE_PcdMaximumDevicePathNodeCount
+//#define _PCD_SET_MODE_32_PcdMaximumDevicePathNodeCount  ASSERT(FALSE)  // It is not allowed to set value for a FIXED_AT_BUILD PCD
+
+#define _PCD_TOKEN_PcdVerifyNodeInList  0U
+#define _PCD_SIZE_PcdVerifyNodeInList 1
+#define _PCD_GET_MODE_SIZE_PcdVerifyNodeInList  _PCD_SIZE_PcdVerifyNodeInList
+#define _PCD_VALUE_PcdVerifyNodeInList  1U
+#define _PCD_GET_MODE_BOOL_PcdVerifyNodeInList  _PCD_VALUE_PcdVerifyNodeInList
+//#define _PCD_SET_MODE_BOOL_PcdVerifyNodeInList  ASSERT(FALSE)  // It is not allowed to set value for a FIXED_AT_BUILD PCD
+
+#define _PCD_TOKEN_PcdFixedDebugPrintErrorLevel  0U
+#define _PCD_SIZE_PcdFixedDebugPrintErrorLevel 4
+#define _PCD_GET_MODE_SIZE_PcdFixedDebugPrintErrorLevel  _PCD_SIZE_PcdFixedDebugPrintErrorLevel
+#define _PCD_VALUE_PcdFixedDebugPrintErrorLevel  0xFFFFFFFFU
+#define _PCD_GET_MODE_32_PcdFixedDebugPrintErrorLevel  _PCD_VALUE_PcdFixedDebugPrintErrorLevel
+//#define _PCD_SET_MODE_32_PcdFixedDebugPrintErrorLevel  ASSERT(FALSE)  // It is not allowed to set value for a FIXED_AT_BUILD PCD
+
+#define _PCD_TOKEN_PcdDebugPropertyMask  0U
+#define _PCD_SIZE_PcdDebugPropertyMask 1
+#define _PCD_GET_MODE_SIZE_PcdDebugPropertyMask  _PCD_SIZE_PcdDebugPropertyMask
+#define _PCD_VALUE_PcdDebugPropertyMask  0xFFU
+#define _PCD_GET_MODE_8_PcdDebugPropertyMask  _PCD_VALUE_PcdDebugPropertyMask
+//#define _PCD_SET_MODE_8_PcdDebugPropertyMask  ASSERT(FALSE)  // It is not allowed to set value for a FIXED_AT_BUILD PCD
+
+#define _PCD_TOKEN_PcdDebugClearMemoryValue  0U
+#define _PCD_SIZE_PcdDebugClearMemoryValue 1
+#define _PCD_GET_MODE_SIZE_PcdDebugClearMemoryValue  _PCD_SIZE_PcdDebugClearMemoryValue
+#define _PCD_VALUE_PcdDebugClearMemoryValue  0xAFU
+#define _PCD_GET_MODE_8_PcdDebugClearMemoryValue  _PCD_VALUE_PcdDebugClearMemoryValue
+//#define _PCD_SET_MODE_8_PcdDebugClearMemoryValue  ASSERT(FALSE)  // It is not allowed to set value for a FIXED_AT_BUILD PCD
+
+#define _PCD_TOKEN_PcdDebugPrintErrorLevel  0U
+#define _PCD_SIZE_PcdDebugPrintErrorLevel 4
+#define _PCD_GET_MODE_SIZE_PcdDebugPrintErrorLevel  _PCD_SIZE_PcdDebugPrintErrorLevel
+#define _PCD_VALUE_PcdDebugPrintErrorLevel  0x8000004F
+#define _PCD_GET_MODE_32_PcdDebugPrintErrorLevel  _PCD_VALUE_PcdDebugPrintErrorLevel
+//#define _PCD_SET_MODE_32_PcdDebugPrintErrorLevel  ASSERT(FALSE)  // It is not allowed to set value for a FIXED_AT_BUILD PCD
+
+#define _PCD_TOKEN_PcdImageLoaderDebugSupport  0U
+#define _PCD_SIZE_PcdImageLoaderDebugSupport 1
+#define _PCD_GET_MODE_SIZE_PcdImageLoaderDebugSupport  _PCD_SIZE_PcdImageLoaderDebugSupport
+#define _PCD_VALUE_PcdImageLoaderDebugSupport  TRUE
+#define _PCD_GET_MODE_BOOL_PcdImageLoaderDebugSupport  _PCD_VALUE_PcdImageLoaderDebugSupport
+//#define _PCD_SET_MODE_BOOL_PcdImageLoaderDebugSupport  ASSERT(FALSE)  // It is not allowed to set value for a FIXED_AT_BUILD PCD
+
+#define _PCD_TOKEN_PcdImageLoaderHashProhibitOverlap  0U
+#define _PCD_SIZE_PcdImageLoaderHashProhibitOverlap 1
+#define _PCD_GET_MODE_SIZE_PcdImageLoaderHashProhibitOverlap  _PCD_SIZE_PcdImageLoaderHashProhibitOverlap
+#define _PCD_VALUE_PcdImageLoaderHashProhibitOverlap  FALSE
+#define _PCD_GET_MODE_BOOL_PcdImageLoaderHashProhibitOverlap  _PCD_VALUE_PcdImageLoaderHashProhibitOverlap
+//#define _PCD_SET_MODE_BOOL_PcdImageLoaderHashProhibitOverlap  ASSERT(FALSE)  // It is not allowed to set value for a FIXED_AT_BUILD PCD
+
+#define _PCD_TOKEN_PcdImageLoaderAllowMisalignedOffset  0U
+#define _PCD_SIZE_PcdImageLoaderAllowMisalignedOffset 1
+#define _PCD_GET_MODE_SIZE_PcdImageLoaderAllowMisalignedOffset  _PCD_SIZE_PcdImageLoaderAllowMisalignedOffset
+#define _PCD_VALUE_PcdImageLoaderAllowMisalignedOffset  FALSE
+#define _PCD_GET_MODE_BOOL_PcdImageLoaderAllowMisalignedOffset  _PCD_VALUE_PcdImageLoaderAllowMisalignedOffset
+//#define _PCD_SET_MODE_BOOL_PcdImageLoaderAllowMisalignedOffset  ASSERT(FALSE)  // It is not allowed to set value for a FIXED_AT_BUILD PCD
+
+#define _PCD_TOKEN_PcdImageLoaderRemoveXForWX  0U
+#define _PCD_SIZE_PcdImageLoaderRemoveXForWX 1
+#define _PCD_GET_MODE_SIZE_PcdImageLoaderRemoveXForWX  _PCD_SIZE_PcdImageLoaderRemoveXForWX
+#define _PCD_VALUE_PcdImageLoaderRemoveXForWX  FALSE
+#define _PCD_GET_MODE_BOOL_PcdImageLoaderRemoveXForWX  _PCD_VALUE_PcdImageLoaderRemoveXForWX
+//#define _PCD_SET_MODE_BOOL_PcdImageLoaderRemoveXForWX  ASSERT(FALSE)  // It is not allowed to set value for a FIXED_AT_BUILD PCD
+
+#define _PCD_TOKEN_PcdImageLoaderWXorX  0U
+#define _PCD_SIZE_PcdImageLoaderWXorX 1
+#define _PCD_GET_MODE_SIZE_PcdImageLoaderWXorX  _PCD_SIZE_PcdImageLoaderWXorX
+#define _PCD_VALUE_PcdImageLoaderWXorX  TRUE
+#define _PCD_GET_MODE_BOOL_PcdImageLoaderWXorX  _PCD_VALUE_PcdImageLoaderWXorX
+//#define _PCD_SET_MODE_BOOL_PcdImageLoaderWXorX  ASSERT(FALSE)  // It is not allowed to set value for a FIXED_AT_BUILD PCD
+
+#define _PCD_TOKEN_PcdImageLoaderLoadHeader  0U
+#define _PCD_SIZE_PcdImageLoaderLoadHeader 1
+#define _PCD_GET_MODE_SIZE_PcdImageLoaderLoadHeader  _PCD_SIZE_PcdImageLoaderLoadHeader
+#define _PCD_VALUE_PcdImageLoaderLoadHeader  TRUE
+#define _PCD_GET_MODE_BOOL_PcdImageLoaderLoadHeader  _PCD_VALUE_PcdImageLoaderLoadHeader
+//#define _PCD_SET_MODE_BOOL_PcdImageLoaderLoadHeader  ASSERT(FALSE)  // It is not allowed to set value for a FIXED_AT_BUILD PCD
+
+#define _PCD_TOKEN_PcdImageLoaderRtRelocAllowTargetMismatch  0U
+#define _PCD_SIZE_PcdImageLoaderRtRelocAllowTargetMismatch 1
+#define _PCD_GET_MODE_SIZE_PcdImageLoaderRtRelocAllowTargetMismatch  _PCD_SIZE_PcdImageLoaderRtRelocAllowTargetMismatch
+#define _PCD_VALUE_PcdImageLoaderRtRelocAllowTargetMismatch  TRUE
+#define _PCD_GET_MODE_BOOL_PcdImageLoaderRtRelocAllowTargetMismatch  _PCD_VALUE_PcdImageLoaderRtRelocAllowTargetMismatch
+//#define _PCD_SET_MODE_BOOL_PcdImageLoaderRtRelocAllowTargetMismatch  ASSERT(FALSE)  // It is not allowed to set value for a FIXED_AT_BUILD PCD
+
+#define _PCD_TOKEN_PcdImageLoaderAlignmentPolicy  0U
+#define _PCD_SIZE_PcdImageLoaderAlignmentPolicy 4
+#define _PCD_GET_MODE_SIZE_PcdImageLoaderAlignmentPolicy  _PCD_SIZE_PcdImageLoaderAlignmentPolicy
+#define _PCD_VALUE_PcdImageLoaderAlignmentPolicy  0U
+#define _PCD_GET_MODE_32_PcdImageLoaderAlignmentPolicy  _PCD_VALUE_PcdImageLoaderAlignmentPolicy
+//#define _PCD_SET_MODE_32_PcdImageLoaderAlignmentPolicy  ASSERT(FALSE)  // It is not allowed to set value for a FIXED_AT_BUILD PCD
+
+#define _PCD_TOKEN_PcdImageLoaderRelocTypePolicy  0U
+#define _PCD_SIZE_PcdImageLoaderRelocTypePolicy 4
+#define _PCD_GET_MODE_SIZE_PcdImageLoaderRelocTypePolicy  _PCD_SIZE_PcdImageLoaderRelocTypePolicy
+#define _PCD_VALUE_PcdImageLoaderRelocTypePolicy  0U
+#define _PCD_GET_MODE_32_PcdImageLoaderRelocTypePolicy  _PCD_VALUE_PcdImageLoaderRelocTypePolicy
+//#define _PCD_SET_MODE_32_PcdImageLoaderRelocTypePolicy  ASSERT(FALSE)  // It is not allowed to set value for a FIXED_AT_BUILD PCD
+
+#define _PCD_TOKEN_PcdDebugRaisePropertyMask  0U
+#define _PCD_SIZE_PcdDebugRaisePropertyMask 1
+#define _PCD_GET_MODE_SIZE_PcdDebugRaisePropertyMask  _PCD_SIZE_PcdDebugRaisePropertyMask
+#define _PCD_VALUE_PcdDebugRaisePropertyMask  0xFFU
+#define _PCD_GET_MODE_8_PcdDebugRaisePropertyMask  _PCD_VALUE_PcdDebugRaisePropertyMask
+//#define _PCD_SET_MODE_8_PcdDebugRaisePropertyMask  ASSERT(FALSE)  // It is not allowed to set value for a FIXED_AT_BUILD PCD
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/BaseTools/Source/C/Include/Common/PeImageEx.h b/BaseTools/Source/C/Include/Common/PeImageEx.h
deleted file mode 100644
index 3e4e129778..0000000000
--- a/BaseTools/Source/C/Include/Common/PeImageEx.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/** @file
-  EFI image format for PE32+. Please note some data structures are different
-  for IA-32 and Itanium-based images, look for UINTN and the #ifdef EFI_IA64
-
-  @bug Fix text - doc as defined in MSFT EFI specification.
-
-  Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
-  Portions copyright (c) 2011 - 2013, ARM Ltd. All rights reserved.<BR>
-  Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
-  Copyright (c) 2022, Loongson Technology Corporation Limited. All rights reserved.<BR>
-
-  SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#ifndef __BT_PE_IMAGE_H__
-#define __BT_PE_IMAGE_H__
-
-#include <IndustryStandard/PeImage.h>
-
-//
-// PE32+ Machine type for EFI images
-//
-#define IMAGE_FILE_MACHINE_ARM         0x01c0
-#define IMAGE_FILE_MACHINE_ARMT        IMAGE_FILE_MACHINE_ARMTHUMB_MIXED
-
-//
-// Support old names for backward compatible
-//
-#define EFI_IMAGE_MACHINE_ARMT         EFI_IMAGE_MACHINE_ARMTHUMB_MIXED
-
-#define EFI_IMAGE_FILE_LARGE_ADDRESS_AWARE  0x0020  // Supports addresses > 2-GB
-
-//
-// Based export types.
-//
-#define EFI_IMAGE_EXPORT_ORDINAL_BASE     1
-#define EFI_IMAGE_EXPORT_ADDR_SIZE        4
-#define EFI_IMAGE_EXPORT_ORDINAL_SIZE     2
-
-//
-// .pdata entries for X64
-//
-typedef struct {
-  UINT32  FunctionStartAddress;
-  UINT32  FunctionEndAddress;
-  UINT32  UnwindInfoAddress;
-} RUNTIME_FUNCTION;
-
-typedef struct {
-  UINT8  Version:3;
-  UINT8  Flags:5;
-  UINT8  SizeOfProlog;
-  UINT8  CountOfUnwindCodes;
-  UINT8  FrameRegister:4;
-  UINT8  FrameRegisterOffset:4;
-} UNWIND_INFO;
-
-#endif
diff --git a/BaseTools/Source/C/Makefiles/header.makefile b/BaseTools/Source/C/Makefiles/header.makefile
index 31f94e9be9..ebf2f573d5 100644
--- a/BaseTools/Source/C/Makefiles/header.makefile
+++ b/BaseTools/Source/C/Makefiles/header.makefile
@@ -86,7 +86,7 @@ endif
 
 INCLUDE = $(TOOL_INCLUDE) -I $(MAKEROOT) -I $(MAKEROOT)/Include/Common -I $(MAKEROOT)/Include/ -I $(MAKEROOT)/Include/IndustryStandard -I $(MAKEROOT)/Common/ -I .. -I . $(ARCH_INCLUDE)
 
-INCLUDE += -I $(EDK2_PATH)/MdePkg/Include/ -I $(EDK2_PATH)/MdeModulePkg/Include/
+INCLUDE += -I $(EDK2_PATH)/MdePkg/Include/ -I $(EDK2_PATH)/MdeModulePkg/Include/ -I $(EDK2_PATH)/OpenCorePkg/User/Include
 
 EDK2_INCLUDE = -include $(MAKEROOT)/Include/Common/AutoGen.h
 
diff --git a/BaseTools/Source/C/Makefiles/ms.common b/BaseTools/Source/C/Makefiles/ms.common
index 291e8f180c..bd066b9cd3 100644
--- a/BaseTools/Source/C/Makefiles/ms.common
+++ b/BaseTools/Source/C/Makefiles/ms.common
@@ -86,7 +86,7 @@ LINKER = $(LD)
 INC = $(INC) -I . -I $(SOURCE_PATH)\Include -I $(ARCH_INCLUDE) -I $(SOURCE_PATH)\Common
 INC = $(INC) -I $(EDK2_PATH)\MdePkg\Include
 
-INC = $(INC) -I $(EDK2_PATH)\MdePkg\Include -I $(EDK2_PATH)\MdeModulePkg\Include
+INC = $(INC) -I $(EDK2_PATH)\MdePkg\Include -I $(EDK2_PATH)\MdeModulePkg\Include -I $(EDK2_PATH)/OpenCorePkg/User/Include
 
 EDK2_INC = $(INC) /FI..\Include\Common\AutoGen.h
 
diff --git a/BaseTools/Source/C/Makefiles/ms.rule b/BaseTools/Source/C/Makefiles/ms.rule
index 97f43126ad..c00df83714 100644
--- a/BaseTools/Source/C/Makefiles/ms.rule
+++ b/BaseTools/Source/C/Makefiles/ms.rule
@@ -7,6 +7,10 @@
 
 #DEPFILES = $(OBJECTS:%.o=%.d)
 
+{$(EDK2_PATH)\BaseTools\ImageTool\}.c{$(EDK2_OBJPATH)\BaseTools\ImageTool\}.obj :
+	-@if not exist $(@D)\ mkdir $(@D)
+	$(CC) -c $(CFLAGS) $(EDK2_INC) $< -Fo$@
+
 {$(EDK2_PATH)\MdePkg\Library\BaseDebugPrintErrorLevelLib\}.c{$(EDK2_OBJPATH)\MdePkg\Library\BaseDebugPrintErrorLevelLib\}.obj :
 	-@if not exist $(@D)\ mkdir $(@D)
 	$(CC) -c $(CFLAGS) $(EDK2_INC) $< -Fo$@
@@ -27,6 +31,22 @@
 	-@if not exist $(@D)\ mkdir $(@D)
 	$(CC) -c $(CFLAGS) $(EDK2_INC) $< -Fo$@
 
+{$(EDK2_PATH)\MdePkg\Library\BaseOverflowLib\}.c{$(EDK2_OBJPATH)\MdePkg\Library\BaseOverflowLib\}.obj :
+	-@if not exist $(@D)\ mkdir $(@D)
+	$(CC) -c $(CFLAGS) $(EDK2_INC) $< -Fo$@
+
+{$(EDK2_PATH)\MdePkg\Library\BasePeCoffLib2\}.c{$(EDK2_OBJPATH)\MdePkg\Library\BasePeCoffLib2\}.obj :
+	-@if not exist $(@D)\ mkdir $(@D)
+	$(CC) -c $(CFLAGS) $(EDK2_INC) $< -Fo$@
+
+{$(EDK2_PATH)\MdePkg\Library\BaseUefiImageLib\}.c{$(EDK2_OBJPATH)\MdePkg\Library\BaseUefiImageLib\}.obj :
+	-@if not exist $(@D)\ mkdir $(@D)
+	$(CC) -c $(CFLAGS) $(EDK2_INC) $< -Fo$@
+
+{$(EDK2_PATH)\MdePkg\Library\BaseUefiImageExtraActionLibNull\}.c{$(EDK2_OBJPATH)\MdePkg\Library\BaseUefiImageExtraActionLibNull\}.obj :
+	-@if not exist $(@D)\ mkdir $(@D)
+	$(CC) -c $(CFLAGS) $(EDK2_INC) $< -Fo$@
+
 {$(EDK2_PATH)\MdeModulePkg\Library\BaseMemoryProfileLibNull\}.c{$(EDK2_OBJPATH)\MdeModulePkg\Library\BaseMemoryProfileLibNull\}.obj :
 	-@if not exist $(@D)\ mkdir $(@D)
 	$(CC) -c $(CFLAGS) $(EDK2_INC) $< -Fo$@
@@ -35,6 +55,10 @@
 	-@if not exist $(@D)\ mkdir $(@D)
 	$(CC) -c $(CFLAGS) $(EDK2_INC) $< -Fo$@
 
+{$(EDK2_PATH)\OpenCorePkg\User\Library\}.c{$(EDK2_OBJPATH)\OpenCorePkg\User\Library\}.obj :
+	-@if not exist $(@D)\ mkdir $(@D)
+	$(CC) -c $(CFLAGS) $(EDK2_INC) $< -Fo$@
+
 
 .c.obj :
 	$(CC) -c $(CFLAGS) $(INC) $< -Fo$@
diff --git a/BaseTools/Source/C/VolInfo/VolInfo.c b/BaseTools/Source/C/VolInfo/VolInfo.c
index 5fe962729f..c16d07ca11 100644
--- a/BaseTools/Source/C/VolInfo/VolInfo.c
+++ b/BaseTools/Source/C/VolInfo/VolInfo.c
@@ -9,6 +9,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
 
 #include <stdio.h>
 #include <stdlib.h>
+#include <stdbool.h>
 #include <string.h>
 #include <ctype.h>
 #include <assert.h>
@@ -24,7 +25,6 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
 #include <Common/PiFirmwareFile.h>
 #include <Common/PiFirmwareVolume.h>
 #include <Guid/FirmwareFileSystem2.h>
-#include <Common/PeImageEx.h>
 #include <Common/GuidedSectionExtractionEx.h>
 
 #include "Compress.h"
@@ -37,7 +37,8 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
 #include "ParseGuidedSectionTools.h"
 #include "StringFuncs.h"
 #include "ParseInf.h"
-#include "PeCoffLib.h"
+
+#include "../../../ImageTool/ImageToolEmit.h"
 
 //
 // Utility global variables
@@ -1417,249 +1418,63 @@ Returns:
   return EFI_SUCCESS;
 }
 
-EFI_STATUS
-EFIAPI
-RebaseImageRead (
-  IN     VOID    *FileHandle,
-  IN     UINTN   FileOffset,
-  IN OUT UINT32  *ReadSize,
-  OUT    VOID    *Buffer
-  )
-/*++
-
-Routine Description:
-
-  Support routine for the PE/COFF Loader that reads a buffer from a PE/COFF file
-
-Arguments:
-
-  FileHandle - The handle to the PE/COFF file
-
-  FileOffset - The offset, in bytes, into the file to read
-
-  ReadSize   - The number of bytes to read from the file starting at FileOffset
-
-  Buffer     - A pointer to the buffer to read the data into.
-
-Returns:
-
-  EFI_SUCCESS - ReadSize bytes of data were read into Buffer from the PE/COFF file starting at FileOffset
-
---*/
-{
-  CHAR8   *Destination8;
-  CHAR8   *Source8;
-  UINT32  Length;
-
-  Destination8  = Buffer;
-  Source8       = (CHAR8 *) ((UINTN) FileHandle + FileOffset);
-  Length        = *ReadSize;
-  while (Length--) {
-    *(Destination8++) = *(Source8++);
-  }
-
-  return EFI_SUCCESS;
-}
-
-EFI_STATUS
-SetAddressToSectionHeader (
-  IN     CHAR8   *FileName,
-  IN OUT UINT8   *FileBuffer,
-  IN     UINT64  NewPe32BaseAddress
-  )
-/*++
-
-Routine Description:
-
-  Set new base address into the section header of PeImage
-
-Arguments:
-
-  FileName           - Name of file
-  FileBuffer         - Pointer to PeImage.
-  NewPe32BaseAddress - New Base Address for PE image.
-
-Returns:
-
-  EFI_SUCCESS          Set new base address into this image successfully.
-
---*/
-{
-  EFI_STATUS                            Status;
-  PE_COFF_LOADER_IMAGE_CONTEXT          ImageContext;
-  UINTN                                 Index;
-  EFI_IMAGE_OPTIONAL_HEADER_UNION       *ImgHdr;
-  EFI_IMAGE_SECTION_HEADER              *SectionHeader;
-
-  //
-  // Initialize context
-  //
-  memset (&ImageContext, 0, sizeof (ImageContext));
-  ImageContext.Handle     = (VOID *) FileBuffer;
-  ImageContext.ImageRead  = (PE_COFF_LOADER_READ_FILE) RebaseImageRead;
-  Status                  = PeCoffLoaderGetImageInfo (&ImageContext);
-  if (EFI_ERROR (Status)) {
-    Error (NULL, 0, 3000, "Invalid", "The input PeImage %s is not valid", FileName);
-    return Status;
-  }
-
-  if (ImageContext.RelocationsStripped) {
-    Error (NULL, 0, 3000, "Invalid", "The input PeImage %s has no relocation to be fixed up", FileName);
-    return Status;
-  }
-
-  //
-  // Get PeHeader pointer
-  //
-  ImgHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)(FileBuffer + ImageContext.PeCoffHeaderOffset);
-
-  //
-  // Get section header list
-  //
-  SectionHeader = (EFI_IMAGE_SECTION_HEADER *) (
-    (UINTN) ImgHdr +
-    sizeof (UINT32) +
-    sizeof (EFI_IMAGE_FILE_HEADER) +
-    ImgHdr->Pe32.FileHeader.SizeOfOptionalHeader
-    );
-
-  //
-  // Set base address into the first section header that doesn't point to code section.
-  //
-  for (Index = 0; Index < ImgHdr->Pe32.FileHeader.NumberOfSections; Index ++, SectionHeader ++) {
-    if ((SectionHeader->Characteristics & EFI_IMAGE_SCN_CNT_CODE) == 0) {
-      *(UINT64 *) &SectionHeader->PointerToRelocations = NewPe32BaseAddress;
-      break;
-    }
-  }
-
-  //
-  // BaseAddress is set to section header.
-  //
-  return EFI_SUCCESS;
-}
-
 EFI_STATUS
 RebaseImage (
   IN     CHAR8   *FileName,
   IN OUT UINT8   *FileBuffer,
-  IN     UINT64  NewPe32BaseAddress
+  IN     UINT32  FileBufferSize,
+  IN     UINT64  NewBaseAddress
   )
 /*++
 
 Routine Description:
 
-  Set new base address into PeImage, and fix up PeImage based on new address.
+  Set new base address into UefiImage, and fix up UefiImage based on new address.
 
 Arguments:
 
   FileName           - Name of file
-  FileBuffer         - Pointer to PeImage.
-  NewPe32BaseAddress - New Base Address for PE image.
+  FileBuffer         - Pointer to UefiImage.
+  NewBaseAddress     - New Base Address for UEFI image.
 
 Returns:
 
   EFI_INVALID_PARAMETER   - BaseAddress is not valid.
-  EFI_SUCCESS             - Update PeImage is correctly.
+  EFI_SUCCESS             - Update UefiImage is correctly.
 
 --*/
 {
-  EFI_STATUS                            Status;
-  PE_COFF_LOADER_IMAGE_CONTEXT          ImageContext;
-  UINTN                                 Index;
-  EFI_IMAGE_OPTIONAL_HEADER_UNION       *ImgHdr;
-  UINT8                                 *MemoryImagePointer;
-  EFI_IMAGE_SECTION_HEADER              *SectionHeader;
+  UINT32 RebasedSize;
+  VOID   *RebasedBuffer;
 
-  //
-  // Initialize context
-  //
-  memset (&ImageContext, 0, sizeof (ImageContext));
-  ImageContext.Handle     = (VOID *) FileBuffer;
-  ImageContext.ImageRead  = (PE_COFF_LOADER_READ_FILE) RebaseImageRead;
-  Status                  = PeCoffLoaderGetImageInfo (&ImageContext);
-  if (EFI_ERROR (Status)) {
-    Error (NULL, 0, 3000, "Invalid", "The input PeImage %s is not valid", FileName);
-    return Status;
+  RebasedBuffer = ToolImageEmit (
+                    &RebasedSize,
+                    FileBuffer,
+                    FileBufferSize,
+                    -1,
+                    -1,
+                    NULL,
+                    0,
+                    true,
+                    NewBaseAddress,
+                    NULL,
+                    FALSE,
+                    TRUE
+                    );
+  if (RebasedBuffer == NULL) {
+    Error (NULL, 0, 3000, "Invalid", "The input UefiImage %s is not valid", FileName);
+    return EFI_UNSUPPORTED;
   }
 
-  if (ImageContext.RelocationsStripped) {
-    Error (NULL, 0, 3000, "Invalid", "The input PeImage %s has no relocation to be fixed up", FileName);
-    return Status;
+  if (RebasedSize > FileBufferSize) {
+    Error (NULL, 0, 3000, "Invalid", "Rebased %s too large: %u vs %u", FileName, RebasedSize, FileBufferSize);
+    return EFI_UNSUPPORTED;
   }
 
-  //
-  // Get PeHeader pointer
-  //
-  ImgHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)(FileBuffer + ImageContext.PeCoffHeaderOffset);
+  memmove (FileBuffer, RebasedBuffer, RebasedSize);
+  memset (FileBuffer + RebasedSize, 0, FileBufferSize - RebasedSize);
 
-  //
-  // Load and Relocate Image Data
-  //
-  MemoryImagePointer = (UINT8 *) malloc ((UINTN) ImageContext.ImageSize + ImageContext.SectionAlignment);
-  if (MemoryImagePointer == NULL) {
-    Error (NULL, 0, 4001, "Resource", "memory cannot be allocated on rebase of %s", FileName);
-    return EFI_OUT_OF_RESOURCES;
-  }
-  memset ((VOID *) MemoryImagePointer, 0, (UINTN) ImageContext.ImageSize + ImageContext.SectionAlignment);
-  ImageContext.ImageAddress = ((UINTN) MemoryImagePointer + ImageContext.SectionAlignment - 1) & (~((INT64)ImageContext.SectionAlignment - 1));
-
-  Status =  PeCoffLoaderLoadImage (&ImageContext);
-  if (EFI_ERROR (Status)) {
-    Error (NULL, 0, 3000, "Invalid", "LocateImage() call failed on rebase of %s", FileName);
-    free ((VOID *) MemoryImagePointer);
-    return Status;
-  }
-
-  ImageContext.DestinationAddress = NewPe32BaseAddress;
-  Status                          = PeCoffLoaderRelocateImage (&ImageContext);
-  if (EFI_ERROR (Status)) {
-    Error (NULL, 0, 3000, "Invalid", "RelocateImage() call failed on rebase of %s", FileName);
-    free ((VOID *) MemoryImagePointer);
-    return Status;
-  }
-
-  //
-  // Copy Relocated data to raw image file.
-  //
-  SectionHeader = (EFI_IMAGE_SECTION_HEADER *) (
-    (UINTN) ImgHdr +
-    sizeof (UINT32) +
-    sizeof (EFI_IMAGE_FILE_HEADER) +
-    ImgHdr->Pe32.FileHeader.SizeOfOptionalHeader
-    );
-
-  for (Index = 0; Index < ImgHdr->Pe32.FileHeader.NumberOfSections; Index ++, SectionHeader ++) {
-    CopyMem (
-      FileBuffer + SectionHeader->PointerToRawData,
-      (VOID*) (UINTN) (ImageContext.ImageAddress + SectionHeader->VirtualAddress),
-      SectionHeader->SizeOfRawData
-      );
-  }
-
-  free ((VOID *) MemoryImagePointer);
-
-  //
-  // Update Image Base Address
-  //
-  if (ImgHdr->Pe32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
-    ImgHdr->Pe32.OptionalHeader.ImageBase = (UINT32) NewPe32BaseAddress;
-  } else if (ImgHdr->Pe32Plus.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) {
-    ImgHdr->Pe32Plus.OptionalHeader.ImageBase = NewPe32BaseAddress;
-  } else {
-    Error (NULL, 0, 3000, "Invalid", "unknown PE magic signature %X in PE32 image %s",
-      ImgHdr->Pe32.OptionalHeader.Magic,
-      FileName
-      );
-    return EFI_ABORTED;
-  }
-
-  //
-  // Set new base address into section header
-  //
-  Status = SetAddressToSectionHeader (FileName, FileBuffer, NewPe32BaseAddress);
-
-  return Status;
+  return EFI_SUCCESS;
 }
 
 EFI_STATUS
@@ -1795,7 +1610,7 @@ Returns:
       if (EnableHash) {
         ToolInputFileName  = "edk2Temp_InputEfi.tmp";
         ToolOutputFileName = "edk2Temp_OutputHash.tmp";
-        RebaseImage(ToolInputFileName, (UINT8*)Ptr + SectionHeaderLen, 0);
+        RebaseImage(ToolInputFileName, (UINT8*)Ptr + SectionHeaderLen, SectionLength - SectionHeaderLen, 0);
         PutFileImage (
           ToolInputFileName,
           (CHAR8*)Ptr + SectionHeaderLen,
@@ -1830,7 +1645,7 @@ Returns:
           CHAR8 *NewStr;
           UINT32 nFileLen;
           if((fp = fopen(ToolOutputFileName,"r")) == NULL) {
-            Error (NULL, 0, 0004, "Hash the PE32 image failed.", NULL);
+            Error (NULL, 0, 0004, "Hash the UEFI image failed.", NULL);
           }
           else {
             fseek(fp,0,SEEK_SET);
@@ -2517,7 +2332,7 @@ Returns:
             The offset from the start of the input file to start \n\
             processing an FV\n");
   fprintf (stdout, "  --hash\n\
-            Generate HASH value of the entire PE image\n");
+            Generate HASH value of the entire UEFI image\n");
   fprintf (stdout, "  --sfo\n\
             Reserved for future use\n");
 }