]> git.proxmox.com Git - mirror_edk2.git/commitdiff
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@426 6f19259b...
authoralfred <alfred@6f19259b-4bc3-4df7-8a09-765794883524>
Tue, 6 Jun 2006 06:25:59 +0000 (06:25 +0000)
committeralfred <alfred@6f19259b-4bc3-4df7-8a09-765794883524>
Tue, 6 Jun 2006 06:25:59 +0000 (06:25 +0000)
EdkModulePkg/Library/EdkPeCoffLoaderLibX64/EdkPeCoffLoaderLibX64.c

index 5ed74f5a92ce60c6250dc88a12fb2592a87c375e..36fad751118e173b31d1fcdd668484402d3d4e9b 100644 (file)
-/*++
-
-Copyright (c) 2006, Intel Corporation                                                         
-All rights reserved. This program and the accompanying materials                          
-are licensed and made available under the terms and conditions of the BSD License         
-which accompanies this distribution.  The full text of the license may be found at        
-http://opensource.org/licenses/bsd-license.php                                            
-                                                                                          
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             
-
-Module Name:
-
-  EdkPeCoffLoaderX64.c
-
-Abstract:
-
-  Wrap the Base PE/COFF loader with the PE COFF Protocol
-
-
---*/
-
-#define IMAGE_64_MACHINE_TYPE_SUPPORTED(Machine) \
-  ((Machine) == EFI_IMAGE_MACHINE_IA32 || \
-   (Machine) == EFI_IMAGE_MACHINE_X64 || \
-   (Machine) == EFI_IMAGE_MACHINE_EBC)
-
-STATIC
-EFI_STATUS
-PeCoffLoader64GetPeHeader (
-  IN OUT PE_COFF_LOADER_IMAGE_CONTEXT  *ImageContext,
-  OUT    EFI_IMAGE_NT_HEADERS64                  *PeHdr
-  );
-
-STATIC
-EFI_STATUS
-PeCoffLoader64CheckImageType (
-  IN OUT PE_COFF_LOADER_IMAGE_CONTEXT  *ImageContext,
-  IN     EFI_IMAGE_NT_HEADERS64                  *PeHdr
-  );
-
-STATIC
-VOID *
-PeCoffLoader64ImageAddress (
-  IN OUT PE_COFF_LOADER_IMAGE_CONTEXT  *ImageContext,
-  IN     UINTN                                 Address
-  );
-
-EFI_STATUS
-EFIAPI
-PeCoffLoader64GetImageInfo (
-  IN     EFI_PEI_PE_COFF_LOADER_PROTOCOL       *This,
-  IN OUT PE_COFF_LOADER_IMAGE_CONTEXT  *ImageContext
-  );
-
-EFI_STATUS
-EFIAPI
-PeCoffLoader64RelocateImage (
-  IN     EFI_PEI_PE_COFF_LOADER_PROTOCOL       *This,
-  IN OUT PE_COFF_LOADER_IMAGE_CONTEXT  *ImageContext
-  );
-
-EFI_STATUS
-EFIAPI
-PeCoffLoader64LoadImage (
-  IN     EFI_PEI_PE_COFF_LOADER_PROTOCOL       *This,
-  IN OUT PE_COFF_LOADER_IMAGE_CONTEXT  *ImageContext
-  );
-
-EFI_STATUS
-EFIAPI
-PeCoffLoader64UnloadImage (
-  IN EFI_PEI_PE_COFF_LOADER_PROTOCOL      *This,
-  IN PE_COFF_LOADER_IMAGE_CONTEXT   *ImageContext
-  );
-
-EFI_STATUS
-PeCoffLoader64RelocateImageEx (
-  IN UINT16      *Reloc,
-  IN OUT CHAR8   *Fixup, 
-  IN OUT CHAR8   **FixupData,
-  IN UINT64      Adjust
-  );
-
-EFI_PEI_PE_COFF_LOADER_PROTOCOL mPeCoffLoaderX64 = {
-  PeCoffLoader64GetImageInfo,
-  PeCoffLoader64LoadImage,
-  PeCoffLoader64RelocateImage,
-  PeCoffLoader64UnloadImage
-};
-
-STATIC
-EFI_STATUS
-PeCoffLoader64GetPeHeader (
-  IN OUT PE_COFF_LOADER_IMAGE_CONTEXT  *ImageContext,
-  OUT    EFI_IMAGE_NT_HEADERS64                *PeHdr
-  )
-/*++
-
-Routine Description:
-  Retrieves the PE Header from a PE/COFF image
-
-Arguments:
-  ImageContext  - The context of the image being loaded
-  PeHdr         - The buffer in which to return the PE header
-
-Returns:
-  EFI_SUCCESS if the PE Header is read, 
-  Otherwise, the error status from reading the PE/COFF image using the ImageRead function.
-
---*/
-{
-  EFI_STATUS            Status;
-  EFI_IMAGE_DOS_HEADER  DosHdr;
-  UINTN                 Size;
-  
-  //
-  // Read the DOS image headers
-  //
-  Size = sizeof (EFI_IMAGE_DOS_HEADER);
-  Status = ImageContext->ImageRead (
-                           ImageContext->Handle, 
-                           0,
-                           &Size, 
-                           &DosHdr
-                           );
-  if (EFI_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;
-  } 
-
-  //
-  // Read the PE/COFF Header
-  //
-  Size = sizeof (EFI_IMAGE_NT_HEADERS64);
-  Status = ImageContext->ImageRead (
-                           ImageContext->Handle, 
-                           ImageContext->PeCoffHeaderOffset, 
-                           &Size, 
-                           PeHdr
-                           );
-  if (EFI_ERROR (Status)) {
-      ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;
-      return Status;
-  }
-
-  return EFI_SUCCESS;
-}
-
-static
-EFI_STATUS
-PeCoffLoader64CheckImageType (
-  IN OUT PE_COFF_LOADER_IMAGE_CONTEXT      *ImageContext,
-  IN     EFI_IMAGE_NT_HEADERS64                    *PeHdr
-  )
-/*++
-
-Routine Description:
-  Checks the PE header of a PE/COFF image to determine if it supported
-
-Arguments:
-  ImageContext  - The context of the image being loaded
-  PeHdr         - The buffer in which to return the PE header
-
-Returns:
-  EFI_SUCCESS if the PE/COFF image is supported
-  EFI_UNSUPPORTED of the PE/COFF image is not supported.
-
---*/
-{
-  //
-  // Check the PE/COFF Header SIgnature
-  //
-  if (PeHdr->Signature != EFI_IMAGE_NT_SIGNATURE) {
-    ImageContext->ImageError = IMAGE_ERROR_INVALID_PE_HEADER_SIGNATURE;
-    return EFI_UNSUPPORTED;
-  }
-
-  //
-  // See if the machine type is supported.  We support a native machine type (IA-32/Itanium-based)
-  // and the machine type for the Virtual Machine.
-  //
-  ImageContext->Machine = PeHdr->FileHeader.Machine;
-  if (!(IMAGE_64_MACHINE_TYPE_SUPPORTED (ImageContext->Machine))) {
-    ImageContext->ImageError = IMAGE_ERROR_INVALID_MACHINE_TYPE;
-    return EFI_UNSUPPORTED;
-  }
-
-  //
-  // See if the image type is supported.  We support EFI Applications, 
-  // EFI Boot Service Drivers, and EFI Runtime Drivers.
-  //
-  ImageContext->ImageType = PeHdr->OptionalHeader.Subsystem;
-  switch (ImageContext->ImageType) {
-
-  case EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION:
-    ImageContext->ImageCodeMemoryType = EfiLoaderCode;
-    ImageContext->ImageDataMemoryType = EfiLoaderData;
-    break;
-  
-  case EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER:
-    ImageContext->ImageCodeMemoryType = EfiBootServicesCode;
-    ImageContext->ImageDataMemoryType = EfiBootServicesData;
-    break;
-  
-  case EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER:
-  case EFI_IMAGE_SUBSYSTEM_SAL_RUNTIME_DRIVER:
-    ImageContext->ImageCodeMemoryType = EfiRuntimeServicesCode;
-    ImageContext->ImageDataMemoryType = EfiRuntimeServicesData;
-    break;
-  
-  default:
-    ImageContext->ImageError = IMAGE_ERROR_INVALID_SUBSYSTEM;
-    return EFI_UNSUPPORTED;
-  }
-
-  return EFI_SUCCESS;
-}
-
-EFI_STATUS
-EFIAPI
-PeCoffLoader64GetImageInfo (
-  IN     EFI_PEI_PE_COFF_LOADER_PROTOCOL           *This,
-  IN OUT PE_COFF_LOADER_IMAGE_CONTEXT      *ImageContext
-  )
-/*++
-
-Routine Description:
-  Retrieves information on a PE/COFF image
-
-Arguments:
-  ImageContext  - The context of the image being loaded
-  PeHdr         - The buffer in which to return the PE header
-
-Returns:
-  EFI_SUCCESS if the information on the PE/COFF image was collected.
-  EFI_UNSUPPORTED of the PE/COFF image is not supported.
-  Otherwise, the error status from reading the PE/COFF image using the 
-    ImageContext->ImageRead() function
-
---*/
-{
-  EFI_STATUS                      Status;
-  EFI_IMAGE_NT_HEADERS64          PeHdr;
-  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;
-
-  if (NULL == ImageContext) {
-    return EFI_INVALID_PARAMETER;
-  }
-
-  //
-  // Assume success
-  //
-  ImageContext->ImageError = IMAGE_ERROR_SUCCESS;
-  
-  Status = PeCoffLoader64GetPeHeader (ImageContext, &PeHdr);
-  if (EFI_ERROR (Status)) {
-    return Status;
-  }
-
-  //
-  // Verify machine type
-  //
-  Status = PeCoffLoader64CheckImageType (ImageContext, &PeHdr);
-  if (EFI_ERROR(Status)) {
-    return Status;
-  }
-
-  //
-  // Retrieve the base address of the image
-  //
-  ImageContext->ImageAddress = PeHdr.OptionalHeader.ImageBase;
-  
-  //
-  // 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 (PeHdr.FileHeader.Characteristics &  EFI_IMAGE_FILE_RELOCS_STRIPPED) {
-    ImageContext->RelocationsStripped = TRUE;
-  } else {
-    ImageContext->RelocationsStripped = FALSE;
-  }
-
-  ImageContext->ImageSize        = (UINT64)PeHdr.OptionalHeader.SizeOfImage;
-  ImageContext->SectionAlignment = PeHdr.OptionalHeader.SectionAlignment;
-  ImageContext->SizeOfHeaders    = PeHdr.OptionalHeader.SizeOfHeaders; 
-
-  //
-  // Modify ImageSize to contain .PDB file name if required and initialize
-  // PdbRVA field...
-  //
-
-  if (PeHdr.OptionalHeader.NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_DEBUG) {
-    DebugDirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *)
-      &(PeHdr.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG]);
-
-    DebugDirectoryEntryRva = DebugDirectoryEntry->VirtualAddress;
-
-    //
-    // 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.FileHeader.SizeOfOptionalHeader
-                      );
-    
-    for (Index = 0; Index < PeHdr.FileHeader.NumberOfSections; Index += 1) {
-      //
-      // Read section header from file
-      //
-      Size = sizeof (EFI_IMAGE_SECTION_HEADER);
-      Status = ImageContext->ImageRead (
-                               ImageContext->Handle, 
-                               SectionHeaderOffset, 
-                               &Size, 
-                               &SectionHeader
-                               );
-      if (EFI_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++) {
-        //
-        // Read next debug directory entry
-        //
-        Size = sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY);
-        Status = ImageContext->ImageRead (
-                                 ImageContext->Handle, 
-                                 DebugDirectoryEntryFileOffset, 
-                                 &Size, 
-                                 &DebugEntry
-                                 );
-        if (EFI_ERROR (Status)) {
-          ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;
-          return Status;
-        }
-        if (DebugEntry.Type == EFI_IMAGE_DEBUG_TYPE_CODEVIEW) {
-          ImageContext->DebugDirectoryEntryRva = (UINT32) (DebugDirectoryEntryRva + Index * sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY));
-          if (DebugEntry.RVA == 0 && DebugEntry.FileOffset != 0) {
-            ImageContext->ImageSize += DebugEntry.SizeOfData;
-          }
-          return EFI_SUCCESS;
-        }
-      }
-    }
-  }
-  return EFI_SUCCESS;
-}
-
-static
-VOID *
-PeCoffLoader64ImageAddress (
-  IN OUT PE_COFF_LOADER_IMAGE_CONTEXT      *ImageContext,
-  IN     UINTN                                     Address
-  )
-/*++
-
-Routine Description:
-  Converts an image address to the loaded address
-
-Arguments:
-  ImageContext  - The context of the image being loaded
-  Address       - The address to be converted to the loaded address
-
-Returns:
-  NULL if the address can not be converted, otherwise, the converted address
-
---*/
-{
-  if (Address >= ImageContext->ImageSize) {
-    ImageContext->ImageError = IMAGE_ERROR_INVALID_IMAGE_ADDRESS;
-    return NULL;
-  }
-  return (CHAR8 *)((UINTN)ImageContext->ImageAddress + Address);
-}
-
-EFI_STATUS
-EFIAPI
-PeCoffLoader64RelocateImage (
-  IN     EFI_PEI_PE_COFF_LOADER_PROTOCOL           *This,
-  IN OUT PE_COFF_LOADER_IMAGE_CONTEXT      *ImageContext
-  )
-/*++
-
-Routine Description:
-  Relocates a PE/COFF image in memory
-
-Arguments:
-  ImageContext - Contains information on the loaded image to relocate
-
-Returns:
-  EFI_SUCCESS    if the PE/COFF image was relocated
-  EFI_LOAD_ERROR if the image is not a valid PE/COFF image
-
---*/
-{
-  EFI_STATUS                 Status;
-  EFI_IMAGE_NT_HEADERS64     *PeHdr;
-  EFI_IMAGE_DATA_DIRECTORY   *RelocDir;
-  IN UINT64                  Adjust;
-  EFI_IMAGE_BASE_RELOCATION  *RelocBase;
-  EFI_IMAGE_BASE_RELOCATION  *RelocBaseEnd;
-  UINT16                     *Reloc;
-  UINT16                     *RelocEnd;
-  CHAR8                      *Fixup;
-  CHAR8                      *FixupBase;
-  UINT16                     *F16;
-  UINT32                     *F32;
-  CHAR8                      *FixupData;
-  EFI_PHYSICAL_ADDRESS       BaseAddress;
-
-
-  //
-  // Assume success
-  //
-  ImageContext->ImageError = IMAGE_ERROR_SUCCESS;
-
-  //
-  // If there are no relocation entries, then we are done
-  //
-  if (ImageContext->RelocationsStripped) {
-    return EFI_SUCCESS;
-  }
-
-  //
-  // If the destination address is not 0, use that rather than the
-  // image address as the relocation target.
-  //
-  if (ImageContext->DestinationAddress) {
-    BaseAddress = ImageContext->DestinationAddress;
-  } else {
-    BaseAddress = ImageContext->ImageAddress;
-  }
-  PeHdr    = (EFI_IMAGE_NT_HEADERS64 *)((UINTN)ImageContext->ImageAddress + 
-                                            ImageContext->PeCoffHeaderOffset);
-  Adjust   = (UINT64) BaseAddress - PeHdr->OptionalHeader.ImageBase;
-
-  PeHdr->OptionalHeader.ImageBase = (UINTN) BaseAddress;
-
-  //
-  // 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 (PeHdr->OptionalHeader.NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC) {
-    RelocDir = &PeHdr->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC];
-    RelocBase = PeCoffLoader64ImageAddress (ImageContext, RelocDir->VirtualAddress);
-    RelocBaseEnd = PeCoffLoader64ImageAddress ( 
-                    ImageContext, 
-                    RelocDir->VirtualAddress + RelocDir->Size - 1
-                    );
-} else {
-    //
-    // Set base and end to bypass processing below.
-    //
-    RelocBase = RelocBaseEnd = 0;
-  }
-  //
-  // 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);
-    FixupBase = PeCoffLoader64ImageAddress (ImageContext, RelocBase->VirtualAddress);
-    if ((CHAR8 *) RelocEnd < (CHAR8 *)((UINTN)ImageContext->ImageAddress) || 
-        (CHAR8 *) RelocEnd > (CHAR8 *)((UINTN)ImageContext->ImageAddress + 
-          (UINTN)ImageContext->ImageSize)) {
-      ImageContext->ImageError = IMAGE_ERROR_FAILED_RELOCATION;
-      return EFI_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 << 16) + (UINT16) Adjust);
-        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_HIGHADJ:
-        // Return the same EFI_UNSUPPORTED return code as 
-        // PeCoffLoader64RelocateImageEx() returns if it does not recognize
-        // the relocation type.
-        //
-        ImageContext->ImageError = IMAGE_ERROR_FAILED_RELOCATION;
-        return EFI_UNSUPPORTED;
-      default:
-        Status = PeCoffLoader64RelocateImageEx (Reloc, Fixup, &FixupData, Adjust);
-        if (EFI_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 EFI_SUCCESS;
-}
-
-
-EFI_STATUS
-PeCoffLoader64RelocateImageEx (
-  IN UINT16      *Reloc,
-  IN OUT CHAR8   *Fixup, 
-  IN OUT CHAR8   **FixupData,
-  IN UINT64      Adjust
-  )
-/*++
-
-Routine Description:
-  Performs an IA-32 specific relocation fixup
-
-Arguments:
-  Reloc      - Pointer to the relocation record
-  Fixup      - Pointer to the address to fix up
-  FixupData  - Pointer to a buffer to log the fixups
-  Adjust     - The offset to adjust the fixup
-
-Returns:
-  None
-
---*/
-{
-  UINT64      *F64;
-
-  switch ((*Reloc) >> 12) {
-
-    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;
-
-    default:
-      return EFI_UNSUPPORTED;
-  }
-
-  return EFI_SUCCESS;
-}
-
-
-
-EFI_STATUS
-EFIAPI
-PeCoffLoader64LoadImage (
-  IN     EFI_PEI_PE_COFF_LOADER_PROTOCOL           *This,
-  IN OUT PE_COFF_LOADER_IMAGE_CONTEXT      *ImageContext
-  )
-/*++
-
-Routine Description:
-  Loads a PE/COFF image into memory
-
-Arguments:
-  ImageContext - Contains information on image to load into memory
-
-Returns:
-  EFI_SUCCESS            if the PE/COFF image was loaded
-  EFI_BUFFER_TOO_SMALL   if the caller did not provide a large enough buffer
-  EFI_LOAD_ERROR         if the image is a runtime driver with no relocations
-  EFI_INVALID_PARAMETER  if the image address is invalid
-
---*/
-{
-  EFI_STATUS                            Status;
-  EFI_IMAGE_NT_HEADERS64                *PeHdr;
-  PE_COFF_LOADER_IMAGE_CONTEXT  CheckContext;
-  EFI_IMAGE_SECTION_HEADER              *FirstSection;
-  EFI_IMAGE_SECTION_HEADER              *Section;
-  UINTN                                 Index;
-  CHAR8                                 *Base;
-  CHAR8                                 *End;
-  CHAR8                                 *MaxEnd;
-  EFI_IMAGE_DATA_DIRECTORY              *DirectoryEntry;
-  EFI_IMAGE_DEBUG_DIRECTORY_ENTRY       *DebugEntry;
-  UINTN                                 Size;
-  UINT32                                TempDebugEntryRva;
-
-  //
-  // 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 = PeCoffLoader64GetImageInfo (
-             This,
-             &CheckContext 
-             );
-  if (EFI_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 EFI_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 == TRUE) {
-    //
-    // 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 EFI_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 EFI_INVALID_PARAMETER;
-    }
-  }
-
-  //
-  // Make sure the allocated space has the proper section alignment
-  //
-  if ((ImageContext->ImageAddress & (CheckContext.SectionAlignment - 1)) != 0) {
-    ImageContext->ImageError = IMAGE_ERROR_INVALID_SECTION_ALIGNMENT;
-    return EFI_INVALID_PARAMETER;
-  }
-
-  //
-  // Read the entire PE/COFF header into memory
-  //
-  Status = ImageContext->ImageRead (
-                ImageContext->Handle, 
-                0, 
-                &ImageContext->SizeOfHeaders, 
-                (VOID *)(UINTN)ImageContext->ImageAddress
-                );
-  if (EFI_ERROR(Status)) {
-    ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;
-    return EFI_LOAD_ERROR;
-  }
-
-  PeHdr = (EFI_IMAGE_NT_HEADERS64 *)
-      ((UINTN)ImageContext->ImageAddress + ImageContext->PeCoffHeaderOffset);
-
-  //
-  // Load each section of the image
-  //
-  FirstSection = (EFI_IMAGE_SECTION_HEADER *) (
-                      (UINTN)ImageContext->ImageAddress +
-                      ImageContext->PeCoffHeaderOffset +
-                      sizeof(UINT32) + 
-                      sizeof(EFI_IMAGE_FILE_HEADER) + 
-                      PeHdr->FileHeader.SizeOfOptionalHeader
-                      );
-
-  Section = FirstSection;
-  for ( Index=0, MaxEnd = NULL; 
-        Index < PeHdr->FileHeader.NumberOfSections; 
-        Index += 1) {
-
-    //
-    // Compute sections address
-    //
-    Base = PeCoffLoader64ImageAddress (ImageContext, Section->VirtualAddress);
-    End  = PeCoffLoader64ImageAddress (
-                  ImageContext, 
-                  Section->VirtualAddress + Section->Misc.VirtualSize - 1);
-    if (End > MaxEnd) {
-      MaxEnd = End;
-    }
-    //
-    // If the base start or end address resolved to 0, then fail.
-    //
-    if (!Base  ||  !End) {
-      ImageContext->ImageError = IMAGE_ERROR_SECTION_NOT_LOADED;
-      return EFI_LOAD_ERROR;
-    }
-
-    //
-    // Read the section, we can resume the length of PE image can't 
-    // exceed the max 32bit integer
-    //
-    Size = (UINTN) Section->Misc.VirtualSize;
-    if ((Size == 0) || (Size > Section->SizeOfRawData)) {
-      Size = (UINTN) Section->SizeOfRawData;
-    }
-    if (Section->SizeOfRawData) {
-      Status = ImageContext->ImageRead (
-                               ImageContext->Handle, 
-                               Section->PointerToRawData, 
-                               &Size, 
-                               Base);
-      if (EFI_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 - (UINTN)Size);
-    }
-
-    //
-    // Next Section
-    //
-    Section += 1;
-  }
-
-  //
-  // Get image's entry point
-  //
-  ImageContext->EntryPoint = 
-      (EFI_PHYSICAL_ADDRESS) (UINTN) PeCoffLoader64ImageAddress (
-                                      ImageContext, 
-                                      PeHdr->OptionalHeader.AddressOfEntryPoint
-                                      );
-
-  //
-  // 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 (PeHdr->OptionalHeader.NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC) {
-    DirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *)
-      &PeHdr->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC];
-    ImageContext->FixupDataSize = 
-      DirectoryEntry->Size / sizeof(UINT16) * sizeof(UINTN);
-  } else {
-    ImageContext->FixupDataSize = 0;
-  }
-  //
-  // 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) {
-    DebugEntry = PeCoffLoader64ImageAddress (
-                  ImageContext, 
-                  ImageContext->DebugDirectoryEntryRva
-                  );
-    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) {
-        ImageContext->CodeView = PeCoffLoader64ImageAddress (ImageContext, TempDebugEntryRva);
-        if (ImageContext->CodeView == NULL) {
-          ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;
-          return EFI_LOAD_ERROR;
-        }
-
-        if (DebugEntry->RVA == 0) {
-          Size = (UINTN) DebugEntry->SizeOfData;
-          Status = ImageContext->ImageRead (
-                        ImageContext->Handle, 
-                        DebugEntry->FileOffset,
-                        &Size, 
-                        ImageContext->CodeView
-                        );
-          if (EFI_ERROR(Status)) {
-            ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;
-            return EFI_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;
-          default:
-            break;
-        }
-      }
-    }
-  }
-  
-  return Status;
-}
-
-EFI_STATUS
-EFIAPI
-PeCoffLoader64UnloadImage (
-  IN EFI_PEI_PE_COFF_LOADER_PROTOCOL      *This,
-  IN PE_COFF_LOADER_IMAGE_CONTEXT   *ImageContext
-  )
-/*++
-
-Routine Description:
-  Unload of images is not supported
-
-Arguments:
-  ImageContext - The image to unload
-
-Returns:
-  EFI_SUCCESS
-
---*/
-{
-  return EFI_SUCCESS;
-}
-
-EFI_PEI_PE_COFF_LOADER_PROTOCOL *
-EFIAPI
-GetPeCoffLoaderProtocol (
-  )
-{
-  return &mPeCoffLoaderX64;
-}
-
-
+/*++\r
+\r
+Copyright (c) 2006, Intel Corporation                                                         \r
+All rights reserved. This program and the accompanying materials                          \r
+are licensed and made available under the terms and conditions of the BSD License         \r
+which accompanies this distribution.  The full text of the license may be found at        \r
+http://opensource.org/licenses/bsd-license.php                                            \r
+                                                                                          \r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
+\r
+Module Name:\r
+\r
+  EdkPeCoffLoaderX64.c\r
+\r
+Abstract:\r
+\r
+  Wrap the Base PE/COFF loader with the PE COFF Protocol\r
+\r
+\r
+--*/\r
+\r
+#define IMAGE_64_MACHINE_TYPE_SUPPORTED(Machine) \\r
+  ((Machine) == EFI_IMAGE_MACHINE_IA32 || \\r
+   (Machine) == EFI_IMAGE_MACHINE_X64 || \\r
+   (Machine) == EFI_IMAGE_MACHINE_EBC)\r
+\r
+STATIC\r
+EFI_STATUS\r
+PeCoffLoader64GetPeHeader (\r
+  IN OUT PE_COFF_LOADER_IMAGE_CONTEXT  *ImageContext,\r
+  OUT    EFI_IMAGE_NT_HEADERS64                  *PeHdr\r
+  );\r
+\r
+STATIC\r
+EFI_STATUS\r
+PeCoffLoader64CheckImageType (\r
+  IN OUT PE_COFF_LOADER_IMAGE_CONTEXT  *ImageContext,\r
+  IN     EFI_IMAGE_NT_HEADERS64                  *PeHdr\r
+  );\r
+\r
+STATIC\r
+VOID *\r
+PeCoffLoader64ImageAddress (\r
+  IN OUT PE_COFF_LOADER_IMAGE_CONTEXT  *ImageContext,\r
+  IN     UINTN                                 Address\r
+  );\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PeCoffLoader64GetImageInfo (\r
+  IN     EFI_PEI_PE_COFF_LOADER_PROTOCOL       *This,\r
+  IN OUT PE_COFF_LOADER_IMAGE_CONTEXT  *ImageContext\r
+  );\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PeCoffLoader64RelocateImage (\r
+  IN     EFI_PEI_PE_COFF_LOADER_PROTOCOL       *This,\r
+  IN OUT PE_COFF_LOADER_IMAGE_CONTEXT  *ImageContext\r
+  );\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PeCoffLoader64LoadImage (\r
+  IN     EFI_PEI_PE_COFF_LOADER_PROTOCOL       *This,\r
+  IN OUT PE_COFF_LOADER_IMAGE_CONTEXT  *ImageContext\r
+  );\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PeCoffLoader64UnloadImage (\r
+  IN EFI_PEI_PE_COFF_LOADER_PROTOCOL      *This,\r
+  IN PE_COFF_LOADER_IMAGE_CONTEXT   *ImageContext\r
+  );\r
+\r
+EFI_STATUS\r
+PeCoffLoader64RelocateImageEx (\r
+  IN UINT16      *Reloc,\r
+  IN OUT CHAR8   *Fixup, \r
+  IN OUT CHAR8   **FixupData,\r
+  IN UINT64      Adjust\r
+  );\r
+\r
+EFI_PEI_PE_COFF_LOADER_PROTOCOL mPeCoffLoaderX64 = {\r
+  PeCoffLoader64GetImageInfo,\r
+  PeCoffLoader64LoadImage,\r
+  PeCoffLoader64RelocateImage,\r
+  PeCoffLoader64UnloadImage\r
+};\r
+\r
+STATIC\r
+EFI_STATUS\r
+PeCoffLoader64GetPeHeader (\r
+  IN OUT PE_COFF_LOADER_IMAGE_CONTEXT  *ImageContext,\r
+  OUT    EFI_IMAGE_NT_HEADERS64                *PeHdr\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+  Retrieves the PE Header from a PE/COFF image\r
+\r
+Arguments:\r
+  ImageContext  - The context of the image being loaded\r
+  PeHdr         - The buffer in which to return the PE header\r
+\r
+Returns:\r
+  EFI_SUCCESS if the PE Header is read, \r
+  Otherwise, the error status from reading the PE/COFF image using the ImageRead function.\r
+\r
+--*/\r
+{\r
+  EFI_STATUS            Status;\r
+  EFI_IMAGE_DOS_HEADER  DosHdr;\r
+  UINTN                 Size;\r
+  \r
+  //\r
+  // Read the DOS image headers\r
+  //\r
+  Size = sizeof (EFI_IMAGE_DOS_HEADER);\r
+  Status = ImageContext->ImageRead (\r
+                           ImageContext->Handle, \r
+                           0,\r
+                           &Size, \r
+                           &DosHdr\r
+                           );\r
+  if (EFI_ERROR (Status)) {\r
+    ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;\r
+    return Status;\r
+  }\r
+\r
+  ImageContext->PeCoffHeaderOffset = 0;\r
+  if (DosHdr.e_magic == EFI_IMAGE_DOS_SIGNATURE) {\r
+    //\r
+    // DOS image header is present, so read the PE header after the DOS image header\r
+    //\r
+    ImageContext->PeCoffHeaderOffset = DosHdr.e_lfanew;\r
+  } \r
+\r
+  //\r
+  // Read the PE/COFF Header\r
+  //\r
+  Size = sizeof (EFI_IMAGE_NT_HEADERS64);\r
+  Status = ImageContext->ImageRead (\r
+                           ImageContext->Handle, \r
+                           ImageContext->PeCoffHeaderOffset, \r
+                           &Size, \r
+                           PeHdr\r
+                           );\r
+  if (EFI_ERROR (Status)) {\r
+      ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;\r
+      return Status;\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+static\r
+EFI_STATUS\r
+PeCoffLoader64CheckImageType (\r
+  IN OUT PE_COFF_LOADER_IMAGE_CONTEXT      *ImageContext,\r
+  IN     EFI_IMAGE_NT_HEADERS64                    *PeHdr\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+  Checks the PE header of a PE/COFF image to determine if it supported\r
+\r
+Arguments:\r
+  ImageContext  - The context of the image being loaded\r
+  PeHdr         - The buffer in which to return the PE header\r
+\r
+Returns:\r
+  EFI_SUCCESS if the PE/COFF image is supported\r
+  EFI_UNSUPPORTED of the PE/COFF image is not supported.\r
+\r
+--*/\r
+{\r
+  //\r
+  // Check the PE/COFF Header SIgnature\r
+  //\r
+  if (PeHdr->Signature != EFI_IMAGE_NT_SIGNATURE) {\r
+    ImageContext->ImageError = IMAGE_ERROR_INVALID_PE_HEADER_SIGNATURE;\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  //\r
+  // See if the machine type is supported.  We support a native machine type (IA-32/Itanium-based)\r
+  // and the machine type for the Virtual Machine.\r
+  //\r
+  ImageContext->Machine = PeHdr->FileHeader.Machine;\r
+  if (!(IMAGE_64_MACHINE_TYPE_SUPPORTED (ImageContext->Machine))) {\r
+    ImageContext->ImageError = IMAGE_ERROR_INVALID_MACHINE_TYPE;\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  //\r
+  // See if the image type is supported.  We support EFI Applications, \r
+  // EFI Boot Service Drivers, and EFI Runtime Drivers.\r
+  //\r
+  ImageContext->ImageType = PeHdr->OptionalHeader.Subsystem;\r
+  switch (ImageContext->ImageType) {\r
+\r
+  case EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION:\r
+    ImageContext->ImageCodeMemoryType = EfiLoaderCode;\r
+    ImageContext->ImageDataMemoryType = EfiLoaderData;\r
+    break;\r
+  \r
+  case EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER:\r
+    ImageContext->ImageCodeMemoryType = EfiBootServicesCode;\r
+    ImageContext->ImageDataMemoryType = EfiBootServicesData;\r
+    break;\r
+  \r
+  case EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER:\r
+  case EFI_IMAGE_SUBSYSTEM_SAL_RUNTIME_DRIVER:\r
+    ImageContext->ImageCodeMemoryType = EfiRuntimeServicesCode;\r
+    ImageContext->ImageDataMemoryType = EfiRuntimeServicesData;\r
+    break;\r
+  \r
+  default:\r
+    ImageContext->ImageError = IMAGE_ERROR_INVALID_SUBSYSTEM;\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PeCoffLoader64GetImageInfo (\r
+  IN     EFI_PEI_PE_COFF_LOADER_PROTOCOL           *This,\r
+  IN OUT PE_COFF_LOADER_IMAGE_CONTEXT      *ImageContext\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+  Retrieves information on a PE/COFF image\r
+\r
+Arguments:\r
+  ImageContext  - The context of the image being loaded\r
+  PeHdr         - The buffer in which to return the PE header\r
+\r
+Returns:\r
+  EFI_SUCCESS if the information on the PE/COFF image was collected.\r
+  EFI_UNSUPPORTED of the PE/COFF image is not supported.\r
+  Otherwise, the error status from reading the PE/COFF image using the \r
+    ImageContext->ImageRead() function\r
+\r
+--*/\r
+{\r
+  EFI_STATUS                      Status;\r
+  EFI_IMAGE_NT_HEADERS64          PeHdr;\r
+  EFI_IMAGE_DATA_DIRECTORY        *DebugDirectoryEntry;\r
+  UINTN                           Size;\r
+  UINTN                           Index;\r
+  UINTN                           DebugDirectoryEntryRva;\r
+  UINTN                           DebugDirectoryEntryFileOffset;\r
+  UINTN                           SectionHeaderOffset;\r
+  EFI_IMAGE_SECTION_HEADER        SectionHeader;\r
+  EFI_IMAGE_DEBUG_DIRECTORY_ENTRY DebugEntry;\r
+\r
+  if (NULL == ImageContext) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  //\r
+  // Assume success\r
+  //\r
+  ImageContext->ImageError = IMAGE_ERROR_SUCCESS;\r
+  \r
+  Status = PeCoffLoader64GetPeHeader (ImageContext, &PeHdr);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  //\r
+  // Verify machine type\r
+  //\r
+  Status = PeCoffLoader64CheckImageType (ImageContext, &PeHdr);\r
+  if (EFI_ERROR(Status)) {\r
+    return Status;\r
+  }\r
+\r
+  //\r
+  // Retrieve the base address of the image\r
+  //\r
+  ImageContext->ImageAddress = PeHdr.OptionalHeader.ImageBase;\r
+  \r
+  //\r
+  // Initialize the alternate destination address to 0 indicating that it \r
+  // should not be used.\r
+  //\r
+  ImageContext->DestinationAddress = 0;\r
+\r
+  //\r
+  // Initialize the codeview pointer.\r
+  //\r
+  ImageContext->CodeView   = NULL;\r
+  ImageContext->PdbPointer = NULL;\r
+  \r
+  //\r
+  // Three cases with regards to relocations:\r
+  // - Image has base relocs, RELOCS_STRIPPED==0    => image is relocatable\r
+  // - Image has no base relocs, RELOCS_STRIPPED==1 => Image is not relocatable\r
+  // - Image has no base relocs, RELOCS_STRIPPED==0 => Image is relocatable but\r
+  //   has no base relocs to apply\r
+  // Obviously having base relocations with RELOCS_STRIPPED==1 is invalid.\r
+  //\r
+  // Look at the file header to determine if relocations have been stripped, and\r
+  // save this info in the image context for later use.\r
+  //\r
+  if (PeHdr.FileHeader.Characteristics &  EFI_IMAGE_FILE_RELOCS_STRIPPED) {\r
+    ImageContext->RelocationsStripped = TRUE;\r
+  } else {\r
+    ImageContext->RelocationsStripped = FALSE;\r
+  }\r
+\r
+  ImageContext->ImageSize        = (UINT64)PeHdr.OptionalHeader.SizeOfImage;\r
+  ImageContext->SectionAlignment = PeHdr.OptionalHeader.SectionAlignment;\r
+  ImageContext->SizeOfHeaders    = PeHdr.OptionalHeader.SizeOfHeaders; \r
+\r
+  //\r
+  // Modify ImageSize to contain .PDB file name if required and initialize\r
+  // PdbRVA field...\r
+  //\r
+\r
+  if (PeHdr.OptionalHeader.NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_DEBUG) {\r
+    DebugDirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *)\r
+      &(PeHdr.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG]);\r
+\r
+    DebugDirectoryEntryRva = DebugDirectoryEntry->VirtualAddress;\r
+\r
+    //\r
+    // Determine the file offset of the debug directory...  This means we walk\r
+    // the sections to find which section contains the RVA of the debug\r
+    // directory\r
+    //\r
+    \r
+    DebugDirectoryEntryFileOffset = 0;\r
+    \r
+    SectionHeaderOffset = (UINTN) (\r
+                      ImageContext->PeCoffHeaderOffset +\r
+                      sizeof (UINT32) + \r
+                      sizeof (EFI_IMAGE_FILE_HEADER) + \r
+                      PeHdr.FileHeader.SizeOfOptionalHeader\r
+                      );\r
+    \r
+    for (Index = 0; Index < PeHdr.FileHeader.NumberOfSections; Index += 1) {\r
+      //\r
+      // Read section header from file\r
+      //\r
+      Size = sizeof (EFI_IMAGE_SECTION_HEADER);\r
+      Status = ImageContext->ImageRead (\r
+                               ImageContext->Handle, \r
+                               SectionHeaderOffset, \r
+                               &Size, \r
+                               &SectionHeader\r
+                               );\r
+      if (EFI_ERROR (Status)) {\r
+        ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;\r
+        return Status;\r
+      }\r
+      \r
+      if (DebugDirectoryEntryRva >= SectionHeader.VirtualAddress &&\r
+          DebugDirectoryEntryRva < SectionHeader.VirtualAddress + SectionHeader.Misc.VirtualSize) {\r
+        DebugDirectoryEntryFileOffset = DebugDirectoryEntryRva - SectionHeader.VirtualAddress + SectionHeader.PointerToRawData;\r
+        break;\r
+      }\r
+      \r
+      SectionHeaderOffset += sizeof (EFI_IMAGE_SECTION_HEADER);\r
+    }\r
+    \r
+    if (DebugDirectoryEntryFileOffset != 0) {\r
+      for (Index = 0; Index < DebugDirectoryEntry->Size; Index++) {\r
+        //\r
+        // Read next debug directory entry\r
+        //\r
+        Size = sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY);\r
+        Status = ImageContext->ImageRead (\r
+                                 ImageContext->Handle, \r
+                                 DebugDirectoryEntryFileOffset, \r
+                                 &Size, \r
+                                 &DebugEntry\r
+                                 );\r
+        if (EFI_ERROR (Status)) {\r
+          ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;\r
+          return Status;\r
+        }\r
+        if (DebugEntry.Type == EFI_IMAGE_DEBUG_TYPE_CODEVIEW) {\r
+          ImageContext->DebugDirectoryEntryRva = (UINT32) (DebugDirectoryEntryRva + Index * sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY));\r
+          if (DebugEntry.RVA == 0 && DebugEntry.FileOffset != 0) {\r
+            ImageContext->ImageSize += DebugEntry.SizeOfData;\r
+          }\r
+          return EFI_SUCCESS;\r
+        }\r
+      }\r
+    }\r
+  }\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+static\r
+VOID *\r
+PeCoffLoader64ImageAddress (\r
+  IN OUT PE_COFF_LOADER_IMAGE_CONTEXT      *ImageContext,\r
+  IN     UINTN                                     Address\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+  Converts an image address to the loaded address\r
+\r
+Arguments:\r
+  ImageContext  - The context of the image being loaded\r
+  Address       - The address to be converted to the loaded address\r
+\r
+Returns:\r
+  NULL if the address can not be converted, otherwise, the converted address\r
+\r
+--*/\r
+{\r
+  if (Address >= ImageContext->ImageSize) {\r
+    ImageContext->ImageError = IMAGE_ERROR_INVALID_IMAGE_ADDRESS;\r
+    return NULL;\r
+  }\r
+  return (CHAR8 *)((UINTN)ImageContext->ImageAddress + Address);\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PeCoffLoader64RelocateImage (\r
+  IN     EFI_PEI_PE_COFF_LOADER_PROTOCOL           *This,\r
+  IN OUT PE_COFF_LOADER_IMAGE_CONTEXT      *ImageContext\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+  Relocates a PE/COFF image in memory\r
+\r
+Arguments:\r
+  ImageContext - Contains information on the loaded image to relocate\r
+\r
+Returns:\r
+  EFI_SUCCESS    if the PE/COFF image was relocated\r
+  EFI_LOAD_ERROR if the image is not a valid PE/COFF image\r
+\r
+--*/\r
+{\r
+  EFI_STATUS                 Status;\r
+  EFI_IMAGE_NT_HEADERS64     *PeHdr;\r
+  EFI_IMAGE_DATA_DIRECTORY   *RelocDir;\r
+  IN UINT64                  Adjust;\r
+  EFI_IMAGE_BASE_RELOCATION  *RelocBase;\r
+  EFI_IMAGE_BASE_RELOCATION  *RelocBaseEnd;\r
+  UINT16                     *Reloc;\r
+  UINT16                     *RelocEnd;\r
+  CHAR8                      *Fixup;\r
+  CHAR8                      *FixupBase;\r
+  UINT16                     *F16;\r
+  UINT32                     *F32;\r
+  CHAR8                      *FixupData;\r
+  EFI_PHYSICAL_ADDRESS       BaseAddress;\r
+\r
+\r
+  //\r
+  // Assume success\r
+  //\r
+  ImageContext->ImageError = IMAGE_ERROR_SUCCESS;\r
+\r
+  //\r
+  // If there are no relocation entries, then we are done\r
+  //\r
+  if (ImageContext->RelocationsStripped) {\r
+    return EFI_SUCCESS;\r
+  }\r
+\r
+  //\r
+  // If the destination address is not 0, use that rather than the\r
+  // image address as the relocation target.\r
+  //\r
+  if (ImageContext->DestinationAddress) {\r
+    BaseAddress = ImageContext->DestinationAddress;\r
+  } else {\r
+    BaseAddress = ImageContext->ImageAddress;\r
+  }\r
+  PeHdr    = (EFI_IMAGE_NT_HEADERS64 *)((UINTN)ImageContext->ImageAddress + \r
+                                            ImageContext->PeCoffHeaderOffset);\r
+  Adjust   = (UINT64) BaseAddress - PeHdr->OptionalHeader.ImageBase;\r
+\r
+  PeHdr->OptionalHeader.ImageBase = (UINTN) BaseAddress;\r
+\r
+  //\r
+  // Find the relocation block\r
+  //\r
+  // Per the PE/COFF spec, you can't assume that a given data directory \r
+  // is present in the image. You have to check the NumberOfRvaAndSizes in \r
+  // the optional header to verify a desired directory entry is there.\r
+  //\r
+  if (PeHdr->OptionalHeader.NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC) {\r
+    RelocDir = &PeHdr->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC];\r
+    RelocBase = PeCoffLoader64ImageAddress (ImageContext, RelocDir->VirtualAddress);\r
+    RelocBaseEnd = PeCoffLoader64ImageAddress ( \r
+                    ImageContext, \r
+                    RelocDir->VirtualAddress + RelocDir->Size - 1\r
+                    );\r
+} else {\r
+    //\r
+    // Set base and end to bypass processing below.\r
+    //\r
+    RelocBase = RelocBaseEnd = 0;\r
+  }\r
+  //\r
+  // Run the relocation information and apply the fixups\r
+  //\r
+  FixupData = ImageContext->FixupData;\r
+  while (RelocBase < RelocBaseEnd) {\r
+           \r
+    Reloc     = (UINT16 *) ((CHAR8 *) RelocBase + sizeof(EFI_IMAGE_BASE_RELOCATION));\r
+    RelocEnd  = (UINT16 *) ((CHAR8 *) RelocBase + RelocBase->SizeOfBlock);\r
+    FixupBase = PeCoffLoader64ImageAddress (ImageContext, RelocBase->VirtualAddress);\r
+    if ((CHAR8 *) RelocEnd < (CHAR8 *)((UINTN)ImageContext->ImageAddress) || \r
+        (CHAR8 *) RelocEnd > (CHAR8 *)((UINTN)ImageContext->ImageAddress + \r
+          (UINTN)ImageContext->ImageSize)) {\r
+      ImageContext->ImageError = IMAGE_ERROR_FAILED_RELOCATION;\r
+      return EFI_LOAD_ERROR;\r
+    }\r
+\r
+    //\r
+    // Run this relocation record\r
+    //\r
+    while (Reloc < RelocEnd) {\r
+\r
+      Fixup = FixupBase + (*Reloc & 0xFFF);\r
+      switch ((*Reloc) >> 12) {\r
+      case EFI_IMAGE_REL_BASED_ABSOLUTE:\r
+        break;\r
+      case EFI_IMAGE_REL_BASED_HIGH:\r
+        F16 = (UINT16 *) Fixup;\r
+        *F16 = (UINT16)((*F16 << 16) + (UINT16) Adjust);\r
+        if (FixupData != NULL) {\r
+          *(UINT16 *) FixupData = *F16;\r
+          FixupData = FixupData + sizeof(UINT16);\r
+        }\r
+        break;\r
+      case EFI_IMAGE_REL_BASED_LOW:\r
+        F16 = (UINT16 *) Fixup;\r
+        *F16 = (UINT16)(*F16 + (UINT16) Adjust);\r
+        if (FixupData != NULL) {\r
+          *(UINT16 *) FixupData = *F16;\r
+          FixupData = FixupData + sizeof(UINT16);\r
+        }\r
+        break;\r
+      case EFI_IMAGE_REL_BASED_HIGHLOW:\r
+        F32 = (UINT32 *) Fixup;\r
+        *F32 = *F32 + (UINT32) Adjust;\r
+        if (FixupData != NULL) {\r
+          FixupData = ALIGN_POINTER(FixupData, sizeof(UINT32));\r
+          *(UINT32 *) FixupData = *F32;\r
+          FixupData = FixupData + sizeof(UINT32);\r
+        }\r
+        break;\r
+      case EFI_IMAGE_REL_BASED_HIGHADJ:\r
+        // Return the same EFI_UNSUPPORTED return code as \r
+        // PeCoffLoader64RelocateImageEx() returns if it does not recognize\r
+        // the relocation type.\r
+        //\r
+        ImageContext->ImageError = IMAGE_ERROR_FAILED_RELOCATION;\r
+        return EFI_UNSUPPORTED;\r
+      default:\r
+        Status = PeCoffLoader64RelocateImageEx (Reloc, Fixup, &FixupData, Adjust);\r
+        if (EFI_ERROR (Status)) {\r
+          ImageContext->ImageError = IMAGE_ERROR_FAILED_RELOCATION;\r
+          return Status;\r
+        }\r
+      }\r
+\r
+      //\r
+      // Next relocation record\r
+      //\r
+      Reloc += 1;\r
+    }\r
+\r
+    //\r
+    // Next reloc block\r
+    //\r
+    RelocBase = (EFI_IMAGE_BASE_RELOCATION *) RelocEnd;\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+\r
+EFI_STATUS\r
+PeCoffLoader64RelocateImageEx (\r
+  IN UINT16      *Reloc,\r
+  IN OUT CHAR8   *Fixup, \r
+  IN OUT CHAR8   **FixupData,\r
+  IN UINT64      Adjust\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+  Performs an IA-32 specific relocation fixup\r
+\r
+Arguments:\r
+  Reloc      - Pointer to the relocation record\r
+  Fixup      - Pointer to the address to fix up\r
+  FixupData  - Pointer to a buffer to log the fixups\r
+  Adjust     - The offset to adjust the fixup\r
+\r
+Returns:\r
+  None\r
+\r
+--*/\r
+{\r
+  UINT64      *F64;\r
+\r
+  switch ((*Reloc) >> 12) {\r
+\r
+    case EFI_IMAGE_REL_BASED_DIR64:\r
+      F64 = (UINT64 *) Fixup;\r
+      *F64 = *F64 + (UINT64) Adjust;\r
+      if (*FixupData != NULL) {\r
+        *FixupData = ALIGN_POINTER(*FixupData, sizeof(UINT64));\r
+        *(UINT64 *)(*FixupData) = *F64;\r
+        *FixupData = *FixupData + sizeof(UINT64);\r
+      }\r
+      break;\r
+\r
+    default:\r
+      return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PeCoffLoader64LoadImage (\r
+  IN     EFI_PEI_PE_COFF_LOADER_PROTOCOL           *This,\r
+  IN OUT PE_COFF_LOADER_IMAGE_CONTEXT      *ImageContext\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+  Loads a PE/COFF image into memory\r
+\r
+Arguments:\r
+  ImageContext - Contains information on image to load into memory\r
+\r
+Returns:\r
+  EFI_SUCCESS            if the PE/COFF image was loaded\r
+  EFI_BUFFER_TOO_SMALL   if the caller did not provide a large enough buffer\r
+  EFI_LOAD_ERROR         if the image is a runtime driver with no relocations\r
+  EFI_INVALID_PARAMETER  if the image address is invalid\r
+\r
+--*/\r
+{\r
+  EFI_STATUS                            Status;\r
+  EFI_IMAGE_NT_HEADERS64                *PeHdr;\r
+  PE_COFF_LOADER_IMAGE_CONTEXT  CheckContext;\r
+  EFI_IMAGE_SECTION_HEADER              *FirstSection;\r
+  EFI_IMAGE_SECTION_HEADER              *Section;\r
+  UINTN                                 Index;\r
+  CHAR8                                 *Base;\r
+  CHAR8                                 *End;\r
+  CHAR8                                 *MaxEnd;\r
+  EFI_IMAGE_DATA_DIRECTORY              *DirectoryEntry;\r
+  EFI_IMAGE_DEBUG_DIRECTORY_ENTRY       *DebugEntry;\r
+  UINTN                                 Size;\r
+  UINT32                                TempDebugEntryRva;\r
+\r
+  //\r
+  // Assume success\r
+  //\r
+  ImageContext->ImageError = IMAGE_ERROR_SUCCESS;\r
+\r
+  //\r
+  // Copy the provided context info into our local version, get what we\r
+  // can from the original image, and then use that to make sure everything\r
+  // is legit.\r
+  //\r
+  CopyMem (\r
+    &CheckContext, \r
+    ImageContext, \r
+    sizeof (PE_COFF_LOADER_IMAGE_CONTEXT)\r
+    );\r
+            \r
+  Status = PeCoffLoader64GetImageInfo (\r
+             This,\r
+             &CheckContext \r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  //\r
+  // Make sure there is enough allocated space for the image being loaded\r
+  //\r
+  if (ImageContext->ImageSize < CheckContext.ImageSize) {\r
+    ImageContext->ImageError = IMAGE_ERROR_INVALID_IMAGE_SIZE;\r
+    return EFI_BUFFER_TOO_SMALL;\r
+  }\r
+\r
+  //\r
+  // If there's no relocations, then make sure it's not a runtime driver,\r
+  // and that it's being loaded at the linked address.\r
+  //\r
+  if (CheckContext.RelocationsStripped == TRUE) {\r
+    //\r
+    // If the image does not contain relocations and it is a runtime driver \r
+    // then return an error.\r
+    //\r
+    if (CheckContext.ImageType == EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER) {\r
+      ImageContext->ImageError = IMAGE_ERROR_INVALID_SUBSYSTEM;\r
+      return EFI_LOAD_ERROR;\r
+    }\r
+    //\r
+    // If the image does not contain relocations, and the requested load address \r
+    // is not the linked address, then return an error.\r
+    //\r
+    if (CheckContext.ImageAddress != ImageContext->ImageAddress) {\r
+      ImageContext->ImageError = IMAGE_ERROR_INVALID_IMAGE_ADDRESS;\r
+      return EFI_INVALID_PARAMETER;\r
+    }\r
+  }\r
+\r
+  //\r
+  // Make sure the allocated space has the proper section alignment\r
+  //\r
+  if ((ImageContext->ImageAddress & (CheckContext.SectionAlignment - 1)) != 0) {\r
+    ImageContext->ImageError = IMAGE_ERROR_INVALID_SECTION_ALIGNMENT;\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  //\r
+  // Read the entire PE/COFF header into memory\r
+  //\r
+  Status = ImageContext->ImageRead (\r
+                ImageContext->Handle, \r
+                0, \r
+                &ImageContext->SizeOfHeaders, \r
+                (VOID *)(UINTN)ImageContext->ImageAddress\r
+                );\r
+  if (EFI_ERROR(Status)) {\r
+    ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;\r
+    return EFI_LOAD_ERROR;\r
+  }\r
+\r
+  PeHdr = (EFI_IMAGE_NT_HEADERS64 *)\r
+      ((UINTN)ImageContext->ImageAddress + ImageContext->PeCoffHeaderOffset);\r
+\r
+  //\r
+  // Load each section of the image\r
+  //\r
+  FirstSection = (EFI_IMAGE_SECTION_HEADER *) (\r
+                      (UINTN)ImageContext->ImageAddress +\r
+                      ImageContext->PeCoffHeaderOffset +\r
+                      sizeof(UINT32) + \r
+                      sizeof(EFI_IMAGE_FILE_HEADER) + \r
+                      PeHdr->FileHeader.SizeOfOptionalHeader\r
+                      );\r
+\r
+  Section = FirstSection;\r
+  for ( Index=0, MaxEnd = NULL; \r
+        Index < PeHdr->FileHeader.NumberOfSections; \r
+        Index += 1) {\r
+\r
+    //\r
+    // Compute sections address\r
+    //\r
+    Base = PeCoffLoader64ImageAddress (ImageContext, Section->VirtualAddress);\r
+    End  = PeCoffLoader64ImageAddress (\r
+                  ImageContext, \r
+                  Section->VirtualAddress + Section->Misc.VirtualSize - 1);\r
+    if (End > MaxEnd) {\r
+      MaxEnd = End;\r
+    }\r
+    //\r
+    // If the base start or end address resolved to 0, then fail.\r
+    //\r
+    if (!Base  ||  !End) {\r
+      ImageContext->ImageError = IMAGE_ERROR_SECTION_NOT_LOADED;\r
+      return EFI_LOAD_ERROR;\r
+    }\r
+\r
+    //\r
+    // Read the section, we can resume the length of PE image can't \r
+    // exceed the max 32bit integer\r
+    //\r
+    Size = (UINTN) Section->Misc.VirtualSize;\r
+    if ((Size == 0) || (Size > Section->SizeOfRawData)) {\r
+      Size = (UINTN) Section->SizeOfRawData;\r
+    }\r
+    if (Section->SizeOfRawData) {\r
+      Status = ImageContext->ImageRead (\r
+                               ImageContext->Handle, \r
+                               Section->PointerToRawData, \r
+                               &Size, \r
+                               Base);\r
+      if (EFI_ERROR(Status)) {\r
+        ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;\r
+        return Status;\r
+      }\r
+    }\r
+\r
+    //\r
+    // If raw size is less then virt size, zero fill the remaining\r
+    //\r
+\r
+    if (Size < Section->Misc.VirtualSize) {\r
+      ZeroMem (Base + Size, Section->Misc.VirtualSize - (UINTN)Size);\r
+    }\r
+\r
+    //\r
+    // Next Section\r
+    //\r
+    Section += 1;\r
+  }\r
+\r
+  //\r
+  // Get image's entry point\r
+  //\r
+  ImageContext->EntryPoint = \r
+      (EFI_PHYSICAL_ADDRESS) (UINTN) PeCoffLoader64ImageAddress (\r
+                                      ImageContext, \r
+                                      PeHdr->OptionalHeader.AddressOfEntryPoint\r
+                                      );\r
+\r
+  //\r
+  // Determine the size of the fixup data\r
+  //\r
+  // Per the PE/COFF spec, you can't assume that a given data directory \r
+  // is present in the image. You have to check the NumberOfRvaAndSizes in \r
+  // the optional header to verify a desired directory entry is there.\r
+  //\r
+  if (PeHdr->OptionalHeader.NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC) {\r
+    DirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *)\r
+      &PeHdr->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC];\r
+    ImageContext->FixupDataSize = \r
+      DirectoryEntry->Size / sizeof(UINT16) * sizeof(UINTN);\r
+  } else {\r
+    ImageContext->FixupDataSize = 0;\r
+  }\r
+  //\r
+  // Consumer must allocate a buffer for the relocation fixup log.\r
+  // Only used for runtime drivers.\r
+  //\r
+  ImageContext->FixupData     = NULL;\r
+\r
+  //\r
+  // Load the Codeview info if present\r
+  //\r
+  if (ImageContext->DebugDirectoryEntryRva != 0) {\r
+    DebugEntry = PeCoffLoader64ImageAddress (\r
+                  ImageContext, \r
+                  ImageContext->DebugDirectoryEntryRva\r
+                  );\r
+    if (DebugEntry != NULL) {\r
+      TempDebugEntryRva = DebugEntry->RVA;\r
+      if (DebugEntry->RVA == 0 && DebugEntry->FileOffset != 0) {\r
+        Section--;\r
+        if ((UINTN) Section->SizeOfRawData < Section->Misc.VirtualSize) {\r
+          TempDebugEntryRva = Section->VirtualAddress + Section->Misc.VirtualSize;\r
+        } else {\r
+          TempDebugEntryRva = Section->VirtualAddress + Section->SizeOfRawData;\r
+        }\r
+      }\r
+      if (TempDebugEntryRva != 0) {\r
+        ImageContext->CodeView = PeCoffLoader64ImageAddress (ImageContext, TempDebugEntryRva);\r
+        if (ImageContext->CodeView == NULL) {\r
+          ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;\r
+          return EFI_LOAD_ERROR;\r
+        }\r
+\r
+        if (DebugEntry->RVA == 0) {\r
+          Size = (UINTN) DebugEntry->SizeOfData;\r
+          Status = ImageContext->ImageRead (\r
+                        ImageContext->Handle, \r
+                        DebugEntry->FileOffset,\r
+                        &Size, \r
+                        ImageContext->CodeView\r
+                        );\r
+          if (EFI_ERROR(Status)) {\r
+            ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;\r
+            return EFI_LOAD_ERROR;\r
+          }\r
+          DebugEntry->RVA = TempDebugEntryRva;\r
+        }\r
+\r
+        switch (* (UINT32 *) ImageContext->CodeView) {\r
+          case CODEVIEW_SIGNATURE_NB10:\r
+            ImageContext->PdbPointer = (CHAR8 *) ImageContext->CodeView + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY);\r
+            break;\r
+          case CODEVIEW_SIGNATURE_RSDS:\r
+            ImageContext->PdbPointer = (CHAR8 *) ImageContext->CodeView + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_RSDS_ENTRY);\r
+            break;\r
+          default:\r
+            break;\r
+        }\r
+      }\r
+    }\r
+  }\r
+  \r
+  return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PeCoffLoader64UnloadImage (\r
+  IN EFI_PEI_PE_COFF_LOADER_PROTOCOL      *This,\r
+  IN PE_COFF_LOADER_IMAGE_CONTEXT   *ImageContext\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+  Unload of images is not supported\r
+\r
+Arguments:\r
+  ImageContext - The image to unload\r
+\r
+Returns:\r
+  EFI_SUCCESS\r
+\r
+--*/\r
+{\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+EFI_PEI_PE_COFF_LOADER_PROTOCOL *\r
+EFIAPI\r
+GetPeCoffLoaderProtocol (\r
+  )\r
+{\r
+  return &mPeCoffLoaderX64;\r
+}\r
+\r
+\r