From c21a7a4e83be66266feff5c44c9be6a6f22b7a31 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Thu, 12 Oct 2023 13:51:17 +0300 Subject: [PATCH] MdeModulePkg: Added EFI_PEI_LOAD_FILE_WITH_HOB_PPI and removed temporary hook. --- MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf | 4 +- MdeModulePkg/Core/DxeIplPeim/DxeLoad.c | 8 +- MdeModulePkg/Core/Pei/Image/Image.c | 209 ++++++++++++++++++------ MdeModulePkg/Core/Pei/PeiMain.h | 11 ++ MdeModulePkg/Core/Pei/PeiMain.inf | 1 + MdePkg/Include/Ppi/LoadFile.h | 19 +++ MdePkg/MdePkg.dec | 1 + 7 files changed, 193 insertions(+), 60 deletions(-) diff --git a/MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf b/MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf index 26ab4bde91..9f6f221390 100644 --- a/MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf +++ b/MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf @@ -89,7 +89,7 @@ gEfiPeiDecompressPpiGuid ## PRODUCES gEfiEndOfPeiSignalPpiGuid ## SOMETIMES_PRODUCES # Not produced on S3 boot path gEfiPeiReadOnlyVariable2PpiGuid ## SOMETIMES_CONSUMES - gEfiPeiLoadFilePpiGuid ## SOMETIMES_CONSUMES + gEfiPeiLoadFileWithHobPpiGuid ## SOMETIMES_CONSUMES gEfiPeiS3Resume2PpiGuid ## SOMETIMES_CONSUMES # Consumed on S3 boot path gEfiPeiRecoveryModulePpiGuid ## SOMETIMES_CONSUMES # Consumed on recovery boot path ## SOMETIMES_CONSUMES @@ -130,7 +130,7 @@ gEfiMdeModulePkgTokenSpaceGuid.PcdImageProtectionPolicy ## SOMETIMES_CONSUMES [Depex] - gEfiPeiLoadFilePpiGuid AND gEfiPeiMasterBootModePpiGuid + gEfiPeiLoadFileWithHobPpiGuid AND gEfiPeiMasterBootModePpiGuid # # [BootMode] diff --git a/MdeModulePkg/Core/DxeIplPeim/DxeLoad.c b/MdeModulePkg/Core/DxeIplPeim/DxeLoad.c index e4ab76a11f..c65c94afa7 100644 --- a/MdeModulePkg/Core/DxeIplPeim/DxeLoad.c +++ b/MdeModulePkg/Core/DxeIplPeim/DxeLoad.c @@ -260,7 +260,7 @@ DxeLoadCore ( EFI_BOOT_MODE BootMode; EFI_PEI_FILE_HANDLE FileHandle; EFI_PEI_READ_ONLY_VARIABLE2_PPI *Variable; - EFI_PEI_LOAD_FILE_PPI *LoadFile; + EFI_PEI_LOAD_FILE_WITH_HOB_PPI *LoadFile; UINTN Instance; UINT32 AuthenticationState; UINTN DataSize; @@ -410,19 +410,19 @@ DxeLoadCore ( // Instance = 0; do { - Status = PeiServicesLocatePpi (&gEfiPeiLoadFilePpiGuid, Instance++, NULL, (VOID **)&LoadFile); + Status = PeiServicesLocatePpi (&gEfiPeiLoadFileWithHobPpiGuid, Instance++, NULL, (VOID **)&LoadFile); // // These must exist an instance of EFI_PEI_LOAD_FILE_PPI to support to load DxeCore file handle successfully. // ASSERT_EFI_ERROR (Status); Status = LoadFile->LoadFile ( - (CONST EFI_PEI_LOAD_FILE_PPI *)&ImageContext, FileHandle, &DxeCoreAddress, &DxeCoreSize, &DxeCoreEntryPoint, - &AuthenticationState + &AuthenticationState, + ImageContext ); } while (EFI_ERROR (Status)); diff --git a/MdeModulePkg/Core/Pei/Image/Image.c b/MdeModulePkg/Core/Pei/Image/Image.c index d0ea3b01ac..a32f1b949a 100644 --- a/MdeModulePkg/Core/Pei/Image/Image.c +++ b/MdeModulePkg/Core/Pei/Image/Image.c @@ -12,10 +12,21 @@ EFI_PEI_LOAD_FILE_PPI mPeiLoadImagePpi = { PeiLoadImageLoadImageWrapper }; -EFI_PEI_PPI_DESCRIPTOR gPpiLoadFilePpiList = { - (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), - &gEfiPeiLoadFilePpiGuid, - &mPeiLoadImagePpi +EFI_PEI_LOAD_FILE_WITH_HOB_PPI mPeiLoadImageWithHobPpi = { + PeiLoadImageLoadImageWithHob +}; + +EFI_PEI_PPI_DESCRIPTOR gPpiLoadFilePpiList[] = { + { + EFI_PEI_PPI_DESCRIPTOR_PPI, + &gEfiPeiLoadFileWithHobPpiGuid, + &mPeiLoadImageWithHobPpi + }, + { + (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), + &gEfiPeiLoadFilePpiGuid, + &mPeiLoadImagePpi + } }; /** @@ -461,10 +472,6 @@ PeiLoadImageLoadImage ( EFI_PHYSICAL_ADDRESS ImageAddress; UINTN DebugBase; UEFI_IMAGE_LOADER_IMAGE_CONTEXT ImageContext; - UINTN Instance; - EFI_PEI_LOAD_FILE_PPI *LoadFile; - BOOLEAN IsHook; - HOB_IMAGE_CONTEXT *Hob; *EntryPoint = 0; *AuthenticationState = 0; @@ -506,52 +513,146 @@ PeiLoadImageLoadImage ( } // - // Save ImageContext into DXE CORE HOB + // Got the entry point from the loaded Pe32Data // - Instance = 0; - IsHook = TRUE; - do { - Status = PeiServicesLocatePpi (&gEfiPeiLoadFilePpiGuid, Instance++, NULL, (VOID **)&LoadFile); - if ((UINTN)PeiServices == (UINTN)LoadFile) { - IsHook = FALSE; - } - } while (!EFI_ERROR (Status)); - - if (IsHook) { - Hob = (HOB_IMAGE_CONTEXT *)*PeiServices; - - Hob->FormatIndex = ImageContext.FormatIndex; - - if (Hob->FormatIndex == UefiImageFormatPe) { - Hob->Ctx.Pe.ImageBuffer = (UINT32)(UINTN)ImageContext.Ctx.Pe.ImageBuffer; - Hob->Ctx.Pe.AddressOfEntryPoint = ImageContext.Ctx.Pe.AddressOfEntryPoint; - Hob->Ctx.Pe.ImageType = ImageContext.Ctx.Pe.ImageType; - Hob->Ctx.Pe.FileBuffer = (UINT32)(UINTN)ImageContext.Ctx.Pe.FileBuffer; - Hob->Ctx.Pe.ExeHdrOffset = ImageContext.Ctx.Pe.ExeHdrOffset; - Hob->Ctx.Pe.SizeOfImage = ImageContext.Ctx.Pe.SizeOfImage; - Hob->Ctx.Pe.FileSize = ImageContext.Ctx.Pe.FileSize; - Hob->Ctx.Pe.Subsystem = ImageContext.Ctx.Pe.Subsystem; - Hob->Ctx.Pe.SectionAlignment = ImageContext.Ctx.Pe.SectionAlignment; - Hob->Ctx.Pe.SectionsOffset = ImageContext.Ctx.Pe.SectionsOffset; - Hob->Ctx.Pe.NumberOfSections = ImageContext.Ctx.Pe.NumberOfSections; - Hob->Ctx.Pe.SizeOfHeaders = ImageContext.Ctx.Pe.SizeOfHeaders; - } else if (Hob->FormatIndex == UefiImageFormatUe) { - Hob->Ctx.Ue.ImageBuffer = (UINT32)(UINTN)ImageContext.Ctx.Ue.ImageBuffer; - Hob->Ctx.Ue.FileBuffer = (UINT32)(UINTN)ImageContext.Ctx.Ue.FileBuffer; - Hob->Ctx.Ue.EntryPointAddress = ImageContext.Ctx.Ue.EntryPointAddress; - Hob->Ctx.Ue.LoadTablesFileOffset = ImageContext.Ctx.Ue.LoadTablesFileOffset; - Hob->Ctx.Ue.NumLoadTables = ImageContext.Ctx.Ue.NumLoadTables; - Hob->Ctx.Ue.LoadTables = (UINT32)(UINTN)ImageContext.Ctx.Ue.LoadTables; - Hob->Ctx.Ue.Segments = (UINT32)(UINTN)ImageContext.Ctx.Ue.Segments; - Hob->Ctx.Ue.LastSegmentIndex = ImageContext.Ctx.Ue.LastSegmentIndex; - Hob->Ctx.Ue.SegmentAlignment = ImageContext.Ctx.Ue.SegmentAlignment; - Hob->Ctx.Ue.ImageSize = ImageContext.Ctx.Ue.ImageSize; - Hob->Ctx.Ue.Subsystem = ImageContext.Ctx.Ue.Subsystem; - Hob->Ctx.Ue.SegmentImageInfoIterSize = ImageContext.Ctx.Ue.SegmentImageInfoIterSize; - Hob->Ctx.Ue.SegmentsFileOffset = ImageContext.Ctx.Ue.SegmentsFileOffset; + *EntryPoint = UefiImageLoaderGetImageEntryPoint (&ImageContext); + + if (ImageAddressArg != NULL) { + *ImageAddressArg = ImageAddress; + } + + if (ImageSizeArg != NULL) { + *ImageSizeArg =UefiImageGetImageSize (&ImageContext); + } + + DEBUG_CODE_BEGIN (); + CHAR8 EfiFileName[512]; + UINT16 Machine; + + Machine = UefiImageGetMachine (&ImageContext); + + // + // Print debug message: Loading PEIM at 0x12345678 EntryPoint=0x12345688 Driver.efi + // + if (Machine != EFI_IMAGE_MACHINE_IA64) { + DEBUG ((DEBUG_INFO | DEBUG_LOAD, "Loading PEIM at 0x%11p DebugBase=0x%11p EntryPoint=0x%11p ", (VOID *)(UINTN)ImageAddress, (VOID *)(UINTN)DebugBase, (VOID *)(UINTN)*EntryPoint)); } else { - ASSERT (FALSE); + // + // For IPF Image, the real entry point should be print. + // + DEBUG ((DEBUG_INFO | DEBUG_LOAD, "Loading PEIM at 0x%11p DebugBase=0x%11p EntryPoint=0x%11p ", (VOID *)(UINTN)ImageAddress, (VOID *)(UINTN)DebugBase, (VOID *)(UINTN)(*(UINT64 *)(UINTN)*EntryPoint))); } + + // + // Print Module Name by PeImage PDB file name. + // + Status = UefiImageGetModuleNameFromSymbolsPath ( + &ImageContext, + EfiFileName, + sizeof (EfiFileName) + ); + if (!RETURN_ERROR (Status)) { + DEBUG ((DEBUG_INFO | DEBUG_LOAD, "%a", EfiFileName)); + } + + DEBUG_CODE_END (); + + DEBUG ((DEBUG_INFO | DEBUG_LOAD, "\n")); + + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +PeiLoadImageLoadImageWithHob ( + IN EFI_PEI_FILE_HANDLE FileHandle, + OUT EFI_PHYSICAL_ADDRESS *ImageAddressArg OPTIONAL, + OUT UINT64 *ImageSizeArg OPTIONAL, + OUT EFI_PHYSICAL_ADDRESS *EntryPoint, + OUT UINT32 *AuthenticationState, + OUT HOB_IMAGE_CONTEXT *Hob + ) +{ + EFI_STATUS Status; + VOID *Pe32Data; + UINT32 Pe32DataSize; + EFI_PHYSICAL_ADDRESS ImageAddress; + UINTN DebugBase; + UEFI_IMAGE_LOADER_IMAGE_CONTEXT ImageContext; + + *EntryPoint = 0; + *AuthenticationState = 0; + + // + // Try to find the exe section. + // + Status = PeiServicesFfsFindSectionData4 ( + EFI_SECTION_PE32, + 0, + FileHandle, + &Pe32Data, + &Pe32DataSize, + AuthenticationState + ); + if (EFI_ERROR (Status)) { + // + // PEI core only carry the loader function for PE32 executables + // If this two section does not exist, just return. + // + return Status; + } + + DEBUG ((DEBUG_INFO, "Loading PEIM %g\n", FileHandle)); + + // + // If memory is installed, perform the shadow operations + // + Status = LoadAndRelocateUefiImage ( + FileHandle, + Pe32Data, + Pe32DataSize, + &ImageContext, + &ImageAddress, + &DebugBase + ); + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Save ImageContext into DXE CORE HOB + // + Hob->FormatIndex = ImageContext.FormatIndex; + + if (Hob->FormatIndex == UefiImageFormatPe) { + Hob->Ctx.Pe.ImageBuffer = (UINT32)(UINTN)ImageContext.Ctx.Pe.ImageBuffer; + Hob->Ctx.Pe.AddressOfEntryPoint = ImageContext.Ctx.Pe.AddressOfEntryPoint; + Hob->Ctx.Pe.ImageType = ImageContext.Ctx.Pe.ImageType; + Hob->Ctx.Pe.FileBuffer = (UINT32)(UINTN)ImageContext.Ctx.Pe.FileBuffer; + Hob->Ctx.Pe.ExeHdrOffset = ImageContext.Ctx.Pe.ExeHdrOffset; + Hob->Ctx.Pe.SizeOfImage = ImageContext.Ctx.Pe.SizeOfImage; + Hob->Ctx.Pe.FileSize = ImageContext.Ctx.Pe.FileSize; + Hob->Ctx.Pe.Subsystem = ImageContext.Ctx.Pe.Subsystem; + Hob->Ctx.Pe.SectionAlignment = ImageContext.Ctx.Pe.SectionAlignment; + Hob->Ctx.Pe.SectionsOffset = ImageContext.Ctx.Pe.SectionsOffset; + Hob->Ctx.Pe.NumberOfSections = ImageContext.Ctx.Pe.NumberOfSections; + Hob->Ctx.Pe.SizeOfHeaders = ImageContext.Ctx.Pe.SizeOfHeaders; + } else if (Hob->FormatIndex == UefiImageFormatUe) { + Hob->Ctx.Ue.ImageBuffer = (UINT32)(UINTN)ImageContext.Ctx.Ue.ImageBuffer; + Hob->Ctx.Ue.FileBuffer = (UINT32)(UINTN)ImageContext.Ctx.Ue.FileBuffer; + Hob->Ctx.Ue.EntryPointAddress = ImageContext.Ctx.Ue.EntryPointAddress; + Hob->Ctx.Ue.LoadTablesFileOffset = ImageContext.Ctx.Ue.LoadTablesFileOffset; + Hob->Ctx.Ue.NumLoadTables = ImageContext.Ctx.Ue.NumLoadTables; + Hob->Ctx.Ue.LoadTables = (UINT32)(UINTN)ImageContext.Ctx.Ue.LoadTables; + Hob->Ctx.Ue.Segments = (UINT32)(UINTN)ImageContext.Ctx.Ue.Segments; + Hob->Ctx.Ue.LastSegmentIndex = ImageContext.Ctx.Ue.LastSegmentIndex; + Hob->Ctx.Ue.SegmentAlignment = ImageContext.Ctx.Ue.SegmentAlignment; + Hob->Ctx.Ue.ImageSize = ImageContext.Ctx.Ue.ImageSize; + Hob->Ctx.Ue.Subsystem = ImageContext.Ctx.Ue.Subsystem; + Hob->Ctx.Ue.SegmentImageInfoIterSize = ImageContext.Ctx.Ue.SegmentImageInfoIterSize; + Hob->Ctx.Ue.SegmentsFileOffset = ImageContext.Ctx.Ue.SegmentsFileOffset; + } else { + ASSERT (FALSE); } // @@ -629,7 +730,7 @@ PeiLoadImageLoadImageWrapper ( ) { return PeiLoadImageLoadImage ( - (CONST EFI_PEI_SERVICES **)This, + GetPeiServicesTablePointer (), FileHandle, ImageAddressArg, ImageSizeArg, @@ -799,13 +900,13 @@ InitializeImageServices ( // The first time we are XIP (running from FLASH). We need to remember the // FLASH address so we can reinstall the memory version that runs faster // - PrivateData->XipLoadFile = &gPpiLoadFilePpiList; + PrivateData->XipLoadFile = gPpiLoadFilePpiList; PeiServicesInstallPpi (PrivateData->XipLoadFile); } else { // // 2nd time we are running from memory so replace the XIP version with the // new memory version. // - PeiServicesReInstallPpi (PrivateData->XipLoadFile, &gPpiLoadFilePpiList); + PeiServicesReInstallPpi (PrivateData->XipLoadFile, gPpiLoadFilePpiList); } } diff --git a/MdeModulePkg/Core/Pei/PeiMain.h b/MdeModulePkg/Core/Pei/PeiMain.h index 0552725a48..4e35b28aa2 100644 --- a/MdeModulePkg/Core/Pei/PeiMain.h +++ b/MdeModulePkg/Core/Pei/PeiMain.h @@ -1474,6 +1474,17 @@ PeiLoadImageLoadImageWrapper ( OUT UINT32 *AuthenticationState ); +EFI_STATUS +EFIAPI +PeiLoadImageLoadImageWithHob ( + IN EFI_PEI_FILE_HANDLE FileHandle, + OUT EFI_PHYSICAL_ADDRESS *ImageAddressArg OPTIONAL, + OUT UINT64 *ImageSizeArg OPTIONAL, + OUT EFI_PHYSICAL_ADDRESS *EntryPoint, + OUT UINT32 *AuthenticationState, + OUT HOB_IMAGE_CONTEXT *Hob + ); + /** Provide a callback for when the security PPI is installed. diff --git a/MdeModulePkg/Core/Pei/PeiMain.inf b/MdeModulePkg/Core/Pei/PeiMain.inf index 54dc10da13..80820ca8c6 100644 --- a/MdeModulePkg/Core/Pei/PeiMain.inf +++ b/MdeModulePkg/Core/Pei/PeiMain.inf @@ -93,6 +93,7 @@ ## PRODUCES ## CONSUMES gEfiPeiLoadFilePpiGuid + gEfiPeiLoadFileWithHobPpiGuid gEfiPeiSecurity2PpiGuid ## NOTIFY gEfiTemporaryRamSupportPpiGuid ## SOMETIMES_CONSUMES gEfiTemporaryRamDonePpiGuid ## SOMETIMES_CONSUMES diff --git a/MdePkg/Include/Ppi/LoadFile.h b/MdePkg/Include/Ppi/LoadFile.h index 838e3fda90..22c2071191 100644 --- a/MdePkg/Include/Ppi/LoadFile.h +++ b/MdePkg/Include/Ppi/LoadFile.h @@ -12,10 +12,13 @@ #ifndef __LOAD_FILE_PPI_H__ #define __LOAD_FILE_PPI_H__ +#include + #define EFI_PEI_LOAD_FILE_PPI_GUID \ { 0xb9e0abfe, 0x5979, 0x4914, { 0x97, 0x7f, 0x6d, 0xee, 0x78, 0xc2, 0x78, 0xa6 } } typedef struct _EFI_PEI_LOAD_FILE_PPI EFI_PEI_LOAD_FILE_PPI; +typedef struct _EFI_PEI_LOAD_FILE_WITH_HOB_PPI EFI_PEI_LOAD_FILE_WITH_HOB_PPI; /** Loads a PEIM into memory for subsequent execution. @@ -56,6 +59,17 @@ EFI_STATUS OUT UINT32 *AuthenticationState ); +typedef +EFI_STATUS +(EFIAPI *EFI_PEI_LOAD_FILE_WITH_HOB)( + IN EFI_PEI_FILE_HANDLE FileHandle, + OUT EFI_PHYSICAL_ADDRESS *ImageAddress, + OUT UINT64 *ImageSize, + OUT EFI_PHYSICAL_ADDRESS *EntryPoint, + OUT UINT32 *AuthenticationState, + OUT HOB_IMAGE_CONTEXT *Hob + ); + /// /// This PPI is a pointer to the Load File service. /// This service will be published by a PEIM. The PEI Foundation @@ -65,6 +79,11 @@ struct _EFI_PEI_LOAD_FILE_PPI { EFI_PEI_LOAD_FILE LoadFile; }; +struct _EFI_PEI_LOAD_FILE_WITH_HOB_PPI { + EFI_PEI_LOAD_FILE_WITH_HOB LoadFile; +}; + extern EFI_GUID gEfiPeiLoadFilePpiGuid; +extern EFI_GUID gEfiPeiLoadFileWithHobPpiGuid; #endif diff --git a/MdePkg/MdePkg.dec b/MdePkg/MdePkg.dec index 0e25637870..60921efdd0 100644 --- a/MdePkg/MdePkg.dec +++ b/MdePkg/MdePkg.dec @@ -953,6 +953,7 @@ ## Include/Ppi/LoadFile.h gEfiPeiLoadFilePpiGuid = { 0xb9e0abfe, 0x5979, 0x4914, { 0x97, 0x7f, 0x6d, 0xee, 0x78, 0xc2, 0x78, 0xa6 } } + gEfiPeiLoadFileWithHobPpiGuid = { 0x14c2d0d0, 0xccfd, 0x40e5, { 0xae, 0xa7, 0x57, 0x23, 0x58, 0xdd, 0xbf, 0xe8 } } ## Include/Ppi/Decompress.h gEfiPeiDecompressPpiGuid = { 0x1a36e4e7, 0xfab6, 0x476a, { 0x8e, 0x75, 0x69, 0x5a, 0x5, 0x76, 0xfd, 0xd7 } }