SecurePE: Replaced old PE loader with Secure one.

This commit is contained in:
Mikhail Krichanov 2023-05-09 18:18:43 +03:00
parent 526a5ef3e6
commit 29ab261538
316 changed files with 13695 additions and 8512 deletions

View File

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

View File

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

View File

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

View File

@ -47,7 +47,6 @@
DefaultExceptionHandlerLib DefaultExceptionHandlerLib
DxeServicesTableLib DxeServicesTableLib
HobLib HobLib
PeCoffGetEntryPointLib
UefiDriverEntryPoint UefiDriverEntryPoint
UefiLib UefiLib

View File

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

View File

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

View File

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

View File

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

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/UefiLib.h>
#include <Library/BaseLib.h> #include <Library/BaseLib.h>
#include <Library/DebugLib.h> #include <Library/DebugLib.h>
#include <Library/PeCoffGetEntryPointLib.h>
#include <Library/PrintLib.h> #include <Library/PrintLib.h>
#include <Library/ArmDisassemblerLib.h> #include <Library/ArmDisassemblerLib.h>
#include <Library/SerialPortLib.h> #include <Library/SerialPortLib.h>
@ -31,11 +30,10 @@ STATIC CHAR8 *gExceptionTypeString[] = {
STATIC BOOLEAN mRecursiveException; STATIC BOOLEAN mRecursiveException;
CHAR8 * CONST CHAR8 *
GetImageName ( GetImageName (
IN UINTN FaultAddress, IN UINTN FaultAddress,
OUT UINTN *ImageBase, OUT UINTN *ImageBase
OUT UINTN *PeCoffSizeOfHeaders
); );
STATIC STATIC
@ -209,14 +207,13 @@ DefaultExceptionHandler (
} }
DEBUG_CODE_BEGIN (); DEBUG_CODE_BEGIN ();
CHAR8 *Pdb, *PrevPdb; CONST CHAR8 *Pdb, *PrevPdb;
UINTN ImageBase; UINTN ImageBase;
UINTN PeCoffSizeOfHeader; UINT64 *Fp;
UINT64 *Fp; UINT64 RootFp[2];
UINT64 RootFp[2]; UINTN Idx;
UINTN Idx;
PrevPdb = Pdb = GetImageName (SystemContext.SystemContextAArch64->ELR, &ImageBase, &PeCoffSizeOfHeader); PrevPdb = Pdb = GetImageName (SystemContext.SystemContextAArch64->ELR, &ImageBase);
if (Pdb != NULL) { if (Pdb != NULL) {
DEBUG (( DEBUG ((
DEBUG_ERROR, DEBUG_ERROR,
@ -241,7 +238,7 @@ DefaultExceptionHandler (
} }
for (Fp = RootFp; Fp[0] != 0; Fp = (UINT64 *)Fp[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) { if (Pdb != NULL) {
if (Pdb != PrevPdb) { if (Pdb != PrevPdb) {
Idx++; Idx++;
@ -262,14 +259,14 @@ DefaultExceptionHandler (
} }
} }
PrevPdb = Pdb = GetImageName (SystemContext.SystemContextAArch64->ELR, &ImageBase, &PeCoffSizeOfHeader); PrevPdb = Pdb = GetImageName (SystemContext.SystemContextAArch64->ELR, &ImageBase);
if (Pdb != NULL) { if (Pdb != NULL) {
DEBUG ((DEBUG_ERROR, "\n[ 0] %a\n", Pdb)); DEBUG ((DEBUG_ERROR, "\n[ 0] %a\n", Pdb));
} }
Idx = 0; Idx = 0;
for (Fp = RootFp; Fp[0] != 0; Fp = (UINT64 *)Fp[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)) { if ((Pdb != NULL) && (Pdb != PrevPdb)) {
DEBUG ((DEBUG_ERROR, "[% 2d] %a\n", ++Idx, Pdb)); DEBUG ((DEBUG_ERROR, "[% 2d] %a\n", ++Idx, Pdb));
PrevPdb = Pdb; PrevPdb = Pdb;

View File

@ -11,7 +11,6 @@
#include <Uefi.h> #include <Uefi.h>
#include <Library/BaseLib.h> #include <Library/BaseLib.h>
#include <Library/DebugLib.h> #include <Library/DebugLib.h>
#include <Library/PeCoffGetEntryPointLib.h>
#include <Library/PrintLib.h> #include <Library/PrintLib.h>
#include <Library/ArmDisassemblerLib.h> #include <Library/ArmDisassemblerLib.h>
#include <Library/SerialPortLib.h> #include <Library/SerialPortLib.h>
@ -48,11 +47,10 @@ STATIC CONST CPSR_CHAR mCpsrChar[] = {
{ 0, '?' } { 0, '?' }
}; };
CHAR8 * CONST CHAR8 *
GetImageName ( GetImageName (
IN UINTN FaultAddress, IN UINTN FaultAddress,
OUT UINTN *ImageBase, OUT UINTN *ImageBase
OUT UINTN *PeCoffSizeOfHeaders
); );
/** /**
@ -221,20 +219,19 @@ DefaultExceptionHandler (
} }
DEBUG_CODE_BEGIN (); DEBUG_CODE_BEGIN ();
CHAR8 *Pdb; CONST CHAR8 *Pdb;
UINT32 ImageBase; UINT32 ImageBase;
UINT32 PeCoffSizeOfHeader; UINT32 Offset;
UINT32 Offset; CHAR8 CpsrStr[CPSR_STRING_SIZE]; // char per bit. Lower 5-bits are mode
CHAR8 CpsrStr[CPSR_STRING_SIZE]; // char per bit. Lower 5-bits are mode // that is a 3 char string
// that is a 3 char string CHAR8 Buffer[80];
CHAR8 Buffer[80]; UINT8 *DisAsm;
UINT8 *DisAsm; UINT32 ItBlock;
UINT32 ItBlock;
CpsrString (SystemContext.SystemContextArm->CPSR, CpsrStr); CpsrString (SystemContext.SystemContextArm->CPSR, CpsrStr);
DEBUG ((DEBUG_ERROR, "%a\n", 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; Offset = SystemContext.SystemContextArm->PC - ImageBase;
if (Pdb != NULL) { if (Pdb != NULL) {
DEBUG ((DEBUG_ERROR, "%a\n", Pdb)); DEBUG ((DEBUG_ERROR, "%a\n", Pdb));
@ -247,7 +244,9 @@ DefaultExceptionHandler (
// you need to subtract out the size of the PE/COFF header to get // you need to subtract out the size of the PE/COFF header to get
// get the offset that matches the link map. // 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 // 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; DisAsm = (UINT8 *)(UINTN)SystemContext.SystemContextArm->PC;

View File

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

View File

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

View File

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

View File

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

View File

@ -47,8 +47,8 @@
SynchronizationLib|MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf SynchronizationLib|MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf
PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.inf PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.inf
PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf
PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf PeCoffLib2|MdePkg/Library/BasePeCoffLib2/BasePeCoffLib2.inf
PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf UefiImageLib|MdePkg/Library/BaseUefiImageLib/BaseUefiImageLibPeCoff.inf
IoLib|MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsicArmVirt.inf IoLib|MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsicArmVirt.inf
UefiDecompressLib|MdePkg/Library/BaseUefiDecompressLib/BaseUefiDecompressLib.inf UefiDecompressLib|MdePkg/Library/BaseUefiDecompressLib/BaseUefiDecompressLib.inf
CpuLib|MdePkg/Library/BaseCpuLib/BaseCpuLib.inf CpuLib|MdePkg/Library/BaseCpuLib/BaseCpuLib.inf
@ -122,8 +122,8 @@
PL011UartLib|ArmPlatformPkg/Library/PL011UartLib/PL011UartLib.inf PL011UartLib|ArmPlatformPkg/Library/PL011UartLib/PL011UartLib.inf
SerialPortLib|ArmVirtPkg/Library/FdtPL011SerialPortLib/FdtPL011SerialPortLib.inf SerialPortLib|ArmVirtPkg/Library/FdtPL011SerialPortLib/FdtPL011SerialPortLib.inf
PeCoffExtraActionLib|ArmPkg/Library/DebugPeCoffExtraActionLib/DebugPeCoffExtraActionLib.inf UefiImageExtraActionLib|ArmPkg/Library/DebugUefiImageExtraActionLib/DebugUefiImageExtraActionLib.inf
#PeCoffExtraActionLib|MdePkg/Library/BasePeCoffExtraActionLibNull/BasePeCoffExtraActionLibNull.inf #UefiImageExtraActionLib|MdePkg/Library/BaseUefiImageExtraActionLibNull/BaseUefiImageExtraActionLibNull.inf
DebugAgentLib|MdeModulePkg/Library/DebugAgentLibNull/DebugAgentLibNull.inf DebugAgentLib|MdeModulePkg/Library/DebugAgentLibNull/DebugAgentLibNull.inf
DebugAgentTimerLib|EmbeddedPkg/Library/DebugAgentTimerLibNull/DebugAgentTimerLibNull.inf DebugAgentTimerLib|EmbeddedPkg/Library/DebugAgentTimerLibNull/DebugAgentTimerLibNull.inf
@ -198,7 +198,6 @@
PeiCoreEntryPoint|MdePkg/Library/PeiCoreEntryPoint/PeiCoreEntryPoint.inf PeiCoreEntryPoint|MdePkg/Library/PeiCoreEntryPoint/PeiCoreEntryPoint.inf
PerformanceLib|MdeModulePkg/Library/PeiPerformanceLib/PeiPerformanceLib.inf PerformanceLib|MdeModulePkg/Library/PeiPerformanceLib/PeiPerformanceLib.inf
OemHookStatusCodeLib|MdeModulePkg/Library/OemHookStatusCodeLibNull/OemHookStatusCodeLibNull.inf OemHookStatusCodeLib|MdeModulePkg/Library/OemHookStatusCodeLibNull/OemHookStatusCodeLibNull.inf
PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf
ExtractGuidedSectionLib|MdePkg/Library/PeiExtractGuidedSectionLib/PeiExtractGuidedSectionLib.inf ExtractGuidedSectionLib|MdePkg/Library/PeiExtractGuidedSectionLib/PeiExtractGuidedSectionLib.inf
PeiServicesTablePointerLib|ArmPkg/Library/PeiServicesTablePointerLib/PeiServicesTablePointerLib.inf PeiServicesTablePointerLib|ArmPkg/Library/PeiServicesTablePointerLib/PeiServicesTablePointerLib.inf
@ -213,7 +212,6 @@
PeimEntryPoint|MdePkg/Library/PeimEntryPoint/PeimEntryPoint.inf PeimEntryPoint|MdePkg/Library/PeimEntryPoint/PeimEntryPoint.inf
PerformanceLib|MdeModulePkg/Library/PeiPerformanceLib/PeiPerformanceLib.inf PerformanceLib|MdeModulePkg/Library/PeiPerformanceLib/PeiPerformanceLib.inf
OemHookStatusCodeLib|MdeModulePkg/Library/OemHookStatusCodeLibNull/OemHookStatusCodeLibNull.inf OemHookStatusCodeLib|MdeModulePkg/Library/OemHookStatusCodeLibNull/OemHookStatusCodeLibNull.inf
PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf
ExtractGuidedSectionLib|MdePkg/Library/PeiExtractGuidedSectionLib/PeiExtractGuidedSectionLib.inf ExtractGuidedSectionLib|MdePkg/Library/PeiExtractGuidedSectionLib/PeiExtractGuidedSectionLib.inf
PeiServicesTablePointerLib|ArmPkg/Library/PeiServicesTablePointerLib/PeiServicesTablePointerLib.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. // window at the beginning of the FD image as a temp stack.
// //
mov x0, x7 mov x0, x7
adr x1, PeCoffLoaderImageReadFromMemory
mov sp, x7 mov sp, x7
bl RelocatePeCoffImage bl RelocateUefiImage
// //
// Discover the memory size and offset from the DTB, and record in the // 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. // window at the beginning of the FD image as a temp stack.
// //
mov r0, r5 mov r0, r5
ADRL (r1, PeCoffLoaderImageReadFromMemory)
mov sp, r5 mov sp, r5
bl RelocatePeCoffImage bl RelocateUefiImage
// //
// Discover the memory size and offset from the DTB, and record in the // Discover the memory size and offset from the DTB, and record in the

View File

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

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

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

View File

@ -46,6 +46,10 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
(((Imm32) >> 2) & 0x7fffff)) (((Imm32) >> 2) & 0x7fffff))
#define ARM_JUMP_TO_THUMB(Offset) _ARM_JUMP_TO_THUMB((Offset) - 8) #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) * Arm instruction to return from exception (MOVS PC, LR)
*/ */
@ -1357,11 +1361,17 @@ Returns:
// Rebase the PE or TE image in FileBuffer of FFS file for XIP // Rebase the PE or TE image in FileBuffer of FFS file for XIP
// Rebase for the debug genfvmap tool // 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)) { if (EFI_ERROR (Status)) {
Error (NULL, 0, 3000, "Invalid", "Could not rebase %s.", FvInfo->FvFiles[Index]); Error (NULL, 0, 3000, "Invalid", "Could not rebase %s.", FvInfo->FvFiles[Index]);
return Status; 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 // copy VTF File
// //
@ -1403,11 +1413,17 @@ Returns:
// Rebase the PE or TE image in FileBuffer of FFS file for XIP. // Rebase the PE or TE image in FileBuffer of FFS file for XIP.
// Rebase Bs and Rt drivers for the debug genfvmap tool. // 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); Status = FfsRebase (FvInfo, FvInfo->FvFiles[Index], (EFI_FFS_FILE_HEADER **)&FileBuffer, &FileSize, (UINTN) FvImage->CurrentFilePointer - (UINTN) FvImage->FileImage, FvMapFile);
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {
Error (NULL, 0, 3000, "Invalid", "Could not rebase %s.", FvInfo->FvFiles[Index]); Error (NULL, 0, 3000, "Invalid", "Could not rebase %s.", FvInfo->FvFiles[Index]);
return Status; 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 // Copy the file
// //
@ -3570,11 +3586,109 @@ Returns:
return EFI_SUCCESS; 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 EFI_STATUS
FfsRebase ( FfsRebase (
IN OUT FV_INFO *FvInfo, IN OUT FV_INFO *FvInfo,
IN CHAR8 *FileName, 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 UINTN XipOffset,
IN FILE *FvMapFile IN FILE *FvMapFile
) )
@ -3647,13 +3761,12 @@ Returns:
return EFI_SUCCESS; return EFI_SUCCESS;
} }
XipBase = FvInfo->BaseAddress + XipOffset; XipBase = FvInfo->BaseAddress + XipOffset;
// //
// We only process files potentially containing PE32 sections. // We only process files potentially containing PE32 sections.
// //
switch (FfsFile->Type) { switch ((*FfsFile)->Type) {
case EFI_FV_FILETYPE_SECURITY_CORE: case EFI_FV_FILETYPE_SECURITY_CORE:
case EFI_FV_FILETYPE_PEI_CORE: case EFI_FV_FILETYPE_PEI_CORE:
case EFI_FV_FILETYPE_PEIM: case EFI_FV_FILETYPE_PEIM:
@ -3665,7 +3778,7 @@ Returns:
// //
// Rebase the inside FvImage. // Rebase the inside FvImage.
// //
GetChildFvFromFfs (FvInfo, FfsFile, XipOffset); GetChildFvFromFfs (FvInfo, *FfsFile, XipOffset);
// //
// Search PE/TE section in FV sectin. // Search PE/TE section in FV sectin.
@ -3675,7 +3788,7 @@ Returns:
return EFI_SUCCESS; return EFI_SUCCESS;
} }
FfsHeaderSize = GetFfsHeaderLength(FfsFile); FfsHeaderSize = GetFfsHeaderLength(*FfsFile);
// //
// Rebase each PE32 section // Rebase each PE32 section
// //
@ -3689,7 +3802,7 @@ Returns:
// //
// Find Pe Image // Find Pe Image
// //
Status = GetSectionByType (FfsFile, EFI_SECTION_PE32, Index, &CurrentPe32Section); Status = GetSectionByType (*FfsFile, EFI_SECTION_PE32, Index, &CurrentPe32Section);
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {
break; break;
} }
@ -3738,7 +3851,7 @@ Returns:
// //
// Calculate the PE32 base address, based on file type // 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_SECURITY_CORE:
case EFI_FV_FILETYPE_PEI_CORE: case EFI_FV_FILETYPE_PEI_CORE:
case EFI_FV_FILETYPE_PEIM: case EFI_FV_FILETYPE_PEIM:
@ -3816,7 +3929,7 @@ Returns:
ImageContext.RelocationsStripped = FALSE; ImageContext.RelocationsStripped = FALSE;
} }
NewPe32BaseAddress = XipBase + (UINTN) CurrentPe32Section.Pe32Section + CurSecHdrSize - (UINTN)FfsFile; NewPe32BaseAddress = XipBase + (UINTN) CurrentPe32Section.Pe32Section + CurSecHdrSize - (UINTN)(*FfsFile);
break; break;
case EFI_FV_FILETYPE_DRIVER: case EFI_FV_FILETYPE_DRIVER:
@ -3831,7 +3944,7 @@ Returns:
Error (NULL, 0, 3000, "Invalid", "PE image Section-Alignment and File-Alignment do not match : %s.", FileName); Error (NULL, 0, 3000, "Invalid", "PE image Section-Alignment and File-Alignment do not match : %s.", FileName);
return EFI_ABORTED; return EFI_ABORTED;
} }
NewPe32BaseAddress = XipBase + (UINTN) CurrentPe32Section.Pe32Section + CurSecHdrSize - (UINTN)FfsFile; NewPe32BaseAddress = XipBase + (UINTN) CurrentPe32Section.Pe32Section + CurSecHdrSize - (UINTN)(*FfsFile);
break; break;
default: default:
@ -3855,15 +3968,28 @@ Returns:
// //
// Load and Relocate Image Data // 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) { if (MemoryImagePointer == NULL) {
Error (NULL, 0, 4001, "Resource", "memory cannot be allocated on rebase of %s", FileName); Error (NULL, 0, 4001, "Resource", "memory cannot be allocated on rebase of %s", FileName);
return EFI_OUT_OF_RESOURCES; return EFI_OUT_OF_RESOURCES;
} }
memset ((VOID *) MemoryImagePointer, 0, (UINTN) ImageContext.ImageSize + ImageContext.SectionAlignment); ImageContext.ImageAddress = ALIGN_VALUE ((UINTN)MemoryImagePointer, ImageContext.SectionAlignment);
ImageContext.ImageAddress = ((UINTN) MemoryImagePointer + ImageContext.SectionAlignment - 1) & (~((UINTN) ImageContext.SectionAlignment - 1));
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)) { if (EFI_ERROR (Status)) {
Error (NULL, 0, 3000, "Invalid", "LocateImage() call failed on rebase of %s", FileName); Error (NULL, 0, 3000, "Invalid", "LocateImage() call failed on rebase of %s", FileName);
free ((VOID *) MemoryImagePointer); free ((VOID *) MemoryImagePointer);
@ -3871,7 +3997,8 @@ Returns:
} }
ImageContext.DestinationAddress = NewPe32BaseAddress; ImageContext.DestinationAddress = NewPe32BaseAddress;
Status = PeCoffLoaderRelocateImage (&ImageContext);
Status = PeCoffLoaderRelocateImage (&ImageContext);
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {
Error (NULL, 0, 3000, "Invalid", "RelocateImage() call failed on rebase of %s Status=%d", FileName, Status); Error (NULL, 0, 3000, "Invalid", "RelocateImage() call failed on rebase of %s Status=%d", FileName, Status);
free ((VOID *) MemoryImagePointer); free ((VOID *) MemoryImagePointer);
@ -3921,15 +4048,15 @@ Returns:
// //
// Now update file checksum // Now update file checksum
// //
if (FfsFile->Attributes & FFS_ATTRIB_CHECKSUM) { if ((*FfsFile)->Attributes & FFS_ATTRIB_CHECKSUM) {
SavedState = FfsFile->State; SavedState = (*FfsFile)->State;
FfsFile->IntegrityCheck.Checksum.File = 0; (*FfsFile)->IntegrityCheck.Checksum.File = 0;
FfsFile->State = 0; (*FfsFile)->State = 0;
FfsFile->IntegrityCheck.Checksum.File = CalculateChecksum8 ( (*FfsFile)->IntegrityCheck.Checksum.File = CalculateChecksum8 (
(UINT8 *) ((UINT8 *)FfsFile + FfsHeaderSize), (UINT8 *) ((UINT8 *)(*FfsFile) + FfsHeaderSize),
GetFfsFileLength (FfsFile) - FfsHeaderSize GetFfsFileLength (*FfsFile) - FfsHeaderSize
); );
FfsFile->State = SavedState; (*FfsFile)->State = SavedState;
} }
// //
@ -3943,14 +4070,14 @@ Returns:
PdbPointer = FileName; PdbPointer = FileName;
} }
WriteMapFile (FvMapFile, PdbPointer, FfsFile, NewPe32BaseAddress, &OrigImageContext); WriteMapFile (FvMapFile, PdbPointer, *FfsFile, NewPe32BaseAddress, &OrigImageContext);
} }
if (FfsFile->Type != EFI_FV_FILETYPE_SECURITY_CORE && if ((*FfsFile)->Type != EFI_FV_FILETYPE_SECURITY_CORE &&
FfsFile->Type != EFI_FV_FILETYPE_PEI_CORE && (*FfsFile)->Type != EFI_FV_FILETYPE_PEI_CORE &&
FfsFile->Type != EFI_FV_FILETYPE_PEIM && (*FfsFile)->Type != EFI_FV_FILETYPE_PEIM &&
FfsFile->Type != EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER && (*FfsFile)->Type != EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER &&
FfsFile->Type != EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE (*FfsFile)->Type != EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE
) { ) {
// //
// Only Peim code may have a TE section // Only Peim code may have a TE section
@ -3967,7 +4094,7 @@ Returns:
// //
// Find Te Image // Find Te Image
// //
Status = GetSectionByType (FfsFile, EFI_SECTION_TE, Index, &CurrentPe32Section); Status = GetSectionByType (*FfsFile, EFI_SECTION_TE, Index, &CurrentPe32Section);
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {
break; break;
} }
@ -4015,7 +4142,7 @@ Returns:
// Set new rebased address. // Set new rebased address.
// //
NewPe32BaseAddress = XipBase + (UINTN) TEImageHeader + sizeof (EFI_TE_IMAGE_HEADER) \ 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. // if reloc is stripped, try to get the original efi image to get reloc info.
@ -4158,15 +4285,15 @@ Returns:
// //
// Now update file checksum // Now update file checksum
// //
if (FfsFile->Attributes & FFS_ATTRIB_CHECKSUM) { if ((*FfsFile)->Attributes & FFS_ATTRIB_CHECKSUM) {
SavedState = FfsFile->State; SavedState = (*FfsFile)->State;
FfsFile->IntegrityCheck.Checksum.File = 0; (*FfsFile)->IntegrityCheck.Checksum.File = 0;
FfsFile->State = 0; (*FfsFile)->State = 0;
FfsFile->IntegrityCheck.Checksum.File = CalculateChecksum8 ( (*FfsFile)->IntegrityCheck.Checksum.File = CalculateChecksum8 (
(UINT8 *)((UINT8 *)FfsFile + FfsHeaderSize), (UINT8 *)((UINT8 *)(*FfsFile) + FfsHeaderSize),
GetFfsFileLength (FfsFile) - FfsHeaderSize GetFfsFileLength (*FfsFile) - FfsHeaderSize
); );
FfsFile->State = SavedState; (*FfsFile)->State = SavedState;
} }
// //
// Get this module function address from ModulePeMapFile and add them into FvMap file // Get this module function address from ModulePeMapFile and add them into FvMap file
@ -4182,7 +4309,7 @@ Returns:
WriteMapFile ( WriteMapFile (
FvMapFile, FvMapFile,
PdbPointer, PdbPointer,
FfsFile, *FfsFile,
NewPe32BaseAddress, NewPe32BaseAddress,
&OrigImageContext &OrigImageContext
); );

View File

@ -331,7 +331,8 @@ EFI_STATUS
FfsRebase ( FfsRebase (
IN OUT FV_INFO *FvInfo, IN OUT FV_INFO *FvInfo,
IN CHAR8 *FileName, 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 UINTN XipOffset,
IN FILE *FvMapFile 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]+$') TemporaryTablePattern = re.compile(r'^_\d+_\d+_[a-fA-F0-9]+$')
TmpTableDict = {} 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 ## Check environment PATH variable to make sure the specified tool is found
# #
# If the tool is found in the PATH, then True is returned # If the tool is found in the PATH, then True is returned
@ -688,7 +706,7 @@ class PeImageInfo():
self.OutputDir = OutputDir self.OutputDir = OutputDir
self.DebugDir = DebugDir self.DebugDir = DebugDir
self.Image = ImageClass 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 ## 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. ## for SMM module in SMRAM, the SMRAM will be allocated from base to top.
if not ModeIsSmm: if not ModeIsSmm:
BaseAddress = BaseAddress - ModuleInfo.Image.Size BaseAddress = BaseAddress - ModuleInfo.Image.Size
BaseAddress = AlignDown(BaseAddress, ModuleInfo.Image.SectionAlignment)
# #
# Update Image to new BaseAddress by GenFw tool # Update Image to new BaseAddress by GenFw tool
# #
LaunchCommand(["GenFw", "--rebase", str(BaseAddress), "-r", ModuleOutputImage], ModuleInfo.OutputDir) LaunchCommand(["GenFw", "--rebase", str(BaseAddress), "-r", ModuleOutputImage], ModuleInfo.OutputDir)
LaunchCommand(["GenFw", "--rebase", str(BaseAddress), "-r", ModuleDebugImage], ModuleInfo.DebugDir) LaunchCommand(["GenFw", "--rebase", str(BaseAddress), "-r", ModuleDebugImage], ModuleInfo.DebugDir)
## for SMM module in SMRAM, the SMRAM will be allocated from base to top.
else: else:
BaseAddress = AlignUp(BaseAddress, ModuleInfo.Image.SectionAlignment)
# #
# Set new address to the section header only for SMM driver. # Set new address to the section header only for SMM driver.
# #

View File

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

View File

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

View File

@ -807,166 +807,6 @@ gXferObjectReadResponse (
return Count; 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. Process "qXfer:object:read:annex:offset,length" request.
@ -1007,7 +847,7 @@ QxferLibrary (
) )
{ {
VOID *LoadAddress; VOID *LoadAddress;
CHAR8 *Pdb; CONST CHAR8 *Pdb;
UINTN Size; UINTN Size;
if (Offset != gPacketqXferLibraryOffset) { if (Offset != gPacketqXferLibraryOffset) {
@ -1035,12 +875,8 @@ QxferLibrary (
for ( ; gEfiDebugImageTableEntry < gDebugImageTableHeader->TableSize; gEfiDebugImageTableEntry++, gDebugTable++) { for ( ; gEfiDebugImageTableEntry < gDebugImageTableHeader->TableSize; gEfiDebugImageTableEntry++, gDebugTable++) {
if (gDebugTable->NormalImage != NULL) { if (gDebugTable->NormalImage != NULL) {
if ((gDebugTable->NormalImage->ImageInfoType == EFI_DEBUG_IMAGE_INFO_TYPE_NORMAL) && if ((gDebugTable->NormalImage->ImageInfoType == EFI_DEBUG_IMAGE_INFO_TYPE_NORMAL) &&
(gDebugTable->NormalImage->LoadedImageProtocolInstance != NULL)) (gDebugTable->NormalImage->LoadedImageProtocolInstance != NULL)) {
{ Pdb = gDebugTable->NormalImage->PdbPath;
Pdb = PeCoffLoaderGetDebuggerInfo (
gDebugTable->NormalImage->LoadedImageProtocolInstance->ImageBase,
&LoadAddress
);
if (Pdb != NULL) { if (Pdb != NULL) {
Size = AsciiSPrint ( Size = AsciiSPrint (
gXferLibraryBuffer, gXferLibraryBuffer,

View File

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

View File

@ -102,7 +102,8 @@ EFIAPI
FfsFindSectionData ( FfsFindSectionData (
IN EFI_SECTION_TYPE SectionType, IN EFI_SECTION_TYPE SectionType,
IN EFI_PEI_FILE_HANDLE FileHandle, IN EFI_PEI_FILE_HANDLE FileHandle,
OUT VOID **SectionData OUT VOID **SectionData,
OUT UINT32 *SectionSize
); );
/** /**
@ -675,7 +676,7 @@ BuildExtractSectionHob (
VOID VOID
EFIAPI EFIAPI
BuildPeCoffLoaderHob ( BuildUefiLoaderHob (
VOID VOID
); );
@ -760,8 +761,9 @@ AllocateAlignedPages (
EFI_STATUS EFI_STATUS
EFIAPI EFIAPI
LoadPeCoffImage ( LoadUefiImage (
IN VOID *PeCoffImage, IN VOID *UefiImage,
IN UINT32 UefiImageSize,
OUT EFI_PHYSICAL_ADDRESS *ImageAddress, OUT EFI_PHYSICAL_ADDRESS *ImageAddress,
OUT UINT64 *ImageSize, OUT UINT64 *ImageSize,
OUT EFI_PHYSICAL_ADDRESS *EntryPoint OUT EFI_PHYSICAL_ADDRESS *EntryPoint

View File

@ -12,12 +12,11 @@
#include <Library/BaseLib.h> #include <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h> #include <Library/BaseMemoryLib.h>
#include <Library/DebugLib.h> #include <Library/DebugLib.h>
#include <Library/PeCoffLib.h> #include <Library/UefiImageLib.h>
#include <Library/HobLib.h> #include <Library/HobLib.h>
#include <Library/PcdLib.h> #include <Library/PcdLib.h>
#include <Library/PrePiHobListPointerLib.h> #include <Library/PrePiHobListPointerLib.h>
#include <Protocol/PeCoffLoader.h>
#include <Guid/ExtractSection.h> #include <Guid/ExtractSection.h>
#include <Guid/MemoryTypeInformation.h> #include <Guid/MemoryTypeInformation.h>
#include <Guid/MemoryAllocationHob.h> #include <Guid/MemoryAllocationHob.h>
@ -782,27 +781,6 @@ BuildExtractSectionHob (
BuildGuidDataHob (Guid, &Data, sizeof (Data)); 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? // May want to put this into a library so you only need the PCD settings if you are using the feature?
VOID VOID
BuildMemoryTypeInformationHob ( BuildMemoryTypeInformationHob (

View File

@ -278,7 +278,8 @@ FfsProcessSection (
IN FFS_CHECK_SECTION_HOOK SectionCheckHook, IN FFS_CHECK_SECTION_HOOK SectionCheckHook,
IN EFI_COMMON_SECTION_HEADER *Section, IN EFI_COMMON_SECTION_HEADER *Section,
IN UINTN SectionSize, IN UINTN SectionSize,
OUT VOID **OutputBuffer OUT VOID **OutputBuffer,
OUT UINT32 *OutputSize
) )
{ {
EFI_STATUS Status; EFI_STATUS Status;
@ -298,6 +299,7 @@ FfsProcessSection (
Found = FALSE; Found = FALSE;
*OutputBuffer = NULL; *OutputBuffer = NULL;
*OutputSize = 0;
ParsedLength = 0; ParsedLength = 0;
Status = EFI_NOT_FOUND; Status = EFI_NOT_FOUND;
while (ParsedLength < SectionSize) { while (ParsedLength < SectionSize) {
@ -313,10 +315,13 @@ FfsProcessSection (
} }
if (Found) { if (Found) {
// FIXME: Use common API with size checks
if (IS_SECTION2 (Section)) { if (IS_SECTION2 (Section)) {
*OutputBuffer = (VOID *)((UINT8 *)Section + sizeof (EFI_COMMON_SECTION_HEADER2)); *OutputBuffer = (VOID *)((UINT8 *)Section + sizeof (EFI_COMMON_SECTION_HEADER2));
*OutputSize = SECTION2_SIZE (Section) - sizeof (EFI_COMMON_SECTION_HEADER2);
} else { } else {
*OutputBuffer = (VOID *)((UINT8 *)Section + sizeof (EFI_COMMON_SECTION_HEADER)); *OutputBuffer = (VOID *)((UINT8 *)Section + sizeof (EFI_COMMON_SECTION_HEADER));
*OutputSize = SECTION_SIZE (Section) - sizeof (EFI_COMMON_SECTION_HEADER);
} }
return EFI_SUCCESS; return EFI_SUCCESS;
@ -432,7 +437,8 @@ FfsProcessSection (
SectionCheckHook, SectionCheckHook,
DstBuffer, DstBuffer,
DstBufferSize, DstBufferSize,
OutputBuffer OutputBuffer,
OutputSize
); );
} }
} }
@ -478,6 +484,7 @@ FfsFindSectionDataWithHook (
IN FFS_CHECK_SECTION_HOOK SectionCheckHook, IN FFS_CHECK_SECTION_HOOK SectionCheckHook,
IN EFI_PEI_FILE_HANDLE FileHandle, IN EFI_PEI_FILE_HANDLE FileHandle,
OUT VOID **SectionData OUT VOID **SectionData
OUT UINT32 *SectionSize
) )
{ {
EFI_FFS_FILE_HEADER *FfsFileHeader; EFI_FFS_FILE_HEADER *FfsFileHeader;
@ -500,7 +507,8 @@ FfsFindSectionDataWithHook (
SectionCheckHook, SectionCheckHook,
Section, Section,
FileSize, FileSize,
SectionData SectionData,
SectionSize
); );
} }
@ -522,9 +530,10 @@ FfsFindSectionData (
IN EFI_SECTION_TYPE SectionType, IN EFI_SECTION_TYPE SectionType,
IN EFI_PEI_FILE_HANDLE FileHandle, 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 +825,7 @@ FfsProcessFvFile (
{ {
EFI_STATUS Status; EFI_STATUS Status;
EFI_PEI_FV_HANDLE FvImageHandle; EFI_PEI_FV_HANDLE FvImageHandle;
UINT32 FvImageHandleSize;
EFI_FV_INFO FvImageInfo; EFI_FV_INFO FvImageInfo;
UINT32 FvAlignment; UINT32 FvAlignment;
VOID *FvBuffer; VOID *FvBuffer;
@ -842,7 +852,13 @@ FfsProcessFvFile (
// //
// Find FvImage in FvFile // 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)) { if (EFI_ERROR (Status)) {
return Status; return Status;
} }

View File

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

View File

@ -6,6 +6,7 @@
**/ **/
#include "ProcessorBind.h"
#include <PrePi.h> #include <PrePi.h>
// //
@ -56,54 +57,40 @@ AllocateCodePages (
EFI_STATUS EFI_STATUS
EFIAPI EFIAPI
LoadPeCoffImage ( LoadUefiImage (
IN VOID *PeCoffImage, IN VOID *UefiImage,
IN UINT32 UefiImageSize,
OUT EFI_PHYSICAL_ADDRESS *ImageAddress, OUT EFI_PHYSICAL_ADDRESS *ImageAddress,
OUT UINT64 *ImageSize, OUT UINT64 *ImageSize,
OUT EFI_PHYSICAL_ADDRESS *EntryPoint OUT EFI_PHYSICAL_ADDRESS *EntryPoint
) )
{ {
RETURN_STATUS Status; RETURN_STATUS Status;
PE_COFF_LOADER_IMAGE_CONTEXT ImageContext; UEFI_IMAGE_LOADER_IMAGE_CONTEXT ImageContext;
VOID *Buffer; VOID *Buffer;
UINT32 BufferSize;
ZeroMem (&ImageContext, sizeof (ImageContext)); Status = UefiImageInitializeContext (&ImageContext, UefiImage, UefiImageSize);
ASSERT_EFI_ERROR (Status);
ImageContext.Handle = PeCoffImage; Status = UefiImageLoaderGetDestinationSize (&ImageContext, &BufferSize);
ImageContext.ImageRead = PeCoffLoaderImageReadFromMemory;
Status = PeCoffLoaderGetImageInfo (&ImageContext);
ASSERT_EFI_ERROR (Status); ASSERT_EFI_ERROR (Status);
// //
// Allocate Memory for the image // Allocate Memory for the image
// //
Buffer = AllocateCodePages (EFI_SIZE_TO_PAGES ((UINT32)ImageContext.ImageSize)); Buffer = AllocateCodePages (EFI_SIZE_TO_PAGES (BufferSize));
ASSERT (Buffer != 0); 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); ASSERT_EFI_ERROR (Status);
// *ImageAddress = (UINTN) UefiImageLoaderGetImageAddress (&ImageContext);
// Relocate the image in our new buffer *ImageSize = UefiImageGetImageSize (&ImageContext);
// *EntryPoint = (UINTN) UefiImageLoaderGetImageEntryPoint (&ImageContext);
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);
return Status; return Status;
} }
@ -122,7 +109,8 @@ LoadDxeCoreFromFfsFile (
) )
{ {
EFI_STATUS Status; EFI_STATUS Status;
VOID *PeCoffImage; VOID *UefiImage;
UINT32 UefiImageSize;
EFI_PHYSICAL_ADDRESS ImageAddress; EFI_PHYSICAL_ADDRESS ImageAddress;
UINT64 ImageSize; UINT64 ImageSize;
EFI_PHYSICAL_ADDRESS EntryPoint; EFI_PHYSICAL_ADDRESS EntryPoint;
@ -131,13 +119,13 @@ LoadDxeCoreFromFfsFile (
VOID *Hob; VOID *Hob;
EFI_FV_FILE_INFO FvFileInfo; 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)) { if (EFI_ERROR (Status)) {
return Status; return Status;
} }
Status = LoadPeCoffImage (PeCoffImage, &ImageAddress, &ImageSize, &EntryPoint); Status = LoadUefiImage (UefiImage, UefiImageSize, &ImageAddress, &ImageSize, &EntryPoint);
// For NT32 Debug Status = SecWinNtPeiLoadFile (PeCoffImage, &ImageAddress, &ImageSize, &EntryPoint); // For NT32 Debug Status = SecWinNtPeiLoadFile (UefiImage, &ImageAddress, &ImageSize, &EntryPoint);
ASSERT_EFI_ERROR (Status); ASSERT_EFI_ERROR (Status);
// //

View File

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

View File

@ -62,8 +62,8 @@
SynchronizationLib|MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf SynchronizationLib|MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf
PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf
CacheMaintenanceLib|MdePkg/Library/BaseCacheMaintenanceLib/BaseCacheMaintenanceLib.inf CacheMaintenanceLib|MdePkg/Library/BaseCacheMaintenanceLib/BaseCacheMaintenanceLib.inf
PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf PeCoffLib2|MdePkg/Library/BasePeCoffLib2/BasePeCoffLib2.inf
PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf UefiImageLib|MdePkg/Library/BaseUefiImageLib/BaseUefiImageLibPeCoff.inf
BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf
FrameBufferBltLib|MdeModulePkg/Library/FrameBufferBltLib/FrameBufferBltLib.inf FrameBufferBltLib|MdeModulePkg/Library/FrameBufferBltLib/FrameBufferBltLib.inf
@ -143,8 +143,7 @@
[LibraryClasses.common.SEC] [LibraryClasses.common.SEC]
PeiServicesLib|EmulatorPkg/Library/SecPeiServicesLib/SecPeiServicesLib.inf PeiServicesLib|EmulatorPkg/Library/SecPeiServicesLib/SecPeiServicesLib.inf
PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
PeCoffGetEntryPointLib|EmulatorPkg/Library/PeiEmuPeCoffGetEntryPointLib/PeiEmuPeCoffGetEntryPointLib.inf UefiImageExtraActionLib|EmulatorPkg/Library/PeiEmuUefiImageExtraActionLib/PeiEmuUefiImageExtraActionLib.inf
PeCoffExtraActionLib|EmulatorPkg/Library/PeiEmuPeCoffExtraActionLib/PeiEmuPeCoffExtraActionLib.inf
SerialPortLib|EmulatorPkg/Library/PeiEmuSerialPortLib/PeiEmuSerialPortLib.inf SerialPortLib|EmulatorPkg/Library/PeiEmuSerialPortLib/PeiEmuSerialPortLib.inf
PpiListLib|EmulatorPkg/Library/SecPpiListLib/SecPpiListLib.inf PpiListLib|EmulatorPkg/Library/SecPpiListLib/SecPpiListLib.inf
DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
@ -152,13 +151,13 @@
[LibraryClasses.common.USER_DEFINED, LibraryClasses.common.BASE] [LibraryClasses.common.USER_DEFINED, LibraryClasses.common.BASE]
DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf 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 MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf
PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
PpiListLib|EmulatorPkg/Library/SecPpiListLib/SecPpiListLib.inf PpiListLib|EmulatorPkg/Library/SecPpiListLib/SecPpiListLib.inf
ThunkPpiList|EmulatorPkg/Library/ThunkPpiList/ThunkPpiList.inf ThunkPpiList|EmulatorPkg/Library/ThunkPpiList/ThunkPpiList.inf
ThunkProtocolList|EmulatorPkg/Library/ThunkProtocolList/ThunkProtocolList.inf ThunkProtocolList|EmulatorPkg/Library/ThunkProtocolList/ThunkProtocolList.inf
PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf
PpiListLib|EmulatorPkg/Library/SecPpiListLib/SecPpiListLib.inf PpiListLib|EmulatorPkg/Library/SecPpiListLib/SecPpiListLib.inf
PeiServicesLib|EmulatorPkg/Library/SecPeiServicesLib/SecPeiServicesLib.inf PeiServicesLib|EmulatorPkg/Library/SecPeiServicesLib/SecPeiServicesLib.inf
@ -167,8 +166,7 @@
HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf
MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf
ReportStatusCodeLib|MdeModulePkg/Library/PeiReportStatusCodeLib/PeiReportStatusCodeLib.inf ReportStatusCodeLib|MdeModulePkg/Library/PeiReportStatusCodeLib/PeiReportStatusCodeLib.inf
PeCoffGetEntryPointLib|EmulatorPkg/Library/PeiEmuPeCoffGetEntryPointLib/PeiEmuPeCoffGetEntryPointLib.inf UefiImageExtraActionLib|EmulatorPkg/Library/PeiEmuUefiImageExtraActionLib/PeiEmuUefiImageExtraActionLib.inf
PeCoffExtraActionLib|EmulatorPkg/Library/PeiEmuPeCoffExtraActionLib/PeiEmuPeCoffExtraActionLib.inf
ExtractGuidedSectionLib|MdePkg/Library/PeiExtractGuidedSectionLib/PeiExtractGuidedSectionLib.inf ExtractGuidedSectionLib|MdePkg/Library/PeiExtractGuidedSectionLib/PeiExtractGuidedSectionLib.inf
SerialPortLib|EmulatorPkg/Library/PeiEmuSerialPortLib/PeiEmuSerialPortLib.inf SerialPortLib|EmulatorPkg/Library/PeiEmuSerialPortLib/PeiEmuSerialPortLib.inf
ReportStatusCodeLib|MdeModulePkg/Library/PeiReportStatusCodeLib/PeiReportStatusCodeLib.inf ReportStatusCodeLib|MdeModulePkg/Library/PeiReportStatusCodeLib/PeiReportStatusCodeLib.inf
@ -184,7 +182,7 @@
HobLib|MdePkg/Library/DxeCoreHobLib/DxeCoreHobLib.inf HobLib|MdePkg/Library/DxeCoreHobLib/DxeCoreHobLib.inf
MemoryAllocationLib|MdeModulePkg/Library/DxeCoreMemoryAllocationLib/DxeCoreMemoryAllocationLib.inf MemoryAllocationLib|MdeModulePkg/Library/DxeCoreMemoryAllocationLib/DxeCoreMemoryAllocationLib.inf
ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.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 ExtractGuidedSectionLib|MdePkg/Library/DxeExtractGuidedSectionLib/DxeExtractGuidedSectionLib.inf
PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
TimerLib|EmulatorPkg/Library/DxeCoreTimerLib/DxeCoreTimerLib.inf TimerLib|EmulatorPkg/Library/DxeCoreTimerLib/DxeCoreTimerLib.inf
@ -206,7 +204,7 @@
MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf
EmuThunkLib|EmulatorPkg/Library/DxeEmuLib/DxeEmuLib.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 ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf
TimerLib|EmulatorPkg/Library/DxeTimerLib/DxeTimerLib.inf TimerLib|EmulatorPkg/Library/DxeTimerLib/DxeTimerLib.inf

View File

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

View File

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

View File

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

View File

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

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

View File

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

View File

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

View File

@ -1,44 +1,43 @@
## @file ## @file
# Component description file for the EdkNt32PeiPeCoffGetEntryPointLib library. # Component description file for the EdkNt32PeiPeCoffGetEntryPointLib library.
# #
# PeCoffGetEntryPointLib library class for NT32 instance implemented by use NTPeiLoadFile PPI. # PeCoffGetEntryPointLib library class for NT32 instance implemented by use NTPeiLoadFile PPI.
# Copyright (c) 2008 - 2018, Intel Corporation. All rights reserved.<BR> # Copyright (c) 2008 - 2018, Intel Corporation. All rights reserved.<BR>
# Portions copyright (c) 2011, Apple Inc. All rights reserved. # Portions copyright (c) 2011, Apple Inc. All rights reserved.
# #
# SPDX-License-Identifier: BSD-2-Clause-Patent # SPDX-License-Identifier: BSD-2-Clause-Patent
# #
# #
## ##
[Defines] [Defines]
INF_VERSION = 0x00010005 INF_VERSION = 0x00010005
BASE_NAME = PeiEmuPeCoffGetEntryPointLib BASE_NAME = PeiEmuPeCoffGetEntryPointLib
FILE_GUID = 1CBED347-7DE6-BC48-AC68-3758598124D2 FILE_GUID = 1CBED347-7DE6-BC48-AC68-3758598124D2
MODULE_TYPE = PEIM MODULE_TYPE = PEIM
VERSION_STRING = 1.0 VERSION_STRING = 1.0
LIBRARY_CLASS = PeCoffGetEntryPointLib LIBRARY_CLASS = PeCoffGetEntryPointLib
# #
# The following information is for reference only and not required by the build tools. # The following information is for reference only and not required by the build tools.
# #
# VALID_ARCHITECTURES = IA32 X64 EBC # VALID_ARCHITECTURES = IA32 X64 EBC
# #
[Sources] [Sources]
PeiEmuPeCoffGetEntryPointLib.c PeiEmuPeCoffGetEntryPointLib.c
[Packages] [Packages]
MdePkg/MdePkg.dec MdePkg/MdePkg.dec
EmulatorPkg/EmulatorPkg.dec EmulatorPkg/EmulatorPkg.dec
[LibraryClasses] [LibraryClasses]
PeiServicesLib PeiServicesLib
DebugLib DebugLib
[Ppis] [Ppis]
gEmuThunkPpiGuid # PPI ALWAYS_CONSUMED gEmuThunkPpiGuid # PPI ALWAYS_CONSUMED

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; 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 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. This service enables a given PEIM to register an interface into the PEI Foundation.
@ -304,6 +312,38 @@ PeiServicesFfsFindSectionData (
return SecFfsFindSectionData (SectionType, FileHandle, SectionData); 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 This service enables PEIMs to register the permanent memory configuration
that has been initialized with the PEI Foundation. 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 "Sec.h"
#include <Ppi/EmuThunk.h>
EFI_PEI_TEMPORARY_RAM_SUPPORT_PPI mSecTemporaryRamSupportPpi = { EFI_PEI_TEMPORARY_RAM_SUPPORT_PPI mSecTemporaryRamSupportPpi = {
SecTemporaryRamSupport 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 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 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_STATUS Status;
EFI_PEI_FV_HANDLE VolumeHandle; EFI_PEI_FV_HANDLE VolumeHandle;
EFI_PEI_FILE_HANDLE FileHandle; EFI_PEI_FILE_HANDLE FileHandle;
VOID *PeCoffImage; VOID *UefiImage;
UINT32 UefiImageSize;
EFI_PEI_CORE_ENTRY_POINT EntryPoint; EFI_PEI_CORE_ENTRY_POINT EntryPoint;
EFI_PEI_PPI_DESCRIPTOR *Ppi; EFI_PEI_PPI_DESCRIPTOR *Ppi;
EFI_PEI_PPI_DESCRIPTOR *SecPpiList; EFI_PEI_PPI_DESCRIPTOR *SecPpiList;
UINTN SecReseveredMemorySize; UINTN SecReseveredMemorySize;
UINTN Index; UINTN Index;
EFI_PEI_PPI_DESCRIPTOR PpiArray[10]; EFI_PEI_PPI_DESCRIPTOR PpiArray[10];
UINT32 AuthenticationStatus;
EMU_MAGIC_PAGE ()->PpiList = PpiList; EMU_MAGIC_PAGE ()->PpiList = PpiList;
ProcessLibraryConstructorList (); ProcessLibraryConstructorList ();
@ -118,10 +168,10 @@ _ModuleEntryPoint (
Status = PeiServicesFfsFindNextFile (EFI_FV_FILETYPE_PEI_CORE, VolumeHandle, &FileHandle); Status = PeiServicesFfsFindNextFile (EFI_FV_FILETYPE_PEI_CORE, VolumeHandle, &FileHandle);
ASSERT_EFI_ERROR (Status); 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); ASSERT_EFI_ERROR (Status);
Status = PeCoffLoaderGetEntryPoint (PeCoffImage, (VOID **)&EntryPoint); Status = UefiImageLoaderGetEntryPoint (UefiImage, UefiImageSize, (VOID **)&EntryPoint);
ASSERT_EFI_ERROR (Status); ASSERT_EFI_ERROR (Status);
// Transfer control to PEI Core // Transfer control to PEI Core

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -44,9 +44,6 @@ EMU_FD_INFO *gFdInfo;
UINTN gSystemMemoryCount = 0; UINTN gSystemMemoryCount = 0;
EMU_SYSTEM_MEMORY *gSystemMemory; EMU_SYSTEM_MEMORY *gSystemMemory;
UINTN mImageContextModHandleArraySize = 0;
IMAGE_CONTEXT_TO_MOD_HANDLE *mImageContextModHandleArray = NULL;
EFI_PEI_PPI_DESCRIPTOR *gPpiList; EFI_PEI_PPI_DESCRIPTOR *gPpiList;
int gInXcode = 0; int gInXcode = 0;
@ -98,11 +95,13 @@ main (
BOOLEAN Done; BOOLEAN Done;
EFI_PEI_FILE_HANDLE FileHandle; EFI_PEI_FILE_HANDLE FileHandle;
VOID *SecFile; VOID *SecFile;
UINT32 SecFileSize;
CHAR16 *MemorySizeStr; CHAR16 *MemorySizeStr;
CHAR16 *FirmwareVolumesStr; CHAR16 *FirmwareVolumesStr;
UINTN *StackPointer; UINTN *StackPointer;
FILE *GdbTempFile; FILE *GdbTempFile;
EMU_THUNK_PPI *SecEmuThunkPpi; EMU_THUNK_PPI *SecEmuThunkPpi;
UINT32 AuthenticationStatus;
// //
// Xcode does not support sourcing gdb scripts directly, so the Xcode XML // Xcode does not support sourcing gdb scripts directly, so the Xcode XML
@ -111,8 +110,7 @@ main (
SecGdbConfigBreak (); SecGdbConfigBreak ();
// //
// If dlopen doesn't work, then we build a gdb script to allow the // We build a gdb script to allow the symbols to be loaded.
// symbols to be loaded.
// //
Index = strlen (*Argv); Index = strlen (*Argv);
gGdbWorkingFileName = AllocatePool (Index + strlen (".gdb") + 1); gGdbWorkingFileName = AllocatePool (Index + strlen (".gdb") + 1);
@ -284,7 +282,14 @@ main (
&FileHandle &FileHandle
); );
if (!EFI_ERROR (Status)) { 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)) { if (!EFI_ERROR (Status)) {
PeiIndex = Index; PeiIndex = Index;
printf (" contains SEC Core"); printf (" contains SEC Core");
@ -330,7 +335,7 @@ main (
// //
// Hand off to SEC // 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 // 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 LargestRegion,
IN UINTN LargestRegionSize, IN UINTN LargestRegionSize,
IN UINTN BootFirmwareVolumeBase, IN UINTN BootFirmwareVolumeBase,
IN VOID *PeiCorePe32File IN VOID *PeiCorePe32File,
IN UINT32 PeiCorePe32Size
) )
{ {
EFI_STATUS Status; EFI_STATUS Status;
@ -597,7 +603,7 @@ SecLoadFromCore (
// //
// Find the SEC Core Entry Point // Find the SEC Core Entry Point
// //
Status = SecPeCoffGetEntryPoint (PeiCorePe32File, (VOID **)&PeiCoreEntryPoint); Status = SecUefiImageGetEntryPoint (PeiCorePe32File, PeiCorePe32Size, (VOID **)&PeiCoreEntryPoint);
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {
return; return;
} }
@ -731,53 +737,28 @@ SecEmuThunkAddress (
RETURN_STATUS RETURN_STATUS
EFIAPI EFIAPI
SecPeCoffGetEntryPoint ( SecUefiImageGetEntryPoint (
IN VOID *Pe32Data, IN VOID *Pe32Data,
IN OUT VOID **EntryPoint IN UINT32 Pe32Size,
IN OUT VOID **EntryPoint
) )
{ {
EFI_STATUS Status; EFI_STATUS Status;
PE_COFF_LOADER_IMAGE_CONTEXT ImageContext; UEFI_IMAGE_LOADER_IMAGE_CONTEXT ImageContext;
ZeroMem (&ImageContext, sizeof (ImageContext)); Status = UefiImageInitializeContext (&ImageContext, Pe32Data, Pe32Size);
ImageContext.Handle = Pe32Data;
ImageContext.ImageRead = (PE_COFF_LOADER_READ_FILE)SecImageRead;
Status = PeCoffLoaderGetImageInfo (&ImageContext);
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {
return Status; return Status;
} }
if (ImageContext.ImageAddress != (UINTN)Pe32Data) { // FIXME: Why cannot the Image be in-place already?
// Status = UefiImageRelocateImageInplaceForExecution (&ImageContext);
// Relocate image to match the address where it resides if (EFI_ERROR (Status)) {
// return Status;
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;
} }
// On Unix a dlopen is done that will change the entry point SecUefiImageRelocateImageExtraAction (&ImageContext);
SecPeCoffRelocateImageExtraAction (&ImageContext); *EntryPoint = (VOID *) (UefiImageLoaderGetImageEntryPoint (&ImageContext));
*EntryPoint = (VOID *)(UINTN)ImageContext.EntryPoint;
return Status; return Status;
} }
@ -900,114 +881,9 @@ Returns:
return EFI_SUCCESS; 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 BOOLEAN
IsPdbFile ( IsPdbFile (
IN CHAR8 *PdbFileName IN CONST CHAR8 *PdbFileName
) )
{ {
UINTN Len; UINTN Len;
@ -1035,23 +911,29 @@ IsPdbFile (
void void
PrintLoadAddress ( 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 ( fprintf (
stderr, stderr,
"0x%08lx Loading NO DEBUG with entry point 0x%08lx\n", "0x%08lx Loading NO DEBUG with entry point 0x%08lx\n",
(unsigned long)(ImageContext->ImageAddress), (unsigned long) UefiImageLoaderGetImageAddress (ImageContext),
(unsigned long)ImageContext->EntryPoint (unsigned long) UefiImageLoaderGetImageEntryPoint (ImageContext)
); );
} else { } else {
fprintf ( fprintf (
stderr, stderr,
"0x%08lx Loading %s with entry point 0x%08lx\n", "0x%08lx Loading %s with entry point 0x%08lx\n",
(unsigned long)(ImageContext->ImageAddress + ImageContext->SizeOfHeaders), (unsigned long) UefiImageLoaderGetImageAddress (ImageContext),
ImageContext->PdbPointer, PdbPath,
(unsigned long)ImageContext->EntryPoint (unsigned long) UefiImageLoaderGetImageEntryPoint (ImageContext)
); );
} }
@ -1059,71 +941,12 @@ PrintLoadAddress (
fflush (stderr); 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__ #ifdef __APPLE__
__attribute__ ((noinline)) __attribute__ ((noinline))
#endif #endif
VOID VOID
SecGdbScriptBreak ( SecGdbScriptBreak (
char *FileName, const char *FileName,
int FileNameLength, int FileNameLength,
long unsigned int LoadAddress, long unsigned int LoadAddress,
int AddSymbolFlag int AddSymbolFlag
@ -1141,28 +964,37 @@ SecGdbScriptBreak (
**/ **/
VOID VOID
GdbScriptAddImage ( 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); PrintLoadAddress (ImageContext);
if ((ImageContext->PdbPointer != NULL) && !IsPdbFile (ImageContext->PdbPointer)) { Status = UefiImageGetSymbolsPath ((ImageContext, &PdbPath,) &PdbPathSize);
if (EFI_ERROR (Status)) {
return;
}
if (!IsPdbFile (PdbPath)) {
FILE *GdbTempFile; FILE *GdbTempFile;
if (FeaturePcdGet (PcdEmulatorLazyLoadSymbols)) { if (FeaturePcdGet (PcdEmulatorLazyLoadSymbols)) {
GdbTempFile = fopen (gGdbWorkingFileName, "a"); GdbTempFile = fopen (gGdbWorkingFileName, "a");
if (GdbTempFile != NULL) { if (GdbTempFile != NULL) {
long unsigned int SymbolsAddr = (long unsigned int)(ImageContext->ImageAddress + ImageContext->SizeOfHeaders); long unsigned int SymbolsAddr = (long unsigned int)UefiImageLoaderGetImageAddress (ImageContext);
mScriptSymbolChangesCount++; mScriptSymbolChangesCount++;
fprintf ( fprintf (
GdbTempFile, GdbTempFile,
"AddFirmwareSymbolFile 0x%x %s 0x%08lx\n", "AddFirmwareSymbolFile 0x%x %s 0x%08lx\n",
mScriptSymbolChangesCount, mScriptSymbolChangesCount,
ImageContext->PdbPointer, PdbPath,
SymbolsAddr SymbolsAddr
); );
fclose (GdbTempFile); fclose (GdbTempFile);
// This is for the lldb breakpoint only // 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 { } else {
ASSERT (FALSE); ASSERT (FALSE);
} }
@ -1171,9 +1003,9 @@ GdbScriptAddImage (
if (GdbTempFile != NULL) { if (GdbTempFile != NULL) {
fprintf ( fprintf (
GdbTempFile, GdbTempFile,
"add-symbol-file %s 0x%08lx\n", "add-symbol-file %s -o 0x%08lx\n",
ImageContext->PdbPointer, PdbPath,
(long unsigned int)(ImageContext->ImageAddress + ImageContext->SizeOfHeaders) (long unsigned int)UefiImageLoaderGetImageAddress (ImageContext)
); );
fclose (GdbTempFile); fclose (GdbTempFile);
@ -1183,7 +1015,7 @@ GdbScriptAddImage (
// Also used for the lldb breakpoint script. The lldb breakpoint script does // Also used for the lldb breakpoint script. The lldb breakpoint script does
// not use the file, it uses the arguments. // 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 { } else {
ASSERT (FALSE); ASSERT (FALSE);
} }
@ -1193,13 +1025,11 @@ GdbScriptAddImage (
VOID VOID
EFIAPI EFIAPI
SecPeCoffRelocateImageExtraAction ( SecUefiImageRelocateImageExtraAction (
IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext
) )
{ {
if (!DlLoadImage (ImageContext)) { GdbScriptAddImage (ImageContext);
GdbScriptAddImage (ImageContext);
}
} }
/** /**
@ -1211,15 +1041,23 @@ SecPeCoffRelocateImageExtraAction (
**/ **/
VOID VOID
GdbScriptRemoveImage ( 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++ // Need to skip .PDB files created from VC++
// //
if (IsPdbFile (ImageContext->PdbPointer)) { if (IsPdbFile (PdbPath)) {
return; return;
} }
@ -1234,24 +1072,24 @@ GdbScriptRemoveImage (
GdbTempFile, GdbTempFile,
"RemoveFirmwareSymbolFile 0x%x %s\n", "RemoveFirmwareSymbolFile 0x%x %s\n",
mScriptSymbolChangesCount, mScriptSymbolChangesCount,
ImageContext->PdbPointer PdbPath
); );
fclose (GdbTempFile); fclose (GdbTempFile);
SecGdbScriptBreak (ImageContext->PdbPointer, strlen (ImageContext->PdbPointer) + 1, 0, 0); SecGdbScriptBreak (PdbPath, PdbPathSize, 0, 0);
} else { } else {
ASSERT (FALSE); ASSERT (FALSE);
} }
} else { } else {
GdbTempFile = fopen (gGdbWorkingFileName, "w"); GdbTempFile = fopen (gGdbWorkingFileName, "w");
if (GdbTempFile != NULL) { if (GdbTempFile != NULL) {
fprintf (GdbTempFile, "remove-symbol-file %s\n", ImageContext->PdbPointer); fprintf (GdbTempFile, "remove-symbol-file %s\n", PdbPath);
fclose (GdbTempFile); fclose (GdbTempFile);
// //
// Target for gdb breakpoint in a script that uses gGdbWorkingFileName to set a breakpoint. // 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.... // 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 { } else {
ASSERT (FALSE); ASSERT (FALSE);
} }
@ -1260,22 +1098,9 @@ GdbScriptRemoveImage (
VOID VOID
EFIAPI EFIAPI
SecPeCoffUnloadImageExtraAction ( SecUefiImageUnloadImageExtraAction (
IN PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext 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); GdbScriptRemoveImage (ImageContext);
} }

View File

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

View File

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

View File

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

View File

@ -358,8 +358,8 @@ ASM_PFX(GasketSecGetNextProtocol):
// PPIs produced by SEC // PPIs produced by SEC
ASM_GLOBAL ASM_PFX(GasketSecPeCoffGetEntryPoint) ASM_GLOBAL ASM_PFX(GasketSecUefiImageGetEntryPoint)
ASM_PFX(GasketSecPeCoffGetEntryPoint): ASM_PFX(GasketSecUefiImageGetEntryPoint):
pushq %rbp // stack frame is for the debugger pushq %rbp // stack frame is for the debugger
movq %rsp, %rbp movq %rsp, %rbp
@ -368,16 +368,17 @@ ASM_PFX(GasketSecPeCoffGetEntryPoint):
movq %rcx, %rdi // Swizzle args movq %rcx, %rdi // Swizzle args
movq %rdx, %rsi movq %rdx, %rsi
movq %r8, %rdx
call ASM_PFX(SecPeCoffGetEntryPoint) call ASM_PFX(SecUefiImageGetEntryPoint)
popq %rdi // restore state popq %rdi // restore state
popq %rsi popq %rsi
popq %rbp popq %rbp
ret ret
ASM_GLOBAL ASM_PFX(GasketSecPeCoffRelocateImageExtraAction) ASM_GLOBAL ASM_PFX(GasketSecUefiImageRelocateImageExtraAction)
ASM_PFX(GasketSecPeCoffRelocateImageExtraAction): ASM_PFX(GasketSecUefiImageRelocateImageExtraAction):
pushq %rbp // stack frame is for the debugger pushq %rbp // stack frame is for the debugger
movq %rsp, %rbp movq %rsp, %rbp
@ -386,15 +387,15 @@ ASM_PFX(GasketSecPeCoffRelocateImageExtraAction):
movq %rcx, %rdi // Swizzle args movq %rcx, %rdi // Swizzle args
call ASM_PFX(SecPeCoffRelocateImageExtraAction) call ASM_PFX(SecUefiImageRelocateImageExtraAction)
popq %rdi // restore state popq %rdi // restore state
popq %rsi popq %rsi
popq %rbp popq %rbp
ret ret
ASM_GLOBAL ASM_PFX(GasketSecPeCoffUnloadImageExtraAction) ASM_GLOBAL ASM_PFX(GasketSecUefiImageUnloadImageExtraAction)
ASM_PFX(GasketSecPeCoffUnloadImageExtraAction): ASM_PFX(GasketSecUefiImageUnloadImageExtraAction):
pushq %rbp // stack frame is for the debugger pushq %rbp // stack frame is for the debugger
movq %rsp, %rbp movq %rsp, %rbp
@ -403,7 +404,7 @@ ASM_PFX(GasketSecPeCoffUnloadImageExtraAction):
movq %rcx, %rdi // Swizzle args movq %rcx, %rdi // Swizzle args
call ASM_PFX(SecPeCoffUnloadImageExtraAction) call ASM_PFX(SecUefiImageUnloadImageExtraAction)
popq %rdi // restore state popq %rdi // restore state
popq %rsi 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 # VOID
# SecGdbScriptBreak ( # SecGdbScriptBreak (
# char *FileName, # const char *FileName,
# int FileNameLength, # int FileNameLength,
# long unsigned int LoadAddress, # long unsigned int LoadAddress,
# int AddSymbolFlag # int AddSymbolFlag
@ -394,7 +394,7 @@ def LoadEmulatorEfiSymbols(frame, bp_loc , internal_dict):
debugger = frame.thread.process.target.debugger debugger = frame.thread.process.target.debugger
if frame.FindVariable ("AddSymbolFlag").GetValueAsUnsigned() == 1: if frame.FindVariable ("AddSymbolFlag").GetValueAsUnsigned() == 1:
LoadAddress = frame.FindVariable ("LoadAddress").GetValueAsUnsigned() - 0x240 LoadAddress = frame.FindVariable ("LoadAddress").GetValueAsUnsigned()
debugger.HandleCommand ("target modules add %s" % FileName) debugger.HandleCommand ("target modules add %s" % FileName)
print("target modules load --slid 0x%x %s" % (LoadAddress, FileName)) print("target modules load --slid 0x%x %s" % (LoadAddress, FileName))

View File

@ -444,6 +444,7 @@ Returns:
BOOLEAN Done; BOOLEAN Done;
EFI_PEI_FILE_HANDLE FileHandle; EFI_PEI_FILE_HANDLE FileHandle;
VOID *SecFile; VOID *SecFile;
UINT32 SecFileSize;
CHAR16 *MemorySizeStr; CHAR16 *MemorySizeStr;
CHAR16 *FirmwareVolumesStr; CHAR16 *FirmwareVolumesStr;
UINTN ProcessAffinityMask; UINTN ProcessAffinityMask;
@ -451,6 +452,7 @@ Returns:
INT32 LowBit; INT32 LowBit;
UINTN ResetJumpCode; UINTN ResetJumpCode;
EMU_THUNK_PPI *SecEmuThunkPpi; EMU_THUNK_PPI *SecEmuThunkPpi;
UINT32 AuthenticationStatus;
// //
// Enable the privilege so that RTC driver can successfully run SetTime() // Enable the privilege so that RTC driver can successfully run SetTime()
@ -648,7 +650,14 @@ Returns:
&FileHandle &FileHandle
); );
if (!EFI_ERROR (Status)) { 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)) { if (!EFI_ERROR (Status)) {
SecPrint (" contains SEC Core"); SecPrint (" contains SEC Core");
} }
@ -679,7 +688,7 @@ Returns:
// //
// Hand off to SEC Core // 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 // 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 UINTN TemporaryRamSize,
IN VOID *BootFirmwareVolumeBase, IN VOID *BootFirmwareVolumeBase,
IN UINTN BootFirmwareVolumeSize, 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 // Load the PEI Core from a Firmware Volume
// //
Status = SecPeCoffGetEntryPoint ( Status = SecUefiImageGetEntryPoint (
SecCorePe32File, SecCorePe32File,
SecCorePe32Size,
&SecCoreEntryPoint &SecCoreEntryPoint
); );
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {
@ -784,40 +795,47 @@ Returns:
RETURN_STATUS RETURN_STATUS
EFIAPI EFIAPI
SecPeCoffGetEntryPoint ( SecUefiImageGetEntryPoint (
IN VOID *Pe32Data, IN VOID *Pe32Data,
IN OUT VOID **EntryPoint IN UINT32 Pe32Size,
IN OUT VOID **EntryPoint
) )
{ {
EFI_STATUS Status; EFI_STATUS Status;
PE_COFF_LOADER_IMAGE_CONTEXT ImageContext; UEFI_IMAGE_LOADER_IMAGE_CONTEXT ImageContext;
VOID *Dest;
UINT32 DestSize;
ZeroMem (&ImageContext, sizeof (ImageContext)); Status = UefiImageInitializeContext (&ImageContext, Pe32Data, Pe32Size);
ImageContext.Handle = Pe32Data;
ImageContext.ImageRead = (PE_COFF_LOADER_READ_FILE)SecImageRead;
Status = PeCoffLoaderGetImageInfo (&ImageContext);
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {
return 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 = UefiImageLoaderGetDestinationSize(&ImageContext, &DestSize);
Status = PeCoffLoaderLoadImage (&ImageContext);
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {
return 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)) { if (EFI_ERROR (Status)) {
return 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; return EFI_SUCCESS;
} }
@ -951,7 +969,7 @@ Returns:
--*/ --*/
EFI_STATUS EFI_STATUS
AddModHandle ( AddModHandle (
IN PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext, IN UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext,
IN VOID *ModHandle IN VOID *ModHandle
) )
@ -1028,7 +1046,7 @@ AddModHandle (
**/ **/
VOID * VOID *
RemoveModHandle ( RemoveModHandle (
IN PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext IN UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext
) )
{ {
UINTN Index; UINTN Index;
@ -1058,8 +1076,8 @@ RemoveModHandle (
VOID VOID
EFIAPI EFIAPI
PeCoffLoaderRelocateImageExtraAction ( UefiImageLoaderRelocateImageExtraAction (
IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext
) )
{ {
EFI_STATUS Status; EFI_STATUS Status;
@ -1084,7 +1102,7 @@ PeCoffLoaderRelocateImageExtraAction (
// Load the DLL if it's not an EBC image. // Load the DLL if it's not an EBC image.
// //
if ((ImageContext->PdbPointer != NULL) && if ((ImageContext->PdbPointer != NULL) &&
(ImageContext->Machine != EFI_IMAGE_MACHINE_EBC)) (UefiImageGetMachine (ImageContext) != EFI_IMAGE_MACHINE_EBC))
{ {
// //
// Convert filename from ASCII to Unicode // Convert filename from ASCII to Unicode
@ -1098,7 +1116,7 @@ PeCoffLoaderRelocateImageExtraAction (
free (DllFileName); 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 // The image will run, but we just can't source level debug. If we
// return an error the image will not run. // 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 // checking as the we can point to the PE32 image loaded by Tiano. This
// step is only needed for source level debugging // step is only needed for source level debugging
// //
// FIXME: Fix ImageBase too
DllEntryPoint = (VOID *)(UINTN)GetProcAddress (Library, "InitializeDriver"); DllEntryPoint = (VOID *)(UINTN)GetProcAddress (Library, "InitializeDriver");
} }
@ -1154,8 +1173,8 @@ PeCoffLoaderRelocateImageExtraAction (
VOID VOID
EFIAPI EFIAPI
PeCoffLoaderUnloadImageExtraAction ( UefiImageLoaderUnloadImageExtraAction (
IN PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext IN UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext
) )
{ {
VOID *ModHandle; VOID *ModHandle;

View File

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

View File

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

View File

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

View File

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

View File

@ -39,7 +39,7 @@
BaseMemoryLib BaseMemoryLib
UefiLib UefiLib
FspWrapperApiLib FspWrapperApiLib
PeCoffLib UefiImageLib
CacheMaintenanceLib CacheMaintenanceLib
DxeServicesLib DxeServicesLib
PerformanceLib PerformanceLib

View File

@ -11,7 +11,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#include <Library/UefiDriverEntryPoint.h> #include <Library/UefiDriverEntryPoint.h>
#include <Library/BaseMemoryLib.h> #include <Library/BaseMemoryLib.h>
#include <Library/DebugLib.h> #include <Library/DebugLib.h>
#include <Library/PeCoffLib.h> #include <Library/UefiImageLib.h>
#include <Library/UefiBootServicesTableLib.h> #include <Library/UefiBootServicesTableLib.h>
#include <Library/DxeServicesLib.h> #include <Library/DxeServicesLib.h>
#include <Library/CacheMaintenanceLib.h> #include <Library/CacheMaintenanceLib.h>
@ -37,9 +37,10 @@ RelocateImageUnder4GIfNeeded (
UINT8 *Buffer; UINT8 *Buffer;
UINTN BufferSize; UINTN BufferSize;
EFI_HANDLE NewImageHandle; EFI_HANDLE NewImageHandle;
UINT32 DestinationSize;
UINTN Pages; UINTN Pages;
EFI_PHYSICAL_ADDRESS FfsBuffer; EFI_PHYSICAL_ADDRESS FfsBuffer;
PE_COFF_LOADER_IMAGE_CONTEXT ImageContext; UEFI_IMAGE_LOADER_IMAGE_CONTEXT ImageContext;
VOID *Interface; VOID *Interface;
// //
@ -83,18 +84,14 @@ RelocateImageUnder4GIfNeeded (
&BufferSize &BufferSize
); );
ASSERT_EFI_ERROR (Status); ASSERT_EFI_ERROR (Status);
ImageContext.Handle = Buffer;
ImageContext.ImageRead = PeCoffLoaderImageReadFromMemory;
// //
// Get information about the image being loaded // Get information about the image being loaded
// //
Status = PeCoffLoaderGetImageInfo (&ImageContext); Status = UefiImageInitializeContext (&ImageContext, Buffer, (UINT32) BufferSize);
ASSERT_EFI_ERROR (Status); ASSERT_EFI_ERROR (Status);
if (ImageContext.SectionAlignment > EFI_PAGE_SIZE) { Status = UefiImageLoaderGetDestinationSize (&ImageContext, &DestinationSize);
Pages = EFI_SIZE_TO_PAGES ((UINTN)(ImageContext.ImageSize + ImageContext.SectionAlignment)); ASSERT_EFI_ERROR (Status);
} else { Pages = EFI_SIZE_TO_PAGES (DestinationSize);
Pages = EFI_SIZE_TO_PAGES ((UINTN)ImageContext.ImageSize);
}
FfsBuffer = 0xFFFFFFFF; FfsBuffer = 0xFFFFFFFF;
Status = gBS->AllocatePages ( Status = gBS->AllocatePages (
@ -104,22 +101,16 @@ RelocateImageUnder4GIfNeeded (
&FfsBuffer &FfsBuffer
); );
ASSERT_EFI_ERROR (Status); 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; Status = UefiImageLoadImageForExecution (
ImageContext.ImageAddress &= ~((EFI_PHYSICAL_ADDRESS)ImageContext.SectionAlignment - 1); &ImageContext,
// (VOID *) (UINTN) FfsBuffer,
// Load the image to our new buffer DestinationSize,
// NULL,
Status = PeCoffLoaderLoadImage (&ImageContext); 0
ASSERT_EFI_ERROR (Status); );
//
// Relocate the image in our new buffer
//
Status = PeCoffLoaderRelocateImage (&ImageContext);
ASSERT_EFI_ERROR (Status); ASSERT_EFI_ERROR (Status);
// //
@ -127,15 +118,10 @@ RelocateImageUnder4GIfNeeded (
// //
gBS->FreePool (Buffer); gBS->FreePool (Buffer);
// DEBUG ((DEBUG_INFO, "Loading driver at 0x%08x EntryPoint=0x%08x\n", UefiImageLoaderGetImageAddress (&ImageContext), UefiImageLoaderGetImageEntryPoint (&ImageContext)));
// Flush the instruction cache so the image data is written before we execute it Status = ((EFI_IMAGE_ENTRY_POINT)(UefiImageLoaderGetImageEntryPoint (&ImageContext)))(NewImageHandle, gST);
//
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);
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "Error: Image at 0x%08x start failed: %r\n", ImageContext.ImageAddress, Status)); DEBUG ((DEBUG_ERROR, "Error: Image at 0x%08x start failed: %r\n", UefiImageLoaderGetImageAddress (&ImageContext), Status));
gBS->FreePages (FfsBuffer, Pages); gBS->FreePages (FfsBuffer, Pages);
} }

View File

@ -39,8 +39,7 @@
FspWrapperHobProcessLib FspWrapperHobProcessLib
CpuLib CpuLib
UefiCpuLib UefiCpuLib
PeCoffGetEntryPointLib UefiImageExtraActionLib
PeCoffExtraActionLib
PerformanceLib PerformanceLib
TimerLib TimerLib
FspWrapperApiLib FspWrapperApiLib

View File

@ -40,8 +40,7 @@
FspWrapperHobProcessLib FspWrapperHobProcessLib
CpuLib CpuLib
UefiCpuLib UefiCpuLib
PeCoffGetEntryPointLib UefiImageExtraActionLib
PeCoffExtraActionLib
PerformanceLib PerformanceLib
FspWrapperApiLib FspWrapperApiLib
FspWrapperApiTestLib FspWrapperApiTestLib

View File

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

View File

@ -113,7 +113,7 @@ MeasureFspFirmwareBlobWithCfg (
VOID *FvEventLog, *UpdEventLog; VOID *FvEventLog, *UpdEventLog;
UINT32 FvEventLogSize, UpdEventLogSize; UINT32 FvEventLogSize, UpdEventLogSize;
EFI_STATUS Status; EFI_STATUS Status;
HASH_HANDLE HashHandle; VOID *HashHandle;
UINT8 *HashBase; UINT8 *HashBase;
UINTN HashSize; UINTN HashSize;
TPML_DIGEST_VALUES DigestList; TPML_DIGEST_VALUES DigestList;

BIN
LoaderFlow.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 213 KiB

View File

@ -2126,7 +2126,7 @@ TrustTransferAtaDevice (
// ATA PassThru PPI. // ATA PassThru PPI.
// //
if ((AtaPassThru->Mode->IoAlign > 1) && if ((AtaPassThru->Mode->IoAlign > 1) &&
!IS_ALIGNED (Buffer, AtaPassThru->Mode->IoAlign)) !ADDRESS_IS_ALIGNED (Buffer, AtaPassThru->Mode->IoAlign))
{ {
NewBuffer = AllocateAlignedPages ( NewBuffer = AllocateAlignedPages (
EFI_SIZE_TO_PAGES (TransferLength), EFI_SIZE_TO_PAGES (TransferLength),

View File

@ -146,7 +146,6 @@ typedef union {
#define AHCI_PORT_SERR 0x0030 #define AHCI_PORT_SERR 0x0030
#define AHCI_PORT_CI 0x0038 #define AHCI_PORT_CI 0x0038
#define IS_ALIGNED(addr, size) (((UINTN) (addr) & (size - 1)) == 0)
#define TIMER_PERIOD_SECONDS(Seconds) MultU64x32((UINT64)(Seconds), 10000000) #define TIMER_PERIOD_SECONDS(Seconds) MultU64x32((UINT64)(Seconds), 10000000)
#pragma pack(1) #pragma pack(1)

View File

@ -194,15 +194,15 @@ AhciAtaPassThruPassThru (
} }
IoAlign = This->Mode->IoAlign; IoAlign = This->Mode->IoAlign;
if ((IoAlign > 1) && !IS_ALIGNED (Packet->InDataBuffer, IoAlign)) { if ((IoAlign > 1) && !ADDRESS_IS_ALIGNED (Packet->InDataBuffer, IoAlign)) {
return EFI_INVALID_PARAMETER; return EFI_INVALID_PARAMETER;
} }
if ((IoAlign > 1) && !IS_ALIGNED (Packet->OutDataBuffer, IoAlign)) { if ((IoAlign > 1) && !ADDRESS_IS_ALIGNED (Packet->OutDataBuffer, IoAlign)) {
return EFI_INVALID_PARAMETER; return EFI_INVALID_PARAMETER;
} }
if ((IoAlign > 1) && !IS_ALIGNED (Packet->Asb, IoAlign)) { if ((IoAlign > 1) && !ADDRESS_IS_ALIGNED (Packet->Asb, IoAlign)) {
return EFI_INVALID_PARAMETER; return EFI_INVALID_PARAMETER;
} }

View File

@ -1299,15 +1299,15 @@ AtaPassThruPassThru (
Instance = ATA_PASS_THRU_PRIVATE_DATA_FROM_THIS (This); Instance = ATA_PASS_THRU_PRIVATE_DATA_FROM_THIS (This);
if ((This->Mode->IoAlign > 1) && !IS_ALIGNED (Packet->InDataBuffer, This->Mode->IoAlign)) { if ((This->Mode->IoAlign > 1) && !ADDRESS_IS_ALIGNED (Packet->InDataBuffer, This->Mode->IoAlign)) {
return EFI_INVALID_PARAMETER; return EFI_INVALID_PARAMETER;
} }
if ((This->Mode->IoAlign > 1) && !IS_ALIGNED (Packet->OutDataBuffer, This->Mode->IoAlign)) { if ((This->Mode->IoAlign > 1) && !ADDRESS_IS_ALIGNED (Packet->OutDataBuffer, This->Mode->IoAlign)) {
return EFI_INVALID_PARAMETER; return EFI_INVALID_PARAMETER;
} }
if ((This->Mode->IoAlign > 1) && !IS_ALIGNED (Packet->Asb, This->Mode->IoAlign)) { if ((This->Mode->IoAlign > 1) && !ADDRESS_IS_ALIGNED (Packet->Asb, This->Mode->IoAlign)) {
return EFI_INVALID_PARAMETER; return EFI_INVALID_PARAMETER;
} }
@ -2039,15 +2039,15 @@ ExtScsiPassThruPassThru (
return EFI_INVALID_PARAMETER; return EFI_INVALID_PARAMETER;
} }
if ((This->Mode->IoAlign > 1) && !IS_ALIGNED (Packet->InDataBuffer, This->Mode->IoAlign)) { if ((This->Mode->IoAlign > 1) && !ADDRESS_IS_ALIGNED (Packet->InDataBuffer, This->Mode->IoAlign)) {
return EFI_INVALID_PARAMETER; return EFI_INVALID_PARAMETER;
} }
if ((This->Mode->IoAlign > 1) && !IS_ALIGNED (Packet->OutDataBuffer, This->Mode->IoAlign)) { if ((This->Mode->IoAlign > 1) && !ADDRESS_IS_ALIGNED (Packet->OutDataBuffer, This->Mode->IoAlign)) {
return EFI_INVALID_PARAMETER; return EFI_INVALID_PARAMETER;
} }
if ((This->Mode->IoAlign > 1) && !IS_ALIGNED (Packet->SenseData, This->Mode->IoAlign)) { if ((This->Mode->IoAlign > 1) && !ADDRESS_IS_ALIGNED (Packet->SenseData, This->Mode->IoAlign)) {
return EFI_INVALID_PARAMETER; return EFI_INVALID_PARAMETER;
} }

View File

@ -148,8 +148,6 @@ struct _ATA_NONBLOCK_TASK {
#define ATA_ATAPI_TIMEOUT EFI_TIMER_PERIOD_SECONDS(3) #define ATA_ATAPI_TIMEOUT EFI_TIMER_PERIOD_SECONDS(3)
#define ATA_SPINUP_TIMEOUT EFI_TIMER_PERIOD_SECONDS(10) #define ATA_SPINUP_TIMEOUT EFI_TIMER_PERIOD_SECONDS(10)
#define IS_ALIGNED(addr, size) (((UINTN) (addr) & (size - 1)) == 0)
#define ATA_PASS_THRU_PRIVATE_DATA_FROM_THIS(a) \ #define ATA_PASS_THRU_PRIVATE_DATA_FROM_THIS(a) \
CR (a, \ CR (a, \
ATA_ATAPI_PASS_THRU_INSTANCE, \ ATA_ATAPI_PASS_THRU_INSTANCE, \

View File

@ -76,7 +76,6 @@
#define ATA_TASK_SIGNATURE SIGNATURE_32 ('A', 'T', 'S', 'K') #define ATA_TASK_SIGNATURE SIGNATURE_32 ('A', 'T', 'S', 'K')
#define ATA_DEVICE_SIGNATURE SIGNATURE_32 ('A', 'B', 'I', 'D') #define ATA_DEVICE_SIGNATURE SIGNATURE_32 ('A', 'B', 'I', 'D')
#define ATA_SUB_TASK_SIGNATURE SIGNATURE_32 ('A', 'S', 'T', 'S') #define ATA_SUB_TASK_SIGNATURE SIGNATURE_32 ('A', 'S', 'T', 'S')
#define IS_ALIGNED(addr, size) (((UINTN) (addr) & (size - 1)) == 0)
// //
// ATA bus data structure for ATA controller // ATA bus data structure for ATA controller

View File

@ -1040,7 +1040,7 @@ TrustTransferAtaDevice (
// Check the alignment of the incoming buffer prior to invoking underlying ATA PassThru // Check the alignment of the incoming buffer prior to invoking underlying ATA PassThru
// //
AtaPassThru = AtaDevice->AtaBusDriverData->AtaPassThru; AtaPassThru = AtaDevice->AtaBusDriverData->AtaPassThru;
if ((AtaPassThru->Mode->IoAlign > 1) && !IS_ALIGNED (Buffer, AtaPassThru->Mode->IoAlign)) { if ((AtaPassThru->Mode->IoAlign > 1) && !ADDRESS_IS_ALIGNED (Buffer, AtaPassThru->Mode->IoAlign)) {
NewBuffer = AllocateAlignedBuffer (AtaDevice, TransferLength); NewBuffer = AllocateAlignedBuffer (AtaDevice, TransferLength);
if (NewBuffer == NULL) { if (NewBuffer == NULL) {
return EFI_OUT_OF_RESOURCES; return EFI_OUT_OF_RESOURCES;

View File

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

View File

@ -2029,7 +2029,7 @@ ScsiDiskReceiveData (
goto Done; goto Done;
} }
if ((ScsiDiskDevice->ScsiIo->IoAlign > 1) && !IS_ALIGNED (PayloadBuffer, ScsiDiskDevice->ScsiIo->IoAlign)) { if ((ScsiDiskDevice->ScsiIo->IoAlign > 1) && !ADDRESS_IS_ALIGNED (PayloadBuffer, ScsiDiskDevice->ScsiIo->IoAlign)) {
AlignedBuffer = AllocateAlignedBuffer (ScsiDiskDevice, PayloadBufferSize); AlignedBuffer = AllocateAlignedBuffer (ScsiDiskDevice, PayloadBufferSize);
if (AlignedBuffer == NULL) { if (AlignedBuffer == NULL) {
Status = EFI_OUT_OF_RESOURCES; Status = EFI_OUT_OF_RESOURCES;
@ -2249,7 +2249,7 @@ ScsiDiskSendData (
goto Done; goto Done;
} }
if ((ScsiDiskDevice->ScsiIo->IoAlign > 1) && !IS_ALIGNED (PayloadBuffer, ScsiDiskDevice->ScsiIo->IoAlign)) { if ((ScsiDiskDevice->ScsiIo->IoAlign > 1) && !ADDRESS_IS_ALIGNED (PayloadBuffer, ScsiDiskDevice->ScsiIo->IoAlign)) {
AlignedBuffer = AllocateAlignedBuffer (ScsiDiskDevice, PayloadBufferSize); AlignedBuffer = AllocateAlignedBuffer (ScsiDiskDevice, PayloadBufferSize);
if (AlignedBuffer == NULL) { if (AlignedBuffer == NULL) {
Status = EFI_OUT_OF_RESOURCES; Status = EFI_OUT_OF_RESOURCES;

View File

@ -38,8 +38,6 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#define IS_DEVICE_FIXED(a) (a)->FixedDevice ? 1 : 0 #define IS_DEVICE_FIXED(a) (a)->FixedDevice ? 1 : 0
#define IS_ALIGNED(addr, size) (((UINTN) (addr) & (size - 1)) == 0)
#define UFS_WLUN_RPMB 0xC4 #define UFS_WLUN_RPMB 0xC4
typedef struct { typedef struct {

View File

@ -133,8 +133,6 @@ typedef struct _UFS_PEIM_HC_PRIVATE_DATA {
#define ROUNDUP8(x) (((x) % 8 == 0) ? (x) : ((x) / 8 + 1) * 8) #define ROUNDUP8(x) (((x) % 8 == 0) ? (x) : ((x) / 8 + 1) * 8)
#define IS_ALIGNED(addr, size) (((UINTN) (addr) & (size - 1)) == 0)
#define GET_UFS_PEIM_HC_PRIVATE_DATA_FROM_THIS(a) CR (a, UFS_PEIM_HC_PRIVATE_DATA, BlkIoPpi, UFS_PEIM_HC_SIG) #define GET_UFS_PEIM_HC_PRIVATE_DATA_FROM_THIS(a) CR (a, UFS_PEIM_HC_PRIVATE_DATA, BlkIoPpi, UFS_PEIM_HC_SIG)
#define GET_UFS_PEIM_HC_PRIVATE_DATA_FROM_THIS2(a) CR (a, UFS_PEIM_HC_PRIVATE_DATA, BlkIo2Ppi, UFS_PEIM_HC_SIG) #define GET_UFS_PEIM_HC_PRIVATE_DATA_FROM_THIS2(a) CR (a, UFS_PEIM_HC_PRIVATE_DATA, BlkIo2Ppi, UFS_PEIM_HC_SIG)
#define GET_UFS_PEIM_HC_PRIVATE_DATA_FROM_THIS_NOTIFY(a) CR (a, UFS_PEIM_HC_PRIVATE_DATA, EndOfPeiNotifyList, UFS_PEIM_HC_SIG) #define GET_UFS_PEIM_HC_PRIVATE_DATA_FROM_THIS_NOTIFY(a) CR (a, UFS_PEIM_HC_PRIVATE_DATA, EndOfPeiNotifyList, UFS_PEIM_HC_SIG)

View File

@ -171,15 +171,15 @@ UfsPassThruPassThru (
return EFI_INVALID_PARAMETER; return EFI_INVALID_PARAMETER;
} }
if ((This->Mode->IoAlign > 1) && !IS_ALIGNED (Packet->InDataBuffer, This->Mode->IoAlign)) { if ((This->Mode->IoAlign > 1) && !ADDRESS_IS_ALIGNED (Packet->InDataBuffer, This->Mode->IoAlign)) {
return EFI_INVALID_PARAMETER; return EFI_INVALID_PARAMETER;
} }
if ((This->Mode->IoAlign > 1) && !IS_ALIGNED (Packet->OutDataBuffer, This->Mode->IoAlign)) { if ((This->Mode->IoAlign > 1) && !ADDRESS_IS_ALIGNED (Packet->OutDataBuffer, This->Mode->IoAlign)) {
return EFI_INVALID_PARAMETER; return EFI_INVALID_PARAMETER;
} }
if ((This->Mode->IoAlign > 1) && !IS_ALIGNED (Packet->SenseData, This->Mode->IoAlign)) { if ((This->Mode->IoAlign > 1) && !ADDRESS_IS_ALIGNED (Packet->SenseData, This->Mode->IoAlign)) {
return EFI_INVALID_PARAMETER; return EFI_INVALID_PARAMETER;
} }

View File

@ -105,8 +105,6 @@ typedef struct {
#define ROUNDUP8(x) (((x) % 8 == 0) ? (x) : ((x) / 8 + 1) * 8) #define ROUNDUP8(x) (((x) % 8 == 0) ? (x) : ((x) / 8 + 1) * 8)
#define IS_ALIGNED(addr, size) (((UINTN) (addr) & (size - 1)) == 0)
#define UFS_PASS_THRU_PRIVATE_DATA_FROM_THIS(a) \ #define UFS_PASS_THRU_PRIVATE_DATA_FROM_THIS(a) \
CR (a, \ CR (a, \
UFS_PASS_THRU_PRIVATE_DATA, \ UFS_PASS_THRU_PRIVATE_DATA, \

View File

@ -73,9 +73,8 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#include <Library/ExtractGuidedSectionLib.h> #include <Library/ExtractGuidedSectionLib.h>
#include <Library/CacheMaintenanceLib.h> #include <Library/CacheMaintenanceLib.h>
#include <Library/BaseMemoryLib.h> #include <Library/BaseMemoryLib.h>
#include <Library/PeCoffLib.h> #include <Library/UefiImageLib.h>
#include <Library/PeCoffGetEntryPointLib.h> #include <Library/UefiImageExtraActionLib.h>
#include <Library/PeCoffExtraActionLib.h>
#include <Library/PcdLib.h> #include <Library/PcdLib.h>
#include <Library/MemoryAllocationLib.h> #include <Library/MemoryAllocationLib.h>
#include <Library/DevicePathLib.h> #include <Library/DevicePathLib.h>
@ -219,35 +218,15 @@ typedef struct {
EFI_RUNTIME_IMAGE_ENTRY *RuntimeData; EFI_RUNTIME_IMAGE_ENTRY *RuntimeData;
/// Pointer to Loaded Image Device Path Protocol /// Pointer to Loaded Image Device Path Protocol
EFI_DEVICE_PATH_PROTOCOL *LoadedImageDevicePath; EFI_DEVICE_PATH_PROTOCOL *LoadedImageDevicePath;
/// PeCoffLoader ImageContext
PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;
/// Status returned by LoadImage() service. /// Status returned by LoadImage() service.
EFI_STATUS LoadImageStatus; EFI_STATUS LoadImageStatus;
VOID *HiiData;
} LOADED_IMAGE_PRIVATE_DATA; } LOADED_IMAGE_PRIVATE_DATA;
#define LOADED_IMAGE_PRIVATE_DATA_FROM_THIS(a) \ #define LOADED_IMAGE_PRIVATE_DATA_FROM_THIS(a) \
CR(a, LOADED_IMAGE_PRIVATE_DATA, Info, LOADED_IMAGE_PRIVATE_DATA_SIGNATURE) CR(a, LOADED_IMAGE_PRIVATE_DATA, Info, LOADED_IMAGE_PRIVATE_DATA_SIGNATURE)
#define IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNATURE SIGNATURE_32 ('I','P','R','C')
typedef struct {
UINT32 Signature;
LIST_ENTRY Link;
EFI_PHYSICAL_ADDRESS CodeSegmentBase;
UINT64 CodeSegmentSize;
} IMAGE_PROPERTIES_RECORD_CODE_SECTION;
#define IMAGE_PROPERTIES_RECORD_SIGNATURE SIGNATURE_32 ('I','P','R','D')
typedef struct {
UINT32 Signature;
LIST_ENTRY Link;
EFI_PHYSICAL_ADDRESS ImageBase;
UINT64 ImageSize;
UINTN CodeSegmentCount;
LIST_ENTRY CodeSegmentList;
} IMAGE_PROPERTIES_RECORD;
// //
// DXE Core Global Variables // DXE Core Global Variables
// //
@ -401,7 +380,8 @@ CoreInitializeEventServices (
**/ **/
EFI_STATUS EFI_STATUS
CoreInitializeImageServices ( CoreInitializeImageServices (
IN VOID *HobStart IN VOID *HobStart,
OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext
); );
/** /**
@ -2396,7 +2376,8 @@ VOID
CoreNewDebugImageInfoEntry ( CoreNewDebugImageInfoEntry (
IN UINT32 ImageInfoType, IN UINT32 ImageInfoType,
IN EFI_LOADED_IMAGE_PROTOCOL *LoadedImage, IN EFI_LOADED_IMAGE_PROTOCOL *LoadedImage,
IN EFI_HANDLE ImageHandle IN EFI_HANDLE ImageHandle,
IN UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext
); );
/** /**
@ -2585,7 +2566,8 @@ VerifyFvHeaderChecksum (
**/ **/
VOID VOID
MemoryProfileInit ( MemoryProfileInit (
IN VOID *HobStart IN VOID *HobStart,
IN UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext
); );
/** /**
@ -2611,8 +2593,9 @@ MemoryProfileInstallProtocol (
**/ **/
EFI_STATUS EFI_STATUS
RegisterMemoryProfileImage ( RegisterMemoryProfileImage (
IN LOADED_IMAGE_PRIVATE_DATA *DriverEntry, IN EFI_DEVICE_PATH_PROTOCOL *FilePath,
IN EFI_FV_FILETYPE FileType IN EFI_FV_FILETYPE FileType,
IN UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext
); );
/** /**
@ -2628,7 +2611,8 @@ RegisterMemoryProfileImage (
**/ **/
EFI_STATUS EFI_STATUS
UnregisterMemoryProfileImage ( UnregisterMemoryProfileImage (
IN LOADED_IMAGE_PRIVATE_DATA *DriverEntry EFI_DEVICE_PATH_PROTOCOL *FilePath,
IN EFI_PHYSICAL_ADDRESS ImageAddress
); );
/** /**
@ -2715,7 +2699,8 @@ InstallMemoryAttributesTableOnMemoryAllocation (
**/ **/
VOID VOID
InsertImageRecord ( InsertImageRecord (
IN EFI_RUNTIME_IMAGE_ENTRY *RuntimeImage IN LOADED_IMAGE_PRIVATE_DATA *Image,
IN UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext
); );
/** /**
@ -2736,8 +2721,8 @@ RemoveImageRecord (
**/ **/
VOID VOID
ProtectUefiImage ( ProtectUefiImage (
IN EFI_LOADED_IMAGE_PROTOCOL *LoadedImage, IN LOADED_IMAGE_PRIVATE_DATA *Image,
IN EFI_DEVICE_PATH_PROTOCOL *LoadedImageDevicePath UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext
); );
/** /**

View File

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

View File

@ -234,15 +234,14 @@ DxeMain (
IN VOID *HobStart IN VOID *HobStart
) )
{ {
EFI_STATUS Status; EFI_STATUS Status;
EFI_PHYSICAL_ADDRESS MemoryBaseAddress; EFI_PHYSICAL_ADDRESS MemoryBaseAddress;
UINT64 MemoryLength; UINT64 MemoryLength;
PE_COFF_LOADER_IMAGE_CONTEXT ImageContext; UEFI_IMAGE_LOADER_IMAGE_CONTEXT ImageContext;
UINTN Index; UINTN Index;
EFI_HOB_GUID_TYPE *GuidHob; EFI_HOB_GUID_TYPE *GuidHob;
EFI_VECTOR_HANDOFF_INFO *VectorInfoList; EFI_VECTOR_HANDOFF_INFO *VectorInfoList;
EFI_VECTOR_HANDOFF_INFO *VectorInfo; EFI_VECTOR_HANDOFF_INFO *VectorInfo;
VOID *EntryPoint;
// //
// Setup the default exception handlers // Setup the default exception handlers
@ -274,8 +273,6 @@ DxeMain (
// //
CoreInitializeMemoryServices (&HobStart, &MemoryBaseAddress, &MemoryLength); CoreInitializeMemoryServices (&HobStart, &MemoryBaseAddress, &MemoryLength);
MemoryProfileInit (HobStart);
// //
// Allocate the EFI System Table and EFI Runtime Service Table from EfiRuntimeServicesData // Allocate the EFI System Table and EFI Runtime Service Table from EfiRuntimeServicesData
// Use the templates to initialize the contents of the EFI System Table and EFI Runtime Services Table // Use the templates to initialize the contents of the EFI System Table and EFI Runtime Services Table
@ -291,9 +288,11 @@ DxeMain (
// //
// Start the Image Services. // Start the Image Services.
// //
Status = CoreInitializeImageServices (HobStart); Status = CoreInitializeImageServices (HobStart, &ImageContext);
ASSERT_EFI_ERROR (Status); ASSERT_EFI_ERROR (Status);
MemoryProfileInit (HobStart, &ImageContext);
// //
// Initialize the Global Coherency Domain Services // Initialize the Global Coherency Domain Services
// //
@ -322,19 +321,9 @@ DxeMain (
// //
// Report DXE Core image information to the PE/COFF Extra Action Library // 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)); UefiImageLoaderRelocateImageExtraAction (&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);
// //
// Install the DXE Services Table into the EFI System Tables's Configuration Table // Install the DXE Services Table into the EFI System Tables's Configuration Table
@ -381,7 +370,8 @@ DxeMain (
CoreNewDebugImageInfoEntry ( CoreNewDebugImageInfoEntry (
EFI_DEBUG_IMAGE_INFO_TYPE_NORMAL, EFI_DEBUG_IMAGE_INFO_TYPE_NORMAL,
gDxeCoreLoadedImage, gDxeCoreLoadedImage,
gDxeCoreImageHandle gDxeCoreImageHandle,
&ImageContext
); );
DEBUG ((DEBUG_INFO | DEBUG_LOAD, "HOBLIST address in DXE = 0x%p\n", HobStart)); 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

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

View File

@ -8,6 +8,10 @@
#include "DxeMain.h" #include "DxeMain.h"
#include "Imem.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) #define IS_UEFI_MEMORY_PROFILE_ENABLED ((PcdGet8 (PcdMemoryProfilePropertyMask) & BIT0) != 0)
@ -104,8 +108,7 @@ EFIAPI
ProfileProtocolRegisterImage ( ProfileProtocolRegisterImage (
IN EDKII_MEMORY_PROFILE_PROTOCOL *This, IN EDKII_MEMORY_PROFILE_PROTOCOL *This,
IN EFI_DEVICE_PATH_PROTOCOL *FilePath, IN EFI_DEVICE_PATH_PROTOCOL *FilePath,
IN PHYSICAL_ADDRESS ImageBase, IN UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext,
IN UINT64 ImageSize,
IN EFI_FV_FILETYPE FileType IN EFI_FV_FILETYPE FileType
); );
@ -247,110 +250,6 @@ GetMemoryProfileContext (
return mMemoryProfileContextPtr; 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. Build driver info.
@ -367,32 +266,27 @@ InternalPeCoffGetEntryPoint (
**/ **/
MEMORY_PROFILE_DRIVER_INFO_DATA * MEMORY_PROFILE_DRIVER_INFO_DATA *
BuildDriverInfo ( BuildDriverInfo (
IN MEMORY_PROFILE_CONTEXT_DATA *ContextData, IN MEMORY_PROFILE_CONTEXT_DATA *ContextData,
IN EFI_GUID *FileName, IN EFI_GUID *FileName,
IN PHYSICAL_ADDRESS ImageBase, IN UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext,
IN UINT64 ImageSize, IN EFI_FV_FILETYPE FileType
IN PHYSICAL_ADDRESS EntryPoint,
IN UINT16 ImageSubsystem,
IN EFI_FV_FILETYPE FileType
) )
{ {
RETURN_STATUS PdbStatus;
EFI_STATUS Status; EFI_STATUS Status;
MEMORY_PROFILE_DRIVER_INFO *DriverInfo; MEMORY_PROFILE_DRIVER_INFO *DriverInfo;
MEMORY_PROFILE_DRIVER_INFO_DATA *DriverInfoData; MEMORY_PROFILE_DRIVER_INFO_DATA *DriverInfoData;
VOID *EntryPointInImage; CONST CHAR8 *PdbString;
CHAR8 *PdbString; UINT32 PdbSize;
UINTN PdbSize;
UINTN PdbOccupiedSize; UINTN PdbOccupiedSize;
PdbSize = 0;
PdbOccupiedSize = 0; PdbOccupiedSize = 0;
PdbString = NULL;
if (ImageBase != 0) { ASSERT (UefiImageLoaderGetImageAddress (ImageContext) != 0);
PdbString = PeCoffLoaderGetPdbPointer ((VOID *)(UINTN)ImageBase);
if (PdbString != NULL) { PdbStatus = UefiImageGetSymbolsPath (ImageContext, &PdbString, &PdbSize);
PdbSize = AsciiStrSize (PdbString); if (!EFI_ERROR (PdbStatus)) {
PdbOccupiedSize = GET_OCCUPIED_SIZE (PdbSize, sizeof (UINT64)); PdbOccupiedSize = GET_OCCUPIED_SIZE (PdbSize, sizeof (UINT64));
}
} }
// //
@ -420,19 +314,10 @@ BuildDriverInfo (
CopyMem (&DriverInfo->FileName, FileName, sizeof (EFI_GUID)); CopyMem (&DriverInfo->FileName, FileName, sizeof (EFI_GUID));
} }
DriverInfo->ImageBase = ImageBase; DriverInfo->ImageBase = UefiImageLoaderGetImageAddress (ImageContext);
DriverInfo->ImageSize = ImageSize; DriverInfo->ImageSize = UefiImageGetImageSize (ImageContext);
DriverInfo->EntryPoint = EntryPoint; DriverInfo->EntryPoint = UefiImageLoaderGetImageEntryPoint (ImageContext);
DriverInfo->ImageSubsystem = ImageSubsystem; DriverInfo->ImageSubsystem = UefiImageGetSubsystem (ImageContext);
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->FileType = FileType; DriverInfo->FileType = FileType;
DriverInfoData->AllocInfoList = (LIST_ENTRY *)(DriverInfoData + 1); DriverInfoData->AllocInfoList = (LIST_ENTRY *)(DriverInfoData + 1);
@ -440,7 +325,7 @@ BuildDriverInfo (
DriverInfo->CurrentUsage = 0; DriverInfo->CurrentUsage = 0;
DriverInfo->PeakUsage = 0; DriverInfo->PeakUsage = 0;
DriverInfo->AllocRecordCount = 0; DriverInfo->AllocRecordCount = 0;
if (PdbSize != 0) { if (!RETURN_ERROR (PdbStatus)) {
DriverInfo->PdbStringOffset = (UINT16)sizeof (MEMORY_PROFILE_DRIVER_INFO); DriverInfo->PdbStringOffset = (UINT16)sizeof (MEMORY_PROFILE_DRIVER_INFO);
DriverInfoData->PdbString = (CHAR8 *)(DriverInfoData->AllocInfoList + 1); DriverInfoData->PdbString = (CHAR8 *)(DriverInfoData->AllocInfoList + 1);
CopyMem (DriverInfoData->PdbString, PdbString, PdbSize); CopyMem (DriverInfoData->PdbString, PdbString, PdbSize);
@ -528,13 +413,13 @@ NeedRecordThisDriver (
**/ **/
BOOLEAN BOOLEAN
RegisterDxeCore ( RegisterDxeCore (
IN VOID *HobStart, IN VOID *HobStart,
IN MEMORY_PROFILE_CONTEXT_DATA *ContextData IN UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext,
IN MEMORY_PROFILE_CONTEXT_DATA *ContextData
) )
{ {
EFI_PEI_HOB_POINTERS DxeCoreHob; EFI_PEI_HOB_POINTERS DxeCoreHob;
MEMORY_PROFILE_DRIVER_INFO_DATA *DriverInfoData; MEMORY_PROFILE_DRIVER_INFO_DATA *DriverInfoData;
PHYSICAL_ADDRESS ImageBase;
UINT8 TempBuffer[sizeof (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH) + sizeof (EFI_DEVICE_PATH_PROTOCOL)]; UINT8 TempBuffer[sizeof (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH) + sizeof (EFI_DEVICE_PATH_PROTOCOL)];
MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *FilePath; MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *FilePath;
@ -565,14 +450,10 @@ RegisterDxeCore (
return FALSE; return FALSE;
} }
ImageBase = DxeCoreHob.MemoryAllocationModule->MemoryAllocationHeader.MemoryBaseAddress;
DriverInfoData = BuildDriverInfo ( DriverInfoData = BuildDriverInfo (
ContextData, ContextData,
&DxeCoreHob.MemoryAllocationModule->ModuleName, &DxeCoreHob.MemoryAllocationModule->ModuleName,
ImageBase, ImageContext,
DxeCoreHob.MemoryAllocationModule->MemoryAllocationHeader.MemoryLength,
DxeCoreHob.MemoryAllocationModule->EntryPoint,
InternalPeCoffGetSubsystem ((VOID *)(UINTN)ImageBase),
EFI_FV_FILETYPE_DXE_CORE EFI_FV_FILETYPE_DXE_CORE
); );
if (DriverInfoData == NULL) { if (DriverInfoData == NULL) {
@ -590,7 +471,8 @@ RegisterDxeCore (
**/ **/
VOID VOID
MemoryProfileInit ( MemoryProfileInit (
IN VOID *HobStart IN VOID *HobStart,
IN UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext
) )
{ {
MEMORY_PROFILE_CONTEXT_DATA *ContextData; MEMORY_PROFILE_CONTEXT_DATA *ContextData;
@ -615,7 +497,7 @@ MemoryProfileInit (
mMemoryProfileDriverPath = AllocateCopyPool (mMemoryProfileDriverPathSize, PcdGetPtr (PcdMemoryProfileDriverPath)); mMemoryProfileDriverPath = AllocateCopyPool (mMemoryProfileDriverPathSize, PcdGetPtr (PcdMemoryProfileDriverPath));
mMemoryProfileContextPtr = &mMemoryProfileContext; mMemoryProfileContextPtr = &mMemoryProfileContext;
RegisterDxeCore (HobStart, &mMemoryProfileContext); RegisterDxeCore (HobStart, ImageContext, &mMemoryProfileContext);
DEBUG ((DEBUG_INFO, "MemoryProfileInit MemoryProfileContext - 0x%x\n", &mMemoryProfileContext)); DEBUG ((DEBUG_INFO, "MemoryProfileInit MemoryProfileContext - 0x%x\n", &mMemoryProfileContext));
} }
@ -692,8 +574,9 @@ GetFileNameFromFilePath (
**/ **/
EFI_STATUS EFI_STATUS
RegisterMemoryProfileImage ( RegisterMemoryProfileImage (
IN LOADED_IMAGE_PRIVATE_DATA *DriverEntry, IN EFI_DEVICE_PATH_PROTOCOL *FilePath,
IN EFI_FV_FILETYPE FileType IN EFI_FV_FILETYPE FileType,
IN UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext
) )
{ {
MEMORY_PROFILE_CONTEXT_DATA *ContextData; MEMORY_PROFILE_CONTEXT_DATA *ContextData;
@ -703,7 +586,7 @@ RegisterMemoryProfileImage (
return EFI_UNSUPPORTED; return EFI_UNSUPPORTED;
} }
if (!NeedRecordThisDriver (DriverEntry->Info.FilePath)) { if (!NeedRecordThisDriver (FilePath)) {
return EFI_UNSUPPORTED; return EFI_UNSUPPORTED;
} }
@ -714,11 +597,8 @@ RegisterMemoryProfileImage (
DriverInfoData = BuildDriverInfo ( DriverInfoData = BuildDriverInfo (
ContextData, ContextData,
GetFileNameFromFilePath (DriverEntry->Info.FilePath), GetFileNameFromFilePath (FilePath),
DriverEntry->ImageContext.ImageAddress, ImageContext,
DriverEntry->ImageContext.ImageSize,
DriverEntry->ImageContext.EntryPoint,
DriverEntry->ImageContext.ImageType,
FileType FileType
); );
if (DriverInfoData == NULL) { if (DriverInfoData == NULL) {
@ -831,21 +711,21 @@ GetMemoryProfileDriverInfoFromAddress (
**/ **/
EFI_STATUS EFI_STATUS
UnregisterMemoryProfileImage ( 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_CONTEXT_DATA *ContextData;
MEMORY_PROFILE_DRIVER_INFO_DATA *DriverInfoData; MEMORY_PROFILE_DRIVER_INFO_DATA *DriverInfoData;
EFI_GUID *FileName; EFI_GUID *FileName;
PHYSICAL_ADDRESS ImageAddress; //VOID *EntryPointInImage;
VOID *EntryPointInImage;
if (!IS_UEFI_MEMORY_PROFILE_ENABLED) { if (!IS_UEFI_MEMORY_PROFILE_ENABLED) {
return EFI_UNSUPPORTED; return EFI_UNSUPPORTED;
} }
if (!NeedRecordThisDriver (DriverEntry->Info.FilePath)) { if (!NeedRecordThisDriver (FilePath)) {
return EFI_UNSUPPORTED; return EFI_UNSUPPORTED;
} }
@ -855,17 +735,7 @@ UnregisterMemoryProfileImage (
} }
DriverInfoData = NULL; DriverInfoData = NULL;
FileName = GetFileNameFromFilePath (DriverEntry->Info.FilePath); FileName = GetFileNameFromFilePath (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;
}
if (FileName != NULL) { if (FileName != NULL) {
DriverInfoData = GetMemoryProfileDriverInfoByFileNameAndAddress (ContextData, FileName, ImageAddress); DriverInfoData = GetMemoryProfileDriverInfoByFileNameAndAddress (ContextData, FileName, ImageAddress);
@ -1629,27 +1499,13 @@ ProfileProtocolGetData (
EFI_STATUS EFI_STATUS
EFIAPI EFIAPI
ProfileProtocolRegisterImage ( ProfileProtocolRegisterImage (
IN EDKII_MEMORY_PROFILE_PROTOCOL *This, IN EDKII_MEMORY_PROFILE_PROTOCOL *This,
IN EFI_DEVICE_PATH_PROTOCOL *FilePath, IN EFI_DEVICE_PATH_PROTOCOL *FilePath,
IN PHYSICAL_ADDRESS ImageBase, IN UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext,
IN UINT64 ImageSize, IN EFI_FV_FILETYPE FileType
IN EFI_FV_FILETYPE FileType
) )
{ {
EFI_STATUS Status; return RegisterMemoryProfileImage (FilePath, FileType, ImageContext);
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);
} }
/** /**
@ -1675,19 +1531,7 @@ ProfileProtocolUnregisterImage (
IN UINT64 ImageSize IN UINT64 ImageSize
) )
{ {
EFI_STATUS Status; return UnregisterMemoryProfileImage (FilePath, ImageBase);
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);
} }
/** /**

View File

@ -160,15 +160,20 @@ CoreUpdateDebugTableCrc32 (
**/ **/
VOID VOID
CoreNewDebugImageInfoEntry ( CoreNewDebugImageInfoEntry (
IN UINT32 ImageInfoType, IN UINT32 ImageInfoType,
IN EFI_LOADED_IMAGE_PROTOCOL *LoadedImage, IN EFI_LOADED_IMAGE_PROTOCOL *LoadedImage,
IN EFI_HANDLE ImageHandle IN EFI_HANDLE ImageHandle,
IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext
) )
{ {
EFI_DEBUG_IMAGE_INFO *Table; EFI_DEBUG_IMAGE_INFO *Table;
EFI_DEBUG_IMAGE_INFO *NewTable; EFI_DEBUG_IMAGE_INFO *NewTable;
UINTN Index; UINTN Index;
UINTN TableSize; 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. // 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 // Copy the old table into the new one
// //
CopyMem (NewTable, Table, TableSize); 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 // Free the old table
// //
@ -212,32 +226,31 @@ CoreNewDebugImageInfoEntry (
// //
// Update the table header // Update the table header
// //
Table = NewTable; 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;
} }
// //
// Allocate data for new entry // Allocate data for new entry
// //
Table[Index].NormalImage = AllocateZeroPool (sizeof (EFI_DEBUG_IMAGE_INFO_NORMAL)); NormalImage = AllocateZeroPool (sizeof (EFI_DEBUG_IMAGE_INFO_NORMAL));
if (Table[Index].NormalImage != NULL) { if (NormalImage != NULL) {
// //
// Update the entry // Update the entry
// //
Table[Index].NormalImage->ImageInfoType = (UINT32)ImageInfoType; NormalImage->ImageInfoType = (UINT32)ImageInfoType;
Table[Index].NormalImage->LoadedImageProtocolInstance = LoadedImage; NormalImage->LoadedImageProtocolInstance = LoadedImage;
Table[Index].NormalImage->ImageHandle = ImageHandle; 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. // 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; mDebugInfoTableHeader.UpdateStatus |= EFI_DEBUG_IMAGE_INFO_TABLE_MODIFIED;
Table[Index].NormalImage = NormalImage;
mDebugInfoTableHeader.TableSize++;
} }
mDebugInfoTableHeader.UpdateStatus &= ~EFI_DEBUG_IMAGE_INFO_UPDATE_IN_PROGRESS; mDebugInfoTableHeader.UpdateStatus &= ~EFI_DEBUG_IMAGE_INFO_UPDATE_IN_PROGRESS;
@ -254,8 +267,9 @@ CoreRemoveDebugImageInfoEntry (
EFI_HANDLE ImageHandle EFI_HANDLE ImageHandle
) )
{ {
EFI_DEBUG_IMAGE_INFO *Table; EFI_DEBUG_IMAGE_INFO *Table;
UINTN Index; UINTN Index;
EFI_DEBUG_IMAGE_INFO_NORMAL *NormalImage;
mDebugInfoTableHeader.UpdateStatus |= EFI_DEBUG_IMAGE_INFO_UPDATE_IN_PROGRESS; 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 // Found a match. Free up the record, then NULL the pointer to indicate the slot
// is free. // is free.
// //
CoreFreePool (Table[Index].NormalImage); NormalImage = Table[Index].NormalImage;
Table[Index].NormalImage = NULL;
// //
// Decrease the number of EFI_DEBUG_IMAGE_INFO elements and set the mDebugInfoTable in modified status. // 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.UpdateStatus |= EFI_DEBUG_IMAGE_INFO_TABLE_MODIFIED;
mDebugInfoTableHeader.TableSize--;
Table[Index].NormalImage = NULL;
if (NormalImage->PdbPath != NULL) {
FreePool (NormalImage->PdbPath);
}
CoreFreePool (NormalImage);
break; break;
} }
} }

View File

@ -21,6 +21,8 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#include "DxeMain.h" #include "DxeMain.h"
#include "HeapGuard.h" #include "HeapGuard.h"
#include "IndustryStandard/PeImage2.h"
#include "ProcessorBind.h"
/** /**
This function for GetMemoryMap() with properties table capability. This function for GetMemoryMap() with properties table capability.
@ -72,7 +74,7 @@ CoreGetMemoryMapWithSeparatedImageSection (
typedef struct { typedef struct {
UINT32 Signature; UINT32 Signature;
UINTN ImageRecordCount; UINTN ImageRecordCount;
UINTN CodeSegmentCountMax; UINTN SectionCountMax;
LIST_ENTRY ImageRecordList; LIST_ENTRY ImageRecordList;
} IMAGE_PROPERTIES_PRIVATE_DATA; } IMAGE_PROPERTIES_PRIVATE_DATA;
@ -194,7 +196,7 @@ InstallMemoryAttributesTable (
case EfiRuntimeServicesCode: case EfiRuntimeServicesCode:
case EfiRuntimeServicesData: case EfiRuntimeServicesData:
CopyMem (MemoryAttributesEntry, MemoryMap, DescriptorSize); 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, "Entry (0x%x)\n", MemoryAttributesEntry));
DEBUG ((DEBUG_VERBOSE, " Type - 0x%x\n", MemoryAttributesEntry->Type)); DEBUG ((DEBUG_VERBOSE, " Type - 0x%x\n", MemoryAttributesEntry->Type));
DEBUG ((DEBUG_VERBOSE, " PhysicalStart - 0x%016lx\n", MemoryAttributesEntry->PhysicalStart)); DEBUG ((DEBUG_VERBOSE, " PhysicalStart - 0x%016lx\n", MemoryAttributesEntry->PhysicalStart));
@ -541,13 +543,13 @@ EnforceMemoryMapAttribute (
@return first image record covered by [buffer, length] @return first image record covered by [buffer, length]
**/ **/
STATIC STATIC
IMAGE_PROPERTIES_RECORD * UEFI_IMAGE_RECORD *
GetImageRecordByAddress ( GetImageRecordByAddress (
IN EFI_PHYSICAL_ADDRESS Buffer, IN EFI_PHYSICAL_ADDRESS Buffer,
IN UINT64 Length IN UINT64 Length
) )
{ {
IMAGE_PROPERTIES_RECORD *ImageRecord; UEFI_IMAGE_RECORD *ImageRecord;
LIST_ENTRY *ImageRecordLink; LIST_ENTRY *ImageRecordLink;
LIST_ENTRY *ImageRecordList; LIST_ENTRY *ImageRecordList;
@ -559,13 +561,13 @@ GetImageRecordByAddress (
{ {
ImageRecord = CR ( ImageRecord = CR (
ImageRecordLink, ImageRecordLink,
IMAGE_PROPERTIES_RECORD, UEFI_IMAGE_RECORD,
Link, Link,
IMAGE_PROPERTIES_RECORD_SIGNATURE UEFI_IMAGE_RECORD_SIGNATURE
); );
if ((Buffer <= ImageRecord->ImageBase) && if ((Buffer <= ImageRecord->StartAddress) &&
(Buffer + Length >= ImageRecord->ImageBase + ImageRecord->ImageSize)) (Buffer + Length >= ImageRecord->EndAddress))
{ {
return ImageRecord; return ImageRecord;
} }
@ -590,88 +592,48 @@ GetImageRecordByAddress (
STATIC STATIC
UINTN UINTN
SetNewRecord ( SetNewRecord (
IN IMAGE_PROPERTIES_RECORD *ImageRecord, IN UEFI_IMAGE_RECORD *ImageRecord,
IN OUT EFI_MEMORY_DESCRIPTOR *NewRecord, IN OUT EFI_MEMORY_DESCRIPTOR *NewRecord,
IN EFI_MEMORY_DESCRIPTOR *OldRecord, IN EFI_MEMORY_DESCRIPTOR *OldRecord,
IN UINTN DescriptorSize IN UINTN DescriptorSize
) )
{ {
EFI_MEMORY_DESCRIPTOR TempRecord; EFI_MEMORY_DESCRIPTOR TempRecord;
IMAGE_PROPERTIES_RECORD_CODE_SECTION *ImageRecordCodeSection; UEFI_IMAGE_RECORD_SEGMENT *ImageRecordSegment;
LIST_ENTRY *ImageRecordCodeSectionLink; UINTN SectionAddress;
LIST_ENTRY *ImageRecordCodeSectionEndLink; UINT32 Index;
LIST_ENTRY *ImageRecordCodeSectionList; UINT32 NewRecordCount;
UINTN NewRecordCount;
UINT64 PhysicalEnd;
UINT64 ImageEnd;
CopyMem (&TempRecord, OldRecord, sizeof (EFI_MEMORY_DESCRIPTOR)); CopyMem (&TempRecord, OldRecord, sizeof (EFI_MEMORY_DESCRIPTOR));
PhysicalEnd = TempRecord.PhysicalStart + EfiPagesToSize (TempRecord.NumberOfPages); //
// Always create a new entry for non-PE image record
//
NewRecordCount = 0; NewRecordCount = 0;
if (ImageRecord->StartAddress > TempRecord.PhysicalStart) {
ImageRecordCodeSectionList = &ImageRecord->CodeSegmentList;
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;
if (TempRecord.PhysicalStart <= ImageRecordCodeSection->CodeSegmentBase) {
//
// DATA
//
NewRecord->Type = TempRecord.Type;
NewRecord->PhysicalStart = TempRecord.PhysicalStart;
NewRecord->VirtualStart = 0;
NewRecord->NumberOfPages = EfiSizeToPages (ImageRecordCodeSection->CodeSegmentBase - NewRecord->PhysicalStart);
NewRecord->Attribute = TempRecord.Attribute | EFI_MEMORY_XP;
if (NewRecord->NumberOfPages != 0) {
NewRecord = NEXT_MEMORY_DESCRIPTOR (NewRecord, DescriptorSize);
NewRecordCount++;
}
//
// CODE
//
NewRecord->Type = TempRecord.Type;
NewRecord->PhysicalStart = ImageRecordCodeSection->CodeSegmentBase;
NewRecord->VirtualStart = 0;
NewRecord->NumberOfPages = EfiSizeToPages (ImageRecordCodeSection->CodeSegmentSize);
NewRecord->Attribute = (TempRecord.Attribute & (~EFI_MEMORY_XP)) | EFI_MEMORY_RO;
if (NewRecord->NumberOfPages != 0) {
NewRecord = NEXT_MEMORY_DESCRIPTOR (NewRecord, DescriptorSize);
NewRecordCount++;
}
TempRecord.PhysicalStart = ImageRecordCodeSection->CodeSegmentBase + EfiPagesToSize (EfiSizeToPages (ImageRecordCodeSection->CodeSegmentSize));
TempRecord.NumberOfPages = EfiSizeToPages (PhysicalEnd - TempRecord.PhysicalStart);
if (TempRecord.NumberOfPages == 0) {
break;
}
}
}
ImageEnd = ImageRecord->ImageBase + ImageRecord->ImageSize;
//
// Final DATA
//
if (TempRecord.PhysicalStart < ImageEnd) {
NewRecord->Type = TempRecord.Type; NewRecord->Type = TempRecord.Type;
NewRecord->PhysicalStart = TempRecord.PhysicalStart; NewRecord->PhysicalStart = TempRecord.PhysicalStart;
NewRecord->VirtualStart = 0; NewRecord->VirtualStart = 0;
NewRecord->NumberOfPages = EfiSizeToPages (ImageEnd - TempRecord.PhysicalStart); NewRecord->NumberOfPages = EfiSizeToPages (ImageRecord->StartAddress - TempRecord.PhysicalStart);
NewRecord->Attribute = TempRecord.Attribute | EFI_MEMORY_XP; NewRecord->Attribute = TempRecord.Attribute;
NewRecordCount++; NewRecord = NEXT_MEMORY_DESCRIPTOR (NewRecord, DescriptorSize);
++NewRecordCount;
} }
return NewRecordCount; SectionAddress = ImageRecord->StartAddress;
for (Index = 0; Index < ImageRecord->NumSegments; ++Index) {
ImageRecordSegment = &ImageRecord->Segments[Index];
NewRecord->Type = TempRecord.Type;
NewRecord->PhysicalStart = SectionAddress;
NewRecord->VirtualStart = 0;
NewRecord->NumberOfPages = EfiSizeToPages (ImageRecordSegment->Size);
NewRecord->Attribute = (TempRecord.Attribute & ~(UINT64) EFI_MEMORY_ACCESS_MASK) | ImageRecordSegment->Attributes;
NewRecord = NEXT_MEMORY_DESCRIPTOR (NewRecord, DescriptorSize);
SectionAddress += ImageRecordSegment->Size;
}
return NewRecordCount + ImageRecord->NumSegments;
} }
/** /**
@ -689,29 +651,32 @@ GetMaxSplitRecordCount (
IN EFI_MEMORY_DESCRIPTOR *OldRecord IN EFI_MEMORY_DESCRIPTOR *OldRecord
) )
{ {
IMAGE_PROPERTIES_RECORD *ImageRecord; UEFI_IMAGE_RECORD *ImageRecord;
UINTN SplitRecordCount; UINTN SplitRecordCount;
UINT64 PhysicalStart; UINT64 PhysicalStart;
UINT64 PhysicalEnd; UINT64 PhysicalEnd;
//
// Per region, there may be one prefix, but the return value is the amount of
// new records in addition to the original one.
//
SplitRecordCount = 0; SplitRecordCount = 0;
PhysicalStart = OldRecord->PhysicalStart; PhysicalStart = OldRecord->PhysicalStart;
PhysicalEnd = OldRecord->PhysicalStart + EfiPagesToSize (OldRecord->NumberOfPages); PhysicalEnd = OldRecord->PhysicalStart + EfiPagesToSize (OldRecord->NumberOfPages);
do { do {
// FIXME: Inline iteration to not always start anew?
ImageRecord = GetImageRecordByAddress (PhysicalStart, PhysicalEnd - PhysicalStart); ImageRecord = GetImageRecordByAddress (PhysicalStart, PhysicalEnd - PhysicalStart);
if (ImageRecord == NULL) { if (ImageRecord == NULL) {
break; break;
} }
SplitRecordCount += (2 * ImageRecord->CodeSegmentCount + 1); //
PhysicalStart = ImageRecord->ImageBase + ImageRecord->ImageSize; // Per image, they may be one trailer.
//
SplitRecordCount += ImageRecord->NumSegments + 1;
PhysicalStart = ImageRecord->EndAddress;
} while ((ImageRecord != NULL) && (PhysicalStart < PhysicalEnd)); } while ((ImageRecord != NULL) && (PhysicalStart < PhysicalEnd));
if (SplitRecordCount != 0) {
SplitRecordCount--;
}
return SplitRecordCount; return SplitRecordCount;
} }
@ -740,13 +705,12 @@ SplitRecord (
) )
{ {
EFI_MEMORY_DESCRIPTOR TempRecord; EFI_MEMORY_DESCRIPTOR TempRecord;
IMAGE_PROPERTIES_RECORD *ImageRecord; UEFI_IMAGE_RECORD *ImageRecord;
IMAGE_PROPERTIES_RECORD *NewImageRecord; UEFI_IMAGE_RECORD *NewImageRecord;
UINT64 PhysicalStart; UINT64 PhysicalStart;
UINT64 PhysicalEnd; UINT64 PhysicalEnd;
UINTN NewRecordCount; UINTN NewRecordCount;
UINTN TotalNewRecordCount; UINTN TotalNewRecordCount;
BOOLEAN IsLastRecordData;
if (MaxSplitRecordCount == 0) { if (MaxSplitRecordCount == 0) {
CopyMem (NewRecord, OldRecord, DescriptorSize); CopyMem (NewRecord, OldRecord, DescriptorSize);
@ -771,31 +735,14 @@ SplitRecord (
// //
if ((PhysicalEnd > PhysicalStart) && (ImageRecord != NULL)) { if ((PhysicalEnd > PhysicalStart) && (ImageRecord != NULL)) {
// //
// If this is still address in this record, need record. // Always create a new entry for non-PE image record
// //
NewRecord = PREVIOUS_MEMORY_DESCRIPTOR (NewRecord, DescriptorSize); NewRecord->Type = TempRecord.Type;
IsLastRecordData = FALSE; NewRecord->PhysicalStart = TempRecord.PhysicalStart;
if ((NewRecord->Attribute & EFI_MEMORY_XP) != 0) { NewRecord->VirtualStart = 0;
IsLastRecordData = TRUE; NewRecord->NumberOfPages = TempRecord.NumberOfPages;
} NewRecord->Attribute = TempRecord.Attribute;
TotalNewRecordCount++;
if (IsLastRecordData) {
//
// Last record is DATA, just merge it.
//
NewRecord->NumberOfPages = EfiSizeToPages (PhysicalEnd - NewRecord->PhysicalStart);
} else {
//
// Last record is CODE, create a new DATA entry.
//
NewRecord = NEXT_MEMORY_DESCRIPTOR (NewRecord, DescriptorSize);
NewRecord->Type = TempRecord.Type;
NewRecord->PhysicalStart = TempRecord.PhysicalStart;
NewRecord->VirtualStart = 0;
NewRecord->NumberOfPages = TempRecord.NumberOfPages;
NewRecord->Attribute = TempRecord.Attribute | EFI_MEMORY_XP;
TotalNewRecordCount++;
}
} }
break; break;
@ -813,7 +760,7 @@ SplitRecord (
// //
// Update PhysicalStart, in order to exclude the image buffer already splitted. // Update PhysicalStart, in order to exclude the image buffer already splitted.
// //
PhysicalStart = ImageRecord->ImageBase + ImageRecord->ImageSize; PhysicalStart = ImageRecord->EndAddress;
TempRecord.PhysicalStart = PhysicalStart; TempRecord.PhysicalStart = PhysicalStart;
TempRecord.NumberOfPages = EfiSizeToPages (PhysicalEnd - PhysicalStart); TempRecord.NumberOfPages = EfiSizeToPages (PhysicalEnd - PhysicalStart);
} while ((ImageRecord != NULL) && (PhysicalStart < PhysicalEnd)); } while ((ImageRecord != NULL) && (PhysicalStart < PhysicalEnd));
@ -887,7 +834,10 @@ SplitTable (
UINTN TotalSplitRecordCount; UINTN TotalSplitRecordCount;
UINTN AdditionalRecordCount; UINTN AdditionalRecordCount;
AdditionalRecordCount = (2 * mImagePropertiesPrivateData.CodeSegmentCountMax + 1) * mImagePropertiesPrivateData.ImageRecordCount; //
// Per image, they may be one trailer. There may be prefixed data.
//
AdditionalRecordCount = (mImagePropertiesPrivateData.SectionCountMax + 1) * mImagePropertiesPrivateData.ImageRecordCount;
TotalSplitRecordCount = 0; TotalSplitRecordCount = 0;
// //
@ -912,11 +862,13 @@ SplitTable (
); );
// //
// Adjust IndexNew according to real split. // Adjust IndexNew according to real split.
// RealSplitRecordCount is the number of new records, so we must add one to
// copy the total number of records.
// //
CopyMem ( CopyMem (
((UINT8 *)MemoryMap + (IndexNew + MaxSplitRecordCount - RealSplitRecordCount) * DescriptorSize), ((UINT8 *)MemoryMap + (IndexNew + MaxSplitRecordCount - RealSplitRecordCount) * DescriptorSize),
((UINT8 *)MemoryMap + IndexNew * DescriptorSize), ((UINT8 *)MemoryMap + IndexNew * DescriptorSize),
RealSplitRecordCount * DescriptorSize (RealSplitRecordCount + 1) * DescriptorSize
); );
IndexNew = IndexNew + MaxSplitRecordCount - RealSplitRecordCount; IndexNew = IndexNew + MaxSplitRecordCount - RealSplitRecordCount;
TotalSplitRecordCount += RealSplitRecordCount; TotalSplitRecordCount += RealSplitRecordCount;
@ -1011,7 +963,11 @@ CoreGetMemoryMapWithSeparatedImageSection (
CoreAcquiremMemoryAttributesTableLock (); CoreAcquiremMemoryAttributesTableLock ();
AdditionalRecordCount = (2 * mImagePropertiesPrivateData.CodeSegmentCountMax + 1) * 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; OldMemoryMapSize = *MemoryMapSize;
Status = CoreGetMemoryMap (MemoryMapSize, MemoryMap, MapKey, DescriptorSize, DescriptorVersion); Status = CoreGetMemoryMap (MemoryMapSize, MemoryMap, MapKey, DescriptorSize, DescriptorVersion);
@ -1060,215 +1016,46 @@ SetMemoryAttributesTableSectionAlignment (
} }
} }
/**
Swap two code sections in image record.
@param FirstImageRecordCodeSection first code section in image record
@param SecondImageRecordCodeSection second code section in image record
**/
STATIC
VOID
SwapImageRecordCodeSection (
IN IMAGE_PROPERTIES_RECORD_CODE_SECTION *FirstImageRecordCodeSection,
IN IMAGE_PROPERTIES_RECORD_CODE_SECTION *SecondImageRecordCodeSection
)
{
IMAGE_PROPERTIES_RECORD_CODE_SECTION TempImageRecordCodeSection;
TempImageRecordCodeSection.CodeSegmentBase = FirstImageRecordCodeSection->CodeSegmentBase;
TempImageRecordCodeSection.CodeSegmentSize = FirstImageRecordCodeSection->CodeSegmentSize;
FirstImageRecordCodeSection->CodeSegmentBase = SecondImageRecordCodeSection->CodeSegmentBase;
FirstImageRecordCodeSection->CodeSegmentSize = SecondImageRecordCodeSection->CodeSegmentSize;
SecondImageRecordCodeSection->CodeSegmentBase = TempImageRecordCodeSection.CodeSegmentBase;
SecondImageRecordCodeSection->CodeSegmentSize = TempImageRecordCodeSection.CodeSegmentSize;
}
/**
Sort code section in image record, based upon CodeSegmentBase from low to high.
@param ImageRecord image record to be sorted
**/
VOID
SortImageRecordCodeSection (
IN IMAGE_PROPERTIES_RECORD *ImageRecord
)
{
IMAGE_PROPERTIES_RECORD_CODE_SECTION *ImageRecordCodeSection;
IMAGE_PROPERTIES_RECORD_CODE_SECTION *NextImageRecordCodeSection;
LIST_ENTRY *ImageRecordCodeSectionLink;
LIST_ENTRY *NextImageRecordCodeSectionLink;
LIST_ENTRY *ImageRecordCodeSectionEndLink;
LIST_ENTRY *ImageRecordCodeSectionList;
ImageRecordCodeSectionList = &ImageRecord->CodeSegmentList;
ImageRecordCodeSectionLink = ImageRecordCodeSectionList->ForwardLink;
NextImageRecordCodeSectionLink = ImageRecordCodeSectionLink->ForwardLink;
ImageRecordCodeSectionEndLink = ImageRecordCodeSectionList;
while (ImageRecordCodeSectionLink != ImageRecordCodeSectionEndLink) {
ImageRecordCodeSection = CR (
ImageRecordCodeSectionLink,
IMAGE_PROPERTIES_RECORD_CODE_SECTION,
Link,
IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNATURE
);
while (NextImageRecordCodeSectionLink != ImageRecordCodeSectionEndLink) {
NextImageRecordCodeSection = CR (
NextImageRecordCodeSectionLink,
IMAGE_PROPERTIES_RECORD_CODE_SECTION,
Link,
IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNATURE
);
if (ImageRecordCodeSection->CodeSegmentBase > NextImageRecordCodeSection->CodeSegmentBase) {
SwapImageRecordCodeSection (ImageRecordCodeSection, NextImageRecordCodeSection);
}
NextImageRecordCodeSectionLink = NextImageRecordCodeSectionLink->ForwardLink;
}
ImageRecordCodeSectionLink = ImageRecordCodeSectionLink->ForwardLink;
NextImageRecordCodeSectionLink = ImageRecordCodeSectionLink->ForwardLink;
}
}
/**
Check if code section in image record is valid.
@param ImageRecord image record to be checked
@retval TRUE image record is valid
@retval FALSE image record is invalid
**/
BOOLEAN
IsImageRecordCodeSectionValid (
IN IMAGE_PROPERTIES_RECORD *ImageRecord
)
{
IMAGE_PROPERTIES_RECORD_CODE_SECTION *ImageRecordCodeSection;
IMAGE_PROPERTIES_RECORD_CODE_SECTION *LastImageRecordCodeSection;
LIST_ENTRY *ImageRecordCodeSectionLink;
LIST_ENTRY *ImageRecordCodeSectionEndLink;
LIST_ENTRY *ImageRecordCodeSectionList;
DEBUG ((DEBUG_VERBOSE, "ImageCode SegmentCount - 0x%x\n", ImageRecord->CodeSegmentCount));
ImageRecordCodeSectionList = &ImageRecord->CodeSegmentList;
ImageRecordCodeSectionLink = ImageRecordCodeSectionList->ForwardLink;
ImageRecordCodeSectionEndLink = ImageRecordCodeSectionList;
LastImageRecordCodeSection = NULL;
while (ImageRecordCodeSectionLink != ImageRecordCodeSectionEndLink) {
ImageRecordCodeSection = CR (
ImageRecordCodeSectionLink,
IMAGE_PROPERTIES_RECORD_CODE_SECTION,
Link,
IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNATURE
);
if (ImageRecordCodeSection->CodeSegmentSize == 0) {
return FALSE;
}
if (ImageRecordCodeSection->CodeSegmentBase < ImageRecord->ImageBase) {
return FALSE;
}
if (ImageRecordCodeSection->CodeSegmentBase >= MAX_ADDRESS - ImageRecordCodeSection->CodeSegmentSize) {
return FALSE;
}
if ((ImageRecordCodeSection->CodeSegmentBase + ImageRecordCodeSection->CodeSegmentSize) > (ImageRecord->ImageBase + ImageRecord->ImageSize)) {
return FALSE;
}
if (LastImageRecordCodeSection != NULL) {
if ((LastImageRecordCodeSection->CodeSegmentBase + LastImageRecordCodeSection->CodeSegmentSize) > ImageRecordCodeSection->CodeSegmentBase) {
return FALSE;
}
}
LastImageRecordCodeSection = ImageRecordCodeSection;
ImageRecordCodeSectionLink = ImageRecordCodeSectionLink->ForwardLink;
}
return TRUE;
}
/**
Swap two image records.
@param FirstImageRecord first image record.
@param SecondImageRecord second image record.
**/
STATIC
VOID
SwapImageRecord (
IN IMAGE_PROPERTIES_RECORD *FirstImageRecord,
IN IMAGE_PROPERTIES_RECORD *SecondImageRecord
)
{
IMAGE_PROPERTIES_RECORD TempImageRecord;
TempImageRecord.ImageBase = FirstImageRecord->ImageBase;
TempImageRecord.ImageSize = FirstImageRecord->ImageSize;
TempImageRecord.CodeSegmentCount = FirstImageRecord->CodeSegmentCount;
FirstImageRecord->ImageBase = SecondImageRecord->ImageBase;
FirstImageRecord->ImageSize = SecondImageRecord->ImageSize;
FirstImageRecord->CodeSegmentCount = SecondImageRecord->CodeSegmentCount;
SecondImageRecord->ImageBase = TempImageRecord.ImageBase;
SecondImageRecord->ImageSize = TempImageRecord.ImageSize;
SecondImageRecord->CodeSegmentCount = TempImageRecord.CodeSegmentCount;
SwapListEntries (&FirstImageRecord->CodeSegmentList, &SecondImageRecord->CodeSegmentList);
}
/** /**
Sort image record based upon the ImageBase from low to high. Sort image record based upon the ImageBase from low to high.
**/ **/
STATIC STATIC
VOID VOID
SortImageRecord ( InsertSortImageRecord (
VOID IN UEFI_IMAGE_RECORD *NewImageRecord
) )
{ {
IMAGE_PROPERTIES_RECORD *ImageRecord; UEFI_IMAGE_RECORD *ImageRecord;
IMAGE_PROPERTIES_RECORD *NextImageRecord; LIST_ENTRY *PrevImageRecordLink;
LIST_ENTRY *ImageRecordLink; LIST_ENTRY *ImageRecordLink;
LIST_ENTRY *NextImageRecordLink; LIST_ENTRY *ImageRecordList;
LIST_ENTRY *ImageRecordEndLink;
LIST_ENTRY *ImageRecordList;
ImageRecordList = &mImagePropertiesPrivateData.ImageRecordList; ImageRecordList = &mImagePropertiesPrivateData.ImageRecordList;
ImageRecordLink = ImageRecordList->ForwardLink; PrevImageRecordLink = ImageRecordList;
NextImageRecordLink = ImageRecordLink->ForwardLink; for (
ImageRecordEndLink = ImageRecordList; ImageRecordLink = GetFirstNode (ImageRecordList);
while (ImageRecordLink != ImageRecordEndLink) { !IsNull (ImageRecordLink, ImageRecordList);
ImageRecordLink = GetNextNode (ImageRecordList, PrevImageRecordLink)
) {
ImageRecord = CR ( ImageRecord = CR (
ImageRecordLink, ImageRecordLink,
IMAGE_PROPERTIES_RECORD, UEFI_IMAGE_RECORD,
Link, Link,
IMAGE_PROPERTIES_RECORD_SIGNATURE UEFI_IMAGE_RECORD_SIGNATURE
); );
while (NextImageRecordLink != ImageRecordEndLink) { if (NewImageRecord->StartAddress < ImageRecord->StartAddress) {
NextImageRecord = CR ( break;
NextImageRecordLink,
IMAGE_PROPERTIES_RECORD,
Link,
IMAGE_PROPERTIES_RECORD_SIGNATURE
);
if (ImageRecord->ImageBase > NextImageRecord->ImageBase) {
SwapImageRecord (ImageRecord, NextImageRecord);
}
NextImageRecordLink = NextImageRecordLink->ForwardLink;
} }
ImageRecordLink = ImageRecordLink->ForwardLink; PrevImageRecordLink = ImageRecordLink;
NextImageRecordLink = ImageRecordLink->ForwardLink; }
InsertHeadList (PrevImageRecordLink, &NewImageRecord->Link);
mImagePropertiesPrivateData.ImageRecordCount++;
if (mImagePropertiesPrivateData.SectionCountMax < NewImageRecord->NumSegments) {
mImagePropertiesPrivateData.SectionCountMax = NewImageRecord->NumSegments;
} }
} }
@ -1279,20 +1066,18 @@ SortImageRecord (
**/ **/
VOID VOID
InsertImageRecord ( InsertImageRecord (
IN EFI_RUNTIME_IMAGE_ENTRY *RuntimeImage IN LOADED_IMAGE_PRIVATE_DATA *Image,
IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext
) )
{ {
VOID *ImageAddress; RETURN_STATUS PdbStatus;
EFI_IMAGE_DOS_HEADER *DosHdr; EFI_RUNTIME_IMAGE_ENTRY *RuntimeImage;
UINT32 PeCoffHeaderOffset;
UINT32 SectionAlignment; UINT32 SectionAlignment;
EFI_IMAGE_SECTION_HEADER *Section; UEFI_IMAGE_RECORD *ImageRecord;
EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr; CONST CHAR8 *PdbPointer;
UINT8 *Name; UINT32 PdbSize;
UINTN Index;
IMAGE_PROPERTIES_RECORD *ImageRecord; RuntimeImage = Image->RuntimeData;
CHAR8 *PdbPointer;
IMAGE_PROPERTIES_RECORD_CODE_SECTION *ImageRecordCodeSection;
DEBUG ((DEBUG_VERBOSE, "InsertImageRecord - 0x%x\n", RuntimeImage)); DEBUG ((DEBUG_VERBOSE, "InsertImageRecord - 0x%x\n", RuntimeImage));
DEBUG ((DEBUG_VERBOSE, "InsertImageRecord - 0x%016lx - 0x%016lx\n", (EFI_PHYSICAL_ADDRESS)(UINTN)RuntimeImage->ImageBase, RuntimeImage->ImageSize)); DEBUG ((DEBUG_VERBOSE, "InsertImageRecord - 0x%016lx - 0x%016lx\n", (EFI_PHYSICAL_ADDRESS)(UINTN)RuntimeImage->ImageBase, RuntimeImage->ImageSize));
@ -1302,155 +1087,45 @@ InsertImageRecord (
return; return;
} }
ImageRecord = AllocatePool (sizeof (*ImageRecord));
if (ImageRecord == NULL) {
return;
}
ImageRecord->Signature = IMAGE_PROPERTIES_RECORD_SIGNATURE;
DEBUG ((DEBUG_VERBOSE, "ImageRecordCount - 0x%x\n", mImagePropertiesPrivateData.ImageRecordCount)); DEBUG ((DEBUG_VERBOSE, "ImageRecordCount - 0x%x\n", mImagePropertiesPrivateData.ImageRecordCount));
// PdbStatus = UefiImageGetSymbolsPath (ImageContext, &PdbPointer, &PdbSize);
// Step 1: record whole region if (!EFI_ERROR (PdbStatus)) {
//
ImageRecord->ImageBase = (EFI_PHYSICAL_ADDRESS)(UINTN)RuntimeImage->ImageBase;
ImageRecord->ImageSize = RuntimeImage->ImageSize;
ImageAddress = RuntimeImage->ImageBase;
PdbPointer = PeCoffLoaderGetPdbPointer ((VOID *)(UINTN)ImageAddress);
if (PdbPointer != NULL) {
DEBUG ((DEBUG_VERBOSE, " Image - %a\n", PdbPointer)); DEBUG ((DEBUG_VERBOSE, " Image - %a\n", PdbPointer));
} }
//
// Check PE/COFF image
//
DosHdr = (EFI_IMAGE_DOS_HEADER *)(UINTN)ImageAddress;
PeCoffHeaderOffset = 0;
if (DosHdr->e_magic == EFI_IMAGE_DOS_SIGNATURE) {
PeCoffHeaderOffset = DosHdr->e_lfanew;
}
Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)((UINT8 *)(UINTN)ImageAddress + PeCoffHeaderOffset);
if (Hdr.Pe32->Signature != EFI_IMAGE_NT_SIGNATURE) {
DEBUG ((DEBUG_VERBOSE, "Hdr.Pe32->Signature invalid - 0x%x\n", Hdr.Pe32->Signature));
// It might be image in SMM.
goto Finish;
}
// //
// Get SectionAlignment // Get SectionAlignment
// //
if (Hdr.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) { SectionAlignment = UefiImageGetSegmentAlignment (ImageContext);
SectionAlignment = Hdr.Pe32->OptionalHeader.SectionAlignment;
} else {
SectionAlignment = Hdr.Pe32Plus->OptionalHeader.SectionAlignment;
}
SetMemoryAttributesTableSectionAlignment (SectionAlignment); SetMemoryAttributesTableSectionAlignment (SectionAlignment);
if ((SectionAlignment & (RUNTIME_PAGE_ALLOCATION_GRANULARITY - 1)) != 0) { if ((SectionAlignment & (RUNTIME_PAGE_ALLOCATION_GRANULARITY - 1)) != 0) {
DEBUG (( DEBUG ((
DEBUG_WARN, DEBUG_WARN,
"!!!!!!!! InsertImageRecord - Section Alignment(0x%x) is not %dK !!!!!!!!\n", "!!!!!!!! InsertImageRecord - Section Alignment(0x%x) is not %dK !!!!!!!!\n",
SectionAlignment, SectionAlignment, RUNTIME_PAGE_ALLOCATION_GRANULARITY >> 10));
RUNTIME_PAGE_ALLOCATION_GRANULARITY >> 10 if (!EFI_ERROR (PdbStatus)) {
));
PdbPointer = PeCoffLoaderGetPdbPointer ((VOID *)(UINTN)ImageAddress);
if (PdbPointer != NULL) {
DEBUG ((DEBUG_WARN, "!!!!!!!! Image - %a !!!!!!!!\n", PdbPointer)); DEBUG ((DEBUG_WARN, "!!!!!!!! Image - %a !!!!!!!!\n", PdbPointer));
} }
goto Finish; goto Finish;
} }
Section = (EFI_IMAGE_SECTION_HEADER *)( ImageRecord = UefiImageLoaderGetImageRecord (ImageContext);
(UINT8 *)(UINTN)ImageAddress + if (ImageRecord == NULL) {
PeCoffHeaderOffset + return ;
sizeof (UINT32) +
sizeof (EFI_IMAGE_FILE_HEADER) +
Hdr.Pe32->FileHeader.SizeOfOptionalHeader
);
ImageRecord->CodeSegmentCount = 0;
InitializeListHead (&ImageRecord->CodeSegmentList);
for (Index = 0; Index < Hdr.Pe32->FileHeader.NumberOfSections; Index++) {
Name = Section[Index].Name;
DEBUG ((
DEBUG_VERBOSE,
" Section - '%c%c%c%c%c%c%c%c'\n",
Name[0],
Name[1],
Name[2],
Name[3],
Name[4],
Name[5],
Name[6],
Name[7]
));
if ((Section[Index].Characteristics & EFI_IMAGE_SCN_CNT_CODE) != 0) {
DEBUG ((DEBUG_VERBOSE, " VirtualSize - 0x%08x\n", Section[Index].Misc.VirtualSize));
DEBUG ((DEBUG_VERBOSE, " VirtualAddress - 0x%08x\n", Section[Index].VirtualAddress));
DEBUG ((DEBUG_VERBOSE, " SizeOfRawData - 0x%08x\n", Section[Index].SizeOfRawData));
DEBUG ((DEBUG_VERBOSE, " PointerToRawData - 0x%08x\n", Section[Index].PointerToRawData));
DEBUG ((DEBUG_VERBOSE, " PointerToRelocations - 0x%08x\n", Section[Index].PointerToRelocations));
DEBUG ((DEBUG_VERBOSE, " PointerToLinenumbers - 0x%08x\n", Section[Index].PointerToLinenumbers));
DEBUG ((DEBUG_VERBOSE, " NumberOfRelocations - 0x%08x\n", Section[Index].NumberOfRelocations));
DEBUG ((DEBUG_VERBOSE, " NumberOfLinenumbers - 0x%08x\n", Section[Index].NumberOfLinenumbers));
DEBUG ((DEBUG_VERBOSE, " Characteristics - 0x%08x\n", Section[Index].Characteristics));
//
// Step 2: record code section
//
ImageRecordCodeSection = AllocatePool (sizeof (*ImageRecordCodeSection));
if (ImageRecordCodeSection == NULL) {
return;
}
ImageRecordCodeSection->Signature = IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNATURE;
ImageRecordCodeSection->CodeSegmentBase = (UINTN)ImageAddress + Section[Index].VirtualAddress;
ImageRecordCodeSection->CodeSegmentSize = Section[Index].SizeOfRawData;
DEBUG ((DEBUG_VERBOSE, "ImageCode: 0x%016lx - 0x%016lx\n", ImageRecordCodeSection->CodeSegmentBase, ImageRecordCodeSection->CodeSegmentSize));
InsertTailList (&ImageRecord->CodeSegmentList, &ImageRecordCodeSection->Link);
ImageRecord->CodeSegmentCount++;
}
} }
if (ImageRecord->CodeSegmentCount == 0) { UefiImageDebugPrintSegments (ImageContext);
SetMemoryAttributesTableSectionAlignment (1); UefiImageDebugPrintImageRecord (ImageRecord);
DEBUG ((DEBUG_ERROR, "!!!!!!!! InsertImageRecord - CodeSegmentCount is 0 !!!!!!!!\n"));
PdbPointer = PeCoffLoaderGetPdbPointer ((VOID *)(UINTN)ImageAddress);
if (PdbPointer != NULL) {
DEBUG ((DEBUG_ERROR, "!!!!!!!! Image - %a !!!!!!!!\n", PdbPointer));
}
goto Finish;
}
// //
// Final // Section order is guaranteed by the PE specification.
// Section validity (e.g. no overlap) is guaranteed by the PE specification.
// //
SortImageRecordCodeSection (ImageRecord);
//
// Check overlap all section in ImageBase/Size
//
if (!IsImageRecordCodeSectionValid (ImageRecord)) {
DEBUG ((DEBUG_ERROR, "IsImageRecordCodeSectionValid - FAIL\n"));
goto Finish;
}
InsertTailList (&mImagePropertiesPrivateData.ImageRecordList, &ImageRecord->Link); InsertSortImageRecord (ImageRecord);
mImagePropertiesPrivateData.ImageRecordCount++;
if (mImagePropertiesPrivateData.CodeSegmentCountMax < ImageRecord->CodeSegmentCount) {
mImagePropertiesPrivateData.CodeSegmentCountMax = ImageRecord->CodeSegmentCount;
}
SortImageRecord ();
Finish: Finish:
return; return;
@ -1465,13 +1140,12 @@ Finish:
@return image record @return image record
**/ **/
STATIC STATIC
IMAGE_PROPERTIES_RECORD * UEFI_IMAGE_RECORD *
FindImageRecord ( FindImageRecord (
IN EFI_PHYSICAL_ADDRESS ImageBase, IN EFI_PHYSICAL_ADDRESS ImageBase
IN UINT64 ImageSize
) )
{ {
IMAGE_PROPERTIES_RECORD *ImageRecord; UEFI_IMAGE_RECORD *ImageRecord;
LIST_ENTRY *ImageRecordLink; LIST_ENTRY *ImageRecordLink;
LIST_ENTRY *ImageRecordList; LIST_ENTRY *ImageRecordList;
@ -1483,13 +1157,12 @@ FindImageRecord (
{ {
ImageRecord = CR ( ImageRecord = CR (
ImageRecordLink, ImageRecordLink,
IMAGE_PROPERTIES_RECORD, UEFI_IMAGE_RECORD,
Link, Link,
IMAGE_PROPERTIES_RECORD_SIGNATURE UEFI_IMAGE_RECORD_SIGNATURE
); );
if ((ImageBase == ImageRecord->ImageBase) && if (ImageBase == ImageRecord->StartAddress)
(ImageSize == ImageRecord->ImageSize))
{ {
return ImageRecord; return ImageRecord;
} }
@ -1508,9 +1181,7 @@ RemoveImageRecord (
IN EFI_RUNTIME_IMAGE_ENTRY *RuntimeImage IN EFI_RUNTIME_IMAGE_ENTRY *RuntimeImage
) )
{ {
IMAGE_PROPERTIES_RECORD *ImageRecord; UEFI_IMAGE_RECORD *ImageRecord;
LIST_ENTRY *CodeSegmentListHead;
IMAGE_PROPERTIES_RECORD_CODE_SECTION *ImageRecordCodeSection;
DEBUG ((DEBUG_VERBOSE, "RemoveImageRecord - 0x%x\n", RuntimeImage)); 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)); DEBUG ((DEBUG_VERBOSE, "RemoveImageRecord - 0x%016lx - 0x%016lx\n", (EFI_PHYSICAL_ADDRESS)(UINTN)RuntimeImage->ImageBase, RuntimeImage->ImageSize));
@ -1520,24 +1191,12 @@ RemoveImageRecord (
return; return;
} }
ImageRecord = FindImageRecord ((EFI_PHYSICAL_ADDRESS)(UINTN)RuntimeImage->ImageBase, RuntimeImage->ImageSize); ImageRecord = FindImageRecord ((EFI_PHYSICAL_ADDRESS)(UINTN)RuntimeImage->ImageBase);
if (ImageRecord == NULL) { if (ImageRecord == NULL) {
DEBUG ((DEBUG_ERROR, "!!!!!!!! ImageRecord not found !!!!!!!!\n")); DEBUG ((DEBUG_ERROR, "!!!!!!!! ImageRecord not found !!!!!!!!\n"));
return; return;
} }
CodeSegmentListHead = &ImageRecord->CodeSegmentList;
while (!IsListEmpty (CodeSegmentListHead)) {
ImageRecordCodeSection = CR (
CodeSegmentListHead->ForwardLink,
IMAGE_PROPERTIES_RECORD_CODE_SECTION,
Link,
IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNATURE
);
RemoveEntryList (&ImageRecordCodeSection->Link);
FreePool (ImageRecordCodeSection);
}
RemoveEntryList (&ImageRecord->Link); RemoveEntryList (&ImageRecord->Link);
FreePool (ImageRecord); FreePool (ImageRecord);
mImagePropertiesPrivateData.ImageRecordCount--; mImagePropertiesPrivateData.ImageRecordCount--;

View File

@ -39,8 +39,12 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#include <Protocol/FirmwareVolume2.h> #include <Protocol/FirmwareVolume2.h>
#include <Protocol/SimpleFileSystem.h> #include <Protocol/SimpleFileSystem.h>
#include "Base.h"
#include "DxeMain.h" #include "DxeMain.h"
#include "Library/UefiImageLib.h"
#include "Mem/HeapGuard.h" #include "Mem/HeapGuard.h"
#include "ProcessorBind.h"
#include "Uefi/UefiMultiPhase.h"
// //
// Image type definitions // Image type definitions
@ -66,29 +70,6 @@ extern LIST_ENTRY mGcdMemorySpaceMap;
STATIC LIST_ENTRY mProtectedImageRecordList; STATIC LIST_ENTRY mProtectedImageRecordList;
/**
Sort code section in image record, based upon CodeSegmentBase from low to high.
@param ImageRecord image record to be sorted
**/
VOID
SortImageRecordCodeSection (
IN IMAGE_PROPERTIES_RECORD *ImageRecord
);
/**
Check if code section in image record is valid.
@param ImageRecord image record to be checked
@retval TRUE image record is valid
@retval FALSE image record is invalid
**/
BOOLEAN
IsImageRecordCodeSectionValid (
IN IMAGE_PROPERTIES_RECORD *ImageRecord
);
/** /**
Get the image type. Get the image type.
@ -235,71 +216,24 @@ SetUefiImageMemoryAttributes (
**/ **/
VOID VOID
SetUefiImageProtectionAttributes ( SetUefiImageProtectionAttributes (
IN IMAGE_PROPERTIES_RECORD *ImageRecord IN UEFI_IMAGE_RECORD *ImageRecord
) )
{ {
IMAGE_PROPERTIES_RECORD_CODE_SECTION *ImageRecordCodeSection; UEFI_IMAGE_RECORD_SEGMENT *ImageRecordSegment;
LIST_ENTRY *ImageRecordCodeSectionLink; UINTN SectionAddress;
LIST_ENTRY *ImageRecordCodeSectionEndLink; UINT32 Index;
LIST_ENTRY *ImageRecordCodeSectionList;
UINT64 CurrentBase;
UINT64 ImageEnd;
ImageRecordCodeSectionList = &ImageRecord->CodeSegmentList; SectionAddress = ImageRecord->StartAddress;
for (Index = 0; Index < ImageRecord->NumSegments; Index++) {
CurrentBase = ImageRecord->ImageBase; ImageRecordSegment = &ImageRecord->Segments[Index];
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
//
SetUefiImageMemoryAttributes ( SetUefiImageMemoryAttributes (
ImageRecordCodeSection->CodeSegmentBase, SectionAddress,
ImageRecordCodeSection->CodeSegmentSize, ImageRecordSegment->Size,
EFI_MEMORY_RO ImageRecordSegment->Attributes
); );
CurrentBase = ImageRecordCodeSection->CodeSegmentBase + ImageRecordCodeSection->CodeSegmentSize;
}
// SectionAddress += ImageRecordSegment->Size;
// Last DATA
//
ASSERT (CurrentBase <= ImageEnd);
if (CurrentBase < ImageEnd) {
//
// DATA
//
SetUefiImageMemoryAttributes (
CurrentBase,
ImageEnd - CurrentBase,
EFI_MEMORY_XP
);
} }
return;
} }
/** /**
@ -347,38 +281,7 @@ IsMemoryProtectionSectionAligned (
} }
} }
/** // FIXME: Deduplicate
Free Image record.
@param[in] ImageRecord A UEFI image record
**/
VOID
FreeImageRecord (
IN IMAGE_PROPERTIES_RECORD *ImageRecord
)
{
LIST_ENTRY *CodeSegmentListHead;
IMAGE_PROPERTIES_RECORD_CODE_SECTION *ImageRecordCodeSection;
CodeSegmentListHead = &ImageRecord->CodeSegmentList;
while (!IsListEmpty (CodeSegmentListHead)) {
ImageRecordCodeSection = CR (
CodeSegmentListHead->ForwardLink,
IMAGE_PROPERTIES_RECORD_CODE_SECTION,
Link,
IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNATURE
);
RemoveEntryList (&ImageRecordCodeSection->Link);
FreePool (ImageRecordCodeSection);
}
if (ImageRecord->Link.ForwardLink != NULL) {
RemoveEntryList (&ImageRecord->Link);
}
FreePool (ImageRecord);
}
/** /**
Protect UEFI PE/COFF image. Protect UEFI PE/COFF image.
@ -387,31 +290,26 @@ FreeImageRecord (
**/ **/
VOID VOID
ProtectUefiImage ( ProtectUefiImage (
IN EFI_LOADED_IMAGE_PROTOCOL *LoadedImage, IN LOADED_IMAGE_PRIVATE_DATA *Image,
IN EFI_DEVICE_PATH_PROTOCOL *LoadedImageDevicePath UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext
) )
{ {
VOID *ImageAddress; RETURN_STATUS PdbStatus;
EFI_IMAGE_DOS_HEADER *DosHdr; EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;
UINT32 PeCoffHeaderOffset; EFI_DEVICE_PATH_PROTOCOL *LoadedImageDevicePath;
UINT32 SectionAlignment; UINT32 SectionAlignment;
EFI_IMAGE_SECTION_HEADER *Section; UEFI_IMAGE_RECORD *ImageRecord;
EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr; CONST CHAR8 *PdbPointer;
UINT8 *Name; UINT32 PdbSize;
UINTN Index;
IMAGE_PROPERTIES_RECORD *ImageRecord;
CHAR8 *PdbPointer;
IMAGE_PROPERTIES_RECORD_CODE_SECTION *ImageRecordCodeSection;
BOOLEAN IsAligned; BOOLEAN IsAligned;
UINT32 ProtectionPolicy; UINT32 ProtectionPolicy;
LoadedImage = &Image->Info;
LoadedImageDevicePath = Image->LoadedImageDevicePath;
DEBUG ((DEBUG_INFO, "ProtectUefiImageCommon - 0x%x\n", LoadedImage)); DEBUG ((DEBUG_INFO, "ProtectUefiImageCommon - 0x%x\n", LoadedImage));
DEBUG ((DEBUG_INFO, " - 0x%016lx - 0x%016lx\n", (EFI_PHYSICAL_ADDRESS)(UINTN)LoadedImage->ImageBase, LoadedImage->ImageSize)); DEBUG ((DEBUG_INFO, " - 0x%016lx - 0x%016lx\n", (EFI_PHYSICAL_ADDRESS)(UINTN)LoadedImage->ImageBase, LoadedImage->ImageSize));
if (gCpu == NULL) {
return;
}
ProtectionPolicy = GetUefiImageProtectionPolicy (LoadedImage, LoadedImageDevicePath); ProtectionPolicy = GetUefiImageProtectionPolicy (LoadedImage, LoadedImageDevicePath);
switch (ProtectionPolicy) { switch (ProtectionPolicy) {
case DO_NOT_PROTECT: case DO_NOT_PROTECT:
@ -423,175 +321,49 @@ ProtectUefiImage (
return; return;
} }
ImageRecord = AllocateZeroPool (sizeof (*ImageRecord)); PdbStatus = UefiImageGetSymbolsPath (ImageContext, &PdbPointer, &PdbSize);
if (ImageRecord == NULL) { if (!RETURN_ERROR (PdbStatus)) {
return;
}
ImageRecord->Signature = IMAGE_PROPERTIES_RECORD_SIGNATURE;
//
// Step 1: record whole region
//
ImageRecord->ImageBase = (EFI_PHYSICAL_ADDRESS)(UINTN)LoadedImage->ImageBase;
ImageRecord->ImageSize = LoadedImage->ImageSize;
ImageAddress = LoadedImage->ImageBase;
PdbPointer = PeCoffLoaderGetPdbPointer ((VOID *)(UINTN)ImageAddress);
if (PdbPointer != NULL) {
DEBUG ((DEBUG_VERBOSE, " Image - %a\n", PdbPointer)); DEBUG ((DEBUG_VERBOSE, " Image - %a\n", PdbPointer));
} }
//
// Check PE/COFF image
//
DosHdr = (EFI_IMAGE_DOS_HEADER *)(UINTN)ImageAddress;
PeCoffHeaderOffset = 0;
if (DosHdr->e_magic == EFI_IMAGE_DOS_SIGNATURE) {
PeCoffHeaderOffset = DosHdr->e_lfanew;
}
Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)((UINT8 *)(UINTN)ImageAddress + PeCoffHeaderOffset);
if (Hdr.Pe32->Signature != EFI_IMAGE_NT_SIGNATURE) {
DEBUG ((DEBUG_VERBOSE, "Hdr.Pe32->Signature invalid - 0x%x\n", Hdr.Pe32->Signature));
// It might be image in SMM.
goto Finish;
}
// //
// Get SectionAlignment // Get SectionAlignment
// //
if (Hdr.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) { SectionAlignment = UefiImageGetSegmentAlignment (ImageContext);
SectionAlignment = Hdr.Pe32->OptionalHeader.SectionAlignment;
} else {
SectionAlignment = Hdr.Pe32Plus->OptionalHeader.SectionAlignment;
}
IsAligned = IsMemoryProtectionSectionAligned (SectionAlignment, LoadedImage->ImageCodeType); IsAligned = IsMemoryProtectionSectionAligned (SectionAlignment, LoadedImage->ImageCodeType);
if (!IsAligned) { if (!IsAligned) {
DEBUG (( DEBUG ((
DEBUG_VERBOSE, DEBUG_VERBOSE,
"!!!!!!!! ProtectUefiImageCommon - Section Alignment(0x%x) is incorrect !!!!!!!!\n", "!!!!!!!! ProtectUefiImageCommon - Section Alignment(0x%x) is incorrect !!!!!!!!\n",
SectionAlignment SectionAlignment));
)); if (!RETURN_ERROR (PdbStatus)) {
PdbPointer = PeCoffLoaderGetPdbPointer ((VOID *)(UINTN)ImageAddress);
if (PdbPointer != NULL) {
DEBUG ((DEBUG_VERBOSE, "!!!!!!!! Image - %a !!!!!!!!\n", PdbPointer)); DEBUG ((DEBUG_VERBOSE, "!!!!!!!! Image - %a !!!!!!!!\n", PdbPointer));
} }
goto Finish; goto Finish;
} }
Section = (EFI_IMAGE_SECTION_HEADER *)( ImageRecord = UefiImageLoaderGetImageRecord (ImageContext);
(UINT8 *)(UINTN)ImageAddress + if (ImageRecord == NULL) {
PeCoffHeaderOffset + return ;
sizeof (UINT32) +
sizeof (EFI_IMAGE_FILE_HEADER) +
Hdr.Pe32->FileHeader.SizeOfOptionalHeader
);
ImageRecord->CodeSegmentCount = 0;
InitializeListHead (&ImageRecord->CodeSegmentList);
for (Index = 0; Index < Hdr.Pe32->FileHeader.NumberOfSections; Index++) {
Name = Section[Index].Name;
DEBUG ((
DEBUG_VERBOSE,
" Section - '%c%c%c%c%c%c%c%c'\n",
Name[0],
Name[1],
Name[2],
Name[3],
Name[4],
Name[5],
Name[6],
Name[7]
));
//
// Instead of assuming that a PE/COFF section of type EFI_IMAGE_SCN_CNT_CODE
// can always be mapped read-only, classify a section as a code section only
// if it has the executable attribute set and the writable attribute cleared.
//
// This adheres more closely to the PE/COFF spec, and avoids issues with
// Linux OS loaders that may consist of a single read/write/execute section.
//
if ((Section[Index].Characteristics & (EFI_IMAGE_SCN_MEM_WRITE | EFI_IMAGE_SCN_MEM_EXECUTE)) == EFI_IMAGE_SCN_MEM_EXECUTE) {
DEBUG ((DEBUG_VERBOSE, " VirtualSize - 0x%08x\n", Section[Index].Misc.VirtualSize));
DEBUG ((DEBUG_VERBOSE, " VirtualAddress - 0x%08x\n", Section[Index].VirtualAddress));
DEBUG ((DEBUG_VERBOSE, " SizeOfRawData - 0x%08x\n", Section[Index].SizeOfRawData));
DEBUG ((DEBUG_VERBOSE, " PointerToRawData - 0x%08x\n", Section[Index].PointerToRawData));
DEBUG ((DEBUG_VERBOSE, " PointerToRelocations - 0x%08x\n", Section[Index].PointerToRelocations));
DEBUG ((DEBUG_VERBOSE, " PointerToLinenumbers - 0x%08x\n", Section[Index].PointerToLinenumbers));
DEBUG ((DEBUG_VERBOSE, " NumberOfRelocations - 0x%08x\n", Section[Index].NumberOfRelocations));
DEBUG ((DEBUG_VERBOSE, " NumberOfLinenumbers - 0x%08x\n", Section[Index].NumberOfLinenumbers));
DEBUG ((DEBUG_VERBOSE, " Characteristics - 0x%08x\n", Section[Index].Characteristics));
//
// Step 2: record code section
//
ImageRecordCodeSection = AllocatePool (sizeof (*ImageRecordCodeSection));
if (ImageRecordCodeSection == NULL) {
return;
}
ImageRecordCodeSection->Signature = IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNATURE;
ImageRecordCodeSection->CodeSegmentBase = (UINTN)ImageAddress + Section[Index].VirtualAddress;
ImageRecordCodeSection->CodeSegmentSize = ALIGN_VALUE (Section[Index].SizeOfRawData, SectionAlignment);
DEBUG ((DEBUG_VERBOSE, "ImageCode: 0x%016lx - 0x%016lx\n", ImageRecordCodeSection->CodeSegmentBase, ImageRecordCodeSection->CodeSegmentSize));
InsertTailList (&ImageRecord->CodeSegmentList, &ImageRecordCodeSection->Link);
ImageRecord->CodeSegmentCount++;
}
} }
if (ImageRecord->CodeSegmentCount == 0) { UefiImageDebugPrintSegments (ImageContext);
// UefiImageDebugPrintImageRecord (ImageRecord);
// If a UEFI executable consists of a single read+write+exec PE/COFF
// section, that isn't actually an error. The image can be launched
// alright, only image protection cannot be applied to it fully.
//
// One example that elicits this is (some) Linux kernels (with the EFI stub
// of course).
//
DEBUG ((DEBUG_WARN, "!!!!!!!! ProtectUefiImageCommon - CodeSegmentCount is 0 !!!!!!!!\n"));
PdbPointer = PeCoffLoaderGetPdbPointer ((VOID *)(UINTN)ImageAddress);
if (PdbPointer != NULL) {
DEBUG ((DEBUG_WARN, "!!!!!!!! Image - %a !!!!!!!!\n", PdbPointer));
}
goto Finish;
}
//
// Final
//
SortImageRecordCodeSection (ImageRecord);
//
// Check overlap all section in ImageBase/Size
//
if (!IsImageRecordCodeSectionValid (ImageRecord)) {
DEBUG ((DEBUG_ERROR, "IsImageRecordCodeSectionValid - FAIL\n"));
goto Finish;
}
//
// Round up the ImageSize, some CPU arch may return EFI_UNSUPPORTED if ImageSize is not aligned.
// Given that the loader always allocates full pages, we know the space after the image is not used.
//
ImageRecord->ImageSize = ALIGN_VALUE (LoadedImage->ImageSize, EFI_PAGE_SIZE);
//
// CPU ARCH present. Update memory attribute directly.
//
SetUefiImageProtectionAttributes (ImageRecord);
// //
// Record the image record in the list so we can undo the protections later // Record the image record in the list so we can undo the protections later
// //
InsertTailList (&mProtectedImageRecordList, &ImageRecord->Link); InsertTailList (&mProtectedImageRecordList, &ImageRecord->Link);
if (gCpu != NULL) {
//
// CPU ARCH present. Update memory attribute directly.
//
SetUefiImageProtectionAttributes (ImageRecord);
}
Finish: Finish:
return; return;
} }
@ -608,30 +380,30 @@ UnprotectUefiImage (
IN EFI_DEVICE_PATH_PROTOCOL *LoadedImageDevicePath IN EFI_DEVICE_PATH_PROTOCOL *LoadedImageDevicePath
) )
{ {
IMAGE_PROPERTIES_RECORD *ImageRecord; UEFI_IMAGE_RECORD *ImageRecord;
LIST_ENTRY *ImageRecordLink; LIST_ENTRY *ImageRecordLink;
if (PcdGet32 (PcdImageProtectionPolicy) != 0) { for (ImageRecordLink = mProtectedImageRecordList.ForwardLink;
for (ImageRecordLink = mProtectedImageRecordList.ForwardLink; ImageRecordLink != &mProtectedImageRecordList;
ImageRecordLink != &mProtectedImageRecordList; ImageRecordLink = ImageRecordLink->ForwardLink)
ImageRecordLink = ImageRecordLink->ForwardLink)
{ {
ImageRecord = CR ( ImageRecord = CR (
ImageRecordLink, ImageRecordLink,
IMAGE_PROPERTIES_RECORD, UEFI_IMAGE_RECORD,
Link, Link,
IMAGE_PROPERTIES_RECORD_SIGNATURE UEFI_IMAGE_RECORD_SIGNATURE
); );
if (ImageRecord->ImageBase == (EFI_PHYSICAL_ADDRESS)(UINTN)LoadedImage->ImageBase) { if (ImageRecord->StartAddress == (EFI_PHYSICAL_ADDRESS)(UINTN)LoadedImage->ImageBase) {
SetUefiImageMemoryAttributes ( // TODO: Revise for removal (e.g. CpuDxe integration)
ImageRecord->ImageBase, if (gCpu != NULL) {
ImageRecord->ImageSize, SetUefiImageMemoryAttributes (ImageRecord->StartAddress,
0 ImageRecord->EndAddress - ImageRecord->StartAddress,
); 0);
FreeImageRecord (ImageRecord);
return;
} }
RemoveEntryList (&ImageRecord->Link);
FreePool (ImageRecord);
return;
} }
} }
} }
@ -774,7 +546,6 @@ MergeMemoryMapForProtectionPolicy (
Remove exec permissions from all regions whose type is identified by Remove exec permissions from all regions whose type is identified by
PcdDxeNxMemoryProtectionPolicy. PcdDxeNxMemoryProtectionPolicy.
**/ **/
STATIC
VOID VOID
InitializeDxeNxMemoryProtectionPolicy ( InitializeDxeNxMemoryProtectionPolicy (
VOID VOID
@ -983,11 +754,8 @@ MemoryProtectionCpuArchProtocolNotify (
) )
{ {
EFI_STATUS Status; EFI_STATUS Status;
EFI_LOADED_IMAGE_PROTOCOL *LoadedImage; LIST_ENTRY *ImageRecordLink;
EFI_DEVICE_PATH_PROTOCOL *LoadedImageDevicePath; UEFI_IMAGE_RECORD *ImageRecord;
UINTN NoHandles;
EFI_HANDLE *HandleBuffer;
UINTN Index;
DEBUG ((DEBUG_INFO, "MemoryProtectionCpuArchProtocolNotify:\n")); DEBUG ((DEBUG_INFO, "MemoryProtectionCpuArchProtocolNotify:\n"));
Status = CoreLocateProtocol (&gEfiCpuArchProtocolGuid, NULL, (VOID **)&gCpu); Status = CoreLocateProtocol (&gEfiCpuArchProtocolGuid, NULL, (VOID **)&gCpu);
@ -1011,41 +779,22 @@ MemoryProtectionCpuArchProtocolNotify (
goto Done; goto Done;
} }
Status = gBS->LocateHandleBuffer ( for (ImageRecordLink = mProtectedImageRecordList.ForwardLink;
ByProtocol, ImageRecordLink != &mProtectedImageRecordList;
&gEfiLoadedImageProtocolGuid, ImageRecordLink = ImageRecordLink->ForwardLink) {
NULL, ImageRecord = CR (
&NoHandles, ImageRecordLink,
&HandleBuffer UEFI_IMAGE_RECORD,
); Link,
if (EFI_ERROR (Status) && (NoHandles == 0)) { UEFI_IMAGE_RECORD_SIGNATURE
goto Done;
}
for (Index = 0; Index < NoHandles; Index++) {
Status = gBS->HandleProtocol (
HandleBuffer[Index],
&gEfiLoadedImageProtocolGuid,
(VOID **)&LoadedImage
); );
if (EFI_ERROR (Status)) {
continue;
}
Status = gBS->HandleProtocol ( //
HandleBuffer[Index], // CPU ARCH present. Update memory attribute directly.
&gEfiLoadedImageDevicePathProtocolGuid, //
(VOID **)&LoadedImageDevicePath SetUefiImageProtectionAttributes (ImageRecord);
);
if (EFI_ERROR (Status)) {
LoadedImageDevicePath = NULL;
}
ProtectUefiImage (LoadedImage, LoadedImageDevicePath);
} }
FreePool (HandleBuffer);
Done: Done:
CoreCloseEvent (Event); CoreCloseEvent (Event);
} }

View File

@ -8,6 +8,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
**/ **/
#include "PeiMain.h" #include "PeiMain.h"
#include "ProcessorBind.h"
/** /**
@ -1009,8 +1010,7 @@ MigratePeim (
EFI_FFS_FILE_HEADER *FileHeader; EFI_FFS_FILE_HEADER *FileHeader;
VOID *Pe32Data; VOID *Pe32Data;
VOID *ImageAddress; VOID *ImageAddress;
CHAR8 *AsciiString; UINT32 ImageSize;
UINTN Index;
Status = EFI_SUCCESS; Status = EFI_SUCCESS;
@ -1018,24 +1018,10 @@ MigratePeim (
ASSERT (!IS_FFS_FILE2 (FileHeader)); ASSERT (!IS_FFS_FILE2 (FileHeader));
ImageAddress = NULL; ImageAddress = NULL;
PeiGetPe32Data (MigratedFileHandle, &ImageAddress); PeiGetPe32Data (MigratedFileHandle, &ImageAddress, &ImageSize);
if (ImageAddress != NULL) { 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); Pe32Data = (VOID *)((UINTN)ImageAddress - (UINTN)MigratedFileHandle + (UINTN)FileHandle);
Status = LoadAndRelocatePeCoffImageInPlace (Pe32Data, ImageAddress); Status = LoadAndRelocateUefiImageInPlace (Pe32Data, ImageAddress, ImageSize);
ASSERT_EFI_ERROR (Status); 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. Migrates PEIMs in the given firmware volume.

View File

@ -35,7 +35,8 @@ PEI_FW_VOL_INSTANCE mPeiFfs2FwVol = {
PeiFfsFvPpiGetFileInfo2, PeiFfsFvPpiGetFileInfo2,
PeiFfsFvPpiFindSectionByType2, PeiFfsFvPpiFindSectionByType2,
EFI_PEI_FIRMWARE_VOLUME_PPI_SIGNATURE, 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, PeiFfsFvPpiGetFileInfo2,
PeiFfsFvPpiFindSectionByType2, PeiFfsFvPpiFindSectionByType2,
EFI_PEI_FIRMWARE_VOLUME_PPI_SIGNATURE, 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 SectionSize The file size to search.
@param OutputBuffer A pointer to the discovered section, if successful. @param OutputBuffer A pointer to the discovered section, if successful.
NULL if section not found 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 AuthenticationStatus Updated upon return to point to the authentication status for this section.
@param IsFfs3Fv Indicates the FV format. @param IsFfs3Fv Indicates the FV format.
@ -786,6 +790,7 @@ ProcessSection (
IN EFI_COMMON_SECTION_HEADER *Section, IN EFI_COMMON_SECTION_HEADER *Section,
IN UINTN SectionSize, IN UINTN SectionSize,
OUT VOID **OutputBuffer, OUT VOID **OutputBuffer,
OUT UINT32 *OutputSize,
OUT UINT32 *AuthenticationStatus, OUT UINT32 *AuthenticationStatus,
IN BOOLEAN IsFfs3Fv IN BOOLEAN IsFfs3Fv
) )
@ -803,11 +808,13 @@ ProcessSection (
EFI_GUID *SectionDefinitionGuid; EFI_GUID *SectionDefinitionGuid;
BOOLEAN SectionCached; BOOLEAN SectionCached;
VOID *TempOutputBuffer; VOID *TempOutputBuffer;
UINT32 TempOutputSize;
UINT32 TempAuthenticationStatus; UINT32 TempAuthenticationStatus;
UINT16 GuidedSectionAttributes; UINT16 GuidedSectionAttributes;
PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices); PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);
*OutputBuffer = NULL; *OutputBuffer = NULL;
*OutputSize = 0;
ParsedLength = 0; ParsedLength = 0;
Index = 0; Index = 0;
Status = EFI_NOT_FOUND; Status = EFI_NOT_FOUND;
@ -840,10 +847,13 @@ ProcessSection (
// //
// Got it! // Got it!
// //
// FIXME: Size checks
if (IS_SECTION2 (Section)) { if (IS_SECTION2 (Section)) {
*OutputBuffer = (VOID *)((UINT8 *)Section + sizeof (EFI_COMMON_SECTION_HEADER2)); *OutputBuffer = (VOID *)((UINT8 *)Section + sizeof (EFI_COMMON_SECTION_HEADER2));
*OutputSize = SECTION2_SIZE (Section) - sizeof (EFI_COMMON_SECTION_HEADER2);
} else { } else {
*OutputBuffer = (VOID *)((UINT8 *)Section + sizeof (EFI_COMMON_SECTION_HEADER)); *OutputBuffer = (VOID *)((UINT8 *)Section + sizeof (EFI_COMMON_SECTION_HEADER));
*OutputSize = SECTION_SIZE (Section) - sizeof (EFI_COMMON_SECTION_HEADER);
} }
return EFI_SUCCESS; return EFI_SUCCESS;
@ -886,11 +896,13 @@ ProcessSection (
PpiOutput, PpiOutput,
PpiOutputSize, PpiOutputSize,
&TempOutputBuffer, &TempOutputBuffer,
&TempOutputSize,
&TempAuthenticationStatus, &TempAuthenticationStatus,
IsFfs3Fv IsFfs3Fv
); );
if (!EFI_ERROR (Status)) { if (!EFI_ERROR (Status)) {
*OutputBuffer = TempOutputBuffer; *OutputBuffer = TempOutputBuffer;
*OutputSize = TempOutputSize;
*AuthenticationStatus = TempAuthenticationStatus | Authentication; *AuthenticationStatus = TempAuthenticationStatus | Authentication;
return EFI_SUCCESS; return EFI_SUCCESS;
} }
@ -973,11 +985,13 @@ ProcessSection (
PpiOutput, PpiOutput,
PpiOutputSize, PpiOutputSize,
&TempOutputBuffer, &TempOutputBuffer,
&TempOutputSize,
&TempAuthenticationStatus, &TempAuthenticationStatus,
IsFfs3Fv IsFfs3Fv
); );
if (!EFI_ERROR (Status)) { if (!EFI_ERROR (Status)) {
*OutputBuffer = TempOutputBuffer; *OutputBuffer = TempOutputBuffer;
*OutputSize = TempOutputSize;
*AuthenticationStatus = TempAuthenticationStatus | Authentication; *AuthenticationStatus = TempAuthenticationStatus | Authentication;
return EFI_SUCCESS; return EFI_SUCCESS;
} }
@ -1060,6 +1074,38 @@ PeiFfsFindSectionData3 (
OUT VOID **SectionData, OUT VOID **SectionData,
OUT UINT32 *AuthenticationStatus 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; PEI_CORE_FV_HANDLE *CoreFvHandle;
@ -1071,7 +1117,7 @@ PeiFfsFindSectionData3 (
if ((CoreFvHandle->FvPpi->Signature == EFI_PEI_FIRMWARE_VOLUME_PPI_SIGNATURE) && if ((CoreFvHandle->FvPpi->Signature == EFI_PEI_FIRMWARE_VOLUME_PPI_SIGNATURE) &&
(CoreFvHandle->FvPpi->Revision == EFI_PEI_FIRMWARE_VOLUME_PPI_REVISION)) (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 VOID **SectionData,
OUT UINT32 *AuthenticationStatus 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_STATUS Status;
EFI_FFS_FILE_HEADER *FfsFileHeader; EFI_FFS_FILE_HEADER *FfsFileHeader;
@ -2077,6 +2174,7 @@ PeiFfsFvPpiFindSectionByType2 (
Section, Section,
FileSize, FileSize,
SectionData, SectionData,
SectionDataSize,
&ExtractedAuthenticationStatus, &ExtractedAuthenticationStatus,
FwVolInstance->IsFfs3Fv FwVolInstance->IsFfs3Fv
); );

View File

@ -185,6 +185,43 @@ PeiFfsFvPpiFindSectionByType2 (
OUT UINT32 *AuthenticationStatus 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. Returns information about a specific file.

View File

@ -18,40 +18,6 @@ EFI_PEI_PPI_DESCRIPTOR gPpiLoadFilePpiList = {
&mPeiLoadImagePpi &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 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. memory range is available, the function will mark the corresponding bits to 1 which indicates the memory range is used.
@ -135,111 +101,43 @@ CheckAndMarkFixLoadingMemoryUsageBitMap (
**/ **/
EFI_STATUS EFI_STATUS
GetPeCoffImageFixLoadingAssignedAddress ( GetUefiImageFixLoadingAssignedAddress (
IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext, IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext,
IN PEI_CORE_INSTANCE *Private IN PEI_CORE_INSTANCE *Private,
OUT EFI_PHYSICAL_ADDRESS *LoadAddress
) )
{ {
UINTN SectionHeaderOffset; EFI_STATUS Status;
EFI_STATUS Status; UINT64 ValueInSectionHeader;
EFI_IMAGE_SECTION_HEADER SectionHeader; EFI_PHYSICAL_ADDRESS FixLoadingAddress;
EFI_IMAGE_OPTIONAL_HEADER_UNION *ImgHdr; UINT32 SizeOfImage;
EFI_PHYSICAL_ADDRESS FixLoadingAddress;
UINT16 Index;
UINTN Size;
UINT16 NumberOfSections;
UINT64 ValueInSectionHeader;
FixLoadingAddress = 0; Status = UefiImageGetFixedAddress (ImageContext, &ValueInSectionHeader);
Status = EFI_NOT_FOUND; if (RETURN_ERROR (Status)) {
return Status;
}
// if ((INT64)PcdGet64(PcdLoadModuleAtFixAddressEnable) > 0) {
// Get PeHeader pointer
//
ImgHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)((CHAR8 *)ImageContext->Handle + ImageContext->PeCoffHeaderOffset);
if (ImageContext->IsTeImage) {
// //
// for TE image, the fix loading address is saved in first section header that doesn't point // When LMFA feature is configured as Load Module at Fixed Absolute Address mode, PointerToRelocations & PointerToLineNumbers field
// to code section. // hold the absolute address of image base running in memory
// //
SectionHeaderOffset = sizeof (EFI_TE_IMAGE_HEADER); FixLoadingAddress = ValueInSectionHeader;
NumberOfSections = ImgHdr->Te.NumberOfSections;
} else { } 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); FixLoadingAddress = (EFI_PHYSICAL_ADDRESS)(Private->LoadModuleAtFixAddressTopAddress + ValueInSectionHeader);
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);
} }
//
// Check if the memory range is available.
//
SizeOfImage = UefiImageGetImageSize (ImageContext);
Status = CheckAndMarkFixLoadingMemoryUsageBitMap (Private, FixLoadingAddress, SizeOfImage);
*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; return Status;
} }
@ -262,38 +160,44 @@ GetPeCoffImageFixLoadingAssignedAddress (
**/ **/
EFI_STATUS EFI_STATUS
LoadAndRelocatePeCoffImage ( LoadAndRelocateUefiImage (
IN EFI_PEI_FILE_HANDLE FileHandle, IN EFI_PEI_FILE_HANDLE FileHandle,
IN VOID *Pe32Data, IN VOID *Pe32Data,
OUT EFI_PHYSICAL_ADDRESS *ImageAddress, IN UINT32 Pe32DataSize,
OUT UINT64 *ImageSize, OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext,
OUT EFI_PHYSICAL_ADDRESS *EntryPoint OUT EFI_PHYSICAL_ADDRESS *ImageAddress
) )
{ {
EFI_STATUS Status; EFI_STATUS Status;
PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;
PEI_CORE_INSTANCE *Private; PEI_CORE_INSTANCE *Private;
UINT64 AlignImageSize; UINT32 DynamicImageSize;
BOOLEAN IsXipImage; BOOLEAN IsXipImage;
EFI_STATUS ReturnStatus; EFI_STATUS ReturnStatus;
BOOLEAN IsS3Boot; BOOLEAN IsS3Boot;
BOOLEAN IsPeiModule; BOOLEAN IsPeiModule;
BOOLEAN IsRegisterForShadow; BOOLEAN IsRegisterForShadow;
EFI_FV_FILE_INFO FileInfo; EFI_FV_FILE_INFO FileInfo;
EFI_PHYSICAL_ADDRESS LoadAddress;
UINT16 Machine;
BOOLEAN LoadDynamically;
Private = PEI_CORE_INSTANCE_FROM_PS_THIS (GetPeiServicesTablePointer ()); Private = PEI_CORE_INSTANCE_FROM_PS_THIS (GetPeiServicesTablePointer ());
ReturnStatus = EFI_SUCCESS; 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)) { if (EFI_ERROR (Status)) {
return 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 // Initialize local IsS3Boot and IsRegisterForShadow variable
// //
@ -312,9 +216,7 @@ LoadAndRelocatePeCoffImage (
// //
// XIP image that ImageAddress is same to Image handle. // XIP image that ImageAddress is same to Image handle.
// //
if (ImageContext.ImageAddress == (EFI_PHYSICAL_ADDRESS)(UINTN)Pe32Data) { IsXipImage = UefiImageImageIsInplace (ImageContext);
IsXipImage = TRUE;
}
// //
// Get file type first // Get file type first
@ -336,7 +238,7 @@ LoadAndRelocatePeCoffImage (
// //
// When Image has no reloc section, it can't be relocated into memory. // 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) || ((!IsPeiModule) || PcdGetBool (PcdMigrateTemporaryRamFirmwareVolumes) ||
(!IsS3Boot && (PcdGetBool (PcdShadowPeimOnBoot) || IsRegisterForShadow)) || (!IsS3Boot && (PcdGetBool (PcdShadowPeimOnBoot) || IsRegisterForShadow)) ||
(IsS3Boot && PcdGetBool (PcdShadowPeimOnS3Boot))) (IsS3Boot && PcdGetBool (PcdShadowPeimOnS3Boot)))
@ -345,125 +247,92 @@ LoadAndRelocatePeCoffImage (
DEBUG ((DEBUG_INFO|DEBUG_LOAD, "The image at 0x%08x without reloc section can't be loaded into memory\n", (UINTN)Pe32Data)); DEBUG ((DEBUG_INFO|DEBUG_LOAD, "The image at 0x%08x without reloc section can't be loaded into memory\n", (UINTN)Pe32Data));
} }
// LoadDynamically = FALSE;
// Set default base address to current image address. DynamicImageSize = 0;
//
ImageContext.ImageAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)Pe32Data;
// //
// Allocate Memory for the image when memory is ready, and image is relocatable. // 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 normal boot, PcdShadowPeimOnBoot decides whether load PEIM or PeiCore into memory.
// On S3 boot, PcdShadowPeimOnS3Boot 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) || ((!IsPeiModule) || PcdGetBool (PcdMigrateTemporaryRamFirmwareVolumes) ||
(!IsS3Boot && (PcdGetBool (PcdShadowPeimOnBoot) || IsRegisterForShadow)) || (!IsS3Boot && (PcdGetBool (PcdShadowPeimOnBoot) || IsRegisterForShadow)) ||
(IsS3Boot && PcdGetBool (PcdShadowPeimOnS3Boot))) (IsS3Boot && PcdGetBool (PcdShadowPeimOnS3Boot)))
) )
{ {
// Status = EFI_UNSUPPORTED;
// 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;
}
if (ImageContext.SectionAlignment > EFI_PAGE_SIZE) { if (PcdGet64(PcdLoadModuleAtFixAddressEnable) != 0 && (Private->HobList.HandoffInformationTable->BootMode != BOOT_ON_S3_RESUME)) {
AlignImageSize += ImageContext.SectionAlignment; Status = GetUefiImageFixLoadingAssignedAddress(ImageContext, Private, &LoadAddress);
} if (!EFI_ERROR (Status)){
DynamicImageSize = UefiImageGetImageSize (ImageContext);
if ((PcdGet64 (PcdLoadModuleAtFixAddressEnable) != 0) && (Private->HobList.HandoffInformationTable->BootMode != BOOT_ON_S3_RESUME)) { if (LoadAddress != UefiImageGetPreferredAddress (ImageContext)) {
Status = GetPeCoffImageFixLoadingAssignedAddress (&ImageContext, Private); Status = EFI_UNSUPPORTED;
if (EFI_ERROR (Status)) { DEBUG ((DEBUG_INFO|DEBUG_LOAD, "LOADING MODULE FIXED ERROR: Loading module at fixed address failed since relocs have been stripped.\n"));
DEBUG ((DEBUG_INFO|DEBUG_LOAD, "LOADING MODULE FIXED ERROR: Failed to load module at fixed address. \n")); }
// } else {
// The PEIM is not assigned valid address, try to allocate page to load it. DEBUG ((EFI_D_INFO|EFI_D_LOAD, "LOADING MODULE FIXED ERROR: Failed to load module at fixed address. \n"));
//
Status = PeiServicesAllocatePages (
EfiBootServicesCode,
EFI_SIZE_TO_PAGES ((UINT32)AlignImageSize),
&ImageContext.ImageAddress
);
} }
} else { }
if (EFI_ERROR (Status)) {
//
// Allocate more buffer to avoid buffer overflow.
//
Status = UefiImageLoaderGetDestinationSize (ImageContext, &DynamicImageSize);
if (RETURN_ERROR (Status)) {
return Status;
}
Status = PeiServicesAllocatePages ( Status = PeiServicesAllocatePages (
EfiBootServicesCode, EfiBootServicesCode,
EFI_SIZE_TO_PAGES ((UINT32)AlignImageSize), EFI_SIZE_TO_PAGES (DynamicImageSize),
&ImageContext.ImageAddress &LoadAddress
); );
} }
if (!EFI_ERROR (Status)) { if (!EFI_ERROR (Status)) {
LoadDynamically = TRUE;
// //
// Adjust the Image Address to make sure it is section alignment. // Load the image to our new buffer
// //
if (ImageContext.SectionAlignment > EFI_PAGE_SIZE) { Status = UefiImageLoadImageForExecution (
ImageContext.ImageAddress = ImageContext,
(ImageContext.ImageAddress + ImageContext.SectionAlignment - 1) & (VOID *) (UINTN)LoadAddress,
~((UINTN)ImageContext.SectionAlignment - 1); DynamicImageSize,
} NULL,
0
// );
// Fix alignment requirement when Load IPF TeImage into memory. if (EFI_ERROR (Status)) {
// Skip the reserved space for the stripped PeHeader when load TeImage into memory. return Status;
//
if (ImageContext.IsTeImage) {
ImageContext.ImageAddress = ImageContext.ImageAddress +
((EFI_TE_IMAGE_HEADER *)Pe32Data)->StrippedSize -
sizeof (EFI_TE_IMAGE_HEADER);
} }
} else { } else {
// //
// No enough memory resource. // No enough memory resource.
// //
if (IsXipImage) { if (!IsXipImage) {
//
// XIP image can still be invoked.
//
ImageContext.ImageAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)Pe32Data;
ReturnStatus = EFI_WARN_BUFFER_TOO_SMALL;
} else {
// //
// Non XIP image can't be loaded because no enough memory is allocated. // Non XIP image can't be loaded because no enough memory is allocated.
// //
ASSERT (FALSE); ASSERT (FALSE);
return EFI_OUT_OF_RESOURCES; return EFI_OUT_OF_RESOURCES;
} }
//
// XIP image can still be invoked.
//
ReturnStatus = EFI_WARN_BUFFER_TOO_SMALL;
} }
} }
// if (!LoadDynamically) {
// Load the image to our new buffer Status = UefiImageLoadImageInplace (ImageContext);
// if (EFI_ERROR (Status)) {
Status = PeCoffLoaderLoadImage (&ImageContext); return Status;
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));
} }
return Status;
} }
// *ImageAddress = UefiImageLoaderGetImageAddress (ImageContext);
// 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;
return ReturnStatus; return ReturnStatus;
} }
@ -479,50 +348,30 @@ LoadAndRelocatePeCoffImage (
**/ **/
EFI_STATUS EFI_STATUS
LoadAndRelocatePeCoffImageInPlace ( LoadAndRelocateUefiImageInPlace (
IN VOID *Pe32Data, IN VOID *Pe32Data,
IN VOID *ImageAddress IN VOID *ImageAddress,
IN UINT32 ImageSize
) )
{ {
EFI_STATUS Status; EFI_STATUS Status;
PE_COFF_LOADER_IMAGE_CONTEXT ImageContext; UEFI_IMAGE_LOADER_IMAGE_CONTEXT ImageContext;
ZeroMem (&ImageContext, sizeof (ImageContext)); ASSERT (Pe32Data != ImageAddress);
ImageContext.Handle = Pe32Data;
ImageContext.ImageRead = PeiImageRead;
Status = PeCoffLoaderGetImageInfo (&ImageContext); CopyMem (ImageAddress, Pe32Data, ImageSize);
Status = UefiImageInitializeContext (&ImageContext, ImageAddress, ImageSize);
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {
ASSERT_EFI_ERROR (Status); ASSERT_EFI_ERROR (Status);
return Status; return Status;
} }
ImageContext.ImageAddress = (PHYSICAL_ADDRESS)(UINTN)ImageAddress;
// //
// Load the image in place // Load the image in place
// //
Status = PeCoffLoaderLoadImage (&ImageContext); Status = UefiImageRelocateImageInplaceForExecution (&ImageContext);
if (EFI_ERROR (Status)) { ASSERT_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);
}
return Status; return Status;
} }
@ -540,7 +389,8 @@ LoadAndRelocatePeCoffImageInPlace (
EFI_STATUS EFI_STATUS
PeiGetPe32Data ( PeiGetPe32Data (
IN EFI_PEI_FILE_HANDLE FileHandle, IN EFI_PEI_FILE_HANDLE FileHandle,
OUT VOID **Pe32Data OUT VOID **Pe32Data,
OUT UINT32 *Pe32DataSize
) )
{ {
EFI_STATUS Status; EFI_STATUS Status;
@ -562,22 +412,24 @@ PeiGetPe32Data (
// Try to find a first exe section (if PcdPeiCoreImageLoaderSearchTeSectionFirst // Try to find a first exe section (if PcdPeiCoreImageLoaderSearchTeSectionFirst
// is true, TE will be searched first). // is true, TE will be searched first).
// //
Status = PeiServicesFfsFindSectionData3 ( Status = PeiServicesFfsFindSectionData4 (
SearchType1, SearchType1,
0, 0,
FileHandle, FileHandle,
Pe32Data, Pe32Data,
Pe32DataSize,
&AuthenticationState &AuthenticationState
); );
// //
// If we didn't find a first exe section, try to find the second exe section. // If we didn't find a first exe section, try to find the second exe section.
// //
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {
Status = PeiServicesFfsFindSectionData3 ( Status = PeiServicesFfsFindSectionData4 (
SearchType2, SearchType2,
0, 0,
FileHandle, FileHandle,
Pe32Data, Pe32Data,
Pe32DataSize,
&AuthenticationState &AuthenticationState
); );
} }
@ -617,15 +469,13 @@ PeiLoadImageLoadImage (
{ {
EFI_STATUS Status; EFI_STATUS Status;
VOID *Pe32Data; VOID *Pe32Data;
UINT32 Pe32DataSize;
EFI_PHYSICAL_ADDRESS ImageAddress; EFI_PHYSICAL_ADDRESS ImageAddress;
UINT64 ImageSize;
EFI_PHYSICAL_ADDRESS ImageEntryPoint;
UINT16 Machine;
EFI_SECTION_TYPE SearchType1; EFI_SECTION_TYPE SearchType1;
EFI_SECTION_TYPE SearchType2; EFI_SECTION_TYPE SearchType2;
UEFI_IMAGE_LOADER_IMAGE_CONTEXT ImageContext;
*EntryPoint = 0; *EntryPoint = 0;
ImageSize = 0;
*AuthenticationState = 0; *AuthenticationState = 0;
if (FeaturePcdGet (PcdPeiCoreImageLoaderSearchTeSectionFirst)) { if (FeaturePcdGet (PcdPeiCoreImageLoaderSearchTeSectionFirst)) {
@ -640,22 +490,24 @@ PeiLoadImageLoadImage (
// Try to find a first exe section (if PcdPeiCoreImageLoaderSearchTeSectionFirst // Try to find a first exe section (if PcdPeiCoreImageLoaderSearchTeSectionFirst
// is true, TE will be searched first). // is true, TE will be searched first).
// //
Status = PeiServicesFfsFindSectionData3 ( Status = PeiServicesFfsFindSectionData4 (
SearchType1, SearchType1,
0, 0,
FileHandle, FileHandle,
&Pe32Data, &Pe32Data,
&Pe32DataSize,
AuthenticationState AuthenticationState
); );
// //
// If we didn't find a first exe section, try to find the second exe section. // If we didn't find a first exe section, try to find the second exe section.
// //
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {
Status = PeiServicesFfsFindSectionData3 ( Status = PeiServicesFfsFindSectionData4 (
SearchType2, SearchType2,
0, 0,
FileHandle, FileHandle,
&Pe32Data, &Pe32Data,
&Pe32DataSize,
AuthenticationState AuthenticationState
); );
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {
@ -672,12 +524,12 @@ PeiLoadImageLoadImage (
// //
// If memory is installed, perform the shadow operations // If memory is installed, perform the shadow operations
// //
Status = LoadAndRelocatePeCoffImage ( Status = LoadAndRelocateUefiImage (
FileHandle, FileHandle,
Pe32Data, Pe32Data,
&ImageAddress, Pe32DataSize,
&ImageSize, &ImageContext,
&ImageEntryPoint &ImageAddress
); );
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {
@ -687,83 +539,47 @@ PeiLoadImageLoadImage (
// //
// Got the entry point from the loaded Pe32Data // Got the entry point from the loaded Pe32Data
// //
Pe32Data = (VOID *)((UINTN)ImageAddress); *EntryPoint = UefiImageLoaderGetImageEntryPoint (&ImageContext);
*EntryPoint = ImageEntryPoint;
Machine = PeCoffLoaderGetMachineType (Pe32Data);
if (!EFI_IMAGE_MACHINE_TYPE_SUPPORTED (Machine)) {
if (!EFI_IMAGE_MACHINE_CROSS_TYPE_SUPPORTED (Machine)) {
return EFI_UNSUPPORTED;
}
}
if (ImageAddressArg != NULL) { if (ImageAddressArg != NULL) {
*ImageAddressArg = ImageAddress; *ImageAddressArg = ImageAddress;
} }
if (ImageSizeArg != NULL) { if (ImageSizeArg != NULL) {
*ImageSizeArg = ImageSize; *ImageSizeArg =UefiImageGetImageSize (&ImageContext);
} }
DEBUG_CODE_BEGIN (); DEBUG_CODE_BEGIN ();
CHAR8 *AsciiString; CHAR8 EfiFileName[512];
CHAR8 EfiFileName[512]; UINT16 Machine;
INT32 Index;
INT32 StartIndex; 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))); 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 {
// //
// Print Module Name by PeImage PDB file name. // For IPF Image, the real entry point should be print.
// //
AsciiString = PeCoffLoaderGetPdbPointer (Pe32Data); DEBUG ((DEBUG_INFO | DEBUG_LOAD, "Loading PEIM at 0x%11p EntryPoint=0x%11p ", (VOID *)(UINTN)ImageAddress, (VOID *)(UINTN)(*(UINT64 *)(UINTN)*EntryPoint)));
if (AsciiString != NULL) {
StartIndex = 0;
for (Index = 0; AsciiString[Index] != 0; Index++) {
if ((AsciiString[Index] == '\\') || (AsciiString[Index] == '/')) {
StartIndex = Index + 1;
}
} }
// //
// Copy the PDB file name to our temporary string, and replace .pdb with .efi // Print Module Name by PeImage PDB file name.
// 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.
// //
for (Index = 0; Index < sizeof (EfiFileName) - 4; Index++) { Status = UefiImageGetModuleNameFromSymbolsPath (
EfiFileName[Index] = AsciiString[Index + StartIndex]; &ImageContext,
if (EfiFileName[Index] == 0) { EfiFileName,
EfiFileName[Index] = '.'; sizeof (EfiFileName)
} );
if (EfiFileName[Index] == '.') { if (!RETURN_ERROR (Status)) {
EfiFileName[Index + 1] = 'e'; DEBUG ((DEBUG_INFO | DEBUG_LOAD, "%a", EfiFileName));
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));
}
DEBUG_CODE_END (); DEBUG_CODE_END ();
DEBUG ((DEBUG_INFO | DEBUG_LOAD, "\n")); DEBUG ((DEBUG_INFO | DEBUG_LOAD, "\n"));
@ -814,7 +630,7 @@ PeiLoadImageLoadImageWrapper (
@retval FALSE Relocation is not stripped. @retval FALSE Relocation is not stripped.
**/ **/
BOOLEAN /*BOOLEAN
RelocationIsStrip ( RelocationIsStrip (
IN VOID *Pe32Data IN VOID *Pe32Data
) )
@ -863,7 +679,7 @@ RelocationIsStrip (
} }
return FALSE; return FALSE;
} }*/
/** /**
Routine to load image file for subsequent execution by LoadFile Ppi. Routine to load image file for subsequent execution by LoadFile Ppi.
@ -896,9 +712,9 @@ PeiLoadImage (
EFI_PEI_LOAD_FILE_PPI *LoadFile; EFI_PEI_LOAD_FILE_PPI *LoadFile;
EFI_PHYSICAL_ADDRESS ImageAddress; EFI_PHYSICAL_ADDRESS ImageAddress;
UINT64 ImageSize; UINT64 ImageSize;
BOOLEAN IsStrip; //BOOLEAN IsStrip;
IsStrip = FALSE; //IsStrip = FALSE;
// //
// If any instances of PEI_LOAD_FILE_PPI are installed, they are called. // If any instances of PEI_LOAD_FILE_PPI are installed, they are called.
// one at a time, until one reports EFI_SUCCESS. // one at a time, until one reports EFI_SUCCESS.
@ -924,7 +740,9 @@ PeiLoadImage (
// //
// The shadowed PEIM must be relocatable. // 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); IsStrip = RelocationIsStrip ((VOID *)(UINTN)ImageAddress);
ASSERT (!IsStrip); ASSERT (!IsStrip);
if (IsStrip) { if (IsStrip) {
@ -935,10 +753,10 @@ PeiLoadImage (
// //
// The image to be started must have the machine type supported by PeiCore. // The image to be started must have the machine type supported by PeiCore.
// //
ASSERT (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 (PeCoffLoaderGetMachineType ((VOID *)(UINTN)ImageAddress))) { if (!EFI_IMAGE_MACHINE_TYPE_SUPPORTED (UefiImageLoaderGetMachineType ((VOID *)(UINTN)ImageAddress))) {
return EFI_UNSUPPORTED; return EFI_UNSUPPORTED;
} }*/
return EFI_SUCCESS; return EFI_SUCCESS;
} }

View File

@ -33,12 +33,11 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#include <Library/PerformanceLib.h> #include <Library/PerformanceLib.h>
#include <Library/PeiServicesLib.h> #include <Library/PeiServicesLib.h>
#include <Library/ReportStatusCodeLib.h> #include <Library/ReportStatusCodeLib.h>
#include <Library/PeCoffLib.h> #include <Library/UefiImageLib.h>
#include <Library/PeCoffGetEntryPointLib.h>
#include <Library/BaseMemoryLib.h> #include <Library/BaseMemoryLib.h>
#include <Library/CacheMaintenanceLib.h> #include <Library/CacheMaintenanceLib.h>
#include <Library/PcdLib.h> #include <Library/PcdLib.h>
#include <IndustryStandard/PeImage.h> #include <IndustryStandard/PeImage2.h>
#include <Library/PeiServicesTablePointerLib.h> #include <Library/PeiServicesTablePointerLib.h>
#include <Library/MemoryAllocationLib.h> #include <Library/MemoryAllocationLib.h>
#include <Guid/FirmwareFileSystem2.h> #include <Guid/FirmwareFileSystem2.h>
@ -289,7 +288,7 @@ struct _PEI_CORE_INSTANCE {
// //
// This field points to the shadowed image read function // This field points to the shadowed image read function
// //
PE_COFF_LOADER_READ_FILE ShadowedImageRead; VOID *ShadowedImageRead;
UINTN TempPeimCount; UINTN TempPeimCount;
@ -903,6 +902,8 @@ PeiFfsFindNextFile (
@param SectionSize The file size to search. @param SectionSize The file size to search.
@param OutputBuffer A pointer to the discovered section, if successful. @param OutputBuffer A pointer to the discovered section, if successful.
NULL if section not found. 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 AuthenticationStatus Updated upon return to point to the authentication status for this section.
@param IsFfs3Fv Indicates the FV format. @param IsFfs3Fv Indicates the FV format.
@ -918,6 +919,7 @@ ProcessSection (
IN EFI_COMMON_SECTION_HEADER *Section, IN EFI_COMMON_SECTION_HEADER *Section,
IN UINTN SectionSize, IN UINTN SectionSize,
OUT VOID **OutputBuffer, OUT VOID **OutputBuffer,
OUT UINT32 *OutputSize,
OUT UINT32 *AuthenticationStatus, OUT UINT32 *AuthenticationStatus,
IN BOOLEAN IsFfs3Fv IN BOOLEAN IsFfs3Fv
); );
@ -969,6 +971,33 @@ PeiFfsFindSectionData3 (
OUT UINT32 *AuthenticationStatus 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 Search the firmware volumes by index
@ -1402,9 +1431,10 @@ InitializeImageServices (
**/ **/
EFI_STATUS EFI_STATUS
LoadAndRelocatePeCoffImageInPlace ( LoadAndRelocateUefiImageInPlace (
IN VOID *Pe32Data, IN VOID *Pe32Data,
IN VOID *ImageAddress IN VOID *ImageAddress,
IN UINT32 ImageSize
); );
/** /**
@ -1420,7 +1450,8 @@ LoadAndRelocatePeCoffImageInPlace (
EFI_STATUS EFI_STATUS
PeiGetPe32Data ( PeiGetPe32Data (
IN EFI_PEI_FILE_HANDLE FileHandle, IN EFI_PEI_FILE_HANDLE FileHandle,
OUT VOID **Pe32Data OUT VOID **Pe32Data,
OUT UINT32 *Pe32DataSize
); );
/** /**

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