From 3d7b0992fccc89cc049de91d02b4869ec81cf9fb Mon Sep 17 00:00:00 2001 From: lgao4 Date: Fri, 28 Sep 2007 08:14:30 +0000 Subject: [PATCH] 1. Replace PeCoffLoader library by PeCoff lib for PeiCore, DxeIpl and DxeMain. 2. Add three PeCoff library instances for NT32 PeImage load. 3. Update PeCoffGetEntryPointLib to support TeImage. git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@3965 6f19259b-4bc3-4df7-8a09-765794883524 --- MdeModulePkg/Core/Dxe/DxeMain.h | 1 + MdeModulePkg/Core/Dxe/DxeMain.inf | 2 +- MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c | 4 - MdeModulePkg/Core/Dxe/Image/Image.c | 8 +- MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf | 2 - MdeModulePkg/Core/DxeIplPeim/DxeLoad.c | 24 +- MdeModulePkg/Core/Pei/Image/Image.c | 226 ++++----------- MdeModulePkg/Core/Pei/PeiMain.h | 2 - MdeModulePkg/Core/Pei/PeiMain.inf | 3 +- MdeModulePkg/MdeModulePkg.dsc | 4 - MdePkg/Include/Library/PeCoffLib.h | 17 ++ .../PeCoffGetEntryPoint.c | 51 ++-- MdePkg/Library/BasePeCoffLib/BasePeCoff.c | 20 ++ .../DxeNt32PeCoffLib/DxeNt32PeCoffLib.c | 225 +++++++++++++++ .../DxeNt32PeCoffLib/DxeNt32PeCoffLib.inf | 50 ++++ .../PeCoffGetEntryPoint.c | 168 ++++++++++- .../PeiCoreNt32PeCoffLib.c | 262 ++++++++++++++++++ .../PeiCoreNt32PeCoffLib.inf | 49 ++++ .../PeiNt32PeCoffLib/PeiNt32PeCoffLib.c | 255 +++++++++++++++++ .../PeiNt32PeCoffLib/PeiNt32PeCoffLib.inf | 50 ++++ Nt32Pkg/Nt32Pkg.dsc | 7 +- 21 files changed, 1186 insertions(+), 244 deletions(-) create mode 100644 Nt32Pkg/Library/DxeNt32PeCoffLib/DxeNt32PeCoffLib.c create mode 100644 Nt32Pkg/Library/DxeNt32PeCoffLib/DxeNt32PeCoffLib.inf create mode 100644 Nt32Pkg/Library/PeiCoreNt32PeCoffLib/PeiCoreNt32PeCoffLib.c create mode 100644 Nt32Pkg/Library/PeiCoreNt32PeCoffLib/PeiCoreNt32PeCoffLib.inf create mode 100644 Nt32Pkg/Library/PeiNt32PeCoffLib/PeiNt32PeCoffLib.c create mode 100644 Nt32Pkg/Library/PeiNt32PeCoffLib/PeiNt32PeCoffLib.inf diff --git a/MdeModulePkg/Core/Dxe/DxeMain.h b/MdeModulePkg/Core/Dxe/DxeMain.h index c5c4f34c49..ed531f7bcc 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain.h +++ b/MdeModulePkg/Core/Dxe/DxeMain.h @@ -82,6 +82,7 @@ Revision History #include #include #include +#include #include "DebugImageInfo.h" #include "Library.h" diff --git a/MdeModulePkg/Core/Dxe/DxeMain.inf b/MdeModulePkg/Core/Dxe/DxeMain.inf index 3b8519b6db..9d6ecd0fba 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain.inf +++ b/MdeModulePkg/Core/Dxe/DxeMain.inf @@ -78,7 +78,6 @@ [LibraryClasses] BaseMemoryLib CacheMaintenanceLib - PeCoffLoaderLib UefiDecompressLib CustomDecompressLib PerformanceLib @@ -87,6 +86,7 @@ UefiLib DebugLib DxeCoreEntryPoint + PeCoffLib [Guids] gEfiEventLegacyBootGuid # ALWAYS_CONSUMED diff --git a/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c b/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c index 26bc94c13f..53f1d5f594 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c +++ b/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c @@ -25,7 +25,6 @@ Abstract: // DXE Core Global Variables for Protocols from PEI // EFI_HANDLE mDecompressHandle = NULL; -EFI_PEI_PE_COFF_LOADER_PROTOCOL *gEfiPeiPeCoffLoader = NULL; // // DXE Core globals for Architecture Protocols @@ -370,9 +369,6 @@ Returns: ); ASSERT_EFI_ERROR (Status); - gEfiPeiPeCoffLoader = GetPeCoffLoaderProtocol (); - ASSERT (gEfiPeiPeCoffLoader != NULL); - // // Register for the GUIDs of the Architectural Protocols, so the rest of the // EFI Boot Services and EFI Runtime Services tables can be filled in. diff --git a/MdeModulePkg/Core/Dxe/Image/Image.c b/MdeModulePkg/Core/Dxe/Image/Image.c index e227f3a6bf..9232cabcef 100644 --- a/MdeModulePkg/Core/Dxe/Image/Image.c +++ b/MdeModulePkg/Core/Dxe/Image/Image.c @@ -213,7 +213,7 @@ Returns: // // Get information about the image being loaded // - Status = gEfiPeiPeCoffLoader->GetImageInfo (gEfiPeiPeCoffLoader, &Image->ImageContext); + Status = PeCoffLoaderGetImageInfo (&Image->ImageContext); if (EFI_ERROR (Status)) { return Status; } @@ -305,7 +305,7 @@ Returns: // // Load the image from the file into the allocated memory // - Status = gEfiPeiPeCoffLoader->LoadImage (gEfiPeiPeCoffLoader, &Image->ImageContext); + Status = PeCoffLoaderLoadImage (&Image->ImageContext); if (EFI_ERROR (Status)) { goto Done; } @@ -328,7 +328,7 @@ Returns: // // Relocate the image in memory // - Status = gEfiPeiPeCoffLoader->RelocateImage (gEfiPeiPeCoffLoader, &Image->ImageContext); + Status = PeCoffLoaderRelocateImage (&Image->ImageContext); if (EFI_ERROR (Status)) { goto Done; } @@ -1085,7 +1085,7 @@ Returns: // // Unload image, free Image->ImageContext->ModHandle // - gEfiPeiPeCoffLoader->UnloadImage (gEfiPeiPeCoffLoader, &Image->ImageContext); + PeCoffLoaderUnloadImage (&Image->ImageContext); // // Free our references to the image handle diff --git a/MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf b/MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf index 3267a8cba0..8115a4a310 100644 --- a/MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf +++ b/MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf @@ -67,7 +67,6 @@ PeiServicesTablePointerLib CustomDecompressLib UefiDecompressLib - PeCoffLoaderLib CacheMaintenanceLib ReportStatusCodeLib PeiServicesLib @@ -90,7 +89,6 @@ gEfiPeiSectionExtractionPpiGuid # PPI SOMETIMES_CONSUMED gEfiEndOfPeiSignalPpiGuid # PPI SOMETIMES_PRODUCED gEfiDxeIplPpiGuid # PPI SOMETIMES_PRODUCED - gEfiPeiPeCoffLoaderGuid gEfiPeiDecompressPpiGuid gEfiPeiFirmwareVolumeInfoPpiGuid diff --git a/MdeModulePkg/Core/DxeIplPeim/DxeLoad.c b/MdeModulePkg/Core/DxeIplPeim/DxeLoad.c index a81475484f..cb13a7d4b0 100644 --- a/MdeModulePkg/Core/DxeIplPeim/DxeLoad.c +++ b/MdeModulePkg/Core/DxeIplPeim/DxeLoad.c @@ -174,7 +174,6 @@ DxeLoadCore ( EFI_PHYSICAL_ADDRESS DxeCoreAddress; UINT64 DxeCoreSize; EFI_PHYSICAL_ADDRESS DxeCoreEntryPoint; - EFI_PEI_PE_COFF_LOADER_PROTOCOL *PeiEfiPeiPeCoffLoader; EFI_BOOT_MODE BootMode; EFI_PEI_FV_HANDLE VolumeHandle; EFI_PEI_FILE_HANDLE FileHandle; @@ -200,12 +199,6 @@ DxeLoadCore ( // Now should have a HOB with the DXE core w/ the old HOB destroyed // } - - // - // Install the PEI Protocols that are shared between PEI and DXE - // - PeiEfiPeiPeCoffLoader = (EFI_PEI_PE_COFF_LOADER_PROTOCOL *) GetPeCoffLoaderProtocol (); - ASSERT (PeiEfiPeiPeCoffLoader != NULL); // // If any FV contains an encapsulated FV extract that FV @@ -244,14 +237,6 @@ DxeLoadCore ( ); // - // Add HOB for the PE/COFF Loader Protocol - // - BuildGuidDataHob ( - &gEfiPeiPeCoffLoaderGuid, - (VOID *)&PeiEfiPeiPeCoffLoader, - sizeof (VOID *) - ); - // // Report Status Code EFI_SW_PEI_PC_HANDOFF_TO_NEXT // REPORT_STATUS_CODE ( @@ -456,9 +441,6 @@ PeiLoadFile ( EFI_STATUS Status; PE_COFF_LOADER_IMAGE_CONTEXT ImageContext; VOID *Pe32Data; - EFI_PEI_PE_COFF_LOADER_PROTOCOL *PeiEfiPeiPeCoffLoader; - - PeiEfiPeiPeCoffLoader = (EFI_PEI_PE_COFF_LOADER_PROTOCOL *)GetPeCoffLoaderProtocol (); // // First try to find the required section in this ffs file. // @@ -489,7 +471,7 @@ PeiLoadFile ( ASSERT_EFI_ERROR (Status); - Status = PeiEfiPeiPeCoffLoader->GetImageInfo (PeiEfiPeiPeCoffLoader, &ImageContext); + Status = PeCoffLoaderGetImageInfo (&ImageContext); if (EFI_ERROR (Status)) { return Status; } @@ -502,14 +484,14 @@ PeiLoadFile ( // // Load the image to our new buffer // - Status = PeiEfiPeiPeCoffLoader->LoadImage (PeiEfiPeiPeCoffLoader, &ImageContext); + Status = PeCoffLoaderLoadImage (&ImageContext); if (EFI_ERROR (Status)) { return Status; } // // Relocate the image in our new buffer // - Status = PeiEfiPeiPeCoffLoader->RelocateImage (PeiEfiPeiPeCoffLoader, &ImageContext); + Status = PeCoffLoaderRelocateImage (&ImageContext); if (EFI_ERROR (Status)) { return Status; } diff --git a/MdeModulePkg/Core/Pei/Image/Image.c b/MdeModulePkg/Core/Pei/Image/Image.c index ebe79a6c50..a430d3ea7a 100644 --- a/MdeModulePkg/Core/Pei/Image/Image.c +++ b/MdeModulePkg/Core/Pei/Image/Image.c @@ -195,7 +195,6 @@ Returns: STATIC EFI_STATUS LoadAndRelocatePeCoffImage ( - IN EFI_PEI_PE_COFF_LOADER_PROTOCOL *PeiEfiPeiPeCoffLoader, IN VOID *Pe32Data, OUT EFI_PHYSICAL_ADDRESS *ImageAddress, OUT UINT64 *ImageSize, @@ -209,8 +208,6 @@ Routine Description: Arguments: - PeiEfiPeiPeCoffLoader - Pointer to a PE COFF loader protocol - Pe32Data - The base address of the PE/COFF file that is to be loaded and relocated ImageAddress - The base address of the relocated PE/COFF image @@ -230,15 +227,13 @@ Returns: EFI_STATUS Status; PE_COFF_LOADER_IMAGE_CONTEXT ImageContext; - ASSERT (PeiEfiPeiPeCoffLoader != NULL); - ZeroMem (&ImageContext, sizeof (ImageContext)); ImageContext.Handle = Pe32Data; Status = GetImageReadFunction (&ImageContext); ASSERT_EFI_ERROR (Status); - Status = PeiEfiPeiPeCoffLoader->GetImageInfo (PeiEfiPeiPeCoffLoader, &ImageContext); + Status = PeCoffLoaderGetImageInfo (&ImageContext); if (EFI_ERROR (Status)) { return Status; } @@ -251,14 +246,14 @@ Returns: // // Load the image to our new buffer // - Status = PeiEfiPeiPeCoffLoader->LoadImage (PeiEfiPeiPeCoffLoader, &ImageContext); + Status = PeCoffLoaderLoadImage (&ImageContext); if (EFI_ERROR (Status)) { return Status; } // // Relocate the image in our new buffer // - Status = PeiEfiPeiPeCoffLoader->RelocateImage (PeiEfiPeiPeCoffLoader, &ImageContext); + Status = PeCoffLoaderRelocateImage (&ImageContext); if (EFI_ERROR (Status)) { return Status; } @@ -312,14 +307,12 @@ Returns: EFI_PHYSICAL_ADDRESS ImageAddress; UINT64 ImageSize; EFI_PHYSICAL_ADDRESS ImageEntryPoint; - EFI_TE_IMAGE_HEADER *TEImageHeader; UINT16 Machine; PEI_CORE_INSTANCE *Private; VOID *EntryPointArg; - *EntryPoint = 0; - TEImageHeader = NULL; - ImageSize = 0; + *EntryPoint = 0; + ImageSize = 0; *AuthenticationState = 0; // @@ -330,11 +323,8 @@ Returns: FileHandle, &Pe32Data ); - if (!EFI_ERROR (Status)) { - TEImageHeader = (EFI_TE_IMAGE_HEADER *)Pe32Data; - } // - // If we didn't find a PE32 section, try to find a TE section. + // If we didn't find a TE section, try to find a PE32 section. // if (EFI_ERROR (Status)) { Status = PeiServicesFfsFindSectionData ( @@ -355,57 +345,38 @@ Returns: if (Private->PeiMemoryInstalled && (Private->HobList.HandoffInformationTable->BootMode != BOOT_ON_S3_RESUME)) { - { - // - // If memory is installed, perform the shadow operations - // - Status = LoadAndRelocatePeCoffImage ( - Private->PeCoffLoader, - Pe32Data, - &ImageAddress, - &ImageSize, - &ImageEntryPoint - ); - - if (EFI_ERROR (Status)) { - return EFI_NOT_FOUND; - } + // + // If memory is installed, perform the shadow operations + // + Status = LoadAndRelocatePeCoffImage ( + Pe32Data, + &ImageAddress, + &ImageSize, + &ImageEntryPoint + ); - // - // Got the entry point from ImageEntryPoint and ImageStartAddress - // - Pe32Data = (VOID *) ((UINTN) ImageAddress); - *EntryPoint = ImageEntryPoint; + if (EFI_ERROR (Status)) { + return Status; } + + // + // Got the entry point from the loaded Pe32Data + // + Pe32Data = (VOID *) ((UINTN) ImageAddress); + *EntryPoint = ImageEntryPoint; } else { - if (TEImageHeader != NULL) { - // - // Retrieve the entry point from the TE image header - // - ImageAddress = (EFI_PHYSICAL_ADDRESS) (UINTN) TEImageHeader; - ImageSize = 0; - *EntryPoint = (EFI_PHYSICAL_ADDRESS)((UINTN) TEImageHeader + sizeof (EFI_TE_IMAGE_HEADER) + - TEImageHeader->AddressOfEntryPoint - TEImageHeader->StrippedSize); - } else { - // - // Retrieve the entry point from the PE/COFF image header - // - ImageAddress = (EFI_PHYSICAL_ADDRESS) (UINTN) Pe32Data; - ImageSize = 0; - Status = PeCoffLoaderGetEntryPoint (Pe32Data, &EntryPointArg); - *EntryPoint = (EFI_PHYSICAL_ADDRESS) (UINTN) EntryPointArg; - if (EFI_ERROR (Status)) { - return EFI_NOT_FOUND; - } + // + // Retrieve the entry point from the PE/COFF or TE image header + // + ImageAddress = (EFI_PHYSICAL_ADDRESS) (UINTN) Pe32Data; + Status = PeCoffLoaderGetEntryPoint (Pe32Data, &EntryPointArg); + if (EFI_ERROR (Status)) { + return Status; } + *EntryPoint = (EFI_PHYSICAL_ADDRESS) (UINTN) EntryPointArg; } - - if (((EFI_TE_IMAGE_HEADER *) (UINTN) ImageAddress)->Signature == EFI_TE_IMAGE_HEADER_SIGNATURE) { - TEImageHeader = (EFI_TE_IMAGE_HEADER *) (UINTN) ImageAddress; - Machine = TEImageHeader->Machine; - } else { - Machine = PeCoffLoaderGetMachineType (Pe32Data); - } + + Machine = PeCoffLoaderGetMachineType (Pe32Data); if (!EFI_IMAGE_MACHINE_TYPE_SUPPORTED (Machine)) { return EFI_UNSUPPORTED; @@ -424,120 +395,29 @@ Returns: // DEBUG ((EFI_D_INFO | EFI_D_LOAD, "Loading PEIM at 0x%08x EntryPoint=0x%08x ", (UINTN) ImageAddress, *EntryPoint)); DEBUG_CODE_BEGIN (); - EFI_IMAGE_DATA_DIRECTORY *DirectoryEntry; - EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *DebugEntry; - UINTN DirCount; - UINTN Index; - UINTN Index1; - BOOLEAN FileNameFound; - CHAR8 *AsciiString; - CHAR8 AsciiBuffer[512]; - VOID *CodeViewEntryPointer; - INTN TEImageAdjust; - EFI_IMAGE_DOS_HEADER *DosHeader; - EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr; - UINT32 NumberOfRvaAndSizes; - - Hdr.Pe32 = NULL; - if (TEImageHeader == NULL) { - DosHeader = (EFI_IMAGE_DOS_HEADER *)Pe32Data; - if (DosHeader->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)((DosHeader->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; - } - } - - // - // Find the codeview info in the image and display the file name - // being loaded. - // - // 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. - // - DebugEntry = NULL; - DirectoryEntry = NULL; - NumberOfRvaAndSizes = 0; - TEImageAdjust = 0; + CHAR8 *AsciiString; + CHAR8 AsciiBuffer[512]; + INT32 Index; + INT32 Index1; - if (TEImageHeader == NULL) { - if (Hdr.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_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]); - DebugEntry = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *) ((UINTN) Pe32Data + DirectoryEntry->VirtualAddress); - } 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]); - DebugEntry = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *) ((UINTN) Pe32Data + DirectoryEntry->VirtualAddress); - } - - if (NumberOfRvaAndSizes <= EFI_IMAGE_DIRECTORY_ENTRY_DEBUG) { - DirectoryEntry = NULL; - DebugEntry = NULL; - } - } else { - if (TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress != 0) { - DirectoryEntry = &TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG]; - TEImageAdjust = sizeof (EFI_TE_IMAGE_HEADER) - TEImageHeader->StrippedSize; - DebugEntry = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *)((UINTN) TEImageHeader + - TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress + - TEImageAdjust); + AsciiString = PeCoffLoaderGetPdbPointer (Pe32Data); + + if (AsciiString != NULL) { + for (Index = AsciiStrLen (AsciiString) - 1; Index >= 0; Index --) { + if (AsciiString[Index] == '\\') { + break; + } } - } - if (DebugEntry != NULL && DirectoryEntry != NULL) { - for (DirCount = 0; DirCount < DirectoryEntry->Size; DirCount += sizeof(EFI_IMAGE_DEBUG_DIRECTORY_ENTRY), DebugEntry++) { - if (DebugEntry->Type == EFI_IMAGE_DEBUG_TYPE_CODEVIEW) { - if (DebugEntry->SizeOfData > 0) { - CodeViewEntryPointer = (VOID *) ((UINTN) DebugEntry->RVA + (UINTN) ImageAddress + (UINTN)TEImageAdjust); - switch (* (UINT32 *) CodeViewEntryPointer) { - case CODEVIEW_SIGNATURE_NB10: - AsciiString = (CHAR8 *)CodeViewEntryPointer + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY); - break; - - case CODEVIEW_SIGNATURE_RSDS: - AsciiString = (CHAR8 *)CodeViewEntryPointer + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_RSDS_ENTRY); - break; - - default: - AsciiString = NULL; - break; - } - if (AsciiString != NULL) { - FileNameFound = FALSE; - for (Index = 0, Index1 = 0; AsciiString[Index] != '\0'; Index++) { - if (AsciiString[Index] == '\\') { - Index1 = Index; - FileNameFound = TRUE; - } - } - - if (FileNameFound) { - for (Index = Index1 + 1; AsciiString[Index] != '.'; Index++) { - AsciiBuffer[Index - (Index1 + 1)] = AsciiString[Index]; - } - AsciiBuffer[Index - (Index1 + 1)] = 0; - DEBUG ((EFI_D_INFO | EFI_D_LOAD, "%a.efi", AsciiBuffer)); - break; - } - } - } + if (Index != 0) { + for (Index1 = 0; AsciiString[Index + 1 + Index1] != '.'; Index1 ++) { + AsciiBuffer [Index1] = AsciiString[Index + 1 + Index1]; } + AsciiBuffer [Index1] = '\0'; + DEBUG ((EFI_D_INFO | EFI_D_LOAD, "%a.efi", AsciiBuffer)); } } + DEBUG_CODE_END (); DEBUG ((EFI_D_INFO | EFI_D_LOAD, "\n")); @@ -691,12 +571,6 @@ Returns: --*/ { - // - // Always update PeCoffLoader pointer as PEI core itself may get - // shadowed into memory - // - PrivateData->PeCoffLoader = GetPeCoffLoaderProtocol (); - if (OldCoreData == NULL) { // // The first time we are XIP (running from FLASH). We need to remember the diff --git a/MdeModulePkg/Core/Pei/PeiMain.h b/MdeModulePkg/Core/Pei/PeiMain.h index da0c0aa1af..2d1e29d9f4 100644 --- a/MdeModulePkg/Core/Pei/PeiMain.h +++ b/MdeModulePkg/Core/Pei/PeiMain.h @@ -54,7 +54,6 @@ Revision History #include #include #include -#include #define PEI_CORE_INTERNAL_FFS_FILE_DISPATCH_TYPE 0xff @@ -133,7 +132,6 @@ typedef struct{ UINTN SizeOfCacheAsRam; VOID *MaxTopOfCarHeap; EFI_PEI_PPI_DESCRIPTOR *XipLoadFile; - EFI_PEI_PE_COFF_LOADER_PROTOCOL *PeCoffLoader; } PEI_CORE_INSTANCE; // diff --git a/MdeModulePkg/Core/Pei/PeiMain.inf b/MdeModulePkg/Core/Pei/PeiMain.inf index 7701696850..d8db002ea8 100644 --- a/MdeModulePkg/Core/Pei/PeiMain.inf +++ b/MdeModulePkg/Core/Pei/PeiMain.inf @@ -82,13 +82,12 @@ DebugLib MemoryAllocationLib CacheMaintenanceLib - PeCoffLoaderLib PeCoffLib [Guids] gPeiAprioriFileNameGuid gEfiFirmwareFileSystem2Guid - + gEfiPeiPeCoffLoaderGuid [Ppis] gEfiPeiSecurityPpiGuid # PPI_NOTIFY SOMETIMES_CONSUMED diff --git a/MdeModulePkg/MdeModulePkg.dsc b/MdeModulePkg/MdeModulePkg.dsc index e80fa4240f..d06c02000b 100644 --- a/MdeModulePkg/MdeModulePkg.dsc +++ b/MdeModulePkg/MdeModulePkg.dsc @@ -41,7 +41,6 @@ PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf TimerLib|MdePkg/Library/BaseTimerLibNullTemplate/BaseTimerLibNullTemplate.inf UefiDecompressLib|MdePkg/Library/BaseUefiDecompressLib/BaseUefiDecompressLib.inf - PeCoffLoaderLib|MdeModulePkg/Library/PeiDxePeCoffLoaderLib/PeCoffLoaderLib.inf CustomDecompressLib|MdePkg/Library/BaseCustomDecompressLibNull/BaseCustomDecompressLibNull.inf S3Lib|MdeModulePkg/Library/PeiS3LibNull/PeiS3LibNull.inf RecoveryLib|MdeModulePkg/Library/PeiRecoveryLibNull/PeiRecoveryLibNull.inf @@ -73,8 +72,6 @@ ReportStatusCodeLib|IntelFrameworkModulePkg/Library/PeiReportStatusCodeLib/PeiReportStatusCodeLib.inf PeiServicesLib|MdePkg/Library/PeiServicesLib/PeiServicesLib.inf PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf - PeCoffLoaderLib|MdeModulePkg/Library/PeiDxePeCoffLoaderLib/PeCoffLoaderLib.inf - [LibraryClasses.common.PEIM] HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf @@ -96,7 +93,6 @@ DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf UefiLib|MdePkg/Library/UefiLib/UefiLib.inf DxeServicesTableLib|MdePkg/Library/DxeServicesTableLib/DxeServicesTableLib.inf - PeCoffLoaderLib|MdeModulePkg/Library/PeiDxePeCoffLoaderLib/PeCoffLoaderLib.inf [LibraryClasses.common.DXE_DRIVER] HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf diff --git a/MdePkg/Include/Library/PeCoffLib.h b/MdePkg/Include/Library/PeCoffLib.h index 93f8d06ad2..2b0050474b 100644 --- a/MdePkg/Include/Library/PeCoffLib.h +++ b/MdePkg/Include/Library/PeCoffLib.h @@ -202,5 +202,22 @@ PeCoffLoaderRelocateImageForRuntime ( ) ; +/** + Unloads a loaded PE/COFF image from memory and releases its taken resource. + + For NT32 emulator, the PE/COFF image loaded by system needs to release. + For real platform, the PE/COFF image loaded by Core doesn't needs to be unloaded, + this function can simply return RETURN_SUCCESS. + + @param ImageContext Pointer to the image context structure that describes the PE/COFF + image to be unloaded. + @retval RETURN_SUCCESS The PE/COFF image was unloaded successfully. +**/ +RETURN_STATUS +EFIAPI +PeCoffLoaderUnloadImage ( + IN PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext + ) +; #endif diff --git a/MdePkg/Library/BasePeCoffGetEntryPointLib/PeCoffGetEntryPoint.c b/MdePkg/Library/BasePeCoffGetEntryPointLib/PeCoffGetEntryPoint.c index 5e1f14d9a7..7ed8f078fc 100644 --- a/MdePkg/Library/BasePeCoffGetEntryPointLib/PeCoffGetEntryPoint.c +++ b/MdePkg/Library/BasePeCoffGetEntryPointLib/PeCoffGetEntryPoint.c @@ -45,31 +45,38 @@ PeCoffLoaderGetEntryPoint ( OUT VOID **EntryPoint ) { - EFI_IMAGE_DOS_HEADER *DosHeader; - EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Header; + EFI_IMAGE_DOS_HEADER *DosHdr; + EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr; ASSERT (Pe32Data != NULL); ASSERT (EntryPoint != NULL); - DosHeader = (EFI_IMAGE_DOS_HEADER *)Pe32Data; - if (DosHeader->e_magic == EFI_IMAGE_DOS_SIGNATURE) { + 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. // - Header.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)((UINTN) Pe32Data + (UINTN) ((DosHeader->e_lfanew) & 0x0ffff)); + 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. // - Header.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)Pe32Data; + Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)Pe32Data; } // // Calculate the entry point relative to the start of the image. // AddressOfEntryPoint is common for PE32 & PE32+ // - *EntryPoint = (VOID *)((UINTN)Pe32Data + (UINTN)(Header.Pe32->OptionalHeader.AddressOfEntryPoint & 0x0ffffffff)); - return RETURN_SUCCESS; + if (Hdr.Te->Signature == EFI_TE_IMAGE_HEADER_SIGNATURE) { + *EntryPoint = (VOID *)((UINTN)Pe32Data + (UINTN)(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)Pe32Data + (UINTN)(Hdr.Pe32->OptionalHeader.AddressOfEntryPoint & 0x0ffffffff)); + return RETURN_SUCCESS; + } + + return RETURN_UNSUPPORTED; } @@ -94,14 +101,24 @@ PeCoffLoaderGetMachineType ( EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr; EFI_IMAGE_DOS_HEADER *DosHdr; - DosHdr = (EFI_IMAGE_DOS_HEADER *)Pe32Data; + ASSERT (Pe32Data != NULL); + + DosHdr = (EFI_IMAGE_DOS_HEADER *)Pe32Data; if (DosHdr->e_magic == EFI_IMAGE_DOS_SIGNATURE) { - Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)((UINTN)Pe32Data + DosHdr->e_lfanew); + // + // 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 { - Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)((UINTN)Pe32Data); + // + // DOS image header is not present, so PE header is at the image base. + // + Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)Pe32Data; } - if (Hdr.Pe32->Signature == EFI_IMAGE_NT_SIGNATURE) { + if (Hdr.Te->Signature == EFI_TE_IMAGE_HEADER_SIGNATURE) { + return Hdr.Te->Machine; + } else if (Hdr.Pe32->Signature == EFI_IMAGE_NT_SIGNATURE) { return Hdr.Pe32->FileHeader.Machine; } @@ -133,7 +150,7 @@ PeCoffLoaderGetPdbPointer ( IN VOID *Pe32Data ) { - EFI_IMAGE_DOS_HEADER *DosHeader; + EFI_IMAGE_DOS_HEADER *DosHdr; EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr; EFI_IMAGE_DATA_DIRECTORY *DirectoryEntry; EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *DebugEntry; @@ -150,12 +167,12 @@ PeCoffLoaderGetPdbPointer ( DebugEntry = NULL; NumberOfRvaAndSizes = 0; - DosHeader = (EFI_IMAGE_DOS_HEADER *)Pe32Data; - if (DosHeader->e_magic == EFI_IMAGE_DOS_SIGNATURE) { + 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) ((DosHeader->e_lfanew) & 0x0ffff)); + 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. @@ -226,7 +243,7 @@ PeCoffLoaderGetPdbPointer ( return NULL; } - for (DirCount = 0; DirCount < DirectoryEntry->Size; DirCount++, DebugEntry++) { + for (DirCount = 0; DirCount < DirectoryEntry->Size; DirCount += sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY), DebugEntry++) { if (DebugEntry->Type == EFI_IMAGE_DEBUG_TYPE_CODEVIEW) { if (DebugEntry->SizeOfData > 0) { CodeViewEntryPointer = (VOID *) ((UINTN) DebugEntry->RVA + ((UINTN)Pe32Data) + (UINTN)TEImageAdjust); diff --git a/MdePkg/Library/BasePeCoffLib/BasePeCoff.c b/MdePkg/Library/BasePeCoffLib/BasePeCoff.c index c56011b24d..fb78aefb8c 100644 --- a/MdePkg/Library/BasePeCoffLib/BasePeCoff.c +++ b/MdePkg/Library/BasePeCoffLib/BasePeCoff.c @@ -1334,3 +1334,23 @@ PeCoffLoaderImageReadFromMemory ( return RETURN_SUCCESS; } +/** + Unloads a loaded PE/COFF image from memory and releases its taken resource. + + For NT32 emulator, the PE/COFF image loaded by system needs to release. + For real platform, the PE/COFF image loaded by Core doesn't needs to be unloaded, + this function can simply return RETURN_SUCCESS. + + @param ImageContext Pointer to the image context structure that describes the PE/COFF + image to be unloaded. + + @retval RETURN_SUCCESS The PE/COFF image was unloaded successfully. +**/ +RETURN_STATUS +EFIAPI +PeCoffLoaderUnloadImage ( + IN PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext + ) +{ + return RETURN_SUCCESS; +} diff --git a/Nt32Pkg/Library/DxeNt32PeCoffLib/DxeNt32PeCoffLib.c b/Nt32Pkg/Library/DxeNt32PeCoffLib/DxeNt32PeCoffLib.c new file mode 100644 index 0000000000..251af43d22 --- /dev/null +++ b/Nt32Pkg/Library/DxeNt32PeCoffLib/DxeNt32PeCoffLib.c @@ -0,0 +1,225 @@ +/*++ + +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: + + DxeNt32PeCoffLib.c + +Abstract: + + Wrap the Nt32 PE/COFF loader with the PE COFF LOADER guid structure + to produce PeCoff library class. + + +--*/ + +#include +#include +#include +#include +#include + +EFI_PEI_PE_COFF_LOADER_PROTOCOL *mPeiEfiPeiPeCoffLoader; + +/** + The constructor function gets the pointer to PeCofferLoader guid structure + from the guid data hob. + + It will ASSERT() if the guid hob of PeCofferLoader guid structure doesn't exist. + + @param ImageHandle The firmware allocated handle for the EFI image. + @param SystemTable A pointer to the EFI System Table. + + @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS. + +**/ +EFI_STATUS +EFIAPI +DxeNt32PeCoffLibConstructor ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_HOB_GUID_TYPE *GuidHob; + + // + // Find guid data hob that contains PeCoffLoader guid structure. + // + GuidHob = GetFirstGuidHob (&gEfiPeiPeCoffLoaderGuid); + ASSERT (GuidHob != NULL); + + // + // Get PeCofferLoader guid structure from guid hob data. + // + mPeiEfiPeiPeCoffLoader = (EFI_PEI_PE_COFF_LOADER_PROTOCOL *)(*(UINTN *)(GET_GUID_HOB_DATA (GuidHob))); + + return EFI_SUCCESS; +} + +/** + Retrieves information about a PE/COFF image. + + Computes the PeCoffHeaderOffset, ImageAddress, ImageSize, DestinationAddress, CodeView, + PdbPointer, RelocationsStripped, SectionAlignment, SizeOfHeaders, and DebugDirectoryEntryRva + fields of the ImageContext structure. If ImageContext is NULL, then return RETURN_INVALID_PARAMETER. + If the PE/COFF image accessed through the ImageRead service in the ImageContext structure is not + a supported PE/COFF image type, then return RETURN_UNSUPPORTED. If any errors occur while + computing the fields of ImageContext, then the error status is returned in the ImageError field of + ImageContext. + + @param ImageContext Pointer to the image context structure that describes the PE/COFF + image that needs to be examined by this function. + + @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. + +**/ +RETURN_STATUS +EFIAPI +PeCoffLoaderGetImageInfo ( + IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext + ) +{ + return mPeiEfiPeiPeCoffLoader->GetImageInfo (mPeiEfiPeiPeCoffLoader, ImageContext); +} + +/** + Applies relocation fixups to a PE/COFF image that was loaded with PeCoffLoaderLoadImage(). + + If the DestinationAddress field of ImageContext is 0, then use the ImageAddress field of + ImageContext as the relocation base address. Otherwise, use the DestinationAddress field + of ImageContext as the relocation base address. The caller must allocate the relocation + fixup log buffer and fill in the FixupData field of ImageContext prior to calling this function. + If ImageContext is NULL, then ASSERT(). + + @param ImageContext Pointer to the image context structure that describes the PE/COFF + image that is being relocated. + + @retval RETURN_SUCCESS The PE/COFF image was relocated. + Extended status information is in the ImageError field of ImageContext. + @retval RETURN_LOAD_ERROR The image in not a valid PE/COFF image. + Extended status information is in the ImageError field of ImageContext. + @retval RETURN_UNSUPPORTED A relocation record type is not supported. + Extended status information is in the ImageError field of ImageContext. + +**/ +RETURN_STATUS +EFIAPI +PeCoffLoaderRelocateImage ( + IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext + ) +{ + return mPeiEfiPeiPeCoffLoader->RelocateImage (mPeiEfiPeiPeCoffLoader, ImageContext); +} + +/** + Loads a PE/COFF image into memory. + + Loads the PE/COFF image accessed through the ImageRead service of ImageContext into the buffer + specified by the ImageAddress and ImageSize fields of ImageContext. The caller must allocate + the load buffer and fill in the ImageAddress and ImageSize fields prior to calling this function. + The EntryPoint, FixupDataSize, CodeView, and PdbPointer fields of ImageContext are computed. + If ImageContext is NULL, then ASSERT(). + + @param ImageContext Pointer to the image context structure that describes the PE/COFF + image that is being loaded. + + @retval RETURN_SUCCESS The PE/COFF image was loaded into the buffer specified by + the ImageAddress and ImageSize fields of ImageContext. + Extended status information is in the ImageError field of ImageContext. + @retval RETURN_BUFFER_TOO_SMALL The caller did not provide a large enough buffer. + Extended status information is in the ImageError field of ImageContext. + @retval RETURN_LOAD_ERROR The PE/COFF image is an EFI Runtime image with no relocations. + Extended status information is in the ImageError field of ImageContext. + @retval RETURN_INVALID_PARAMETER The image address is invalid. + Extended status information is in the ImageError field of ImageContext. + +**/ +RETURN_STATUS +EFIAPI +PeCoffLoaderLoadImage ( + IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext + ) +{ + return mPeiEfiPeiPeCoffLoader->LoadImage (mPeiEfiPeiPeCoffLoader, ImageContext); +} + +/** + ImageRead function that operates on a memory buffer whos base is passed into + FileHandle. + + @param FileHandle Ponter to baes of the input stream + @param FileOffset Offset to the start of the buffer + @param ReadSize Number of bytes to copy into the buffer + @param Buffer Location to place results of read + + @retval RETURN_SUCCESS Data is read from FileOffset from the Handle into + the buffer. +**/ +RETURN_STATUS +EFIAPI +PeCoffLoaderImageReadFromMemory ( + IN VOID *FileHandle, + IN UINTN FileOffset, + IN OUT UINTN *ReadSize, + OUT VOID *Buffer + ) +{ + return RETURN_UNSUPPORTED; +} + + +/** + Reapply fixups on a fixed up PE32/PE32+ image to allow virutal calling at EFI + runtime. + + PE_COFF_LOADER_IMAGE_CONTEXT.FixupData stores information needed to reapply + the fixups with a virtual mapping. + + + @param ImageBase Base address of relocated image + @param VirtImageBase Virtual mapping for ImageBase + @param ImageSize Size of the image to relocate + @param RelocationData Location to place results of read + +**/ +VOID +EFIAPI +PeCoffLoaderRelocateImageForRuntime ( + IN PHYSICAL_ADDRESS ImageBase, + IN PHYSICAL_ADDRESS VirtImageBase, + IN UINTN ImageSize, + IN VOID *RelocationData + ) +{ +} + +/** + Unloads a loaded PE/COFF image from memory and releases its taken resource. + + For NT32 emulator, the PE/COFF image loaded by system needs to release. + For real platform, the PE/COFF image loaded by Core doesn't needs to be unloaded, + this function can simply return RETURN_SUCCESS. + + @param ImageContext Pointer to the image context structure that describes the PE/COFF + image to be unloaded. + + @retval RETURN_SUCCESS The PE/COFF image was unloaded successfully. +**/ +RETURN_STATUS +EFIAPI +PeCoffLoaderUnloadImage ( + IN PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext + ) +{ + return mPeiEfiPeiPeCoffLoader->UnloadImage (mPeiEfiPeiPeCoffLoader, ImageContext); +} diff --git a/Nt32Pkg/Library/DxeNt32PeCoffLib/DxeNt32PeCoffLib.inf b/Nt32Pkg/Library/DxeNt32PeCoffLib/DxeNt32PeCoffLib.inf new file mode 100644 index 0000000000..d136b21101 --- /dev/null +++ b/Nt32Pkg/Library/DxeNt32PeCoffLib/DxeNt32PeCoffLib.inf @@ -0,0 +1,50 @@ +#/** @file +# PeCoff libary for Dxe modules that run NT32 emulator. +# +# Lib to provide memory journal status code reporting Routines +# Copyright (c) 2007, 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. + +# +# +#**/ + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = DxeNt32PeCoffLib + FILE_GUID = 624571b0-4b69-40e3-bd13-78fae0e84270 + MODULE_TYPE = DXE + VERSION_STRING = 1.0 + LIBRARY_CLASS = PeCoffLib|DXE_CORE DXE_DRIVER + EDK_RELEASE_VERSION = 0x00020000 + EFI_SPECIFICATION_VERSION = 0x00020000 + + CONSTRUCTOR = DxeNt32PeCoffLibConstructor + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 +# + +[Sources.common] + DxeNt32PeCoffLib.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + Nt32Pkg/Nt32Pkg.dec + +[LibraryClasses] + DebugLib + HobLib + +[Guids] + gEfiPeiPeCoffLoaderGuid # ALWAYS_CONSUMED + diff --git a/Nt32Pkg/Library/Nt32PeiPeCoffGetEntryPointLib/PeCoffGetEntryPoint.c b/Nt32Pkg/Library/Nt32PeiPeCoffGetEntryPointLib/PeCoffGetEntryPoint.c index 4f3c505cdd..70647426fa 100644 --- a/Nt32Pkg/Library/Nt32PeiPeCoffGetEntryPointLib/PeCoffGetEntryPoint.c +++ b/Nt32Pkg/Library/Nt32PeiPeCoffGetEntryPointLib/PeCoffGetEntryPoint.c @@ -27,6 +27,7 @@ Revision History #include #include #include +#include RETURN_STATUS @@ -63,15 +64,16 @@ Returns: UINT64 ImageSize; EFI_PHYSICAL_ADDRESS ImageEntryPoint; + ASSERT (Pe32Data != NULL); + ASSERT (EntryPoint != NULL); + Status = PeiServicesLocatePpi ( &gNtPeiLoadFilePpiGuid, 0, &PpiDescriptor, &PeiNtService ); - if (EFI_ERROR (Status)) { - return Status; - } + ASSERT_EFI_ERROR (Status); Status = PeiNtService->PeiLoadFileService ( Pe32Data, @@ -79,6 +81,10 @@ Returns: &ImageSize, &ImageEntryPoint ); + if (EFI_ERROR (Status)) { + return Status; + } + *EntryPoint = (VOID*)(UINTN)ImageEntryPoint; return Status; } @@ -90,9 +96,9 @@ Returns: level debug. - @param Image Pointer to a PE/COFF header + @param Pe32Data Pointer to a PE/COFF header - @return Machine type or zero if not a valid iamge + @return Machine type or zero if not a valid iamge **/ UINT16 @@ -104,17 +110,163 @@ PeCoffLoaderGetMachineType ( EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr; EFI_IMAGE_DOS_HEADER *DosHdr; + ASSERT (Pe32Data != NULL); + DosHdr = (EFI_IMAGE_DOS_HEADER *)Pe32Data; if (DosHdr->e_magic == EFI_IMAGE_DOS_SIGNATURE) { - Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)((UINTN)Pe32Data + DosHdr->e_lfanew); + // + // 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 { - Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)((UINTN)Pe32Data); + // + // DOS image header is not present, so PE header is at the image base. + // + Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)Pe32Data; } - if (Hdr.Pe32->Signature == EFI_IMAGE_NT_SIGNATURE) { + if (Hdr.Te->Signature == EFI_TE_IMAGE_HEADER_SIGNATURE) { + return Hdr.Te->Machine; + } else if (Hdr.Pe32->Signature == EFI_IMAGE_NT_SIGNATURE) { return Hdr.Pe32->FileHeader.Machine; } return 0x0000; } +/** + Returns a pointer to the PDB file name for a PE/COFF image that has been + 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 ASSERT(). + + @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; + + ASSERT (Pe32Data != NULL); + + TEImageAdjust = 0; + DirectoryEntry = NULL; + DebugEntry = NULL; + NumberOfRvaAndSizes = 0; + + 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; + } + + if (Hdr.Te->Signature == EFI_TE_IMAGE_HEADER_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; + DebugEntry = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *)((UINTN) Hdr.Te + + Hdr.Te->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress + + TEImageAdjust); + } + } else if (Hdr.Pe32->Signature == EFI_IMAGE_NT_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 EFI_IMAGE_MACHINE_IA32: + // + // Assume PE32 image with IA32 Machine field. + // + Magic = EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC; + break; + case EFI_IMAGE_MACHINE_X64: + case EFI_IMAGE_MACHINE_IPF: + // + // Assume PE32+ image with X64 or IPF Machine field + // + Magic = EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC; + break; + default: + // + // For unknow Machine field, use Magic in optional Header + // + Magic = Hdr.Pe32->OptionalHeader.Magic; + } + + if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_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]); + DebugEntry = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *) ((UINTN) Pe32Data + DirectoryEntry->VirtualAddress); + } else if (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]); + DebugEntry = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *) ((UINTN) Pe32Data + DirectoryEntry->VirtualAddress); + } + + if (NumberOfRvaAndSizes <= EFI_IMAGE_DIRECTORY_ENTRY_DEBUG) { + DirectoryEntry = NULL; + DebugEntry = NULL; + } + } else { + return NULL; + } + + if (DebugEntry == NULL || DirectoryEntry == NULL) { + return NULL; + } + + for (DirCount = 0; DirCount < DirectoryEntry->Size; DirCount += sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY), DebugEntry++) { + if (DebugEntry->Type == EFI_IMAGE_DEBUG_TYPE_CODEVIEW) { + if (DebugEntry->SizeOfData > 0) { + CodeViewEntryPointer = (VOID *) ((UINTN) DebugEntry->RVA + ((UINTN)Pe32Data) + (UINTN)TEImageAdjust); + 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)); + default: + break; + } + } + } + } + + return NULL; +} diff --git a/Nt32Pkg/Library/PeiCoreNt32PeCoffLib/PeiCoreNt32PeCoffLib.c b/Nt32Pkg/Library/PeiCoreNt32PeCoffLib/PeiCoreNt32PeCoffLib.c new file mode 100644 index 0000000000..45ccf84d66 --- /dev/null +++ b/Nt32Pkg/Library/PeiCoreNt32PeCoffLib/PeiCoreNt32PeCoffLib.c @@ -0,0 +1,262 @@ +/*++ + +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: + + PeiCoreNt32PeCoffLib.c + +Abstract: + + Wrap the Nt32 PE/COFF loader with the PE COFF LOADER guid structure + to produce PeCoff library class. + + +--*/ + +#include +#include +#include +#include +#include +#include + +EFI_PEI_PE_COFF_LOADER_PROTOCOL *mPeiEfiPeiPeCoffLoader = NULL; + +/** + The function caches the pointer of PeCofferLoader guid structure + into the guid data hob. + + The funtion must be called after PeCofferLoader guid structure is installed. + It will ASSERT() if PeCofferLoader guid structure is not installed. + + @retval EFI_SUCCESS PeCofferLoader guid structure is found. + +**/ +EFI_STATUS +EFIAPI +GetPeCoffLoaderStucture ( + ) +{ + EFI_STATUS Status; + EFI_HOB_GUID_TYPE *GuidHob; + + Status = EFI_NOT_FOUND; + + // + // Try to get guid data hob that contains PeCoffLoader guid structure. + // + GuidHob = GetFirstGuidHob (&gEfiPeiPeCoffLoaderGuid); + + if (GuidHob == NULL) { + // + // GuidHob is not ready, try to locate PeCoffLoader guid structure. + // + Status = PeiServicesLocatePpi ( + &gEfiPeiPeCoffLoaderGuid, + 0, + NULL, + &mPeiEfiPeiPeCoffLoader + ); + + // + // PeCofferLoader guid structure must be installed before this library runs. + // + ASSERT_EFI_ERROR (Status); + + // + // Build guid data hob of PeCofferLoader guid structure for DXE module use. + // + BuildGuidDataHob ( + &gEfiPeiPeCoffLoaderGuid, + (VOID *) &mPeiEfiPeiPeCoffLoader, + sizeof (VOID *) + ); + } else { + // + // Get PeCofferLoader guid structure directly from guid hob data. + // + mPeiEfiPeiPeCoffLoader = (EFI_PEI_PE_COFF_LOADER_PROTOCOL *)(*(UINTN *)(GET_GUID_HOB_DATA (GuidHob))); + } + + return EFI_SUCCESS; +} + +/** + Retrieves information about a PE/COFF image. + + Computes the PeCoffHeaderOffset, ImageAddress, ImageSize, DestinationAddress, CodeView, + PdbPointer, RelocationsStripped, SectionAlignment, SizeOfHeaders, and DebugDirectoryEntryRva + fields of the ImageContext structure. If ImageContext is NULL, then return RETURN_INVALID_PARAMETER. + If the PE/COFF image accessed through the ImageRead service in the ImageContext structure is not + a supported PE/COFF image type, then return RETURN_UNSUPPORTED. If any errors occur while + computing the fields of ImageContext, then the error status is returned in the ImageError field of + ImageContext. + + @param ImageContext Pointer to the image context structure that describes the PE/COFF + image that needs to be examined by this function. + + @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. + +**/ +RETURN_STATUS +EFIAPI +PeCoffLoaderGetImageInfo ( + IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext + ) +{ + if (mPeiEfiPeiPeCoffLoader == NULL) { + GetPeCoffLoaderStucture (); + } + return mPeiEfiPeiPeCoffLoader->GetImageInfo (mPeiEfiPeiPeCoffLoader, ImageContext); +} + +/** + Applies relocation fixups to a PE/COFF image that was loaded with PeCoffLoaderLoadImage(). + + If the DestinationAddress field of ImageContext is 0, then use the ImageAddress field of + ImageContext as the relocation base address. Otherwise, use the DestinationAddress field + of ImageContext as the relocation base address. The caller must allocate the relocation + fixup log buffer and fill in the FixupData field of ImageContext prior to calling this function. + If ImageContext is NULL, then ASSERT(). + + @param ImageContext Pointer to the image context structure that describes the PE/COFF + image that is being relocated. + + @retval RETURN_SUCCESS The PE/COFF image was relocated. + Extended status information is in the ImageError field of ImageContext. + @retval RETURN_LOAD_ERROR The image in not a valid PE/COFF image. + Extended status information is in the ImageError field of ImageContext. + @retval RETURN_UNSUPPORTED A relocation record type is not supported. + Extended status information is in the ImageError field of ImageContext. + +**/ +RETURN_STATUS +EFIAPI +PeCoffLoaderRelocateImage ( + IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext + ) +{ + if (mPeiEfiPeiPeCoffLoader == NULL) { + GetPeCoffLoaderStucture (); + } + return mPeiEfiPeiPeCoffLoader->RelocateImage (mPeiEfiPeiPeCoffLoader, ImageContext); +} + +/** + Loads a PE/COFF image into memory. + + Loads the PE/COFF image accessed through the ImageRead service of ImageContext into the buffer + specified by the ImageAddress and ImageSize fields of ImageContext. The caller must allocate + the load buffer and fill in the ImageAddress and ImageSize fields prior to calling this function. + The EntryPoint, FixupDataSize, CodeView, and PdbPointer fields of ImageContext are computed. + If ImageContext is NULL, then ASSERT(). + + @param ImageContext Pointer to the image context structure that describes the PE/COFF + image that is being loaded. + + @retval RETURN_SUCCESS The PE/COFF image was loaded into the buffer specified by + the ImageAddress and ImageSize fields of ImageContext. + Extended status information is in the ImageError field of ImageContext. + @retval RETURN_BUFFER_TOO_SMALL The caller did not provide a large enough buffer. + Extended status information is in the ImageError field of ImageContext. + @retval RETURN_LOAD_ERROR The PE/COFF image is an EFI Runtime image with no relocations. + Extended status information is in the ImageError field of ImageContext. + @retval RETURN_INVALID_PARAMETER The image address is invalid. + Extended status information is in the ImageError field of ImageContext. + +**/ +RETURN_STATUS +EFIAPI +PeCoffLoaderLoadImage ( + IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext + ) +{ + if (mPeiEfiPeiPeCoffLoader == NULL) { + GetPeCoffLoaderStucture (); + } + return mPeiEfiPeiPeCoffLoader->LoadImage (mPeiEfiPeiPeCoffLoader, ImageContext); +} + +/** + ImageRead function that operates on a memory buffer whos base is passed into + FileHandle. + + @param FileHandle Ponter to baes of the input stream + @param FileOffset Offset to the start of the buffer + @param ReadSize Number of bytes to copy into the buffer + @param Buffer Location to place results of read + + @retval RETURN_SUCCESS Data is read from FileOffset from the Handle into + the buffer. +**/ +RETURN_STATUS +EFIAPI +PeCoffLoaderImageReadFromMemory ( + IN VOID *FileHandle, + IN UINTN FileOffset, + IN OUT UINTN *ReadSize, + OUT VOID *Buffer + ) +{ + return RETURN_UNSUPPORTED; +} + + +/** + Reapply fixups on a fixed up PE32/PE32+ image to allow virutal calling at EFI + runtime. + + PE_COFF_LOADER_IMAGE_CONTEXT.FixupData stores information needed to reapply + the fixups with a virtual mapping. + + + @param ImageBase Base address of relocated image + @param VirtImageBase Virtual mapping for ImageBase + @param ImageSize Size of the image to relocate + @param RelocationData Location to place results of read + +**/ +VOID +EFIAPI +PeCoffLoaderRelocateImageForRuntime ( + IN PHYSICAL_ADDRESS ImageBase, + IN PHYSICAL_ADDRESS VirtImageBase, + IN UINTN ImageSize, + IN VOID *RelocationData + ) +{ +} + +/** + Unloads a loaded PE/COFF image from memory and releases its taken resource. + + For NT32 emulator, the PE/COFF image loaded by system needs to release. + For real platform, the PE/COFF image loaded by Core doesn't needs to be unloaded, + this function can simply return RETURN_SUCCESS. + + @param ImageContext Pointer to the image context structure that describes the PE/COFF + image to be unloaded. + + @retval RETURN_SUCCESS The PE/COFF image was unloaded successfully. +**/ +RETURN_STATUS +EFIAPI +PeCoffLoaderUnloadImage ( + IN PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext + ) +{ + if (mPeiEfiPeiPeCoffLoader == NULL) { + GetPeCoffLoaderStucture (); + } + return mPeiEfiPeiPeCoffLoader->UnloadImage (mPeiEfiPeiPeCoffLoader, ImageContext); +} diff --git a/Nt32Pkg/Library/PeiCoreNt32PeCoffLib/PeiCoreNt32PeCoffLib.inf b/Nt32Pkg/Library/PeiCoreNt32PeCoffLib/PeiCoreNt32PeCoffLib.inf new file mode 100644 index 0000000000..26d69b8029 --- /dev/null +++ b/Nt32Pkg/Library/PeiCoreNt32PeCoffLib/PeiCoreNt32PeCoffLib.inf @@ -0,0 +1,49 @@ +#/** @file +# PeCoff libary for PeiCore modules that run NT32 emulator. +# +# Lib to provide memory journal status code reporting Routines +# Copyright (c) 2007, 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. + +# +# +#**/ + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = PeiCoreNt32PeCoffLib + FILE_GUID = ef9fd7ee-3181-4b16-adc1-8615f88b58b8 + MODULE_TYPE = PEIM + VERSION_STRING = 1.0 + LIBRARY_CLASS = PeCoffLib|PEI_CORE + EDK_RELEASE_VERSION = 0x00020000 + EFI_SPECIFICATION_VERSION = 0x00020000 + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 +# + +[Sources.common] + PeiCoreNt32PeCoffLib.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + Nt32Pkg/Nt32Pkg.dec + +[LibraryClasses] + PeiServicesLib + DebugLib + HobLib + +[Guids] + gEfiPeiPeCoffLoaderGuid # ALWAYS_CONSUMED + diff --git a/Nt32Pkg/Library/PeiNt32PeCoffLib/PeiNt32PeCoffLib.c b/Nt32Pkg/Library/PeiNt32PeCoffLib/PeiNt32PeCoffLib.c new file mode 100644 index 0000000000..733826fd2c --- /dev/null +++ b/Nt32Pkg/Library/PeiNt32PeCoffLib/PeiNt32PeCoffLib.c @@ -0,0 +1,255 @@ +/*++ + +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: + + PeiNt32PeCoffLib.c + +Abstract: + + Wrap the Nt32 PE/COFF loader with the PE COFF LOADER guid structure + to produce PeCoff library class. + + +--*/ + +#include +#include +#include +#include +#include + +EFI_PEI_PE_COFF_LOADER_PROTOCOL *mPeiEfiPeiPeCoffLoader; + +/** + The constructor function caches the pointer of PeCofferLoader guid structure + into the guid data hob. + + The constructor must be called after PeCofferLoader guid structure is installed. + It will ASSERT() if PeCofferLoader guid structure is not installed. + + @param FfsHeader Pointer to FFS header the loaded driver. + @param PeiServices Pointer to the PEI services. + + @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS. + +**/ +EFI_STATUS +EFIAPI +PeiNt32PeCoffLibConstructor ( + IN EFI_FFS_FILE_HEADER *FfsHeader, + IN EFI_PEI_SERVICES **PeiServices + ) +{ + EFI_STATUS Status; + EFI_HOB_GUID_TYPE *GuidHob; + + Status = EFI_NOT_FOUND; + + // + // Try to get guid data hob that contains PeCoffLoader guid structure. + // + GuidHob = GetFirstGuidHob (&gEfiPeiPeCoffLoaderGuid); + + if (GuidHob == NULL) { + // + // GuidHob is not ready, try to locate PeCoffLoader guid structure. + // + Status = (*PeiServices)->LocatePpi ( + PeiServices, + &gEfiPeiPeCoffLoaderGuid, + 0, + NULL, + &mPeiEfiPeiPeCoffLoader + ); + + // + // PeCofferLoader guid structure must be installed before this library runs. + // + ASSERT_EFI_ERROR (Status); + + // + // Build guid data hob of PeCofferLoader guid structure for DXE module use. + // + BuildGuidDataHob ( + &gEfiPeiPeCoffLoaderGuid, + (VOID *) &mPeiEfiPeiPeCoffLoader, + sizeof (VOID *) + ); + } else { + // + // Get PeCofferLoader guid structure directly from guid hob data. + // + mPeiEfiPeiPeCoffLoader = (EFI_PEI_PE_COFF_LOADER_PROTOCOL *)(*(UINTN *)(GET_GUID_HOB_DATA (GuidHob))); + } + + return EFI_SUCCESS; +} + +/** + Retrieves information about a PE/COFF image. + + Computes the PeCoffHeaderOffset, ImageAddress, ImageSize, DestinationAddress, CodeView, + PdbPointer, RelocationsStripped, SectionAlignment, SizeOfHeaders, and DebugDirectoryEntryRva + fields of the ImageContext structure. If ImageContext is NULL, then return RETURN_INVALID_PARAMETER. + If the PE/COFF image accessed through the ImageRead service in the ImageContext structure is not + a supported PE/COFF image type, then return RETURN_UNSUPPORTED. If any errors occur while + computing the fields of ImageContext, then the error status is returned in the ImageError field of + ImageContext. + + @param ImageContext Pointer to the image context structure that describes the PE/COFF + image that needs to be examined by this function. + + @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. + +**/ +RETURN_STATUS +EFIAPI +PeCoffLoaderGetImageInfo ( + IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext + ) +{ + return mPeiEfiPeiPeCoffLoader->GetImageInfo (mPeiEfiPeiPeCoffLoader, ImageContext); +} + +/** + Applies relocation fixups to a PE/COFF image that was loaded with PeCoffLoaderLoadImage(). + + If the DestinationAddress field of ImageContext is 0, then use the ImageAddress field of + ImageContext as the relocation base address. Otherwise, use the DestinationAddress field + of ImageContext as the relocation base address. The caller must allocate the relocation + fixup log buffer and fill in the FixupData field of ImageContext prior to calling this function. + If ImageContext is NULL, then ASSERT(). + + @param ImageContext Pointer to the image context structure that describes the PE/COFF + image that is being relocated. + + @retval RETURN_SUCCESS The PE/COFF image was relocated. + Extended status information is in the ImageError field of ImageContext. + @retval RETURN_LOAD_ERROR The image in not a valid PE/COFF image. + Extended status information is in the ImageError field of ImageContext. + @retval RETURN_UNSUPPORTED A relocation record type is not supported. + Extended status information is in the ImageError field of ImageContext. + +**/ +RETURN_STATUS +EFIAPI +PeCoffLoaderRelocateImage ( + IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext + ) +{ + return mPeiEfiPeiPeCoffLoader->RelocateImage (mPeiEfiPeiPeCoffLoader, ImageContext); +} + +/** + Loads a PE/COFF image into memory. + + Loads the PE/COFF image accessed through the ImageRead service of ImageContext into the buffer + specified by the ImageAddress and ImageSize fields of ImageContext. The caller must allocate + the load buffer and fill in the ImageAddress and ImageSize fields prior to calling this function. + The EntryPoint, FixupDataSize, CodeView, and PdbPointer fields of ImageContext are computed. + If ImageContext is NULL, then ASSERT(). + + @param ImageContext Pointer to the image context structure that describes the PE/COFF + image that is being loaded. + + @retval RETURN_SUCCESS The PE/COFF image was loaded into the buffer specified by + the ImageAddress and ImageSize fields of ImageContext. + Extended status information is in the ImageError field of ImageContext. + @retval RETURN_BUFFER_TOO_SMALL The caller did not provide a large enough buffer. + Extended status information is in the ImageError field of ImageContext. + @retval RETURN_LOAD_ERROR The PE/COFF image is an EFI Runtime image with no relocations. + Extended status information is in the ImageError field of ImageContext. + @retval RETURN_INVALID_PARAMETER The image address is invalid. + Extended status information is in the ImageError field of ImageContext. + +**/ +RETURN_STATUS +EFIAPI +PeCoffLoaderLoadImage ( + IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext + ) +{ + return mPeiEfiPeiPeCoffLoader->LoadImage (mPeiEfiPeiPeCoffLoader, ImageContext); +} + +/** + ImageRead function that operates on a memory buffer whos base is passed into + FileHandle. + + @param FileHandle Ponter to baes of the input stream + @param FileOffset Offset to the start of the buffer + @param ReadSize Number of bytes to copy into the buffer + @param Buffer Location to place results of read + + @retval RETURN_SUCCESS Data is read from FileOffset from the Handle into + the buffer. +**/ +RETURN_STATUS +EFIAPI +PeCoffLoaderImageReadFromMemory ( + IN VOID *FileHandle, + IN UINTN FileOffset, + IN OUT UINTN *ReadSize, + OUT VOID *Buffer + ) +{ + return RETURN_UNSUPPORTED; +} + + +/** + Reapply fixups on a fixed up PE32/PE32+ image to allow virutal calling at EFI + runtime. + + PE_COFF_LOADER_IMAGE_CONTEXT.FixupData stores information needed to reapply + the fixups with a virtual mapping. + + + @param ImageBase Base address of relocated image + @param VirtImageBase Virtual mapping for ImageBase + @param ImageSize Size of the image to relocate + @param RelocationData Location to place results of read + +**/ +VOID +EFIAPI +PeCoffLoaderRelocateImageForRuntime ( + IN PHYSICAL_ADDRESS ImageBase, + IN PHYSICAL_ADDRESS VirtImageBase, + IN UINTN ImageSize, + IN VOID *RelocationData + ) +{ +} + +/** + Unloads a loaded PE/COFF image from memory and releases its taken resource. + + For NT32 emulator, the PE/COFF image loaded by system needs to release. + For real platform, the PE/COFF image loaded by Core doesn't needs to be unloaded, + this function can simply return RETURN_SUCCESS. + + @param ImageContext Pointer to the image context structure that describes the PE/COFF + image to be unloaded. + + @retval RETURN_SUCCESS The PE/COFF image was unloaded successfully. +**/ +RETURN_STATUS +EFIAPI +PeCoffLoaderUnloadImage ( + IN PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext + ) +{ + return mPeiEfiPeiPeCoffLoader->UnloadImage (mPeiEfiPeiPeCoffLoader, ImageContext); +} diff --git a/Nt32Pkg/Library/PeiNt32PeCoffLib/PeiNt32PeCoffLib.inf b/Nt32Pkg/Library/PeiNt32PeCoffLib/PeiNt32PeCoffLib.inf new file mode 100644 index 0000000000..9bfadfd6d7 --- /dev/null +++ b/Nt32Pkg/Library/PeiNt32PeCoffLib/PeiNt32PeCoffLib.inf @@ -0,0 +1,50 @@ +#/** @file +# PeCoff libary for PEIM modules that run NT32 emulator. +# +# Lib to provide memory journal status code reporting Routines +# Copyright (c) 2007, 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. + +# +# +#**/ + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = PeiNt32PeCoffLib + FILE_GUID = 91404129-c58a-40bb-8a2b-f05bc05a961c + MODULE_TYPE = PEIM + VERSION_STRING = 1.0 + LIBRARY_CLASS = PeCoffLib|PEIM + EDK_RELEASE_VERSION = 0x00020000 + EFI_SPECIFICATION_VERSION = 0x00020000 + + CONSTRUCTOR = PeiNt32PeCoffLibConstructor + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 +# + +[Sources.common] + PeiNt32PeCoffLib.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + Nt32Pkg/Nt32Pkg.dec + +[LibraryClasses] + DebugLib + HobLib + +[Guids] + gEfiPeiPeCoffLoaderGuid # ALWAYS_CONSUMED + diff --git a/Nt32Pkg/Nt32Pkg.dsc b/Nt32Pkg/Nt32Pkg.dsc index 14286f9bf2..a54ff4de2a 100644 --- a/Nt32Pkg/Nt32Pkg.dsc +++ b/Nt32Pkg/Nt32Pkg.dsc @@ -79,6 +79,7 @@ [LibraryClasses.common.SEC] DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf ReportStatusCodeLib|IntelFrameworkModulePkg/Library/BaseReportStatusCodeLib/BaseReportStatusCodeLib.inf + PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf [LibraryClasses.common.DXE_CORE] DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf @@ -88,10 +89,10 @@ MemoryAllocationLib|MdePkg/Library/DxeMemoryAllocationLib/DxeMemoryAllocationLib.inf UefiLib|MdePkg/Library/UefiLib/UefiLib.inf ReportStatusCodeLib|IntelFrameworkModulePkg/Library/DxeReportStatusCodeLibFramework/DxeReportStatusCodeLib.inf - PeCoffLoaderLib|MdeModulePkg/Library/DxePeCoffLoaderFromHobLib/DxePeCoffLoaderFromHobLib.inf UefiRuntimeServicesTableLib|MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf DebugLib|IntelFrameworkModulePkg/Library/PeiDxeDebugLibReportStatusCode/PeiDxeDebugLibReportStatusCode.inf PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf + PeCoffLib|Nt32Pkg/Library/DxeNT32PeCoffLib/DxeNT32PeCoffLib.inf [LibraryClasses.common.DXE_SMM_DRIVER] DxeServicesTableLib|MdePkg/Library/DxeServicesTableLib/DxeServicesTableLib.inf @@ -118,11 +119,11 @@ PeiServicesLib|MdePkg/Library/PeiServicesLib/PeiServicesLib.inf MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf ReportStatusCodeLib|IntelFrameworkModulePkg/Library/PeiReportStatusCodeLib/PeiReportStatusCodeLib.inf - PeCoffLoaderLib|Nt32Pkg/Library/Nt32PeCoffLoaderLib/Nt32PeCoffLoaderLib.inf PeiServicesTablePointerLib|MdePkg/Library/PeiServicesTablePointerLib/PeiServicesTablePointerLib.inf OemHookStatusCodeLib|Nt32Pkg/Library/PeiNt32OemHookStatusCodeLib/PeiNt32OemHookStatusCodeLib.inf PeCoffGetEntryPointLib|Nt32Pkg/Library/Nt32PeiPeCoffGetEntryPointLib/Nt32PeiPeCoffGetEntryPointLib.inf DebugLib|IntelFrameworkModulePkg/Library/PeiDxeDebugLibReportStatusCode/PeiDxeDebugLibReportStatusCode.inf + PeCoffLib|Nt32Pkg/Library/PeiNT32PeCoffLib/PeiNT32PeCoffLib.inf [LibraryClasses.common.PEI_CORE] HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf @@ -135,7 +136,7 @@ PeCoffGetEntryPointLib|Nt32Pkg/Library/Nt32PeiPeCoffGetEntryPointLib/Nt32PeiPeCoffGetEntryPointLib.inf PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf DebugLib|IntelFrameworkModulePkg/Library/PeiDxeDebugLibReportStatusCode/PeiDxeDebugLibReportStatusCode.inf - PeCoffLoaderLib|Nt32Pkg/Library/Nt32PeCoffLoaderLib/Nt32PeCoffLoaderLib.inf + PeCoffLib|Nt32Pkg/Library/PeiCoreNT32PeCoffLib/PeiCoreNT32PeCoffLib.inf [LibraryClasses.common.DXE_RUNTIME_DRIVER] UefiRuntimeServicesTableLib|MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf -- 2.39.2