SecurePE: Replaced old PE loader with Secure one.

This commit is contained in:
Mikhail Krichanov 2024-07-18 11:30:45 +03:00
parent 666a6ab2d3
commit a955e8811b
291 changed files with 12502 additions and 7161 deletions

View File

@ -54,9 +54,9 @@
UefiLib|MdePkg/Library/UefiLib/UefiLib.inf
DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf
UefiRuntimeServicesTableLib|MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf
PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf
PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf
PeCoffExtraActionLib|MdePkg/Library/BasePeCoffExtraActionLibNull/BasePeCoffExtraActionLibNull.inf
PeCoffLib2|MdePkg/Library/BasePeCoffLib2/BasePeCoffLib2.inf
UefiImageLib|MdePkg/Library/BaseUefiImageLib/BaseUefiImageLibPeCoff.inf
UefiImageExtraActionLib|MdePkg/Library/BaseUefiImageExtraActionLibNull/BaseUefiImageExtraActionLibNull.inf
UefiHiiServicesLib|MdeModulePkg/Library/UefiHiiServicesLib/UefiHiiServicesLib.inf
HiiLib|MdeModulePkg/Library/UefiHiiLib/UefiHiiLib.inf
@ -111,7 +111,7 @@
ArmPkg/Library/ArmDisassemblerLib/ArmDisassemblerLib.inf
ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf
ArmPkg/Library/DebugAgentSymbolsBaseLib/DebugAgentSymbolsBaseLib.inf
ArmPkg/Library/DebugPeCoffExtraActionLib/DebugPeCoffExtraActionLib.inf
ArmPkg/Library/DebugUefiImageExtraActionLib/DebugUefiImageExtraActionLib.inf
ArmPkg/Library/DefaultExceptionHandlerLib/DefaultExceptionHandlerLib.inf
ArmPkg/Library/SemiHostingDebugLib/SemiHostingDebugLib.inf
ArmPkg/Library/SemiHostingSerialPortLib/SemiHostingSerialPortLib.inf

View File

@ -35,7 +35,6 @@
DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf
MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf
PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf
SerialPortLib|MdePkg/Library/BaseSerialPortLibNull/BaseSerialPortLibNull.inf
UefiBootServicesTableLib|MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.inf

View File

@ -20,7 +20,6 @@
#include <Library/UefiBootServicesTableLib.h>
#include <Library/DxeServicesTableLib.h>
#include <Library/CacheMaintenanceLib.h>
#include <Library/PeCoffGetEntryPointLib.h>
#include <Library/UefiLib.h>
#include <Library/CpuLib.h>
#include <Library/DefaultExceptionHandlerLib.h>

View File

@ -49,7 +49,6 @@
DxeServicesTableLib
HobLib
MemoryAllocationLib
PeCoffGetEntryPointLib
UefiDriverEntryPoint
UefiLib

View File

@ -32,4 +32,3 @@
BaseLib
PrintLib
DebugLib
PeCoffGetEntryPointLib

View File

@ -13,8 +13,8 @@
#include <Library/DebugLib.h>
#include <Library/DebugAgentLib.h>
#include <Library/PcdLib.h>
#include <Library/PeCoffExtraActionLib.h>
#include <Library/PeCoffLib.h>
#include <Library/UefiImageExtraActionLib.h>
#include <Library/UefiImageLib.h>
#include <Pi/PiFirmwareFile.h>
#include <Pi/PiFirmwareVolume.h>
@ -165,34 +165,39 @@ GetFfsFile (
EFI_STATUS
GetImageContext (
IN EFI_FFS_FILE_HEADER *FfsHeader,
OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext
IN EFI_FFS_FILE_HEADER *FfsHeader,
OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext
)
{
EFI_STATUS Status;
UINTN ParsedLength;
UINTN SectionSize;
UINTN SectionLength;
EFI_COMMON_SECTION_HEADER *Section;
VOID *EfiImage;
UINTN ImageAddress;
EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *DebugEntry;
VOID *CodeViewEntryPointer;
EFI_STATUS Status;
UINTN ParsedLength;
UINT32 SectionSize;
UINT32 SectionLength;
EFI_COMMON_SECTION_HEADER *Section;
VOID *EfiImage;
Section = (EFI_COMMON_SECTION_HEADER *)(FfsHeader + 1);
SectionSize = *(UINT32 *)(FfsHeader->Size) & 0x00FFFFFF;
SectionSize -= sizeof (EFI_FFS_FILE_HEADER);
ParsedLength = 0;
EfiImage = NULL;
Section = (EFI_COMMON_SECTION_HEADER *)(FfsHeader + 1);
SectionLength = 0;
SectionSize = *(UINT32 *)(FfsHeader->Size) & 0x00FFFFFF;
SectionSize -= sizeof (EFI_FFS_FILE_HEADER);
ParsedLength = 0;
EfiImage = NULL;
while (ParsedLength < SectionSize) {
//
// Size is 24 bits wide so mask upper 8 bits.
//
SectionLength = *(UINT32 *)Section->Size & 0x00FFFFFF;
if (SectionLength < sizeof (*Section)) {
return EFI_VOLUME_CORRUPTED;
}
if ((Section->Type == EFI_SECTION_PE32) || (Section->Type == EFI_SECTION_TE)) {
EfiImage = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)(Section + 1);
EfiImage = (Section + 1);
break;
}
//
// Size is 24 bits wide so mask upper 8 bits.
// SectionLength is adjusted it is 4 byte aligned.
// Go to the next section
//
@ -208,34 +213,10 @@ GetImageContext (
}
// Initialize the Image Context
ZeroMem (ImageContext, sizeof (PE_COFF_LOADER_IMAGE_CONTEXT));
ImageContext->Handle = EfiImage;
ImageContext->ImageRead = PeCoffLoaderImageReadFromMemory;
Status = PeCoffLoaderGetImageInfo (ImageContext);
if (!EFI_ERROR (Status) && ((VOID *)(UINTN)ImageContext->DebugDirectoryEntryRva != NULL)) {
ImageAddress = ImageContext->ImageAddress;
if (ImageContext->IsTeImage) {
ImageAddress += sizeof (EFI_TE_IMAGE_HEADER) - ((EFI_TE_IMAGE_HEADER *)EfiImage)->StrippedSize;
}
DebugEntry = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *)(ImageAddress + ImageContext->DebugDirectoryEntryRva);
if (DebugEntry->Type == EFI_IMAGE_DEBUG_TYPE_CODEVIEW) {
CodeViewEntryPointer = (VOID *)(ImageAddress + (UINTN)DebugEntry->RVA);
switch (*(UINT32 *)CodeViewEntryPointer) {
case CODEVIEW_SIGNATURE_NB10:
ImageContext->PdbPointer = (CHAR8 *)CodeViewEntryPointer + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY);
break;
case CODEVIEW_SIGNATURE_RSDS:
ImageContext->PdbPointer = (CHAR8 *)CodeViewEntryPointer + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_RSDS_ENTRY);
break;
case CODEVIEW_SIGNATURE_MTOC:
ImageContext->PdbPointer = (CHAR8 *)CodeViewEntryPointer + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_MTOC_ENTRY);
break;
default:
break;
}
}
// FIXME: Common FFS API with size checks
Status = UefiImageInitializeContext (ImageContext, EfiImage, SectionLength - sizeof (*Section));
if (!EFI_ERROR(Status)) {
Status = UefiImageLoadImageInplace( ImageContext);
}
return Status;
@ -271,9 +252,9 @@ InitializeDebugAgent (
IN DEBUG_AGENT_CONTINUE Function OPTIONAL
)
{
EFI_STATUS Status;
EFI_FFS_FILE_HEADER *FfsHeader;
PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;
EFI_STATUS Status;
EFI_FFS_FILE_HEADER *FfsHeader;
UEFI_IMAGE_LOADER_IMAGE_CONTEXT ImageContext;
// We use InitFlag to know if DebugAgent has been initialized from
// Sec (DEBUG_AGENT_INIT_PREMEM_SEC) or PrePi (DEBUG_AGENT_INIT_POSTMEM_SEC)
@ -286,7 +267,7 @@ InitializeDebugAgent (
if (!EFI_ERROR (Status)) {
Status = GetImageContext (FfsHeader, &ImageContext);
if (!EFI_ERROR (Status)) {
PeCoffLoaderRelocateImageExtraAction (&ImageContext);
UefiImageLoaderRelocateImageExtraAction (&ImageContext);
}
}
} else if (InitFlag == DEBUG_AGENT_INIT_POSTMEM_SEC) {
@ -297,7 +278,7 @@ InitializeDebugAgent (
if (!EFI_ERROR (Status)) {
Status = GetImageContext (FfsHeader, &ImageContext);
if (!EFI_ERROR (Status)) {
PeCoffLoaderRelocateImageExtraAction (&ImageContext);
UefiImageLoaderRelocateImageExtraAction (&ImageContext);
}
}
@ -308,7 +289,7 @@ InitializeDebugAgent (
if (!EFI_ERROR (Status)) {
Status = GetImageContext (FfsHeader, &ImageContext);
if (!EFI_ERROR (Status)) {
PeCoffLoaderRelocateImageExtraAction (&ImageContext);
UefiImageLoaderRelocateImageExtraAction (&ImageContext);
}
}
}

View File

@ -24,8 +24,8 @@
[LibraryClasses]
DebugLib
PcdLib
PeCoffExtraActionLib
PeCoffLib
UefiImageExtraActionLib
UefiImageLib
[Pcd]
gArmTokenSpaceGuid.PcdSecureFvBaseAddress

View File

@ -0,0 +1,141 @@
/**@file
Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.<BR>
Portions copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>
Portions copyright (c) 2011 - 2012, ARM Ltd. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include <PiDxe.h>
#include <Library/UefiImageLib.h>
#include <Library/BaseLib.h>
#include <Library/DebugLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/UefiImageExtraActionLib.h>
#include <Library/PrintLib.h>
/**
If the build is done on cygwin the paths are cygpaths.
/cygdrive/c/tmp.txt vs c:\tmp.txt so we need to convert
them to work with RVD commands
@param Name Path to convert if needed
**/
CONST CHAR8 *
DeCygwinPathIfNeeded (
IN CONST CHAR8 *Name,
IN CHAR8 *Temp,
IN UINTN Size
)
{
CHAR8 *Ptr;
UINTN Index;
UINTN Index2;
Ptr = AsciiStrStr (Name, "/cygdrive/");
if (Ptr == NULL) {
return Name;
}
for (Index = 9, Index2 = 0; (Index < (Size + 9)) && (Ptr[Index] != '\0'); Index++, Index2++) {
Temp[Index2] = Ptr[Index];
if (Temp[Index2] == '/') {
Temp[Index2] = '\\';
}
if (Index2 == 1) {
Temp[Index2 - 1] = Ptr[Index];
Temp[Index2] = ':';
}
}
return Temp;
}
/**
Performs additional actions after a PE/COFF image has been loaded and relocated.
If ImageContext is NULL, then ASSERT().
@param ImageContext Pointer to the image context structure that describes the
PE/COFF image that has already been loaded and relocated.
**/
VOID
EFIAPI
UefiImageLoaderRelocateImageExtraAction (
IN CONST UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext
)
{
RETURN_STATUS Status;
CONST CHAR8 *PdbPath;
UINT32 PdbPathSize;
#if defined (__CC_ARM) || defined (__GNUC__)
CHAR8 Temp[512];
#endif
Status = UefiImageGetSymbolsPath (ImageContext, &PdbPath, &PdbPathSize);
if (!RETURN_ERROR (Status)) {
#ifdef __CC_ARM
#if (__ARMCC_VERSION < 500000)
// Print out the command for the RVD debugger to load symbols for this image
DEBUG ((DEBUG_LOAD | DEBUG_INFO, "load /a /ni /np %a &0x%p\n", DeCygwinPathIfNeeded (PdbPath, Temp, sizeof (Temp)), UefiImageLoaderGetImageAddress (ImageContext)));
#else
// Print out the command for the DS-5 to load symbols for this image
DEBUG ((DEBUG_LOAD | DEBUG_INFO, "add-symbol-file %a -o 0x%p\n", DeCygwinPathIfNeeded (PdbPath, Temp, sizeof (Temp)), UefiImageLoaderGetImageAddress (ImageContext)));
#endif
#elif __GNUC__
// This may not work correctly if you generate PE/COFF directly as then the Offset would not be required
DEBUG ((DEBUG_LOAD | DEBUG_INFO, "add-symbol-file %a -o 0x%p\n", DeCygwinPathIfNeeded (PdbPath, Temp, sizeof (Temp)), UefiImageLoaderGetImageAddress (ImageContext)));
#else
DEBUG ((DEBUG_LOAD | DEBUG_INFO, "Loading driver at 0x%11p EntryPoint=0x%11p\n", (VOID *)(UINTN)UefiImageLoaderGetImageAddress (ImageContext), FUNCTION_ENTRY_POINT (UefiImageLoaderGetImageEntryPoint (ImageContext))));
#endif
} else {
DEBUG ((DEBUG_LOAD | DEBUG_INFO, "Loading driver at 0x%11p EntryPoint=0x%11p\n", (VOID *)(UINTN)UefiImageLoaderGetImageAddress (ImageContext), FUNCTION_ENTRY_POINT (UefiImageLoaderGetImageEntryPoint (ImageContext))));
}
}
/**
Performs additional actions just before a PE/COFF image is unloaded. Any resources
that were allocated by UefiImageLoaderRelocateImageExtraAction() must be freed.
If ImageContext is NULL, then ASSERT().
@param ImageContext Pointer to the image context structure that describes the
PE/COFF image that is being unloaded.
**/
VOID
EFIAPI
UefiImageLoaderUnloadImageExtraAction (
IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext
)
{
RETURN_STATUS Status;
CONST CHAR8 *PdbPath;
UINT32 PdbPathSize;
#if defined (__CC_ARM) || defined (__GNUC__)
CHAR8 Temp[512];
#endif
Status = UefiImageGetSymbolsPath (ImageContext, &PdbPath, &PdbPathSize);
if (!RETURN_ERROR (Status)) {
#ifdef __CC_ARM
// Print out the command for the RVD debugger to load symbols for this image
DEBUG ((DEBUG_LOAD | DEBUG_INFO, "unload symbols_only %a\n", DeCygwinPathIfNeeded (PdbPath, Temp, sizeof (Temp))));
#elif __GNUC__
// This may not work correctly if you generate PE/COFF directly as then the Offset would not be required
DEBUG ((DEBUG_LOAD | DEBUG_INFO, "remove-symbol-file %a 0x%08x\n", DeCygwinPathIfNeeded (PdbPath, Temp, sizeof (Temp)), (UINTN)UefiImageLoaderGetImageAddress (ImageContext)));
#else
DEBUG ((DEBUG_LOAD | DEBUG_INFO, "Unloading %a\n", PdbPath));
#endif
} else {
DEBUG ((DEBUG_LOAD | DEBUG_INFO, "Unloading driver at 0x%11p\n", (VOID *)(UINTN)UefiImageLoaderGetImageAddress (ImageContext)));
}
}

View File

@ -0,0 +1,33 @@
#/** @file
# UEFI Image extra action library for DXE phase that run Unix emulator.
#
# Lib to provide memory journal status code reporting Routines
# Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.<BR>
# Portions copyright (c) 2010, Apple Inc. All rights reserved.<BR>
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
#
#**/
[Defines]
INF_VERSION = 0x00010005
BASE_NAME = DebugUnixUefiImageExtraActionLib
FILE_GUID = C3E9448E-1726-42fb-9368-41F75B038C0C
MODULE_TYPE = BASE
VERSION_STRING = 1.0
LIBRARY_CLASS = UefiImageExtraActionLib
#
# The following information is for reference only and not required by the build tools.
#
# VALID_ARCHITECTURES = ARM
#
[Sources.common]
DebugUefiImageExtraActionLib.c
[Packages]
MdePkg/MdePkg.dec
[LibraryClasses]
DebugLib

View File

@ -12,7 +12,6 @@
#include <Library/UefiLib.h>
#include <Library/BaseLib.h>
#include <Library/DebugLib.h>
#include <Library/PeCoffGetEntryPointLib.h>
#include <Library/PrintLib.h>
#include <Library/ArmDisassemblerLib.h>
#include <Library/SerialPortLib.h>
@ -37,11 +36,10 @@ STATIC CHAR8 *gExceptionTypeString[] = {
STATIC BOOLEAN mRecursiveException;
CHAR8 *
CONST CHAR8 *
GetImageName (
IN UINTN FaultAddress,
OUT UINTN *ImageBase,
OUT UINTN *PeCoffSizeOfHeaders
OUT UINTN *ImageBase
);
STATIC
@ -212,14 +210,13 @@ DefaultExceptionHandler (
UnicodeSPrintAsciiFormat (UnicodeBuffer, MAX_PRINT_CHARS, Buffer);
DEBUG_CODE_BEGIN ();
CHAR8 *Pdb, *PrevPdb;
UINTN ImageBase;
UINTN PeCoffSizeOfHeader;
UINT64 *Fp;
UINT64 RootFp[2];
UINTN Idx;
CONST CHAR8 *Pdb, *PrevPdb;
UINTN ImageBase;
UINT64 *Fp;
UINT64 RootFp[2];
UINTN Idx;
PrevPdb = Pdb = GetImageName (SystemContext.SystemContextAArch64->ELR, &ImageBase, &PeCoffSizeOfHeader);
PrevPdb = Pdb = GetImageName (SystemContext.SystemContextAArch64->ELR, &ImageBase);
if (Pdb != NULL) {
DEBUG ((
DEBUG_ERROR,
@ -244,7 +241,7 @@ DefaultExceptionHandler (
}
for (Fp = RootFp; Fp[0] != 0; Fp = (UINT64 *)Fp[0]) {
Pdb = GetImageName (Fp[1], &ImageBase, &PeCoffSizeOfHeader);
Pdb = GetImageName (Fp[1], &ImageBase);
if (Pdb != NULL) {
if (Pdb != PrevPdb) {
Idx++;
@ -265,14 +262,14 @@ DefaultExceptionHandler (
}
}
PrevPdb = Pdb = GetImageName (SystemContext.SystemContextAArch64->ELR, &ImageBase, &PeCoffSizeOfHeader);
PrevPdb = Pdb = GetImageName (SystemContext.SystemContextAArch64->ELR, &ImageBase);
if (Pdb != NULL) {
DEBUG ((DEBUG_ERROR, "\n[ 0] %a\n", Pdb));
}
Idx = 0;
for (Fp = RootFp; Fp[0] != 0; Fp = (UINT64 *)Fp[0]) {
Pdb = GetImageName (Fp[1], &ImageBase, &PeCoffSizeOfHeader);
Pdb = GetImageName (Fp[1], &ImageBase);
if ((Pdb != NULL) && (Pdb != PrevPdb)) {
DEBUG ((DEBUG_ERROR, "[% 2d] %a\n", ++Idx, Pdb));
PrevPdb = Pdb;

View File

@ -11,7 +11,6 @@
#include <Uefi.h>
#include <Library/BaseLib.h>
#include <Library/DebugLib.h>
#include <Library/PeCoffGetEntryPointLib.h>
#include <Library/PrintLib.h>
#include <Library/ArmDisassemblerLib.h>
#include <Library/SerialPortLib.h>
@ -54,11 +53,10 @@ STATIC CONST CPSR_CHAR mCpsrChar[] = {
{ 0, '?' }
};
CHAR8 *
CONST CHAR8 *
GetImageName (
IN UINTN FaultAddress,
OUT UINTN *ImageBase,
OUT UINTN *PeCoffSizeOfHeaders
OUT UINTN *ImageBase
);
/**
@ -229,20 +227,19 @@ DefaultExceptionHandler (
UnicodeSPrintAsciiFormat (UnicodeBuffer, MAX_PRINT_CHARS, Buffer);
DEBUG_CODE_BEGIN ();
CHAR8 *Pdb;
UINT32 ImageBase;
UINT32 PeCoffSizeOfHeader;
UINT32 Offset;
CHAR8 CpsrStr[CPSR_STRING_SIZE]; // char per bit. Lower 5-bits are mode
// that is a 3 char string
CHAR8 Buffer[80];
UINT8 *DisAsm;
UINT32 ItBlock;
CONST CHAR8 *Pdb;
UINT32 ImageBase;
UINT32 Offset;
CHAR8 CpsrStr[CPSR_STRING_SIZE]; // char per bit. Lower 5-bits are mode
// that is a 3 char string
CHAR8 Buffer[80];
UINT8 *DisAsm;
UINT32 ItBlock;
CpsrString (SystemContext.SystemContextArm->CPSR, CpsrStr);
DEBUG ((DEBUG_ERROR, "%a\n", CpsrStr));
Pdb = GetImageName (SystemContext.SystemContextArm->PC, &ImageBase, &PeCoffSizeOfHeader);
Pdb = GetImageName (SystemContext.SystemContextArm->PC, &ImageBase);
Offset = SystemContext.SystemContextArm->PC - ImageBase;
if (Pdb != NULL) {
DEBUG ((DEBUG_ERROR, "%a\n", Pdb));
@ -255,7 +252,9 @@ DefaultExceptionHandler (
// you need to subtract out the size of the PE/COFF header to get
// get the offset that matches the link map.
//
DEBUG ((DEBUG_ERROR, "loaded at 0x%08x (PE/COFF offset) 0x%x (ELF or Mach-O offset) 0x%x", ImageBase, Offset, Offset - PeCoffSizeOfHeader));
// FIXME: Used to have (ELF or Mach-O offset) 0x%x
// Substitute with .text address (better + may be needed for GDB symbols?)
DEBUG ((EFI_D_ERROR, "loaded at 0x%08x (PE/COFF offset) 0x%x", ImageBase, Offset));
// If we come from an image it is safe to show the instruction. We know it should not fault
DisAsm = (UINT8 *)(UINTN)SystemContext.SystemContextArm->PC;

View File

@ -34,7 +34,6 @@
BaseLib
PrintLib
DebugLib
PeCoffGetEntryPointLib
ArmDisassemblerLib
SerialPortLib
UefiBootServicesTableLib

View File

@ -7,7 +7,6 @@
**/
#include <Uefi.h>
#include <Library/PeCoffGetEntryPointLib.h>
#include <Library/UefiLib.h>
#include <Guid/DebugImageInfoTable.h>
@ -20,17 +19,15 @@
@param FaultAddress Address to find PE/COFF image for.
@param ImageBase Return load address of found image
@param PeCoffSizeOfHeaders Return the size of the PE/COFF header for the image that was found
@retval NULL FaultAddress not in a loaded PE/COFF image.
@retval Path and file name of PE/COFF image.
**/
CHAR8 *
CONST CHAR8 *
GetImageName (
IN UINTN FaultAddress,
OUT UINTN *ImageBase,
OUT UINTN *PeCoffSizeOfHeaders
OUT UINTN *ImageBase
)
{
EFI_STATUS Status;
@ -59,8 +56,7 @@ GetImageName (
(Address <= ((CHAR8 *)DebugTable->NormalImage->LoadedImageProtocolInstance->ImageBase + DebugTable->NormalImage->LoadedImageProtocolInstance->ImageSize)))
{
*ImageBase = (UINTN)DebugTable->NormalImage->LoadedImageProtocolInstance->ImageBase;
*PeCoffSizeOfHeaders = PeCoffGetSizeOfHeaders ((VOID *)(UINTN)*ImageBase);
return PeCoffLoaderGetPdbPointer (DebugTable->NormalImage->LoadedImageProtocolInstance->ImageBase);
return DebugTable->NormalImage->PdbPath;
}
}
}

View File

@ -56,8 +56,9 @@
MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
MemoryInitPeiLib|ArmPlatformPkg/MemoryInitPei/MemoryInitPeiLib.inf
PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
PeCoffExtraActionLib|MdePkg/Library/BasePeCoffExtraActionLibNull/BasePeCoffExtraActionLibNull.inf
PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf
UefiImageExtraActionLib|MdePkg/Library/BaseUefiImageExtraActionLibNull/BaseUefiImageExtraActionLibNull.inf
PeCoffLib2|MdePkg/Library/BasePeCoffLib2/BasePeCoffLib2.inf
UefiImageLib|MdePkg/Library/BaseUefiImageLib/BaseUefiImageLibPeCoff.inf
PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.inf
PL011UartClockLib|ArmPlatformPkg/Library/PL011UartClockLib/PL011UartClockLib.inf
PL011UartLib|ArmPlatformPkg/Library/PL011UartLib/PL011UartLib.inf

View File

@ -20,6 +20,7 @@
#include <Library/HobLib.h>
#include <Library/SerialPortLib.h>
#include <Library/ArmPlatformLib.h>
#include <Library/UefiImageLib.h>
extern UINT64 mSystemMemoryEnd;

View File

@ -47,8 +47,8 @@
SynchronizationLib|MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf
PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.inf
PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf
PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf
PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf
PeCoffLib2|MdePkg/Library/BasePeCoffLib2/BasePeCoffLib2.inf
UefiImageLib|MdePkg/Library/BaseUefiImageLib/BaseUefiImageLibPeCoff.inf
IoLib|MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsicArmVirt.inf
UefiDecompressLib|MdePkg/Library/BaseUefiDecompressLib/BaseUefiDecompressLib.inf
CpuLib|MdePkg/Library/BaseCpuLib/BaseCpuLib.inf
@ -124,8 +124,8 @@
SerialPortLib|ArmVirtPkg/Library/FdtPL011SerialPortLib/FdtPL011SerialPortLib.inf
FdtSerialPortAddressLib|OvmfPkg/Library/FdtSerialPortAddressLib/FdtSerialPortAddressLib.inf
PeCoffExtraActionLib|ArmPkg/Library/DebugPeCoffExtraActionLib/DebugPeCoffExtraActionLib.inf
#PeCoffExtraActionLib|MdePkg/Library/BasePeCoffExtraActionLibNull/BasePeCoffExtraActionLibNull.inf
UefiImageExtraActionLib|ArmPkg/Library/DebugUefiImageExtraActionLib/DebugUefiImageExtraActionLib.inf
#UefiImageExtraActionLib|MdePkg/Library/BaseUefiImageExtraActionLibNull/BaseUefiImageExtraActionLibNull.inf
DebugAgentLib|MdeModulePkg/Library/DebugAgentLibNull/DebugAgentLibNull.inf
DebugAgentTimerLib|EmbeddedPkg/Library/DebugAgentTimerLibNull/DebugAgentTimerLibNull.inf
@ -205,7 +205,6 @@
PeiCoreEntryPoint|MdePkg/Library/PeiCoreEntryPoint/PeiCoreEntryPoint.inf
PerformanceLib|MdeModulePkg/Library/PeiPerformanceLib/PeiPerformanceLib.inf
OemHookStatusCodeLib|MdeModulePkg/Library/OemHookStatusCodeLibNull/OemHookStatusCodeLibNull.inf
PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf
ExtractGuidedSectionLib|MdePkg/Library/PeiExtractGuidedSectionLib/PeiExtractGuidedSectionLib.inf
PeiServicesTablePointerLib|ArmPkg/Library/PeiServicesTablePointerLib/PeiServicesTablePointerLib.inf
@ -223,7 +222,6 @@
PeimEntryPoint|MdePkg/Library/PeimEntryPoint/PeimEntryPoint.inf
PerformanceLib|MdeModulePkg/Library/PeiPerformanceLib/PeiPerformanceLib.inf
OemHookStatusCodeLib|MdeModulePkg/Library/OemHookStatusCodeLibNull/OemHookStatusCodeLibNull.inf
PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf
ExtractGuidedSectionLib|MdePkg/Library/PeiExtractGuidedSectionLib/PeiExtractGuidedSectionLib.inf
PeiServicesTablePointerLib|ArmPkg/Library/PeiServicesTablePointerLib/PeiServicesTablePointerLib.inf

View File

@ -142,9 +142,8 @@ ASM_PFX(DiscoverDramFromDt):
// window at the beginning of the FD image as a temp stack.
//
mov x0, x7
adr x1, PeCoffLoaderImageReadFromMemory
mov sp, x7
bl RelocatePeCoffImage
bl RelocateUefiImage
//
// Discover the memory size and offset from the DTB, and record in the

View File

@ -146,9 +146,8 @@ ASM_PFX(ArmPlatformPeiBootAction):
// window at the beginning of the FD image as a temp stack.
//
mov r0, r5
ADRL (r1, PeCoffLoaderImageReadFromMemory)
mov sp, r5
bl RelocatePeCoffImage
bl RelocateUefiImage
//
// Discover the memory size and offset from the DTB, and record in the

View File

@ -47,7 +47,7 @@
SerialPortLib
ExtractGuidedSectionLib
LzmaDecompressLib
PeCoffLib
UefiImageLib
PrePiLib
MemoryAllocationLib
HobLib

33
ArmVirtPkg/PrePi/PrePi.c Executable file → Normal file
View File

@ -9,7 +9,7 @@
#include <PiPei.h>
#include <Pi/PiBootMode.h>
#include <Library/PeCoffLib.h>
#include <Library/UefiImageLib.h>
#include <Library/PrePiLib.h>
#include <Library/PrintLib.h>
#include <Library/PrePiHobListPointerLib.h>
@ -131,15 +131,15 @@ CEntryPoint (
}
VOID
RelocatePeCoffImage (
IN EFI_PEI_FV_HANDLE FwVolHeader,
IN PE_COFF_LOADER_READ_FILE ImageRead
RelocateUefiImage (
IN EFI_PEI_FV_HANDLE FwVolHeader
)
{
EFI_PEI_FILE_HANDLE FileHandle;
VOID *SectionData;
PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;
EFI_STATUS Status;
EFI_PEI_FILE_HANDLE FileHandle;
VOID *SectionData;
UINT32 SectionSize;
UEFI_IMAGE_LOADER_IMAGE_CONTEXT ImageContext;
EFI_STATUS Status;
FileHandle = NULL;
Status = FfsFindNextFile (
@ -149,21 +149,16 @@ RelocatePeCoffImage (
);
ASSERT_EFI_ERROR (Status);
Status = FfsFindSectionData (EFI_SECTION_PE32, FileHandle, &SectionData);
Status = FfsFindSectionData (EFI_SECTION_PE32, FileHandle, &SectionData, &SectionSize);
if (EFI_ERROR (Status)) {
Status = FfsFindSectionData (EFI_SECTION_TE, FileHandle, &SectionData);
Status = FfsFindSectionData (EFI_SECTION_TE, FileHandle, &SectionData, &SectionSize);
}
ASSERT_EFI_ERROR (Status);
ZeroMem (&ImageContext, sizeof ImageContext);
Status = UefiImageInitializeContext (&ImageContext, SectionData, SectionSize);
ASSERT_RETURN_ERROR (Status);
ImageContext.Handle = (EFI_HANDLE)SectionData;
ImageContext.ImageRead = ImageRead;
PeCoffLoaderGetImageInfo (&ImageContext);
if (ImageContext.ImageAddress != (UINTN)SectionData) {
ImageContext.ImageAddress = (UINTN)SectionData;
PeCoffLoaderRelocateImage (&ImageContext);
}
Status = UefiImageRelocateImageInplaceForExecution (&ImageContext);
ASSERT_RETURN_ERROR (Status);
}

View File

@ -45,6 +45,10 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
(((Imm32) >> 2) & 0x7fffff))
#define ARM_JUMP_TO_THUMB(Offset) _ARM_JUMP_TO_THUMB((Offset) - 8)
#define ALIGN_VALUE_ADDEND(Value, Alignment) (((Alignment) - (Value)) & ((Alignment) - 1U))
#define ALIGN_VALUE(Value, Alignment) ((Value) + ALIGN_VALUE_ADDEND (Value, Alignment))
#define IS_ALIGNED(Value, Alignment) (((Value) & ((Alignment) - 1U)) == 0U)
/*
* Arm instruction to return from exception (MOVS PC, LR)
*/
@ -1299,11 +1303,17 @@ Returns:
// Rebase the PE or TE image in FileBuffer of FFS file for XIP
// Rebase for the debug genfvmap tool
//
Status = FfsRebase (FvInfo, FvInfo->FvFiles[Index], (EFI_FFS_FILE_HEADER *) FileBuffer, (UINTN) *VtfFileImage - (UINTN) FvImage->FileImage, FvMapFile);
Status = FfsRebase (FvInfo, FvInfo->FvFiles[Index], (EFI_FFS_FILE_HEADER **)&FileBuffer, &FileSize, (UINTN) *VtfFileImage - (UINTN) FvImage->FileImage, FvMapFile);
if (EFI_ERROR (Status)) {
Error (NULL, 0, 3000, "Invalid", "Could not rebase %s.", FvInfo->FvFiles[Index]);
return Status;
}
if (FileSize > (UINTN) ((UINTN) *VtfFileImage - (UINTN) FvImage->CurrentFilePointer)) {
free (FileBuffer);
Error (NULL, 0, 4002, "Resource", "FV space is full, not enough room to add file %s after ImageBase aligning.", FvInfo->FvFiles[Index]);
return EFI_OUT_OF_RESOURCES;
}
//
// copy VTF File
//
@ -1345,11 +1355,17 @@ Returns:
// Rebase the PE or TE image in FileBuffer of FFS file for XIP.
// Rebase Bs and Rt drivers for the debug genfvmap tool.
//
Status = FfsRebase (FvInfo, FvInfo->FvFiles[Index], (EFI_FFS_FILE_HEADER *) FileBuffer, (UINTN) FvImage->CurrentFilePointer - (UINTN) FvImage->FileImage, FvMapFile);
if (EFI_ERROR (Status)) {
Error (NULL, 0, 3000, "Invalid", "Could not rebase %s.", FvInfo->FvFiles[Index]);
return Status;
}
Status = FfsRebase (FvInfo, FvInfo->FvFiles[Index], (EFI_FFS_FILE_HEADER **)&FileBuffer, &FileSize, (UINTN) FvImage->CurrentFilePointer - (UINTN) FvImage->FileImage, FvMapFile);
if (EFI_ERROR (Status)) {
Error (NULL, 0, 3000, "Invalid", "Could not rebase %s.", FvInfo->FvFiles[Index]);
return Status;
}
if (FileSize > (UINTN) ((UINTN) *VtfFileImage - (UINTN) FvImage->CurrentFilePointer)) {
free (FileBuffer);
Error (NULL, 0, 4002, "Resource", "FV space is full, not enough room to add file %s after ImageBase aligning.", FvInfo->FvFiles[Index]);
return EFI_OUT_OF_RESOURCES;
}
//
// Copy the file
//
@ -3447,11 +3463,109 @@ Returns:
return EFI_SUCCESS;
}
EFI_PHYSICAL_ADDRESS
AddPadSection (
IN OUT EFI_PHYSICAL_ADDRESS *BaseAddress,
IN UINT32 Alignment,
IN OUT EFI_FFS_FILE_HEADER **FfsFile,
IN OUT UINTN *FileSize,
IN OUT EFI_FILE_SECTION_POINTER *Section
)
{
EFI_COMMON_SECTION_HEADER *NewSection;
UINT32 FfsHeaderLength;
UINT32 FfsFileLength;
UINT32 PadSize;
UINTN PadAddress;
UINT8 *FfsPart;
UINT32 PartSize;
UINT32 Offset;
EFI_FFS_INTEGRITY_CHECK *IntegrityCheck;
PadAddress = ALIGN_VALUE (*BaseAddress + sizeof (EFI_COMMON_SECTION_HEADER), Alignment);
PadSize = PadAddress - *BaseAddress;
Offset = (UINT32)((UINTN)((*Section).Pe32Section) - (UINTN)(*FfsFile));
PartSize = GetFfsFileLength (*FfsFile) - Offset;
FfsPart = calloc (1, PartSize);
if (FfsPart == NULL) {
fprintf (stderr, "GenFv: Could not allocate memory for FfsPart\n");
return EFI_OUT_OF_RESOURCES;
}
CopyMem (FfsPart, (UINT8 *)(UINTN)((*Section).Pe32Section), PartSize);
FfsFileLength = GetFfsFileLength (*FfsFile) + PadSize;
*FfsFile = realloc (*FfsFile, FfsFileLength);
if (*FfsFile == NULL) {
fprintf (stderr, "GenFv: Could not reallocate memory for FfsFile\n");
free (FfsPart);
return EFI_OUT_OF_RESOURCES;
}
*FileSize += PadSize;
NewSection = (EFI_COMMON_SECTION_HEADER *)((UINTN)(*FfsFile) + Offset);
NewSection->Size[0] = (UINT8)(PadSize & 0xff);
NewSection->Size[1] = (UINT8)((PadSize & 0xff00) >> 8);
NewSection->Size[2] = (UINT8)((PadSize & 0xff0000) >> 16);
NewSection->Type = EFI_SECTION_RAW;
++NewSection;
ZeroMem ((VOID *)NewSection, PadSize - sizeof (EFI_COMMON_SECTION_HEADER));
*Section = (EFI_FILE_SECTION_POINTER)(EFI_PE32_SECTION *)((UINT8 *)NewSection + PadSize - sizeof (EFI_COMMON_SECTION_HEADER));
CopyMem (
(UINT8 *)((*Section).Pe32Section),
FfsPart,
PartSize
);
FfsHeaderLength = GetFfsHeaderLength(*FfsFile);
if (FfsHeaderLength > sizeof(EFI_FFS_FILE_HEADER)) {
((EFI_FFS_FILE_HEADER2 *)(*FfsFile))->ExtendedSize = FfsFileLength;
} else {
(*FfsFile)->Size[0] = (UINT8)(FfsFileLength & 0x000000FF);
(*FfsFile)->Size[1] = (UINT8)((FfsFileLength & 0x0000FF00) >> 8);
(*FfsFile)->Size[2] = (UINT8)((FfsFileLength & 0x00FF0000) >> 16);
}
//
// Recalculate the FFS header checksum. Instead of setting Header and State
// both to zero, set Header to (UINT8)(-State) so State preserves its original
// value
//
IntegrityCheck = &(*FfsFile)->IntegrityCheck;
IntegrityCheck->Checksum.Header = (UINT8) (0x100 - (*FfsFile)->State);
IntegrityCheck->Checksum.File = 0;
IntegrityCheck->Checksum.Header = CalculateChecksum8 (
(UINT8 *)(*FfsFile), FfsHeaderLength);
if ((*FfsFile)->Attributes & FFS_ATTRIB_CHECKSUM) {
//
// Ffs header checksum = zero, so only need to calculate ffs body.
//
IntegrityCheck->Checksum.File = CalculateChecksum8 (
(UINT8 *)(*FfsFile) + FfsHeaderLength,
FfsFileLength - FfsHeaderLength);
} else {
IntegrityCheck->Checksum.File = FFS_FIXED_CHECKSUM;
}
*BaseAddress = PadAddress;
free (FfsPart);
return EFI_SUCCESS;
}
EFI_STATUS
FfsRebase (
IN OUT FV_INFO *FvInfo,
IN CHAR8 *FileName,
IN OUT EFI_FFS_FILE_HEADER *FfsFile,
IN OUT EFI_FFS_FILE_HEADER **FfsFile,
IN OUT UINTN *FileSize,
IN UINTN XipOffset,
IN FILE *FvMapFile
)
@ -3524,13 +3638,12 @@ Returns:
return EFI_SUCCESS;
}
XipBase = FvInfo->BaseAddress + XipOffset;
//
// We only process files potentially containing PE32 sections.
//
switch (FfsFile->Type) {
switch ((*FfsFile)->Type) {
case EFI_FV_FILETYPE_SECURITY_CORE:
case EFI_FV_FILETYPE_PEI_CORE:
case EFI_FV_FILETYPE_PEIM:
@ -3542,7 +3655,7 @@ Returns:
//
// Rebase the inside FvImage.
//
GetChildFvFromFfs (FvInfo, FfsFile, XipOffset);
GetChildFvFromFfs (FvInfo, *FfsFile, XipOffset);
//
// Search PE/TE section in FV sectin.
@ -3552,7 +3665,7 @@ Returns:
return EFI_SUCCESS;
}
FfsHeaderSize = GetFfsHeaderLength(FfsFile);
FfsHeaderSize = GetFfsHeaderLength(*FfsFile);
//
// Rebase each PE32 section
//
@ -3566,7 +3679,7 @@ Returns:
//
// Find Pe Image
//
Status = GetSectionByType (FfsFile, EFI_SECTION_PE32, Index, &CurrentPe32Section);
Status = GetSectionByType (*FfsFile, EFI_SECTION_PE32, Index, &CurrentPe32Section);
if (EFI_ERROR (Status)) {
break;
}
@ -3615,7 +3728,7 @@ Returns:
//
// Calculate the PE32 base address, based on file type
//
switch (FfsFile->Type) {
switch ((*FfsFile)->Type) {
case EFI_FV_FILETYPE_SECURITY_CORE:
case EFI_FV_FILETYPE_PEI_CORE:
case EFI_FV_FILETYPE_PEIM:
@ -3693,7 +3806,7 @@ Returns:
ImageContext.RelocationsStripped = FALSE;
}
NewPe32BaseAddress = XipBase + (UINTN) CurrentPe32Section.Pe32Section + CurSecHdrSize - (UINTN)FfsFile;
NewPe32BaseAddress = XipBase + (UINTN) CurrentPe32Section.Pe32Section + CurSecHdrSize - (UINTN)(*FfsFile);
break;
case EFI_FV_FILETYPE_DRIVER:
@ -3708,7 +3821,7 @@ Returns:
Error (NULL, 0, 3000, "Invalid", "PE image Section-Alignment and File-Alignment do not match : %s.", FileName);
return EFI_ABORTED;
}
NewPe32BaseAddress = XipBase + (UINTN) CurrentPe32Section.Pe32Section + CurSecHdrSize - (UINTN)FfsFile;
NewPe32BaseAddress = XipBase + (UINTN) CurrentPe32Section.Pe32Section + CurSecHdrSize - (UINTN)(*FfsFile);
break;
default:
@ -3732,15 +3845,28 @@ Returns:
//
// Load and Relocate Image Data
//
MemoryImagePointer = (UINT8 *) malloc ((UINTN) ImageContext.ImageSize + ImageContext.SectionAlignment);
MemoryImagePointer = (UINT8 *) calloc (1, (UINTN)ImageContext.ImageSize + ImageContext.SectionAlignment);
if (MemoryImagePointer == NULL) {
Error (NULL, 0, 4001, "Resource", "memory cannot be allocated on rebase of %s", FileName);
return EFI_OUT_OF_RESOURCES;
}
memset ((VOID *) MemoryImagePointer, 0, (UINTN) ImageContext.ImageSize + ImageContext.SectionAlignment);
ImageContext.ImageAddress = ((UINTN) MemoryImagePointer + ImageContext.SectionAlignment - 1) & (~((UINTN) ImageContext.SectionAlignment - 1));
ImageContext.ImageAddress = ALIGN_VALUE ((UINTN)MemoryImagePointer, ImageContext.SectionAlignment);
Status = PeCoffLoaderLoadImage (&ImageContext);
if (!(IS_ALIGNED (NewPe32BaseAddress, ImageContext.SectionAlignment))) {
Status = AddPadSection (&NewPe32BaseAddress, ImageContext.SectionAlignment, FfsFile, FileSize, &CurrentPe32Section);
if (EFI_ERROR (Status)) {
free ((VOID *) MemoryImagePointer);
return Status;
}
CurSecHdrSize = GetSectionHeaderLength (CurrentPe32Section.CommonHeader);
ImageContext.Handle = (VOID *) ((UINTN) CurrentPe32Section.Pe32Section + CurSecHdrSize);
PdbPointer = PeCoffLoaderGetPdbPointer (ImageContext.Handle);
ImgHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)((UINTN) CurrentPe32Section.Pe32Section + CurSecHdrSize + ImageContext.PeCoffHeaderOffset);
}
Status = PeCoffLoaderLoadImage (&ImageContext);
if (EFI_ERROR (Status)) {
Error (NULL, 0, 3000, "Invalid", "LocateImage() call failed on rebase of %s", FileName);
free ((VOID *) MemoryImagePointer);
@ -3748,7 +3874,8 @@ Returns:
}
ImageContext.DestinationAddress = NewPe32BaseAddress;
Status = PeCoffLoaderRelocateImage (&ImageContext);
Status = PeCoffLoaderRelocateImage (&ImageContext);
if (EFI_ERROR (Status)) {
Error (NULL, 0, 3000, "Invalid", "RelocateImage() call failed on rebase of %s Status=%d", FileName, Status);
free ((VOID *) MemoryImagePointer);
@ -3798,15 +3925,15 @@ Returns:
//
// Now update file checksum
//
if (FfsFile->Attributes & FFS_ATTRIB_CHECKSUM) {
SavedState = FfsFile->State;
FfsFile->IntegrityCheck.Checksum.File = 0;
FfsFile->State = 0;
FfsFile->IntegrityCheck.Checksum.File = CalculateChecksum8 (
(UINT8 *) ((UINT8 *)FfsFile + FfsHeaderSize),
GetFfsFileLength (FfsFile) - FfsHeaderSize
if ((*FfsFile)->Attributes & FFS_ATTRIB_CHECKSUM) {
SavedState = (*FfsFile)->State;
(*FfsFile)->IntegrityCheck.Checksum.File = 0;
(*FfsFile)->State = 0;
(*FfsFile)->IntegrityCheck.Checksum.File = CalculateChecksum8 (
(UINT8 *) ((UINT8 *)(*FfsFile) + FfsHeaderSize),
GetFfsFileLength (*FfsFile) - FfsHeaderSize
);
FfsFile->State = SavedState;
(*FfsFile)->State = SavedState;
}
//
@ -3820,14 +3947,14 @@ Returns:
PdbPointer = FileName;
}
WriteMapFile (FvMapFile, PdbPointer, FfsFile, NewPe32BaseAddress, &OrigImageContext);
WriteMapFile (FvMapFile, PdbPointer, *FfsFile, NewPe32BaseAddress, &OrigImageContext);
}
if (FfsFile->Type != EFI_FV_FILETYPE_SECURITY_CORE &&
FfsFile->Type != EFI_FV_FILETYPE_PEI_CORE &&
FfsFile->Type != EFI_FV_FILETYPE_PEIM &&
FfsFile->Type != EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER &&
FfsFile->Type != EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE
if ((*FfsFile)->Type != EFI_FV_FILETYPE_SECURITY_CORE &&
(*FfsFile)->Type != EFI_FV_FILETYPE_PEI_CORE &&
(*FfsFile)->Type != EFI_FV_FILETYPE_PEIM &&
(*FfsFile)->Type != EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER &&
(*FfsFile)->Type != EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE
) {
//
// Only Peim code may have a TE section
@ -3844,7 +3971,7 @@ Returns:
//
// Find Te Image
//
Status = GetSectionByType (FfsFile, EFI_SECTION_TE, Index, &CurrentPe32Section);
Status = GetSectionByType (*FfsFile, EFI_SECTION_TE, Index, &CurrentPe32Section);
if (EFI_ERROR (Status)) {
break;
}
@ -3892,7 +4019,7 @@ Returns:
// Set new rebased address.
//
NewPe32BaseAddress = XipBase + (UINTN) TEImageHeader + sizeof (EFI_TE_IMAGE_HEADER) \
- TEImageHeader->StrippedSize - (UINTN) FfsFile;
- TEImageHeader->StrippedSize - (UINTN) (*FfsFile);
//
// if reloc is stripped, try to get the original efi image to get reloc info.
@ -4035,15 +4162,15 @@ Returns:
//
// Now update file checksum
//
if (FfsFile->Attributes & FFS_ATTRIB_CHECKSUM) {
SavedState = FfsFile->State;
FfsFile->IntegrityCheck.Checksum.File = 0;
FfsFile->State = 0;
FfsFile->IntegrityCheck.Checksum.File = CalculateChecksum8 (
(UINT8 *)((UINT8 *)FfsFile + FfsHeaderSize),
GetFfsFileLength (FfsFile) - FfsHeaderSize
if ((*FfsFile)->Attributes & FFS_ATTRIB_CHECKSUM) {
SavedState = (*FfsFile)->State;
(*FfsFile)->IntegrityCheck.Checksum.File = 0;
(*FfsFile)->State = 0;
(*FfsFile)->IntegrityCheck.Checksum.File = CalculateChecksum8 (
(UINT8 *)((UINT8 *)(*FfsFile) + FfsHeaderSize),
GetFfsFileLength (*FfsFile) - FfsHeaderSize
);
FfsFile->State = SavedState;
(*FfsFile)->State = SavedState;
}
//
// Get this module function address from ModulePeMapFile and add them into FvMap file
@ -4059,7 +4186,7 @@ Returns:
WriteMapFile (
FvMapFile,
PdbPointer,
FfsFile,
*FfsFile,
NewPe32BaseAddress,
&OrigImageContext
);

View File

@ -331,7 +331,8 @@ EFI_STATUS
FfsRebase (
IN OUT FV_INFO *FvInfo,
IN CHAR8 *FileName,
IN OUT EFI_FFS_FILE_HEADER *FfsFile,
IN OUT EFI_FFS_FILE_HEADER **FfsFile,
IN OUT UINTN *FileSize,
IN UINTN XipOffset,
IN FILE *FvMapFile
);

View File

@ -70,6 +70,24 @@ gSupportedTarget = ['all', 'genc', 'genmake', 'modules', 'libraries', 'fds', 'cl
TemporaryTablePattern = re.compile(r'^_\d+_\d+_[a-fA-F0-9]+$')
TmpTableDict = {}
## Return the biggest multiple of alignment that is smaller than or equal to
# value.
#
# @param value The value to align down.
# @param alignment The boundary to align down to.
#
def AlignDown(value, alignment):
return value - (value % alignment)
## Return the smallest multiple of alignment that is bigger than or equal to
# value.
#
# @param value The value to align up.
# @param alignment The boundary to align up to.
#
def AlignUp(value, alignment):
return AlignDown(value + alignment - 1, alignment)
## Check environment PATH variable to make sure the specified tool is found
#
# If the tool is found in the PATH, then True is returned
@ -688,7 +706,7 @@ class PeImageInfo():
self.OutputDir = OutputDir
self.DebugDir = DebugDir
self.Image = ImageClass
self.Image.Size = (self.Image.Size // 0x1000 + 1) * 0x1000
self.Image.Size = AlignUp(self.Image.Size, 0x1000)
## The class implementing the EDK2 build process
#
@ -1502,12 +1520,15 @@ class Build():
## for SMM module in SMRAM, the SMRAM will be allocated from base to top.
if not ModeIsSmm:
BaseAddress = BaseAddress - ModuleInfo.Image.Size
BaseAddress = AlignDown(BaseAddress, ModuleInfo.Image.SectionAlignment)
#
# Update Image to new BaseAddress by GenFw tool
#
LaunchCommand(["GenFw", "--rebase", str(BaseAddress), "-r", ModuleOutputImage], ModuleInfo.OutputDir)
LaunchCommand(["GenFw", "--rebase", str(BaseAddress), "-r", ModuleDebugImage], ModuleInfo.DebugDir)
## for SMM module in SMRAM, the SMRAM will be allocated from base to top.
else:
BaseAddress = AlignUp(BaseAddress, ModuleInfo.Image.SectionAlignment)
#
# Set new address to the section header only for SMM driver.
#

View File

@ -79,7 +79,6 @@
gEmbeddedDeviceGuid = { 0xbf4b9d10, 0x13ec, 0x43dd, { 0x88, 0x80, 0xe9, 0xb, 0x71, 0x8f, 0x27, 0xde } }
gEmbeddedExternalDeviceProtocolGuid = { 0x735F8C64, 0xD696, 0x44D0, { 0xBD, 0xF2, 0x44, 0x7F, 0xD0, 0x5A, 0x54, 0x06 }}
gEmbeddedGpioProtocolGuid = { 0x17a0a3d7, 0xc0a5, 0x4635, { 0xbb, 0xd5, 0x07, 0x21, 0x87, 0xdf, 0xe2, 0xee }}
gPeCoffLoaderProtocolGuid = { 0xB323179B, 0x97FB, 0x477E, { 0xB0, 0xFE, 0xD8, 0x85, 0x91, 0xFA, 0x11, 0xAB } }
gEmbeddedMmcHostProtocolGuid = { 0x3e591c00, 0x9e4a, 0x11df, {0x92, 0x44, 0x00, 0x02, 0xA5, 0xD5, 0xC5, 0x1B }}
gAndroidFastbootTransportProtocolGuid = { 0x74bd9fe0, 0x8902, 0x11e3, {0xb9, 0xd3, 0xf7, 0x22, 0x38, 0xfc, 0x9a, 0x31}}
gAndroidFastbootPlatformProtocolGuid = { 0x524685a0, 0x89a0, 0x11e3, {0x9d, 0x4d, 0xbf, 0xa9, 0xf6, 0xa4, 0x03, 0x08}}

View File

@ -58,9 +58,9 @@
ReportStatusCodeLib|MdeModulePkg/Library/PeiDxeDebugLibReportStatusCode/PeiDxeDebugLibReportStatusCode.inf
PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf
PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf
PeCoffExtraActionLib|MdePkg/Library/BasePeCoffExtraActionLibNull/BasePeCoffExtraActionLibNull.inf
PeCoffLib2|MdePkg/Library/BasePeCoffLib2/BasePeCoffLib2.inf
UefiImageLib|MdePkg/Library/BaseUefiImageLib/BaseUefiImageLibPeCoff.inf
UefiImageExtraActionLib|MdePkg/Library/BaseUefiImageExtraActionLibNull/BaseUefiImageExtraActionLibNull.inf
CacheMaintenanceLib|MdePkg/Library/BaseCacheMaintenanceLib/BaseCacheMaintenanceLib.inf
PrePiLib|EmbeddedPkg/Library/PrePiLib/PrePiLib.inf

View File

@ -807,166 +807,6 @@ gXferObjectReadResponse (
return Count;
}
/**
Note: This should be a library function. In the Apple case you have to add
the size of the PE/COFF header into the starting address to make things work
right as there is no way to pad the Mach-O for the size of the PE/COFF header.
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.
@param DebugBase Address that the debugger would use as the base of the image
@return The PDB file name for the PE/COFF image specified by Pe32Data or NULL
if it cannot be retrieved. DebugBase is only valid if PDB file name is
valid.
**/
VOID *
EFIAPI
PeCoffLoaderGetDebuggerInfo (
IN VOID *Pe32Data,
OUT VOID **DebugBase
)
{
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;
UINTN SizeOfHeaders;
ASSERT (Pe32Data != NULL);
TEImageAdjust = 0;
DirectoryEntry = NULL;
DebugEntry = NULL;
NumberOfRvaAndSizes = 0;
SizeOfHeaders = 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);
}
SizeOfHeaders = sizeof (EFI_TE_IMAGE_HEADER) + (UINTN)Hdr.Te->BaseOfCode - (UINTN)Hdr.Te->StrippedSize;
// __APPLE__ check this math...
*DebugBase = ((CHAR8 *)Pe32Data) - TEImageAdjust;
} else if (Hdr.Pe32->Signature == EFI_IMAGE_NT_SIGNATURE) {
*DebugBase = Pe32Data;
//
// 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_IA64:
//
// Assume PE32+ image with X64 or IPF Machine field
//
Magic = EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC;
break;
default:
//
// For unknown Machine field, use Magic in optional Header
//
Magic = Hdr.Pe32->OptionalHeader.Magic;
}
if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
//
// Use PE32 offset get Debug Directory Entry
//
SizeOfHeaders = Hdr.Pe32->OptionalHeader.SizeOfHeaders;
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
//
SizeOfHeaders = Hdr.Pe32Plus->OptionalHeader.SizeOfHeaders;
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));
case CODEVIEW_SIGNATURE_MTOC:
*DebugBase = (VOID *)(UINTN)((UINTN)DebugBase - SizeOfHeaders);
return (VOID *)((CHAR8 *)CodeViewEntryPointer + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_MTOC_ENTRY));
default:
break;
}
}
}
}
(void)SizeOfHeaders;
return NULL;
}
/**
Process "qXfer:object:read:annex:offset,length" request.
@ -1007,7 +847,7 @@ QxferLibrary (
)
{
VOID *LoadAddress;
CHAR8 *Pdb;
CONST CHAR8 *Pdb;
UINTN Size;
if (Offset != gPacketqXferLibraryOffset) {
@ -1035,12 +875,8 @@ QxferLibrary (
for ( ; gEfiDebugImageTableEntry < gDebugImageTableHeader->TableSize; gEfiDebugImageTableEntry++, gDebugTable++) {
if (gDebugTable->NormalImage != NULL) {
if ((gDebugTable->NormalImage->ImageInfoType == EFI_DEBUG_IMAGE_INFO_TYPE_NORMAL) &&
(gDebugTable->NormalImage->LoadedImageProtocolInstance != NULL))
{
Pdb = PeCoffLoaderGetDebuggerInfo (
gDebugTable->NormalImage->LoadedImageProtocolInstance->ImageBase,
&LoadAddress
);
(gDebugTable->NormalImage->LoadedImageProtocolInstance != NULL)) {
Pdb = gDebugTable->NormalImage->PdbPath;
if (Pdb != NULL) {
Size = AsciiSPrint (
gXferLibraryBuffer,

View File

@ -26,7 +26,7 @@
#include <Protocol/LoadedImage.h>
#include <Protocol/LoadedImage.h>
#include <Guid/DebugImageInfoTable.h>
#include <IndustryStandard/PeImage.h>
#include <IndustryStandard/PeImage2.h>
extern CONST CHAR8 mHexToStr[];

View File

@ -71,6 +71,7 @@ EFI_STATUS
@param FileHeader A pointer to the file header that contains the set of sections to
be searched.
@param SectionData A pointer to the discovered section, if successful.
@param SectionSize A pointer to the size of the discovered section, if successful.
@retval EFI_SUCCESS The section was found.
@retval EFI_NOT_FOUND The section was not found.
@ -82,7 +83,8 @@ FfsFindSectionDataWithHook (
IN EFI_SECTION_TYPE SectionType,
IN FFS_CHECK_SECTION_HOOK SectionCheckHook,
IN EFI_PEI_FILE_HANDLE FileHandle,
OUT VOID **SectionData
OUT VOID **SectionData,
OUT UINT32 *SectionSize
);
/**
@ -92,6 +94,7 @@ FfsFindSectionDataWithHook (
@param FileHandle A pointer to the file header that contains the set of sections to
be searched.
@param SectionData A pointer to the discovered section, if successful.
@param SectionSize A pointer to the size of the discovered section, if successful.
@retval EFI_SUCCESS The section was found.
@retval EFI_NOT_FOUND The section was not found.
@ -102,7 +105,8 @@ EFIAPI
FfsFindSectionData (
IN EFI_SECTION_TYPE SectionType,
IN EFI_PEI_FILE_HANDLE FileHandle,
OUT VOID **SectionData
OUT VOID **SectionData,
OUT UINT32 *SectionSize
);
/**
@ -675,7 +679,7 @@ BuildExtractSectionHob (
VOID
EFIAPI
BuildPeCoffLoaderHob (
BuildUefiLoaderHob (
VOID
);
@ -760,10 +764,11 @@ AllocateAlignedPages (
EFI_STATUS
EFIAPI
LoadPeCoffImage (
IN VOID *PeCoffImage,
LoadUefiImage (
IN VOID *UefiImage,
IN UINT32 UefiImageSize,
OUT EFI_PHYSICAL_ADDRESS *ImageAddress,
OUT UINT64 *ImageSize,
OUT UINT32 *ImageSize,
OUT EFI_PHYSICAL_ADDRESS *EntryPoint
);

View File

@ -12,12 +12,11 @@
#include <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/DebugLib.h>
#include <Library/PeCoffLib.h>
#include <Library/UefiImageLib.h>
#include <Library/HobLib.h>
#include <Library/PcdLib.h>
#include <Library/PrePiHobListPointerLib.h>
#include <Protocol/PeCoffLoader.h>
#include <Guid/ExtractSection.h>
#include <Guid/MemoryTypeInformation.h>
#include <Guid/MemoryAllocationHob.h>
@ -825,27 +824,6 @@ BuildExtractSectionHob (
BuildGuidDataHob (Guid, &Data, sizeof (Data));
}
PE_COFF_LOADER_PROTOCOL gPeCoffProtocol = {
PeCoffLoaderGetImageInfo,
PeCoffLoaderLoadImage,
PeCoffLoaderRelocateImage,
PeCoffLoaderImageReadFromMemory,
PeCoffLoaderRelocateImageForRuntime,
PeCoffLoaderUnloadImage
};
VOID
EFIAPI
BuildPeCoffLoaderHob (
VOID
)
{
VOID *Ptr;
Ptr = &gPeCoffProtocol;
BuildGuidDataHob (&gPeCoffLoaderProtocolGuid, &Ptr, sizeof (VOID *));
}
// May want to put this into a library so you only need the PCD settings if you are using the feature?
VOID
BuildMemoryTypeInformationHob (

View File

@ -278,7 +278,8 @@ FfsProcessSection (
IN FFS_CHECK_SECTION_HOOK SectionCheckHook,
IN EFI_COMMON_SECTION_HEADER *Section,
IN UINTN SectionSize,
OUT VOID **OutputBuffer
OUT VOID **OutputBuffer,
OUT UINT32 *OutputSize
)
{
EFI_STATUS Status;
@ -298,6 +299,7 @@ FfsProcessSection (
Found = FALSE;
*OutputBuffer = NULL;
*OutputSize = 0;
ParsedLength = 0;
Status = EFI_NOT_FOUND;
while (ParsedLength < SectionSize) {
@ -313,10 +315,13 @@ FfsProcessSection (
}
if (Found) {
// FIXME: Use common API with size checks
if (IS_SECTION2 (Section)) {
*OutputBuffer = (VOID *)((UINT8 *)Section + sizeof (EFI_COMMON_SECTION_HEADER2));
*OutputSize = SECTION2_SIZE (Section) - sizeof (EFI_COMMON_SECTION_HEADER2);
} else {
*OutputBuffer = (VOID *)((UINT8 *)Section + sizeof (EFI_COMMON_SECTION_HEADER));
*OutputSize = SECTION_SIZE (Section) - sizeof (EFI_COMMON_SECTION_HEADER);
}
return EFI_SUCCESS;
@ -432,7 +437,8 @@ FfsProcessSection (
SectionCheckHook,
DstBuffer,
DstBufferSize,
OutputBuffer
OutputBuffer,
OutputSize
);
}
}
@ -466,6 +472,7 @@ CheckNextSection:
@param FileHandle A pointer to the file header that contains the set of sections to
be searched.
@param SectionData A pointer to the discovered section, if successful.
@param SectionSize A pointer to the size of the discovered section, if successful.
@retval EFI_SUCCESS The section was found.
@retval EFI_NOT_FOUND The section was not found.
@ -477,7 +484,8 @@ FfsFindSectionDataWithHook (
IN EFI_SECTION_TYPE SectionType,
IN FFS_CHECK_SECTION_HOOK SectionCheckHook,
IN EFI_PEI_FILE_HANDLE FileHandle,
OUT VOID **SectionData
OUT VOID **SectionData,
OUT UINT32 *SectionSize
)
{
EFI_FFS_FILE_HEADER *FfsFileHeader;
@ -500,7 +508,8 @@ FfsFindSectionDataWithHook (
SectionCheckHook,
Section,
FileSize,
SectionData
SectionData,
SectionSize
);
}
@ -511,6 +520,7 @@ FfsFindSectionDataWithHook (
@param FileHandle A pointer to the file header that contains the set of sections to
be searched.
@param SectionData A pointer to the discovered section, if successful.
@param SectionSize A pointer to the size of the discovered section, if successful.
@retval EFI_SUCCESS The section was found.
@retval EFI_NOT_FOUND The section was not found.
@ -521,10 +531,11 @@ EFIAPI
FfsFindSectionData (
IN EFI_SECTION_TYPE SectionType,
IN EFI_PEI_FILE_HANDLE FileHandle,
OUT VOID **SectionData
OUT VOID **SectionData,
OUT UINT32 *SectionSize
)
{
return FfsFindSectionDataWithHook (SectionType, NULL, FileHandle, SectionData);
return FfsFindSectionDataWithHook (SectionType, NULL, FileHandle, SectionData, SectionSize);
}
/**
@ -816,6 +827,7 @@ FfsProcessFvFile (
{
EFI_STATUS Status;
EFI_PEI_FV_HANDLE FvImageHandle;
UINT32 FvImageHandleSize;
EFI_FV_INFO FvImageInfo;
UINT32 FvAlignment;
VOID *FvBuffer;
@ -842,7 +854,13 @@ FfsProcessFvFile (
//
// Find FvImage in FvFile
//
Status = FfsFindSectionDataWithHook (EFI_SECTION_FIRMWARE_VOLUME_IMAGE, NULL, FvFileHandle, (VOID **)&FvImageHandle);
Status = FfsFindSectionDataWithHook (
EFI_SECTION_FIRMWARE_VOLUME_IMAGE,
NULL,
FvFileHandle,
(VOID **)&FvImageHandle,
&FvImageHandleSize
);
if (EFI_ERROR (Status)) {
return Status;
}

View File

@ -18,7 +18,7 @@
#include <Library/DebugLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/UefiDecompressLib.h>
#include <Library/PeCoffLib.h>
#include <Library/UefiImageLib.h>
#include <Library/CacheMaintenanceLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/TimerLib.h>

View File

@ -6,6 +6,7 @@
**/
#include "ProcessorBind.h"
#include <PrePi.h>
//
@ -56,54 +57,45 @@ AllocateCodePages (
EFI_STATUS
EFIAPI
LoadPeCoffImage (
IN VOID *PeCoffImage,
LoadUefiImage (
IN VOID *UefiImage,
IN UINT32 UefiImageSize,
OUT EFI_PHYSICAL_ADDRESS *ImageAddress,
OUT UINT64 *ImageSize,
OUT UINT32 *DestinationSize,
OUT EFI_PHYSICAL_ADDRESS *EntryPoint
)
{
RETURN_STATUS Status;
PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;
VOID *Buffer;
RETURN_STATUS Status;
UEFI_IMAGE_LOADER_IMAGE_CONTEXT ImageContext;
UINT32 ImageSize;
VOID *Buffer;
UINT32 BufferSize;
UINT32 BufferPages;
UINT32 BufferAlignment;
ZeroMem (&ImageContext, sizeof (ImageContext));
ImageContext.Handle = PeCoffImage;
ImageContext.ImageRead = PeCoffLoaderImageReadFromMemory;
Status = PeCoffLoaderGetImageInfo (&ImageContext);
Status = UefiImageInitializeContext (&ImageContext, UefiImage, UefiImageSize);
ASSERT_EFI_ERROR (Status);
ImageSize = UefiImageGetImageSize (&ImageContext);
BufferPages = EFI_SIZE_TO_PAGES (ImageSize);
BufferSize = EFI_PAGES_TO_SIZE (BufferPages);
BufferAlignment = UefiImageGetSegmentAlignment (&ImageContext);
//
// Allocate Memory for the image
//
Buffer = AllocateCodePages (EFI_SIZE_TO_PAGES ((UINT32)ImageContext.ImageSize));
Buffer = AllocateAlignedCodePages (BufferPages, BufferAlignment);
ASSERT (Buffer != 0);
ImageContext.ImageAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)Buffer;
//
// Load the image to our new buffer
// Load and relocate the image to our new buffer
//
Status = PeCoffLoaderLoadImage (&ImageContext);
Status = UefiImageLoadImageForExecution (&ImageContext, Buffer, BufferSize, NULL, 0);
ASSERT_EFI_ERROR (Status);
//
// Relocate the image in our new buffer
//
Status = PeCoffLoaderRelocateImage (&ImageContext);
ASSERT_EFI_ERROR (Status);
*ImageAddress = ImageContext.ImageAddress;
*ImageSize = ImageContext.ImageSize;
*EntryPoint = ImageContext.EntryPoint;
//
// Flush not needed for all architectures. We could have a processor specific
// function in this library that does the no-op if needed.
//
InvalidateInstructionCacheRange ((VOID *)(UINTN)*ImageAddress, (UINTN)*ImageSize);
*ImageAddress = (UINTN) Buffer;
*DestinationSize = BufferSize;
*EntryPoint = (UINTN) UefiImageLoaderGetImageEntryPoint (&ImageContext);
return Status;
}
@ -122,22 +114,23 @@ LoadDxeCoreFromFfsFile (
)
{
EFI_STATUS Status;
VOID *PeCoffImage;
VOID *UefiImage;
UINT32 UefiImageSize;
EFI_PHYSICAL_ADDRESS ImageAddress;
UINT64 ImageSize;
UINT32 DestinationSize;
EFI_PHYSICAL_ADDRESS EntryPoint;
VOID *BaseOfStack;
VOID *TopOfStack;
VOID *Hob;
EFI_FV_FILE_INFO FvFileInfo;
Status = FfsFindSectionDataWithHook (EFI_SECTION_PE32, NULL, FileHandle, &PeCoffImage);
Status = FfsFindSectionDataWithHook (EFI_SECTION_PE32, NULL, FileHandle, &UefiImage, &UefiImageSize);
if (EFI_ERROR (Status)) {
return Status;
}
Status = LoadPeCoffImage (PeCoffImage, &ImageAddress, &ImageSize, &EntryPoint);
// For NT32 Debug Status = SecWinNtPeiLoadFile (PeCoffImage, &ImageAddress, &ImageSize, &EntryPoint);
Status = LoadUefiImage (UefiImage, UefiImageSize, &ImageAddress, &DestinationSize, &EntryPoint);
// For NT32 Debug Status = SecWinNtPeiLoadFile (UefiImage, &ImageAddress, &ImageSize, &EntryPoint);
ASSERT_EFI_ERROR (Status);
//
@ -146,7 +139,7 @@ LoadDxeCoreFromFfsFile (
Status = FfsGetFileInfo (FileHandle, &FvFileInfo);
ASSERT_EFI_ERROR (Status);
BuildModuleHob (&FvFileInfo.FileName, (EFI_PHYSICAL_ADDRESS)(UINTN)ImageAddress, EFI_SIZE_TO_PAGES ((UINT32)ImageSize) * EFI_PAGE_SIZE, EntryPoint);
BuildModuleHob (&FvFileInfo.FileName, (EFI_PHYSICAL_ADDRESS)(UINTN)ImageAddress, DestinationSize, EntryPoint);
DEBUG ((DEBUG_INFO | DEBUG_LOAD, "Loading DxeCore at 0x%10p EntryPoint=0x%10p\n", (VOID *)(UINTN)ImageAddress, (VOID *)(UINTN)EntryPoint));

View File

@ -41,7 +41,7 @@
DebugLib
BaseMemoryLib
UefiDecompressLib
PeCoffLib
UefiImageLib
CacheMaintenanceLib
PrintLib
SerialPortLib
@ -53,9 +53,6 @@
[Guids]
gEfiMemoryTypeInformationGuid
[Protocols]
gPeCoffLoaderProtocolGuid
[FixedPcd.common]
gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiACPIReclaimMemory

View File

@ -62,8 +62,8 @@
SynchronizationLib|MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf
PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf
CacheMaintenanceLib|MdePkg/Library/BaseCacheMaintenanceLib/BaseCacheMaintenanceLib.inf
PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf
PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf
PeCoffLib2|MdePkg/Library/BasePeCoffLib2/BasePeCoffLib2.inf
UefiImageLib|MdePkg/Library/BaseUefiImageLib/BaseUefiImageLibPeCoff.inf
BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf
FrameBufferBltLib|MdeModulePkg/Library/FrameBufferBltLib/FrameBufferBltLib.inf
@ -145,8 +145,7 @@
[LibraryClasses.common.SEC]
PeiServicesLib|EmulatorPkg/Library/SecPeiServicesLib/SecPeiServicesLib.inf
PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
PeCoffGetEntryPointLib|EmulatorPkg/Library/PeiEmuPeCoffGetEntryPointLib/PeiEmuPeCoffGetEntryPointLib.inf
PeCoffExtraActionLib|EmulatorPkg/Library/PeiEmuPeCoffExtraActionLib/PeiEmuPeCoffExtraActionLib.inf
UefiImageExtraActionLib|EmulatorPkg/Library/PeiEmuUefiImageExtraActionLib/PeiEmuUefiImageExtraActionLib.inf
SerialPortLib|EmulatorPkg/Library/PeiEmuSerialPortLib/PeiEmuSerialPortLib.inf
PpiListLib|EmulatorPkg/Library/SecPpiListLib/SecPpiListLib.inf
DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
@ -154,13 +153,13 @@
[LibraryClasses.common.USER_DEFINED, LibraryClasses.common.BASE]
DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf
PeCoffExtraActionLib|MdePkg/Library/BasePeCoffExtraActionLibNull/BasePeCoffExtraActionLibNull.inf
UefiImageExtraActionLib|MdePkg/Library/BaseUefiImageExtraActionLibNull/BaseUefiImageExtraActionLibNull.inf
HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf
MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf
PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
PpiListLib|EmulatorPkg/Library/SecPpiListLib/SecPpiListLib.inf
ThunkPpiList|EmulatorPkg/Library/ThunkPpiList/ThunkPpiList.inf
ThunkProtocolList|EmulatorPkg/Library/ThunkProtocolList/ThunkProtocolList.inf
PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf
PpiListLib|EmulatorPkg/Library/SecPpiListLib/SecPpiListLib.inf
PeiServicesLib|EmulatorPkg/Library/SecPeiServicesLib/SecPeiServicesLib.inf
@ -169,8 +168,7 @@
HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf
MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf
ReportStatusCodeLib|MdeModulePkg/Library/PeiReportStatusCodeLib/PeiReportStatusCodeLib.inf
PeCoffGetEntryPointLib|EmulatorPkg/Library/PeiEmuPeCoffGetEntryPointLib/PeiEmuPeCoffGetEntryPointLib.inf
PeCoffExtraActionLib|EmulatorPkg/Library/PeiEmuPeCoffExtraActionLib/PeiEmuPeCoffExtraActionLib.inf
UefiImageExtraActionLib|EmulatorPkg/Library/PeiEmuUefiImageExtraActionLib/PeiEmuUefiImageExtraActionLib.inf
ExtractGuidedSectionLib|MdePkg/Library/PeiExtractGuidedSectionLib/PeiExtractGuidedSectionLib.inf
SerialPortLib|EmulatorPkg/Library/PeiEmuSerialPortLib/PeiEmuSerialPortLib.inf
ReportStatusCodeLib|MdeModulePkg/Library/PeiReportStatusCodeLib/PeiReportStatusCodeLib.inf
@ -186,7 +184,7 @@
HobLib|MdePkg/Library/DxeCoreHobLib/DxeCoreHobLib.inf
MemoryAllocationLib|MdeModulePkg/Library/DxeCoreMemoryAllocationLib/DxeCoreMemoryAllocationLib.inf
ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf
PeCoffExtraActionLib|EmulatorPkg/Library/DxeEmuPeCoffExtraActionLib/DxeEmuPeCoffExtraActionLib.inf
UefiImageExtraActionLib|EmulatorPkg/Library/DxeEmuUefiImageExtraActionLib/DxeEmuUefiImageExtraActionLib.inf
ExtractGuidedSectionLib|MdePkg/Library/DxeExtractGuidedSectionLib/DxeExtractGuidedSectionLib.inf
PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
TimerLib|EmulatorPkg/Library/DxeCoreTimerLib/DxeCoreTimerLib.inf
@ -208,7 +206,7 @@
MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf
EmuThunkLib|EmulatorPkg/Library/DxeEmuLib/DxeEmuLib.inf
PeCoffExtraActionLib|EmulatorPkg/Library/DxeEmuPeCoffExtraActionLib/DxeEmuPeCoffExtraActionLib.inf
UefiImageExtraActionLib|EmulatorPkg/Library/DxeEmuUefiImageExtraActionLib/DxeEmuUefiImageExtraActionLib.inf
ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf
TimerLib|EmulatorPkg/Library/DxeTimerLib/DxeTimerLib.inf

View File

@ -23,7 +23,7 @@ typedef struct {
// Used by SecPeiServicesLib
EFI_PEI_PPI_DESCRIPTOR *PpiList;
// Needed by PEI PEI PeCoffLoaderExtraActionLib
// Needed by PEI PEI UefiImageLoaderExtraActionLib
EMU_THUNK_PROTOCOL *Thunk;
} EMU_MAGIC_PAGE_LAYOUT;

View File

@ -17,7 +17,7 @@
// neded for things like EFI_TIME_CAPABILITIES
#include <Uefi.h>
#include <Library/PeCoffExtraActionLib.h>
#include <Library/UefiImageExtraActionLib.h>
#include <Protocol/EmuIoThunk.h>
#include <Protocol/DevicePath.h>
@ -88,20 +88,21 @@ BOOLEAN
typedef
EFI_STATUS
(EFIAPI *EMU_PE_COFF_GET_ENTRY_POINT)(
IN VOID *Pe32Data,
IN OUT VOID **EntryPoint
IN VOID *Pe32Data,
IN UINT32 Pe32Size,
IN OUT VOID **EntryPoint
);
typedef
VOID
(EFIAPI *EMU_PE_COFF_RELOCATE_EXTRA_ACTION)(
IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext
IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext
);
typedef
VOID
(EFIAPI *EMU_PE_COFF_UNLOAD_EXTRA_ACTION)(
IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext
IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext
);
typedef
@ -217,9 +218,9 @@ struct _EMU_THUNK_PROTOCOL {
///
/// PE/COFF loader hooks to get symbols loaded
///
EMU_PE_COFF_GET_ENTRY_POINT PeCoffGetEntryPoint;
EMU_PE_COFF_RELOCATE_EXTRA_ACTION PeCoffRelocateImageExtraAction;
EMU_PE_COFF_UNLOAD_EXTRA_ACTION PeCoffUnloadImageExtraAction;
EMU_PE_COFF_GET_ENTRY_POINT UefiImageGetEntryPoint;
EMU_PE_COFF_RELOCATE_EXTRA_ACTION UefiImageRelocateImageExtraAction;
EMU_PE_COFF_UNLOAD_EXTRA_ACTION UefiImageUnloadImageExtraAction;
///
/// DXE Architecture Protocol Services

View File

@ -1,3 +1,5 @@
#ifndef DISABLE_NEW_DEPRECATED_INTERFACES
/** @file
Provides services to perform additional actions to relocate and unload
PE/Coff image for Emu environment specific purpose such as souce level debug.
@ -23,7 +25,8 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
//
// Cache of UnixThunk protocol
//
EMU_THUNK_PROTOCOL *mThunk = NULL;
EMU_THUNK_PROTOCOL *mThunk = NULL;
/**
The constructor function gets the pointer of the WinNT thunk functions
@ -39,7 +42,7 @@ DxeEmuPeCoffLibExtraActionConstructor (
IN EFI_SYSTEM_TABLE *SystemTable
)
{
EFI_HOB_GUID_TYPE *GuidHob;
EFI_HOB_GUID_TYPE *GuidHob;
//
// Retrieve EmuThunkProtocol from GUID'ed HOB
@ -72,6 +75,8 @@ PeCoffLoaderRelocateImageExtraAction (
}
}
/**
Performs additional actions just before a PE/COFF image is unloaded. Any resources
that were allocated by PeCoffLoaderRelocateImageExtraAction() must be freed.
@ -92,3 +97,5 @@ PeCoffLoaderUnloadImageExtraAction (
mThunk->PeCoffUnloadImageExtraAction (ImageContext);
}
}
#endif // DISABLE_NEW_DEPRECATED_INTERFACES

View File

@ -0,0 +1,94 @@
/** @file
Provides services to perform additional actions to relocate and unload
PE/Coff image for Emu environment specific purpose such as souce level debug.
This version only works for DXE phase
Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.<BR>
Portions copyright (c) 2008 - 2011, Apple Inc. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include <PiDxe.h>
#include <Protocol/EmuThunk.h>
#include <Library/UefiImageLib.h>
#include <Library/BaseLib.h>
#include <Library/DebugLib.h>
#include <Library/HobLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/UefiImageExtraActionLib.h>
//
// Cache of UnixThunk protocol
//
EMU_THUNK_PROTOCOL *mThunk = NULL;
/**
The constructor function gets the pointer of the WinNT thunk functions
It will ASSERT() if Unix thunk protocol is not installed.
@retval EFI_SUCCESS Unix thunk protocol is found and cached.
**/
EFI_STATUS
EFIAPI
DxeEmuUefiImageLibExtraActionConstructor (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
EFI_HOB_GUID_TYPE *GuidHob;
//
// Retrieve EmuThunkProtocol from GUID'ed HOB
//
GuidHob = GetFirstGuidHob (&gEmuThunkProtocolGuid);
ASSERT (GuidHob != NULL);
mThunk = (EMU_THUNK_PROTOCOL *)(*(UINTN *)(GET_GUID_HOB_DATA (GuidHob)));
ASSERT (mThunk != NULL);
return EFI_SUCCESS;
}
/**
Performs additional actions after a PE/COFF image has been loaded and relocated.
If ImageContext is NULL, then ASSERT().
@param ImageContext Pointer to the image context structure that describes the
PE/COFF image that has already been loaded and relocated.
**/
VOID
EFIAPI
UefiImageLoaderRelocateImageExtraAction (
IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext
)
{
if (mThunk != NULL) {
mThunk->UefiImageRelocateImageExtraAction (ImageContext);
}
}
/**
Performs additional actions just before a PE/COFF image is unloaded. Any resources
that were allocated by UefiImageLoaderRelocateImageExtraAction() must be freed.
If ImageContext is NULL, then ASSERT().
@param ImageContext Pointer to the image context structure that describes the
PE/COFF image that is being unloaded.
**/
VOID
EFIAPI
UefiImageLoaderUnloadImageExtraAction (
IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext
)
{
if (mThunk != NULL) {
mThunk->UefiImageUnloadImageExtraAction (ImageContext);
}
}

View File

@ -0,0 +1,42 @@
## @file
# PeCoff extra action libary for DXE phase that run Emu emulator.
#
# Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.<BR>
# Portions copyright (c) 2011, Apple Inc. All rights reserved.
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
#
##
[Defines]
INF_VERSION = 0x00010005
BASE_NAME = DxeEmuUefiImageExtraActionLib
FILE_GUID = 68FCD487-D230-6846-95B1-5E1F2EF942C4
MODULE_TYPE = DXE_DRIVER
VERSION_STRING = 1.0
LIBRARY_CLASS = UefiImageExtraActionLib|DXE_CORE DXE_DRIVER DXE_RUNTIME_DRIVER UEFI_DRIVER UEFI_APPLICATION
CONSTRUCTOR = DxeEmuUefiImageLibExtraActionConstructor
#
# The following information is for reference only and not required by the build tools.
#
# VALID_ARCHITECTURES = IA32
#
[Sources]
DxeEmuUefiImageExtraActionLib.c
[Packages]
MdePkg/MdePkg.dec
EmulatorPkg/EmulatorPkg.dec
[LibraryClasses]
DebugLib
HobLib
BaseMemoryLib
[Protocols]
gEmuThunkProtocolGuid # PROTOCOL ALWAYS_CONSUMED

View File

@ -1,3 +1,5 @@
#ifndef DISABLE_NEW_DEPRECATED_INTERFACES
/** @file
Provides services to perform additional actions to relocate and unload
PE/Coff image for Emu environment specific purpose such as souce level debug.
@ -22,7 +24,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
//
// Cache of UnixThunk protocol
//
EMU_THUNK_PROTOCOL *mThunk = NULL;
EMU_THUNK_PROTOCOL *mThunk = NULL;
/**
The function caches the pointer of the Unix thunk functions
@ -36,21 +38,22 @@ EFIAPI
EmuPeCoffGetThunkStucture (
)
{
EMU_THUNK_PPI *ThunkPpi;
EFI_STATUS Status;
EMU_THUNK_PPI *ThunkPpi;
EFI_STATUS Status;
//
// Locate Unix ThunkPpi for retrieving standard output handle
//
Status = PeiServicesLocatePpi (
&gEmuThunkPpiGuid,
0,
NULL,
(VOID **)&ThunkPpi
);
&gEmuThunkPpiGuid,
0,
NULL,
(VOID **) &ThunkPpi
);
ASSERT_EFI_ERROR (Status);
EMU_MAGIC_PAGE ()->Thunk = (EMU_THUNK_PROTOCOL *)ThunkPpi->Thunk ();
EMU_MAGIC_PAGE()->Thunk = (EMU_THUNK_PROTOCOL *) ThunkPpi->Thunk ();
return EFI_SUCCESS;
}
@ -70,12 +73,12 @@ PeCoffLoaderRelocateImageExtraAction (
IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext
)
{
if (EMU_MAGIC_PAGE ()->Thunk == NULL) {
if (EMU_MAGIC_PAGE()->Thunk == NULL) {
EmuPeCoffGetThunkStucture ();
}
EMU_MAGIC_PAGE()->Thunk->PeCoffRelocateImageExtraAction (ImageContext);
}
EMU_MAGIC_PAGE ()->Thunk->PeCoffRelocateImageExtraAction (ImageContext);
}
/**
Performs additional actions just before a PE/COFF image is unloaded. Any resources
@ -93,9 +96,10 @@ PeCoffLoaderUnloadImageExtraAction (
IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext
)
{
if (EMU_MAGIC_PAGE ()->Thunk == NULL) {
if (EMU_MAGIC_PAGE()->Thunk == NULL) {
EmuPeCoffGetThunkStucture ();
}
EMU_MAGIC_PAGE ()->Thunk->PeCoffUnloadImageExtraAction (ImageContext);
EMU_MAGIC_PAGE()->Thunk->PeCoffUnloadImageExtraAction (ImageContext);
}
#endif // DISABLE_NEW_DEPRECATED_INTERFACES

View File

@ -7,7 +7,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include "PiPei.h"
#include <Library/PeCoffGetEntryPointLib.h>
//#include <Library/PeCoffGetEntryPointLib.h>
#include <Library/PeiServicesLib.h>
#include <IndustryStandard/PeImage.h>
#include <Library/DebugLib.h>
@ -35,8 +35,9 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
RETURN_STATUS
EFIAPI
PeCoffLoaderGetEntryPoint (
IN VOID *Pe32Data,
IN OUT VOID **EntryPoint
IN VOID *Pe32Data,
IN UINT32 Pe32Size,
IN OUT VOID **EntryPoint
)
{
EMU_THUNK_PPI *ThunkPpi;
@ -56,7 +57,7 @@ PeCoffLoaderGetEntryPoint (
Thunk = (EMU_THUNK_PROTOCOL *)ThunkPpi->Thunk ();
return Thunk->PeCoffGetEntryPoint (Pe32Data, EntryPoint);
return Thunk->PeCoffGetEntryPoint (Pe32Data, Pe32Size, EntryPoint);
}
/**

View File

@ -0,0 +1,101 @@
/** @file
Provides services to perform additional actions to relocate and unload
PE/Coff image for Emu environment specific purpose such as souce level debug.
This version only works for PEI phase
Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.<BR>
Portions copyright (c) 2008 - 2011, Apple Inc. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include <PiPei.h>
#include <Ppi/EmuThunk.h>
#include <Protocol/EmuThunk.h>
#include <Library/UefiImageLib.h>
#include <Library/PeiServicesLib.h>
#include <Library/DebugLib.h>
#include <Library/BaseLib.h>
#include <Library/UefiImageExtraActionLib.h>
#include <Library/EmuMagicPageLib.h>
//
// Cache of UnixThunk protocol
//
EMU_THUNK_PROTOCOL *mThunk = NULL;
/**
The function caches the pointer of the Unix thunk functions
It will ASSERT() if Unix thunk ppi is not installed.
@retval EFI_SUCCESS WinNT thunk protocol is found and cached.
**/
EFI_STATUS
EFIAPI
EmuUefiImageGetThunkStucture (
)
{
EMU_THUNK_PPI *ThunkPpi;
EFI_STATUS Status;
//
// Locate Unix ThunkPpi for retrieving standard output handle
//
Status = PeiServicesLocatePpi (
&gEmuThunkPpiGuid,
0,
NULL,
(VOID **)&ThunkPpi
);
ASSERT_EFI_ERROR (Status);
EMU_MAGIC_PAGE ()->Thunk = (EMU_THUNK_PROTOCOL *)ThunkPpi->Thunk ();
return EFI_SUCCESS;
}
/**
Performs additional actions after a PE/COFF image has been loaded and relocated.
If ImageContext is NULL, then ASSERT().
@param ImageContext Pointer to the image context structure that describes the
PE/COFF image that has already been loaded and relocated.
**/
VOID
EFIAPI
UefiImageLoaderRelocateImageExtraAction (
IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext
)
{
if (EMU_MAGIC_PAGE ()->Thunk == NULL) {
EmuUefiImageGetThunkStucture ();
}
EMU_MAGIC_PAGE ()->Thunk->UefiImageRelocateImageExtraAction (ImageContext);
}
/**
Performs additional actions just before a PE/COFF image is unloaded. Any resources
that were allocated by UefiImageLoaderRelocateImageExtraAction() must be freed.
If ImageContext is NULL, then ASSERT().
@param ImageContext Pointer to the image context structure that describes the
PE/COFF image that is being unloaded.
**/
VOID
EFIAPI
UefiImageLoaderUnloadImageExtraAction (
IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext
)
{
if (EMU_MAGIC_PAGE ()->Thunk == NULL) {
EmuUefiImageGetThunkStucture ();
}
EMU_MAGIC_PAGE ()->Thunk->UefiImageUnloadImageExtraAction (ImageContext);
}

View File

@ -0,0 +1,43 @@
## @file
# PeCoff extra action libary for Pei phase that run Emu emulator.
#
# Lib to provide memory journal status code reporting Routines
# Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.<BR>
# Portions copyright (c) 2011, Apple Inc. All rights reserved.
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
#
##
[Defines]
INF_VERSION = 0x00010005
BASE_NAME = PeiEmuUefiImageExtraActionLib
FILE_GUID = 79C4E72A-730B-F040-8129-95877B3A97A8
MODULE_TYPE = PEIM
VERSION_STRING = 1.0
LIBRARY_CLASS = UefiImageExtraActionLib|PEI_CORE PEIM
#
# The following information is for reference only and not required by the build tools.
#
# VALID_ARCHITECTURES = IA32
#
[Sources]
PeiEmuUefiImageExtraActionLib.c
[Packages]
MdePkg/MdePkg.dec
EmulatorPkg/EmulatorPkg.dec
[LibraryClasses]
BaseLib
PeiServicesLib
DebugLib
[Ppis]
gEmuThunkPpiGuid # PPI ALWAYS_CONSUMED
[Pcd]
gEmulatorPkgTokenSpaceGuid.PcdPeiServicesTablePage

View File

@ -276,3 +276,52 @@ Returns:
return EFI_NOT_FOUND;
}
// FIXME: Docs
EFI_STATUS
SecFfsFindSectionData2 (
IN EFI_SECTION_TYPE SectionType,
IN EFI_FFS_FILE_HEADER *FfsFileHeader,
IN OUT VOID **SectionData,
OUT UINT32 *SectionDataSize
)
{
UINT32 FileSize;
EFI_COMMON_SECTION_HEADER *Section;
UINT32 SectionLength;
UINT32 ParsedLength;
//
// Size is 24 bits wide so mask upper 8 bits.
// Does not include FfsFileHeader header size
// FileSize is adjusted to FileOccupiedSize as it is 8 byte aligned.
//
Section = (EFI_COMMON_SECTION_HEADER *) (FfsFileHeader + 1);
FileSize = *(UINT32 *) (FfsFileHeader->Size) & 0x00FFFFFF;
FileSize -= sizeof (EFI_FFS_FILE_HEADER);
*SectionData = NULL;
ParsedLength = 0;
while (ParsedLength < FileSize) {
// FIXME: Common API with size checks
//
// Size is 24 bits wide so mask upper 8 bits.
//
SectionLength = *(UINT32 *) Section->Size & 0x00FFFFFF;
if (Section->Type == SectionType) {
*SectionData = (VOID *) (Section + 1);
*SectionDataSize = SectionLength - sizeof (*Section);
return EFI_SUCCESS;
}
//
// SectionLength is adjusted it is 4 byte aligned.
// Go to the next section
//
SectionLength = GET_OCCUPIED_SIZE (SectionLength, 4);
ParsedLength += SectionLength;
Section = (EFI_COMMON_SECTION_HEADER *) ((UINT8 *) Section + SectionLength);
}
return EFI_NOT_FOUND;
}

View File

@ -26,6 +26,14 @@ SecFfsFindSectionData (
OUT VOID **SectionData
);
EFI_STATUS
SecFfsFindSectionData2 (
IN EFI_SECTION_TYPE SectionType,
IN EFI_FFS_FILE_HEADER *FfsFileHeader,
IN OUT VOID **SectionData,
OUT UINT32 *SectionDataSize
);
/**
This service enables a given PEIM to register an interface into the PEI Foundation.
@ -304,6 +312,38 @@ PeiServicesFfsFindSectionData (
return SecFfsFindSectionData (SectionType, FileHandle, SectionData);
}
/**
This service enables PEIMs to discover sections of a given instance and type within a valid FFS file.
@param SectionType The value of the section type to find.
@param SectionInstance Section instance to find.
@param FileHandle A pointer to the file header that contains the set
of sections to be searched.
@param SectionData A pointer to the discovered section, if successful.
@param SectionDataSize The size of the discovered section, if successful.
@param AuthenticationStatus A pointer to the authentication status for this section.
@retval EFI_SUCCESS The section was found.
@retval EFI_NOT_FOUND The section was not found.
**/
EFI_STATUS
EFIAPI
PeiServicesFfsFindSectionData4 (
IN EFI_SECTION_TYPE SectionType,
IN UINTN SectionInstance,
IN EFI_PEI_FILE_HANDLE FileHandle,
OUT VOID **SectionData,
OUT UINT32 *SectionDataSize,
OUT UINT32 *AuthenticationStatus
)
{
ASSERT (SectionInstance == 0);
*AuthenticationStatus = 0;
return SecFfsFindSectionData2 (SectionType, FileHandle, SectionData, SectionDataSize);
}
/**
This service enables PEIMs to register the permanent memory configuration
that has been initialized with the PEI Foundation.

View File

@ -9,6 +9,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include "Sec.h"
#include <Ppi/EmuThunk.h>
EFI_PEI_TEMPORARY_RAM_SUPPORT_PPI mSecTemporaryRamSupportPpi = {
SecTemporaryRamSupport
@ -22,6 +23,53 @@ EFI_PEI_PPI_DESCRIPTOR gPrivateDispatchTable[] = {
}
};
//FIXME:
/**
Retrieves and returns a pointer to the entry point to a PE/COFF image that has been loaded
into system memory with the PE/COFF Loader Library functions.
Retrieves the entry point to the PE/COFF image specified by Pe32Data and returns this entry
point in EntryPoint. If the entry point could not be retrieved from the PE/COFF image, then
return RETURN_INVALID_PARAMETER. Otherwise return RETURN_SUCCESS.
If Pe32Data is NULL, then ASSERT().
If EntryPoint is NULL, then ASSERT().
@param Pe32Data The pointer to the PE/COFF image that is loaded in system memory.
@param EntryPoint The pointer to entry point to the PE/COFF image to return.
@retval RETURN_SUCCESS EntryPoint was returned.
@retval RETURN_INVALID_PARAMETER The entry point could not be found in the PE/COFF image.
**/
RETURN_STATUS
EFIAPI
UefiImageLoaderGetEntryPoint (
IN VOID *Pe32Data,
IN UINT32 Pe32Size,
IN OUT VOID **EntryPoint
)
{
EMU_THUNK_PPI *ThunkPpi;
EFI_STATUS Status;
EMU_THUNK_PROTOCOL *Thunk;
//
// Locate EmuThunkPpi for retrieving standard output handle
//
Status = PeiServicesLocatePpi (
&gEmuThunkPpiGuid,
0,
NULL,
(VOID **) &ThunkPpi
);
ASSERT_EFI_ERROR (Status);
Thunk = (EMU_THUNK_PROTOCOL *)ThunkPpi->Thunk ();
return Thunk->UefiImageGetEntryPoint (Pe32Data, Pe32Size, EntryPoint);
}
/**
The entry point of PE/COFF Image for the PEI Core, that has been hijacked by this
SEC that sits on top of an OS application. So the entry and exit of this module
@ -64,13 +112,15 @@ _ModuleEntryPoint (
EFI_STATUS Status;
EFI_PEI_FV_HANDLE VolumeHandle;
EFI_PEI_FILE_HANDLE FileHandle;
VOID *PeCoffImage;
VOID *UefiImage;
UINT32 UefiImageSize;
EFI_PEI_CORE_ENTRY_POINT EntryPoint;
EFI_PEI_PPI_DESCRIPTOR *Ppi;
EFI_PEI_PPI_DESCRIPTOR *SecPpiList;
UINTN SecReseveredMemorySize;
UINTN Index;
EFI_PEI_PPI_DESCRIPTOR PpiArray[10];
UINT32 AuthenticationStatus;
EMU_MAGIC_PAGE ()->PpiList = PpiList;
ProcessLibraryConstructorList ();
@ -118,10 +168,10 @@ _ModuleEntryPoint (
Status = PeiServicesFfsFindNextFile (EFI_FV_FILETYPE_PEI_CORE, VolumeHandle, &FileHandle);
ASSERT_EFI_ERROR (Status);
Status = PeiServicesFfsFindSectionData (EFI_SECTION_PE32, FileHandle, &PeCoffImage);
Status = PeiServicesFfsFindSectionData4 (EFI_SECTION_PE32, 0, FileHandle, &UefiImage, &UefiImageSize, &AuthenticationStatus);
ASSERT_EFI_ERROR (Status);
Status = PeCoffLoaderGetEntryPoint (PeCoffImage, (VOID **)&EntryPoint);
Status = UefiImageLoaderGetEntryPoint (UefiImage, UefiImageSize, (VOID **)&EntryPoint);
ASSERT_EFI_ERROR (Status);
// Transfer control to PEI Core

View File

@ -15,7 +15,6 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#include <Library/EmuMagicPageLib.h>
#include <Library/DebugLib.h>
#include <Library/PeiServicesLib.h>
#include <Library/PeCoffGetEntryPointLib.h>
#include <Library/BaseMemoryLib.h>
#include <Ppi/TemporaryRamSupport.h>

View File

@ -36,7 +36,6 @@
[LibraryClasses]
DebugLib
PeCoffGetEntryPointLib
PeiServicesLib
PpiListLib
BaseMemoryLib

View File

@ -41,7 +41,7 @@ set $SymbolFileChangesCount = 0
#
define AddFirmwareSymbolFile
if $SymbolFileChangesCount < $arg0
add-symbol-file $arg1 $arg2
add-symbol-file $arg1 -o $arg2
set $SymbolFileChangesCount = $arg0
end
end

View File

@ -415,9 +415,9 @@ EMU_THUNK_PROTOCOL gEmuThunkProtocol = {
GasketSecMalloc,
GasketSecValloc,
GasketSecFree,
GasketSecPeCoffGetEntryPoint,
GasketSecPeCoffRelocateImageExtraAction,
GasketSecPeCoffUnloadImageExtraAction,
GasketSecUefiImageGetEntryPoint,
GasketSecUefiImageRelocateImageExtraAction,
GasketSecUefiImageUnloadImageExtraAction,
GasketSecEnableInterrupt,
GasketSecDisableInterrupt,
GasketQueryPerformanceFrequency,

View File

@ -67,21 +67,22 @@ GasketSecFree (
RETURN_STATUS
EFIAPI
GasketSecPeCoffGetEntryPoint (
GasketSecUefiImageGetEntryPoint (
IN VOID *Pe32Data,
IN UINT32 Pe32Size,
IN OUT VOID **EntryPoint
);
VOID
EFIAPI
GasketSecPeCoffRelocateImageExtraAction (
IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext
GasketSecUefiImageRelocateImageExtraAction (
IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext
);
VOID
EFIAPI
GasketSecPeCoffUnloadImageExtraAction (
IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext
GasketSecUefiImageUnloadImageExtraAction (
IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext
);
VOID

View File

@ -44,9 +44,6 @@ EMU_FD_INFO *gFdInfo;
UINTN gSystemMemoryCount = 0;
EMU_SYSTEM_MEMORY *gSystemMemory;
UINTN mImageContextModHandleArraySize = 0;
IMAGE_CONTEXT_TO_MOD_HANDLE *mImageContextModHandleArray = NULL;
EFI_PEI_PPI_DESCRIPTOR *gPpiList;
int gInXcode = 0;
@ -98,11 +95,13 @@ main (
BOOLEAN Done;
EFI_PEI_FILE_HANDLE FileHandle;
VOID *SecFile;
UINT32 SecFileSize;
CHAR16 *MemorySizeStr;
CHAR16 *FirmwareVolumesStr;
UINTN *StackPointer;
FILE *GdbTempFile;
EMU_THUNK_PPI *SecEmuThunkPpi;
UINT32 AuthenticationStatus;
//
// Xcode does not support sourcing gdb scripts directly, so the Xcode XML
@ -111,8 +110,7 @@ main (
SecGdbConfigBreak ();
//
// If dlopen doesn't work, then we build a gdb script to allow the
// symbols to be loaded.
// We build a gdb script to allow the symbols to be loaded.
//
Index = strlen (*Argv);
gGdbWorkingFileName = AllocatePool (Index + strlen (".gdb") + 1);
@ -284,7 +282,14 @@ main (
&FileHandle
);
if (!EFI_ERROR (Status)) {
Status = PeiServicesFfsFindSectionData (EFI_SECTION_PE32, FileHandle, &SecFile);
Status = PeiServicesFfsFindSectionData4 (
EFI_SECTION_PE32,
0,
FileHandle,
&SecFile,
&SecFileSize,
&AuthenticationStatus
);
if (!EFI_ERROR (Status)) {
PeiIndex = Index;
printf (" contains SEC Core");
@ -330,7 +335,7 @@ main (
//
// Hand off to SEC
//
SecLoadFromCore ((UINTN)InitialStackMemory, (UINTN)InitialStackMemorySize, (UINTN)gFdInfo[0].Address, SecFile);
SecLoadFromCore ((UINTN)InitialStackMemory, (UINTN)InitialStackMemorySize, (UINTN)gFdInfo[0].Address, SecFile, SecFileSize);
//
// If we get here, then the SEC Core returned. This is an error as SEC should
@ -546,7 +551,8 @@ SecLoadFromCore (
IN UINTN LargestRegion,
IN UINTN LargestRegionSize,
IN UINTN BootFirmwareVolumeBase,
IN VOID *PeiCorePe32File
IN VOID *PeiCorePe32File,
IN UINT32 PeiCorePe32Size
)
{
EFI_STATUS Status;
@ -597,7 +603,7 @@ SecLoadFromCore (
//
// Find the SEC Core Entry Point
//
Status = SecPeCoffGetEntryPoint (PeiCorePe32File, (VOID **)&PeiCoreEntryPoint);
Status = SecUefiImageGetEntryPoint (PeiCorePe32File, PeiCorePe32Size, (VOID **)&PeiCoreEntryPoint);
if (EFI_ERROR (Status)) {
return;
}
@ -731,53 +737,28 @@ SecEmuThunkAddress (
RETURN_STATUS
EFIAPI
SecPeCoffGetEntryPoint (
IN VOID *Pe32Data,
IN OUT VOID **EntryPoint
SecUefiImageGetEntryPoint (
IN VOID *Pe32Data,
IN UINT32 Pe32Size,
IN OUT VOID **EntryPoint
)
{
EFI_STATUS Status;
PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;
EFI_STATUS Status;
UEFI_IMAGE_LOADER_IMAGE_CONTEXT ImageContext;
ZeroMem (&ImageContext, sizeof (ImageContext));
ImageContext.Handle = Pe32Data;
ImageContext.ImageRead = (PE_COFF_LOADER_READ_FILE)SecImageRead;
Status = PeCoffLoaderGetImageInfo (&ImageContext);
Status = UefiImageInitializeContext (&ImageContext, Pe32Data, Pe32Size);
if (EFI_ERROR (Status)) {
return Status;
}
if (ImageContext.ImageAddress != (UINTN)Pe32Data) {
//
// Relocate image to match the address where it resides
//
ImageContext.ImageAddress = (UINTN)Pe32Data;
Status = PeCoffLoaderLoadImage (&ImageContext);
if (EFI_ERROR (Status)) {
return Status;
}
Status = PeCoffLoaderRelocateImage (&ImageContext);
if (EFI_ERROR (Status)) {
return Status;
}
} else {
//
// Or just return image entry point
//
ImageContext.PdbPointer = PeCoffLoaderGetPdbPointer (Pe32Data);
Status = PeCoffLoaderGetEntryPoint (Pe32Data, EntryPoint);
if (EFI_ERROR (Status)) {
return Status;
}
ImageContext.EntryPoint = (UINTN)*EntryPoint;
// FIXME: Why cannot the Image be in-place already?
Status = UefiImageRelocateImageInplaceForExecution (&ImageContext);
if (EFI_ERROR (Status)) {
return Status;
}
// On Unix a dlopen is done that will change the entry point
SecPeCoffRelocateImageExtraAction (&ImageContext);
*EntryPoint = (VOID *)(UINTN)ImageContext.EntryPoint;
SecUefiImageRelocateImageExtraAction (&ImageContext);
*EntryPoint = (VOID *) (UefiImageLoaderGetImageEntryPoint (&ImageContext));
return Status;
}
@ -900,114 +881,9 @@ Returns:
return EFI_SUCCESS;
}
/*++
Routine Description:
Store the ModHandle in an array indexed by the Pdb File name.
The ModHandle is needed to unload the image.
Arguments:
ImageContext - Input data returned from PE Loader Library. Used to find the
.PDB file name of the PE Image.
ModHandle - Returned from LoadLibraryEx() and stored for call to
FreeLibrary().
Returns:
EFI_SUCCESS - ModHandle was stored.
**/
EFI_STATUS
AddHandle (
IN PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext,
IN VOID *ModHandle
)
{
UINTN Index;
IMAGE_CONTEXT_TO_MOD_HANDLE *Array;
UINTN PreviousSize;
Array = mImageContextModHandleArray;
for (Index = 0; Index < mImageContextModHandleArraySize; Index++, Array++) {
if (Array->ImageContext == NULL) {
//
// Make a copy of the string and store the ModHandle
//
Array->ImageContext = ImageContext;
Array->ModHandle = ModHandle;
return EFI_SUCCESS;
}
}
//
// No free space in mImageContextModHandleArray so grow it by
// IMAGE_CONTEXT_TO_MOD_HANDLE entires. realloc will
// copy the old values to the new location. But it does
// not zero the new memory area.
//
PreviousSize = mImageContextModHandleArraySize * sizeof (IMAGE_CONTEXT_TO_MOD_HANDLE);
mImageContextModHandleArraySize += MAX_IMAGE_CONTEXT_TO_MOD_HANDLE_ARRAY_SIZE;
mImageContextModHandleArray = ReallocatePool (
(mImageContextModHandleArraySize - 1) * sizeof (IMAGE_CONTEXT_TO_MOD_HANDLE),
mImageContextModHandleArraySize * sizeof (IMAGE_CONTEXT_TO_MOD_HANDLE),
mImageContextModHandleArray
);
if (mImageContextModHandleArray == NULL) {
ASSERT (FALSE);
return EFI_OUT_OF_RESOURCES;
}
memset (mImageContextModHandleArray + PreviousSize, 0, MAX_IMAGE_CONTEXT_TO_MOD_HANDLE_ARRAY_SIZE * sizeof (IMAGE_CONTEXT_TO_MOD_HANDLE));
return AddHandle (ImageContext, ModHandle);
}
/*++
Routine Description:
Return the ModHandle and delete the entry in the array.
Arguments:
ImageContext - Input data returned from PE Loader Library. Used to find the
.PDB file name of the PE Image.
Returns:
ModHandle - ModHandle associated with ImageContext is returned
NULL - No ModHandle associated with ImageContext
**/
VOID *
RemoveHandle (
IN PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext
)
{
UINTN Index;
IMAGE_CONTEXT_TO_MOD_HANDLE *Array;
if (ImageContext->PdbPointer == NULL) {
//
// If no PDB pointer there is no ModHandle so return NULL
//
return NULL;
}
Array = mImageContextModHandleArray;
for (Index = 0; Index < mImageContextModHandleArraySize; Index++, Array++) {
if (Array->ImageContext == ImageContext) {
//
// If you find a match return it and delete the entry
//
Array->ImageContext = NULL;
return Array->ModHandle;
}
}
return NULL;
}
BOOLEAN
IsPdbFile (
IN CHAR8 *PdbFileName
IN CONST CHAR8 *PdbFileName
)
{
UINTN Len;
@ -1035,23 +911,29 @@ IsPdbFile (
void
PrintLoadAddress (
IN PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext
IN UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext
)
{
if (ImageContext->PdbPointer == NULL) {
EFI_STATUS Status;
CONST CHAR8 *PdbPath;
UINT32 PdbPathSize;
Status = UefiImageGetSymbolsPath (ImageContext, &PdbPath, &PdbPathSize);
if (EFI_ERROR (Status)) {
fprintf (
stderr,
"0x%08lx Loading NO DEBUG with entry point 0x%08lx\n",
(unsigned long)(ImageContext->ImageAddress),
(unsigned long)ImageContext->EntryPoint
(unsigned long) UefiImageLoaderGetImageAddress (ImageContext),
(unsigned long) UefiImageLoaderGetImageEntryPoint (ImageContext)
);
} else {
fprintf (
stderr,
"0x%08lx Loading %s with entry point 0x%08lx\n",
(unsigned long)(ImageContext->ImageAddress + ImageContext->SizeOfHeaders),
ImageContext->PdbPointer,
(unsigned long)ImageContext->EntryPoint
(unsigned long) UefiImageLoaderGetImageAddress (ImageContext),
PdbPath,
(unsigned long) UefiImageLoaderGetImageEntryPoint (ImageContext)
);
}
@ -1059,71 +941,12 @@ PrintLoadAddress (
fflush (stderr);
}
/**
Loads the image using dlopen so symbols will be automatically
loaded by gdb.
@param ImageContext The PE/COFF image context
@retval TRUE - The image was successfully loaded
@retval FALSE - The image was successfully loaded
**/
BOOLEAN
DlLoadImage (
IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext
)
{
#ifdef __APPLE__
return FALSE;
#else
void *Handle = NULL;
void *Entry = NULL;
if (ImageContext->PdbPointer == NULL) {
return FALSE;
}
if (!IsPdbFile (ImageContext->PdbPointer)) {
return FALSE;
}
fprintf (
stderr,
"Loading %s 0x%08lx - entry point 0x%08lx\n",
ImageContext->PdbPointer,
(unsigned long)ImageContext->ImageAddress,
(unsigned long)ImageContext->EntryPoint
);
Handle = dlopen (ImageContext->PdbPointer, RTLD_NOW);
if (Handle != NULL) {
Entry = dlsym (Handle, "_ModuleEntryPoint");
AddHandle (ImageContext, Handle);
} else {
printf ("%s\n", dlerror ());
}
if (Entry != NULL) {
ImageContext->EntryPoint = (UINTN)Entry;
printf ("Change %s Entrypoint to :0x%08lx\n", ImageContext->PdbPointer, (unsigned long)Entry);
return TRUE;
} else {
return FALSE;
}
#endif
}
#ifdef __APPLE__
__attribute__ ((noinline))
#endif
VOID
SecGdbScriptBreak (
char *FileName,
const char *FileName,
int FileNameLength,
long unsigned int LoadAddress,
int AddSymbolFlag
@ -1141,28 +964,37 @@ SecGdbScriptBreak (
**/
VOID
GdbScriptAddImage (
IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext
IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext
)
{
EFI_STATUS Status;
CONST CHAR8 *PdbPath;
UINT32 PdbPathSize;
PrintLoadAddress (ImageContext);
if ((ImageContext->PdbPointer != NULL) && !IsPdbFile (ImageContext->PdbPointer)) {
Status = UefiImageGetSymbolsPath ((ImageContext, &PdbPath,) &PdbPathSize);
if (EFI_ERROR (Status)) {
return;
}
if (!IsPdbFile (PdbPath)) {
FILE *GdbTempFile;
if (FeaturePcdGet (PcdEmulatorLazyLoadSymbols)) {
GdbTempFile = fopen (gGdbWorkingFileName, "a");
if (GdbTempFile != NULL) {
long unsigned int SymbolsAddr = (long unsigned int)(ImageContext->ImageAddress + ImageContext->SizeOfHeaders);
long unsigned int SymbolsAddr = (long unsigned int)UefiImageLoaderGetImageAddress (ImageContext);
mScriptSymbolChangesCount++;
fprintf (
GdbTempFile,
"AddFirmwareSymbolFile 0x%x %s 0x%08lx\n",
mScriptSymbolChangesCount,
ImageContext->PdbPointer,
PdbPath,
SymbolsAddr
);
fclose (GdbTempFile);
// This is for the lldb breakpoint only
SecGdbScriptBreak (ImageContext->PdbPointer, strlen (ImageContext->PdbPointer) + 1, (long unsigned int)(ImageContext->ImageAddress + ImageContext->SizeOfHeaders), 1);
SecGdbScriptBreak (PdbPath, PdbPathSize, (long unsigned int)UefiImageLoaderGetImageAddress (ImageContext), 1);
} else {
ASSERT (FALSE);
}
@ -1171,9 +1003,9 @@ GdbScriptAddImage (
if (GdbTempFile != NULL) {
fprintf (
GdbTempFile,
"add-symbol-file %s 0x%08lx\n",
ImageContext->PdbPointer,
(long unsigned int)(ImageContext->ImageAddress + ImageContext->SizeOfHeaders)
"add-symbol-file %s -o 0x%08lx\n",
PdbPath,
(long unsigned int)UefiImageLoaderGetImageAddress (ImageContext)
);
fclose (GdbTempFile);
@ -1183,7 +1015,7 @@ GdbScriptAddImage (
// Also used for the lldb breakpoint script. The lldb breakpoint script does
// not use the file, it uses the arguments.
//
SecGdbScriptBreak (ImageContext->PdbPointer, strlen (ImageContext->PdbPointer) + 1, (long unsigned int)(ImageContext->ImageAddress + ImageContext->SizeOfHeaders), 1);
SecGdbScriptBreak (PdbPath, PdbPathSize, (long unsigned int)UefiImageLoaderGetImageAddress (ImageContext), 1);
} else {
ASSERT (FALSE);
}
@ -1193,13 +1025,11 @@ GdbScriptAddImage (
VOID
EFIAPI
SecPeCoffRelocateImageExtraAction (
IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext
SecUefiImageRelocateImageExtraAction (
IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext
)
{
if (!DlLoadImage (ImageContext)) {
GdbScriptAddImage (ImageContext);
}
GdbScriptAddImage (ImageContext);
}
/**
@ -1211,15 +1041,23 @@ SecPeCoffRelocateImageExtraAction (
**/
VOID
GdbScriptRemoveImage (
IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext
IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext
)
{
FILE *GdbTempFile;
FILE *GdbTempFile;
EFI_STATUS Status;
CONST CHAR8 *PdbPath;
UINT32 PdbPathSize;
Status = UefiImageGetSymbolsPath (ImageContext, &PdbPath, &PdbPathSize);
if (EFI_ERROR (Status)) {
return;
}
//
// Need to skip .PDB files created from VC++
//
if (IsPdbFile (ImageContext->PdbPointer)) {
if (IsPdbFile (PdbPath)) {
return;
}
@ -1234,24 +1072,24 @@ GdbScriptRemoveImage (
GdbTempFile,
"RemoveFirmwareSymbolFile 0x%x %s\n",
mScriptSymbolChangesCount,
ImageContext->PdbPointer
PdbPath
);
fclose (GdbTempFile);
SecGdbScriptBreak (ImageContext->PdbPointer, strlen (ImageContext->PdbPointer) + 1, 0, 0);
SecGdbScriptBreak (PdbPath, PdbPathSize, 0, 0);
} else {
ASSERT (FALSE);
}
} else {
GdbTempFile = fopen (gGdbWorkingFileName, "w");
if (GdbTempFile != NULL) {
fprintf (GdbTempFile, "remove-symbol-file %s\n", ImageContext->PdbPointer);
fprintf (GdbTempFile, "remove-symbol-file %s\n", PdbPath);
fclose (GdbTempFile);
//
// Target for gdb breakpoint in a script that uses gGdbWorkingFileName to set a breakpoint.
// Hey what can you say scripting in gdb is not that great....
//
SecGdbScriptBreak (ImageContext->PdbPointer, strlen (ImageContext->PdbPointer) + 1, 0, 0);
SecGdbScriptBreak (PdbPath, PdbPathSize, 0, 0);
} else {
ASSERT (FALSE);
}
@ -1260,22 +1098,9 @@ GdbScriptRemoveImage (
VOID
EFIAPI
SecPeCoffUnloadImageExtraAction (
IN PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext
SecUefiImageUnloadImageExtraAction (
IN UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext
)
{
VOID *Handle;
//
// Check to see if the image symbols were loaded with gdb script, or dlopen
//
Handle = RemoveHandle (ImageContext);
if (Handle != NULL) {
#ifndef __APPLE__
dlclose (Handle);
#endif
return;
}
GdbScriptRemoveImage (ImageContext);
}

View File

@ -85,7 +85,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#include <PiPei.h>
#include <Uefi.h>
#include <Library/PeCoffLib.h>
#include <Library/UefiImageLib.h>
#include <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/MemoryAllocationLib.h>
@ -97,7 +97,6 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#include <Library/ThunkPpiList.h>
#include <Library/ThunkProtocolList.h>
#include <Library/PeiServicesLib.h>
#include <Library/PeCoffGetEntryPointLib.h>
#include <Library/EmuMagicPageLib.h>
#include <Ppi/EmuThunk.h>
@ -137,7 +136,7 @@ typedef struct {
#define MAX_IMAGE_CONTEXT_TO_MOD_HANDLE_ARRAY_SIZE 0x100
typedef struct {
PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext;
UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext;
VOID *ModHandle;
} IMAGE_CONTEXT_TO_MOD_HANDLE;
@ -162,7 +161,8 @@ SecLoadFromCore (
IN UINTN LargestRegion,
IN UINTN LargestRegionSize,
IN UINTN BootFirmwareVolumeBase,
IN VOID *PeiCoreFile
IN VOID *PeiCoreFile,
IN UINT32 PeiCorePe32Size
);
EFI_STATUS
@ -194,17 +194,11 @@ SecFfsFindSectionData (
);
EFI_STATUS
EFIAPI
SecUnixPeCoffLoaderLoadAsDll (
IN CHAR8 *PdbFileName,
IN VOID **ImageEntryPoint,
OUT VOID **ModHandle
);
EFI_STATUS
EFIAPI
SecUnixPeCoffLoaderFreeLibrary (
OUT VOID *ModHandle
SecFfsFindSectionData2 (
IN EFI_SECTION_TYPE SectionType,
IN EFI_FFS_FILE_HEADER *FfsFileHeader,
IN OUT VOID **SectionData,
OUT UINT32 *SectionDataSize
);
EFI_STATUS
@ -228,7 +222,7 @@ GasketSecUnixFdAddress (
EFI_STATUS
GetImageReadFunction (
IN PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext,
IN UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext,
IN EFI_PHYSICAL_ADDRESS *TopOfMemory
);
@ -273,21 +267,22 @@ GasketSecTemporaryRamSupport (
RETURN_STATUS
EFIAPI
SecPeCoffGetEntryPoint (
SecUefiImageGetEntryPoint (
IN VOID *Pe32Data,
IN UINT32 Pe32Size,
IN OUT VOID **EntryPoint
);
VOID
EFIAPI
SecPeCoffRelocateImageExtraAction (
IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext
SecUefiImageRelocateImageExtraAction (
IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext
);
VOID
EFIAPI
SecPeCoffLoaderUnloadImageExtraAction (
IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext
SecUefiImageLoaderUnloadImageExtraAction (
IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext
);
VOID

View File

@ -55,12 +55,11 @@
PrintLib
BaseMemoryLib
BaseLib
PeCoffLib
UefiImageLib
ThunkPpiList
ThunkProtocolList
PpiListLib
PeiServicesLib
PeCoffGetEntryPointLib
[Ppis]
gEfiPeiStatusCodePpiGuid # PPI ALWAYS_PRODUCED

View File

@ -313,24 +313,26 @@ ASM_PFX(GasketSecGetNextProtocol):
// PPIs produced by SEC
ASM_GLOBAL ASM_PFX(GasketSecPeCoffGetEntryPoint)
ASM_PFX(GasketSecPeCoffGetEntryPoint):
ASM_GLOBAL ASM_PFX(GasketSecUefiImageGetEntryPoint)
ASM_PFX(GasketSecUefiImageGetEntryPoint):
pushl %ebp
movl %esp, %ebp
subl $24, %esp // sub extra 16 from the stack for alignment
subl $40, %esp // sub extra 16 from the stack for alignment
and $-16, %esp // stack needs to end in 0xFFFFFFF0 before call
movl 16(%ebp), %eax
movl %eax, 8(%esp)
movl 12(%ebp), %eax
movl %eax, 4(%esp)
movl 8(%ebp), %eax
movl %eax, (%esp)
call ASM_PFX(SecPeCoffGetEntryPoint)
call ASM_PFX(SecUefiImageGetEntryPoint)
leave
ret
ASM_GLOBAL ASM_PFX(GasketSecPeCoffRelocateImageExtraAction)
ASM_PFX(GasketSecPeCoffRelocateImageExtraAction):
ASM_GLOBAL ASM_PFX(GasketSecUefiImageRelocateImageExtraAction)
ASM_PFX(GasketSecUefiImageRelocateImageExtraAction):
pushl %ebp
movl %esp, %ebp
subl $24, %esp // sub extra 16 from the stack for alignment
@ -338,13 +340,13 @@ ASM_PFX(GasketSecPeCoffRelocateImageExtraAction):
movl 8(%ebp), %eax
movl %eax, (%esp)
call ASM_PFX(SecPeCoffRelocateImageExtraAction)
call ASM_PFX(SecUefiImageRelocateImageExtraAction)
leave
ret
ASM_GLOBAL ASM_PFX(GasketSecPeCoffUnloadImageExtraAction)
ASM_PFX(GasketSecPeCoffUnloadImageExtraAction):
ASM_GLOBAL ASM_PFX(GasketSecUefiImageUnloadImageExtraAction)
ASM_PFX(GasketSecUefiImageUnloadImageExtraAction):
pushl %ebp
movl %esp, %ebp
subl $24, %esp // sub extra 16 from the stack for alignment
@ -352,7 +354,7 @@ ASM_PFX(GasketSecPeCoffUnloadImageExtraAction):
movl 8(%ebp), %eax
movl %eax, (%esp)
call ASM_PFX(SecPeCoffUnloadImageExtraAction)
call ASM_PFX(SecUefiImageUnloadImageExtraAction)
leave
ret

View File

@ -358,8 +358,8 @@ ASM_PFX(GasketSecGetNextProtocol):
// PPIs produced by SEC
ASM_GLOBAL ASM_PFX(GasketSecPeCoffGetEntryPoint)
ASM_PFX(GasketSecPeCoffGetEntryPoint):
ASM_GLOBAL ASM_PFX(GasketSecUefiImageGetEntryPoint)
ASM_PFX(GasketSecUefiImageGetEntryPoint):
pushq %rbp // stack frame is for the debugger
movq %rsp, %rbp
@ -368,16 +368,17 @@ ASM_PFX(GasketSecPeCoffGetEntryPoint):
movq %rcx, %rdi // Swizzle args
movq %rdx, %rsi
movq %r8, %rdx
call ASM_PFX(SecPeCoffGetEntryPoint)
call ASM_PFX(SecUefiImageGetEntryPoint)
popq %rdi // restore state
popq %rsi
popq %rbp
ret
ASM_GLOBAL ASM_PFX(GasketSecPeCoffRelocateImageExtraAction)
ASM_PFX(GasketSecPeCoffRelocateImageExtraAction):
ASM_GLOBAL ASM_PFX(GasketSecUefiImageRelocateImageExtraAction)
ASM_PFX(GasketSecUefiImageRelocateImageExtraAction):
pushq %rbp // stack frame is for the debugger
movq %rsp, %rbp
@ -386,15 +387,15 @@ ASM_PFX(GasketSecPeCoffRelocateImageExtraAction):
movq %rcx, %rdi // Swizzle args
call ASM_PFX(SecPeCoffRelocateImageExtraAction)
call ASM_PFX(SecUefiImageRelocateImageExtraAction)
popq %rdi // restore state
popq %rsi
popq %rbp
ret
ASM_GLOBAL ASM_PFX(GasketSecPeCoffUnloadImageExtraAction)
ASM_PFX(GasketSecPeCoffUnloadImageExtraAction):
ASM_GLOBAL ASM_PFX(GasketSecUefiImageUnloadImageExtraAction)
ASM_PFX(GasketSecUefiImageUnloadImageExtraAction):
pushq %rbp // stack frame is for the debugger
movq %rsp, %rbp
@ -403,7 +404,7 @@ ASM_PFX(GasketSecPeCoffUnloadImageExtraAction):
movq %rcx, %rdi // Swizzle args
call ASM_PFX(SecPeCoffUnloadImageExtraAction)
call ASM_PFX(SecUefiImageUnloadImageExtraAction)
popq %rdi // restore state
popq %rsi

4
EmulatorPkg/Unix/lldbefi.py Executable file → Normal file
View File

@ -361,7 +361,7 @@ def LoadEmulatorEfiSymbols(frame, bp_loc , internal_dict):
#
# VOID
# SecGdbScriptBreak (
# char *FileName,
# const char *FileName,
# int FileNameLength,
# long unsigned int LoadAddress,
# int AddSymbolFlag
@ -394,7 +394,7 @@ def LoadEmulatorEfiSymbols(frame, bp_loc , internal_dict):
debugger = frame.thread.process.target.debugger
if frame.FindVariable ("AddSymbolFlag").GetValueAsUnsigned() == 1:
LoadAddress = frame.FindVariable ("LoadAddress").GetValueAsUnsigned() - 0x240
LoadAddress = frame.FindVariable ("LoadAddress").GetValueAsUnsigned()
debugger.HandleCommand ("target modules add %s" % FileName)
print("target modules load --slid 0x%x %s" % (LoadAddress, FileName))

View File

@ -444,6 +444,7 @@ Returns:
BOOLEAN Done;
EFI_PEI_FILE_HANDLE FileHandle;
VOID *SecFile;
UINT32 SecFileSize;
CHAR16 *MemorySizeStr;
CHAR16 *FirmwareVolumesStr;
UINTN ProcessAffinityMask;
@ -451,6 +452,7 @@ Returns:
INT32 LowBit;
UINTN ResetJumpCode;
EMU_THUNK_PPI *SecEmuThunkPpi;
UINT32 AuthenticationStatus;
//
// Enable the privilege so that RTC driver can successfully run SetTime()
@ -648,7 +650,14 @@ Returns:
&FileHandle
);
if (!EFI_ERROR (Status)) {
Status = PeiServicesFfsFindSectionData (EFI_SECTION_PE32, FileHandle, &SecFile);
Status = PeiServicesFfsFindSectionData4 (
EFI_SECTION_PE32,
0,
FileHandle,
&SecFile,
&SecFileSize,
&AuthenticationStatus
);
if (!EFI_ERROR (Status)) {
SecPrint (" contains SEC Core");
}
@ -679,7 +688,7 @@ Returns:
//
// Hand off to SEC Core
//
SecLoadSecCore ((UINTN)TemporaryRam, TemporaryRamSize, gFdInfo[0].Address, gFdInfo[0].Size, SecFile);
SecLoadSecCore ((UINTN)TemporaryRam, TemporaryRamSize, gFdInfo[0].Address, gFdInfo[0].Size, SecFile, SecFileSize);
//
// If we get here, then the SEC Core returned. This is an error as SEC should
@ -695,7 +704,8 @@ SecLoadSecCore (
IN UINTN TemporaryRamSize,
IN VOID *BootFirmwareVolumeBase,
IN UINTN BootFirmwareVolumeSize,
IN VOID *SecCorePe32File
IN VOID *SecCorePe32File,
IN UINT32 SecCorePe32Size
)
/*++
@ -759,8 +769,9 @@ Returns:
//
// Load the PEI Core from a Firmware Volume
//
Status = SecPeCoffGetEntryPoint (
Status = SecUefiImageGetEntryPoint (
SecCorePe32File,
SecCorePe32Size,
&SecCoreEntryPoint
);
if (EFI_ERROR (Status)) {
@ -784,40 +795,47 @@ Returns:
RETURN_STATUS
EFIAPI
SecPeCoffGetEntryPoint (
IN VOID *Pe32Data,
IN OUT VOID **EntryPoint
SecUefiImageGetEntryPoint (
IN VOID *Pe32Data,
IN UINT32 Pe32Size,
IN OUT VOID **EntryPoint
)
{
EFI_STATUS Status;
PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;
EFI_STATUS Status;
UEFI_IMAGE_LOADER_IMAGE_CONTEXT ImageContext;
VOID *Dest;
UINT32 DestSize;
ZeroMem (&ImageContext, sizeof (ImageContext));
ImageContext.Handle = Pe32Data;
ImageContext.ImageRead = (PE_COFF_LOADER_READ_FILE)SecImageRead;
Status = PeCoffLoaderGetImageInfo (&ImageContext);
Status = UefiImageInitializeContext (&ImageContext, Pe32Data, Pe32Size);
if (EFI_ERROR (Status)) {
return Status;
}
//
// XIP for SEC and PEI_CORE
// Allocate space in NT (not emulator) memory with ReadWrite and Execute attribute.
// Extra space is for alignment
//
ImageContext.ImageAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)Pe32Data;
Status = PeCoffLoaderLoadImage (&ImageContext);
Status = UefiImageLoaderGetDestinationSize(&ImageContext, &DestSize);
if (EFI_ERROR (Status)) {
return Status;
}
Status = PeCoffLoaderRelocateImage (&ImageContext);
Dest = VirtualAlloc (NULL, (SIZE_T) DestSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
if (Dest == NULL) {
return EFI_OUT_OF_RESOURCES;
}
Status = UefiImageLoadImage (&ImageContext, Dest, DestSize);
if (EFI_ERROR (Status)) {
return Status;
}
*EntryPoint = (VOID *)(UINTN)ImageContext.EntryPoint;
Status = UefiImageRelocateImage (&ImageContext, (UINTN) Dest, NULL, 0);
if (EFI_ERROR (Status)) {
return Status;
}
*EntryPoint = (VOID *) (UefiImageLoaderGetImageEntryPoint (&ImageContext));
return EFI_SUCCESS;
}
@ -951,7 +969,7 @@ Returns:
--*/
EFI_STATUS
AddModHandle (
IN PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext,
IN UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext,
IN VOID *ModHandle
)
@ -1028,7 +1046,7 @@ AddModHandle (
**/
VOID *
RemoveModHandle (
IN PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext
IN UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext
)
{
UINTN Index;
@ -1058,8 +1076,8 @@ RemoveModHandle (
VOID
EFIAPI
PeCoffLoaderRelocateImageExtraAction (
IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext
UefiImageLoaderRelocateImageExtraAction (
IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext
)
{
EFI_STATUS Status;
@ -1084,7 +1102,7 @@ PeCoffLoaderRelocateImageExtraAction (
// Load the DLL if it's not an EBC image.
//
if ((ImageContext->PdbPointer != NULL) &&
(ImageContext->Machine != EFI_IMAGE_MACHINE_EBC))
(UefiImageGetMachine (ImageContext) != EFI_IMAGE_MACHINE_EBC))
{
//
// Convert filename from ASCII to Unicode
@ -1098,7 +1116,7 @@ PeCoffLoaderRelocateImageExtraAction (
free (DllFileName);
//
// Never return an error if PeCoffLoaderRelocateImage() succeeded.
// Never return an error if UefiImageRelocateImage() succeeded.
// The image will run, but we just can't source level debug. If we
// return an error the image will not run.
//
@ -1126,6 +1144,7 @@ PeCoffLoaderRelocateImageExtraAction (
// checking as the we can point to the PE32 image loaded by Tiano. This
// step is only needed for source level debugging
//
// FIXME: Fix ImageBase too
DllEntryPoint = (VOID *)(UINTN)GetProcAddress (Library, "InitializeDriver");
}
@ -1154,8 +1173,8 @@ PeCoffLoaderRelocateImageExtraAction (
VOID
EFIAPI
PeCoffLoaderUnloadImageExtraAction (
IN PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext
UefiImageLoaderUnloadImageExtraAction (
IN UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext
)
{
VOID *ModHandle;

View File

@ -21,7 +21,7 @@ Abstract:
#include "WinInclude.h"
#include <PiPei.h>
#include <IndustryStandard/PeImage.h>
#include <IndustryStandard/PeImage2.h>
#include <Guid/FileInfo.h>
#include <Guid/FileSystemInfo.h>
#include <Guid/FileSystemVolumeLabelInfo.h>
@ -35,7 +35,7 @@ Abstract:
#include <Protocol/EmuSnp.h>
#include <Library/BaseLib.h>
#include <Library/PeCoffLib.h>
#include <Library/UefiImageLib.h>
#include <Library/DebugLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/ThunkPpiList.h>
@ -44,7 +44,7 @@ Abstract:
#include <Library/PrintLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/PeiServicesLib.h>
#include <Library/PeCoffExtraActionLib.h>
#include <Library/UefiImageExtraActionLib.h>
#include <Library/NetLib.h>
#define TEMPORARY_RAM_SIZE 0x20000
@ -61,8 +61,9 @@ typedef struct {
RETURN_STATUS
EFIAPI
SecPeCoffGetEntryPoint (
SecUefiImageGetEntryPoint (
IN VOID *Pe32Data,
IN UINT32 Pe32Size,
IN OUT VOID **EntryPoint
);
@ -72,7 +73,8 @@ SecLoadSecCore (
IN UINTN TemporaryRamSize,
IN VOID *BootFirmwareVolumeBase,
IN UINTN BootFirmwareVolumeSize,
IN VOID *SecCorePe32File
IN VOID *SecCorePe32File,
IN UINT32 SecCorePe32Size
)
/*++

View File

@ -49,7 +49,7 @@
PrintLib
BaseMemoryLib
BaseLib
PeCoffLib
UefiImageLib
ThunkPpiList
ThunkProtocolList
PpiListLib

View File

@ -581,9 +581,9 @@ EMU_THUNK_PROTOCOL gEmuThunkProtocol = {
SecAlloc,
NULL,
SecFree,
SecPeCoffGetEntryPoint,
PeCoffLoaderRelocateImageExtraAction,
PeCoffLoaderUnloadImageExtraAction,
SecUefiImageGetEntryPoint,
UefiImageLoaderRelocateImageExtraAction,
UefiImageLoaderUnloadImageExtraAction,
SecEnableInterrupt,
SecDisableInterrupt,
SecQueryPerformanceFrequency,

View File

@ -90,11 +90,11 @@
PeiServicesTablePointerLib|MdePkg/Library/PeiServicesTablePointerLibIdt/PeiServicesTablePointerLibIdt.inf
PeiServicesLib|MdePkg/Library/PeiServicesLib/PeiServicesLib.inf
MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf
PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf
ReportStatusCodeLib|MdeModulePkg/Library/PeiReportStatusCodeLib/PeiReportStatusCodeLib.inf
CacheMaintenanceLib|MdePkg/Library/BaseCacheMaintenanceLib/BaseCacheMaintenanceLib.inf
PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf
PeCoffExtraActionLib|MdePkg/Library/BasePeCoffExtraActionLibNull/BasePeCoffExtraActionLibNull.inf
PeCoffLib2|MdePkg/Library/BasePeCoffLib2/BasePeCoffLib2.inf
UefiImageLib|MdePkg/Library/BaseUefiImageLib/BaseUefiImageLibPeCoff.inf
UefiImageExtraActionLib|MdePkg/Library/BaseUefiImageExtraActionLibNull/BaseUefiImageExtraActionLibNull.inf
UefiDecompressLib|MdePkg/Library/BaseUefiDecompressLib/BaseUefiDecompressLib.inf
SynchronizationLib|MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf
CpuLib|MdePkg/Library/BaseCpuLib/BaseCpuLib.inf

View File

@ -39,12 +39,13 @@
BaseMemoryLib
UefiLib
FspWrapperApiLib
PeCoffLib
UefiImageLib
CacheMaintenanceLib
DxeServicesLib
PerformanceLib
HobLib
FspWrapperPlatformLib
MemoryAllocationLib
[Protocols]
gEfiPciEnumerationCompleteProtocolGuid ## CONSUMES

View File

@ -11,11 +11,13 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#include <Library/UefiDriverEntryPoint.h>
#include <Library/BaseMemoryLib.h>
#include <Library/DebugLib.h>
#include <Library/PeCoffLib.h>
#include <Library/UefiImageLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/DxeServicesLib.h>
#include <Library/CacheMaintenanceLib.h>
#include <Library/UefiLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/MemoryAllocationLibEx.h>
/**
Relocate this image under 4G memory.
@ -37,9 +39,11 @@ RelocateImageUnder4GIfNeeded (
UINT8 *Buffer;
UINTN BufferSize;
EFI_HANDLE NewImageHandle;
UINT32 ImageSize;
UINT32 ImageAlignment;
UINTN Pages;
EFI_PHYSICAL_ADDRESS FfsBuffer;
PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;
UEFI_IMAGE_LOADER_IMAGE_CONTEXT ImageContext;
VOID *Interface;
//
@ -83,43 +87,34 @@ RelocateImageUnder4GIfNeeded (
&BufferSize
);
ASSERT_EFI_ERROR (Status);
ImageContext.Handle = Buffer;
ImageContext.ImageRead = PeCoffLoaderImageReadFromMemory;
//
// Get information about the image being loaded
//
Status = PeCoffLoaderGetImageInfo (&ImageContext);
Status = UefiImageInitializeContext (&ImageContext, Buffer, (UINT32) BufferSize);
ASSERT_EFI_ERROR (Status);
if (ImageContext.SectionAlignment > EFI_PAGE_SIZE) {
Pages = EFI_SIZE_TO_PAGES ((UINTN)(ImageContext.ImageSize + ImageContext.SectionAlignment));
} else {
Pages = EFI_SIZE_TO_PAGES ((UINTN)ImageContext.ImageSize);
}
ImageSize = UefiImageGetImageSize (&ImageContext);
ImageAlignment = UefiImageGetSegmentAlignment (&ImageContext);
Pages = EFI_SIZE_TO_PAGES (ImageSize);
FfsBuffer = 0xFFFFFFFF;
Status = gBS->AllocatePages (
AllocateMaxAddress,
EfiBootServicesCode,
Pages,
&FfsBuffer
);
Status = AllocateAlignedPagesEx (
AllocateMaxAddress,
EfiBootServicesCode,
Pages,
ImageAlignment,
&FfsBuffer
);
ASSERT_EFI_ERROR (Status);
ImageContext.ImageAddress = (PHYSICAL_ADDRESS)(UINTN)FfsBuffer;
//
// Align buffer on section boundary
// Load and relocate the image to our new buffer
//
ImageContext.ImageAddress += ImageContext.SectionAlignment - 1;
ImageContext.ImageAddress &= ~((EFI_PHYSICAL_ADDRESS)ImageContext.SectionAlignment - 1);
//
// Load the image to our new buffer
//
Status = PeCoffLoaderLoadImage (&ImageContext);
ASSERT_EFI_ERROR (Status);
//
// Relocate the image in our new buffer
//
Status = PeCoffLoaderRelocateImage (&ImageContext);
Status = UefiImageLoadImageForExecution (
&ImageContext,
(VOID *) (UINTN) FfsBuffer,
ImageSize,
NULL,
0
);
ASSERT_EFI_ERROR (Status);
//
@ -127,16 +122,11 @@ RelocateImageUnder4GIfNeeded (
//
gBS->FreePool (Buffer);
//
// Flush the instruction cache so the image data is written before we execute it
//
InvalidateInstructionCacheRange ((VOID *)(UINTN)ImageContext.ImageAddress, (UINTN)ImageContext.ImageSize);
DEBUG ((DEBUG_INFO, "Loading driver at 0x%08x EntryPoint=0x%08x\n", (UINTN)ImageContext.ImageAddress, (UINTN)ImageContext.EntryPoint));
Status = ((EFI_IMAGE_ENTRY_POINT)(UINTN)(ImageContext.EntryPoint))(NewImageHandle, gST);
DEBUG ((DEBUG_INFO, "Loading driver at 0x%08llx EntryPoint=0x%08x\n", FfsBuffer, UefiImageLoaderGetImageEntryPoint (&ImageContext)));
Status = ((EFI_IMAGE_ENTRY_POINT)(UefiImageLoaderGetImageEntryPoint (&ImageContext)))(NewImageHandle, gST);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "Error: Image at 0x%08x start failed: %r\n", ImageContext.ImageAddress, Status));
gBS->FreePages (FfsBuffer, Pages);
DEBUG ((DEBUG_ERROR, "Error: Image at 0x%08llx start failed: %r\n", FfsBuffer, Status));
FreeAlignedPages ((VOID *)(UINTN)FfsBuffer, Pages);
}
//

View File

@ -38,8 +38,8 @@
FspWrapperPlatformLib
FspWrapperHobProcessLib
CpuLib
PeCoffGetEntryPointLib
PeCoffExtraActionLib
UefiCpuLib
UefiImageExtraActionLib
PerformanceLib
TimerLib
FspWrapperApiLib

View File

@ -39,8 +39,8 @@
FspWrapperPlatformLib
FspWrapperHobProcessLib
CpuLib
PeCoffGetEntryPointLib
PeCoffExtraActionLib
UefiCpuLib
UefiImageExtraActionLib
PerformanceLib
FspWrapperApiLib
FspWrapperApiTestLib

View File

@ -27,9 +27,9 @@
DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.inf
PciCf8Lib|MdePkg/Library/BasePciCf8Lib/BasePciCf8Lib.inf
IoLib|MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf
PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf
PeCoffExtraActionLib|MdePkg/Library/BasePeCoffExtraActionLibNull/BasePeCoffExtraActionLibNull.inf
PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf
UefiImageExtraActionLib|MdePkg/Library/BaseUefiImageExtraActionLibNull/BaseUefiImageExtraActionLibNull.inf
PeCoffLib2|MdePkg/Library/BasePeCoffLib2/BasePeCoffLib2.inf
UefiImageLib|MdePkg/Library/BaseUefiImageLib/BaseUefiImageLibPeCoff.inf
CacheMaintenanceLib|MdePkg/Library/BaseCacheMaintenanceLib/BaseCacheMaintenanceLib.inf
PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.inf

BIN
LoaderFlow.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 213 KiB

View File

@ -40,7 +40,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#include <Library/PcdLib.h>
#include <IndustryStandard/Pci.h>
#include <IndustryStandard/PeImage.h>
#include <IndustryStandard/PeImage2.h>
#include <IndustryStandard/Acpi.h>
typedef struct _PCI_IO_DEVICE PCI_IO_DEVICE;

View File

@ -73,11 +73,11 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#include <Library/ExtractGuidedSectionLib.h>
#include <Library/CacheMaintenanceLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/PeCoffLib.h>
#include <Library/PeCoffGetEntryPointLib.h>
#include <Library/PeCoffExtraActionLib.h>
#include <Library/UefiImageLib.h>
#include <Library/UefiImageExtraActionLib.h>
#include <Library/PcdLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/MemoryAllocationLibEx.h>
#include <Library/DevicePathLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/ReportStatusCodeLib.h>
@ -219,10 +219,10 @@ typedef struct {
EFI_RUNTIME_IMAGE_ENTRY *RuntimeData;
/// Pointer to Loaded Image Device Path Protocol
EFI_DEVICE_PATH_PROTOCOL *LoadedImageDevicePath;
/// PeCoffLoader ImageContext
PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;
/// Status returned by LoadImage() service.
EFI_STATUS LoadImageStatus;
VOID *HiiData;
} LOADED_IMAGE_PRIVATE_DATA;
#define LOADED_IMAGE_PRIVATE_DATA_FROM_THIS(a) \
@ -389,7 +389,8 @@ CoreInitializeEventServices (
**/
EFI_STATUS
CoreInitializeImageServices (
IN VOID *HobStart
IN VOID *HobStart,
OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext
);
/**
@ -2384,7 +2385,8 @@ VOID
CoreNewDebugImageInfoEntry (
IN UINT32 ImageInfoType,
IN EFI_LOADED_IMAGE_PROTOCOL *LoadedImage,
IN EFI_HANDLE ImageHandle
IN EFI_HANDLE ImageHandle,
IN UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext
);
/**
@ -2573,7 +2575,8 @@ VerifyFvHeaderChecksum (
**/
VOID
MemoryProfileInit (
IN VOID *HobStart
IN VOID *HobStart,
IN UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext
);
/**
@ -2599,8 +2602,9 @@ MemoryProfileInstallProtocol (
**/
EFI_STATUS
RegisterMemoryProfileImage (
IN LOADED_IMAGE_PRIVATE_DATA *DriverEntry,
IN EFI_FV_FILETYPE FileType
IN EFI_DEVICE_PATH_PROTOCOL *FilePath,
IN EFI_FV_FILETYPE FileType,
IN UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext
);
/**
@ -2616,7 +2620,8 @@ RegisterMemoryProfileImage (
**/
EFI_STATUS
UnregisterMemoryProfileImage (
IN LOADED_IMAGE_PRIVATE_DATA *DriverEntry
EFI_DEVICE_PATH_PROTOCOL *FilePath,
IN EFI_PHYSICAL_ADDRESS ImageAddress
);
/**
@ -2703,7 +2708,8 @@ InstallMemoryAttributesTableOnMemoryAllocation (
**/
VOID
InsertImageRecord (
IN EFI_RUNTIME_IMAGE_ENTRY *RuntimeImage
IN LOADED_IMAGE_PRIVATE_DATA *Image,
IN UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext
);
/**
@ -2724,8 +2730,8 @@ RemoveImageRecord (
**/
VOID
ProtectUefiImage (
IN EFI_LOADED_IMAGE_PROTOCOL *LoadedImage,
IN EFI_DEVICE_PATH_PROTOCOL *LoadedImageDevicePath
IN LOADED_IMAGE_PRIVATE_DATA *Image,
UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext
);
/**

View File

@ -82,9 +82,8 @@
UefiLib
DebugLib
DxeCoreEntryPoint
PeCoffLib
PeCoffGetEntryPointLib
PeCoffExtraActionLib
UefiImageLib
UefiImageExtraActionLib
ExtractGuidedSectionLib
MemoryAllocationLib
UefiBootServicesTableLib

View File

@ -234,15 +234,14 @@ DxeMain (
IN VOID *HobStart
)
{
EFI_STATUS Status;
EFI_PHYSICAL_ADDRESS MemoryBaseAddress;
UINT64 MemoryLength;
PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;
UINTN Index;
EFI_HOB_GUID_TYPE *GuidHob;
EFI_VECTOR_HANDOFF_INFO *VectorInfoList;
EFI_VECTOR_HANDOFF_INFO *VectorInfo;
VOID *EntryPoint;
EFI_STATUS Status;
EFI_PHYSICAL_ADDRESS MemoryBaseAddress;
UINT64 MemoryLength;
UEFI_IMAGE_LOADER_IMAGE_CONTEXT ImageContext;
UINTN Index;
EFI_HOB_GUID_TYPE *GuidHob;
EFI_VECTOR_HANDOFF_INFO *VectorInfoList;
EFI_VECTOR_HANDOFF_INFO *VectorInfo;
//
// Setup the default exception handlers
@ -274,14 +273,14 @@ DxeMain (
//
CoreInitializeMemoryServices (&HobStart, &MemoryBaseAddress, &MemoryLength);
MemoryProfileInit (HobStart);
//
// Start the Image Services.
//
Status = CoreInitializeImageServices (HobStart);
Status = CoreInitializeImageServices (HobStart, &ImageContext);
ASSERT_EFI_ERROR (Status);
MemoryProfileInit (HobStart, &ImageContext);
//
// Initialize the Global Coherency Domain Services
//
@ -327,19 +326,9 @@ DxeMain (
//
// Report DXE Core image information to the PE/COFF Extra Action Library
// FIXME: This is done by DxeIpl, why is this needed here? Difference PEI/DXE?
//
ZeroMem (&ImageContext, sizeof (ImageContext));
ImageContext.ImageAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)gDxeCoreLoadedImage->ImageBase;
ImageContext.PdbPointer = PeCoffLoaderGetPdbPointer ((VOID *)(UINTN)ImageContext.ImageAddress);
ImageContext.SizeOfHeaders = PeCoffGetSizeOfHeaders ((VOID *)(UINTN)ImageContext.ImageAddress);
Status = PeCoffLoaderGetEntryPoint ((VOID *)(UINTN)ImageContext.ImageAddress, &EntryPoint);
if (Status == EFI_SUCCESS) {
ImageContext.EntryPoint = (EFI_PHYSICAL_ADDRESS)(UINTN)EntryPoint;
}
ImageContext.Handle = (VOID *)(UINTN)gDxeCoreLoadedImage->ImageBase;
ImageContext.ImageRead = PeCoffLoaderImageReadFromMemory;
PeCoffLoaderRelocateImageExtraAction (&ImageContext);
UefiImageLoaderRelocateImageExtraAction (&ImageContext);
//
// Install the DXE Services Table into the EFI System Tables's Configuration Table
@ -386,7 +375,8 @@ DxeMain (
CoreNewDebugImageInfoEntry (
EFI_DEBUG_IMAGE_INFO_TYPE_NORMAL,
gDxeCoreLoadedImage,
gDxeCoreImageHandle
gDxeCoreImageHandle,
&ImageContext
);
DEBUG ((DEBUG_INFO | DEBUG_LOAD, "HOBLIST address in DXE = 0x%p\n", HobStart));

File diff suppressed because it is too large Load Diff

View File

@ -1528,7 +1528,7 @@ PromoteGuardedFreePages (
OUT EFI_PHYSICAL_ADDRESS *EndAddress
)
{
EFI_STATUS Status;
EFI_STATUS Status;
UINTN AvailablePages;
UINT64 Bitmap;
EFI_PHYSICAL_ADDRESS Start;

View File

@ -8,6 +8,10 @@
#include "DxeMain.h"
#include "Imem.h"
#include "Library/UefiImageLib.h"
#include "ProcessorBind.h"
#include "Protocol/LoadedImage.h"
#include "Uefi/UefiBaseType.h"
#define IS_UEFI_MEMORY_PROFILE_ENABLED ((PcdGet8 (PcdMemoryProfilePropertyMask) & BIT0) != 0)
@ -104,8 +108,7 @@ EFIAPI
ProfileProtocolRegisterImage (
IN EDKII_MEMORY_PROFILE_PROTOCOL *This,
IN EFI_DEVICE_PATH_PROTOCOL *FilePath,
IN PHYSICAL_ADDRESS ImageBase,
IN UINT64 ImageSize,
IN UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext,
IN EFI_FV_FILETYPE FileType
);
@ -247,110 +250,6 @@ GetMemoryProfileContext (
return mMemoryProfileContextPtr;
}
/**
Retrieves and returns the Subsystem of a PE/COFF image that has been loaded into system memory.
If Pe32Data is NULL, then ASSERT().
@param Pe32Data The pointer to the PE/COFF image that is loaded in system memory.
@return The Subsystem of the PE/COFF image.
**/
UINT16
InternalPeCoffGetSubsystem (
IN VOID *Pe32Data
)
{
EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr;
EFI_IMAGE_DOS_HEADER *DosHdr;
UINT16 Magic;
ASSERT (Pe32Data != NULL);
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) {
return Hdr.Te->Subsystem;
} else if (Hdr.Pe32->Signature == EFI_IMAGE_NT_SIGNATURE) {
Magic = Hdr.Pe32->OptionalHeader.Magic;
if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
return Hdr.Pe32->OptionalHeader.Subsystem;
} else if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) {
return Hdr.Pe32Plus->OptionalHeader.Subsystem;
}
}
return 0x0000;
}
/**
Retrieves and returns a pointer to the entry point to a PE/COFF image that has been loaded
into system memory with the PE/COFF Loader Library functions.
Retrieves the entry point to the PE/COFF image specified by Pe32Data and returns this entry
point in EntryPoint. If the entry point could not be retrieved from the PE/COFF image, then
return RETURN_INVALID_PARAMETER. Otherwise return RETURN_SUCCESS.
If Pe32Data is NULL, then ASSERT().
If EntryPoint is NULL, then ASSERT().
@param Pe32Data The pointer to the PE/COFF image that is loaded in system memory.
@param EntryPoint The pointer to entry point to the PE/COFF image to return.
@retval RETURN_SUCCESS EntryPoint was returned.
@retval RETURN_INVALID_PARAMETER The entry point could not be found in the PE/COFF image.
**/
RETURN_STATUS
InternalPeCoffGetEntryPoint (
IN VOID *Pe32Data,
OUT VOID **EntryPoint
)
{
EFI_IMAGE_DOS_HEADER *DosHdr;
EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr;
ASSERT (Pe32Data != NULL);
ASSERT (EntryPoint != NULL);
DosHdr = (EFI_IMAGE_DOS_HEADER *)Pe32Data;
if (DosHdr->e_magic == EFI_IMAGE_DOS_SIGNATURE) {
//
// DOS image header is present, so read the PE header after the DOS image header.
//
Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)((UINTN)Pe32Data + (UINTN)((DosHdr->e_lfanew) & 0x0ffff));
} else {
//
// DOS image header is not present, so PE header is at the image base.
//
Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)Pe32Data;
}
//
// Calculate the entry point relative to the start of the image.
// AddressOfEntryPoint is common for PE32 & PE32+
//
if (Hdr.Te->Signature == EFI_TE_IMAGE_HEADER_SIGNATURE) {
*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;
}
/**
Build driver info.
@ -367,32 +266,27 @@ InternalPeCoffGetEntryPoint (
**/
MEMORY_PROFILE_DRIVER_INFO_DATA *
BuildDriverInfo (
IN MEMORY_PROFILE_CONTEXT_DATA *ContextData,
IN EFI_GUID *FileName,
IN PHYSICAL_ADDRESS ImageBase,
IN UINT64 ImageSize,
IN PHYSICAL_ADDRESS EntryPoint,
IN UINT16 ImageSubsystem,
IN EFI_FV_FILETYPE FileType
IN MEMORY_PROFILE_CONTEXT_DATA *ContextData,
IN EFI_GUID *FileName,
IN UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext,
IN EFI_FV_FILETYPE FileType
)
{
RETURN_STATUS PdbStatus;
EFI_STATUS Status;
MEMORY_PROFILE_DRIVER_INFO *DriverInfo;
MEMORY_PROFILE_DRIVER_INFO_DATA *DriverInfoData;
VOID *EntryPointInImage;
CHAR8 *PdbString;
UINTN PdbSize;
CONST CHAR8 *PdbString;
UINT32 PdbSize;
UINTN PdbOccupiedSize;
PdbSize = 0;
PdbOccupiedSize = 0;
PdbString = NULL;
if (ImageBase != 0) {
PdbString = PeCoffLoaderGetPdbPointer ((VOID *)(UINTN)ImageBase);
if (PdbString != NULL) {
PdbSize = AsciiStrSize (PdbString);
PdbOccupiedSize = GET_OCCUPIED_SIZE (PdbSize, sizeof (UINT64));
}
ASSERT (UefiImageLoaderGetImageAddress (ImageContext) != 0);
PdbStatus = UefiImageGetSymbolsPath (ImageContext, &PdbString, &PdbSize);
if (!EFI_ERROR (PdbStatus)) {
PdbOccupiedSize = GET_OCCUPIED_SIZE (PdbSize, sizeof (UINT64));
}
//
@ -420,19 +314,10 @@ BuildDriverInfo (
CopyMem (&DriverInfo->FileName, FileName, sizeof (EFI_GUID));
}
DriverInfo->ImageBase = ImageBase;
DriverInfo->ImageSize = ImageSize;
DriverInfo->EntryPoint = EntryPoint;
DriverInfo->ImageSubsystem = ImageSubsystem;
if ((EntryPoint != 0) && ((EntryPoint < ImageBase) || (EntryPoint >= (ImageBase + ImageSize)))) {
//
// If the EntryPoint is not in the range of image buffer, it should come from emulation environment.
// So patch ImageBuffer here to align the EntryPoint.
//
Status = InternalPeCoffGetEntryPoint ((VOID *)(UINTN)ImageBase, &EntryPointInImage);
ASSERT_EFI_ERROR (Status);
DriverInfo->ImageBase = ImageBase + EntryPoint - (PHYSICAL_ADDRESS)(UINTN)EntryPointInImage;
}
DriverInfo->ImageBase = UefiImageLoaderGetImageAddress (ImageContext);
DriverInfo->ImageSize = UefiImageGetImageSize (ImageContext);
DriverInfo->EntryPoint = UefiImageLoaderGetImageEntryPoint (ImageContext);
DriverInfo->ImageSubsystem = UefiImageGetSubsystem (ImageContext);
DriverInfo->FileType = FileType;
DriverInfoData->AllocInfoList = (LIST_ENTRY *)(DriverInfoData + 1);
@ -440,7 +325,7 @@ BuildDriverInfo (
DriverInfo->CurrentUsage = 0;
DriverInfo->PeakUsage = 0;
DriverInfo->AllocRecordCount = 0;
if (PdbSize != 0) {
if (!RETURN_ERROR (PdbStatus)) {
DriverInfo->PdbStringOffset = (UINT16)sizeof (MEMORY_PROFILE_DRIVER_INFO);
DriverInfoData->PdbString = (CHAR8 *)(DriverInfoData->AllocInfoList + 1);
CopyMem (DriverInfoData->PdbString, PdbString, PdbSize);
@ -528,13 +413,13 @@ NeedRecordThisDriver (
**/
BOOLEAN
RegisterDxeCore (
IN VOID *HobStart,
IN MEMORY_PROFILE_CONTEXT_DATA *ContextData
IN VOID *HobStart,
IN UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext,
IN MEMORY_PROFILE_CONTEXT_DATA *ContextData
)
{
EFI_PEI_HOB_POINTERS DxeCoreHob;
MEMORY_PROFILE_DRIVER_INFO_DATA *DriverInfoData;
PHYSICAL_ADDRESS ImageBase;
UINT8 TempBuffer[sizeof (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH) + sizeof (EFI_DEVICE_PATH_PROTOCOL)];
MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *FilePath;
@ -565,14 +450,10 @@ RegisterDxeCore (
return FALSE;
}
ImageBase = DxeCoreHob.MemoryAllocationModule->MemoryAllocationHeader.MemoryBaseAddress;
DriverInfoData = BuildDriverInfo (
ContextData,
&DxeCoreHob.MemoryAllocationModule->ModuleName,
ImageBase,
DxeCoreHob.MemoryAllocationModule->MemoryAllocationHeader.MemoryLength,
DxeCoreHob.MemoryAllocationModule->EntryPoint,
InternalPeCoffGetSubsystem ((VOID *)(UINTN)ImageBase),
ImageContext,
EFI_FV_FILETYPE_DXE_CORE
);
if (DriverInfoData == NULL) {
@ -590,7 +471,8 @@ RegisterDxeCore (
**/
VOID
MemoryProfileInit (
IN VOID *HobStart
IN VOID *HobStart,
IN UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext
)
{
MEMORY_PROFILE_CONTEXT_DATA *ContextData;
@ -615,7 +497,7 @@ MemoryProfileInit (
mMemoryProfileDriverPath = AllocateCopyPool (mMemoryProfileDriverPathSize, PcdGetPtr (PcdMemoryProfileDriverPath));
mMemoryProfileContextPtr = &mMemoryProfileContext;
RegisterDxeCore (HobStart, &mMemoryProfileContext);
RegisterDxeCore (HobStart, ImageContext, &mMemoryProfileContext);
DEBUG ((DEBUG_INFO, "MemoryProfileInit MemoryProfileContext - 0x%x\n", &mMemoryProfileContext));
}
@ -692,8 +574,9 @@ GetFileNameFromFilePath (
**/
EFI_STATUS
RegisterMemoryProfileImage (
IN LOADED_IMAGE_PRIVATE_DATA *DriverEntry,
IN EFI_FV_FILETYPE FileType
IN EFI_DEVICE_PATH_PROTOCOL *FilePath,
IN EFI_FV_FILETYPE FileType,
IN UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext
)
{
MEMORY_PROFILE_CONTEXT_DATA *ContextData;
@ -703,7 +586,7 @@ RegisterMemoryProfileImage (
return EFI_UNSUPPORTED;
}
if (!NeedRecordThisDriver (DriverEntry->Info.FilePath)) {
if (!NeedRecordThisDriver (FilePath)) {
return EFI_UNSUPPORTED;
}
@ -714,11 +597,8 @@ RegisterMemoryProfileImage (
DriverInfoData = BuildDriverInfo (
ContextData,
GetFileNameFromFilePath (DriverEntry->Info.FilePath),
DriverEntry->ImageContext.ImageAddress,
DriverEntry->ImageContext.ImageSize,
DriverEntry->ImageContext.EntryPoint,
DriverEntry->ImageContext.ImageType,
GetFileNameFromFilePath (FilePath),
ImageContext,
FileType
);
if (DriverInfoData == NULL) {
@ -831,21 +711,21 @@ GetMemoryProfileDriverInfoFromAddress (
**/
EFI_STATUS
UnregisterMemoryProfileImage (
IN LOADED_IMAGE_PRIVATE_DATA *DriverEntry
EFI_DEVICE_PATH_PROTOCOL *FilePath,
IN EFI_PHYSICAL_ADDRESS ImageAddress
)
{
EFI_STATUS Status;
//EFI_STATUS Status;
MEMORY_PROFILE_CONTEXT_DATA *ContextData;
MEMORY_PROFILE_DRIVER_INFO_DATA *DriverInfoData;
EFI_GUID *FileName;
PHYSICAL_ADDRESS ImageAddress;
VOID *EntryPointInImage;
//VOID *EntryPointInImage;
if (!IS_UEFI_MEMORY_PROFILE_ENABLED) {
return EFI_UNSUPPORTED;
}
if (!NeedRecordThisDriver (DriverEntry->Info.FilePath)) {
if (!NeedRecordThisDriver (FilePath)) {
return EFI_UNSUPPORTED;
}
@ -855,17 +735,7 @@ UnregisterMemoryProfileImage (
}
DriverInfoData = NULL;
FileName = GetFileNameFromFilePath (DriverEntry->Info.FilePath);
ImageAddress = DriverEntry->ImageContext.ImageAddress;
if ((DriverEntry->ImageContext.EntryPoint < ImageAddress) || (DriverEntry->ImageContext.EntryPoint >= (ImageAddress + DriverEntry->ImageContext.ImageSize))) {
//
// If the EntryPoint is not in the range of image buffer, it should come from emulation environment.
// So patch ImageAddress here to align the EntryPoint.
//
Status = InternalPeCoffGetEntryPoint ((VOID *)(UINTN)ImageAddress, &EntryPointInImage);
ASSERT_EFI_ERROR (Status);
ImageAddress = ImageAddress + (UINTN)DriverEntry->ImageContext.EntryPoint - (UINTN)EntryPointInImage;
}
FileName = GetFileNameFromFilePath (FilePath);
if (FileName != NULL) {
DriverInfoData = GetMemoryProfileDriverInfoByFileNameAndAddress (ContextData, FileName, ImageAddress);
@ -1629,27 +1499,13 @@ ProfileProtocolGetData (
EFI_STATUS
EFIAPI
ProfileProtocolRegisterImage (
IN EDKII_MEMORY_PROFILE_PROTOCOL *This,
IN EFI_DEVICE_PATH_PROTOCOL *FilePath,
IN PHYSICAL_ADDRESS ImageBase,
IN UINT64 ImageSize,
IN EFI_FV_FILETYPE FileType
IN EDKII_MEMORY_PROFILE_PROTOCOL *This,
IN EFI_DEVICE_PATH_PROTOCOL *FilePath,
IN UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext,
IN EFI_FV_FILETYPE FileType
)
{
EFI_STATUS Status;
LOADED_IMAGE_PRIVATE_DATA DriverEntry;
VOID *EntryPointInImage;
ZeroMem (&DriverEntry, sizeof (DriverEntry));
DriverEntry.Info.FilePath = FilePath;
DriverEntry.ImageContext.ImageAddress = ImageBase;
DriverEntry.ImageContext.ImageSize = ImageSize;
Status = InternalPeCoffGetEntryPoint ((VOID *)(UINTN)ImageBase, &EntryPointInImage);
ASSERT_EFI_ERROR (Status);
DriverEntry.ImageContext.EntryPoint = (PHYSICAL_ADDRESS)(UINTN)EntryPointInImage;
DriverEntry.ImageContext.ImageType = InternalPeCoffGetSubsystem ((VOID *)(UINTN)ImageBase);
return RegisterMemoryProfileImage (&DriverEntry, FileType);
return RegisterMemoryProfileImage (FilePath, FileType, ImageContext);
}
/**
@ -1675,19 +1531,7 @@ ProfileProtocolUnregisterImage (
IN UINT64 ImageSize
)
{
EFI_STATUS Status;
LOADED_IMAGE_PRIVATE_DATA DriverEntry;
VOID *EntryPointInImage;
ZeroMem (&DriverEntry, sizeof (DriverEntry));
DriverEntry.Info.FilePath = FilePath;
DriverEntry.ImageContext.ImageAddress = ImageBase;
DriverEntry.ImageContext.ImageSize = ImageSize;
Status = InternalPeCoffGetEntryPoint ((VOID *)(UINTN)ImageBase, &EntryPointInImage);
ASSERT_EFI_ERROR (Status);
DriverEntry.ImageContext.EntryPoint = (PHYSICAL_ADDRESS)(UINTN)EntryPointInImage;
return UnregisterMemoryProfileImage (&DriverEntry);
return UnregisterMemoryProfileImage (FilePath, ImageBase);
}
/**

View File

@ -160,15 +160,20 @@ CoreUpdateDebugTableCrc32 (
**/
VOID
CoreNewDebugImageInfoEntry (
IN UINT32 ImageInfoType,
IN EFI_LOADED_IMAGE_PROTOCOL *LoadedImage,
IN EFI_HANDLE ImageHandle
IN UINT32 ImageInfoType,
IN EFI_LOADED_IMAGE_PROTOCOL *LoadedImage,
IN EFI_HANDLE ImageHandle,
IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext
)
{
EFI_DEBUG_IMAGE_INFO *Table;
EFI_DEBUG_IMAGE_INFO *NewTable;
UINTN Index;
UINTN TableSize;
EFI_DEBUG_IMAGE_INFO *Table;
EFI_DEBUG_IMAGE_INFO *NewTable;
UINTN Index;
UINTN TableSize;
EFI_DEBUG_IMAGE_INFO_NORMAL *NormalImage;
RETURN_STATUS Status;
CONST CHAR8 *PdbPath;
UINT32 PdbPathSize;
//
// Set the flag indicating that we're in the process of updating the table.
@ -205,6 +210,15 @@ CoreNewDebugImageInfoEntry (
// Copy the old table into the new one
//
CopyMem (NewTable, Table, TableSize);
mDebugInfoTableHeader.EfiDebugImageInfoTable = NewTable;
//
// Set the first empty entry index to be the original max table entries.
//
Index = mMaxTableEntries;
//
// Enlarge the max table entries.
//
mMaxTableEntries += EFI_PAGE_SIZE / EFI_DEBUG_TABLE_ENTRY_SIZE;
//
// Free the old table
//
@ -212,32 +226,31 @@ CoreNewDebugImageInfoEntry (
//
// Update the table header
//
Table = NewTable;
mDebugInfoTableHeader.EfiDebugImageInfoTable = NewTable;
//
// Enlarge the max table entries and set the first empty entry index to
// be the original max table entries.
//
Index = mMaxTableEntries;
mMaxTableEntries += EFI_PAGE_SIZE / EFI_DEBUG_TABLE_ENTRY_SIZE;
Table = NewTable;
}
//
// Allocate data for new entry
//
Table[Index].NormalImage = AllocateZeroPool (sizeof (EFI_DEBUG_IMAGE_INFO_NORMAL));
if (Table[Index].NormalImage != NULL) {
NormalImage = AllocateZeroPool (sizeof (EFI_DEBUG_IMAGE_INFO_NORMAL));
if (NormalImage != NULL) {
//
// Update the entry
//
Table[Index].NormalImage->ImageInfoType = (UINT32)ImageInfoType;
Table[Index].NormalImage->LoadedImageProtocolInstance = LoadedImage;
Table[Index].NormalImage->ImageHandle = ImageHandle;
NormalImage->ImageInfoType = (UINT32)ImageInfoType;
NormalImage->LoadedImageProtocolInstance = LoadedImage;
NormalImage->ImageHandle = ImageHandle;
Status = UefiImageGetSymbolsPath (ImageContext, &PdbPath, &PdbPathSize);
if (!RETURN_ERROR (Status)) {
NormalImage->PdbPath = AllocateCopyPool (PdbPathSize, PdbPath);
}
//
// Increase the number of EFI_DEBUG_IMAGE_INFO elements and set the mDebugInfoTable in modified status.
//
mDebugInfoTableHeader.TableSize++;
mDebugInfoTableHeader.UpdateStatus |= EFI_DEBUG_IMAGE_INFO_TABLE_MODIFIED;
Table[Index].NormalImage = NormalImage;
mDebugInfoTableHeader.TableSize++;
}
mDebugInfoTableHeader.UpdateStatus &= ~EFI_DEBUG_IMAGE_INFO_UPDATE_IN_PROGRESS;
@ -254,8 +267,9 @@ CoreRemoveDebugImageInfoEntry (
EFI_HANDLE ImageHandle
)
{
EFI_DEBUG_IMAGE_INFO *Table;
UINTN Index;
EFI_DEBUG_IMAGE_INFO *Table;
UINTN Index;
EFI_DEBUG_IMAGE_INFO_NORMAL *NormalImage;
mDebugInfoTableHeader.UpdateStatus |= EFI_DEBUG_IMAGE_INFO_UPDATE_IN_PROGRESS;
@ -267,13 +281,19 @@ CoreRemoveDebugImageInfoEntry (
// Found a match. Free up the record, then NULL the pointer to indicate the slot
// is free.
//
CoreFreePool (Table[Index].NormalImage);
Table[Index].NormalImage = NULL;
NormalImage = Table[Index].NormalImage;
//
// Decrease the number of EFI_DEBUG_IMAGE_INFO elements and set the mDebugInfoTable in modified status.
//
mDebugInfoTableHeader.TableSize--;
mDebugInfoTableHeader.UpdateStatus |= EFI_DEBUG_IMAGE_INFO_TABLE_MODIFIED;
mDebugInfoTableHeader.TableSize--;
Table[Index].NormalImage = NULL;
if (NormalImage->PdbPath != NULL) {
FreePool (NormalImage->PdbPath);
}
CoreFreePool (NormalImage);
break;
}
}

View File

@ -22,6 +22,8 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#include "DxeMain.h"
#include "HeapGuard.h"
#include "IndustryStandard/PeImage2.h"
#include "ProcessorBind.h"
/**
This function for GetMemoryMap() with properties table capability.
@ -73,7 +75,7 @@ CoreGetMemoryMapWithSeparatedImageSection (
typedef struct {
UINT32 Signature;
UINTN ImageRecordCount;
UINTN CodeSegmentCountMax;
UINTN SectionCountMax;
LIST_ENTRY ImageRecordList;
} IMAGE_PROPERTIES_PRIVATE_DATA;
@ -201,7 +203,7 @@ InstallMemoryAttributesTable (
case EfiRuntimeServicesCode:
case EfiRuntimeServicesData:
CopyMem (MemoryAttributesEntry, MemoryMap, DescriptorSize);
MemoryAttributesEntry->Attribute &= (EFI_MEMORY_RO|EFI_MEMORY_XP|EFI_MEMORY_RUNTIME);
MemoryAttributesEntry->Attribute &= EFI_MEMORY_ACCESS_MASK | EFI_MEMORY_RUNTIME;
DEBUG ((DEBUG_VERBOSE, "Entry (0x%x)\n", MemoryAttributesEntry));
DEBUG ((DEBUG_VERBOSE, " Type - 0x%x\n", MemoryAttributesEntry->Type));
DEBUG ((DEBUG_VERBOSE, " PhysicalStart - 0x%016lx\n", MemoryAttributesEntry->PhysicalStart));
@ -284,15 +286,6 @@ InstallMemoryAttributesTableOnEndOfDxe (
{
mMemoryAttributesTableEndOfDxe = TRUE;
InstallMemoryAttributesTable ();
DEBUG_CODE_BEGIN ();
if ( mImagePropertiesPrivateData.ImageRecordCount > 0) {
DEBUG ((DEBUG_INFO, "DXE - Total Runtime Image Count: 0x%x\n", mImagePropertiesPrivateData.ImageRecordCount));
DEBUG ((DEBUG_INFO, "DXE - Dump Runtime Image Records:\n"));
DumpImageRecords (&mImagePropertiesPrivateData.ImageRecordList);
}
DEBUG_CODE_END ();
}
/**
@ -526,7 +519,11 @@ CoreGetMemoryMapWithSeparatedImageSection (
CoreAcquiremMemoryAttributesTableLock ();
AdditionalRecordCount = (2 * mImagePropertiesPrivateData.CodeSegmentCountMax + 3) * mImagePropertiesPrivateData.ImageRecordCount;
//
// Per image, there may be one additional trailer. There may be prefixed data
// (counted as the original entry).
//
AdditionalRecordCount = (mImagePropertiesPrivateData.SectionCountMax + 1) * mImagePropertiesPrivateData.ImageRecordCount;
OldMemoryMapSize = *MemoryMapSize;
Status = CoreGetMemoryMap (MemoryMapSize, MemoryMap, MapKey, DescriptorSize, DescriptorVersion);
@ -566,6 +563,68 @@ CoreGetMemoryMapWithSeparatedImageSection (
// Below functions are for ImageRecord
//
/**
Set MemoryAttributesTable according to PE/COFF image section alignment.
@param SectionAlignment PE/COFF section alignment
**/
STATIC
VOID
SetMemoryAttributesTableSectionAlignment (
IN UINT32 SectionAlignment
)
{
if (((SectionAlignment & (RUNTIME_PAGE_ALLOCATION_GRANULARITY - 1)) != 0) &&
mMemoryAttributesTableEnable)
{
DEBUG ((DEBUG_VERBOSE, "SetMemoryAttributesTableSectionAlignment - Clear\n"));
mMemoryAttributesTableEnable = FALSE;
}
}
/**
Sort image record based upon the ImageBase from low to high.
**/
STATIC
VOID
InsertSortImageRecord (
IN UEFI_IMAGE_RECORD *NewImageRecord
)
{
UEFI_IMAGE_RECORD *ImageRecord;
LIST_ENTRY *PrevImageRecordLink;
LIST_ENTRY *ImageRecordLink;
LIST_ENTRY *ImageRecordList;
ImageRecordList = &mImagePropertiesPrivateData.ImageRecordList;
PrevImageRecordLink = ImageRecordList;
for (
ImageRecordLink = GetFirstNode (ImageRecordList);
!IsNull (ImageRecordLink, ImageRecordList);
ImageRecordLink = GetNextNode (ImageRecordList, PrevImageRecordLink)
) {
ImageRecord = CR (
ImageRecordLink,
UEFI_IMAGE_RECORD,
Link,
UEFI_IMAGE_RECORD_SIGNATURE
);
if (NewImageRecord->StartAddress < ImageRecord->StartAddress) {
break;
}
PrevImageRecordLink = ImageRecordLink;
}
InsertHeadList (PrevImageRecordLink, &NewImageRecord->Link);
mImagePropertiesPrivateData.ImageRecordCount++;
if (mImagePropertiesPrivateData.SectionCountMax < NewImageRecord->NumSegments) {
mImagePropertiesPrivateData.SectionCountMax = NewImageRecord->NumSegments;
}
}
/**
Insert image record.
@ -573,13 +632,18 @@ CoreGetMemoryMapWithSeparatedImageSection (
**/
VOID
InsertImageRecord (
IN EFI_RUNTIME_IMAGE_ENTRY *RuntimeImage
IN LOADED_IMAGE_PRIVATE_DATA *Image,
IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext
)
{
EFI_STATUS Status;
IMAGE_PROPERTIES_RECORD *ImageRecord;
CHAR8 *PdbPointer;
UINT32 RequiredAlignment;
RETURN_STATUS PdbStatus;
EFI_RUNTIME_IMAGE_ENTRY *RuntimeImage;
UINT32 SectionAlignment;
UEFI_IMAGE_RECORD *ImageRecord;
CONST CHAR8 *PdbPointer;
UINT32 PdbSize;
RuntimeImage = Image->RuntimeData;
DEBUG ((DEBUG_VERBOSE, "InsertImageRecord - 0x%x\n", RuntimeImage));
@ -588,71 +652,85 @@ InsertImageRecord (
return;
}
ImageRecord = AllocatePool (sizeof (*ImageRecord));
if (ImageRecord == NULL) {
return;
}
DEBUG ((DEBUG_VERBOSE, "ImageRecordCount - 0x%x\n", mImagePropertiesPrivateData.ImageRecordCount));
InitializeListHead (&ImageRecord->Link);
InitializeListHead (&ImageRecord->CodeSegmentList);
PdbPointer = PeCoffLoaderGetPdbPointer ((VOID *)(UINTN)RuntimeImage->ImageBase);
if (PdbPointer != NULL) {
PdbStatus = UefiImageGetSymbolsPath (ImageContext, &PdbPointer, &PdbSize);
if (!EFI_ERROR (PdbStatus)) {
DEBUG ((DEBUG_VERBOSE, " Image - %a\n", PdbPointer));
}
RequiredAlignment = RUNTIME_PAGE_ALLOCATION_GRANULARITY;
Status = CreateImagePropertiesRecord (
RuntimeImage->ImageBase,
RuntimeImage->ImageSize,
&RequiredAlignment,
ImageRecord
);
//
// Get SectionAlignment
//
SectionAlignment = UefiImageGetSegmentAlignment (ImageContext);
if (EFI_ERROR (Status)) {
if (Status == EFI_ABORTED) {
mMemoryAttributesTableEnable = FALSE;
SetMemoryAttributesTableSectionAlignment (SectionAlignment);
if ((SectionAlignment & (RUNTIME_PAGE_ALLOCATION_GRANULARITY - 1)) != 0) {
DEBUG ((
DEBUG_WARN,
"!!!!!!!! InsertImageRecord - Section Alignment(0x%x) is not %dK !!!!!!!!\n",
SectionAlignment, RUNTIME_PAGE_ALLOCATION_GRANULARITY >> 10));
if (!EFI_ERROR (PdbStatus)) {
DEBUG ((DEBUG_WARN, "!!!!!!!! Image - %a !!!!!!!!\n", PdbPointer));
}
Status = EFI_ABORTED;
goto Finish;
return;
}
if (ImageRecord->CodeSegmentCount == 0) {
mMemoryAttributesTableEnable = FALSE;
DEBUG ((DEBUG_ERROR, "!!!!!!!! InsertImageRecord - CodeSegmentCount is 0 !!!!!!!!\n"));
if (PdbPointer != NULL) {
DEBUG ((DEBUG_ERROR, "!!!!!!!! Image - %a !!!!!!!!\n", PdbPointer));
ImageRecord = UefiImageLoaderGetImageRecord (ImageContext);
if (ImageRecord == NULL) {
return ;
}
UefiImageDebugPrintSegments (ImageContext);
UefiImageDebugPrintImageRecord (ImageRecord);
//
// Section order is guaranteed by the PE specification.
// Section validity (e.g. no overlap) is guaranteed by the PE specification.
//
InsertSortImageRecord (ImageRecord);
}
/**
Find image record according to image base and size.
@param ImageBase Base of PE image
@param ImageSize Size of PE image
@return image record
**/
STATIC
UEFI_IMAGE_RECORD *
FindImageRecord (
IN EFI_PHYSICAL_ADDRESS ImageBase
)
{
UEFI_IMAGE_RECORD *ImageRecord;
LIST_ENTRY *ImageRecordLink;
LIST_ENTRY *ImageRecordList;
ImageRecordList = &mImagePropertiesPrivateData.ImageRecordList;
for (ImageRecordLink = ImageRecordList->ForwardLink;
ImageRecordLink != ImageRecordList;
ImageRecordLink = ImageRecordLink->ForwardLink)
{
ImageRecord = CR (
ImageRecordLink,
UEFI_IMAGE_RECORD,
Link,
UEFI_IMAGE_RECORD_SIGNATURE
);
if (ImageBase == ImageRecord->StartAddress)
{
return ImageRecord;
}
Status = EFI_ABORTED;
goto Finish;
}
//
// Check overlap all section in ImageBase/Size
//
if (!IsImageRecordCodeSectionValid (ImageRecord)) {
DEBUG ((DEBUG_ERROR, "IsImageRecordCodeSectionValid - FAIL\n"));
Status = EFI_ABORTED;
goto Finish;
}
InsertTailList (&mImagePropertiesPrivateData.ImageRecordList, &ImageRecord->Link);
mImagePropertiesPrivateData.ImageRecordCount++;
if (mImagePropertiesPrivateData.CodeSegmentCountMax < ImageRecord->CodeSegmentCount) {
mImagePropertiesPrivateData.CodeSegmentCountMax = ImageRecord->CodeSegmentCount;
}
SortImageRecord (&mImagePropertiesPrivateData.ImageRecordList);
Finish:
if (EFI_ERROR (Status) && (ImageRecord != NULL)) {
DeleteImagePropertiesRecord (ImageRecord);
}
return;
return NULL;
}
/**
@ -665,7 +743,7 @@ RemoveImageRecord (
IN EFI_RUNTIME_IMAGE_ENTRY *RuntimeImage
)
{
IMAGE_PROPERTIES_RECORD *ImageRecord;
UEFI_IMAGE_RECORD *ImageRecord;
DEBUG ((DEBUG_VERBOSE, "RemoveImageRecord - 0x%x\n", RuntimeImage));
DEBUG ((DEBUG_VERBOSE, "RemoveImageRecord - 0x%016lx - 0x%016lx\n", (EFI_PHYSICAL_ADDRESS)(UINTN)RuntimeImage->ImageBase, RuntimeImage->ImageSize));
@ -675,7 +753,7 @@ RemoveImageRecord (
return;
}
ImageRecord = FindImageRecord ((EFI_PHYSICAL_ADDRESS)(UINTN)RuntimeImage->ImageBase, RuntimeImage->ImageSize, &mImagePropertiesPrivateData.ImageRecordList);
ImageRecord = FindImageRecord ((EFI_PHYSICAL_ADDRESS)(UINTN)RuntimeImage->ImageBase);
if (ImageRecord == NULL) {
DEBUG ((DEBUG_ERROR, "!!!!!!!! ImageRecord not found !!!!!!!!\n"));
return;

View File

@ -40,8 +40,12 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#include <Protocol/FirmwareVolume2.h>
#include <Protocol/SimpleFileSystem.h>
#include "Base.h"
#include "DxeMain.h"
#include "Library/UefiImageLib.h"
#include "Mem/HeapGuard.h"
#include "ProcessorBind.h"
#include "Uefi/UefiMultiPhase.h"
//
// Image type definitions
@ -213,113 +217,73 @@ SetUefiImageMemoryAttributes (
**/
VOID
SetUefiImageProtectionAttributes (
IN IMAGE_PROPERTIES_RECORD *ImageRecord
IN UEFI_IMAGE_RECORD *ImageRecord
)
{
IMAGE_PROPERTIES_RECORD_CODE_SECTION *ImageRecordCodeSection;
LIST_ENTRY *ImageRecordCodeSectionLink;
LIST_ENTRY *ImageRecordCodeSectionEndLink;
LIST_ENTRY *ImageRecordCodeSectionList;
UINT64 CurrentBase;
UINT64 ImageEnd;
UEFI_IMAGE_RECORD_SEGMENT *ImageRecordSegment;
UINTN SectionAddress;
UINT32 Index;
ImageRecordCodeSectionList = &ImageRecord->CodeSegmentList;
CurrentBase = ImageRecord->ImageBase;
ImageEnd = ImageRecord->ImageBase + ImageRecord->ImageSize;
ImageRecordCodeSectionLink = ImageRecordCodeSectionList->ForwardLink;
ImageRecordCodeSectionEndLink = ImageRecordCodeSectionList;
while (ImageRecordCodeSectionLink != ImageRecordCodeSectionEndLink) {
ImageRecordCodeSection = CR (
ImageRecordCodeSectionLink,
IMAGE_PROPERTIES_RECORD_CODE_SECTION,
Link,
IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNATURE
);
ImageRecordCodeSectionLink = ImageRecordCodeSectionLink->ForwardLink;
ASSERT (CurrentBase <= ImageRecordCodeSection->CodeSegmentBase);
if (CurrentBase < ImageRecordCodeSection->CodeSegmentBase) {
//
// DATA
//
SetUefiImageMemoryAttributes (
CurrentBase,
ImageRecordCodeSection->CodeSegmentBase - CurrentBase,
EFI_MEMORY_XP
);
}
//
// CODE
//
SectionAddress = ImageRecord->StartAddress;
for (Index = 0; Index < ImageRecord->NumSegments; Index++) {
ImageRecordSegment = &ImageRecord->Segments[Index];
SetUefiImageMemoryAttributes (
ImageRecordCodeSection->CodeSegmentBase,
ImageRecordCodeSection->CodeSegmentSize,
EFI_MEMORY_RO
SectionAddress,
ImageRecordSegment->Size,
ImageRecordSegment->Attributes
);
CurrentBase = ImageRecordCodeSection->CodeSegmentBase + ImageRecordCodeSection->CodeSegmentSize;
}
//
// Last DATA
//
ASSERT (CurrentBase <= ImageEnd);
if (CurrentBase < ImageEnd) {
//
// DATA
//
SetUefiImageMemoryAttributes (
CurrentBase,
ImageEnd - CurrentBase,
EFI_MEMORY_XP
);
SectionAddress += ImageRecordSegment->Size;
}
return;
}
/**
Return the section alignment requirement for the PE image section type.
Return if the PE image section is aligned.
@param[in] MemoryType PE/COFF image memory type
@retval The required section alignment for this memory type
@param[in] SectionAlignment PE/COFF section alignment
@param[in] MemoryType PE/COFF image memory type
@retval TRUE The PE image section is aligned.
@retval FALSE The PE image section is not aligned.
**/
STATIC
UINT32
GetMemoryProtectionSectionAlignment (
BOOLEAN
IsMemoryProtectionSectionAligned (
IN UINT32 SectionAlignment,
IN EFI_MEMORY_TYPE MemoryType
)
{
UINT32 SectionAlignment;
UINT32 PageAlignment;
switch (MemoryType) {
case EfiRuntimeServicesCode:
case EfiACPIMemoryNVS:
case EfiReservedMemoryType:
SectionAlignment = RUNTIME_PAGE_ALLOCATION_GRANULARITY;
PageAlignment = RUNTIME_PAGE_ALLOCATION_GRANULARITY;
break;
case EfiRuntimeServicesData:
ASSERT (FALSE);
SectionAlignment = RUNTIME_PAGE_ALLOCATION_GRANULARITY;
PageAlignment = RUNTIME_PAGE_ALLOCATION_GRANULARITY;
break;
case EfiBootServicesCode:
case EfiLoaderCode:
SectionAlignment = EFI_PAGE_SIZE;
PageAlignment = EFI_PAGE_SIZE;
break;
case EfiACPIReclaimMemory:
default:
ASSERT (FALSE);
SectionAlignment = EFI_PAGE_SIZE;
PageAlignment = EFI_PAGE_SIZE;
break;
}
return SectionAlignment;
if ((SectionAlignment & (PageAlignment - 1)) != 0) {
return FALSE;
} else {
return TRUE;
}
}
// FIXME: Deduplicate
/**
Protect UEFI PE/COFF image.
@ -328,22 +292,26 @@ GetMemoryProtectionSectionAlignment (
**/
VOID
ProtectUefiImage (
IN EFI_LOADED_IMAGE_PROTOCOL *LoadedImage,
IN EFI_DEVICE_PATH_PROTOCOL *LoadedImageDevicePath
IN LOADED_IMAGE_PRIVATE_DATA *Image,
UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext
)
{
IMAGE_PROPERTIES_RECORD *ImageRecord;
UINT32 ProtectionPolicy;
EFI_STATUS Status;
UINT32 RequiredAlignment;
RETURN_STATUS PdbStatus;
EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;
EFI_DEVICE_PATH_PROTOCOL *LoadedImageDevicePath;
UINT32 SectionAlignment;
UEFI_IMAGE_RECORD *ImageRecord;
CONST CHAR8 *PdbPointer;
UINT32 PdbSize;
BOOLEAN IsAligned;
UINT32 ProtectionPolicy;
LoadedImage = &Image->Info;
LoadedImageDevicePath = Image->LoadedImageDevicePath;
DEBUG ((DEBUG_INFO, "ProtectUefiImageCommon - 0x%x\n", LoadedImage));
DEBUG ((DEBUG_INFO, " - 0x%016lx - 0x%016lx\n", (EFI_PHYSICAL_ADDRESS)(UINTN)LoadedImage->ImageBase, LoadedImage->ImageSize));
if (gCpu == NULL) {
return;
}
ProtectionPolicy = GetUefiImageProtectionPolicy (LoadedImage, LoadedImageDevicePath);
switch (ProtectionPolicy) {
case DO_NOT_PROTECT:
@ -355,36 +323,49 @@ ProtectUefiImage (
return;
}
ImageRecord = AllocateZeroPool (sizeof (*ImageRecord));
if (ImageRecord == NULL) {
return;
PdbStatus = UefiImageGetSymbolsPath (ImageContext, &PdbPointer, &PdbSize);
if (!RETURN_ERROR (PdbStatus)) {
DEBUG ((DEBUG_VERBOSE, " Image - %a\n", PdbPointer));
}
RequiredAlignment = GetMemoryProtectionSectionAlignment (LoadedImage->ImageCodeType);
//
// Get SectionAlignment
//
SectionAlignment = UefiImageGetSegmentAlignment (ImageContext);
Status = CreateImagePropertiesRecord (
LoadedImage->ImageBase,
LoadedImage->ImageSize,
&RequiredAlignment,
ImageRecord
);
IsAligned = IsMemoryProtectionSectionAligned (SectionAlignment, LoadedImage->ImageCodeType);
if (!IsAligned) {
DEBUG ((
DEBUG_VERBOSE,
"!!!!!!!! ProtectUefiImageCommon - Section Alignment(0x%x) is incorrect !!!!!!!!\n",
SectionAlignment));
if (!RETURN_ERROR (PdbStatus)) {
DEBUG ((DEBUG_VERBOSE, "!!!!!!!! Image - %a !!!!!!!!\n", PdbPointer));
}
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "%a failed to create image properties record\n", __func__));
FreePool (ImageRecord);
goto Finish;
}
//
// CPU ARCH present. Update memory attribute directly.
//
SetUefiImageProtectionAttributes (ImageRecord);
ImageRecord = UefiImageLoaderGetImageRecord (ImageContext);
if (ImageRecord == NULL) {
return ;
}
UefiImageDebugPrintSegments (ImageContext);
UefiImageDebugPrintImageRecord (ImageRecord);
//
// Record the image record in the list so we can undo the protections later
//
InsertTailList (&mProtectedImageRecordList, &ImageRecord->Link);
if (gCpu != NULL) {
//
// CPU ARCH present. Update memory attribute directly.
//
SetUefiImageProtectionAttributes (ImageRecord);
}
Finish:
return;
}
@ -401,30 +382,31 @@ UnprotectUefiImage (
IN EFI_DEVICE_PATH_PROTOCOL *LoadedImageDevicePath
)
{
IMAGE_PROPERTIES_RECORD *ImageRecord;
LIST_ENTRY *ImageRecordLink;
UEFI_IMAGE_RECORD *ImageRecord;
LIST_ENTRY *ImageRecordLink;
if (PcdGet32 (PcdImageProtectionPolicy) != 0) {
for (ImageRecordLink = mProtectedImageRecordList.ForwardLink;
ImageRecordLink != &mProtectedImageRecordList;
ImageRecordLink = ImageRecordLink->ForwardLink)
{
ImageRecord = CR (
ImageRecordLink,
IMAGE_PROPERTIES_RECORD,
Link,
IMAGE_PROPERTIES_RECORD_SIGNATURE
);
for (ImageRecordLink = mProtectedImageRecordList.ForwardLink;
ImageRecordLink != &mProtectedImageRecordList;
ImageRecordLink = ImageRecordLink->ForwardLink) {
ImageRecord = CR (
ImageRecordLink,
UEFI_IMAGE_RECORD,
Link,
UEFI_IMAGE_RECORD_SIGNATURE
);
if (ImageRecord->ImageBase == (EFI_PHYSICAL_ADDRESS)(UINTN)LoadedImage->ImageBase) {
if (ImageRecord->StartAddress == (EFI_PHYSICAL_ADDRESS)(UINTN)LoadedImage->ImageBase) {
// TODO: Revise for removal (e.g. CpuDxe integration)
if (gCpu != NULL) {
SetUefiImageMemoryAttributes (
ImageRecord->ImageBase,
ImageRecord->ImageSize,
ImageRecord->StartAddress,
ImageRecord->EndAddress - ImageRecord->StartAddress,
0
);
DeleteImagePropertiesRecord (ImageRecord);
return;
}
RemoveEntryList (&ImageRecord->Link);
FreePool (ImageRecord);
return;
}
}
}
@ -567,7 +549,6 @@ MergeMemoryMapForProtectionPolicy (
Remove exec permissions from all regions whose type is identified by
PcdDxeNxMemoryProtectionPolicy.
**/
STATIC
VOID
InitializeDxeNxMemoryProtectionPolicy (
VOID
@ -775,12 +756,9 @@ MemoryProtectionCpuArchProtocolNotify (
IN VOID *Context
)
{
EFI_STATUS Status;
EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;
EFI_DEVICE_PATH_PROTOCOL *LoadedImageDevicePath;
UINTN NoHandles;
EFI_HANDLE *HandleBuffer;
UINTN Index;
EFI_STATUS Status;
LIST_ENTRY *ImageRecordLink;
UEFI_IMAGE_RECORD *ImageRecord;
DEBUG ((DEBUG_INFO, "MemoryProtectionCpuArchProtocolNotify:\n"));
Status = CoreLocateProtocol (&gEfiCpuArchProtocolGuid, NULL, (VOID **)&gCpu);
@ -804,41 +782,22 @@ MemoryProtectionCpuArchProtocolNotify (
goto Done;
}
Status = gBS->LocateHandleBuffer (
ByProtocol,
&gEfiLoadedImageProtocolGuid,
NULL,
&NoHandles,
&HandleBuffer
);
if (EFI_ERROR (Status) && (NoHandles == 0)) {
goto Done;
}
for (Index = 0; Index < NoHandles; Index++) {
Status = gBS->HandleProtocol (
HandleBuffer[Index],
&gEfiLoadedImageProtocolGuid,
(VOID **)&LoadedImage
for (ImageRecordLink = mProtectedImageRecordList.ForwardLink;
ImageRecordLink != &mProtectedImageRecordList;
ImageRecordLink = ImageRecordLink->ForwardLink) {
ImageRecord = CR (
ImageRecordLink,
UEFI_IMAGE_RECORD,
Link,
UEFI_IMAGE_RECORD_SIGNATURE
);
if (EFI_ERROR (Status)) {
continue;
}
Status = gBS->HandleProtocol (
HandleBuffer[Index],
&gEfiLoadedImageDevicePathProtocolGuid,
(VOID **)&LoadedImageDevicePath
);
if (EFI_ERROR (Status)) {
LoadedImageDevicePath = NULL;
}
ProtectUefiImage (LoadedImage, LoadedImageDevicePath);
//
// CPU ARCH present. Update memory attribute directly.
//
SetUefiImageProtectionAttributes (ImageRecord);
}
FreePool (HandleBuffer);
Done:
CoreCloseEvent (Event);
}

View File

@ -8,6 +8,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include "PeiMain.h"
#include "ProcessorBind.h"
/**
@ -1009,8 +1010,7 @@ MigratePeim (
EFI_FFS_FILE_HEADER *FileHeader;
VOID *Pe32Data;
VOID *ImageAddress;
CHAR8 *AsciiString;
UINTN Index;
UINT32 ImageSize;
Status = EFI_SUCCESS;
@ -1018,24 +1018,10 @@ MigratePeim (
ASSERT (!IS_FFS_FILE2 (FileHeader));
ImageAddress = NULL;
PeiGetPe32Data (MigratedFileHandle, &ImageAddress);
PeiGetPe32Data (MigratedFileHandle, &ImageAddress, &ImageSize);
if (ImageAddress != NULL) {
DEBUG_CODE_BEGIN ();
AsciiString = PeCoffLoaderGetPdbPointer (ImageAddress);
for (Index = 0; AsciiString[Index] != 0; Index++) {
if ((AsciiString[Index] == '\\') || (AsciiString[Index] == '/')) {
AsciiString = AsciiString + Index + 1;
Index = 0;
} else if (AsciiString[Index] == '.') {
AsciiString[Index] = 0;
}
}
DEBUG ((DEBUG_VERBOSE, "%a", AsciiString));
DEBUG_CODE_END ();
Pe32Data = (VOID *)((UINTN)ImageAddress - (UINTN)MigratedFileHandle + (UINTN)FileHandle);
Status = LoadAndRelocatePeCoffImageInPlace (Pe32Data, ImageAddress);
Status = LoadAndRelocateUefiImageInPlace (Pe32Data, ImageAddress, ImageSize);
ASSERT_EFI_ERROR (Status);
}
@ -1097,6 +1083,104 @@ ConvertStatusCodeCallbacks (
}
}
/**
Migrates SEC modules in the given firmware volume.
Migrating SECURITY_CORE files requires special treatment since they are not tracked for PEI dispatch.
This functioun should be called after the FV has been copied to its post-memory location and the PEI Core FV list has
been updated.
@param Private Pointer to the PeiCore's private data structure.
@param FvIndex The firmware volume index to migrate.
@param OrgFvHandle The handle to the firmware volume in temporary memory.
@retval EFI_SUCCESS SEC modules were migrated successfully
@retval EFI_INVALID_PARAMETER The Private pointer is NULL or FvCount is invalid.
@retval EFI_NOT_FOUND Can't find valid FFS header.
**/
EFI_STATUS
EFIAPI
MigrateSecModulesInFv (
IN PEI_CORE_INSTANCE *Private,
IN UINTN FvIndex,
IN UINTN OrgFvHandle
)
{
EFI_STATUS Status;
EFI_STATUS FindFileStatus;
EFI_PEI_FILE_HANDLE MigratedFileHandle;
EFI_PEI_FILE_HANDLE FileHandle;
UINT32 SectionAuthenticationStatus;
UINT32 FileSize;
VOID *OrgPe32SectionData;
VOID *Pe32SectionData;
UINT32 Pe32SectionDataSize;
EFI_FFS_FILE_HEADER *FfsFileHeader;
EFI_COMMON_SECTION_HEADER *Section;
BOOLEAN IsFfs3Fv;
UINTN SectionInstance;
if (Private == NULL || FvIndex >= Private->FvCount) {
return EFI_INVALID_PARAMETER;
}
do {
FindFileStatus = PeiFfsFindNextFile (
GetPeiServicesTablePointer (),
EFI_FV_FILETYPE_SECURITY_CORE,
Private->Fv[FvIndex].FvHandle,
&MigratedFileHandle
);
if (!EFI_ERROR (FindFileStatus ) && MigratedFileHandle != NULL) {
FileHandle = (EFI_PEI_FILE_HANDLE) ((UINTN) MigratedFileHandle - (UINTN) Private->Fv[FvIndex].FvHandle + OrgFvHandle);
FfsFileHeader = (EFI_FFS_FILE_HEADER *) MigratedFileHandle;
DEBUG ((DEBUG_VERBOSE, " Migrating SEC_CORE MigratedFileHandle at 0x%x.\n", (UINTN) MigratedFileHandle));
DEBUG ((DEBUG_VERBOSE, " FileHandle at 0x%x.\n", (UINTN) FileHandle));
IsFfs3Fv = CompareGuid (&Private->Fv[FvIndex].FvHeader->FileSystemGuid, &gEfiFirmwareFileSystem3Guid);
if (IS_FFS_FILE2 (FfsFileHeader)) {
ASSERT (FFS_FILE2_SIZE (FfsFileHeader) > 0x00FFFFFF);
if (!IsFfs3Fv) {
DEBUG ((DEBUG_ERROR, "It is a FFS3 formatted file: %g in a non-FFS3 formatted FV.\n", &FfsFileHeader->Name));
return EFI_NOT_FOUND;
}
Section = (EFI_COMMON_SECTION_HEADER *) ((UINT8 *) FfsFileHeader + sizeof (EFI_FFS_FILE_HEADER2));
FileSize = FFS_FILE2_SIZE (FfsFileHeader) - sizeof (EFI_FFS_FILE_HEADER2);
} else {
Section = (EFI_COMMON_SECTION_HEADER *) ((UINT8 *) FfsFileHeader + sizeof (EFI_FFS_FILE_HEADER));
FileSize = FFS_FILE_SIZE (FfsFileHeader) - sizeof (EFI_FFS_FILE_HEADER);
}
SectionInstance = 1;
SectionAuthenticationStatus = 0;
Status = ProcessSection (
GetPeiServicesTablePointer (),
EFI_SECTION_PE32,
&SectionInstance,
Section,
FileSize,
&Pe32SectionData,
&Pe32SectionDataSize,
&SectionAuthenticationStatus,
IsFfs3Fv
);
if (!EFI_ERROR (Status)) {
OrgPe32SectionData = (VOID *) ((UINTN) Pe32SectionData - (UINTN) MigratedFileHandle + (UINTN) FileHandle);
DEBUG ((DEBUG_VERBOSE, " PE32 section in migrated file at 0x%x.\n", (UINTN) Pe32SectionData));
DEBUG ((DEBUG_VERBOSE, " PE32 section in original file at 0x%x.\n", (UINTN) OrgPe32SectionData));
Status = LoadAndRelocateUefiImageInPlace (OrgPe32SectionData, Pe32SectionData, Pe32SectionDataSize);
ASSERT_EFI_ERROR (Status);
}
}
} while (!EFI_ERROR (FindFileStatus));
return EFI_SUCCESS;
}
/**
Migrates PEIMs in the given firmware volume.

View File

@ -35,7 +35,8 @@ PEI_FW_VOL_INSTANCE mPeiFfs2FwVol = {
PeiFfsFvPpiGetFileInfo2,
PeiFfsFvPpiFindSectionByType2,
EFI_PEI_FIRMWARE_VOLUME_PPI_SIGNATURE,
EFI_PEI_FIRMWARE_VOLUME_PPI_REVISION
EFI_PEI_FIRMWARE_VOLUME_PPI_REVISION,
PeiFfsFvPpiFindSectionByType3
}
};
@ -52,7 +53,8 @@ PEI_FW_VOL_INSTANCE mPeiFfs3FwVol = {
PeiFfsFvPpiGetFileInfo2,
PeiFfsFvPpiFindSectionByType2,
EFI_PEI_FIRMWARE_VOLUME_PPI_SIGNATURE,
EFI_PEI_FIRMWARE_VOLUME_PPI_REVISION
EFI_PEI_FIRMWARE_VOLUME_PPI_REVISION,
PeiFfsFvPpiFindSectionByType3
}
};
@ -771,6 +773,8 @@ VerifyGuidedSectionGuid (
@param SectionSize The file size to search.
@param OutputBuffer A pointer to the discovered section, if successful.
NULL if section not found
@param OutputSize The size of the discovered section, if successful.
0 if section not found
@param AuthenticationStatus Updated upon return to point to the authentication status for this section.
@param IsFfs3Fv Indicates the FV format.
@ -786,6 +790,7 @@ ProcessSection (
IN EFI_COMMON_SECTION_HEADER *Section,
IN UINTN SectionSize,
OUT VOID **OutputBuffer,
OUT UINT32 *OutputSize,
OUT UINT32 *AuthenticationStatus,
IN BOOLEAN IsFfs3Fv
)
@ -803,11 +808,13 @@ ProcessSection (
EFI_GUID *SectionDefinitionGuid;
BOOLEAN SectionCached;
VOID *TempOutputBuffer;
UINT32 TempOutputSize;
UINT32 TempAuthenticationStatus;
UINT16 GuidedSectionAttributes;
PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);
*OutputBuffer = NULL;
*OutputSize = 0;
ParsedLength = 0;
Index = 0;
Status = EFI_NOT_FOUND;
@ -840,10 +847,13 @@ ProcessSection (
//
// Got it!
//
// FIXME: Size checks
if (IS_SECTION2 (Section)) {
*OutputBuffer = (VOID *)((UINT8 *)Section + sizeof (EFI_COMMON_SECTION_HEADER2));
*OutputSize = SECTION2_SIZE (Section) - sizeof (EFI_COMMON_SECTION_HEADER2);
} else {
*OutputBuffer = (VOID *)((UINT8 *)Section + sizeof (EFI_COMMON_SECTION_HEADER));
*OutputSize = SECTION_SIZE (Section) - sizeof (EFI_COMMON_SECTION_HEADER);
}
return EFI_SUCCESS;
@ -886,11 +896,13 @@ ProcessSection (
PpiOutput,
PpiOutputSize,
&TempOutputBuffer,
&TempOutputSize,
&TempAuthenticationStatus,
IsFfs3Fv
);
if (!EFI_ERROR (Status)) {
*OutputBuffer = TempOutputBuffer;
*OutputSize = TempOutputSize;
*AuthenticationStatus = TempAuthenticationStatus | Authentication;
return EFI_SUCCESS;
}
@ -973,11 +985,13 @@ ProcessSection (
PpiOutput,
PpiOutputSize,
&TempOutputBuffer,
&TempOutputSize,
&TempAuthenticationStatus,
IsFfs3Fv
);
if (!EFI_ERROR (Status)) {
*OutputBuffer = TempOutputBuffer;
*OutputSize = TempOutputSize;
*AuthenticationStatus = TempAuthenticationStatus | Authentication;
return EFI_SUCCESS;
}
@ -1060,6 +1074,38 @@ PeiFfsFindSectionData3 (
OUT VOID **SectionData,
OUT UINT32 *AuthenticationStatus
)
{
UINT32 SectionDataSize;
return PeiFfsFindSectionData4 (PeiServices, SectionType, SectionInstance, FileHandle, SectionData, &SectionDataSize, AuthenticationStatus);
}
/**
Searches for the next matching section within the specified file.
@param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
@param SectionType The value of the section type to find.
@param SectionInstance Section instance to find.
@param FileHandle Handle of the firmware file to search.
@param SectionData A pointer to the discovered section, if successful.
@param SectionDataSize The size of the discovered section, if successful.
@param AuthenticationStatus A pointer to the authentication status for this section.
@retval EFI_SUCCESS The section was found.
@retval EFI_NOT_FOUND The section was not found.
**/
EFI_STATUS
EFIAPI
PeiFfsFindSectionData4 (
IN CONST EFI_PEI_SERVICES **PeiServices,
IN EFI_SECTION_TYPE SectionType,
IN UINTN SectionInstance,
IN EFI_PEI_FILE_HANDLE FileHandle,
OUT VOID **SectionData,
OUT UINT32 *SectionDataSize,
OUT UINT32 *AuthenticationStatus
)
{
PEI_CORE_FV_HANDLE *CoreFvHandle;
@ -1071,7 +1117,7 @@ PeiFfsFindSectionData3 (
if ((CoreFvHandle->FvPpi->Signature == EFI_PEI_FIRMWARE_VOLUME_PPI_SIGNATURE) &&
(CoreFvHandle->FvPpi->Revision == EFI_PEI_FIRMWARE_VOLUME_PPI_REVISION))
{
return CoreFvHandle->FvPpi->FindSectionByType2 (CoreFvHandle->FvPpi, SectionType, SectionInstance, FileHandle, SectionData, AuthenticationStatus);
return CoreFvHandle->FvPpi->FindSectionByType3 (CoreFvHandle->FvPpi, SectionType, SectionInstance, FileHandle, SectionData, SectionDataSize, AuthenticationStatus);
}
//
@ -2028,6 +2074,57 @@ PeiFfsFvPpiFindSectionByType2 (
OUT VOID **SectionData,
OUT UINT32 *AuthenticationStatus
)
{
UINT32 SectionDataSize;
// FIXME: Deprecate
return PeiFfsFvPpiFindSectionByType3 (
This,
SearchType,
SearchInstance,
FileHandle,
SectionData,
&SectionDataSize,
AuthenticationStatus
);
}
/**
Find the next matching section in the firmware file.
This service enables PEI modules to discover sections
of a given instance and type within a valid file.
@param This Points to this instance of the
EFI_PEI_FIRMWARE_VOLUME_PPI.
@param SearchType A filter to find only sections of this
type.
@param SearchInstance A filter to find the specific instance
of sections.
@param FileHandle Handle of firmware file in which to
search.
@param SectionData Updated upon return to point to the
section found.
@param SectionDataSize Updated upon return to point to the
section size found.
@param AuthenticationStatus Updated upon return to point to the
authentication status for this section.
@retval EFI_SUCCESS Section was found.
@retval EFI_NOT_FOUND Section of the specified type was not
found. SectionData contains NULL.
**/
EFI_STATUS
EFIAPI
PeiFfsFvPpiFindSectionByType3 (
IN CONST EFI_PEI_FIRMWARE_VOLUME_PPI *This,
IN EFI_SECTION_TYPE SearchType,
IN UINTN SearchInstance,
IN EFI_PEI_FILE_HANDLE FileHandle,
OUT VOID **SectionData,
OUT UINT32 *SectionDataSize,
OUT UINT32 *AuthenticationStatus
)
{
EFI_STATUS Status;
EFI_FFS_FILE_HEADER *FfsFileHeader;
@ -2077,6 +2174,7 @@ PeiFfsFvPpiFindSectionByType2 (
Section,
FileSize,
SectionData,
SectionDataSize,
&ExtractedAuthenticationStatus,
FwVolInstance->IsFfs3Fv
);

View File

@ -185,6 +185,43 @@ PeiFfsFvPpiFindSectionByType2 (
OUT UINT32 *AuthenticationStatus
);
/**
Find the next matching section in the firmware file.
This service enables PEI modules to discover sections
of a given instance and type within a valid file.
@param This Points to this instance of the
EFI_PEI_FIRMWARE_VOLUME_PPI.
@param SearchType A filter to find only sections of this
type.
@param SearchInstance A filter to find the specific instance
of sections.
@param FileHandle Handle of firmware file in which to
search.
@param SectionData Updated upon return to point to the
section found.
@param SectionDataSize Updated upon return to point to the
section size found.
@param AuthenticationStatus Updated upon return to point to the
authentication status for this section.
@retval EFI_SUCCESS Section was found.
@retval EFI_NOT_FOUND Section of the specified type was not
found. SectionData contains NULL.
**/
EFI_STATUS
EFIAPI
PeiFfsFvPpiFindSectionByType3 (
IN CONST EFI_PEI_FIRMWARE_VOLUME_PPI *This,
IN EFI_SECTION_TYPE SearchType,
IN UINTN SearchInstance,
IN EFI_PEI_FILE_HANDLE FileHandle,
OUT VOID **SectionData,
OUT UINT32 *SectionDataSize,
OUT UINT32 *AuthenticationStatus
);
/**
Returns information about a specific file.

View File

@ -18,40 +18,6 @@ EFI_PEI_PPI_DESCRIPTOR gPpiLoadFilePpiList = {
&mPeiLoadImagePpi
};
/**
Support routine for the PE/COFF Loader that reads a buffer from a PE/COFF file.
The function is used for XIP code to have optimized memory copy.
@param FileHandle - The handle to the PE/COFF file
@param FileOffset - The offset, in bytes, into the file to read
@param ReadSize - The number of bytes to read from the file starting at FileOffset
@param Buffer - A pointer to the buffer to read the data into.
@return EFI_SUCCESS - ReadSize bytes of data were read into Buffer from the PE/COFF file starting at FileOffset
**/
EFI_STATUS
EFIAPI
PeiImageRead (
IN VOID *FileHandle,
IN UINTN FileOffset,
IN UINTN *ReadSize,
OUT VOID *Buffer
)
{
CHAR8 *Destination8;
CHAR8 *Source8;
Destination8 = Buffer;
Source8 = (CHAR8 *)((UINTN)FileHandle + FileOffset);
if (Destination8 != Source8) {
CopyMem (Destination8, Source8, *ReadSize);
}
return EFI_SUCCESS;
}
/**
To check memory usage bit map array to figure out if the memory range the image will be loaded in is available or not. If
memory range is available, the function will mark the corresponding bits to 1 which indicates the memory range is used.
@ -135,111 +101,36 @@ CheckAndMarkFixLoadingMemoryUsageBitMap (
**/
EFI_STATUS
GetPeCoffImageFixLoadingAssignedAddress (
IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext,
IN PEI_CORE_INSTANCE *Private
GetUefiImageFixLoadingAssignedAddress (
OUT EFI_PHYSICAL_ADDRESS *LoadAddress,
IN UINT64 ValueInSectionHeader,
IN UINT32 ImageDestSize,
IN PEI_CORE_INSTANCE *Private
)
{
UINTN SectionHeaderOffset;
EFI_STATUS Status;
EFI_IMAGE_SECTION_HEADER SectionHeader;
EFI_IMAGE_OPTIONAL_HEADER_UNION *ImgHdr;
EFI_PHYSICAL_ADDRESS FixLoadingAddress;
UINT16 Index;
UINTN Size;
UINT16 NumberOfSections;
UINT64 ValueInSectionHeader;
EFI_STATUS Status;
EFI_PHYSICAL_ADDRESS FixLoadingAddress;
FixLoadingAddress = 0;
Status = EFI_NOT_FOUND;
//
// Get PeHeader pointer
//
ImgHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)((CHAR8 *)ImageContext->Handle + ImageContext->PeCoffHeaderOffset);
if (ImageContext->IsTeImage) {
if ((INT64)PcdGet64(PcdLoadModuleAtFixAddressEnable) > 0) {
//
// for TE image, the fix loading address is saved in first section header that doesn't point
// to code section.
// When LMFA feature is configured as Load Module at Fixed Absolute Address mode, PointerToRelocations & PointerToLineNumbers field
// hold the absolute address of image base running in memory
//
SectionHeaderOffset = sizeof (EFI_TE_IMAGE_HEADER);
NumberOfSections = ImgHdr->Te.NumberOfSections;
FixLoadingAddress = ValueInSectionHeader;
} else {
SectionHeaderOffset = ImageContext->PeCoffHeaderOffset +
sizeof (UINT32) +
sizeof (EFI_IMAGE_FILE_HEADER) +
ImgHdr->Pe32.FileHeader.SizeOfOptionalHeader;
NumberOfSections = ImgHdr->Pe32.FileHeader.NumberOfSections;
}
//
// Get base address from the first section header that doesn't point to code section.
//
for (Index = 0; Index < NumberOfSections; Index++) {
//
// Read section header from file
// When LMFA feature is configured as Load Module at Fixed offset mode, PointerToRelocations & PointerToLineNumbers field
// hold the offset relative to a platform-specific top address.
//
Size = sizeof (EFI_IMAGE_SECTION_HEADER);
Status = ImageContext->ImageRead (
ImageContext->Handle,
SectionHeaderOffset,
&Size,
&SectionHeader
);
if (EFI_ERROR (Status)) {
return Status;
}
Status = EFI_NOT_FOUND;
if ((SectionHeader.Characteristics & EFI_IMAGE_SCN_CNT_CODE) == 0) {
//
// Build tool will save the address in PointerToRelocations & PointerToLineNumbers fields in the first section header
// that doesn't point to code section in image header, as well as ImageBase field of image header. A notable thing is
// that for PEIM, the value in ImageBase field may not be equal to the value in PointerToRelocations & PointerToLineNumbers because
// for XIP PEIM, ImageBase field holds the image base address running on the Flash. And PointerToRelocations & PointerToLineNumbers
// hold the image base address when it is shadow to the memory. And there is an assumption that when the feature is enabled, if a
// module is assigned a loading address by tools, PointerToRelocations & PointerToLineNumbers fields should NOT be Zero, or
// else, these 2 fields should be set to Zero
//
ValueInSectionHeader = ReadUnaligned64 ((UINT64 *)&SectionHeader.PointerToRelocations);
if (ValueInSectionHeader != 0) {
//
// Found first section header that doesn't point to code section.
//
if ((INT64)PcdGet64 (PcdLoadModuleAtFixAddressEnable) > 0) {
//
// When LMFA feature is configured as Load Module at Fixed Absolute Address mode, PointerToRelocations & PointerToLineNumbers field
// hold the absolute address of image base running in memory
//
FixLoadingAddress = ValueInSectionHeader;
} else {
//
// When LMFA feature is configured as Load Module at Fixed offset mode, PointerToRelocations & PointerToLineNumbers field
// hold the offset relative to a platform-specific top address.
//
FixLoadingAddress = (EFI_PHYSICAL_ADDRESS)(Private->LoadModuleAtFixAddressTopAddress + (INT64)ValueInSectionHeader);
}
//
// Check if the memory range is available.
//
Status = CheckAndMarkFixLoadingMemoryUsageBitMap (Private, FixLoadingAddress, (UINT32)ImageContext->ImageSize);
if (!EFI_ERROR (Status)) {
//
// The assigned address is valid. Return the specified loading address
//
ImageContext->ImageAddress = FixLoadingAddress;
}
}
break;
}
SectionHeaderOffset += sizeof (EFI_IMAGE_SECTION_HEADER);
FixLoadingAddress = (EFI_PHYSICAL_ADDRESS)(Private->LoadModuleAtFixAddressTopAddress + ValueInSectionHeader);
}
//
// Check if the memory range is available.
//
Status = CheckAndMarkFixLoadingMemoryUsageBitMap (Private, FixLoadingAddress, ImageDestSize);
*LoadAddress = FixLoadingAddress;
DEBUG ((DEBUG_INFO|DEBUG_LOAD, "LOADING MODULE FIXED INFO: Loading module at fixed address 0x%11p. Status= %r \n", (VOID *)(UINTN)FixLoadingAddress, Status));
DEBUG ((EFI_D_INFO|EFI_D_LOAD, "LOADING MODULE FIXED INFO: Loading module at fixed address 0x%11p. Status= %r \n", (VOID *)(UINTN)FixLoadingAddress, Status));
return Status;
}
@ -262,38 +153,49 @@ GetPeCoffImageFixLoadingAssignedAddress (
**/
EFI_STATUS
LoadAndRelocatePeCoffImage (
LoadAndRelocateUefiImage (
IN EFI_PEI_FILE_HANDLE FileHandle,
IN VOID *Pe32Data,
OUT EFI_PHYSICAL_ADDRESS *ImageAddress,
OUT UINT64 *ImageSize,
OUT EFI_PHYSICAL_ADDRESS *EntryPoint
IN UINT32 Pe32DataSize,
OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext,
OUT EFI_PHYSICAL_ADDRESS *ImageAddress
)
{
EFI_STATUS Status;
PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;
BOOLEAN Success;
PEI_CORE_INSTANCE *Private;
UINT64 AlignImageSize;
UINT32 ImageSize;
UINT32 ImageAlignment;
UINT64 ValueInSectionHeader;
BOOLEAN IsXipImage;
EFI_STATUS ReturnStatus;
BOOLEAN IsS3Boot;
BOOLEAN IsPeiModule;
BOOLEAN IsRegisterForShadow;
EFI_FV_FILE_INFO FileInfo;
UINT32 DestinationPages;
UINT32 DestinationSize;
EFI_PHYSICAL_ADDRESS Destination;
UINT16 Machine;
BOOLEAN LoadDynamically;
Private = PEI_CORE_INSTANCE_FROM_PS_THIS (GetPeiServicesTablePointer ());
ReturnStatus = EFI_SUCCESS;
IsXipImage = FALSE;
ZeroMem (&ImageContext, sizeof (ImageContext));
ImageContext.Handle = Pe32Data;
ImageContext.ImageRead = PeiImageRead;
Status = PeCoffLoaderGetImageInfo (&ImageContext);
Status = UefiImageInitializeContext (ImageContext, Pe32Data, Pe32DataSize);
if (EFI_ERROR (Status)) {
return Status;
}
Machine = UefiImageGetMachine (ImageContext);
if (!EFI_IMAGE_MACHINE_TYPE_SUPPORTED (Machine)) {
if (!EFI_IMAGE_MACHINE_CROSS_TYPE_SUPPORTED (Machine)) {
return EFI_UNSUPPORTED;
}
}
//
// Initialize local IsS3Boot and IsRegisterForShadow variable
//
@ -312,9 +214,7 @@ LoadAndRelocatePeCoffImage (
//
// XIP image that ImageAddress is same to Image handle.
//
if (ImageContext.ImageAddress == (EFI_PHYSICAL_ADDRESS)(UINTN)Pe32Data) {
IsXipImage = TRUE;
}
IsXipImage = UefiImageImageIsInplace (ImageContext);
//
// Get file type first
@ -336,7 +236,7 @@ LoadAndRelocatePeCoffImage (
//
// When Image has no reloc section, it can't be relocated into memory.
//
if (ImageContext.RelocationsStripped && (Private->PeiMemoryInstalled) &&
if (UefiImageGetRelocsStripped (ImageContext) && (Private->PeiMemoryInstalled) &&
((!IsPeiModule) || PcdGetBool (PcdMigrateTemporaryRamFirmwareVolumes) ||
(!IsS3Boot && (PcdGetBool (PcdShadowPeimOnBoot) || IsRegisterForShadow)) ||
(IsS3Boot && PcdGetBool (PcdShadowPeimOnS3Boot)))
@ -345,125 +245,95 @@ LoadAndRelocatePeCoffImage (
DEBUG ((DEBUG_INFO|DEBUG_LOAD, "The image at 0x%08x without reloc section can't be loaded into memory\n", (UINTN)Pe32Data));
}
//
// Set default base address to current image address.
//
ImageContext.ImageAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)Pe32Data;
LoadDynamically = FALSE;
ImageSize = UefiImageGetImageSize (ImageContext);
DestinationPages = EFI_SIZE_TO_PAGES (ImageSize);
DestinationSize = EFI_PAGES_TO_SIZE (DestinationPages);
//
// Allocate Memory for the image when memory is ready, and image is relocatable.
// On normal boot, PcdShadowPeimOnBoot decides whether load PEIM or PeiCore into memory.
// On S3 boot, PcdShadowPeimOnS3Boot decides whether load PEIM or PeiCore into memory.
//
if ((!ImageContext.RelocationsStripped) && (Private->PeiMemoryInstalled) &&
if ((!UefiImageGetRelocsStripped (ImageContext)) && (Private->PeiMemoryInstalled) &&
((!IsPeiModule) || PcdGetBool (PcdMigrateTemporaryRamFirmwareVolumes) ||
(!IsS3Boot && (PcdGetBool (PcdShadowPeimOnBoot) || IsRegisterForShadow)) ||
(IsS3Boot && PcdGetBool (PcdShadowPeimOnS3Boot)))
)
{
//
// Allocate more buffer to avoid buffer overflow.
//
if (ImageContext.IsTeImage) {
AlignImageSize = ImageContext.ImageSize + ((EFI_TE_IMAGE_HEADER *)Pe32Data)->StrippedSize - sizeof (EFI_TE_IMAGE_HEADER);
} else {
AlignImageSize = ImageContext.ImageSize;
Success = FALSE;
if (PcdGet64(PcdLoadModuleAtFixAddressEnable) != 0 && (Private->HobList.HandoffInformationTable->BootMode != BOOT_ON_S3_RESUME)) {
Status = UefiImageGetFixedAddress (ImageContext, &ValueInSectionHeader);
if (!RETURN_ERROR (Status)) {
Status = GetUefiImageFixLoadingAssignedAddress(&Destination, ValueInSectionHeader, DestinationSize, Private);
}
if (!EFI_ERROR (Status)){
Success = Destination == UefiImageGetPreferredAddress (ImageContext);
if (!Success) {
DEBUG ((DEBUG_INFO|DEBUG_LOAD, "LOADING MODULE FIXED ERROR: Loading module at fixed address failed since relocs have been stripped.\n"));
}
} else {
DEBUG ((EFI_D_INFO|EFI_D_LOAD, "LOADING MODULE FIXED ERROR: Failed to load module at fixed address. \n"));
}
}
if (ImageContext.SectionAlignment > EFI_PAGE_SIZE) {
AlignImageSize += ImageContext.SectionAlignment;
if (!Success) {
//
// Allocate more buffer to avoid buffer overflow.
//
ImageAlignment = UefiImageGetSegmentAlignment (ImageContext);
Destination = (UINTN)AllocateAlignedCodePages (
DestinationPages,
ImageAlignment
);
Success = Destination != 0;
}
if ((PcdGet64 (PcdLoadModuleAtFixAddressEnable) != 0) && (Private->HobList.HandoffInformationTable->BootMode != BOOT_ON_S3_RESUME)) {
Status = GetPeCoffImageFixLoadingAssignedAddress (&ImageContext, Private);
if (Success) {
LoadDynamically = TRUE;
//
// Load the image to our new buffer
//
Status = UefiImageLoadImageForExecution (
ImageContext,
(VOID *) (UINTN)Destination,
DestinationSize,
NULL,
0
);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_INFO|DEBUG_LOAD, "LOADING MODULE FIXED ERROR: Failed to load module at fixed address. \n"));
//
// The PEIM is not assigned valid address, try to allocate page to load it.
//
Status = PeiServicesAllocatePages (
EfiBootServicesCode,
EFI_SIZE_TO_PAGES ((UINT32)AlignImageSize),
&ImageContext.ImageAddress
);
}
} else {
Status = PeiServicesAllocatePages (
EfiBootServicesCode,
EFI_SIZE_TO_PAGES ((UINT32)AlignImageSize),
&ImageContext.ImageAddress
);
}
if (!EFI_ERROR (Status)) {
//
// Adjust the Image Address to make sure it is section alignment.
//
if (ImageContext.SectionAlignment > EFI_PAGE_SIZE) {
ImageContext.ImageAddress =
(ImageContext.ImageAddress + ImageContext.SectionAlignment - 1) &
~((UINTN)ImageContext.SectionAlignment - 1);
}
//
// Fix alignment requirement when Load IPF TeImage into memory.
// Skip the reserved space for the stripped PeHeader when load TeImage into memory.
//
if (ImageContext.IsTeImage) {
ImageContext.ImageAddress = ImageContext.ImageAddress +
((EFI_TE_IMAGE_HEADER *)Pe32Data)->StrippedSize -
sizeof (EFI_TE_IMAGE_HEADER);
return Status;
}
} else {
//
// No enough memory resource.
//
if (IsXipImage) {
//
// XIP image can still be invoked.
//
ImageContext.ImageAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)Pe32Data;
ReturnStatus = EFI_WARN_BUFFER_TOO_SMALL;
} else {
if (!IsXipImage) {
//
// Non XIP image can't be loaded because no enough memory is allocated.
//
ASSERT (FALSE);
return EFI_OUT_OF_RESOURCES;
}
//
// XIP image can still be invoked.
//
ReturnStatus = EFI_WARN_BUFFER_TOO_SMALL;
}
}
//
// Load the image to our new buffer
//
Status = PeCoffLoaderLoadImage (&ImageContext);
if (EFI_ERROR (Status)) {
if (ImageContext.ImageError == IMAGE_ERROR_INVALID_SECTION_ALIGNMENT) {
DEBUG ((DEBUG_ERROR, "PEIM Image Address 0x%11p doesn't meet with section alignment 0x%x.\n", (VOID *)(UINTN)ImageContext.ImageAddress, ImageContext.SectionAlignment));
if (!LoadDynamically) {
Status = UefiImageLoadImageInplace (ImageContext);
if (EFI_ERROR (Status)) {
return Status;
}
return Status;
}
//
// Relocate the image in our new buffer
//
Status = PeCoffLoaderRelocateImage (&ImageContext);
if (EFI_ERROR (Status)) {
return Status;
}
//
// Flush the instruction cache so the image data is written before we execute it
//
if (ImageContext.ImageAddress != (EFI_PHYSICAL_ADDRESS)(UINTN)Pe32Data) {
InvalidateInstructionCacheRange ((VOID *)(UINTN)ImageContext.ImageAddress, (UINTN)ImageContext.ImageSize);
}
*ImageAddress = ImageContext.ImageAddress;
*ImageSize = ImageContext.ImageSize;
*EntryPoint = ImageContext.EntryPoint;
*ImageAddress = UefiImageLoaderGetImageAddress (ImageContext);
return ReturnStatus;
}
@ -479,50 +349,30 @@ LoadAndRelocatePeCoffImage (
**/
EFI_STATUS
LoadAndRelocatePeCoffImageInPlace (
LoadAndRelocateUefiImageInPlace (
IN VOID *Pe32Data,
IN VOID *ImageAddress
IN VOID *ImageAddress,
IN UINT32 ImageSize
)
{
EFI_STATUS Status;
PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;
UEFI_IMAGE_LOADER_IMAGE_CONTEXT ImageContext;
ZeroMem (&ImageContext, sizeof (ImageContext));
ImageContext.Handle = Pe32Data;
ImageContext.ImageRead = PeiImageRead;
ASSERT (Pe32Data != ImageAddress);
Status = PeCoffLoaderGetImageInfo (&ImageContext);
CopyMem (ImageAddress, Pe32Data, ImageSize);
Status = UefiImageInitializeContext (&ImageContext, ImageAddress, ImageSize);
if (EFI_ERROR (Status)) {
ASSERT_EFI_ERROR (Status);
return Status;
}
ImageContext.ImageAddress = (PHYSICAL_ADDRESS)(UINTN)ImageAddress;
//
// Load the image in place
//
Status = PeCoffLoaderLoadImage (&ImageContext);
if (EFI_ERROR (Status)) {
ASSERT_EFI_ERROR (Status);
return Status;
}
//
// Relocate the image in place
//
Status = PeCoffLoaderRelocateImage (&ImageContext);
if (EFI_ERROR (Status)) {
ASSERT_EFI_ERROR (Status);
return Status;
}
//
// Flush the instruction cache so the image data is written before we execute it
//
if (ImageContext.ImageAddress != (EFI_PHYSICAL_ADDRESS)(UINTN)Pe32Data) {
InvalidateInstructionCacheRange ((VOID *)(UINTN)ImageContext.ImageAddress, (UINTN)ImageContext.ImageSize);
}
Status = UefiImageRelocateImageInplaceForExecution (&ImageContext);
ASSERT_EFI_ERROR (Status);
return Status;
}
@ -540,7 +390,8 @@ LoadAndRelocatePeCoffImageInPlace (
EFI_STATUS
PeiGetPe32Data (
IN EFI_PEI_FILE_HANDLE FileHandle,
OUT VOID **Pe32Data
OUT VOID **Pe32Data,
OUT UINT32 *Pe32DataSize
)
{
EFI_STATUS Status;
@ -562,22 +413,24 @@ PeiGetPe32Data (
// Try to find a first exe section (if PcdPeiCoreImageLoaderSearchTeSectionFirst
// is true, TE will be searched first).
//
Status = PeiServicesFfsFindSectionData3 (
Status = PeiServicesFfsFindSectionData4 (
SearchType1,
0,
FileHandle,
Pe32Data,
Pe32DataSize,
&AuthenticationState
);
//
// If we didn't find a first exe section, try to find the second exe section.
//
if (EFI_ERROR (Status)) {
Status = PeiServicesFfsFindSectionData3 (
Status = PeiServicesFfsFindSectionData4 (
SearchType2,
0,
FileHandle,
Pe32Data,
Pe32DataSize,
&AuthenticationState
);
}
@ -617,15 +470,13 @@ PeiLoadImageLoadImage (
{
EFI_STATUS Status;
VOID *Pe32Data;
UINT32 Pe32DataSize;
EFI_PHYSICAL_ADDRESS ImageAddress;
UINT64 ImageSize;
EFI_PHYSICAL_ADDRESS ImageEntryPoint;
UINT16 Machine;
EFI_SECTION_TYPE SearchType1;
EFI_SECTION_TYPE SearchType2;
UEFI_IMAGE_LOADER_IMAGE_CONTEXT ImageContext;
*EntryPoint = 0;
ImageSize = 0;
*AuthenticationState = 0;
if (FeaturePcdGet (PcdPeiCoreImageLoaderSearchTeSectionFirst)) {
@ -640,22 +491,24 @@ PeiLoadImageLoadImage (
// Try to find a first exe section (if PcdPeiCoreImageLoaderSearchTeSectionFirst
// is true, TE will be searched first).
//
Status = PeiServicesFfsFindSectionData3 (
Status = PeiServicesFfsFindSectionData4 (
SearchType1,
0,
FileHandle,
&Pe32Data,
&Pe32DataSize,
AuthenticationState
);
//
// If we didn't find a first exe section, try to find the second exe section.
//
if (EFI_ERROR (Status)) {
Status = PeiServicesFfsFindSectionData3 (
Status = PeiServicesFfsFindSectionData4 (
SearchType2,
0,
FileHandle,
&Pe32Data,
&Pe32DataSize,
AuthenticationState
);
if (EFI_ERROR (Status)) {
@ -672,12 +525,12 @@ PeiLoadImageLoadImage (
//
// If memory is installed, perform the shadow operations
//
Status = LoadAndRelocatePeCoffImage (
Status = LoadAndRelocateUefiImage (
FileHandle,
Pe32Data,
&ImageAddress,
&ImageSize,
&ImageEntryPoint
Pe32DataSize,
&ImageContext,
&ImageAddress
);
if (EFI_ERROR (Status)) {
@ -687,83 +540,47 @@ PeiLoadImageLoadImage (
//
// Got the entry point from the loaded Pe32Data
//
Pe32Data = (VOID *)((UINTN)ImageAddress);
*EntryPoint = ImageEntryPoint;
Machine = PeCoffLoaderGetMachineType (Pe32Data);
if (!EFI_IMAGE_MACHINE_TYPE_SUPPORTED (Machine)) {
if (!EFI_IMAGE_MACHINE_CROSS_TYPE_SUPPORTED (Machine)) {
return EFI_UNSUPPORTED;
}
}
*EntryPoint = UefiImageLoaderGetImageEntryPoint (&ImageContext);
if (ImageAddressArg != NULL) {
*ImageAddressArg = ImageAddress;
}
if (ImageSizeArg != NULL) {
*ImageSizeArg = ImageSize;
*ImageSizeArg =UefiImageGetImageSize (&ImageContext);
}
DEBUG_CODE_BEGIN ();
CHAR8 *AsciiString;
CHAR8 EfiFileName[512];
INT32 Index;
INT32 StartIndex;
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 EntryPoint=0x%11p ", (VOID *)(UINTN)ImageAddress, (VOID *)(UINTN)*EntryPoint));
} else {
//
// For IPF Image, the real entry point should be print.
// Print debug message: Loading PEIM at 0x12345678 EntryPoint=0x12345688 Driver.efi
//
DEBUG ((DEBUG_INFO | DEBUG_LOAD, "Loading PEIM at 0x%11p EntryPoint=0x%11p ", (VOID *)(UINTN)ImageAddress, (VOID *)(UINTN)(*(UINT64 *)(UINTN)*EntryPoint)));
}
//
// Print Module Name by PeImage PDB file name.
//
AsciiString = PeCoffLoaderGetPdbPointer (Pe32Data);
if (AsciiString != NULL) {
StartIndex = 0;
for (Index = 0; AsciiString[Index] != 0; Index++) {
if ((AsciiString[Index] == '\\') || (AsciiString[Index] == '/')) {
StartIndex = Index + 1;
}
if (Machine != EFI_IMAGE_MACHINE_IA64) {
DEBUG ((DEBUG_INFO | DEBUG_LOAD, "Loading PEIM at 0x%11p EntryPoint=0x%11p ", (VOID *)(UINTN)ImageAddress, (VOID *)(UINTN)*EntryPoint));
} else {
//
// For IPF Image, the real entry point should be print.
//
DEBUG ((DEBUG_INFO | DEBUG_LOAD, "Loading PEIM at 0x%11p EntryPoint=0x%11p ", (VOID *)(UINTN)ImageAddress, (VOID *)(UINTN)(*(UINT64 *)(UINTN)*EntryPoint)));
}
//
// Copy the PDB file name to our temporary string, and replace .pdb with .efi
// The PDB file name is limited in the range of 0~511.
// If the length is bigger than 511, trim the redundant characters to avoid overflow in array boundary.
// Print Module Name by PeImage PDB file name.
//
for (Index = 0; Index < sizeof (EfiFileName) - 4; Index++) {
EfiFileName[Index] = AsciiString[Index + StartIndex];
if (EfiFileName[Index] == 0) {
EfiFileName[Index] = '.';
}
Status = UefiImageGetModuleNameFromSymbolsPath (
&ImageContext,
EfiFileName,
sizeof (EfiFileName)
);
if (EfiFileName[Index] == '.') {
EfiFileName[Index + 1] = 'e';
EfiFileName[Index + 2] = 'f';
EfiFileName[Index + 3] = 'i';
EfiFileName[Index + 4] = 0;
break;
}
if (!RETURN_ERROR (Status)) {
DEBUG ((DEBUG_INFO | DEBUG_LOAD, "%a", EfiFileName));
}
if (Index == sizeof (EfiFileName) - 4) {
EfiFileName[Index] = 0;
}
DEBUG ((DEBUG_INFO | DEBUG_LOAD, "%a", EfiFileName));
}
DEBUG_CODE_END ();
DEBUG ((DEBUG_INFO | DEBUG_LOAD, "\n"));
@ -814,7 +631,7 @@ PeiLoadImageLoadImageWrapper (
@retval FALSE Relocation is not stripped.
**/
BOOLEAN
/*BOOLEAN
RelocationIsStrip (
IN VOID *Pe32Data
)
@ -863,7 +680,7 @@ RelocationIsStrip (
}
return FALSE;
}
}*/
/**
Routine to load image file for subsequent execution by LoadFile Ppi.
@ -896,9 +713,9 @@ PeiLoadImage (
EFI_PEI_LOAD_FILE_PPI *LoadFile;
EFI_PHYSICAL_ADDRESS ImageAddress;
UINT64 ImageSize;
BOOLEAN IsStrip;
//BOOLEAN IsStrip;
IsStrip = FALSE;
//IsStrip = FALSE;
//
// If any instances of PEI_LOAD_FILE_PPI are installed, they are called.
// one at a time, until one reports EFI_SUCCESS.
@ -924,7 +741,9 @@ PeiLoadImage (
//
// The shadowed PEIM must be relocatable.
//
if (PeimState == PEIM_STATE_REGISTER_FOR_SHADOW) {
// FIXME:
/*if (PeimState == PEIM_STATE_REGISTER_FOR_SHADOW) {
// FIXME: Assumes headers were loaded into the image memory
IsStrip = RelocationIsStrip ((VOID *)(UINTN)ImageAddress);
ASSERT (!IsStrip);
if (IsStrip) {
@ -935,10 +754,10 @@ PeiLoadImage (
//
// The image to be started must have the machine type supported by PeiCore.
//
ASSERT (EFI_IMAGE_MACHINE_TYPE_SUPPORTED (PeCoffLoaderGetMachineType ((VOID *)(UINTN)ImageAddress)));
if (!EFI_IMAGE_MACHINE_TYPE_SUPPORTED (PeCoffLoaderGetMachineType ((VOID *)(UINTN)ImageAddress))) {
ASSERT (EFI_IMAGE_MACHINE_TYPE_SUPPORTED (UefiImageLoaderGetMachineType ((VOID *)(UINTN)ImageAddress)));
if (!EFI_IMAGE_MACHINE_TYPE_SUPPORTED (UefiImageLoaderGetMachineType ((VOID *)(UINTN)ImageAddress))) {
return EFI_UNSUPPORTED;
}
}*/
return EFI_SUCCESS;
}

View File

@ -33,12 +33,11 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#include <Library/PerformanceLib.h>
#include <Library/PeiServicesLib.h>
#include <Library/ReportStatusCodeLib.h>
#include <Library/PeCoffLib.h>
#include <Library/PeCoffGetEntryPointLib.h>
#include <Library/UefiImageLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/CacheMaintenanceLib.h>
#include <Library/PcdLib.h>
#include <IndustryStandard/PeImage.h>
#include <IndustryStandard/PeImage2.h>
#include <Library/PeiServicesTablePointerLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Guid/FirmwareFileSystem2.h>
@ -289,7 +288,7 @@ struct _PEI_CORE_INSTANCE {
//
// This field points to the shadowed image read function
//
PE_COFF_LOADER_READ_FILE ShadowedImageRead;
VOID *ShadowedImageRead;
UINTN TempPeimCount;
@ -903,6 +902,8 @@ PeiFfsFindNextFile (
@param SectionSize The file size to search.
@param OutputBuffer A pointer to the discovered section, if successful.
NULL if section not found.
@param OutputSize The size of the discovered section, if successful.
0 if section not found
@param AuthenticationStatus Updated upon return to point to the authentication status for this section.
@param IsFfs3Fv Indicates the FV format.
@ -918,6 +919,7 @@ ProcessSection (
IN EFI_COMMON_SECTION_HEADER *Section,
IN UINTN SectionSize,
OUT VOID **OutputBuffer,
OUT UINT32 *OutputSize,
OUT UINT32 *AuthenticationStatus,
IN BOOLEAN IsFfs3Fv
);
@ -969,6 +971,33 @@ PeiFfsFindSectionData3 (
OUT UINT32 *AuthenticationStatus
);
/**
Searches for the next matching section within the specified file.
@param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
@param SectionType The value of the section type to find.
@param SectionInstance Section instance to find.
@param FileHandle Handle of the firmware file to search.
@param SectionData A pointer to the discovered section, if successful.
@param SectionDataSize The size of the discovered section, if successful.
@param AuthenticationStatus A pointer to the authentication status for this section.
@retval EFI_SUCCESS The section was found.
@retval EFI_NOT_FOUND The section was not found.
**/
EFI_STATUS
EFIAPI
PeiFfsFindSectionData4 (
IN CONST EFI_PEI_SERVICES **PeiServices,
IN EFI_SECTION_TYPE SectionType,
IN UINTN SectionInstance,
IN EFI_PEI_FILE_HANDLE FileHandle,
OUT VOID **SectionData,
OUT UINT32 *SectionDataSize,
OUT UINT32 *AuthenticationStatus
);
/**
Search the firmware volumes by index
@ -1391,9 +1420,10 @@ InitializeImageServices (
**/
EFI_STATUS
LoadAndRelocatePeCoffImageInPlace (
LoadAndRelocateUefiImageInPlace (
IN VOID *Pe32Data,
IN VOID *ImageAddress
IN VOID *ImageAddress,
IN UINT32 ImageSize
);
/**
@ -1409,7 +1439,8 @@ LoadAndRelocatePeCoffImageInPlace (
EFI_STATUS
PeiGetPe32Data (
IN EFI_PEI_FILE_HANDLE FileHandle,
OUT VOID **Pe32Data
OUT VOID **Pe32Data,
OUT UINT32 *Pe32DataSize
);
/**

View File

@ -53,7 +53,6 @@
[LibraryClasses]
BaseMemoryLib
PeCoffGetEntryPointLib
ReportStatusCodeLib
PeiServicesLib
PerformanceLib
@ -63,7 +62,7 @@
DebugLib
MemoryAllocationLib
CacheMaintenanceLib
PeCoffLib
UefiImageLib
PeiServicesTablePointerLib
PcdLib

View File

@ -60,6 +60,7 @@ EFI_PEI_SERVICES gPs = {
PeiFfsGetFileInfo2,
PeiResetSystem2,
PeiFreePages,
PeiFfsFindSectionData4
};
/**

View File

@ -1082,14 +1082,16 @@ ConvertPeiCorePpiPointers (
IN PEI_CORE_FV_HANDLE *CoreFvHandle
)
{
EFI_FV_FILE_INFO FileInfo;
EFI_PHYSICAL_ADDRESS OrgImageBase;
EFI_PHYSICAL_ADDRESS MigratedImageBase;
UINTN PeiCoreModuleSize;
EFI_PEI_FILE_HANDLE PeiCoreFileHandle;
VOID *PeiCoreImageBase;
VOID *PeiCoreEntryPoint;
EFI_STATUS Status;
EFI_FV_FILE_INFO FileInfo;
EFI_PHYSICAL_ADDRESS OrgImageBase;
EFI_PHYSICAL_ADDRESS MigratedImageBase;
UINTN PeiCoreModuleSize;
EFI_PEI_FILE_HANDLE PeiCoreFileHandle;
VOID *PeiCoreImageBase;
UINT32 PeiCoreImageSize;
//VOID *PeiCoreEntryPoint;
EFI_STATUS Status;
UEFI_IMAGE_LOADER_IMAGE_CONTEXT ImageContext;
PeiCoreFileHandle = NULL;
@ -1108,17 +1110,18 @@ ConvertPeiCorePpiPointers (
Status = CoreFvHandle->FvPpi->GetFileInfo (CoreFvHandle->FvPpi, PeiCoreFileHandle, &FileInfo);
ASSERT_EFI_ERROR (Status);
Status = PeiGetPe32Data (PeiCoreFileHandle, &PeiCoreImageBase);
Status = PeiGetPe32Data (PeiCoreFileHandle, &PeiCoreImageBase, &PeiCoreImageSize);
ASSERT_EFI_ERROR (Status);
//
// Find PEI Core EntryPoint in the BFV in temporary memory.
//
Status = PeCoffLoaderGetEntryPoint ((VOID *)(UINTN)PeiCoreImageBase, &PeiCoreEntryPoint);
// FIXME: "Assume" sanity and skip full initialisation?
Status = UefiImageInitializeContext (&ImageContext, (VOID *) (UINTN) PeiCoreImageBase, PeiCoreImageSize);
ASSERT_EFI_ERROR (Status);
OrgImageBase = (UINTN)PeiCoreImageBase;
MigratedImageBase = (UINTN)_ModuleEntryPoint - ((UINTN)PeiCoreEntryPoint - (UINTN)PeiCoreImageBase);
MigratedImageBase = (UINTN)_ModuleEntryPoint - UefiImageGetEntryPointAddress (&ImageContext);
//
// Size of loaded PEI_CORE in permanent memory.

View File

@ -0,0 +1,153 @@
/** @file
Support functions for managing debug image info table when loading and unloading
images.
Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include "PiSmmCore.h"
// FIXME: Unify with DXE
EFI_DEBUG_IMAGE_INFO_TABLE_HEADER mDebugInfoTableHeader = {
0, // volatile UINT32 UpdateStatus;
0, // UINT32 TableSize;
NULL // EFI_DEBUG_IMAGE_INFO *EfiDebugImageInfoTable;
};
UINTN mMaxTableEntries = 0;
#define EFI_DEBUG_TABLE_ENTRY_SIZE (sizeof (VOID *))
/**
Creates and initializes the DebugImageInfo Table. Also creates the configuration
table and registers it into the system table.
**/
VOID
SmmInitializeDebugImageInfoTable (
VOID
)
{
EFI_STATUS Status;
//
// Install the EFI_SYSTEM_TABLE_POINTER structure in the EFI System
// Configuration Table
//
Status = SmmInstallConfigurationTable (
gSmst,
&gEfiDebugImageInfoTableGuid,
&mDebugInfoTableHeader,
sizeof (mDebugInfoTableHeader)
);
ASSERT_EFI_ERROR (Status);
}
/**
Adds a new DebugImageInfo structure to the DebugImageInfo Table. Re-Allocates
the table if it's not large enough to accomidate another entry.
@param ImageInfoType type of debug image information
@param LoadedImage pointer to the loaded image protocol for the image being
loaded
@param ImageHandle image handle for the image being loaded
**/
VOID
SmmNewDebugImageInfoEntry (
IN UINT32 ImageInfoType,
IN EFI_LOADED_IMAGE_PROTOCOL *LoadedImage,
IN EFI_HANDLE ImageHandle,
IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext
)
{
EFI_DEBUG_IMAGE_INFO *Table;
EFI_DEBUG_IMAGE_INFO *NewTable;
UINTN Index;
UINTN TableSize;
EFI_DEBUG_IMAGE_INFO_NORMAL *NormalImage;
RETURN_STATUS Status;
CONST CHAR8 *PdbPath;
UINT32 PdbPathSize;
//
// Set the flag indicating that we're in the process of updating the table.
//
mDebugInfoTableHeader.UpdateStatus |= EFI_DEBUG_IMAGE_INFO_UPDATE_IN_PROGRESS;
Table = mDebugInfoTableHeader.EfiDebugImageInfoTable;
if (mDebugInfoTableHeader.TableSize < mMaxTableEntries) {
//
// We still have empty entires in the Table, find the first empty entry.
//
Index = 0;
while (Table[Index].NormalImage != NULL) {
Index++;
}
//
// There must be an empty entry in the in the table.
//
ASSERT (Index < mMaxTableEntries);
} else {
//
// Table is full, so re-allocate another page for a larger table...
//
TableSize = mMaxTableEntries * EFI_DEBUG_TABLE_ENTRY_SIZE;
NewTable = AllocateZeroPool (TableSize + EFI_PAGE_SIZE);
if (NewTable == NULL) {
mDebugInfoTableHeader.UpdateStatus &= ~EFI_DEBUG_IMAGE_INFO_UPDATE_IN_PROGRESS;
return;
}
//
// Copy the old table into the new one
//
CopyMem (NewTable, Table, TableSize);
mDebugInfoTableHeader.EfiDebugImageInfoTable = NewTable;
//
// Enlarge the max table entries.
//
mMaxTableEntries += EFI_PAGE_SIZE / EFI_DEBUG_TABLE_ENTRY_SIZE;
//
// Free the old table
//
SmmFreePool (Table);
//
// Update the table header
//
Table = NewTable;
//
// Set the first empty entry index to be the original max table entries.
//
Index = mMaxTableEntries;
}
//
// Allocate data for new entry
//
NormalImage = AllocateZeroPool (sizeof (EFI_DEBUG_IMAGE_INFO_NORMAL));
if (NormalImage != NULL) {
//
// Update the entry
//
NormalImage->ImageInfoType = (UINT32) ImageInfoType;
NormalImage->LoadedImageProtocolInstance = LoadedImage;
NormalImage->ImageHandle = ImageHandle;
Status = UefiImageGetSymbolsPath (ImageContext, &PdbPath, &PdbPathSize);
if (!RETURN_ERROR (Status)) {
NormalImage->PdbPath = AllocateCopyPool (PdbPathSize, PdbPath);
}
//
// Increase the number of EFI_DEBUG_IMAGE_INFO elements and set the mDebugInfoTable in modified status.
//
mDebugInfoTableHeader.UpdateStatus |= EFI_DEBUG_IMAGE_INFO_TABLE_MODIFIED;
Table[Index].NormalImage = NormalImage;
mDebugInfoTableHeader.TableSize++;
}
mDebugInfoTableHeader.UpdateStatus &= ~EFI_DEBUG_IMAGE_INFO_UPDATE_IN_PROGRESS;
}

View File

@ -33,7 +33,9 @@
**/
#include "Library/UefiImageLib.h"
#include "PiSmmCore.h"
#include "Uefi/UefiBaseType.h"
//
// SMM Dispatcher Data structures
@ -213,84 +215,18 @@ CheckAndMarkFixLoadingMemoryUsageBitMap (
**/
EFI_STATUS
GetPeCoffImageFixLoadingAssignedAddress (
IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext
GetUefiImageFixLoadingAssignedAddress (
OUT EFI_PHYSICAL_ADDRESS *LoadAddress,
IN UINT64 ValueInSectionHeader,
IN UINT32 ImageDestSize
)
{
UINTN SectionHeaderOffset;
EFI_STATUS Status;
EFI_IMAGE_SECTION_HEADER SectionHeader;
EFI_IMAGE_OPTIONAL_HEADER_UNION *ImgHdr;
EFI_PHYSICAL_ADDRESS FixLoadingAddress;
UINT16 Index;
UINTN Size;
UINT16 NumberOfSections;
UINT64 ValueInSectionHeader;
RETURN_STATUS Status;
EFI_PHYSICAL_ADDRESS FixLoadingAddress;
FixLoadingAddress = 0;
Status = EFI_NOT_FOUND;
//
// Get PeHeader pointer
//
ImgHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)((CHAR8 *)ImageContext->Handle + ImageContext->PeCoffHeaderOffset);
SectionHeaderOffset = ImageContext->PeCoffHeaderOffset +
sizeof (UINT32) +
sizeof (EFI_IMAGE_FILE_HEADER) +
ImgHdr->Pe32.FileHeader.SizeOfOptionalHeader;
NumberOfSections = ImgHdr->Pe32.FileHeader.NumberOfSections;
//
// Get base address from the first section header that doesn't point to code section.
//
for (Index = 0; Index < NumberOfSections; Index++) {
//
// Read section header from file
//
Size = sizeof (EFI_IMAGE_SECTION_HEADER);
Status = ImageContext->ImageRead (
ImageContext->Handle,
SectionHeaderOffset,
&Size,
&SectionHeader
);
if (EFI_ERROR (Status)) {
return Status;
}
Status = EFI_NOT_FOUND;
if ((SectionHeader.Characteristics & EFI_IMAGE_SCN_CNT_CODE) == 0) {
//
// Build tool will save the address in PointerToRelocations & PointerToLineNumbers fields in the first section header
// that doesn't point to code section in image header.So there is an assumption that when the feature is enabled,
// if a module with a loading address assigned by tools, the PointerToRelocations & PointerToLineNumbers fields
// should not be Zero, or else, these 2 fields should be set to Zero
//
ValueInSectionHeader = ReadUnaligned64 ((UINT64 *)&SectionHeader.PointerToRelocations);
if (ValueInSectionHeader != 0) {
//
// Found first section header that doesn't point to code section in which build tool saves the
// offset to SMRAM base as image base in PointerToRelocations & PointerToLineNumbers fields
//
FixLoadingAddress = (EFI_PHYSICAL_ADDRESS)(gLoadModuleAtFixAddressSmramBase + (INT64)ValueInSectionHeader);
//
// Check if the memory range is available.
//
Status = CheckAndMarkFixLoadingMemoryUsageBitMap (FixLoadingAddress, (UINTN)(ImageContext->ImageSize + ImageContext->SectionAlignment));
if (!EFI_ERROR (Status)) {
//
// The assigned address is valid. Return the specified loading address
//
ImageContext->ImageAddress = FixLoadingAddress;
}
}
break;
}
SectionHeaderOffset += sizeof (EFI_IMAGE_SECTION_HEADER);
}
FixLoadingAddress = (EFI_PHYSICAL_ADDRESS)(gLoadModuleAtFixAddressSmramBase + ValueInSectionHeader);
Status = CheckAndMarkFixLoadingMemoryUsageBitMap (FixLoadingAddress, ImageDestSize);
*LoadAddress = FixLoadingAddress;
DEBUG ((DEBUG_INFO|DEBUG_LOAD, "LOADING MODULE FIXED INFO: Loading module at fixed address %x, Status = %r\n", FixLoadingAddress, Status));
return Status;
@ -307,24 +243,29 @@ GetPeCoffImageFixLoadingAssignedAddress (
EFI_STATUS
EFIAPI
SmmLoadImage (
IN OUT EFI_SMM_DRIVER_ENTRY *DriverEntry
IN OUT EFI_SMM_DRIVER_ENTRY *DriverEntry,
OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext
)
{
UINT32 AuthenticationStatus;
UINTN FilePathSize;
VOID *Buffer;
UINTN Size;
UINTN PageCount;
UINT32 DstBufferPages;
EFI_GUID *NameGuid;
EFI_STATUS Status;
EFI_STATUS SecurityStatus;
EFI_HANDLE DeviceHandle;
EFI_PHYSICAL_ADDRESS DstBuffer;
UINT32 ImageSize;
UINT32 ImageAlignment;
UINT64 ValueInSectionHeader;
VOID *DstBuffer;
UINT32 DstBufferSize;
EFI_DEVICE_PATH_PROTOCOL *FilePath;
EFI_DEVICE_PATH_PROTOCOL *OriginalFilePath;
EFI_DEVICE_PATH_PROTOCOL *HandleFilePath;
EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv;
PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;
EFI_PHYSICAL_ADDRESS LoadAddress;
PERF_LOAD_IMAGE_BEGIN (DriverEntry->ImageHandle);
@ -413,6 +354,18 @@ SmmLoadImage (
return Status;
}
//
// Get information about the image being loaded
//
Status = UefiImageInitializeContextPreHash (ImageContext, Buffer, (UINT32) Size);
if (EFI_ERROR (Status)) {
if (Buffer != NULL) {
gBS->FreePool (Buffer);
}
return Status;
}
// FIXME: Context?
//
// Verify File Authentication through the Security2 Architectural Protocol
//
@ -420,8 +373,8 @@ SmmLoadImage (
SecurityStatus = mSecurity2->FileAuthentication (
mSecurity2,
OriginalFilePath,
Buffer,
Size,
ImageContext,
sizeof (*ImageContext),
FALSE
);
}
@ -444,24 +397,23 @@ SmmLoadImage (
return Status;
}
//
// Initialize ImageContext
//
ImageContext.Handle = Buffer;
ImageContext.ImageRead = PeCoffLoaderImageReadFromMemory;
//
// Get information about the image being loaded
//
Status = PeCoffLoaderGetImageInfo (&ImageContext);
if (EFI_ERROR (Status)) {
if (Buffer != NULL) {
gBS->FreePool (Buffer);
}
Status = UefiImageInitializeContextPostHash (ImageContext);
if (RETURN_ERROR (Status)) {
return Status;
}
//
// Stripped relocations are not supported for both fixed-address and dynamic
// loading.
//
if (UefiImageGetRelocsStripped (ImageContext)) {
return EFI_UNSUPPORTED;
}
ImageSize = UefiImageGetImageSize (ImageContext);
DstBufferPages = EFI_SIZE_TO_PAGES (ImageSize);
DstBufferSize = EFI_PAGES_TO_SIZE (DstBufferPages);
ImageAlignment = UefiImageGetSegmentAlignment (ImageContext);
//
// if Loading module at Fixed Address feature is enabled, then cut out a memory range started from TESG BASE
// to hold the Smm driver code
@ -470,102 +422,68 @@ SmmLoadImage (
//
// Get the fixed loading address assigned by Build tool
//
Status = GetPeCoffImageFixLoadingAssignedAddress (&ImageContext);
Status = UefiImageGetFixedAddress (ImageContext, &ValueInSectionHeader);
if (!RETURN_ERROR (Status)) {
Status = GetUefiImageFixLoadingAssignedAddress (&LoadAddress, ValueInSectionHeader, DstBufferSize);
}
if (!EFI_ERROR (Status)) {
//
// Since the memory range to load Smm core already been cut out, so no need to allocate and free this range
// following statements is to bypass SmmFreePages
//
PageCount = 0;
DstBuffer = (UINTN)gLoadModuleAtFixAddressSmramBase;
DstBufferPages = 0;
DstBuffer = (VOID *)(UINTN)LoadAddress;
} else {
DEBUG ((DEBUG_INFO|DEBUG_LOAD, "LOADING MODULE FIXED ERROR: Failed to load module at fixed address. \n"));
//
// allocate the memory to load the SMM driver
//
PageCount = (UINTN)EFI_SIZE_TO_PAGES ((UINTN)ImageContext.ImageSize + ImageContext.SectionAlignment);
DstBuffer = (UINTN)(-1);
Status = SmmAllocatePages (
AllocateMaxAddress,
EfiRuntimeServicesCode,
PageCount,
&DstBuffer
);
if (EFI_ERROR (Status)) {
DstBuffer = AllocateAlignedCodePages (DstBufferPages, ImageAlignment);
if (DstBuffer == NULL) {
if (Buffer != NULL) {
gBS->FreePool (Buffer);
}
return Status;
}
ImageContext.ImageAddress = (EFI_PHYSICAL_ADDRESS)DstBuffer;
return EFI_OUT_OF_RESOURCES;
}
}
} else {
PageCount = (UINTN)EFI_SIZE_TO_PAGES ((UINTN)ImageContext.ImageSize + ImageContext.SectionAlignment);
DstBuffer = (UINTN)(-1);
Status = SmmAllocatePages (
AllocateMaxAddress,
EfiRuntimeServicesCode,
PageCount,
&DstBuffer
);
if (EFI_ERROR (Status)) {
DstBuffer = AllocateAlignedCodePages (DstBufferPages, ImageAlignment);
if (DstBuffer == NULL) {
if (Buffer != NULL) {
gBS->FreePool (Buffer);
}
return Status;
return EFI_OUT_OF_RESOURCES;
}
ImageContext.ImageAddress = (EFI_PHYSICAL_ADDRESS)DstBuffer;
}
//
// Align buffer on section boundary
//
ImageContext.ImageAddress += ImageContext.SectionAlignment - 1;
ImageContext.ImageAddress &= ~((EFI_PHYSICAL_ADDRESS)ImageContext.SectionAlignment - 1);
//
// Load the image to our new buffer
//
Status = PeCoffLoaderLoadImage (&ImageContext);
Status = UefiImageLoadImageForExecution (
ImageContext,
DstBuffer,
DstBufferSize,
NULL,
0
);
if (EFI_ERROR (Status)) {
if (Buffer != NULL) {
gBS->FreePool (Buffer);
}
SmmFreePages (DstBuffer, PageCount);
FreeAlignedPages (DstBuffer, DstBufferPages);
return Status;
}
//
// Relocate the image in our new buffer
//
Status = PeCoffLoaderRelocateImage (&ImageContext);
if (EFI_ERROR (Status)) {
if (Buffer != NULL) {
gBS->FreePool (Buffer);
}
SmmFreePages (DstBuffer, PageCount);
return Status;
}
//
// Flush the instruction cache so the image data are written before we execute it
//
InvalidateInstructionCacheRange ((VOID *)(UINTN)ImageContext.ImageAddress, (UINTN)ImageContext.ImageSize);
//
// Save Image EntryPoint in DriverEntry
//
DriverEntry->ImageEntryPoint = ImageContext.EntryPoint;
DriverEntry->ImageBuffer = DstBuffer;
DriverEntry->NumberOfPage = PageCount;
DriverEntry->ImageEntryPoint = UefiImageLoaderGetImageEntryPoint (ImageContext);
DriverEntry->ImageBuffer = (UINTN)DstBuffer;
DriverEntry->NumberOfPage = DstBufferPages;
//
// Allocate a Loaded Image Protocol in EfiBootServicesData
@ -576,7 +494,7 @@ SmmLoadImage (
gBS->FreePool (Buffer);
}
SmmFreePages (DstBuffer, PageCount);
FreeAlignedPages (DstBuffer, DstBufferPages);
return Status;
}
@ -604,14 +522,14 @@ SmmLoadImage (
gBS->FreePool (Buffer);
}
SmmFreePages (DstBuffer, PageCount);
FreeAlignedPages (DstBuffer, DstBufferPages);
return Status;
}
CopyMem (DriverEntry->LoadedImage->FilePath, FilePath, GetDevicePathSize (FilePath));
DriverEntry->LoadedImage->ImageBase = (VOID *)(UINTN)ImageContext.ImageAddress;
DriverEntry->LoadedImage->ImageSize = ImageContext.ImageSize;
DriverEntry->LoadedImage->ImageBase = DstBuffer;
DriverEntry->LoadedImage->ImageSize = ImageSize;
DriverEntry->LoadedImage->ImageCodeType = EfiRuntimeServicesCode;
DriverEntry->LoadedImage->ImageDataType = EfiRuntimeServicesData;
@ -625,14 +543,14 @@ SmmLoadImage (
}
gBS->FreePool (DriverEntry->LoadedImage->FilePath);
SmmFreePages (DstBuffer, PageCount);
FreeAlignedPages (DstBuffer, DstBufferPages);
return Status;
}
CopyMem (DriverEntry->SmmLoadedImage.FilePath, FilePath, GetDevicePathSize (FilePath));
CopyMem (DriverEntry->SmmLoadedImage.FilePath, FilePath, GetDevicePathSize(FilePath));
DriverEntry->SmmLoadedImage.ImageBase = (VOID *)(UINTN)ImageContext.ImageAddress;
DriverEntry->SmmLoadedImage.ImageSize = ImageContext.ImageSize;
DriverEntry->SmmLoadedImage.ImageBase = DstBuffer;
DriverEntry->SmmLoadedImage.ImageSize = ImageSize;
DriverEntry->SmmLoadedImage.ImageCodeType = EfiRuntimeServicesCode;
DriverEntry->SmmLoadedImage.ImageDataType = EfiRuntimeServicesData;
@ -660,60 +578,42 @@ SmmLoadImage (
PERF_LOAD_IMAGE_END (DriverEntry->ImageHandle);
SmmInsertImageRecord (&DriverEntry->SmmLoadedImage, ImageContext);
//
// Register the image in the Debug Image Info Table if the attribute is set
//
SmmNewDebugImageInfoEntry (
EFI_DEBUG_IMAGE_INFO_TYPE_NORMAL,
&DriverEntry->SmmLoadedImage,
DriverEntry->SmmImageHandle,
ImageContext
);
//
// Print the load address and the PDB file name if it is available
//
DEBUG_CODE_BEGIN ();
UINTN Index;
UINTN StartIndex;
CHAR8 EfiFileName[256];
CHAR8 EfiFileName[256];
DEBUG ((
DEBUG_INFO | DEBUG_LOAD,
"Loading SMM driver at 0x%11p EntryPoint=0x%11p ",
(VOID *)(UINTN)ImageContext.ImageAddress,
FUNCTION_ENTRY_POINT (ImageContext.EntryPoint)
));
DEBUG ((DEBUG_INFO | DEBUG_LOAD,
"Loading SMM driver at 0x%11p EntryPoint=0x%11p ",
DstBuffer,
FUNCTION_ENTRY_POINT (UefiImageLoaderGetImageEntryPoint (ImageContext))));
//
// Print Module Name by Pdb file path.
// Windows and Unix style file path are all trimmed correctly.
//
if (ImageContext.PdbPointer != NULL) {
StartIndex = 0;
for (Index = 0; ImageContext.PdbPointer[Index] != 0; Index++) {
if ((ImageContext.PdbPointer[Index] == '\\') || (ImageContext.PdbPointer[Index] == '/')) {
StartIndex = Index + 1;
}
}
//
// Copy the PDB file name to our temporary string, and replace .pdb with .efi
// The PDB file name is limited in the range of 0~255.
// If the length is bigger than 255, trim the redundant characters to avoid overflow in array boundary.
//
for (Index = 0; Index < sizeof (EfiFileName) - 4; Index++) {
EfiFileName[Index] = ImageContext.PdbPointer[Index + StartIndex];
if (EfiFileName[Index] == 0) {
EfiFileName[Index] = '.';
}
if (EfiFileName[Index] == '.') {
EfiFileName[Index + 1] = 'e';
EfiFileName[Index + 2] = 'f';
EfiFileName[Index + 3] = 'i';
EfiFileName[Index + 4] = 0;
break;
}
}
if (Index == sizeof (EfiFileName) - 4) {
EfiFileName[Index] = 0;
}
DEBUG ((DEBUG_INFO | DEBUG_LOAD, "%a", EfiFileName)); // &Image->ImageContext.PdbPointer[StartIndex]));
Status = UefiImageGetModuleNameFromSymbolsPath (
ImageContext,
EfiFileName,
sizeof (EfiFileName)
);
if (!EFI_ERROR (Status)) {
DEBUG ((DEBUG_INFO | DEBUG_LOAD, "%a", EfiFileName));
}
DEBUG ((DEBUG_INFO | DEBUG_LOAD, "\n"));
@ -852,11 +752,12 @@ SmmDispatcher (
VOID
)
{
EFI_STATUS Status;
LIST_ENTRY *Link;
EFI_SMM_DRIVER_ENTRY *DriverEntry;
BOOLEAN ReadyToRun;
BOOLEAN PreviousSmmEntryPointRegistered;
EFI_STATUS Status;
LIST_ENTRY *Link;
EFI_SMM_DRIVER_ENTRY *DriverEntry;
BOOLEAN ReadyToRun;
BOOLEAN PreviousSmmEntryPointRegistered;
UEFI_IMAGE_LOADER_IMAGE_CONTEXT ImageContext;
if (!gRequestDispatch) {
return EFI_NOT_FOUND;
@ -889,8 +790,7 @@ SmmDispatcher (
// skip the LoadImage
//
if (DriverEntry->ImageHandle == NULL) {
Status = SmmLoadImage (DriverEntry);
Status = SmmLoadImage (DriverEntry, &ImageContext);
//
// Update the driver state to reflect that it's been loaded
//
@ -929,7 +829,7 @@ SmmDispatcher (
//
// For each SMM driver, pass NULL as ImageHandle
//
RegisterSmramProfileImage (DriverEntry, TRUE);
RegisterSmramProfileImage (&DriverEntry->FileName, TRUE, &ImageContext);
PERF_START_IMAGE_BEGIN (DriverEntry->ImageHandle);
Status = ((EFI_IMAGE_ENTRY_POINT)(UINTN)DriverEntry->ImageEntryPoint)(DriverEntry->ImageHandle, gST);
PERF_START_IMAGE_END (DriverEntry->ImageHandle);
@ -940,7 +840,12 @@ SmmDispatcher (
DriverEntry->SmmLoadedImage.ImageBase,
Status
));
UnregisterSmramProfileImage (DriverEntry, TRUE);
UnregisterSmramProfileImage (
&DriverEntry->FileName,
(UINTN) DriverEntry->LoadedImage->ImageBase,
DriverEntry->LoadedImage->ImageSize,
TRUE
);
SmmFreePages (DriverEntry->ImageBuffer, DriverEntry->NumberOfPage);
//
// Uninstall LoadedImage

View File

@ -22,7 +22,8 @@
#include <Library/UefiBootServicesTableLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/DebugLib.h>
#include "PiSmmCoreMemoryAllocationServices.h"
#include "PiSmmCore.h"
#include "PiSmmCorePrivateData.h"
#include <Library/MemoryProfileLib.h>

View File

@ -16,12 +16,12 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#include <Library/PcdLib.h>
#include <Library/ImagePropertiesRecordLib.h>
#include <Library/PeCoffLib.h>
#include <Library/PeCoffGetEntryPointLib.h>
#include <Library/UefiImageLib.h>
#include <Guid/PiSmmMemoryAttributesTable.h>
#include "PiSmmCore.h"
#include "ProcessorBind.h"
#define PREVIOUS_MEMORY_DESCRIPTOR(MemoryDescriptor, Size) \
((EFI_MEMORY_DESCRIPTOR *)((UINT8 *)(MemoryDescriptor) - (Size)))
@ -31,7 +31,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
typedef struct {
UINT32 Signature;
UINTN ImageRecordCount;
UINTN CodeSegmentCountMax;
UINT32 NumberOfSectionsMax;
LIST_ENTRY ImageRecordList;
} IMAGE_PROPERTIES_PRIVATE_DATA;
@ -212,7 +212,10 @@ SmmCoreGetMemoryMapMemoryAttributesTable (
return EFI_INVALID_PARAMETER;
}
AdditionalRecordCount = (2 * mImagePropertiesPrivateData.CodeSegmentCountMax + 3) * mImagePropertiesPrivateData.ImageRecordCount;
//
// Per image, they may be one trailer. There may be prefixed data.
//
AdditionalRecordCount = (mImagePropertiesPrivateData.NumberOfSectionsMax + 1) * mImagePropertiesPrivateData.ImageRecordCount + 1;
OldMemoryMapSize = *MemoryMapSize;
Status = SmmCoreGetMemoryMap (MemoryMapSize, MemoryMap, MapKey, DescriptorSize, DescriptorVersion);
@ -251,6 +254,98 @@ SmmCoreGetMemoryMapMemoryAttributesTable (
// Below functions are for ImageRecord
//
/**
Set MemoryProtectionAttribute according to PE/COFF image section alignment.
@param[in] SectionAlignment PE/COFF section alignment
**/
STATIC
VOID
SetMemoryAttributesTableSectionAlignment (
IN UINT32 SectionAlignment
)
{
if (((SectionAlignment & (RUNTIME_PAGE_ALLOCATION_GRANULARITY - 1)) != 0) &&
((mMemoryProtectionAttribute & EFI_MEMORY_ATTRIBUTES_RUNTIME_MEMORY_PROTECTION_NON_EXECUTABLE_PE_DATA) != 0))
{
DEBUG ((DEBUG_VERBOSE, "SMM SetMemoryAttributesTableSectionAlignment - Clear\n"));
mMemoryProtectionAttribute &= ~((UINT64)EFI_MEMORY_ATTRIBUTES_RUNTIME_MEMORY_PROTECTION_NON_EXECUTABLE_PE_DATA);
}
}
/**
Sort image record based upon the ImageBase from low to high.
**/
STATIC
VOID
InsertSortImageRecord (
IN UEFI_IMAGE_RECORD *NewImageRecord
)
{
UEFI_IMAGE_RECORD *ImageRecord;
LIST_ENTRY *PrevImageRecordLink;
LIST_ENTRY *ImageRecordLink;
LIST_ENTRY *ImageRecordList;
ImageRecordList = &mImagePropertiesPrivateData.ImageRecordList;
PrevImageRecordLink = ImageRecordList;
for (
ImageRecordLink = GetFirstNode (ImageRecordList);
!IsNull (ImageRecordLink, ImageRecordList);
ImageRecordLink = GetNextNode (ImageRecordList, PrevImageRecordLink)
) {
ImageRecord = CR (
ImageRecordLink,
UEFI_IMAGE_RECORD,
Link,
UEFI_IMAGE_RECORD_SIGNATURE
);
if (NewImageRecord->StartAddress < ImageRecord->StartAddress) {
break;
}
PrevImageRecordLink = ImageRecordLink;
}
InsertHeadList (PrevImageRecordLink, &NewImageRecord->Link);
mImagePropertiesPrivateData.ImageRecordCount++;
if (mImagePropertiesPrivateData.NumberOfSectionsMax < NewImageRecord->NumSegments) {
mImagePropertiesPrivateData.NumberOfSectionsMax = NewImageRecord->NumSegments;
}
}
/**
Dump image record.
**/
STATIC
VOID
DumpImageRecord (
VOID
)
{
UEFI_IMAGE_RECORD *ImageRecord;
LIST_ENTRY *ImageRecordLink;
LIST_ENTRY *ImageRecordList;
UINTN Index;
ImageRecordList = &mImagePropertiesPrivateData.ImageRecordList;
for (ImageRecordLink = ImageRecordList->ForwardLink, Index = 0;
ImageRecordLink != ImageRecordList;
ImageRecordLink = ImageRecordLink->ForwardLink, Index++)
{
ImageRecord = CR (
ImageRecordLink,
UEFI_IMAGE_RECORD,
Link,
UEFI_IMAGE_RECORD_SIGNATURE
);
DEBUG ((DEBUG_VERBOSE, "SMM Image[%d]: 0x%016lx - 0x%016lx\n", Index, ImageRecord->StartAddress, ImageRecord->EndAddress - ImageRecord->StartAddress));
}
}
/**
Insert image record.
@ -258,82 +353,60 @@ SmmCoreGetMemoryMapMemoryAttributesTable (
**/
VOID
SmmInsertImageRecord (
IN EFI_SMM_DRIVER_ENTRY *DriverEntry
IN EFI_LOADED_IMAGE_PROTOCOL *LoadedImage,
IN UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext
)
{
EFI_STATUS Status;
IMAGE_PROPERTIES_RECORD *ImageRecord;
CHAR8 *PdbPointer;
UINT32 RequiredAlignment;
RETURN_STATUS PdbStatus;
PHYSICAL_ADDRESS ImageBuffer;
UINTN NumberOfPage;
UINT32 SectionAlignment;
UEFI_IMAGE_RECORD *ImageRecord;
CONST CHAR8 *PdbPointer;
UINT32 PdbSize;
DEBUG ((DEBUG_VERBOSE, "SMM InsertImageRecord - 0x%x\n", DriverEntry));
ImageBuffer = (UINTN)LoadedImage->ImageBase;
NumberOfPage = EFI_SIZE_TO_PAGES((UINTN)LoadedImage->ImageSize);
ImageRecord = AllocatePool (sizeof (*ImageRecord));
DEBUG ((DEBUG_VERBOSE, "SMM InsertImageRecord - 0x%016lx - 0x%08x\n", ImageBuffer, NumberOfPage));
DEBUG ((DEBUG_VERBOSE, "SMM ImageRecordCount - 0x%x\n", mImagePropertiesPrivateData.ImageRecordCount));
PdbStatus = UefiImageGetSymbolsPath (ImageContext, &PdbPointer, &PdbSize);
if (!RETURN_ERROR (PdbStatus)) {
DEBUG ((DEBUG_VERBOSE, "SMM Image - %a\n", PdbPointer));
}
//
// Get SectionAlignment
//
SectionAlignment = UefiImageGetSegmentAlignment (ImageContext);
SetMemoryAttributesTableSectionAlignment (SectionAlignment);
if ((SectionAlignment & (RUNTIME_PAGE_ALLOCATION_GRANULARITY - 1)) != 0) {
DEBUG ((
DEBUG_WARN,
"SMM !!!!!!!! InsertImageRecord - Section Alignment(0x%x) is not %dK !!!!!!!!\n",
SectionAlignment, RUNTIME_PAGE_ALLOCATION_GRANULARITY >> 10));
if (!RETURN_ERROR (PdbStatus)) {
DEBUG ((DEBUG_WARN, "SMM !!!!!!!! Image - %a !!!!!!!!\n", PdbPointer));
}
return;
}
//
// The image headers are not recorded among the sections, allocate one more.
//
ImageRecord = UefiImageLoaderGetImageRecord (ImageContext);
if (ImageRecord == NULL) {
return;
}
InitializeListHead (&ImageRecord->Link);
InitializeListHead (&ImageRecord->CodeSegmentList);
UefiImageDebugPrintSegments (ImageContext);
UefiImageDebugPrintImageRecord (ImageRecord);
PdbPointer = PeCoffLoaderGetPdbPointer ((VOID *)(UINTN)DriverEntry->ImageBuffer);
if (PdbPointer != NULL) {
DEBUG ((DEBUG_VERBOSE, "SMM Image - %a\n", PdbPointer));
}
RequiredAlignment = RUNTIME_PAGE_ALLOCATION_GRANULARITY;
Status = CreateImagePropertiesRecord (
(VOID *)(UINTN)DriverEntry->ImageBuffer,
LShiftU64 (DriverEntry->NumberOfPage, EFI_PAGE_SHIFT),
&RequiredAlignment,
ImageRecord
);
if (EFI_ERROR (Status)) {
if (Status == EFI_ABORTED) {
mMemoryProtectionAttribute &=
~((UINT64)EFI_MEMORY_ATTRIBUTES_RUNTIME_MEMORY_PROTECTION_NON_EXECUTABLE_PE_DATA);
}
goto Finish;
}
if (ImageRecord->CodeSegmentCount == 0) {
mMemoryProtectionAttribute &=
~((UINT64)EFI_MEMORY_ATTRIBUTES_RUNTIME_MEMORY_PROTECTION_NON_EXECUTABLE_PE_DATA);
DEBUG ((DEBUG_ERROR, "SMM !!!!!!!! InsertImageRecord - CodeSegmentCount is 0 !!!!!!!!\n"));
if (PdbPointer != NULL) {
DEBUG ((DEBUG_ERROR, "SMM !!!!!!!! Image - %a !!!!!!!!\n", PdbPointer));
}
Status = EFI_ABORTED;
goto Finish;
}
//
// Check overlap all section in ImageBase/Size
//
if (!IsImageRecordCodeSectionValid (ImageRecord)) {
DEBUG ((DEBUG_ERROR, "SMM IsImageRecordCodeSectionValid - FAIL\n"));
Status = EFI_ABORTED;
goto Finish;
}
InsertTailList (&mImagePropertiesPrivateData.ImageRecordList, &ImageRecord->Link);
mImagePropertiesPrivateData.ImageRecordCount++;
if (mImagePropertiesPrivateData.CodeSegmentCountMax < ImageRecord->CodeSegmentCount) {
mImagePropertiesPrivateData.CodeSegmentCountMax = ImageRecord->CodeSegmentCount;
}
SortImageRecord (&mImagePropertiesPrivateData.ImageRecordList);
Finish:
if (EFI_ERROR (Status) && (ImageRecord != NULL)) {
DeleteImagePropertiesRecord (ImageRecord);
}
return;
InsertSortImageRecord (ImageRecord);
}
/**
@ -418,60 +491,6 @@ PublishMemoryAttributesTable (
ASSERT_EFI_ERROR (Status);
}
/**
This function installs all SMM image record information.
**/
VOID
SmmInstallImageRecord (
VOID
)
{
EFI_STATUS Status;
UINTN NoHandles;
EFI_HANDLE *HandleBuffer;
EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;
UINTN Index;
EFI_SMM_DRIVER_ENTRY DriverEntry;
Status = SmmLocateHandleBuffer (
ByProtocol,
&gEfiLoadedImageProtocolGuid,
NULL,
&NoHandles,
&HandleBuffer
);
if (EFI_ERROR (Status)) {
return;
}
for (Index = 0; Index < NoHandles; Index++) {
Status = gSmst->SmmHandleProtocol (
HandleBuffer[Index],
&gEfiLoadedImageProtocolGuid,
(VOID **)&LoadedImage
);
if (EFI_ERROR (Status)) {
continue;
}
DEBUG ((DEBUG_VERBOSE, "LoadedImage - 0x%x 0x%x ", LoadedImage->ImageBase, LoadedImage->ImageSize));
{
VOID *PdbPointer;
PdbPointer = PeCoffLoaderGetPdbPointer (LoadedImage->ImageBase);
if (PdbPointer != NULL) {
DEBUG ((DEBUG_VERBOSE, "(%a) ", PdbPointer));
}
}
DEBUG ((DEBUG_VERBOSE, "\n"));
ZeroMem (&DriverEntry, sizeof (DriverEntry));
DriverEntry.ImageBuffer = (UINTN)LoadedImage->ImageBase;
DriverEntry.NumberOfPage = EFI_SIZE_TO_PAGES ((UINTN)LoadedImage->ImageSize);
SmmInsertImageRecord (&DriverEntry);
}
FreePool (HandleBuffer);
}
/**
Install MemoryAttributesTable.
@ -489,8 +508,6 @@ SmmInstallMemoryAttributesTable (
IN EFI_HANDLE Handle
)
{
SmmInstallImageRecord ();
DEBUG ((DEBUG_VERBOSE, "SMM MemoryProtectionAttribute - 0x%016lx\n", mMemoryProtectionAttribute));
if ((mMemoryProtectionAttribute & EFI_MEMORY_ATTRIBUTES_RUNTIME_MEMORY_PROTECTION_NON_EXECUTABLE_PE_DATA) == 0) {
return EFI_SUCCESS;
@ -500,7 +517,7 @@ SmmInstallMemoryAttributesTable (
if ( mImagePropertiesPrivateData.ImageRecordCount > 0) {
DEBUG ((DEBUG_INFO, "SMM - Total Runtime Image Count - 0x%x\n", mImagePropertiesPrivateData.ImageRecordCount));
DEBUG ((DEBUG_INFO, "SMM - Dump Runtime Image Records:\n"));
DumpImageRecords (&mImagePropertiesPrivateData.ImageRecordList);
DumpImageRecord ();
}
DEBUG_CODE_END ();

View File

@ -815,7 +815,7 @@ SmmCoreInstallLoadedImage (
mSmmCoreLoadedImage->SystemTable = gST;
mSmmCoreLoadedImage->ImageBase = (VOID *)(UINTN)gSmmCorePrivate->PiSmmCoreImageBase;
mSmmCoreLoadedImage->ImageSize = gSmmCorePrivate->PiSmmCoreImageSize;
mSmmCoreLoadedImage->ImageSize = UefiImageGetImageSize (&gSmmCorePrivate->PiSmmCoreImageContext);
mSmmCoreLoadedImage->ImageCodeType = EfiRuntimeServicesCode;
mSmmCoreLoadedImage->ImageDataType = EfiRuntimeServicesData;
@ -847,13 +847,13 @@ SmmCoreInstallLoadedImage (
mSmmCoreDriverEntry->SmmLoadedImage.SystemTable = gST;
mSmmCoreDriverEntry->SmmLoadedImage.ImageBase = (VOID *)(UINTN)gSmmCorePrivate->PiSmmCoreImageBase;
mSmmCoreDriverEntry->SmmLoadedImage.ImageSize = gSmmCorePrivate->PiSmmCoreImageSize;
mSmmCoreDriverEntry->SmmLoadedImage.ImageSize = UefiImageGetImageSize (&gSmmCorePrivate->PiSmmCoreImageContext);
mSmmCoreDriverEntry->SmmLoadedImage.ImageCodeType = EfiRuntimeServicesCode;
mSmmCoreDriverEntry->SmmLoadedImage.ImageDataType = EfiRuntimeServicesData;
mSmmCoreDriverEntry->ImageEntryPoint = gSmmCorePrivate->PiSmmCoreEntryPoint;
mSmmCoreDriverEntry->ImageEntryPoint = UefiImageLoaderGetImageEntryPoint (&gSmmCorePrivate->PiSmmCoreImageContext);
mSmmCoreDriverEntry->ImageBuffer = gSmmCorePrivate->PiSmmCoreImageBase;
mSmmCoreDriverEntry->NumberOfPage = EFI_SIZE_TO_PAGES ((UINTN)gSmmCorePrivate->PiSmmCoreImageSize);
mSmmCoreDriverEntry->NumberOfPage = EFI_SIZE_TO_PAGES ((UINTN)UefiImageGetImageSize (&gSmmCorePrivate->PiSmmCoreImageContext));
//
// Create a new image handle in the SMM handle database for the SMM Driver
@ -867,6 +867,21 @@ SmmCoreInstallLoadedImage (
);
ASSERT_EFI_ERROR (Status);
SmmInsertImageRecord (&mSmmCoreDriverEntry->SmmLoadedImage, &gSmmCorePrivate->PiSmmCoreImageContext);
//
// Create the aligned system table pointer structure that is used by external
// debuggers to locate the system table... Also, install debug image info
// configuration table.
//
SmmInitializeDebugImageInfoTable ();
SmmNewDebugImageInfoEntry (
EFI_DEBUG_IMAGE_INFO_TYPE_NORMAL,
&mSmmCoreDriverEntry->SmmLoadedImage,
mSmmCoreDriverEntry->SmmImageHandle,
&gSmmCorePrivate->PiSmmCoreImageContext
);
return;
}

View File

@ -37,11 +37,11 @@
#include <Guid/SmiHandlerProfile.h>
#include <Guid/EndOfS3Resume.h>
#include <Guid/S3SmmInitDone.h>
#include <Guid/DebugImageInfoTable.h>
#include <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/PeCoffLib.h>
#include <Library/PeCoffGetEntryPointLib.h>
#include <Library/UefiImageLib.h>
#include <Library/CacheMaintenanceLib.h>
#include <Library/DebugLib.h>
#include <Library/ReportStatusCodeLib.h>
@ -55,6 +55,7 @@
#include <Library/HobLib.h>
#include <Library/SmmMemLib.h>
#include <Library/SafeIntLib.h>
#include <Library/SmmServicesTableLib.h>
#include "PiSmmCorePrivateData.h"
#include "HeapGuard.h"
@ -1020,8 +1021,9 @@ SmramProfileInstallProtocol (
**/
EFI_STATUS
RegisterSmramProfileImage (
IN EFI_SMM_DRIVER_ENTRY *DriverEntry,
IN BOOLEAN RegisterToDxe
IN EFI_GUID *FileName,
IN BOOLEAN RegisterToDxe,
IN UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext
);
/**
@ -1038,8 +1040,10 @@ RegisterSmramProfileImage (
**/
EFI_STATUS
UnregisterSmramProfileImage (
IN EFI_SMM_DRIVER_ENTRY *DriverEntry,
IN BOOLEAN UnregisterToDxe
IN EFI_GUID *FileName,
IN PHYSICAL_ADDRESS ImageBase,
IN UINT64 ImageSize,
IN BOOLEAN UnregisterFromDxe
);
/**
@ -1352,4 +1356,50 @@ SmmEntryPointMemoryManagementHook (
VOID
);
/**
Creates and initializes the DebugImageInfo Table. Also creates the configuration
table and registers it into the system table.
Note:
This function allocates memory, frees it, and then allocates memory at an
address within the initial allocation. Since this function is called early
in DXE core initialization (before drivers are dispatched), this should not
be a problem.
**/
VOID
SmmInitializeDebugImageInfoTable (
VOID
);
/**
Adds a new DebugImageInfo structure to the DebugImageInfo Table. Re-Allocates
the table if it's not large enough to accomidate another entry.
@param ImageInfoType type of debug image information
@param LoadedImage pointer to the loaded image protocol for the image being
loaded
@param ImageHandle image handle for the image being loaded
**/
VOID
SmmNewDebugImageInfoEntry (
IN UINT32 ImageInfoType,
IN EFI_LOADED_IMAGE_PROTOCOL *LoadedImage,
IN EFI_HANDLE ImageHandle,
IN UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext
);
/**
Insert image record.
@param[in] DriverEntry Driver information
**/
VOID
SmmInsertImageRecord (
IN EFI_LOADED_IMAGE_PROTOCOL *LoadedImage,
IN UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext
);
#endif

View File

@ -37,6 +37,8 @@
SmiHandlerProfile.c
HeapGuard.c
HeapGuard.h
MemoryAllocation.c
DebugImageInfo.c
[Packages]
MdePkg/MdePkg.dec
@ -46,8 +48,7 @@
UefiDriverEntryPoint
BaseLib
BaseMemoryLib
PeCoffLib
PeCoffGetEntryPointLib
UefiImageLib
CacheMaintenanceLib
DebugLib
ReportStatusCodeLib
@ -99,6 +100,7 @@
gEfiMdeModulePkgTokenSpaceGuid.PcdHeapGuardPoolType ## CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdHeapGuardPropertyMask ## CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiS3Enable ## CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdMaxEfiSystemTablePointerAddress ## CONSUMES
[Guids]
gAprioriGuid ## SOMETIMES_CONSUMES ## File
@ -120,6 +122,7 @@
gSmiHandlerProfileGuid
gEdkiiEndOfS3ResumeGuid ## SOMETIMES_PRODUCES ## GUID # Install protocol
gEdkiiS3SmmInitDoneGuid ## SOMETIMES_PRODUCES ## GUID # Install protocol
gEfiDebugImageInfoTableGuid ## PRODUCES ## SystemTable
[UserExtensions.TianoCore."ExtraFiles"]
PiSmmCoreExtra.uni

View File

@ -22,6 +22,7 @@
/// the SMM Entry Point enabling the use of SMM Mode. In this case, the SMM Core
/// should be notified again to dispatch more SMM Drivers using SMM Mode.
///
#include "Library/UefiImageLib.h"
#define COMM_BUFFER_SMM_DISPATCH_ERROR 0x00
#define COMM_BUFFER_SMM_DISPATCH_SUCCESS 0x01
#define COMM_BUFFER_SMM_DISPATCH_RESTART 0x02
@ -112,8 +113,7 @@ typedef struct {
EFI_STATUS ReturnStatus;
EFI_PHYSICAL_ADDRESS PiSmmCoreImageBase;
UINT64 PiSmmCoreImageSize;
EFI_PHYSICAL_ADDRESS PiSmmCoreEntryPoint;
UEFI_IMAGE_LOADER_IMAGE_CONTEXT PiSmmCoreImageContext;
} SMM_CORE_PRIVATE_DATA;
#endif

View File

@ -23,7 +23,7 @@
#include <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/PeCoffLib.h>
#include <Library/UefiImageLib.h>
#include <Library/CacheMaintenanceLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/DebugLib.h>
@ -36,6 +36,8 @@
#include <Library/ReportStatusCodeLib.h>
#include "PiSmmCorePrivateData.h"
#include <Library/SafeIntLib.h>
#include "ProcessorBind.h"
#include "Uefi/UefiBaseType.h"
#define SMRAM_CAPABILITIES (EFI_MEMORY_WB | EFI_MEMORY_UC)
@ -913,91 +915,41 @@ SmmIplSetVirtualAddressNotify (
@retval EFI_NOT_FOUND The image has no assigned fixed loading address.
**/
EFI_STATUS
GetPeCoffImageFixLoadingAssignedAddress (
IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext
GetUefiImageFixLoadingAssignedAddress (
IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext,
OUT EFI_PHYSICAL_ADDRESS *LoadAddress
)
{
UINTN SectionHeaderOffset;
EFI_STATUS Status;
EFI_IMAGE_SECTION_HEADER SectionHeader;
EFI_IMAGE_OPTIONAL_HEADER_UNION *ImgHdr;
EFI_PHYSICAL_ADDRESS FixLoadingAddress;
UINT16 Index;
UINTN Size;
UINT16 NumberOfSections;
EFI_PHYSICAL_ADDRESS SmramBase;
UINT64 SmmCodeSize;
UINT64 ValueInSectionHeader;
EFI_STATUS Status;
UINT64 ValueInSectionHeader;
EFI_PHYSICAL_ADDRESS FixLoadingAddress;
UINT32 SizeOfImage;
EFI_PHYSICAL_ADDRESS SmramBase;
UINT64 SmmCodeSize;
Status = UefiImageGetFixedAddress (ImageContext, &ValueInSectionHeader);
if (RETURN_ERROR (Status)) {
return Status;
}
//
// Build tool will calculate the smm code size and then patch the PcdLoadFixAddressSmmCodePageNumber
//
SmmCodeSize = EFI_PAGES_TO_SIZE (PcdGet32 (PcdLoadFixAddressSmmCodePageNumber));
SmmCodeSize = EFI_PAGES_TO_SIZE (PcdGet32(PcdLoadFixAddressSmmCodePageNumber));
SmramBase = mLMFAConfigurationTable->SmramBase;
FixLoadingAddress = 0;
Status = EFI_NOT_FOUND;
SmramBase = mLMFAConfigurationTable->SmramBase;
//
// Get PeHeader pointer
//
ImgHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)((CHAR8 *)ImageContext->Handle + ImageContext->PeCoffHeaderOffset);
SectionHeaderOffset = ImageContext->PeCoffHeaderOffset +
sizeof (UINT32) +
sizeof (EFI_IMAGE_FILE_HEADER) +
ImgHdr->Pe32.FileHeader.SizeOfOptionalHeader;
NumberOfSections = ImgHdr->Pe32.FileHeader.NumberOfSections;
FixLoadingAddress = SmramBase + ValueInSectionHeader;
SizeOfImage = UefiImageGetImageSize (ImageContext);
//
// Get base address from the first section header that doesn't point to code section.
//
for (Index = 0; Index < NumberOfSections; Index++) {
if (SmramBase + SmmCodeSize >= FixLoadingAddress + SizeOfImage
&& SmramBase <= FixLoadingAddress) {
//
// Read section header from file
// The assigned address is valid. Return the specified loading address
//
Size = sizeof (EFI_IMAGE_SECTION_HEADER);
Status = ImageContext->ImageRead (
ImageContext->Handle,
SectionHeaderOffset,
&Size,
&SectionHeader
);
if (EFI_ERROR (Status)) {
return Status;
}
Status = EFI_NOT_FOUND;
if ((SectionHeader.Characteristics & EFI_IMAGE_SCN_CNT_CODE) == 0) {
//
// Build tool saves the offset to SMRAM base as image base in PointerToRelocations & PointerToLineNumbers fields in the
// first section header that doesn't point to code section in image header. And there is an assumption that when the
// feature is enabled, if a module is assigned a loading address by tools, PointerToRelocations & PointerToLineNumbers
// fields should NOT be Zero, or else, these 2 fields should be set to Zero
//
ValueInSectionHeader = ReadUnaligned64 ((UINT64 *)&SectionHeader.PointerToRelocations);
if (ValueInSectionHeader != 0) {
//
// Found first section header that doesn't point to code section in which build tool saves the
// offset to SMRAM base as image base in PointerToRelocations & PointerToLineNumbers fields
//
FixLoadingAddress = (EFI_PHYSICAL_ADDRESS)(SmramBase + (INT64)ValueInSectionHeader);
if ((SmramBase + SmmCodeSize > FixLoadingAddress) && (SmramBase <= FixLoadingAddress)) {
//
// The assigned address is valid. Return the specified loading address
//
ImageContext->ImageAddress = FixLoadingAddress;
Status = EFI_SUCCESS;
}
}
break;
}
SectionHeaderOffset += sizeof (EFI_IMAGE_SECTION_HEADER);
*LoadAddress = FixLoadingAddress;
Status = EFI_SUCCESS;
}
DEBUG ((DEBUG_INFO|DEBUG_LOAD, "LOADING MODULE FIXED INFO: Loading module at fixed address %x, Status = %r \n", FixLoadingAddress, Status));
DEBUG ((EFI_D_INFO|EFI_D_LOAD, "LOADING MODULE FIXED INFO: Loading module at fixed address %x, Status = %r \n", FixLoadingAddress, Status));
return Status;
}
@ -1024,9 +976,14 @@ ExecuteSmmCoreFromSmram (
EFI_STATUS Status;
VOID *SourceBuffer;
UINTN SourceSize;
PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;
UINT32 ImageSize;
UINT32 ImageAlignment;
UINT32 DestinationPages;
UINT32 DestinationSize;
UINT32 AlignSubtrahend;
UINTN PageCount;
EFI_IMAGE_ENTRY_POINT EntryPoint;
EFI_PHYSICAL_ADDRESS LoadAddress;
//
// Search all Firmware Volumes for a PE/COFF image in a file of type SMM_CORE
@ -1043,20 +1000,26 @@ ExecuteSmmCoreFromSmram (
return Status;
}
//
// Initialize ImageContext
//
ImageContext.Handle = SourceBuffer;
ImageContext.ImageRead = PeCoffLoaderImageReadFromMemory;
//
// Get information about the image being loaded
//
Status = PeCoffLoaderGetImageInfo (&ImageContext);
Status = UefiImageInitializeContext (&gSmmCorePrivate->PiSmmCoreImageContext, SourceBuffer, (UINT32) SourceSize);
if (EFI_ERROR (Status)) {
return Status;
}
//
// Stripped relocations are not supported for both fixed-address and dynamic
// loading.
//
if (UefiImageGetRelocsStripped (&gSmmCorePrivate->PiSmmCoreImageContext)) {
return EFI_UNSUPPORTED;
}
ImageSize = UefiImageGetImageSize (&gSmmCorePrivate->PiSmmCoreImageContext);
DestinationPages = EFI_SIZE_TO_PAGES (ImageSize);
DestinationSize = EFI_PAGES_TO_SIZE (DestinationPages);
ImageAlignment = UefiImageGetSegmentAlignment (&gSmmCorePrivate->PiSmmCoreImageContext);
//
// if Loading module at Fixed Address feature is enabled, the SMM core driver will be loaded to
// the address assigned by build tool.
@ -1065,7 +1028,7 @@ ExecuteSmmCoreFromSmram (
//
// Get the fixed loading address assigned by Build tool
//
Status = GetPeCoffImageFixLoadingAssignedAddress (&ImageContext);
Status = GetUefiImageFixLoadingAssignedAddress (&gSmmCorePrivate->PiSmmCoreImageContext, &LoadAddress);
if (!EFI_ERROR (Status)) {
//
// Since the memory range to load SMM CORE will be cut out in SMM core, so no need to allocate and free this range
@ -1081,7 +1044,11 @@ ExecuteSmmCoreFromSmram (
// Allocate memory for the image being loaded from the EFI_SRAM_DESCRIPTOR
// specified by SmramRange
//
PageCount = (UINTN)EFI_SIZE_TO_PAGES ((UINTN)ImageContext.ImageSize + ImageContext.SectionAlignment);
AlignSubtrahend = ALIGN_VALUE_SUBTRAHEND (
SmramRange->CpuStart + SmramRange->PhysicalSize,
ImageAlignment
);
PageCount = (UINTN)DestinationPages + (UINTN)EFI_SIZE_TO_PAGES ((UINTN)AlignSubtrahend);
ASSERT ((SmramRange->PhysicalSize & EFI_PAGE_MASK) == 0);
ASSERT (SmramRange->PhysicalSize > EFI_PAGES_TO_SIZE (PageCount));
@ -1095,14 +1062,18 @@ ExecuteSmmCoreFromSmram (
//
// Align buffer on section boundary
//
ImageContext.ImageAddress = SmramRangeSmmCore->CpuStart;
LoadAddress = SmramRangeSmmCore->CpuStart;
}
} else {
//
// Allocate memory for the image being loaded from the EFI_SRAM_DESCRIPTOR
// specified by SmramRange
//
PageCount = (UINTN)EFI_SIZE_TO_PAGES ((UINTN)ImageContext.ImageSize + ImageContext.SectionAlignment);
AlignSubtrahend = ALIGN_VALUE_SUBTRAHEND (
SmramRange->CpuStart + SmramRange->PhysicalSize,
ImageAlignment
);
PageCount = (UINTN)DestinationPages + (UINTN)EFI_SIZE_TO_PAGES ((UINTN)AlignSubtrahend);
ASSERT ((SmramRange->PhysicalSize & EFI_PAGE_MASK) == 0);
ASSERT (SmramRange->PhysicalSize > EFI_PAGES_TO_SIZE (PageCount));
@ -1116,50 +1087,34 @@ ExecuteSmmCoreFromSmram (
//
// Align buffer on section boundary
//
ImageContext.ImageAddress = SmramRangeSmmCore->CpuStart;
LoadAddress = SmramRangeSmmCore->CpuStart;
}
ImageContext.ImageAddress += ImageContext.SectionAlignment - 1;
ImageContext.ImageAddress &= ~((EFI_PHYSICAL_ADDRESS)ImageContext.SectionAlignment - 1);
//
// Print debug message showing SMM Core load address.
//
DEBUG ((DEBUG_INFO, "SMM IPL loading SMM Core at SMRAM address %p\n", (VOID *)(UINTN)ImageContext.ImageAddress));
DEBUG ((DEBUG_INFO, "SMM IPL loading SMM Core at SMRAM destination %p\n", (VOID *)(UINTN)LoadAddress));
//
// Load the image to our new buffer
//
Status = PeCoffLoaderLoadImage (&ImageContext);
Status = UefiImageLoadImageForExecution (&gSmmCorePrivate->PiSmmCoreImageContext, (VOID *)(UINTN)LoadAddress, DestinationSize, NULL, 0);
if (!EFI_ERROR (Status)) {
LoadAddress = UefiImageLoaderGetImageAddress (&gSmmCorePrivate->PiSmmCoreImageContext);
//
// Relocate the image in our new buffer
// Print debug message showing SMM Core entry point address.
//
Status = PeCoffLoaderRelocateImage (&ImageContext);
if (!EFI_ERROR (Status)) {
//
// Flush the instruction cache so the image data are written before we execute it
//
InvalidateInstructionCacheRange ((VOID *)(UINTN)ImageContext.ImageAddress, (UINTN)ImageContext.ImageSize);
DEBUG ((DEBUG_INFO, "SMM IPL calling SMM Core at SMRAM address %p\n", (VOID *)(UINTN)(UefiImageLoaderGetImageEntryPoint (&gSmmCorePrivate->PiSmmCoreImageContext))));
//
// Print debug message showing SMM Core entry point address.
//
DEBUG ((DEBUG_INFO, "SMM IPL calling SMM Core at SMRAM address %p\n", (VOID *)(UINTN)ImageContext.EntryPoint));
gSmmCorePrivate->PiSmmCoreImageBase = LoadAddress;
DEBUG ((DEBUG_INFO, "PiSmmCoreImageBase - 0x%016lx\n", gSmmCorePrivate->PiSmmCoreImageBase));
DEBUG ((DEBUG_INFO, "PiSmmCoreImageSize - 0x%016lx\n", UefiImageGetImageSize (&gSmmCorePrivate->PiSmmCoreImageContext)));
gSmmCorePrivate->PiSmmCoreImageBase = ImageContext.ImageAddress;
gSmmCorePrivate->PiSmmCoreImageSize = ImageContext.ImageSize;
DEBUG ((DEBUG_INFO, "PiSmmCoreImageBase - 0x%016lx\n", gSmmCorePrivate->PiSmmCoreImageBase));
DEBUG ((DEBUG_INFO, "PiSmmCoreImageSize - 0x%016lx\n", gSmmCorePrivate->PiSmmCoreImageSize));
gSmmCorePrivate->PiSmmCoreEntryPoint = ImageContext.EntryPoint;
//
// Execute image
//
EntryPoint = (EFI_IMAGE_ENTRY_POINT)(UINTN)ImageContext.EntryPoint;
Status = EntryPoint ((EFI_HANDLE)Context, gST);
}
//
// Execute image
//
EntryPoint = (EFI_IMAGE_ENTRY_POINT)(UINTN)(UefiImageLoaderGetImageEntryPoint (&gSmmCorePrivate->PiSmmCoreImageContext));
Status = EntryPoint ((EFI_HANDLE)Context, gST);
}
//

View File

@ -35,7 +35,7 @@
UefiDriverEntryPoint
BaseLib
BaseMemoryLib
PeCoffLib
UefiImageLib
CacheMaintenanceLib
MemoryAllocationLib
DebugLib

View File

@ -16,7 +16,6 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#include <Library/PrintLib.h>
#include <Library/UefiLib.h>
#include <Library/DevicePathLib.h>
#include <Library/PeCoffGetEntryPointLib.h>
#include <Protocol/LoadedImage.h>
#include <Protocol/SmmAccess2.h>
#include <Protocol/SmmReadyToLock.h>
@ -65,7 +64,7 @@ RegisterSmiHandlerProfileHandler (
**/
RETURN_STATUS
InternalPeCoffGetEntryPoint (
InternalUefiImageGetEntryPoint (
IN VOID *Pe32Data,
OUT VOID **EntryPoint
);
@ -255,7 +254,6 @@ GetSmmLoadedImage (
CHAR16 *PathStr;
EFI_SMM_DRIVER_ENTRY *LoadedImagePrivate;
PHYSICAL_ADDRESS EntryPoint;
VOID *EntryPointInImage;
EFI_GUID Guid;
CHAR8 *PdbString;
PHYSICAL_ADDRESS RealImageBase;
@ -315,15 +313,6 @@ GetSmmLoadedImage (
RealImageBase = (UINTN)LoadedImage->ImageBase;
if (LoadedImagePrivate->Signature == EFI_SMM_DRIVER_ENTRY_SIGNATURE) {
EntryPoint = LoadedImagePrivate->ImageEntryPoint;
if ((EntryPoint != 0) && ((EntryPoint < (UINTN)LoadedImage->ImageBase) || (EntryPoint >= ((UINTN)LoadedImage->ImageBase + LoadedImage->ImageSize)))) {
//
// If the EntryPoint is not in the range of image buffer, it should come from emulation environment.
// So patch ImageBuffer here to align the EntryPoint.
//
Status = InternalPeCoffGetEntryPoint (LoadedImage->ImageBase, &EntryPointInImage);
ASSERT_EFI_ERROR (Status);
RealImageBase = (UINTN)LoadedImage->ImageBase + EntryPoint - (UINTN)EntryPointInImage;
}
}
DEBUG ((DEBUG_INFO, "(0x%lx - 0x%lx", RealImageBase, LoadedImage->ImageSize));
@ -333,10 +322,11 @@ GetSmmLoadedImage (
DEBUG ((DEBUG_INFO, ")\n"));
if (RealImageBase != 0) {
PdbString = PeCoffLoaderGetPdbPointer ((VOID *)(UINTN)RealImageBase);
// FIXME:
/*if (RealImageBase != 0) {
PdbString = UefiImageLoaderGetPdbPointer ((VOID *)(UINTN)RealImageBase);
DEBUG ((DEBUG_INFO, " pdb - %a\n", PdbString));
} else {
} else*/ {
PdbString = NULL;
}

View File

@ -128,8 +128,7 @@ EFIAPI
SmramProfileProtocolRegisterImage (
IN EDKII_SMM_MEMORY_PROFILE_PROTOCOL *This,
IN EFI_DEVICE_PATH_PROTOCOL *FilePath,
IN PHYSICAL_ADDRESS ImageBase,
IN UINT64 ImageSize,
IN UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext,
IN EFI_FV_FILETYPE FileType
);
@ -249,110 +248,6 @@ GetSmramProfileContext (
return mSmramProfileContextPtr;
}
/**
Retrieves and returns the Subsystem of a PE/COFF image that has been loaded into system memory.
If Pe32Data is NULL, then ASSERT().
@param Pe32Data The pointer to the PE/COFF image that is loaded in system memory.
@return The Subsystem of the PE/COFF image.
**/
UINT16
InternalPeCoffGetSubsystem (
IN VOID *Pe32Data
)
{
EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr;
EFI_IMAGE_DOS_HEADER *DosHdr;
UINT16 Magic;
ASSERT (Pe32Data != NULL);
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) {
return Hdr.Te->Subsystem;
} else if (Hdr.Pe32->Signature == EFI_IMAGE_NT_SIGNATURE) {
Magic = Hdr.Pe32->OptionalHeader.Magic;
if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
return Hdr.Pe32->OptionalHeader.Subsystem;
} else if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) {
return Hdr.Pe32Plus->OptionalHeader.Subsystem;
}
}
return 0x0000;
}
/**
Retrieves and returns a pointer to the entry point to a PE/COFF image that has been loaded
into system memory with the PE/COFF Loader Library functions.
Retrieves the entry point to the PE/COFF image specified by Pe32Data and returns this entry
point in EntryPoint. If the entry point could not be retrieved from the PE/COFF image, then
return RETURN_INVALID_PARAMETER. Otherwise return RETURN_SUCCESS.
If Pe32Data is NULL, then ASSERT().
If EntryPoint is NULL, then ASSERT().
@param Pe32Data The pointer to the PE/COFF image that is loaded in system memory.
@param EntryPoint The pointer to entry point to the PE/COFF image to return.
@retval RETURN_SUCCESS EntryPoint was returned.
@retval RETURN_INVALID_PARAMETER The entry point could not be found in the PE/COFF image.
**/
RETURN_STATUS
InternalPeCoffGetEntryPoint (
IN VOID *Pe32Data,
OUT VOID **EntryPoint
)
{
EFI_IMAGE_DOS_HEADER *DosHdr;
EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr;
ASSERT (Pe32Data != NULL);
ASSERT (EntryPoint != NULL);
DosHdr = (EFI_IMAGE_DOS_HEADER *)Pe32Data;
if (DosHdr->e_magic == EFI_IMAGE_DOS_SIGNATURE) {
//
// DOS image header is present, so read the PE header after the DOS image header.
//
Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)((UINTN)Pe32Data + (UINTN)((DosHdr->e_lfanew) & 0x0ffff));
} else {
//
// DOS image header is not present, so PE header is at the image base.
//
Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)Pe32Data;
}
//
// Calculate the entry point relative to the start of the image.
// AddressOfEntryPoint is common for PE32 & PE32+
//
if (Hdr.Te->Signature == EFI_TE_IMAGE_HEADER_SIGNATURE) {
*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;
}
/**
Build driver info.
@ -371,30 +266,26 @@ MEMORY_PROFILE_DRIVER_INFO_DATA *
BuildDriverInfo (
IN MEMORY_PROFILE_CONTEXT_DATA *ContextData,
IN EFI_GUID *FileName,
IN PHYSICAL_ADDRESS ImageBase,
IN UINT64 ImageSize,
IN PHYSICAL_ADDRESS EntryPoint,
IN UINT16 ImageSubsystem,
IN UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext,
IN EFI_PHYSICAL_ADDRESS LoadAddress,
IN EFI_FV_FILETYPE FileType
)
{
RETURN_STATUS PdbStatus;
EFI_STATUS Status;
MEMORY_PROFILE_DRIVER_INFO *DriverInfo;
MEMORY_PROFILE_DRIVER_INFO_DATA *DriverInfoData;
VOID *EntryPointInImage;
CHAR8 *PdbString;
UINTN PdbSize;
UINTN PdbOccupiedSize;
MEMORY_PROFILE_DRIVER_INFO_DATA *DriverInfoData;
CONST CHAR8 *PdbString;
UINT32 PdbSize;
UINTN PdbOccupiedSize;
PdbSize = 0;
PdbOccupiedSize = 0;
PdbString = NULL;
if (ImageBase != 0) {
PdbString = PeCoffLoaderGetPdbPointer ((VOID *)(UINTN)ImageBase);
if (PdbString != NULL) {
PdbSize = AsciiStrSize (PdbString);
PdbOccupiedSize = GET_OCCUPIED_SIZE (PdbSize, sizeof (UINT64));
}
ASSERT (UefiImageLoaderGetImageAddress (ImageContext) != 0);
PdbStatus = UefiImageGetSymbolsPath (ImageContext, &PdbString, &PdbSize);
if (!EFI_ERROR (PdbStatus)) {
PdbOccupiedSize = GET_OCCUPIED_SIZE (PdbSize, sizeof (UINT64));
}
//
@ -422,19 +313,10 @@ BuildDriverInfo (
CopyMem (&DriverInfo->FileName, FileName, sizeof (EFI_GUID));
}
DriverInfo->ImageBase = ImageBase;
DriverInfo->ImageSize = ImageSize;
DriverInfo->EntryPoint = EntryPoint;
DriverInfo->ImageSubsystem = ImageSubsystem;
if ((EntryPoint != 0) && ((EntryPoint < ImageBase) || (EntryPoint >= (ImageBase + ImageSize)))) {
//
// If the EntryPoint is not in the range of image buffer, it should come from emulation environment.
// So patch ImageBuffer here to align the EntryPoint.
//
Status = InternalPeCoffGetEntryPoint ((VOID *)(UINTN)ImageBase, &EntryPointInImage);
ASSERT_EFI_ERROR (Status);
DriverInfo->ImageBase = ImageBase + EntryPoint - (PHYSICAL_ADDRESS)(UINTN)EntryPointInImage;
}
DriverInfo->ImageBase = LoadAddress;
DriverInfo->ImageSize = UefiImageGetImageSize (ImageContext);
DriverInfo->EntryPoint = UefiImageLoaderGetImageEntryPoint (ImageContext);
DriverInfo->ImageSubsystem = UefiImageGetSubsystem (ImageContext);
DriverInfo->FileType = FileType;
DriverInfoData->AllocInfoList = (LIST_ENTRY *)(DriverInfoData + 1);
@ -442,7 +324,7 @@ BuildDriverInfo (
DriverInfo->CurrentUsage = 0;
DriverInfo->PeakUsage = 0;
DriverInfo->AllocRecordCount = 0;
if (PdbSize != 0) {
if (!RETURN_ERROR (PdbStatus)) {
DriverInfo->PdbStringOffset = (UINT16)sizeof (MEMORY_PROFILE_DRIVER_INFO);
DriverInfoData->PdbString = (CHAR8 *)(DriverInfoData->AllocInfoList + 1);
CopyMem (DriverInfoData->PdbString, PdbString, PdbSize);
@ -470,8 +352,7 @@ BuildDriverInfo (
VOID
RegisterImageToDxe (
IN EFI_GUID *FileName,
IN PHYSICAL_ADDRESS ImageBase,
IN UINT64 ImageSize,
IN UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext,
IN EFI_FV_FILETYPE FileType
)
{
@ -490,8 +371,7 @@ RegisterImageToDxe (
Status = ProfileProtocol->RegisterImage (
ProfileProtocol,
(EFI_DEVICE_PATH_PROTOCOL *)FilePath,
ImageBase,
ImageSize,
ImageContext,
FileType
);
}
@ -610,7 +490,6 @@ RegisterSmmCore (
)
{
MEMORY_PROFILE_DRIVER_INFO_DATA *DriverInfoData;
PHYSICAL_ADDRESS ImageBase;
UINT8 TempBuffer[sizeof (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH) + sizeof (EFI_DEVICE_PATH_PROTOCOL)];
MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *FilePath;
@ -622,14 +501,11 @@ RegisterSmmCore (
return FALSE;
}
ImageBase = gSmmCorePrivate->PiSmmCoreImageBase;
DriverInfoData = BuildDriverInfo (
ContextData,
&gEfiCallerIdGuid,
ImageBase,
gSmmCorePrivate->PiSmmCoreImageSize,
gSmmCorePrivate->PiSmmCoreEntryPoint,
InternalPeCoffGetSubsystem ((VOID *)(UINTN)ImageBase),
&gSmmCorePrivate->PiSmmCoreImageContext,
gSmmCorePrivate->PiSmmCoreImageBase,
EFI_FV_FILETYPE_SMM_CORE
);
if (DriverInfoData == NULL) {
@ -652,8 +528,7 @@ SmramProfileInit (
RegisterImageToDxe (
&gEfiCallerIdGuid,
gSmmCorePrivate->PiSmmCoreImageBase,
gSmmCorePrivate->PiSmmCoreImageSize,
&gSmmCorePrivate->PiSmmCoreImageContext,
EFI_FV_FILETYPE_SMM_CORE
);
@ -754,8 +629,9 @@ GetFileNameFromFilePath (
**/
EFI_STATUS
RegisterSmramProfileImage (
IN EFI_SMM_DRIVER_ENTRY *DriverEntry,
IN BOOLEAN RegisterToDxe
IN EFI_GUID *FileName,
IN BOOLEAN RegisterToDxe,
IN UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext
)
{
MEMORY_PROFILE_CONTEXT_DATA *ContextData;
@ -765,9 +641,8 @@ RegisterSmramProfileImage (
if (RegisterToDxe) {
RegisterImageToDxe (
&DriverEntry->FileName,
DriverEntry->ImageBuffer,
EFI_PAGES_TO_SIZE (DriverEntry->NumberOfPage),
FileName,
ImageContext,
EFI_FV_FILETYPE_SMM
);
}
@ -777,7 +652,7 @@ RegisterSmramProfileImage (
}
FilePath = (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *)TempBuffer;
EfiInitializeFwVolDevicepathNode (FilePath, &DriverEntry->FileName);
EfiInitializeFwVolDevicepathNode (FilePath, FileName);
SetDevicePathEndNode (FilePath + 1);
if (!NeedRecordThisDriver ((EFI_DEVICE_PATH_PROTOCOL *)FilePath)) {
@ -791,11 +666,9 @@ RegisterSmramProfileImage (
DriverInfoData = BuildDriverInfo (
ContextData,
&DriverEntry->FileName,
DriverEntry->ImageBuffer,
EFI_PAGES_TO_SIZE (DriverEntry->NumberOfPage),
DriverEntry->ImageEntryPoint,
InternalPeCoffGetSubsystem ((VOID *)(UINTN)DriverEntry->ImageBuffer),
FileName,
ImageContext,
UefiImageLoaderGetImageAddress (ImageContext),
EFI_FV_FILETYPE_SMM
);
if (DriverInfoData == NULL) {
@ -909,24 +782,22 @@ GetMemoryProfileDriverInfoFromAddress (
**/
EFI_STATUS
UnregisterSmramProfileImage (
IN EFI_SMM_DRIVER_ENTRY *DriverEntry,
IN BOOLEAN UnregisterFromDxe
IN EFI_GUID *FileName,
IN PHYSICAL_ADDRESS ImageBase,
IN UINT64 ImageSize,
IN BOOLEAN UnregisterFromDxe
)
{
EFI_STATUS Status;
MEMORY_PROFILE_CONTEXT_DATA *ContextData;
MEMORY_PROFILE_DRIVER_INFO_DATA *DriverInfoData;
EFI_GUID *FileName;
PHYSICAL_ADDRESS ImageAddress;
VOID *EntryPointInImage;
UINT8 TempBuffer[sizeof (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH) + sizeof (EFI_DEVICE_PATH_PROTOCOL)];
MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *FilePath;
if (UnregisterFromDxe) {
UnregisterImageFromDxe (
&DriverEntry->FileName,
DriverEntry->ImageBuffer,
EFI_PAGES_TO_SIZE (DriverEntry->NumberOfPage)
FileName,
ImageBase,
ImageSize
);
}
@ -935,7 +806,7 @@ UnregisterSmramProfileImage (
}
FilePath = (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *)TempBuffer;
EfiInitializeFwVolDevicepathNode (FilePath, &DriverEntry->FileName);
EfiInitializeFwVolDevicepathNode (FilePath, FileName);
SetDevicePathEndNode (FilePath + 1);
if (!NeedRecordThisDriver ((EFI_DEVICE_PATH_PROTOCOL *)FilePath)) {
@ -948,24 +819,13 @@ UnregisterSmramProfileImage (
}
DriverInfoData = NULL;
FileName = &DriverEntry->FileName;
ImageAddress = DriverEntry->ImageBuffer;
if ((DriverEntry->ImageEntryPoint < ImageAddress) || (DriverEntry->ImageEntryPoint >= (ImageAddress + EFI_PAGES_TO_SIZE (DriverEntry->NumberOfPage)))) {
//
// If the EntryPoint is not in the range of image buffer, it should come from emulation environment.
// So patch ImageAddress here to align the EntryPoint.
//
Status = InternalPeCoffGetEntryPoint ((VOID *)(UINTN)ImageAddress, &EntryPointInImage);
ASSERT_EFI_ERROR (Status);
ImageAddress = ImageAddress + (UINTN)DriverEntry->ImageEntryPoint - (UINTN)EntryPointInImage;
}
if (FileName != NULL) {
DriverInfoData = GetMemoryProfileDriverInfoByFileNameAndAddress (ContextData, FileName, ImageAddress);
DriverInfoData = GetMemoryProfileDriverInfoByFileNameAndAddress (ContextData, FileName, ImageBase);
}
if (DriverInfoData == NULL) {
DriverInfoData = GetMemoryProfileDriverInfoFromAddress (ContextData, ImageAddress);
DriverInfoData = GetMemoryProfileDriverInfoFromAddress (ContextData, ImageBase);
}
if (DriverInfoData == NULL) {
@ -1989,29 +1849,20 @@ EFIAPI
SmramProfileProtocolRegisterImage (
IN EDKII_SMM_MEMORY_PROFILE_PROTOCOL *This,
IN EFI_DEVICE_PATH_PROTOCOL *FilePath,
IN PHYSICAL_ADDRESS ImageBase,
IN UINT64 ImageSize,
IN UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext,
IN EFI_FV_FILETYPE FileType
)
{
EFI_STATUS Status;
EFI_SMM_DRIVER_ENTRY DriverEntry;
VOID *EntryPointInImage;
EFI_GUID *Name;
EFI_GUID *FileName;
EFI_GUID ZeroGuid;
ZeroMem (&DriverEntry, sizeof (DriverEntry));
Name = GetFileNameFromFilePath (FilePath);
if (Name != NULL) {
CopyMem (&DriverEntry.FileName, Name, sizeof (EFI_GUID));
FileName = GetFileNameFromFilePath (FilePath);
if (FileName == NULL) {
ZeroMem (&ZeroGuid, sizeof (ZeroGuid));
FileName = &ZeroGuid;
}
DriverEntry.ImageBuffer = ImageBase;
DriverEntry.NumberOfPage = EFI_SIZE_TO_PAGES ((UINTN)ImageSize);
Status = InternalPeCoffGetEntryPoint ((VOID *)(UINTN)DriverEntry.ImageBuffer, &EntryPointInImage);
ASSERT_EFI_ERROR (Status);
DriverEntry.ImageEntryPoint = (PHYSICAL_ADDRESS)(UINTN)EntryPointInImage;
return RegisterSmramProfileImage (&DriverEntry, FALSE);
return RegisterSmramProfileImage (FileName, FALSE, ImageContext);
}
/**
@ -2037,24 +1888,16 @@ SmramProfileProtocolUnregisterImage (
IN UINT64 ImageSize
)
{
EFI_STATUS Status;
EFI_SMM_DRIVER_ENTRY DriverEntry;
VOID *EntryPointInImage;
EFI_GUID *Name;
EFI_GUID *FileName;
EFI_GUID ZeroGuid;
ZeroMem (&DriverEntry, sizeof (DriverEntry));
Name = GetFileNameFromFilePath (FilePath);
if (Name != NULL) {
CopyMem (&DriverEntry.FileName, Name, sizeof (EFI_GUID));
FileName = GetFileNameFromFilePath (FilePath);
if (FileName == NULL) {
ZeroMem (&ZeroGuid, sizeof (ZeroGuid));
FileName = &ZeroGuid;
}
DriverEntry.ImageBuffer = ImageBase;
DriverEntry.NumberOfPage = EFI_SIZE_TO_PAGES ((UINTN)ImageSize);
Status = InternalPeCoffGetEntryPoint ((VOID *)(UINTN)DriverEntry.ImageBuffer, &EntryPointInImage);
ASSERT_EFI_ERROR (Status);
DriverEntry.ImageEntryPoint = (PHYSICAL_ADDRESS)(UINTN)EntryPointInImage;
return UnregisterSmramProfileImage (&DriverEntry, FALSE);
return UnregisterSmramProfileImage (FileName, ImageBase, ImageSize, FALSE);
}
/**

View File

@ -325,14 +325,12 @@ RuntimeDriverSetVirtualAddressMap (
Status = RuntimeDriverConvertPointer (0, (VOID **)&VirtImageBase);
ASSERT_EFI_ERROR (Status);
PeCoffLoaderRelocateImageForRuntime (
(EFI_PHYSICAL_ADDRESS)(UINTN)RuntimeImage->ImageBase,
UefiImageRuntimeRelocateImageForExecution (
(VOID *)(UINTN)RuntimeImage->ImageBase,
(UINT32)RuntimeImage->ImageSize,
VirtImageBase,
(UINTN)RuntimeImage->ImageSize,
RuntimeImage->RelocationData
);
InvalidateInstructionCacheRange (RuntimeImage->ImageBase, (UINTN)RuntimeImage->ImageSize);
}
}

View File

@ -22,7 +22,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#include <Library/UefiBootServicesTableLib.h>
#include <Library/UefiLib.h>
#include <Library/CacheMaintenanceLib.h>
#include <Library/PeCoffLib.h>
#include <Library/UefiImageLib.h>
//
// Function Prototypes

Some files were not shown because too many files have changed in this diff Show More