+/*++\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
+ PeiCoreNt32PeCoffLib.c\r
+\r
+Abstract:\r
+\r
+ Wrap the Nt32 PE/COFF loader with the PE COFF LOADER guid structure\r
+ to produce PeCoff library class.\r
+\r
+\r
+--*/\r
+\r
+#include <PiPei.h>\r
+#include <Guid/PeiPeCoffLoader.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/PeCoffLib.h>\r
+#include <Library/HobLib.h>\r
+#include <Library/PeiServicesLib.h>\r
+\r
+EFI_PEI_PE_COFF_LOADER_PROTOCOL *mPeiEfiPeiPeCoffLoader = NULL;\r
+\r
+/**\r
+ The function caches the pointer of PeCofferLoader guid structure\r
+ into the guid data hob.\r
+\r
+ The funtion must be called after PeCofferLoader guid structure is installed.\r
+ It will ASSERT() if PeCofferLoader guid structure is not installed.\r
+\r
+ @retval EFI_SUCCESS PeCofferLoader guid structure is found.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+GetPeCoffLoaderStucture (\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_HOB_GUID_TYPE *GuidHob;\r
+\r
+ Status = EFI_NOT_FOUND;\r
+ \r
+ //\r
+ // Try to get guid data hob that contains PeCoffLoader guid structure.\r
+ //\r
+ GuidHob = GetFirstGuidHob (&gEfiPeiPeCoffLoaderGuid);\r
+\r
+ if (GuidHob == NULL) {\r
+ //\r
+ // GuidHob is not ready, try to locate PeCoffLoader guid structure.\r
+ //\r
+ Status = PeiServicesLocatePpi (\r
+ &gEfiPeiPeCoffLoaderGuid,\r
+ 0,\r
+ NULL,\r
+ &mPeiEfiPeiPeCoffLoader\r
+ );\r
+ \r
+ //\r
+ // PeCofferLoader guid structure must be installed before this library runs.\r
+ //\r
+ ASSERT_EFI_ERROR (Status);\r
+ \r
+ //\r
+ // Build guid data hob of PeCofferLoader guid structure for DXE module use. \r
+ //\r
+ BuildGuidDataHob (\r
+ &gEfiPeiPeCoffLoaderGuid,\r
+ (VOID *) &mPeiEfiPeiPeCoffLoader,\r
+ sizeof (VOID *)\r
+ );\r
+ } else {\r
+ //\r
+ // Get PeCofferLoader guid structure directly from guid hob data.\r
+ //\r
+ mPeiEfiPeiPeCoffLoader = (EFI_PEI_PE_COFF_LOADER_PROTOCOL *)(*(UINTN *)(GET_GUID_HOB_DATA (GuidHob)));\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+ Retrieves information about a PE/COFF image.\r
+\r
+ Computes the PeCoffHeaderOffset, ImageAddress, ImageSize, DestinationAddress, CodeView,\r
+ PdbPointer, RelocationsStripped, SectionAlignment, SizeOfHeaders, and DebugDirectoryEntryRva\r
+ fields of the ImageContext structure. If ImageContext is NULL, then return RETURN_INVALID_PARAMETER.\r
+ If the PE/COFF image accessed through the ImageRead service in the ImageContext structure is not\r
+ a supported PE/COFF image type, then return RETURN_UNSUPPORTED. If any errors occur while\r
+ computing the fields of ImageContext, then the error status is returned in the ImageError field of\r
+ ImageContext. \r
+\r
+ @param ImageContext Pointer to the image context structure that describes the PE/COFF\r
+ image that needs to be examined by this function.\r
+\r
+ @retval RETURN_SUCCESS The information on the PE/COFF image was collected.\r
+ @retval RETURN_INVALID_PARAMETER ImageContext is NULL.\r
+ @retval RETURN_UNSUPPORTED The PE/COFF image is not supported.\r
+\r
+**/\r
+RETURN_STATUS\r
+EFIAPI\r
+PeCoffLoaderGetImageInfo (\r
+ IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext\r
+ )\r
+{\r
+ if (mPeiEfiPeiPeCoffLoader == NULL) {\r
+ GetPeCoffLoaderStucture ();\r
+ }\r
+ return mPeiEfiPeiPeCoffLoader->GetImageInfo (mPeiEfiPeiPeCoffLoader, ImageContext);\r
+}\r
+\r
+/**\r
+ Applies relocation fixups to a PE/COFF image that was loaded with PeCoffLoaderLoadImage().\r
+\r
+ If the DestinationAddress field of ImageContext is 0, then use the ImageAddress field of\r
+ ImageContext as the relocation base address. Otherwise, use the DestinationAddress field\r
+ of ImageContext as the relocation base address. The caller must allocate the relocation\r
+ fixup log buffer and fill in the FixupData field of ImageContext prior to calling this function. \r
+ If ImageContext is NULL, then ASSERT().\r
+\r
+ @param ImageContext Pointer to the image context structure that describes the PE/COFF\r
+ image that is being relocated.\r
+\r
+ @retval RETURN_SUCCESS The PE/COFF image was relocated.\r
+ Extended status information is in the ImageError field of ImageContext.\r
+ @retval RETURN_LOAD_ERROR The image in not a valid PE/COFF image.\r
+ Extended status information is in the ImageError field of ImageContext.\r
+ @retval RETURN_UNSUPPORTED A relocation record type is not supported.\r
+ Extended status information is in the ImageError field of ImageContext.\r
+\r
+**/\r
+RETURN_STATUS\r
+EFIAPI\r
+PeCoffLoaderRelocateImage (\r
+ IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext\r
+ )\r
+{\r
+ if (mPeiEfiPeiPeCoffLoader == NULL) {\r
+ GetPeCoffLoaderStucture ();\r
+ }\r
+ return mPeiEfiPeiPeCoffLoader->RelocateImage (mPeiEfiPeiPeCoffLoader, ImageContext);\r
+}\r
+\r
+/**\r
+ Loads a PE/COFF image into memory.\r
+\r
+ Loads the PE/COFF image accessed through the ImageRead service of ImageContext into the buffer\r
+ specified by the ImageAddress and ImageSize fields of ImageContext. The caller must allocate\r
+ the load buffer and fill in the ImageAddress and ImageSize fields prior to calling this function.\r
+ The EntryPoint, FixupDataSize, CodeView, and PdbPointer fields of ImageContext are computed.\r
+ If ImageContext is NULL, then ASSERT().\r
+\r
+ @param ImageContext Pointer to the image context structure that describes the PE/COFF\r
+ image that is being loaded.\r
+\r
+ @retval RETURN_SUCCESS The PE/COFF image was loaded into the buffer specified by\r
+ the ImageAddress and ImageSize fields of ImageContext.\r
+ Extended status information is in the ImageError field of ImageContext.\r
+ @retval RETURN_BUFFER_TOO_SMALL The caller did not provide a large enough buffer.\r
+ Extended status information is in the ImageError field of ImageContext.\r
+ @retval RETURN_LOAD_ERROR The PE/COFF image is an EFI Runtime image with no relocations.\r
+ Extended status information is in the ImageError field of ImageContext.\r
+ @retval RETURN_INVALID_PARAMETER The image address is invalid.\r
+ Extended status information is in the ImageError field of ImageContext.\r
+\r
+**/\r
+RETURN_STATUS\r
+EFIAPI\r
+PeCoffLoaderLoadImage (\r
+ IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext\r
+ )\r
+{\r
+ if (mPeiEfiPeiPeCoffLoader == NULL) {\r
+ GetPeCoffLoaderStucture ();\r
+ }\r
+ return mPeiEfiPeiPeCoffLoader->LoadImage (mPeiEfiPeiPeCoffLoader, ImageContext);\r
+}\r
+\r
+/**\r
+ ImageRead function that operates on a memory buffer whos base is passed into\r
+ FileHandle. \r
+\r
+ @param FileHandle Ponter to baes of the input stream\r
+ @param FileOffset Offset to the start of the buffer\r
+ @param ReadSize Number of bytes to copy into the buffer\r
+ @param Buffer Location to place results of read\r
+\r
+ @retval RETURN_SUCCESS Data is read from FileOffset from the Handle into \r
+ the buffer.\r
+**/\r
+RETURN_STATUS\r
+EFIAPI\r
+PeCoffLoaderImageReadFromMemory (\r
+ IN VOID *FileHandle,\r
+ IN UINTN FileOffset,\r
+ IN OUT UINTN *ReadSize,\r
+ OUT VOID *Buffer\r
+ )\r
+{\r
+ return RETURN_UNSUPPORTED;\r
+}\r
+\r
+\r
+/**\r
+ Reapply fixups on a fixed up PE32/PE32+ image to allow virutal calling at EFI\r
+ runtime. \r
+ \r
+ PE_COFF_LOADER_IMAGE_CONTEXT.FixupData stores information needed to reapply\r
+ the fixups with a virtual mapping.\r
+\r
+\r
+ @param ImageBase Base address of relocated image\r
+ @param VirtImageBase Virtual mapping for ImageBase\r
+ @param ImageSize Size of the image to relocate\r
+ @param RelocationData Location to place results of read\r
+ \r
+**/\r
+VOID\r
+EFIAPI\r
+PeCoffLoaderRelocateImageForRuntime (\r
+ IN PHYSICAL_ADDRESS ImageBase,\r
+ IN PHYSICAL_ADDRESS VirtImageBase,\r
+ IN UINTN ImageSize,\r
+ IN VOID *RelocationData\r
+ )\r
+{\r
+}\r
+\r
+/**\r
+ Unloads a loaded PE/COFF image from memory and releases its taken resource.\r
+ \r
+ For NT32 emulator, the PE/COFF image loaded by system needs to release.\r
+ For real platform, the PE/COFF image loaded by Core doesn't needs to be unloaded, \r
+ this function can simply return RETURN_SUCCESS.\r
+\r
+ @param ImageContext Pointer to the image context structure that describes the PE/COFF\r
+ image to be unloaded.\r
+\r
+ @retval RETURN_SUCCESS The PE/COFF image was unloaded successfully.\r
+**/\r
+RETURN_STATUS\r
+EFIAPI\r
+PeCoffLoaderUnloadImage (\r
+ IN PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext\r
+ )\r
+{\r
+ if (mPeiEfiPeiPeCoffLoader == NULL) {\r
+ GetPeCoffLoaderStucture ();\r
+ }\r
+ return mPeiEfiPeiPeCoffLoader->UnloadImage (mPeiEfiPeiPeCoffLoader, ImageContext);\r
+}\r