mirror of
https://github.com/acidanthera/audk.git
synced 2025-07-27 07:34:06 +02:00
SecurePE: Replaced old PE loader with Secure one.
This commit is contained in:
parent
2802a08822
commit
dbcf8301e1
@ -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
|
||||||
@ -112,7 +112,7 @@
|
|||||||
ArmPkg/Library/ArmCacheMaintenanceLib/ArmCacheMaintenanceLib.inf
|
ArmPkg/Library/ArmCacheMaintenanceLib/ArmCacheMaintenanceLib.inf
|
||||||
ArmPkg/Library/ArmPsciResetSystemLib/ArmPsciResetSystemLib.inf
|
ArmPkg/Library/ArmPsciResetSystemLib/ArmPsciResetSystemLib.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
|
||||||
|
@ -34,7 +34,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
|
||||||
|
@ -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>
|
||||||
|
@ -49,7 +49,6 @@
|
|||||||
DxeServicesTableLib
|
DxeServicesTableLib
|
||||||
HobLib
|
HobLib
|
||||||
MemoryAllocationLib
|
MemoryAllocationLib
|
||||||
PeCoffGetEntryPointLib
|
|
||||||
UefiDriverEntryPoint
|
UefiDriverEntryPoint
|
||||||
UefiLib
|
UefiLib
|
||||||
|
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
|
|
||||||
#include <Library/ArmSvcLib.h>
|
#include <Library/ArmSvcLib.h>
|
||||||
#include <Library/ArmFfaLib.h>
|
#include <Library/ArmFfaLib.h>
|
||||||
#include <Library/PeCoffLib.h>
|
#include <Library/UefiImageLib.h>
|
||||||
#include <Library/FvLib.h>
|
#include <Library/FvLib.h>
|
||||||
|
|
||||||
#define CPU_INFO_FLAG_PRIMARY_CPU 0x00000001
|
#define CPU_INFO_FLAG_PRIMARY_CPU 0x00000001
|
||||||
@ -157,56 +157,6 @@ typedef RETURN_STATUS (*REGION_PERMISSION_UPDATE_FUNC) (
|
|||||||
IN UINT64 Length
|
IN UINT64 Length
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
|
||||||
Privileged firmware assigns RO & Executable attributes to all memory occupied
|
|
||||||
by the Boot Firmware Volume. This function sets the correct permissions of
|
|
||||||
sections in the Standalone MM Core module to be able to access RO and RW data
|
|
||||||
and make further progress in the boot process.
|
|
||||||
|
|
||||||
@param [in] ImageContext Pointer to PE/COFF image context
|
|
||||||
@param [in] ImageBase Base of image in memory
|
|
||||||
@param [in] SectionHeaderOffset Offset of PE/COFF image section header
|
|
||||||
@param [in] NumberOfSections Number of Sections
|
|
||||||
@param [in] TextUpdater Function to change code permissions
|
|
||||||
@param [in] ReadOnlyUpdater Function to change RO permissions
|
|
||||||
@param [in] ReadWriteUpdater Function to change RW permissions
|
|
||||||
|
|
||||||
**/
|
|
||||||
EFI_STATUS
|
|
||||||
EFIAPI
|
|
||||||
UpdateMmFoundationPeCoffPermissions (
|
|
||||||
IN CONST PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext,
|
|
||||||
IN EFI_PHYSICAL_ADDRESS ImageBase,
|
|
||||||
IN UINT32 SectionHeaderOffset,
|
|
||||||
IN CONST UINT16 NumberOfSections,
|
|
||||||
IN REGION_PERMISSION_UPDATE_FUNC TextUpdater,
|
|
||||||
IN REGION_PERMISSION_UPDATE_FUNC ReadOnlyUpdater,
|
|
||||||
IN REGION_PERMISSION_UPDATE_FUNC ReadWriteUpdater
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Privileged firmware assigns RO & Executable attributes to all memory occupied
|
|
||||||
by the Boot Firmware Volume. This function locates the section information of
|
|
||||||
the Standalone MM Core module to be able to change permissions of the
|
|
||||||
individual sections later in the boot process.
|
|
||||||
|
|
||||||
@param [in] TeData Pointer to PE/COFF image data
|
|
||||||
@param [in, out] ImageContext Pointer to PE/COFF image context
|
|
||||||
@param [out] ImageBase Pointer to ImageBase variable
|
|
||||||
@param [in, out] SectionHeaderOffset Offset of PE/COFF image section header
|
|
||||||
@param [in, out] NumberOfSections Number of Sections
|
|
||||||
|
|
||||||
**/
|
|
||||||
EFI_STATUS
|
|
||||||
EFIAPI
|
|
||||||
GetStandaloneMmCorePeCoffSections (
|
|
||||||
IN VOID *TeData,
|
|
||||||
IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext,
|
|
||||||
OUT EFI_PHYSICAL_ADDRESS *ImageBase,
|
|
||||||
IN OUT UINT32 *SectionHeaderOffset,
|
|
||||||
IN OUT UINT16 *NumberOfSections
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Privileged firmware assigns RO & Executable attributes to all memory occupied
|
Privileged firmware assigns RO & Executable attributes to all memory occupied
|
||||||
by the Boot Firmware Volume. This function locates the Standalone MM Core
|
by the Boot Firmware Volume. This function locates the Standalone MM Core
|
||||||
@ -220,10 +170,10 @@ GetStandaloneMmCorePeCoffSections (
|
|||||||
**/
|
**/
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
EFIAPI
|
EFIAPI
|
||||||
LocateStandaloneMmCorePeCoffData (
|
LocateStandaloneMmCoreUefiImage (
|
||||||
IN EFI_FIRMWARE_VOLUME_HEADER *BfvAddress,
|
IN EFI_FIRMWARE_VOLUME_HEADER *BfvAddress,
|
||||||
IN OUT VOID **TeData,
|
IN OUT VOID **TeData,
|
||||||
IN OUT UINTN *TeDataSize
|
IN OUT UINT32 *TeDataSize
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -37,6 +37,7 @@
|
|||||||
#include <Library/SerialPortLib.h>
|
#include <Library/SerialPortLib.h>
|
||||||
#include <Library/StandaloneMmMmuLib.h>
|
#include <Library/StandaloneMmMmuLib.h>
|
||||||
#include <Library/PcdLib.h>
|
#include <Library/PcdLib.h>
|
||||||
|
#include <Library/MemoryAllocationLib.h>
|
||||||
|
|
||||||
#include <IndustryStandard/ArmStdSmc.h>
|
#include <IndustryStandard/ArmStdSmc.h>
|
||||||
#include <IndustryStandard/ArmMmSvc.h>
|
#include <IndustryStandard/ArmMmSvc.h>
|
||||||
@ -1010,13 +1011,12 @@ CEntryPoint (
|
|||||||
PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;
|
PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;
|
||||||
ARM_SVC_ARGS EventCompleteSvcArgs;
|
ARM_SVC_ARGS EventCompleteSvcArgs;
|
||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
UINT32 SectionHeaderOffset;
|
|
||||||
UINT16 NumberOfSections;
|
|
||||||
COMM_PROTOCOL CommProtocol;
|
COMM_PROTOCOL CommProtocol;
|
||||||
VOID *HobStart;
|
VOID *HobStart;
|
||||||
VOID *TeData;
|
VOID *TeData;
|
||||||
UINTN TeDataSize;
|
UINT32 TeDataSize;
|
||||||
EFI_PHYSICAL_ADDRESS ImageBase;
|
UINT32 SectionIndex;
|
||||||
|
UEFI_IMAGE_RECORD *ImageRecord;
|
||||||
EDKII_PI_MM_CPU_DRIVER_EP_PROTOCOL *PiMmCpuDriverEpProtocol;
|
EDKII_PI_MM_CPU_DRIVER_EP_PROTOCOL *PiMmCpuDriverEpProtocol;
|
||||||
EDKII_PI_MM_CPU_DRIVER_ENTRYPOINT CpuDriverEntryPoint;
|
EDKII_PI_MM_CPU_DRIVER_ENTRYPOINT CpuDriverEntryPoint;
|
||||||
EFI_HOB_FIRMWARE_VOLUME *FvHob;
|
EFI_HOB_FIRMWARE_VOLUME *FvHob;
|
||||||
@ -1051,7 +1051,7 @@ CEntryPoint (
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Locate PE/COFF File information for the Standalone MM core module
|
// Locate PE/COFF File information for the Standalone MM core module
|
||||||
Status = LocateStandaloneMmCorePeCoffData (
|
Status = LocateStandaloneMmCoreUefiImage (
|
||||||
(EFI_FIRMWARE_VOLUME_HEADER *)(UINTN)FvHob->BaseAddress,
|
(EFI_FIRMWARE_VOLUME_HEADER *)(UINTN)FvHob->BaseAddress,
|
||||||
&TeData,
|
&TeData,
|
||||||
&TeDataSize
|
&TeDataSize
|
||||||
@ -1061,53 +1061,46 @@ CEntryPoint (
|
|||||||
goto finish;
|
goto finish;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DEBUG ((DEBUG_INFO, "Found Standalone MM PE data - 0x%x\n", TeData));
|
||||||
|
|
||||||
// Obtain the PE/COFF Section information for the Standalone MM core module
|
// Obtain the PE/COFF Section information for the Standalone MM core module
|
||||||
Status = GetStandaloneMmCorePeCoffSections (
|
Status = UefiImageInitializeContext (&ImageContext, TeData, TeDataSize);
|
||||||
TeData,
|
|
||||||
&ImageContext,
|
|
||||||
&ImageBase,
|
|
||||||
&SectionHeaderOffset,
|
|
||||||
&NumberOfSections
|
|
||||||
);
|
|
||||||
|
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
|
DEBUG ((DEBUG_ERROR, "Unable to locate Standalone MM Core PE-COFF Section information - %r\n", Status));
|
||||||
goto finish;
|
goto finish;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
ImageRecord = UefiImageLoaderGetImageRecord (&ImageContext);
|
||||||
// ImageBase may deviate from ImageContext.ImageAddress if we are dealing
|
|
||||||
// with a TE image, in which case the latter points to the actual offset
|
|
||||||
// of the image, whereas ImageBase refers to the address where the image
|
|
||||||
// would start if the stripped PE headers were still in place. In either
|
|
||||||
// case, we need to fix up ImageBase so it refers to the actual current
|
|
||||||
// load address.
|
|
||||||
//
|
|
||||||
ImageBase += (UINTN)TeData - ImageContext.ImageAddress;
|
|
||||||
|
|
||||||
// Update the memory access permissions of individual sections in the
|
if (ImageRecord == NULL) {
|
||||||
// Standalone MM core module
|
|
||||||
Status = UpdateMmFoundationPeCoffPermissions (
|
|
||||||
&ImageContext,
|
|
||||||
ImageBase,
|
|
||||||
SectionHeaderOffset,
|
|
||||||
NumberOfSections,
|
|
||||||
ArmSetMemoryRegionNoExec,
|
|
||||||
ArmSetMemoryRegionReadOnly,
|
|
||||||
ArmClearMemoryRegionReadOnly
|
|
||||||
);
|
|
||||||
if (EFI_ERROR (Status)) {
|
|
||||||
goto finish;
|
goto finish;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ImageContext.ImageAddress != (UINTN)TeData) {
|
UINT32 Address = 0;
|
||||||
ImageContext.ImageAddress = (UINTN)TeData;
|
for (SectionIndex = 0; SectionIndex < ImageRecord->NumSegments; ++ SectionIndex) {
|
||||||
ArmSetMemoryRegionNoExec (ImageBase, SIZE_4KB);
|
if ((ImageRecord->Segments[SectionIndex].Attributes & EFI_MEMORY_XP) != 0) {
|
||||||
ArmClearMemoryRegionReadOnly (ImageBase, SIZE_4KB);
|
ArmSetMemoryRegionNoExec (
|
||||||
|
Address,
|
||||||
|
ImageRecord->Segments[SectionIndex].Size
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
Status = PeCoffLoaderRelocateImage (&ImageContext);
|
if ((ImageRecord->Segments[SectionIndex].Attributes & EFI_MEMORY_RO) == 0) {
|
||||||
ASSERT_EFI_ERROR (Status);
|
ArmClearMemoryRegionReadOnly (
|
||||||
|
Address,
|
||||||
|
ImageRecord->Segments[SectionIndex].Size
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Address += ImageRecord->Segments[SectionIndex].Size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FreePool (ImageRecord);
|
||||||
|
|
||||||
|
// FIXME: Should relocation not be performed with all of the Image writable?
|
||||||
|
Status = UefiImageRelocateImageInplaceForExecution (&ImageContext);
|
||||||
|
ASSERT_EFI_ERROR (Status);
|
||||||
|
|
||||||
// Set the gHobList to point to the HOB list passed by TF-A.
|
// Set the gHobList to point to the HOB list passed by TF-A.
|
||||||
// This will be used by StandaloneMmCoreHobLib in early stage.
|
// This will be used by StandaloneMmCoreHobLib in early stage.
|
||||||
gHobList = HobStart;
|
gHobList = HobStart;
|
||||||
|
@ -63,11 +63,9 @@
|
|||||||
gArmTokenSpaceGuid.PcdStMmStackSize
|
gArmTokenSpaceGuid.PcdStMmStackSize
|
||||||
|
|
||||||
#
|
#
|
||||||
# This configuration fails for CLANGPDB, which does not support PIE in the GCC
|
# This configuration fails for CLANGDPB, which does not support PIE in the GCC
|
||||||
# sense. Such however is required for ARM family StandaloneMmCore
|
# sense. Such however is required for AArch64 StandaloneMmCore self-relocation,
|
||||||
# self-relocation, and thus the CLANGPDB toolchain is unsupported for ARM and
|
# and thus the CLANGPDB toolchain is unsupported for AArch64 for this module.
|
||||||
# AARCH64 for this module.
|
|
||||||
#
|
#
|
||||||
[BuildOptions]
|
[BuildOptions]
|
||||||
GCC:*_*_ARM_CC_FLAGS = -fpie
|
|
||||||
GCC:*_*_AARCH64_CC_FLAGS = -fpie
|
GCC:*_*_AARCH64_CC_FLAGS = -fpie
|
||||||
|
@ -24,162 +24,23 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
|
|||||||
|
|
||||||
#include <IndustryStandard/ArmStdSmc.h>
|
#include <IndustryStandard/ArmStdSmc.h>
|
||||||
|
|
||||||
/**
|
|
||||||
Privileged firmware assigns RO & Executable attributes to all memory occupied
|
|
||||||
by the Boot Firmware Volume. This function sets the correct permissions of
|
|
||||||
sections in the Standalone MM Core module to be able to access RO and RW data
|
|
||||||
and make further progress in the boot process.
|
|
||||||
|
|
||||||
@param [in] ImageContext Pointer to PE/COFF image context
|
|
||||||
@param [in] ImageBase Base of image in memory
|
|
||||||
@param [in] SectionHeaderOffset Offset of PE/COFF image section header
|
|
||||||
@param [in] NumberOfSections Number of Sections
|
|
||||||
@param [in] TextUpdater Function to change code permissions
|
|
||||||
@param [in] ReadOnlyUpdater Function to change RO permissions
|
|
||||||
@param [in] ReadWriteUpdater Function to change RW permissions
|
|
||||||
|
|
||||||
**/
|
|
||||||
EFI_STATUS
|
|
||||||
EFIAPI
|
|
||||||
UpdateMmFoundationPeCoffPermissions (
|
|
||||||
IN CONST PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext,
|
|
||||||
IN EFI_PHYSICAL_ADDRESS ImageBase,
|
|
||||||
IN UINT32 SectionHeaderOffset,
|
|
||||||
IN CONST UINT16 NumberOfSections,
|
|
||||||
IN REGION_PERMISSION_UPDATE_FUNC TextUpdater,
|
|
||||||
IN REGION_PERMISSION_UPDATE_FUNC ReadOnlyUpdater,
|
|
||||||
IN REGION_PERMISSION_UPDATE_FUNC ReadWriteUpdater
|
|
||||||
)
|
|
||||||
{
|
|
||||||
EFI_IMAGE_SECTION_HEADER SectionHeader;
|
|
||||||
RETURN_STATUS Status;
|
|
||||||
EFI_PHYSICAL_ADDRESS Base;
|
|
||||||
UINTN Size;
|
|
||||||
UINTN ReadSize;
|
|
||||||
UINTN Index;
|
|
||||||
|
|
||||||
ASSERT (ImageContext != NULL);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Iterate over the sections
|
|
||||||
//
|
|
||||||
for (Index = 0; Index < NumberOfSections; Index++) {
|
|
||||||
//
|
|
||||||
// Read section header from file
|
|
||||||
//
|
|
||||||
Size = sizeof (EFI_IMAGE_SECTION_HEADER);
|
|
||||||
ReadSize = Size;
|
|
||||||
Status = ImageContext->ImageRead (
|
|
||||||
ImageContext->Handle,
|
|
||||||
SectionHeaderOffset,
|
|
||||||
&Size,
|
|
||||||
&SectionHeader
|
|
||||||
);
|
|
||||||
|
|
||||||
if (RETURN_ERROR (Status) || (Size != ReadSize)) {
|
|
||||||
DEBUG ((
|
|
||||||
DEBUG_ERROR,
|
|
||||||
"%a: ImageContext->ImageRead () failed (Status = %r)\n",
|
|
||||||
__func__,
|
|
||||||
Status
|
|
||||||
));
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
DEBUG ((
|
|
||||||
DEBUG_INFO,
|
|
||||||
"%a: Section %d of image at 0x%lx has 0x%x permissions\n",
|
|
||||||
__func__,
|
|
||||||
Index,
|
|
||||||
ImageContext->ImageAddress,
|
|
||||||
SectionHeader.Characteristics
|
|
||||||
));
|
|
||||||
DEBUG ((
|
|
||||||
DEBUG_INFO,
|
|
||||||
"%a: Section %d of image at 0x%lx has %a name\n",
|
|
||||||
__func__,
|
|
||||||
Index,
|
|
||||||
ImageContext->ImageAddress,
|
|
||||||
SectionHeader.Name
|
|
||||||
));
|
|
||||||
DEBUG ((
|
|
||||||
DEBUG_INFO,
|
|
||||||
"%a: Section %d of image at 0x%lx has 0x%x address\n",
|
|
||||||
__func__,
|
|
||||||
Index,
|
|
||||||
ImageContext->ImageAddress,
|
|
||||||
ImageContext->ImageAddress + SectionHeader.VirtualAddress
|
|
||||||
));
|
|
||||||
DEBUG ((
|
|
||||||
DEBUG_INFO,
|
|
||||||
"%a: Section %d of image at 0x%lx has 0x%x data\n",
|
|
||||||
__func__,
|
|
||||||
Index,
|
|
||||||
ImageContext->ImageAddress,
|
|
||||||
SectionHeader.PointerToRawData
|
|
||||||
));
|
|
||||||
|
|
||||||
//
|
|
||||||
// If the section is marked as XN then remove the X attribute. Furthermore,
|
|
||||||
// if it is a writeable section then mark it appropriately as well.
|
|
||||||
//
|
|
||||||
if ((SectionHeader.Characteristics & EFI_IMAGE_SCN_MEM_EXECUTE) == 0) {
|
|
||||||
Base = ImageBase + SectionHeader.VirtualAddress;
|
|
||||||
|
|
||||||
TextUpdater (Base, SectionHeader.Misc.VirtualSize);
|
|
||||||
|
|
||||||
if ((SectionHeader.Characteristics & EFI_IMAGE_SCN_MEM_WRITE) != 0) {
|
|
||||||
ReadWriteUpdater (Base, SectionHeader.Misc.VirtualSize);
|
|
||||||
DEBUG ((
|
|
||||||
DEBUG_INFO,
|
|
||||||
"%a: Mapping section %d of image at 0x%lx with RW-XN permissions\n",
|
|
||||||
__func__,
|
|
||||||
Index,
|
|
||||||
ImageContext->ImageAddress
|
|
||||||
));
|
|
||||||
} else {
|
|
||||||
DEBUG ((
|
|
||||||
DEBUG_INFO,
|
|
||||||
"%a: Mapping section %d of image at 0x%lx with RO-XN permissions\n",
|
|
||||||
__func__,
|
|
||||||
Index,
|
|
||||||
ImageContext->ImageAddress
|
|
||||||
));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
DEBUG ((
|
|
||||||
DEBUG_INFO,
|
|
||||||
"%a: Ignoring section %d of image at 0x%lx with 0x%x permissions\n",
|
|
||||||
__func__,
|
|
||||||
Index,
|
|
||||||
ImageContext->ImageAddress,
|
|
||||||
SectionHeader.Characteristics
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
SectionHeaderOffset += sizeof (EFI_IMAGE_SECTION_HEADER);
|
|
||||||
}
|
|
||||||
|
|
||||||
return RETURN_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Privileged firmware assigns RO & Executable attributes to all memory occupied
|
Privileged firmware assigns RO & Executable attributes to all memory occupied
|
||||||
by the Boot Firmware Volume. This function locates the Standalone MM Core
|
by the Boot Firmware Volume. This function locates the Standalone MM Core
|
||||||
module PE/COFF image in the BFV and returns this information.
|
module PE/COFF image in the BFV and returns this information.
|
||||||
|
|
||||||
@param [in] BfvAddress Base Address of Boot Firmware Volume
|
@param [in] BfvAddress Base Address of Boot Firmware Volume
|
||||||
@param [in, out] TeData Pointer to address for allocating memory
|
@param [in, out] UefiImage Pointer to address for allocating memory
|
||||||
for PE/COFF image data
|
for PE/COFF image data
|
||||||
@param [in, out] TeDataSize Pointer to size of PE/COFF image data
|
@param [in, out] UefiImageSize Pointer to size of PE/COFF image data
|
||||||
|
|
||||||
**/
|
**/
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
EFIAPI
|
EFIAPI
|
||||||
LocateStandaloneMmCorePeCoffData (
|
LocateStandaloneMmCoreUefiImage (
|
||||||
IN EFI_FIRMWARE_VOLUME_HEADER *BfvAddress,
|
IN EFI_FIRMWARE_VOLUME_HEADER *BfvAddress,
|
||||||
IN OUT VOID **TeData,
|
IN OUT VOID **UefiImage,
|
||||||
IN OUT UINTN *TeDataSize
|
IN OUT UINT32 *UefiImageSize
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
EFI_FFS_FILE_HEADER *FileHeader;
|
EFI_FFS_FILE_HEADER *FileHeader;
|
||||||
@ -201,9 +62,9 @@ LocateStandaloneMmCorePeCoffData (
|
|||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
Status = FfsFindSectionData (EFI_SECTION_PE32, FileHeader, TeData, TeDataSize);
|
Status = FfsFindSectionData (EFI_SECTION_PE32, FileHeader, UefiImage, UefiImageSize);
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
Status = FfsFindSectionData (EFI_SECTION_TE, FileHeader, TeData, TeDataSize);
|
Status = FfsFindSectionData (EFI_SECTION_TE, FileHeader, UefiImage, UefiImageSize);
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
DEBUG ((
|
DEBUG ((
|
||||||
DEBUG_ERROR,
|
DEBUG_ERROR,
|
||||||
@ -214,170 +75,6 @@ LocateStandaloneMmCorePeCoffData (
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DEBUG ((DEBUG_INFO, "Found Standalone MM PE data - 0x%x\n", *TeData));
|
DEBUG ((DEBUG_INFO, "Found Standalone MM PE data - 0x%x\n", *UefiImage));
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
Returns the PC COFF section information.
|
|
||||||
|
|
||||||
@param [in, out] ImageContext Pointer to PE/COFF image context
|
|
||||||
@param [out] ImageBase Base of image in memory
|
|
||||||
@param [out] SectionHeaderOffset Offset of PE/COFF image section header
|
|
||||||
@param [out] NumberOfSections Number of Sections
|
|
||||||
|
|
||||||
**/
|
|
||||||
STATIC
|
|
||||||
EFI_STATUS
|
|
||||||
GetPeCoffSectionInformation (
|
|
||||||
IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext,
|
|
||||||
OUT EFI_PHYSICAL_ADDRESS *ImageBase,
|
|
||||||
OUT UINT32 *SectionHeaderOffset,
|
|
||||||
OUT UINT16 *NumberOfSections
|
|
||||||
)
|
|
||||||
{
|
|
||||||
RETURN_STATUS Status;
|
|
||||||
EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr;
|
|
||||||
EFI_IMAGE_OPTIONAL_HEADER_UNION HdrData;
|
|
||||||
UINTN Size;
|
|
||||||
UINTN ReadSize;
|
|
||||||
|
|
||||||
ASSERT (ImageContext != NULL);
|
|
||||||
ASSERT (SectionHeaderOffset != NULL);
|
|
||||||
ASSERT (NumberOfSections != NULL);
|
|
||||||
|
|
||||||
Status = PeCoffLoaderGetImageInfo (ImageContext);
|
|
||||||
if (RETURN_ERROR (Status)) {
|
|
||||||
DEBUG ((
|
|
||||||
DEBUG_ERROR,
|
|
||||||
"%a: PeCoffLoaderGetImageInfo () failed (Status == %r)\n",
|
|
||||||
__func__,
|
|
||||||
Status
|
|
||||||
));
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ImageContext->SectionAlignment < EFI_PAGE_SIZE) {
|
|
||||||
//
|
|
||||||
// The sections need to be at least 4 KB aligned, since that is the
|
|
||||||
// granularity at which we can tighten permissions.
|
|
||||||
//
|
|
||||||
if (!ImageContext->IsTeImage) {
|
|
||||||
DEBUG ((
|
|
||||||
DEBUG_WARN,
|
|
||||||
"%a: non-TE Image at 0x%lx has SectionAlignment < 4 KB (%lu)\n",
|
|
||||||
__func__,
|
|
||||||
ImageContext->ImageAddress,
|
|
||||||
ImageContext->SectionAlignment
|
|
||||||
));
|
|
||||||
return RETURN_UNSUPPORTED;
|
|
||||||
}
|
|
||||||
|
|
||||||
ImageContext->SectionAlignment = EFI_PAGE_SIZE;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Read the PE/COFF Header. For PE32 (32-bit) this will read in too much
|
|
||||||
// data, but that should not hurt anything. Hdr.Pe32->OptionalHeader.Magic
|
|
||||||
// determines if this is a PE32 or PE32+ image. The magic is in the same
|
|
||||||
// location in both images.
|
|
||||||
//
|
|
||||||
Hdr.Union = &HdrData;
|
|
||||||
Size = sizeof (EFI_IMAGE_OPTIONAL_HEADER_UNION);
|
|
||||||
ReadSize = Size;
|
|
||||||
Status = ImageContext->ImageRead (
|
|
||||||
ImageContext->Handle,
|
|
||||||
ImageContext->PeCoffHeaderOffset,
|
|
||||||
&Size,
|
|
||||||
Hdr.Pe32
|
|
||||||
);
|
|
||||||
|
|
||||||
if (RETURN_ERROR (Status) || (Size != ReadSize)) {
|
|
||||||
DEBUG ((
|
|
||||||
DEBUG_ERROR,
|
|
||||||
"%a: TmpContext->ImageRead () failed (Status = %r)\n",
|
|
||||||
__func__,
|
|
||||||
Status
|
|
||||||
));
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
*ImageBase = ImageContext->ImageAddress;
|
|
||||||
if (!ImageContext->IsTeImage) {
|
|
||||||
ASSERT (Hdr.Pe32->Signature == EFI_IMAGE_NT_SIGNATURE);
|
|
||||||
|
|
||||||
*SectionHeaderOffset = ImageContext->PeCoffHeaderOffset + sizeof (UINT32) +
|
|
||||||
sizeof (EFI_IMAGE_FILE_HEADER);
|
|
||||||
*NumberOfSections = Hdr.Pe32->FileHeader.NumberOfSections;
|
|
||||||
|
|
||||||
switch (Hdr.Pe32->OptionalHeader.Magic) {
|
|
||||||
case EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC:
|
|
||||||
*SectionHeaderOffset += Hdr.Pe32->FileHeader.SizeOfOptionalHeader;
|
|
||||||
break;
|
|
||||||
case EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC:
|
|
||||||
*SectionHeaderOffset += Hdr.Pe32Plus->FileHeader.SizeOfOptionalHeader;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
ASSERT (FALSE);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
*SectionHeaderOffset = (UINTN)(sizeof (EFI_TE_IMAGE_HEADER));
|
|
||||||
*NumberOfSections = Hdr.Te->NumberOfSections;
|
|
||||||
*ImageBase -= (UINT32)Hdr.Te->StrippedSize - sizeof (EFI_TE_IMAGE_HEADER);
|
|
||||||
}
|
|
||||||
|
|
||||||
return RETURN_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
Privileged firmware assigns RO & Executable attributes to all memory occupied
|
|
||||||
by the Boot Firmware Volume. This function locates the section information of
|
|
||||||
the Standalone MM Core module to be able to change permissions of the
|
|
||||||
individual sections later in the boot process.
|
|
||||||
|
|
||||||
@param [in] TeData Pointer to PE/COFF image data
|
|
||||||
@param [in, out] ImageContext Pointer to PE/COFF image context
|
|
||||||
@param [out] ImageBase Pointer to ImageBase variable
|
|
||||||
@param [in, out] SectionHeaderOffset Offset of PE/COFF image section header
|
|
||||||
@param [in, out] NumberOfSections Number of Sections
|
|
||||||
|
|
||||||
**/
|
|
||||||
EFI_STATUS
|
|
||||||
EFIAPI
|
|
||||||
GetStandaloneMmCorePeCoffSections (
|
|
||||||
IN VOID *TeData,
|
|
||||||
IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext,
|
|
||||||
OUT EFI_PHYSICAL_ADDRESS *ImageBase,
|
|
||||||
IN OUT UINT32 *SectionHeaderOffset,
|
|
||||||
IN OUT UINT16 *NumberOfSections
|
|
||||||
)
|
|
||||||
{
|
|
||||||
EFI_STATUS Status;
|
|
||||||
|
|
||||||
// Initialize the Image Context
|
|
||||||
ZeroMem (ImageContext, sizeof (PE_COFF_LOADER_IMAGE_CONTEXT));
|
|
||||||
ImageContext->Handle = TeData;
|
|
||||||
ImageContext->ImageRead = PeCoffLoaderImageReadFromMemory;
|
|
||||||
|
|
||||||
DEBUG ((DEBUG_INFO, "Found Standalone MM PE data - 0x%x\n", TeData));
|
|
||||||
|
|
||||||
Status = GetPeCoffSectionInformation (
|
|
||||||
ImageContext,
|
|
||||||
ImageBase,
|
|
||||||
SectionHeaderOffset,
|
|
||||||
NumberOfSections
|
|
||||||
);
|
|
||||||
if (EFI_ERROR (Status)) {
|
|
||||||
DEBUG ((DEBUG_ERROR, "Unable to locate Standalone MM Core PE-COFF Section information - %r\n", Status));
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
DEBUG ((
|
|
||||||
DEBUG_INFO,
|
|
||||||
"Standalone MM Core PE-COFF SectionHeaderOffset - 0x%x, NumberOfSections - %d\n",
|
|
||||||
*SectionHeaderOffset,
|
|
||||||
*NumberOfSections
|
|
||||||
));
|
|
||||||
|
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
SectionSize = *(UINT32 *)(FfsHeader->Size) & 0x00FFFFFF;
|
SectionLength = 0;
|
||||||
SectionSize -= sizeof (EFI_FFS_FILE_HEADER);
|
SectionSize = *(UINT32 *)(FfsHeader->Size) & 0x00FFFFFF;
|
||||||
ParsedLength = 0;
|
SectionSize -= sizeof (EFI_FFS_FILE_HEADER);
|
||||||
EfiImage = NULL;
|
ParsedLength = 0;
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -24,8 +24,8 @@
|
|||||||
[LibraryClasses]
|
[LibraryClasses]
|
||||||
DebugLib
|
DebugLib
|
||||||
PcdLib
|
PcdLib
|
||||||
PeCoffExtraActionLib
|
UefiImageExtraActionLib
|
||||||
PeCoffLib
|
UefiImageLib
|
||||||
|
|
||||||
[Pcd]
|
[Pcd]
|
||||||
gArmTokenSpaceGuid.PcdSecureFvBaseAddress
|
gArmTokenSpaceGuid.PcdSecureFvBaseAddress
|
||||||
|
@ -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)));
|
||||||
|
}
|
||||||
|
}
|
@ -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
|
@ -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/SerialPortLib.h>
|
#include <Library/SerialPortLib.h>
|
||||||
#include <Library/UefiBootServicesTableLib.h>
|
#include <Library/UefiBootServicesTableLib.h>
|
||||||
@ -36,11 +35,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
|
||||||
@ -211,14 +209,13 @@ DefaultExceptionHandler (
|
|||||||
UnicodeSPrintAsciiFormat (UnicodeBuffer, MAX_PRINT_CHARS, Buffer);
|
UnicodeSPrintAsciiFormat (UnicodeBuffer, MAX_PRINT_CHARS, Buffer);
|
||||||
|
|
||||||
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,
|
||||||
@ -243,7 +240,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++;
|
||||||
@ -264,14 +261,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;
|
||||||
|
@ -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/SerialPortLib.h>
|
#include <Library/SerialPortLib.h>
|
||||||
#include <Library/UefiBootServicesTableLib.h>
|
#include <Library/UefiBootServicesTableLib.h>
|
||||||
@ -53,11 +52,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
|
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -225,16 +223,16 @@ DefaultExceptionHandler (
|
|||||||
UnicodeSPrintAsciiFormat (UnicodeBuffer, MAX_PRINT_CHARS, Buffer);
|
UnicodeSPrintAsciiFormat (UnicodeBuffer, MAX_PRINT_CHARS, Buffer);
|
||||||
|
|
||||||
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];
|
// that is a 3 char string
|
||||||
|
|
||||||
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 +245,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));
|
||||||
}
|
}
|
||||||
|
|
||||||
DEBUG_CODE_END ();
|
DEBUG_CODE_END ();
|
||||||
|
@ -34,7 +34,6 @@
|
|||||||
BaseLib
|
BaseLib
|
||||||
PrintLib
|
PrintLib
|
||||||
DebugLib
|
DebugLib
|
||||||
PeCoffGetEntryPointLib
|
|
||||||
SerialPortLib
|
SerialPortLib
|
||||||
UefiBootServicesTableLib
|
UefiBootServicesTableLib
|
||||||
|
|
||||||
|
@ -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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -52,8 +52,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
|
||||||
|
@ -61,8 +61,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
|
||||||
@ -125,8 +125,8 @@
|
|||||||
SerialPortLib|ArmVirtPkg/Library/FdtPL011SerialPortLib/FdtPL011SerialPortLib.inf
|
SerialPortLib|ArmVirtPkg/Library/FdtPL011SerialPortLib/FdtPL011SerialPortLib.inf
|
||||||
FdtSerialPortAddressLib|OvmfPkg/Library/FdtSerialPortAddressLib/FdtSerialPortAddressLib.inf
|
FdtSerialPortAddressLib|OvmfPkg/Library/FdtSerialPortAddressLib/FdtSerialPortAddressLib.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
|
||||||
@ -205,7 +205,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
|
||||||
@ -223,7 +222,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
|
||||||
|
@ -149,9 +149,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
|
||||||
|
@ -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
|
||||||
|
@ -46,7 +46,7 @@
|
|||||||
TimerLib
|
TimerLib
|
||||||
SerialPortLib
|
SerialPortLib
|
||||||
ExtractGuidedSectionLib
|
ExtractGuidedSectionLib
|
||||||
PeCoffLib
|
UefiImageLib
|
||||||
PrePiLib
|
PrePiLib
|
||||||
MemoryAllocationLib
|
MemoryAllocationLib
|
||||||
HobLib
|
HobLib
|
||||||
|
33
ArmVirtPkg/PrePi/PrePi.c
Executable file → Normal file
33
ArmVirtPkg/PrePi/PrePi.c
Executable file → Normal 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>
|
||||||
@ -129,15 +129,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 (
|
||||||
@ -147,21 +147,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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -54,6 +54,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)
|
||||||
*/
|
*/
|
||||||
@ -1308,11 +1312,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
|
||||||
//
|
//
|
||||||
@ -1354,11 +1364,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
|
||||||
//
|
//
|
||||||
@ -3456,11 +3472,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
|
||||||
)
|
)
|
||||||
@ -3533,13 +3647,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:
|
||||||
@ -3551,7 +3664,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.
|
||||||
@ -3561,7 +3674,7 @@ Returns:
|
|||||||
return EFI_SUCCESS;
|
return EFI_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
FfsHeaderSize = GetFfsHeaderLength(FfsFile);
|
FfsHeaderSize = GetFfsHeaderLength(*FfsFile);
|
||||||
//
|
//
|
||||||
// Rebase each PE32 section
|
// Rebase each PE32 section
|
||||||
//
|
//
|
||||||
@ -3575,7 +3688,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;
|
||||||
}
|
}
|
||||||
@ -3624,7 +3737,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:
|
||||||
@ -3702,7 +3815,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:
|
||||||
@ -3717,7 +3830,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:
|
||||||
@ -3741,15 +3854,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);
|
||||||
@ -3757,7 +3883,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);
|
||||||
@ -3807,15 +3934,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;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
@ -3829,14 +3956,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
|
||||||
@ -3853,7 +3980,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;
|
||||||
}
|
}
|
||||||
@ -3901,7 +4028,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.
|
||||||
@ -4044,15 +4171,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
|
||||||
@ -4068,7 +4195,7 @@ Returns:
|
|||||||
WriteMapFile (
|
WriteMapFile (
|
||||||
FvMapFile,
|
FvMapFile,
|
||||||
PdbPointer,
|
PdbPointer,
|
||||||
FfsFile,
|
*FfsFile,
|
||||||
NewPe32BaseAddress,
|
NewPe32BaseAddress,
|
||||||
&OrigImageContext
|
&OrigImageContext
|
||||||
);
|
);
|
||||||
|
@ -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
|
||||||
);
|
);
|
||||||
|
@ -72,6 +72,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
|
||||||
@ -706,7 +724,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
|
||||||
#
|
#
|
||||||
@ -1520,12 +1538,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.
|
||||||
#
|
#
|
||||||
|
@ -81,7 +81,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}}
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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,
|
||||||
|
@ -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[];
|
||||||
|
|
||||||
|
@ -71,6 +71,7 @@ EFI_STATUS
|
|||||||
@param FileHeader A pointer to the file header that contains the set of sections to
|
@param FileHeader A pointer to the file header that contains the set of sections to
|
||||||
be searched.
|
be searched.
|
||||||
@param SectionData A pointer to the discovered section, if successful.
|
@param SectionData A pointer to the discovered section, if successful.
|
||||||
|
@param SectionSize A pointer to the size of the discovered section, if successful.
|
||||||
|
|
||||||
@retval EFI_SUCCESS The section was found.
|
@retval EFI_SUCCESS The section was found.
|
||||||
@retval EFI_NOT_FOUND The section was not found.
|
@retval EFI_NOT_FOUND The section was not found.
|
||||||
@ -82,7 +83,8 @@ FfsFindSectionDataWithHook (
|
|||||||
IN EFI_SECTION_TYPE SectionType,
|
IN EFI_SECTION_TYPE SectionType,
|
||||||
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
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -92,6 +94,7 @@ FfsFindSectionDataWithHook (
|
|||||||
@param FileHandle A pointer to the file header that contains the set of sections to
|
@param FileHandle A pointer to the file header that contains the set of sections to
|
||||||
be searched.
|
be searched.
|
||||||
@param SectionData A pointer to the discovered section, if successful.
|
@param SectionData A pointer to the discovered section, if successful.
|
||||||
|
@param SectionSize A pointer to the size of the discovered section, if successful.
|
||||||
|
|
||||||
@retval EFI_SUCCESS The section was found.
|
@retval EFI_SUCCESS The section was found.
|
||||||
@retval EFI_NOT_FOUND The section was not found.
|
@retval EFI_NOT_FOUND The section was not found.
|
||||||
@ -102,7 +105,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 +679,7 @@ BuildExtractSectionHob (
|
|||||||
|
|
||||||
VOID
|
VOID
|
||||||
EFIAPI
|
EFIAPI
|
||||||
BuildPeCoffLoaderHob (
|
BuildUefiLoaderHob (
|
||||||
VOID
|
VOID
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -760,10 +764,11 @@ 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 UINT32 *ImageSize,
|
||||||
OUT EFI_PHYSICAL_ADDRESS *EntryPoint
|
OUT EFI_PHYSICAL_ADDRESS *EntryPoint
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -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>
|
||||||
@ -821,27 +820,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 (
|
||||||
|
@ -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
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -466,6 +472,7 @@ CheckNextSection:
|
|||||||
@param FileHandle A pointer to the file header that contains the set of sections to
|
@param FileHandle A pointer to the file header that contains the set of sections to
|
||||||
be searched.
|
be searched.
|
||||||
@param SectionData A pointer to the discovered section, if successful.
|
@param SectionData A pointer to the discovered section, if successful.
|
||||||
|
@param SectionSize A pointer to the size of the discovered section, if successful.
|
||||||
|
|
||||||
@retval EFI_SUCCESS The section was found.
|
@retval EFI_SUCCESS The section was found.
|
||||||
@retval EFI_NOT_FOUND The section was not found.
|
@retval EFI_NOT_FOUND The section was not found.
|
||||||
@ -477,7 +484,8 @@ FfsFindSectionDataWithHook (
|
|||||||
IN EFI_SECTION_TYPE SectionType,
|
IN EFI_SECTION_TYPE SectionType,
|
||||||
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 +508,8 @@ FfsFindSectionDataWithHook (
|
|||||||
SectionCheckHook,
|
SectionCheckHook,
|
||||||
Section,
|
Section,
|
||||||
FileSize,
|
FileSize,
|
||||||
SectionData
|
SectionData,
|
||||||
|
SectionSize
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -511,6 +520,7 @@ FfsFindSectionDataWithHook (
|
|||||||
@param FileHandle A pointer to the file header that contains the set of sections to
|
@param FileHandle A pointer to the file header that contains the set of sections to
|
||||||
be searched.
|
be searched.
|
||||||
@param SectionData A pointer to the discovered section, if successful.
|
@param SectionData A pointer to the discovered section, if successful.
|
||||||
|
@param SectionSize A pointer to the size of the discovered section, if successful.
|
||||||
|
|
||||||
@retval EFI_SUCCESS The section was found.
|
@retval EFI_SUCCESS The section was found.
|
||||||
@retval EFI_NOT_FOUND The section was not found.
|
@retval EFI_NOT_FOUND The section was not found.
|
||||||
@ -521,10 +531,11 @@ 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
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
return FfsFindSectionDataWithHook (SectionType, NULL, FileHandle, SectionData);
|
return FfsFindSectionDataWithHook (SectionType, NULL, FileHandle, SectionData, SectionSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -816,6 +827,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 +854,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;
|
||||||
}
|
}
|
||||||
|
@ -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>
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
**/
|
**/
|
||||||
|
|
||||||
|
#include "ProcessorBind.h"
|
||||||
#include <PrePi.h>
|
#include <PrePi.h>
|
||||||
|
|
||||||
//
|
//
|
||||||
@ -56,54 +57,45 @@ 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 UINT32 *DestinationSize,
|
||||||
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;
|
UINT32 ImageSize;
|
||||||
|
VOID *Buffer;
|
||||||
|
UINT32 BufferSize;
|
||||||
|
UINT32 BufferPages;
|
||||||
|
UINT32 BufferAlignment;
|
||||||
|
|
||||||
ZeroMem (&ImageContext, sizeof (ImageContext));
|
Status = UefiImageInitializeContext (&ImageContext, UefiImage, UefiImageSize);
|
||||||
|
|
||||||
ImageContext.Handle = PeCoffImage;
|
|
||||||
ImageContext.ImageRead = PeCoffLoaderImageReadFromMemory;
|
|
||||||
|
|
||||||
Status = PeCoffLoaderGetImageInfo (&ImageContext);
|
|
||||||
ASSERT_EFI_ERROR (Status);
|
ASSERT_EFI_ERROR (Status);
|
||||||
|
|
||||||
|
ImageSize = UefiImageGetImageSize (&ImageContext);
|
||||||
|
BufferPages = EFI_SIZE_TO_PAGES (ImageSize);
|
||||||
|
BufferSize = EFI_PAGES_TO_SIZE (BufferPages);
|
||||||
|
BufferAlignment = UefiImageGetSegmentAlignment (&ImageContext);
|
||||||
|
|
||||||
//
|
//
|
||||||
// Allocate Memory for the image
|
// Allocate Memory for the image
|
||||||
//
|
//
|
||||||
Buffer = AllocateCodePages (EFI_SIZE_TO_PAGES ((UINT32)ImageContext.ImageSize));
|
Buffer = AllocateAlignedCodePages (BufferPages, BufferAlignment);
|
||||||
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) Buffer;
|
||||||
// Relocate the image in our new buffer
|
*DestinationSize = BufferSize;
|
||||||
//
|
*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,22 +114,23 @@ LoadDxeCoreFromFfsFile (
|
|||||||
)
|
)
|
||||||
{
|
{
|
||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
VOID *PeCoffImage;
|
VOID *UefiImage;
|
||||||
|
UINT32 UefiImageSize;
|
||||||
EFI_PHYSICAL_ADDRESS ImageAddress;
|
EFI_PHYSICAL_ADDRESS ImageAddress;
|
||||||
UINT64 ImageSize;
|
UINT32 DestinationSize;
|
||||||
EFI_PHYSICAL_ADDRESS EntryPoint;
|
EFI_PHYSICAL_ADDRESS EntryPoint;
|
||||||
VOID *BaseOfStack;
|
VOID *BaseOfStack;
|
||||||
VOID *TopOfStack;
|
VOID *TopOfStack;
|
||||||
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, &DestinationSize, &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);
|
||||||
|
|
||||||
//
|
//
|
||||||
@ -146,7 +139,7 @@ LoadDxeCoreFromFfsFile (
|
|||||||
Status = FfsGetFileInfo (FileHandle, &FvFileInfo);
|
Status = FfsGetFileInfo (FileHandle, &FvFileInfo);
|
||||||
ASSERT_EFI_ERROR (Status);
|
ASSERT_EFI_ERROR (Status);
|
||||||
|
|
||||||
BuildModuleHob (&FvFileInfo.FileName, (EFI_PHYSICAL_ADDRESS)(UINTN)ImageAddress, EFI_SIZE_TO_PAGES ((UINT32)ImageSize) * EFI_PAGE_SIZE, EntryPoint);
|
BuildModuleHob (&FvFileInfo.FileName, (EFI_PHYSICAL_ADDRESS)(UINTN)ImageAddress, DestinationSize, EntryPoint);
|
||||||
|
|
||||||
DEBUG ((DEBUG_INFO | DEBUG_LOAD, "Loading DxeCore at 0x%10p EntryPoint=0x%10p\n", (VOID *)(UINTN)ImageAddress, (VOID *)(UINTN)EntryPoint));
|
DEBUG ((DEBUG_INFO | DEBUG_LOAD, "Loading DxeCore at 0x%10p EntryPoint=0x%10p\n", (VOID *)(UINTN)ImageAddress, (VOID *)(UINTN)EntryPoint));
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
|
||||||
@ -145,8 +145,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
|
||||||
@ -154,13 +153,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
|
||||||
|
|
||||||
@ -169,8 +168,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
|
||||||
@ -186,7 +184,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
|
||||||
@ -208,7 +206,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
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -17,7 +17,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>
|
||||||
@ -88,20 +88,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
|
||||||
@ -217,9 +218,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
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
#ifndef DISABLE_NEW_DEPRECATED_INTERFACES
|
||||||
|
|
||||||
/** @file
|
/** @file
|
||||||
Provides services to perform additional actions to relocate and unload
|
Provides services to perform additional actions to relocate and unload
|
||||||
PE/Coff image for Emu environment specific purpose such as souce level debug.
|
PE/Coff image for Emu environment specific purpose such as souce level debug.
|
||||||
@ -23,7 +25,8 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
|
|||||||
//
|
//
|
||||||
// Cache of UnixThunk protocol
|
// Cache of UnixThunk protocol
|
||||||
//
|
//
|
||||||
EMU_THUNK_PROTOCOL *mThunk = NULL;
|
EMU_THUNK_PROTOCOL *mThunk = NULL;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
The constructor function gets the pointer of the WinNT thunk functions
|
The constructor function gets the pointer of the WinNT thunk functions
|
||||||
@ -39,7 +42,7 @@ DxeEmuPeCoffLibExtraActionConstructor (
|
|||||||
IN EFI_SYSTEM_TABLE *SystemTable
|
IN EFI_SYSTEM_TABLE *SystemTable
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
EFI_HOB_GUID_TYPE *GuidHob;
|
EFI_HOB_GUID_TYPE *GuidHob;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Retrieve EmuThunkProtocol from GUID'ed HOB
|
// Retrieve EmuThunkProtocol from GUID'ed HOB
|
||||||
@ -72,6 +75,8 @@ PeCoffLoaderRelocateImageExtraAction (
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Performs additional actions just before a PE/COFF image is unloaded. Any resources
|
Performs additional actions just before a PE/COFF image is unloaded. Any resources
|
||||||
that were allocated by PeCoffLoaderRelocateImageExtraAction() must be freed.
|
that were allocated by PeCoffLoaderRelocateImageExtraAction() must be freed.
|
||||||
@ -92,3 +97,5 @@ PeCoffLoaderUnloadImageExtraAction (
|
|||||||
mThunk->PeCoffUnloadImageExtraAction (ImageContext);
|
mThunk->PeCoffUnloadImageExtraAction (ImageContext);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif // DISABLE_NEW_DEPRECATED_INTERFACES
|
||||||
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
@ -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
|
||||||
|
|
@ -1,3 +1,5 @@
|
|||||||
|
#ifndef DISABLE_NEW_DEPRECATED_INTERFACES
|
||||||
|
|
||||||
/** @file
|
/** @file
|
||||||
Provides services to perform additional actions to relocate and unload
|
Provides services to perform additional actions to relocate and unload
|
||||||
PE/Coff image for Emu environment specific purpose such as souce level debug.
|
PE/Coff image for Emu environment specific purpose such as souce level debug.
|
||||||
@ -22,7 +24,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
|
|||||||
//
|
//
|
||||||
// Cache of UnixThunk protocol
|
// Cache of UnixThunk protocol
|
||||||
//
|
//
|
||||||
EMU_THUNK_PROTOCOL *mThunk = NULL;
|
EMU_THUNK_PROTOCOL *mThunk = NULL;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
The function caches the pointer of the Unix thunk functions
|
The function caches the pointer of the Unix thunk functions
|
||||||
@ -36,21 +38,22 @@ EFIAPI
|
|||||||
EmuPeCoffGetThunkStucture (
|
EmuPeCoffGetThunkStucture (
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
EMU_THUNK_PPI *ThunkPpi;
|
EMU_THUNK_PPI *ThunkPpi;
|
||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Locate Unix ThunkPpi for retrieving standard output handle
|
// Locate Unix ThunkPpi for retrieving standard output handle
|
||||||
//
|
//
|
||||||
Status = PeiServicesLocatePpi (
|
Status = PeiServicesLocatePpi (
|
||||||
&gEmuThunkPpiGuid,
|
&gEmuThunkPpiGuid,
|
||||||
0,
|
0,
|
||||||
NULL,
|
NULL,
|
||||||
(VOID **)&ThunkPpi
|
(VOID **) &ThunkPpi
|
||||||
);
|
);
|
||||||
ASSERT_EFI_ERROR (Status);
|
ASSERT_EFI_ERROR (Status);
|
||||||
|
|
||||||
EMU_MAGIC_PAGE ()->Thunk = (EMU_THUNK_PROTOCOL *)ThunkPpi->Thunk ();
|
EMU_MAGIC_PAGE()->Thunk = (EMU_THUNK_PROTOCOL *) ThunkPpi->Thunk ();
|
||||||
|
|
||||||
return EFI_SUCCESS;
|
return EFI_SUCCESS;
|
||||||
}
|
}
|
||||||
@ -70,12 +73,12 @@ PeCoffLoaderRelocateImageExtraAction (
|
|||||||
IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext
|
IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
if (EMU_MAGIC_PAGE ()->Thunk == NULL) {
|
if (EMU_MAGIC_PAGE()->Thunk == NULL) {
|
||||||
EmuPeCoffGetThunkStucture ();
|
EmuPeCoffGetThunkStucture ();
|
||||||
}
|
}
|
||||||
|
EMU_MAGIC_PAGE()->Thunk->PeCoffRelocateImageExtraAction (ImageContext);
|
||||||
|
}
|
||||||
|
|
||||||
EMU_MAGIC_PAGE ()->Thunk->PeCoffRelocateImageExtraAction (ImageContext);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Performs additional actions just before a PE/COFF image is unloaded. Any resources
|
Performs additional actions just before a PE/COFF image is unloaded. Any resources
|
||||||
@ -93,9 +96,10 @@ PeCoffLoaderUnloadImageExtraAction (
|
|||||||
IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext
|
IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
if (EMU_MAGIC_PAGE ()->Thunk == NULL) {
|
if (EMU_MAGIC_PAGE()->Thunk == NULL) {
|
||||||
EmuPeCoffGetThunkStucture ();
|
EmuPeCoffGetThunkStucture ();
|
||||||
}
|
}
|
||||||
|
EMU_MAGIC_PAGE()->Thunk->PeCoffUnloadImageExtraAction (ImageContext);
|
||||||
EMU_MAGIC_PAGE ()->Thunk->PeCoffUnloadImageExtraAction (ImageContext);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif // DISABLE_NEW_DEPRECATED_INTERFACES
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -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);
|
||||||
|
}
|
@ -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
|
@ -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;
|
||||||
|
}
|
||||||
|
@ -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.
|
||||||
|
@ -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
|
||||||
|
@ -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>
|
||||||
|
@ -36,7 +36,6 @@
|
|||||||
|
|
||||||
[LibraryClasses]
|
[LibraryClasses]
|
||||||
DebugLib
|
DebugLib
|
||||||
PeCoffGetEntryPointLib
|
|
||||||
PeiServicesLib
|
PeiServicesLib
|
||||||
PpiListLib
|
PpiListLib
|
||||||
BaseMemoryLib
|
BaseMemoryLib
|
||||||
|
@ -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
|
||||||
|
@ -415,9 +415,9 @@ EMU_THUNK_PROTOCOL gEmuThunkProtocol = {
|
|||||||
GasketSecMalloc,
|
GasketSecMalloc,
|
||||||
GasketSecValloc,
|
GasketSecValloc,
|
||||||
GasketSecFree,
|
GasketSecFree,
|
||||||
GasketSecPeCoffGetEntryPoint,
|
GasketSecUefiImageGetEntryPoint,
|
||||||
GasketSecPeCoffRelocateImageExtraAction,
|
GasketSecUefiImageRelocateImageExtraAction,
|
||||||
GasketSecPeCoffUnloadImageExtraAction,
|
GasketSecUefiImageUnloadImageExtraAction,
|
||||||
GasketSecEnableInterrupt,
|
GasketSecEnableInterrupt,
|
||||||
GasketSecDisableInterrupt,
|
GasketSecDisableInterrupt,
|
||||||
GasketQueryPerformanceFrequency,
|
GasketQueryPerformanceFrequency,
|
||||||
|
@ -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
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
@ -55,12 +55,11 @@
|
|||||||
PrintLib
|
PrintLib
|
||||||
BaseMemoryLib
|
BaseMemoryLib
|
||||||
BaseLib
|
BaseLib
|
||||||
PeCoffLib
|
UefiImageLib
|
||||||
ThunkPpiList
|
ThunkPpiList
|
||||||
ThunkProtocolList
|
ThunkProtocolList
|
||||||
PpiListLib
|
PpiListLib
|
||||||
PeiServicesLib
|
PeiServicesLib
|
||||||
PeCoffGetEntryPointLib
|
|
||||||
StackCheckLib
|
StackCheckLib
|
||||||
|
|
||||||
[Ppis]
|
[Ppis]
|
||||||
|
@ -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
|
||||||
|
@ -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
4
EmulatorPkg/Unix/lldbefi.py
Executable file → Normal 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))
|
||||||
|
@ -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;
|
||||||
|
|
||||||
//
|
//
|
||||||
// If enabled use the magic page to communicate between modules
|
// If enabled use the magic page to communicate between modules
|
||||||
@ -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;
|
||||||
@ -1064,8 +1082,8 @@ typedef struct {
|
|||||||
|
|
||||||
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;
|
||||||
@ -1103,7 +1121,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
|
||||||
@ -1117,7 +1135,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.
|
||||||
//
|
//
|
||||||
@ -1316,8 +1334,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;
|
||||||
|
@ -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
|
||||||
)
|
)
|
||||||
|
|
||||||
/*++
|
/*++
|
||||||
|
@ -49,7 +49,7 @@
|
|||||||
PrintLib
|
PrintLib
|
||||||
BaseMemoryLib
|
BaseMemoryLib
|
||||||
BaseLib
|
BaseLib
|
||||||
PeCoffLib
|
UefiImageLib
|
||||||
ThunkPpiList
|
ThunkPpiList
|
||||||
ThunkProtocolList
|
ThunkProtocolList
|
||||||
PpiListLib
|
PpiListLib
|
||||||
|
@ -592,9 +592,9 @@ EMU_THUNK_PROTOCOL gEmuThunkProtocol = {
|
|||||||
SecAlloc,
|
SecAlloc,
|
||||||
NULL,
|
NULL,
|
||||||
SecFree,
|
SecFree,
|
||||||
SecPeCoffGetEntryPoint,
|
SecUefiImageGetEntryPoint,
|
||||||
PeCoffLoaderRelocateImageExtraAction,
|
UefiImageLoaderRelocateImageExtraAction,
|
||||||
PeCoffLoaderUnloadImageExtraAction,
|
UefiImageLoaderUnloadImageExtraAction,
|
||||||
SecEnableInterrupt,
|
SecEnableInterrupt,
|
||||||
SecDisableInterrupt,
|
SecDisableInterrupt,
|
||||||
SecQueryPerformanceFrequency,
|
SecQueryPerformanceFrequency,
|
||||||
|
@ -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
|
||||||
|
@ -39,12 +39,13 @@
|
|||||||
BaseMemoryLib
|
BaseMemoryLib
|
||||||
UefiLib
|
UefiLib
|
||||||
FspWrapperApiLib
|
FspWrapperApiLib
|
||||||
PeCoffLib
|
UefiImageLib
|
||||||
CacheMaintenanceLib
|
CacheMaintenanceLib
|
||||||
DxeServicesLib
|
DxeServicesLib
|
||||||
PerformanceLib
|
PerformanceLib
|
||||||
HobLib
|
HobLib
|
||||||
FspWrapperPlatformLib
|
FspWrapperPlatformLib
|
||||||
|
MemoryAllocationLib
|
||||||
|
|
||||||
[Protocols]
|
[Protocols]
|
||||||
gEfiPciEnumerationCompleteProtocolGuid ## CONSUMES
|
gEfiPciEnumerationCompleteProtocolGuid ## CONSUMES
|
||||||
|
@ -11,11 +11,13 @@ 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>
|
||||||
#include <Library/UefiLib.h>
|
#include <Library/UefiLib.h>
|
||||||
|
#include <Library/MemoryAllocationLib.h>
|
||||||
|
#include <Library/MemoryAllocationLibEx.h>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Relocate this image under 4G memory.
|
Relocate this image under 4G memory.
|
||||||
@ -37,9 +39,11 @@ RelocateImageUnder4GIfNeeded (
|
|||||||
UINT8 *Buffer;
|
UINT8 *Buffer;
|
||||||
UINTN BufferSize;
|
UINTN BufferSize;
|
||||||
EFI_HANDLE NewImageHandle;
|
EFI_HANDLE NewImageHandle;
|
||||||
|
UINT32 ImageSize;
|
||||||
|
UINT32 ImageAlignment;
|
||||||
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,43 +87,34 @@ 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) {
|
ImageSize = UefiImageGetImageSize (&ImageContext);
|
||||||
Pages = EFI_SIZE_TO_PAGES ((UINTN)(ImageContext.ImageSize + ImageContext.SectionAlignment));
|
ImageAlignment = UefiImageGetSegmentAlignment (&ImageContext);
|
||||||
} else {
|
Pages = EFI_SIZE_TO_PAGES (ImageSize);
|
||||||
Pages = EFI_SIZE_TO_PAGES ((UINTN)ImageContext.ImageSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
FfsBuffer = 0xFFFFFFFF;
|
FfsBuffer = 0xFFFFFFFF;
|
||||||
Status = gBS->AllocatePages (
|
Status = AllocateAlignedPagesEx (
|
||||||
AllocateMaxAddress,
|
AllocateMaxAddress,
|
||||||
EfiBootServicesCode,
|
EfiBootServicesCode,
|
||||||
Pages,
|
Pages,
|
||||||
&FfsBuffer
|
ImageAlignment,
|
||||||
);
|
&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
|
ImageSize,
|
||||||
//
|
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,16 +122,11 @@ RelocateImageUnder4GIfNeeded (
|
|||||||
//
|
//
|
||||||
gBS->FreePool (Buffer);
|
gBS->FreePool (Buffer);
|
||||||
|
|
||||||
//
|
DEBUG ((DEBUG_INFO, "Loading driver at 0x%08llx EntryPoint=0x%08x\n", FfsBuffer, 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%08llx start failed: %r\n", FfsBuffer, Status));
|
||||||
gBS->FreePages (FfsBuffer, Pages);
|
FreeAlignedPages ((VOID *)(UINTN)FfsBuffer, Pages);
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -38,8 +38,8 @@
|
|||||||
FspWrapperPlatformLib
|
FspWrapperPlatformLib
|
||||||
FspWrapperHobProcessLib
|
FspWrapperHobProcessLib
|
||||||
CpuLib
|
CpuLib
|
||||||
PeCoffGetEntryPointLib
|
UefiCpuLib
|
||||||
PeCoffExtraActionLib
|
UefiImageExtraActionLib
|
||||||
PerformanceLib
|
PerformanceLib
|
||||||
TimerLib
|
TimerLib
|
||||||
FspWrapperApiLib
|
FspWrapperApiLib
|
||||||
|
@ -39,8 +39,8 @@
|
|||||||
FspWrapperPlatformLib
|
FspWrapperPlatformLib
|
||||||
FspWrapperHobProcessLib
|
FspWrapperHobProcessLib
|
||||||
CpuLib
|
CpuLib
|
||||||
PeCoffGetEntryPointLib
|
UefiCpuLib
|
||||||
PeCoffExtraActionLib
|
UefiImageExtraActionLib
|
||||||
PerformanceLib
|
PerformanceLib
|
||||||
FspWrapperApiLib
|
FspWrapperApiLib
|
||||||
FspWrapperApiTestLib
|
FspWrapperApiTestLib
|
||||||
|
@ -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
|
||||||
|
BIN
LoaderFlow.png
Normal file
BIN
LoaderFlow.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 213 KiB |
@ -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;
|
||||||
|
@ -73,11 +73,11 @@ 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/MemoryAllocationLibEx.h>
|
||||||
#include <Library/DevicePathLib.h>
|
#include <Library/DevicePathLib.h>
|
||||||
#include <Library/UefiBootServicesTableLib.h>
|
#include <Library/UefiBootServicesTableLib.h>
|
||||||
#include <Library/ReportStatusCodeLib.h>
|
#include <Library/ReportStatusCodeLib.h>
|
||||||
@ -220,10 +220,10 @@ 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) \
|
||||||
@ -390,7 +390,8 @@ CoreInitializeEventServices (
|
|||||||
**/
|
**/
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
CoreInitializeImageServices (
|
CoreInitializeImageServices (
|
||||||
IN VOID *HobStart
|
IN VOID *HobStart,
|
||||||
|
OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -2385,7 +2386,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
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -2574,7 +2576,8 @@ VerifyFvHeaderChecksum (
|
|||||||
**/
|
**/
|
||||||
VOID
|
VOID
|
||||||
MemoryProfileInit (
|
MemoryProfileInit (
|
||||||
IN VOID *HobStart
|
IN VOID *HobStart,
|
||||||
|
IN UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -2600,8 +2603,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
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -2617,7 +2621,8 @@ RegisterMemoryProfileImage (
|
|||||||
**/
|
**/
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
UnregisterMemoryProfileImage (
|
UnregisterMemoryProfileImage (
|
||||||
IN LOADED_IMAGE_PRIVATE_DATA *DriverEntry
|
EFI_DEVICE_PATH_PROTOCOL *FilePath,
|
||||||
|
IN EFI_PHYSICAL_ADDRESS ImageAddress
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -2704,7 +2709,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
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -2725,8 +2731,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
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -82,9 +82,8 @@
|
|||||||
UefiLib
|
UefiLib
|
||||||
DebugLib
|
DebugLib
|
||||||
DxeCoreEntryPoint
|
DxeCoreEntryPoint
|
||||||
PeCoffLib
|
UefiImageLib
|
||||||
PeCoffGetEntryPointLib
|
UefiImageExtraActionLib
|
||||||
PeCoffExtraActionLib
|
|
||||||
ExtractGuidedSectionLib
|
ExtractGuidedSectionLib
|
||||||
MemoryAllocationLib
|
MemoryAllocationLib
|
||||||
UefiBootServicesTableLib
|
UefiBootServicesTableLib
|
||||||
|
@ -236,15 +236,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
|
||||||
@ -276,8 +275,6 @@ DxeMain (
|
|||||||
//
|
//
|
||||||
CoreInitializeMemoryServices (&HobStart, &MemoryBaseAddress, &MemoryLength);
|
CoreInitializeMemoryServices (&HobStart, &MemoryBaseAddress, &MemoryLength);
|
||||||
|
|
||||||
MemoryProfileInit (HobStart);
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Start the Handle Services.
|
// Start the Handle Services.
|
||||||
//
|
//
|
||||||
@ -287,9 +284,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
|
||||||
//
|
//
|
||||||
@ -335,19 +334,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
|
||||||
@ -394,7 +383,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
@ -1533,7 +1533,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;
|
||||||
|
@ -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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,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.
|
||||||
@ -73,7 +75,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;
|
||||||
|
|
||||||
@ -201,7 +203,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));
|
||||||
@ -284,15 +286,6 @@ InstallMemoryAttributesTableOnEndOfDxe (
|
|||||||
{
|
{
|
||||||
mMemoryAttributesTableEndOfDxe = TRUE;
|
mMemoryAttributesTableEndOfDxe = TRUE;
|
||||||
InstallMemoryAttributesTable ();
|
InstallMemoryAttributesTable ();
|
||||||
|
|
||||||
DEBUG_CODE_BEGIN ();
|
|
||||||
if ( mImagePropertiesPrivateData.ImageRecordCount > 0) {
|
|
||||||
DEBUG ((DEBUG_INFO, "DXE - Total Runtime Image Count: 0x%x\n", mImagePropertiesPrivateData.ImageRecordCount));
|
|
||||||
DEBUG ((DEBUG_INFO, "DXE - Dump Runtime Image Records:\n"));
|
|
||||||
DumpImageRecords (&mImagePropertiesPrivateData.ImageRecordList);
|
|
||||||
}
|
|
||||||
|
|
||||||
DEBUG_CODE_END ();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -534,7 +527,11 @@ CoreGetMemoryMapWithSeparatedImageSection (
|
|||||||
|
|
||||||
CoreAcquiremMemoryAttributesTableLock ();
|
CoreAcquiremMemoryAttributesTableLock ();
|
||||||
|
|
||||||
AdditionalRecordCount = (2 * mImagePropertiesPrivateData.CodeSegmentCountMax + 3) * mImagePropertiesPrivateData.ImageRecordCount;
|
//
|
||||||
|
// Per image, there may be one additional trailer. There may be prefixed data
|
||||||
|
// (counted as the original entry).
|
||||||
|
//
|
||||||
|
AdditionalRecordCount = (mImagePropertiesPrivateData.SectionCountMax + 1) * mImagePropertiesPrivateData.ImageRecordCount;
|
||||||
|
|
||||||
OldMemoryMapSize = *MemoryMapSize;
|
OldMemoryMapSize = *MemoryMapSize;
|
||||||
Status = CoreGetMemoryMap (MemoryMapSize, MemoryMap, MapKey, DescriptorSize, DescriptorVersion);
|
Status = CoreGetMemoryMap (MemoryMapSize, MemoryMap, MapKey, DescriptorSize, DescriptorVersion);
|
||||||
@ -574,6 +571,68 @@ CoreGetMemoryMapWithSeparatedImageSection (
|
|||||||
// Below functions are for ImageRecord
|
// Below functions are for ImageRecord
|
||||||
//
|
//
|
||||||
|
|
||||||
|
/**
|
||||||
|
Set MemoryAttributesTable according to PE/COFF image section alignment.
|
||||||
|
|
||||||
|
@param SectionAlignment PE/COFF section alignment
|
||||||
|
**/
|
||||||
|
STATIC
|
||||||
|
VOID
|
||||||
|
SetMemoryAttributesTableSectionAlignment (
|
||||||
|
IN UINT32 SectionAlignment
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (((SectionAlignment & (RUNTIME_PAGE_ALLOCATION_GRANULARITY - 1)) != 0) &&
|
||||||
|
mMemoryAttributesTableEnable)
|
||||||
|
{
|
||||||
|
DEBUG ((DEBUG_VERBOSE, "SetMemoryAttributesTableSectionAlignment - Clear\n"));
|
||||||
|
mMemoryAttributesTableEnable = FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Sort image record based upon the ImageBase from low to high.
|
||||||
|
**/
|
||||||
|
STATIC
|
||||||
|
VOID
|
||||||
|
InsertSortImageRecord (
|
||||||
|
IN UEFI_IMAGE_RECORD *NewImageRecord
|
||||||
|
)
|
||||||
|
{
|
||||||
|
UEFI_IMAGE_RECORD *ImageRecord;
|
||||||
|
LIST_ENTRY *PrevImageRecordLink;
|
||||||
|
LIST_ENTRY *ImageRecordLink;
|
||||||
|
LIST_ENTRY *ImageRecordList;
|
||||||
|
|
||||||
|
ImageRecordList = &mImagePropertiesPrivateData.ImageRecordList;
|
||||||
|
|
||||||
|
PrevImageRecordLink = ImageRecordList;
|
||||||
|
for (
|
||||||
|
ImageRecordLink = GetFirstNode (ImageRecordList);
|
||||||
|
!IsNull (ImageRecordLink, ImageRecordList);
|
||||||
|
ImageRecordLink = GetNextNode (ImageRecordList, PrevImageRecordLink)
|
||||||
|
) {
|
||||||
|
ImageRecord = CR (
|
||||||
|
ImageRecordLink,
|
||||||
|
UEFI_IMAGE_RECORD,
|
||||||
|
Link,
|
||||||
|
UEFI_IMAGE_RECORD_SIGNATURE
|
||||||
|
);
|
||||||
|
if (NewImageRecord->StartAddress < ImageRecord->StartAddress) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
PrevImageRecordLink = ImageRecordLink;
|
||||||
|
}
|
||||||
|
|
||||||
|
InsertHeadList (PrevImageRecordLink, &NewImageRecord->Link);
|
||||||
|
mImagePropertiesPrivateData.ImageRecordCount++;
|
||||||
|
|
||||||
|
if (mImagePropertiesPrivateData.SectionCountMax < NewImageRecord->NumSegments) {
|
||||||
|
mImagePropertiesPrivateData.SectionCountMax = NewImageRecord->NumSegments;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Insert image record.
|
Insert image record.
|
||||||
|
|
||||||
@ -581,13 +640,18 @@ CoreGetMemoryMapWithSeparatedImageSection (
|
|||||||
**/
|
**/
|
||||||
VOID
|
VOID
|
||||||
InsertImageRecord (
|
InsertImageRecord (
|
||||||
IN EFI_RUNTIME_IMAGE_ENTRY *RuntimeImage
|
IN LOADED_IMAGE_PRIVATE_DATA *Image,
|
||||||
|
IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
EFI_STATUS Status;
|
RETURN_STATUS PdbStatus;
|
||||||
IMAGE_PROPERTIES_RECORD *ImageRecord;
|
EFI_RUNTIME_IMAGE_ENTRY *RuntimeImage;
|
||||||
CHAR8 *PdbPointer;
|
UINT32 SectionAlignment;
|
||||||
UINT32 RequiredAlignment;
|
UEFI_IMAGE_RECORD *ImageRecord;
|
||||||
|
CONST CHAR8 *PdbPointer;
|
||||||
|
UINT32 PdbSize;
|
||||||
|
|
||||||
|
RuntimeImage = Image->RuntimeData;
|
||||||
|
|
||||||
DEBUG ((DEBUG_VERBOSE, "InsertImageRecord - 0x%x\n", RuntimeImage));
|
DEBUG ((DEBUG_VERBOSE, "InsertImageRecord - 0x%x\n", RuntimeImage));
|
||||||
|
|
||||||
@ -596,71 +660,85 @@ InsertImageRecord (
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ImageRecord = AllocatePool (sizeof (*ImageRecord));
|
DEBUG ((DEBUG_VERBOSE, "ImageRecordCount - 0x%x\n", mImagePropertiesPrivateData.ImageRecordCount));
|
||||||
if (ImageRecord == NULL) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
InitializeListHead (&ImageRecord->Link);
|
PdbStatus = UefiImageGetSymbolsPath (ImageContext, &PdbPointer, &PdbSize);
|
||||||
InitializeListHead (&ImageRecord->CodeSegmentList);
|
if (!EFI_ERROR (PdbStatus)) {
|
||||||
|
|
||||||
PdbPointer = PeCoffLoaderGetPdbPointer ((VOID *)(UINTN)RuntimeImage->ImageBase);
|
|
||||||
if (PdbPointer != NULL) {
|
|
||||||
DEBUG ((DEBUG_VERBOSE, " Image - %a\n", PdbPointer));
|
DEBUG ((DEBUG_VERBOSE, " Image - %a\n", PdbPointer));
|
||||||
}
|
}
|
||||||
|
|
||||||
RequiredAlignment = RUNTIME_PAGE_ALLOCATION_GRANULARITY;
|
//
|
||||||
Status = CreateImagePropertiesRecord (
|
// Get SectionAlignment
|
||||||
RuntimeImage->ImageBase,
|
//
|
||||||
RuntimeImage->ImageSize,
|
SectionAlignment = UefiImageGetSegmentAlignment (ImageContext);
|
||||||
&RequiredAlignment,
|
|
||||||
ImageRecord
|
|
||||||
);
|
|
||||||
|
|
||||||
if (EFI_ERROR (Status)) {
|
SetMemoryAttributesTableSectionAlignment (SectionAlignment);
|
||||||
if (Status == EFI_ABORTED) {
|
if ((SectionAlignment & (RUNTIME_PAGE_ALLOCATION_GRANULARITY - 1)) != 0) {
|
||||||
mMemoryAttributesTableEnable = FALSE;
|
DEBUG ((
|
||||||
|
DEBUG_WARN,
|
||||||
|
"!!!!!!!! InsertImageRecord - Section Alignment(0x%x) is not %dK !!!!!!!!\n",
|
||||||
|
SectionAlignment, RUNTIME_PAGE_ALLOCATION_GRANULARITY >> 10));
|
||||||
|
if (!EFI_ERROR (PdbStatus)) {
|
||||||
|
DEBUG ((DEBUG_WARN, "!!!!!!!! Image - %a !!!!!!!!\n", PdbPointer));
|
||||||
}
|
}
|
||||||
|
|
||||||
Status = EFI_ABORTED;
|
return;
|
||||||
goto Finish;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ImageRecord->CodeSegmentCount == 0) {
|
ImageRecord = UefiImageLoaderGetImageRecord (ImageContext);
|
||||||
mMemoryAttributesTableEnable = FALSE;
|
if (ImageRecord == NULL) {
|
||||||
DEBUG ((DEBUG_ERROR, "!!!!!!!! InsertImageRecord - CodeSegmentCount is 0 !!!!!!!!\n"));
|
return ;
|
||||||
if (PdbPointer != NULL) {
|
}
|
||||||
DEBUG ((DEBUG_ERROR, "!!!!!!!! Image - %a !!!!!!!!\n", PdbPointer));
|
|
||||||
|
UefiImageDebugPrintSegments (ImageContext);
|
||||||
|
UefiImageDebugPrintImageRecord (ImageRecord);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Section order is guaranteed by the PE specification.
|
||||||
|
// Section validity (e.g. no overlap) is guaranteed by the PE specification.
|
||||||
|
//
|
||||||
|
|
||||||
|
InsertSortImageRecord (ImageRecord);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Find image record according to image base and size.
|
||||||
|
|
||||||
|
@param ImageBase Base of PE image
|
||||||
|
@param ImageSize Size of PE image
|
||||||
|
|
||||||
|
@return image record
|
||||||
|
**/
|
||||||
|
STATIC
|
||||||
|
UEFI_IMAGE_RECORD *
|
||||||
|
FindImageRecord (
|
||||||
|
IN EFI_PHYSICAL_ADDRESS ImageBase
|
||||||
|
)
|
||||||
|
{
|
||||||
|
UEFI_IMAGE_RECORD *ImageRecord;
|
||||||
|
LIST_ENTRY *ImageRecordLink;
|
||||||
|
LIST_ENTRY *ImageRecordList;
|
||||||
|
|
||||||
|
ImageRecordList = &mImagePropertiesPrivateData.ImageRecordList;
|
||||||
|
|
||||||
|
for (ImageRecordLink = ImageRecordList->ForwardLink;
|
||||||
|
ImageRecordLink != ImageRecordList;
|
||||||
|
ImageRecordLink = ImageRecordLink->ForwardLink)
|
||||||
|
{
|
||||||
|
ImageRecord = CR (
|
||||||
|
ImageRecordLink,
|
||||||
|
UEFI_IMAGE_RECORD,
|
||||||
|
Link,
|
||||||
|
UEFI_IMAGE_RECORD_SIGNATURE
|
||||||
|
);
|
||||||
|
|
||||||
|
if (ImageBase == ImageRecord->StartAddress)
|
||||||
|
{
|
||||||
|
return ImageRecord;
|
||||||
}
|
}
|
||||||
|
|
||||||
Status = EFI_ABORTED;
|
|
||||||
goto Finish;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
return NULL;
|
||||||
// Check overlap all section in ImageBase/Size
|
|
||||||
//
|
|
||||||
if (!IsImageRecordCodeSectionValid (ImageRecord)) {
|
|
||||||
DEBUG ((DEBUG_ERROR, "IsImageRecordCodeSectionValid - FAIL\n"));
|
|
||||||
Status = EFI_ABORTED;
|
|
||||||
goto Finish;
|
|
||||||
}
|
|
||||||
|
|
||||||
InsertTailList (&mImagePropertiesPrivateData.ImageRecordList, &ImageRecord->Link);
|
|
||||||
mImagePropertiesPrivateData.ImageRecordCount++;
|
|
||||||
|
|
||||||
if (mImagePropertiesPrivateData.CodeSegmentCountMax < ImageRecord->CodeSegmentCount) {
|
|
||||||
mImagePropertiesPrivateData.CodeSegmentCountMax = ImageRecord->CodeSegmentCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
SortImageRecord (&mImagePropertiesPrivateData.ImageRecordList);
|
|
||||||
|
|
||||||
Finish:
|
|
||||||
if (EFI_ERROR (Status) && (ImageRecord != NULL)) {
|
|
||||||
DeleteImagePropertiesRecord (ImageRecord);
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -673,7 +751,7 @@ RemoveImageRecord (
|
|||||||
IN EFI_RUNTIME_IMAGE_ENTRY *RuntimeImage
|
IN EFI_RUNTIME_IMAGE_ENTRY *RuntimeImage
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
IMAGE_PROPERTIES_RECORD *ImageRecord;
|
UEFI_IMAGE_RECORD *ImageRecord;
|
||||||
|
|
||||||
DEBUG ((DEBUG_VERBOSE, "RemoveImageRecord - 0x%x\n", RuntimeImage));
|
DEBUG ((DEBUG_VERBOSE, "RemoveImageRecord - 0x%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));
|
||||||
@ -683,7 +761,7 @@ RemoveImageRecord (
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ImageRecord = FindImageRecord ((EFI_PHYSICAL_ADDRESS)(UINTN)RuntimeImage->ImageBase, RuntimeImage->ImageSize, &mImagePropertiesPrivateData.ImageRecordList);
|
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;
|
||||||
|
@ -40,8 +40,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
|
||||||
@ -213,113 +217,73 @@ 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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Return the section alignment requirement for the PE image section type.
|
Return if the PE image section is aligned.
|
||||||
|
|
||||||
@param[in] MemoryType PE/COFF image memory type
|
@param[in] SectionAlignment PE/COFF section alignment
|
||||||
|
@param[in] MemoryType PE/COFF image memory type
|
||||||
@retval The required section alignment for this memory type
|
|
||||||
|
|
||||||
|
@retval TRUE The PE image section is aligned.
|
||||||
|
@retval FALSE The PE image section is not aligned.
|
||||||
**/
|
**/
|
||||||
STATIC
|
STATIC
|
||||||
UINT32
|
BOOLEAN
|
||||||
GetMemoryProtectionSectionAlignment (
|
IsMemoryProtectionSectionAligned (
|
||||||
|
IN UINT32 SectionAlignment,
|
||||||
IN EFI_MEMORY_TYPE MemoryType
|
IN EFI_MEMORY_TYPE MemoryType
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
UINT32 SectionAlignment;
|
UINT32 PageAlignment;
|
||||||
|
|
||||||
switch (MemoryType) {
|
switch (MemoryType) {
|
||||||
case EfiRuntimeServicesCode:
|
case EfiRuntimeServicesCode:
|
||||||
case EfiACPIMemoryNVS:
|
case EfiACPIMemoryNVS:
|
||||||
case EfiReservedMemoryType:
|
case EfiReservedMemoryType:
|
||||||
SectionAlignment = RUNTIME_PAGE_ALLOCATION_GRANULARITY;
|
PageAlignment = RUNTIME_PAGE_ALLOCATION_GRANULARITY;
|
||||||
break;
|
break;
|
||||||
case EfiRuntimeServicesData:
|
case EfiRuntimeServicesData:
|
||||||
ASSERT (FALSE);
|
ASSERT (FALSE);
|
||||||
SectionAlignment = RUNTIME_PAGE_ALLOCATION_GRANULARITY;
|
PageAlignment = RUNTIME_PAGE_ALLOCATION_GRANULARITY;
|
||||||
break;
|
break;
|
||||||
case EfiBootServicesCode:
|
case EfiBootServicesCode:
|
||||||
case EfiLoaderCode:
|
case EfiLoaderCode:
|
||||||
SectionAlignment = EFI_PAGE_SIZE;
|
PageAlignment = EFI_PAGE_SIZE;
|
||||||
break;
|
break;
|
||||||
case EfiACPIReclaimMemory:
|
case EfiACPIReclaimMemory:
|
||||||
default:
|
default:
|
||||||
ASSERT (FALSE);
|
ASSERT (FALSE);
|
||||||
SectionAlignment = EFI_PAGE_SIZE;
|
PageAlignment = EFI_PAGE_SIZE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return SectionAlignment;
|
if ((SectionAlignment & (PageAlignment - 1)) != 0) {
|
||||||
|
return FALSE;
|
||||||
|
} else {
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FIXME: Deduplicate
|
||||||
/**
|
/**
|
||||||
Protect UEFI PE/COFF image.
|
Protect UEFI PE/COFF image.
|
||||||
|
|
||||||
@ -328,22 +292,26 @@ GetMemoryProtectionSectionAlignment (
|
|||||||
**/
|
**/
|
||||||
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
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
IMAGE_PROPERTIES_RECORD *ImageRecord;
|
RETURN_STATUS PdbStatus;
|
||||||
UINT32 ProtectionPolicy;
|
EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;
|
||||||
EFI_STATUS Status;
|
EFI_DEVICE_PATH_PROTOCOL *LoadedImageDevicePath;
|
||||||
UINT32 RequiredAlignment;
|
UINT32 SectionAlignment;
|
||||||
|
UEFI_IMAGE_RECORD *ImageRecord;
|
||||||
|
CONST CHAR8 *PdbPointer;
|
||||||
|
UINT32 PdbSize;
|
||||||
|
BOOLEAN IsAligned;
|
||||||
|
UINT32 ProtectionPolicy;
|
||||||
|
|
||||||
|
LoadedImage = &Image->Info;
|
||||||
|
LoadedImageDevicePath = Image->LoadedImageDevicePath;
|
||||||
|
|
||||||
DEBUG ((DEBUG_INFO, "ProtectUefiImageCommon - 0x%x\n", LoadedImage));
|
DEBUG ((DEBUG_INFO, "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:
|
||||||
@ -355,36 +323,49 @@ ProtectUefiImage (
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ImageRecord = AllocateZeroPool (sizeof (*ImageRecord));
|
PdbStatus = UefiImageGetSymbolsPath (ImageContext, &PdbPointer, &PdbSize);
|
||||||
if (ImageRecord == NULL) {
|
if (!RETURN_ERROR (PdbStatus)) {
|
||||||
return;
|
DEBUG ((DEBUG_VERBOSE, " Image - %a\n", PdbPointer));
|
||||||
}
|
}
|
||||||
|
|
||||||
RequiredAlignment = GetMemoryProtectionSectionAlignment (LoadedImage->ImageCodeType);
|
//
|
||||||
|
// Get SectionAlignment
|
||||||
|
//
|
||||||
|
SectionAlignment = UefiImageGetSegmentAlignment (ImageContext);
|
||||||
|
|
||||||
Status = CreateImagePropertiesRecord (
|
IsAligned = IsMemoryProtectionSectionAligned (SectionAlignment, LoadedImage->ImageCodeType);
|
||||||
LoadedImage->ImageBase,
|
if (!IsAligned) {
|
||||||
LoadedImage->ImageSize,
|
DEBUG ((
|
||||||
&RequiredAlignment,
|
DEBUG_VERBOSE,
|
||||||
ImageRecord
|
"!!!!!!!! ProtectUefiImageCommon - Section Alignment(0x%x) is incorrect !!!!!!!!\n",
|
||||||
);
|
SectionAlignment));
|
||||||
|
if (!RETURN_ERROR (PdbStatus)) {
|
||||||
|
DEBUG ((DEBUG_VERBOSE, "!!!!!!!! Image - %a !!!!!!!!\n", PdbPointer));
|
||||||
|
}
|
||||||
|
|
||||||
if (EFI_ERROR (Status)) {
|
|
||||||
DEBUG ((DEBUG_ERROR, "%a failed to create image properties record\n", __func__));
|
|
||||||
FreePool (ImageRecord);
|
|
||||||
goto Finish;
|
goto Finish;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
ImageRecord = UefiImageLoaderGetImageRecord (ImageContext);
|
||||||
// CPU ARCH present. Update memory attribute directly.
|
if (ImageRecord == NULL) {
|
||||||
//
|
return ;
|
||||||
SetUefiImageProtectionAttributes (ImageRecord);
|
}
|
||||||
|
|
||||||
|
UefiImageDebugPrintSegments (ImageContext);
|
||||||
|
UefiImageDebugPrintImageRecord (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;
|
||||||
}
|
}
|
||||||
@ -401,30 +382,31 @@ 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 (
|
||||||
{
|
ImageRecordLink,
|
||||||
ImageRecord = CR (
|
UEFI_IMAGE_RECORD,
|
||||||
ImageRecordLink,
|
Link,
|
||||||
IMAGE_PROPERTIES_RECORD,
|
UEFI_IMAGE_RECORD_SIGNATURE
|
||||||
Link,
|
);
|
||||||
IMAGE_PROPERTIES_RECORD_SIGNATURE
|
|
||||||
);
|
|
||||||
|
|
||||||
if (ImageRecord->ImageBase == (EFI_PHYSICAL_ADDRESS)(UINTN)LoadedImage->ImageBase) {
|
if (ImageRecord->StartAddress == (EFI_PHYSICAL_ADDRESS)(UINTN)LoadedImage->ImageBase) {
|
||||||
|
// TODO: Revise for removal (e.g. CpuDxe integration)
|
||||||
|
if (gCpu != NULL) {
|
||||||
SetUefiImageMemoryAttributes (
|
SetUefiImageMemoryAttributes (
|
||||||
ImageRecord->ImageBase,
|
ImageRecord->StartAddress,
|
||||||
ImageRecord->ImageSize,
|
ImageRecord->EndAddress - ImageRecord->StartAddress,
|
||||||
0
|
0
|
||||||
);
|
);
|
||||||
DeleteImagePropertiesRecord (ImageRecord);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
RemoveEntryList (&ImageRecord->Link);
|
||||||
|
FreePool (ImageRecord);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -567,7 +549,6 @@ MergeMemoryMapForProtectionPolicy (
|
|||||||
Remove exec permissions from all regions whose type is identified by
|
Remove exec permissions from all regions whose type is identified by
|
||||||
PcdDxeNxMemoryProtectionPolicy.
|
PcdDxeNxMemoryProtectionPolicy.
|
||||||
**/
|
**/
|
||||||
STATIC
|
|
||||||
VOID
|
VOID
|
||||||
InitializeDxeNxMemoryProtectionPolicy (
|
InitializeDxeNxMemoryProtectionPolicy (
|
||||||
VOID
|
VOID
|
||||||
@ -775,12 +756,9 @@ MemoryProtectionCpuArchProtocolNotify (
|
|||||||
IN VOID *Context
|
IN VOID *Context
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
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);
|
||||||
@ -804,41 +782,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);
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
|
|||||||
**/
|
**/
|
||||||
|
|
||||||
#include "PeiMain.h"
|
#include "PeiMain.h"
|
||||||
|
#include "ProcessorBind.h"
|
||||||
|
|
||||||
//
|
//
|
||||||
// Utility global variables
|
// Utility global variables
|
||||||
@ -1377,8 +1378,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;
|
||||||
|
|
||||||
@ -1386,24 +1386,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);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1465,6 +1451,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.
|
||||||
|
|
||||||
|
@ -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;
|
||||||
@ -844,10 +851,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;
|
||||||
@ -894,11 +904,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;
|
||||||
}
|
}
|
||||||
@ -981,11 +993,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;
|
||||||
}
|
}
|
||||||
@ -1072,6 +1086,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;
|
||||||
|
|
||||||
@ -1083,7 +1129,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);
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
@ -2040,6 +2086,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;
|
||||||
@ -2089,6 +2186,7 @@ PeiFfsFvPpiFindSectionByType2 (
|
|||||||
Section,
|
Section,
|
||||||
FileSize,
|
FileSize,
|
||||||
SectionData,
|
SectionData,
|
||||||
|
SectionDataSize,
|
||||||
&ExtractedAuthenticationStatus,
|
&ExtractedAuthenticationStatus,
|
||||||
FwVolInstance->IsFfs3Fv
|
FwVolInstance->IsFfs3Fv
|
||||||
);
|
);
|
||||||
|
@ -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.
|
||||||
|
|
||||||
|
@ -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,36 @@ CheckAndMarkFixLoadingMemoryUsageBitMap (
|
|||||||
|
|
||||||
**/
|
**/
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
GetPeCoffImageFixLoadingAssignedAddress (
|
GetUefiImageFixLoadingAssignedAddress (
|
||||||
IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext,
|
OUT EFI_PHYSICAL_ADDRESS *LoadAddress,
|
||||||
IN PEI_CORE_INSTANCE *Private
|
IN UINT64 ValueInSectionHeader,
|
||||||
|
IN UINT32 ImageDestSize,
|
||||||
|
IN PEI_CORE_INSTANCE *Private
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
UINTN SectionHeaderOffset;
|
EFI_STATUS Status;
|
||||||
EFI_STATUS Status;
|
EFI_PHYSICAL_ADDRESS FixLoadingAddress;
|
||||||
EFI_IMAGE_SECTION_HEADER SectionHeader;
|
|
||||||
EFI_IMAGE_OPTIONAL_HEADER_UNION *ImgHdr;
|
|
||||||
EFI_PHYSICAL_ADDRESS FixLoadingAddress;
|
|
||||||
UINT16 Index;
|
|
||||||
UINTN Size;
|
|
||||||
UINT16 NumberOfSections;
|
|
||||||
UINT64 ValueInSectionHeader;
|
|
||||||
|
|
||||||
FixLoadingAddress = 0;
|
if ((INT64)PcdGet64(PcdLoadModuleAtFixAddressEnable) > 0) {
|
||||||
Status = EFI_NOT_FOUND;
|
|
||||||
|
|
||||||
//
|
|
||||||
// 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.
|
||||||
|
//
|
||||||
|
Status = CheckAndMarkFixLoadingMemoryUsageBitMap (Private, FixLoadingAddress, ImageDestSize);
|
||||||
|
*LoadAddress = FixLoadingAddress;
|
||||||
|
|
||||||
DEBUG ((DEBUG_INFO|DEBUG_LOAD, "LOADING MODULE FIXED INFO: Loading module at fixed address 0x%11p. Status= %r \n", (VOID *)(UINTN)FixLoadingAddress, Status));
|
DEBUG ((EFI_D_INFO|EFI_D_LOAD, "LOADING MODULE FIXED INFO: Loading module at fixed address 0x%11p. Status= %r \n", (VOID *)(UINTN)FixLoadingAddress, Status));
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -262,38 +153,49 @@ 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;
|
BOOLEAN Success;
|
||||||
PEI_CORE_INSTANCE *Private;
|
PEI_CORE_INSTANCE *Private;
|
||||||
UINT64 AlignImageSize;
|
UINT32 ImageSize;
|
||||||
|
UINT32 ImageAlignment;
|
||||||
|
UINT64 ValueInSectionHeader;
|
||||||
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;
|
||||||
|
UINT32 DestinationPages;
|
||||||
|
UINT32 DestinationSize;
|
||||||
|
EFI_PHYSICAL_ADDRESS Destination;
|
||||||
|
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 +214,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 +236,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 +245,95 @@ LoadAndRelocatePeCoffImage (
|
|||||||
DEBUG ((DEBUG_INFO|DEBUG_LOAD, "The image at 0x%08x without reloc section can't be loaded into memory\n", (UINTN)Pe32Data));
|
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.
|
ImageSize = UefiImageGetImageSize (ImageContext);
|
||||||
//
|
DestinationPages = EFI_SIZE_TO_PAGES (ImageSize);
|
||||||
ImageContext.ImageAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)Pe32Data;
|
DestinationSize = EFI_PAGES_TO_SIZE (DestinationPages);
|
||||||
|
|
||||||
//
|
//
|
||||||
// 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)))
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
//
|
Success = FALSE;
|
||||||
// Allocate more buffer to avoid buffer overflow.
|
|
||||||
//
|
if (PcdGet64(PcdLoadModuleAtFixAddressEnable) != 0 && (Private->HobList.HandoffInformationTable->BootMode != BOOT_ON_S3_RESUME)) {
|
||||||
if (ImageContext.IsTeImage) {
|
Status = UefiImageGetFixedAddress (ImageContext, &ValueInSectionHeader);
|
||||||
AlignImageSize = ImageContext.ImageSize + ((EFI_TE_IMAGE_HEADER *)Pe32Data)->StrippedSize - sizeof (EFI_TE_IMAGE_HEADER);
|
if (!RETURN_ERROR (Status)) {
|
||||||
} else {
|
Status = GetUefiImageFixLoadingAssignedAddress(&Destination, ValueInSectionHeader, DestinationSize, Private);
|
||||||
AlignImageSize = ImageContext.ImageSize;
|
}
|
||||||
|
|
||||||
|
if (!EFI_ERROR (Status)){
|
||||||
|
Success = Destination == UefiImageGetPreferredAddress (ImageContext);
|
||||||
|
|
||||||
|
if (!Success) {
|
||||||
|
DEBUG ((DEBUG_INFO|DEBUG_LOAD, "LOADING MODULE FIXED ERROR: Loading module at fixed address failed since relocs have been stripped.\n"));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
DEBUG ((EFI_D_INFO|EFI_D_LOAD, "LOADING MODULE FIXED ERROR: Failed to load module at fixed address. \n"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ImageContext.SectionAlignment > EFI_PAGE_SIZE) {
|
if (!Success) {
|
||||||
AlignImageSize += ImageContext.SectionAlignment;
|
//
|
||||||
|
// Allocate more buffer to avoid buffer overflow.
|
||||||
|
//
|
||||||
|
ImageAlignment = UefiImageGetSegmentAlignment (ImageContext);
|
||||||
|
|
||||||
|
Destination = (UINTN)AllocateAlignedCodePages (
|
||||||
|
DestinationPages,
|
||||||
|
ImageAlignment
|
||||||
|
);
|
||||||
|
Success = Destination != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((PcdGet64 (PcdLoadModuleAtFixAddressEnable) != 0) && (Private->HobList.HandoffInformationTable->BootMode != BOOT_ON_S3_RESUME)) {
|
if (Success) {
|
||||||
Status = GetPeCoffImageFixLoadingAssignedAddress (&ImageContext, Private);
|
LoadDynamically = TRUE;
|
||||||
|
//
|
||||||
|
// Load the image to our new buffer
|
||||||
|
//
|
||||||
|
Status = UefiImageLoadImageForExecution (
|
||||||
|
ImageContext,
|
||||||
|
(VOID *) (UINTN)Destination,
|
||||||
|
DestinationSize,
|
||||||
|
NULL,
|
||||||
|
0
|
||||||
|
);
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
DEBUG ((DEBUG_INFO|DEBUG_LOAD, "LOADING MODULE FIXED ERROR: Failed to load module at fixed address. \n"));
|
return Status;
|
||||||
//
|
|
||||||
// The PEIM is not assigned valid address, try to allocate page to load it.
|
|
||||||
//
|
|
||||||
Status = PeiServicesAllocatePages (
|
|
||||||
EfiBootServicesCode,
|
|
||||||
EFI_SIZE_TO_PAGES ((UINT32)AlignImageSize),
|
|
||||||
&ImageContext.ImageAddress
|
|
||||||
);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Status = PeiServicesAllocatePages (
|
|
||||||
EfiBootServicesCode,
|
|
||||||
EFI_SIZE_TO_PAGES ((UINT32)AlignImageSize),
|
|
||||||
&ImageContext.ImageAddress
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!EFI_ERROR (Status)) {
|
|
||||||
//
|
|
||||||
// Adjust the Image Address to make sure it is section alignment.
|
|
||||||
//
|
|
||||||
if (ImageContext.SectionAlignment > EFI_PAGE_SIZE) {
|
|
||||||
ImageContext.ImageAddress =
|
|
||||||
(ImageContext.ImageAddress + ImageContext.SectionAlignment - 1) &
|
|
||||||
~((UINTN)ImageContext.SectionAlignment - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Fix alignment requirement when Load IPF TeImage into memory.
|
|
||||||
// Skip the reserved space for the stripped PeHeader when load TeImage into memory.
|
|
||||||
//
|
|
||||||
if (ImageContext.IsTeImage) {
|
|
||||||
ImageContext.ImageAddress = ImageContext.ImageAddress +
|
|
||||||
((EFI_TE_IMAGE_HEADER *)Pe32Data)->StrippedSize -
|
|
||||||
sizeof (EFI_TE_IMAGE_HEADER);
|
|
||||||
}
|
}
|
||||||
} 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 +349,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 +390,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 +413,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 +470,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 +491,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 +525,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 +540,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 +631,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 +680,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 +713,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 +741,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 +754,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;
|
||||||
}
|
}
|
||||||
|
@ -36,12 +36,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 <Library/TimerLib.h>
|
#include <Library/TimerLib.h>
|
||||||
@ -312,7 +311,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;
|
||||||
|
|
||||||
@ -929,6 +928,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.
|
||||||
|
|
||||||
@ -944,6 +945,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
|
||||||
);
|
);
|
||||||
@ -995,6 +997,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
|
||||||
|
|
||||||
@ -1417,9 +1446,10 @@ InitializeImageServices (
|
|||||||
|
|
||||||
**/
|
**/
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
LoadAndRelocatePeCoffImageInPlace (
|
LoadAndRelocateUefiImageInPlace (
|
||||||
IN VOID *Pe32Data,
|
IN VOID *Pe32Data,
|
||||||
IN VOID *ImageAddress
|
IN VOID *ImageAddress,
|
||||||
|
IN UINT32 ImageSize
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1435,7 +1465,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
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -53,7 +53,6 @@
|
|||||||
|
|
||||||
[LibraryClasses]
|
[LibraryClasses]
|
||||||
BaseMemoryLib
|
BaseMemoryLib
|
||||||
PeCoffGetEntryPointLib
|
|
||||||
ReportStatusCodeLib
|
ReportStatusCodeLib
|
||||||
PeiServicesLib
|
PeiServicesLib
|
||||||
PerformanceLib
|
PerformanceLib
|
||||||
@ -63,7 +62,7 @@
|
|||||||
DebugLib
|
DebugLib
|
||||||
MemoryAllocationLib
|
MemoryAllocationLib
|
||||||
CacheMaintenanceLib
|
CacheMaintenanceLib
|
||||||
PeCoffLib
|
UefiImageLib
|
||||||
PeiServicesTablePointerLib
|
PeiServicesTablePointerLib
|
||||||
PcdLib
|
PcdLib
|
||||||
TimerLib
|
TimerLib
|
||||||
|
@ -65,6 +65,7 @@ EFI_PEI_SERVICES gPs = {
|
|||||||
PeiFfsGetFileInfo2,
|
PeiFfsGetFileInfo2,
|
||||||
PeiResetSystem2,
|
PeiResetSystem2,
|
||||||
PeiFreePages,
|
PeiFreePages,
|
||||||
|
PeiFfsFindSectionData4
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1082,14 +1082,16 @@ ConvertPeiCorePpiPointers (
|
|||||||
IN PEI_CORE_FV_HANDLE *CoreFvHandle
|
IN PEI_CORE_FV_HANDLE *CoreFvHandle
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
EFI_FV_FILE_INFO FileInfo;
|
EFI_FV_FILE_INFO FileInfo;
|
||||||
EFI_PHYSICAL_ADDRESS OrgImageBase;
|
EFI_PHYSICAL_ADDRESS OrgImageBase;
|
||||||
EFI_PHYSICAL_ADDRESS MigratedImageBase;
|
EFI_PHYSICAL_ADDRESS MigratedImageBase;
|
||||||
UINTN PeiCoreModuleSize;
|
UINTN PeiCoreModuleSize;
|
||||||
EFI_PEI_FILE_HANDLE PeiCoreFileHandle;
|
EFI_PEI_FILE_HANDLE PeiCoreFileHandle;
|
||||||
VOID *PeiCoreImageBase;
|
VOID *PeiCoreImageBase;
|
||||||
VOID *PeiCoreEntryPoint;
|
UINT32 PeiCoreImageSize;
|
||||||
EFI_STATUS Status;
|
//VOID *PeiCoreEntryPoint;
|
||||||
|
EFI_STATUS Status;
|
||||||
|
UEFI_IMAGE_LOADER_IMAGE_CONTEXT ImageContext;
|
||||||
|
|
||||||
PeiCoreFileHandle = NULL;
|
PeiCoreFileHandle = NULL;
|
||||||
|
|
||||||
@ -1108,17 +1110,18 @@ ConvertPeiCorePpiPointers (
|
|||||||
Status = CoreFvHandle->FvPpi->GetFileInfo (CoreFvHandle->FvPpi, PeiCoreFileHandle, &FileInfo);
|
Status = CoreFvHandle->FvPpi->GetFileInfo (CoreFvHandle->FvPpi, PeiCoreFileHandle, &FileInfo);
|
||||||
ASSERT_EFI_ERROR (Status);
|
ASSERT_EFI_ERROR (Status);
|
||||||
|
|
||||||
Status = PeiGetPe32Data (PeiCoreFileHandle, &PeiCoreImageBase);
|
Status = PeiGetPe32Data (PeiCoreFileHandle, &PeiCoreImageBase, &PeiCoreImageSize);
|
||||||
ASSERT_EFI_ERROR (Status);
|
ASSERT_EFI_ERROR (Status);
|
||||||
|
|
||||||
//
|
//
|
||||||
// Find PEI Core EntryPoint in the BFV in temporary memory.
|
// Find PEI Core EntryPoint in the BFV in temporary memory.
|
||||||
//
|
//
|
||||||
Status = PeCoffLoaderGetEntryPoint ((VOID *)(UINTN)PeiCoreImageBase, &PeiCoreEntryPoint);
|
// FIXME: "Assume" sanity and skip full initialisation?
|
||||||
|
Status = UefiImageInitializeContext (&ImageContext, (VOID *) (UINTN) PeiCoreImageBase, PeiCoreImageSize);
|
||||||
ASSERT_EFI_ERROR (Status);
|
ASSERT_EFI_ERROR (Status);
|
||||||
|
|
||||||
OrgImageBase = (UINTN)PeiCoreImageBase;
|
OrgImageBase = (UINTN)PeiCoreImageBase;
|
||||||
MigratedImageBase = (UINTN)_ModuleEntryPoint - ((UINTN)PeiCoreEntryPoint - (UINTN)PeiCoreImageBase);
|
MigratedImageBase = (UINTN)_ModuleEntryPoint - UefiImageGetEntryPointAddress (&ImageContext);
|
||||||
|
|
||||||
//
|
//
|
||||||
// Size of loaded PEI_CORE in permanent memory.
|
// Size of loaded PEI_CORE in permanent memory.
|
||||||
|
153
MdeModulePkg/Core/PiSmmCore/DebugImageInfo.c
Normal file
153
MdeModulePkg/Core/PiSmmCore/DebugImageInfo.c
Normal file
@ -0,0 +1,153 @@
|
|||||||
|
/** @file
|
||||||
|
Support functions for managing debug image info table when loading and unloading
|
||||||
|
images.
|
||||||
|
|
||||||
|
Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||||
|
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||||
|
|
||||||
|
**/
|
||||||
|
|
||||||
|
#include "PiSmmCore.h"
|
||||||
|
|
||||||
|
// FIXME: Unify with DXE
|
||||||
|
|
||||||
|
EFI_DEBUG_IMAGE_INFO_TABLE_HEADER mDebugInfoTableHeader = {
|
||||||
|
0, // volatile UINT32 UpdateStatus;
|
||||||
|
0, // UINT32 TableSize;
|
||||||
|
NULL // EFI_DEBUG_IMAGE_INFO *EfiDebugImageInfoTable;
|
||||||
|
};
|
||||||
|
|
||||||
|
UINTN mMaxTableEntries = 0;
|
||||||
|
|
||||||
|
#define EFI_DEBUG_TABLE_ENTRY_SIZE (sizeof (VOID *))
|
||||||
|
|
||||||
|
/**
|
||||||
|
Creates and initializes the DebugImageInfo Table. Also creates the configuration
|
||||||
|
table and registers it into the system table.
|
||||||
|
|
||||||
|
**/
|
||||||
|
VOID
|
||||||
|
SmmInitializeDebugImageInfoTable (
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
{
|
||||||
|
EFI_STATUS Status;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Install the EFI_SYSTEM_TABLE_POINTER structure in the EFI System
|
||||||
|
// Configuration Table
|
||||||
|
//
|
||||||
|
Status = SmmInstallConfigurationTable (
|
||||||
|
gSmst,
|
||||||
|
&gEfiDebugImageInfoTableGuid,
|
||||||
|
&mDebugInfoTableHeader,
|
||||||
|
sizeof (mDebugInfoTableHeader)
|
||||||
|
);
|
||||||
|
ASSERT_EFI_ERROR (Status);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Adds a new DebugImageInfo structure to the DebugImageInfo Table. Re-Allocates
|
||||||
|
the table if it's not large enough to accomidate another entry.
|
||||||
|
|
||||||
|
@param ImageInfoType type of debug image information
|
||||||
|
@param LoadedImage pointer to the loaded image protocol for the image being
|
||||||
|
loaded
|
||||||
|
@param ImageHandle image handle for the image being loaded
|
||||||
|
|
||||||
|
**/
|
||||||
|
VOID
|
||||||
|
SmmNewDebugImageInfoEntry (
|
||||||
|
IN UINT32 ImageInfoType,
|
||||||
|
IN EFI_LOADED_IMAGE_PROTOCOL *LoadedImage,
|
||||||
|
IN EFI_HANDLE ImageHandle,
|
||||||
|
IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext
|
||||||
|
)
|
||||||
|
{
|
||||||
|
EFI_DEBUG_IMAGE_INFO *Table;
|
||||||
|
EFI_DEBUG_IMAGE_INFO *NewTable;
|
||||||
|
UINTN Index;
|
||||||
|
UINTN TableSize;
|
||||||
|
EFI_DEBUG_IMAGE_INFO_NORMAL *NormalImage;
|
||||||
|
RETURN_STATUS Status;
|
||||||
|
CONST CHAR8 *PdbPath;
|
||||||
|
UINT32 PdbPathSize;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Set the flag indicating that we're in the process of updating the table.
|
||||||
|
//
|
||||||
|
mDebugInfoTableHeader.UpdateStatus |= EFI_DEBUG_IMAGE_INFO_UPDATE_IN_PROGRESS;
|
||||||
|
|
||||||
|
Table = mDebugInfoTableHeader.EfiDebugImageInfoTable;
|
||||||
|
|
||||||
|
if (mDebugInfoTableHeader.TableSize < mMaxTableEntries) {
|
||||||
|
//
|
||||||
|
// We still have empty entires in the Table, find the first empty entry.
|
||||||
|
//
|
||||||
|
Index = 0;
|
||||||
|
while (Table[Index].NormalImage != NULL) {
|
||||||
|
Index++;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// There must be an empty entry in the in the table.
|
||||||
|
//
|
||||||
|
ASSERT (Index < mMaxTableEntries);
|
||||||
|
} else {
|
||||||
|
//
|
||||||
|
// Table is full, so re-allocate another page for a larger table...
|
||||||
|
//
|
||||||
|
TableSize = mMaxTableEntries * EFI_DEBUG_TABLE_ENTRY_SIZE;
|
||||||
|
NewTable = AllocateZeroPool (TableSize + EFI_PAGE_SIZE);
|
||||||
|
if (NewTable == NULL) {
|
||||||
|
mDebugInfoTableHeader.UpdateStatus &= ~EFI_DEBUG_IMAGE_INFO_UPDATE_IN_PROGRESS;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Copy the old table into the new one
|
||||||
|
//
|
||||||
|
CopyMem (NewTable, Table, TableSize);
|
||||||
|
mDebugInfoTableHeader.EfiDebugImageInfoTable = NewTable;
|
||||||
|
//
|
||||||
|
// Enlarge the max table entries.
|
||||||
|
//
|
||||||
|
mMaxTableEntries += EFI_PAGE_SIZE / EFI_DEBUG_TABLE_ENTRY_SIZE;
|
||||||
|
//
|
||||||
|
// Free the old table
|
||||||
|
//
|
||||||
|
SmmFreePool (Table);
|
||||||
|
//
|
||||||
|
// Update the table header
|
||||||
|
//
|
||||||
|
Table = NewTable;
|
||||||
|
//
|
||||||
|
// Set the first empty entry index to be the original max table entries.
|
||||||
|
//
|
||||||
|
Index = mMaxTableEntries;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Allocate data for new entry
|
||||||
|
//
|
||||||
|
NormalImage = AllocateZeroPool (sizeof (EFI_DEBUG_IMAGE_INFO_NORMAL));
|
||||||
|
if (NormalImage != NULL) {
|
||||||
|
//
|
||||||
|
// Update the entry
|
||||||
|
//
|
||||||
|
NormalImage->ImageInfoType = (UINT32) ImageInfoType;
|
||||||
|
NormalImage->LoadedImageProtocolInstance = LoadedImage;
|
||||||
|
NormalImage->ImageHandle = ImageHandle;
|
||||||
|
|
||||||
|
Status = UefiImageGetSymbolsPath (ImageContext, &PdbPath, &PdbPathSize);
|
||||||
|
if (!RETURN_ERROR (Status)) {
|
||||||
|
NormalImage->PdbPath = AllocateCopyPool (PdbPathSize, PdbPath);
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Increase the number of EFI_DEBUG_IMAGE_INFO elements and set the mDebugInfoTable in modified status.
|
||||||
|
//
|
||||||
|
mDebugInfoTableHeader.UpdateStatus |= EFI_DEBUG_IMAGE_INFO_TABLE_MODIFIED;
|
||||||
|
Table[Index].NormalImage = NormalImage;
|
||||||
|
mDebugInfoTableHeader.TableSize++;
|
||||||
|
}
|
||||||
|
mDebugInfoTableHeader.UpdateStatus &= ~EFI_DEBUG_IMAGE_INFO_UPDATE_IN_PROGRESS;
|
||||||
|
}
|
@ -33,7 +33,9 @@
|
|||||||
|
|
||||||
**/
|
**/
|
||||||
|
|
||||||
|
#include "Library/UefiImageLib.h"
|
||||||
#include "PiSmmCore.h"
|
#include "PiSmmCore.h"
|
||||||
|
#include "Uefi/UefiBaseType.h"
|
||||||
|
|
||||||
//
|
//
|
||||||
// SMM Dispatcher Data structures
|
// SMM Dispatcher Data structures
|
||||||
@ -213,84 +215,18 @@ CheckAndMarkFixLoadingMemoryUsageBitMap (
|
|||||||
|
|
||||||
**/
|
**/
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
GetPeCoffImageFixLoadingAssignedAddress (
|
GetUefiImageFixLoadingAssignedAddress (
|
||||||
IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext
|
OUT EFI_PHYSICAL_ADDRESS *LoadAddress,
|
||||||
|
IN UINT64 ValueInSectionHeader,
|
||||||
|
IN UINT32 ImageDestSize
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
UINTN SectionHeaderOffset;
|
RETURN_STATUS Status;
|
||||||
EFI_STATUS Status;
|
EFI_PHYSICAL_ADDRESS FixLoadingAddress;
|
||||||
EFI_IMAGE_SECTION_HEADER SectionHeader;
|
|
||||||
EFI_IMAGE_OPTIONAL_HEADER_UNION *ImgHdr;
|
|
||||||
EFI_PHYSICAL_ADDRESS FixLoadingAddress;
|
|
||||||
UINT16 Index;
|
|
||||||
UINTN Size;
|
|
||||||
UINT16 NumberOfSections;
|
|
||||||
UINT64 ValueInSectionHeader;
|
|
||||||
|
|
||||||
FixLoadingAddress = 0;
|
FixLoadingAddress = (EFI_PHYSICAL_ADDRESS)(gLoadModuleAtFixAddressSmramBase + ValueInSectionHeader);
|
||||||
Status = EFI_NOT_FOUND;
|
Status = CheckAndMarkFixLoadingMemoryUsageBitMap (FixLoadingAddress, ImageDestSize);
|
||||||
|
*LoadAddress = FixLoadingAddress;
|
||||||
//
|
|
||||||
// Get PeHeader pointer
|
|
||||||
//
|
|
||||||
ImgHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)((CHAR8 *)ImageContext->Handle + ImageContext->PeCoffHeaderOffset);
|
|
||||||
SectionHeaderOffset = ImageContext->PeCoffHeaderOffset +
|
|
||||||
sizeof (UINT32) +
|
|
||||||
sizeof (EFI_IMAGE_FILE_HEADER) +
|
|
||||||
ImgHdr->Pe32.FileHeader.SizeOfOptionalHeader;
|
|
||||||
NumberOfSections = ImgHdr->Pe32.FileHeader.NumberOfSections;
|
|
||||||
|
|
||||||
//
|
|
||||||
// Get base address from the first section header that doesn't point to code section.
|
|
||||||
//
|
|
||||||
for (Index = 0; Index < NumberOfSections; Index++) {
|
|
||||||
//
|
|
||||||
// Read section header from file
|
|
||||||
//
|
|
||||||
Size = sizeof (EFI_IMAGE_SECTION_HEADER);
|
|
||||||
Status = ImageContext->ImageRead (
|
|
||||||
ImageContext->Handle,
|
|
||||||
SectionHeaderOffset,
|
|
||||||
&Size,
|
|
||||||
&SectionHeader
|
|
||||||
);
|
|
||||||
if (EFI_ERROR (Status)) {
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
Status = EFI_NOT_FOUND;
|
|
||||||
|
|
||||||
if ((SectionHeader.Characteristics & EFI_IMAGE_SCN_CNT_CODE) == 0) {
|
|
||||||
//
|
|
||||||
// Build tool will save the address in PointerToRelocations & PointerToLineNumbers fields in the first section header
|
|
||||||
// that doesn't point to code section in image header.So there is an assumption that when the feature is enabled,
|
|
||||||
// if a module with a loading address assigned by tools, the PointerToRelocations & PointerToLineNumbers fields
|
|
||||||
// should not be Zero, or else, these 2 fields should be set to Zero
|
|
||||||
//
|
|
||||||
ValueInSectionHeader = ReadUnaligned64 ((UINT64 *)&SectionHeader.PointerToRelocations);
|
|
||||||
if (ValueInSectionHeader != 0) {
|
|
||||||
//
|
|
||||||
// Found first section header that doesn't point to code section in which build tool saves the
|
|
||||||
// offset to SMRAM base as image base in PointerToRelocations & PointerToLineNumbers fields
|
|
||||||
//
|
|
||||||
FixLoadingAddress = (EFI_PHYSICAL_ADDRESS)(gLoadModuleAtFixAddressSmramBase + (INT64)ValueInSectionHeader);
|
|
||||||
//
|
|
||||||
// Check if the memory range is available.
|
|
||||||
//
|
|
||||||
Status = CheckAndMarkFixLoadingMemoryUsageBitMap (FixLoadingAddress, (UINTN)(ImageContext->ImageSize + ImageContext->SectionAlignment));
|
|
||||||
if (!EFI_ERROR (Status)) {
|
|
||||||
//
|
|
||||||
// The assigned address is valid. Return the specified loading address
|
|
||||||
//
|
|
||||||
ImageContext->ImageAddress = FixLoadingAddress;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
SectionHeaderOffset += sizeof (EFI_IMAGE_SECTION_HEADER);
|
|
||||||
}
|
|
||||||
|
|
||||||
DEBUG ((DEBUG_INFO|DEBUG_LOAD, "LOADING MODULE FIXED INFO: Loading module at fixed address %x, Status = %r\n", FixLoadingAddress, Status));
|
DEBUG ((DEBUG_INFO|DEBUG_LOAD, "LOADING MODULE FIXED INFO: Loading module at fixed address %x, Status = %r\n", FixLoadingAddress, Status));
|
||||||
return Status;
|
return Status;
|
||||||
@ -307,24 +243,29 @@ GetPeCoffImageFixLoadingAssignedAddress (
|
|||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
EFIAPI
|
EFIAPI
|
||||||
SmmLoadImage (
|
SmmLoadImage (
|
||||||
IN OUT EFI_SMM_DRIVER_ENTRY *DriverEntry
|
IN OUT EFI_SMM_DRIVER_ENTRY *DriverEntry,
|
||||||
|
OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
UINT32 AuthenticationStatus;
|
UINT32 AuthenticationStatus;
|
||||||
UINTN FilePathSize;
|
UINTN FilePathSize;
|
||||||
VOID *Buffer;
|
VOID *Buffer;
|
||||||
UINTN Size;
|
UINTN Size;
|
||||||
UINTN PageCount;
|
UINT32 DstBufferPages;
|
||||||
EFI_GUID *NameGuid;
|
EFI_GUID *NameGuid;
|
||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
EFI_STATUS SecurityStatus;
|
EFI_STATUS SecurityStatus;
|
||||||
EFI_HANDLE DeviceHandle;
|
EFI_HANDLE DeviceHandle;
|
||||||
EFI_PHYSICAL_ADDRESS DstBuffer;
|
UINT32 ImageSize;
|
||||||
|
UINT32 ImageAlignment;
|
||||||
|
UINT64 ValueInSectionHeader;
|
||||||
|
VOID *DstBuffer;
|
||||||
|
UINT32 DstBufferSize;
|
||||||
EFI_DEVICE_PATH_PROTOCOL *FilePath;
|
EFI_DEVICE_PATH_PROTOCOL *FilePath;
|
||||||
EFI_DEVICE_PATH_PROTOCOL *OriginalFilePath;
|
EFI_DEVICE_PATH_PROTOCOL *OriginalFilePath;
|
||||||
EFI_DEVICE_PATH_PROTOCOL *HandleFilePath;
|
EFI_DEVICE_PATH_PROTOCOL *HandleFilePath;
|
||||||
EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv;
|
EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv;
|
||||||
PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;
|
EFI_PHYSICAL_ADDRESS LoadAddress;
|
||||||
|
|
||||||
PERF_LOAD_IMAGE_BEGIN (DriverEntry->ImageHandle);
|
PERF_LOAD_IMAGE_BEGIN (DriverEntry->ImageHandle);
|
||||||
|
|
||||||
@ -413,6 +354,18 @@ SmmLoadImage (
|
|||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Get information about the image being loaded
|
||||||
|
//
|
||||||
|
Status = UefiImageInitializeContextPreHash (ImageContext, Buffer, (UINT32) Size);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
if (Buffer != NULL) {
|
||||||
|
gBS->FreePool (Buffer);
|
||||||
|
}
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME: Context?
|
||||||
//
|
//
|
||||||
// Verify File Authentication through the Security2 Architectural Protocol
|
// Verify File Authentication through the Security2 Architectural Protocol
|
||||||
//
|
//
|
||||||
@ -420,8 +373,8 @@ SmmLoadImage (
|
|||||||
SecurityStatus = mSecurity2->FileAuthentication (
|
SecurityStatus = mSecurity2->FileAuthentication (
|
||||||
mSecurity2,
|
mSecurity2,
|
||||||
OriginalFilePath,
|
OriginalFilePath,
|
||||||
Buffer,
|
ImageContext,
|
||||||
Size,
|
sizeof (*ImageContext),
|
||||||
FALSE
|
FALSE
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -444,24 +397,23 @@ SmmLoadImage (
|
|||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
Status = UefiImageInitializeContextPostHash (ImageContext);
|
||||||
// Initialize ImageContext
|
if (RETURN_ERROR (Status)) {
|
||||||
//
|
|
||||||
ImageContext.Handle = Buffer;
|
|
||||||
ImageContext.ImageRead = PeCoffLoaderImageReadFromMemory;
|
|
||||||
|
|
||||||
//
|
|
||||||
// Get information about the image being loaded
|
|
||||||
//
|
|
||||||
Status = PeCoffLoaderGetImageInfo (&ImageContext);
|
|
||||||
if (EFI_ERROR (Status)) {
|
|
||||||
if (Buffer != NULL) {
|
|
||||||
gBS->FreePool (Buffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Stripped relocations are not supported for both fixed-address and dynamic
|
||||||
|
// loading.
|
||||||
|
//
|
||||||
|
if (UefiImageGetRelocsStripped (ImageContext)) {
|
||||||
|
return EFI_UNSUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
ImageSize = UefiImageGetImageSize (ImageContext);
|
||||||
|
DstBufferPages = EFI_SIZE_TO_PAGES (ImageSize);
|
||||||
|
DstBufferSize = EFI_PAGES_TO_SIZE (DstBufferPages);
|
||||||
|
ImageAlignment = UefiImageGetSegmentAlignment (ImageContext);
|
||||||
//
|
//
|
||||||
// if Loading module at Fixed Address feature is enabled, then cut out a memory range started from TESG BASE
|
// if Loading module at Fixed Address feature is enabled, then cut out a memory range started from TESG BASE
|
||||||
// to hold the Smm driver code
|
// to hold the Smm driver code
|
||||||
@ -470,102 +422,68 @@ SmmLoadImage (
|
|||||||
//
|
//
|
||||||
// Get the fixed loading address assigned by Build tool
|
// Get the fixed loading address assigned by Build tool
|
||||||
//
|
//
|
||||||
Status = GetPeCoffImageFixLoadingAssignedAddress (&ImageContext);
|
Status = UefiImageGetFixedAddress (ImageContext, &ValueInSectionHeader);
|
||||||
|
if (!RETURN_ERROR (Status)) {
|
||||||
|
Status = GetUefiImageFixLoadingAssignedAddress (&LoadAddress, ValueInSectionHeader, DstBufferSize);
|
||||||
|
}
|
||||||
|
|
||||||
if (!EFI_ERROR (Status)) {
|
if (!EFI_ERROR (Status)) {
|
||||||
//
|
//
|
||||||
// Since the memory range to load Smm core already been cut out, so no need to allocate and free this range
|
// Since the memory range to load Smm core already been cut out, so no need to allocate and free this range
|
||||||
// following statements is to bypass SmmFreePages
|
// following statements is to bypass SmmFreePages
|
||||||
//
|
//
|
||||||
PageCount = 0;
|
DstBufferPages = 0;
|
||||||
DstBuffer = (UINTN)gLoadModuleAtFixAddressSmramBase;
|
DstBuffer = (VOID *)(UINTN)LoadAddress;
|
||||||
} else {
|
} else {
|
||||||
DEBUG ((DEBUG_INFO|DEBUG_LOAD, "LOADING MODULE FIXED ERROR: Failed to load module at fixed address. \n"));
|
DEBUG ((DEBUG_INFO|DEBUG_LOAD, "LOADING MODULE FIXED ERROR: Failed to load module at fixed address. \n"));
|
||||||
//
|
//
|
||||||
// allocate the memory to load the SMM driver
|
// allocate the memory to load the SMM driver
|
||||||
//
|
//
|
||||||
PageCount = (UINTN)EFI_SIZE_TO_PAGES ((UINTN)ImageContext.ImageSize + ImageContext.SectionAlignment);
|
DstBuffer = AllocateAlignedCodePages (DstBufferPages, ImageAlignment);
|
||||||
DstBuffer = (UINTN)(-1);
|
if (DstBuffer == NULL) {
|
||||||
|
|
||||||
Status = SmmAllocatePages (
|
|
||||||
AllocateMaxAddress,
|
|
||||||
EfiRuntimeServicesCode,
|
|
||||||
PageCount,
|
|
||||||
&DstBuffer
|
|
||||||
);
|
|
||||||
if (EFI_ERROR (Status)) {
|
|
||||||
if (Buffer != NULL) {
|
if (Buffer != NULL) {
|
||||||
gBS->FreePool (Buffer);
|
gBS->FreePool (Buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Status;
|
return EFI_OUT_OF_RESOURCES;
|
||||||
}
|
}
|
||||||
|
|
||||||
ImageContext.ImageAddress = (EFI_PHYSICAL_ADDRESS)DstBuffer;
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
PageCount = (UINTN)EFI_SIZE_TO_PAGES ((UINTN)ImageContext.ImageSize + ImageContext.SectionAlignment);
|
DstBuffer = AllocateAlignedCodePages (DstBufferPages, ImageAlignment);
|
||||||
DstBuffer = (UINTN)(-1);
|
if (DstBuffer == NULL) {
|
||||||
|
|
||||||
Status = SmmAllocatePages (
|
|
||||||
AllocateMaxAddress,
|
|
||||||
EfiRuntimeServicesCode,
|
|
||||||
PageCount,
|
|
||||||
&DstBuffer
|
|
||||||
);
|
|
||||||
if (EFI_ERROR (Status)) {
|
|
||||||
if (Buffer != NULL) {
|
if (Buffer != NULL) {
|
||||||
gBS->FreePool (Buffer);
|
gBS->FreePool (Buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Status;
|
return EFI_OUT_OF_RESOURCES;
|
||||||
}
|
}
|
||||||
|
|
||||||
ImageContext.ImageAddress = (EFI_PHYSICAL_ADDRESS)DstBuffer;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// Align buffer on section boundary
|
|
||||||
//
|
|
||||||
ImageContext.ImageAddress += ImageContext.SectionAlignment - 1;
|
|
||||||
ImageContext.ImageAddress &= ~((EFI_PHYSICAL_ADDRESS)ImageContext.SectionAlignment - 1);
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Load the image to our new buffer
|
// Load the image to our new buffer
|
||||||
//
|
//
|
||||||
Status = PeCoffLoaderLoadImage (&ImageContext);
|
Status = UefiImageLoadImageForExecution (
|
||||||
|
ImageContext,
|
||||||
|
DstBuffer,
|
||||||
|
DstBufferSize,
|
||||||
|
NULL,
|
||||||
|
0
|
||||||
|
);
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
if (Buffer != NULL) {
|
if (Buffer != NULL) {
|
||||||
gBS->FreePool (Buffer);
|
gBS->FreePool (Buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
SmmFreePages (DstBuffer, PageCount);
|
FreeAlignedPages (DstBuffer, DstBufferPages);
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// Relocate the image in our new buffer
|
|
||||||
//
|
|
||||||
Status = PeCoffLoaderRelocateImage (&ImageContext);
|
|
||||||
if (EFI_ERROR (Status)) {
|
|
||||||
if (Buffer != NULL) {
|
|
||||||
gBS->FreePool (Buffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
SmmFreePages (DstBuffer, PageCount);
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Flush the instruction cache so the image data are written before we execute it
|
|
||||||
//
|
|
||||||
InvalidateInstructionCacheRange ((VOID *)(UINTN)ImageContext.ImageAddress, (UINTN)ImageContext.ImageSize);
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Save Image EntryPoint in DriverEntry
|
// Save Image EntryPoint in DriverEntry
|
||||||
//
|
//
|
||||||
DriverEntry->ImageEntryPoint = ImageContext.EntryPoint;
|
DriverEntry->ImageEntryPoint = UefiImageLoaderGetImageEntryPoint (ImageContext);
|
||||||
DriverEntry->ImageBuffer = DstBuffer;
|
DriverEntry->ImageBuffer = (UINTN)DstBuffer;
|
||||||
DriverEntry->NumberOfPage = PageCount;
|
DriverEntry->NumberOfPage = DstBufferPages;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Allocate a Loaded Image Protocol in EfiBootServicesData
|
// Allocate a Loaded Image Protocol in EfiBootServicesData
|
||||||
@ -576,7 +494,7 @@ SmmLoadImage (
|
|||||||
gBS->FreePool (Buffer);
|
gBS->FreePool (Buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
SmmFreePages (DstBuffer, PageCount);
|
FreeAlignedPages (DstBuffer, DstBufferPages);
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -604,14 +522,14 @@ SmmLoadImage (
|
|||||||
gBS->FreePool (Buffer);
|
gBS->FreePool (Buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
SmmFreePages (DstBuffer, PageCount);
|
FreeAlignedPages (DstBuffer, DstBufferPages);
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
CopyMem (DriverEntry->LoadedImage->FilePath, FilePath, GetDevicePathSize (FilePath));
|
CopyMem (DriverEntry->LoadedImage->FilePath, FilePath, GetDevicePathSize (FilePath));
|
||||||
|
|
||||||
DriverEntry->LoadedImage->ImageBase = (VOID *)(UINTN)ImageContext.ImageAddress;
|
DriverEntry->LoadedImage->ImageBase = DstBuffer;
|
||||||
DriverEntry->LoadedImage->ImageSize = ImageContext.ImageSize;
|
DriverEntry->LoadedImage->ImageSize = ImageSize;
|
||||||
DriverEntry->LoadedImage->ImageCodeType = EfiRuntimeServicesCode;
|
DriverEntry->LoadedImage->ImageCodeType = EfiRuntimeServicesCode;
|
||||||
DriverEntry->LoadedImage->ImageDataType = EfiRuntimeServicesData;
|
DriverEntry->LoadedImage->ImageDataType = EfiRuntimeServicesData;
|
||||||
|
|
||||||
@ -625,14 +543,14 @@ SmmLoadImage (
|
|||||||
}
|
}
|
||||||
|
|
||||||
gBS->FreePool (DriverEntry->LoadedImage->FilePath);
|
gBS->FreePool (DriverEntry->LoadedImage->FilePath);
|
||||||
SmmFreePages (DstBuffer, PageCount);
|
FreeAlignedPages (DstBuffer, DstBufferPages);
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
CopyMem (DriverEntry->SmmLoadedImage.FilePath, FilePath, GetDevicePathSize (FilePath));
|
CopyMem (DriverEntry->SmmLoadedImage.FilePath, FilePath, GetDevicePathSize(FilePath));
|
||||||
|
|
||||||
DriverEntry->SmmLoadedImage.ImageBase = (VOID *)(UINTN)ImageContext.ImageAddress;
|
DriverEntry->SmmLoadedImage.ImageBase = DstBuffer;
|
||||||
DriverEntry->SmmLoadedImage.ImageSize = ImageContext.ImageSize;
|
DriverEntry->SmmLoadedImage.ImageSize = ImageSize;
|
||||||
DriverEntry->SmmLoadedImage.ImageCodeType = EfiRuntimeServicesCode;
|
DriverEntry->SmmLoadedImage.ImageCodeType = EfiRuntimeServicesCode;
|
||||||
DriverEntry->SmmLoadedImage.ImageDataType = EfiRuntimeServicesData;
|
DriverEntry->SmmLoadedImage.ImageDataType = EfiRuntimeServicesData;
|
||||||
|
|
||||||
@ -660,60 +578,42 @@ SmmLoadImage (
|
|||||||
|
|
||||||
PERF_LOAD_IMAGE_END (DriverEntry->ImageHandle);
|
PERF_LOAD_IMAGE_END (DriverEntry->ImageHandle);
|
||||||
|
|
||||||
|
SmmInsertImageRecord (&DriverEntry->SmmLoadedImage, ImageContext);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Register the image in the Debug Image Info Table if the attribute is set
|
||||||
|
//
|
||||||
|
SmmNewDebugImageInfoEntry (
|
||||||
|
EFI_DEBUG_IMAGE_INFO_TYPE_NORMAL,
|
||||||
|
&DriverEntry->SmmLoadedImage,
|
||||||
|
DriverEntry->SmmImageHandle,
|
||||||
|
ImageContext
|
||||||
|
);
|
||||||
|
|
||||||
//
|
//
|
||||||
// Print the load address and the PDB file name if it is available
|
// Print the load address and the PDB file name if it is available
|
||||||
//
|
//
|
||||||
|
|
||||||
DEBUG_CODE_BEGIN ();
|
DEBUG_CODE_BEGIN ();
|
||||||
|
|
||||||
UINTN Index;
|
CHAR8 EfiFileName[256];
|
||||||
UINTN StartIndex;
|
|
||||||
CHAR8 EfiFileName[256];
|
|
||||||
|
|
||||||
DEBUG ((
|
DEBUG ((DEBUG_INFO | DEBUG_LOAD,
|
||||||
DEBUG_INFO | DEBUG_LOAD,
|
"Loading SMM driver at 0x%11p EntryPoint=0x%11p ",
|
||||||
"Loading SMM driver at 0x%11p EntryPoint=0x%11p ",
|
DstBuffer,
|
||||||
(VOID *)(UINTN)ImageContext.ImageAddress,
|
FUNCTION_ENTRY_POINT (UefiImageLoaderGetImageEntryPoint (ImageContext))));
|
||||||
FUNCTION_ENTRY_POINT (ImageContext.EntryPoint)
|
|
||||||
));
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Print Module Name by Pdb file path.
|
// Print Module Name by Pdb file path.
|
||||||
// Windows and Unix style file path are all trimmed correctly.
|
// Windows and Unix style file path are all trimmed correctly.
|
||||||
//
|
//
|
||||||
if (ImageContext.PdbPointer != NULL) {
|
Status = UefiImageGetModuleNameFromSymbolsPath (
|
||||||
StartIndex = 0;
|
ImageContext,
|
||||||
for (Index = 0; ImageContext.PdbPointer[Index] != 0; Index++) {
|
EfiFileName,
|
||||||
if ((ImageContext.PdbPointer[Index] == '\\') || (ImageContext.PdbPointer[Index] == '/')) {
|
sizeof (EfiFileName)
|
||||||
StartIndex = Index + 1;
|
);
|
||||||
}
|
if (!EFI_ERROR (Status)) {
|
||||||
}
|
DEBUG ((DEBUG_INFO | DEBUG_LOAD, "%a", EfiFileName));
|
||||||
|
|
||||||
//
|
|
||||||
// Copy the PDB file name to our temporary string, and replace .pdb with .efi
|
|
||||||
// The PDB file name is limited in the range of 0~255.
|
|
||||||
// If the length is bigger than 255, trim the redundant characters to avoid overflow in array boundary.
|
|
||||||
//
|
|
||||||
for (Index = 0; Index < sizeof (EfiFileName) - 4; Index++) {
|
|
||||||
EfiFileName[Index] = ImageContext.PdbPointer[Index + StartIndex];
|
|
||||||
if (EfiFileName[Index] == 0) {
|
|
||||||
EfiFileName[Index] = '.';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (EfiFileName[Index] == '.') {
|
|
||||||
EfiFileName[Index + 1] = 'e';
|
|
||||||
EfiFileName[Index + 2] = 'f';
|
|
||||||
EfiFileName[Index + 3] = 'i';
|
|
||||||
EfiFileName[Index + 4] = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Index == sizeof (EfiFileName) - 4) {
|
|
||||||
EfiFileName[Index] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
DEBUG ((DEBUG_INFO | DEBUG_LOAD, "%a", EfiFileName)); // &Image->ImageContext.PdbPointer[StartIndex]));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DEBUG ((DEBUG_INFO | DEBUG_LOAD, "\n"));
|
DEBUG ((DEBUG_INFO | DEBUG_LOAD, "\n"));
|
||||||
@ -852,11 +752,12 @@ SmmDispatcher (
|
|||||||
VOID
|
VOID
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
LIST_ENTRY *Link;
|
LIST_ENTRY *Link;
|
||||||
EFI_SMM_DRIVER_ENTRY *DriverEntry;
|
EFI_SMM_DRIVER_ENTRY *DriverEntry;
|
||||||
BOOLEAN ReadyToRun;
|
BOOLEAN ReadyToRun;
|
||||||
BOOLEAN PreviousSmmEntryPointRegistered;
|
BOOLEAN PreviousSmmEntryPointRegistered;
|
||||||
|
UEFI_IMAGE_LOADER_IMAGE_CONTEXT ImageContext;
|
||||||
|
|
||||||
if (!gRequestDispatch) {
|
if (!gRequestDispatch) {
|
||||||
return EFI_NOT_FOUND;
|
return EFI_NOT_FOUND;
|
||||||
@ -889,8 +790,7 @@ SmmDispatcher (
|
|||||||
// skip the LoadImage
|
// skip the LoadImage
|
||||||
//
|
//
|
||||||
if (DriverEntry->ImageHandle == NULL) {
|
if (DriverEntry->ImageHandle == NULL) {
|
||||||
Status = SmmLoadImage (DriverEntry);
|
Status = SmmLoadImage (DriverEntry, &ImageContext);
|
||||||
|
|
||||||
//
|
//
|
||||||
// Update the driver state to reflect that it's been loaded
|
// Update the driver state to reflect that it's been loaded
|
||||||
//
|
//
|
||||||
@ -929,7 +829,7 @@ SmmDispatcher (
|
|||||||
//
|
//
|
||||||
// For each SMM driver, pass NULL as ImageHandle
|
// For each SMM driver, pass NULL as ImageHandle
|
||||||
//
|
//
|
||||||
RegisterSmramProfileImage (DriverEntry, TRUE);
|
RegisterSmramProfileImage (&DriverEntry->FileName, TRUE, &ImageContext);
|
||||||
PERF_START_IMAGE_BEGIN (DriverEntry->ImageHandle);
|
PERF_START_IMAGE_BEGIN (DriverEntry->ImageHandle);
|
||||||
Status = ((EFI_IMAGE_ENTRY_POINT)(UINTN)DriverEntry->ImageEntryPoint)(DriverEntry->ImageHandle, gST);
|
Status = ((EFI_IMAGE_ENTRY_POINT)(UINTN)DriverEntry->ImageEntryPoint)(DriverEntry->ImageHandle, gST);
|
||||||
PERF_START_IMAGE_END (DriverEntry->ImageHandle);
|
PERF_START_IMAGE_END (DriverEntry->ImageHandle);
|
||||||
@ -940,7 +840,12 @@ SmmDispatcher (
|
|||||||
DriverEntry->SmmLoadedImage.ImageBase,
|
DriverEntry->SmmLoadedImage.ImageBase,
|
||||||
Status
|
Status
|
||||||
));
|
));
|
||||||
UnregisterSmramProfileImage (DriverEntry, TRUE);
|
UnregisterSmramProfileImage (
|
||||||
|
&DriverEntry->FileName,
|
||||||
|
(UINTN) DriverEntry->LoadedImage->ImageBase,
|
||||||
|
DriverEntry->LoadedImage->ImageSize,
|
||||||
|
TRUE
|
||||||
|
);
|
||||||
SmmFreePages (DriverEntry->ImageBuffer, DriverEntry->NumberOfPage);
|
SmmFreePages (DriverEntry->ImageBuffer, DriverEntry->NumberOfPage);
|
||||||
//
|
//
|
||||||
// Uninstall LoadedImage
|
// Uninstall LoadedImage
|
||||||
|
@ -22,7 +22,8 @@
|
|||||||
#include <Library/UefiBootServicesTableLib.h>
|
#include <Library/UefiBootServicesTableLib.h>
|
||||||
#include <Library/BaseMemoryLib.h>
|
#include <Library/BaseMemoryLib.h>
|
||||||
#include <Library/DebugLib.h>
|
#include <Library/DebugLib.h>
|
||||||
#include "PiSmmCoreMemoryAllocationServices.h"
|
#include "PiSmmCore.h"
|
||||||
|
#include "PiSmmCorePrivateData.h"
|
||||||
|
|
||||||
#include <Library/MemoryProfileLib.h>
|
#include <Library/MemoryProfileLib.h>
|
||||||
|
|
@ -16,12 +16,12 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
|
|||||||
#include <Library/PcdLib.h>
|
#include <Library/PcdLib.h>
|
||||||
#include <Library/ImagePropertiesRecordLib.h>
|
#include <Library/ImagePropertiesRecordLib.h>
|
||||||
|
|
||||||
#include <Library/PeCoffLib.h>
|
#include <Library/UefiImageLib.h>
|
||||||
#include <Library/PeCoffGetEntryPointLib.h>
|
|
||||||
|
|
||||||
#include <Guid/PiSmmMemoryAttributesTable.h>
|
#include <Guid/PiSmmMemoryAttributesTable.h>
|
||||||
|
|
||||||
#include "PiSmmCore.h"
|
#include "PiSmmCore.h"
|
||||||
|
#include "ProcessorBind.h"
|
||||||
|
|
||||||
#define PREVIOUS_MEMORY_DESCRIPTOR(MemoryDescriptor, Size) \
|
#define PREVIOUS_MEMORY_DESCRIPTOR(MemoryDescriptor, Size) \
|
||||||
((EFI_MEMORY_DESCRIPTOR *)((UINT8 *)(MemoryDescriptor) - (Size)))
|
((EFI_MEMORY_DESCRIPTOR *)((UINT8 *)(MemoryDescriptor) - (Size)))
|
||||||
@ -31,7 +31,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
|
|||||||
typedef struct {
|
typedef struct {
|
||||||
UINT32 Signature;
|
UINT32 Signature;
|
||||||
UINTN ImageRecordCount;
|
UINTN ImageRecordCount;
|
||||||
UINTN CodeSegmentCountMax;
|
UINT32 NumberOfSectionsMax;
|
||||||
LIST_ENTRY ImageRecordList;
|
LIST_ENTRY ImageRecordList;
|
||||||
} IMAGE_PROPERTIES_PRIVATE_DATA;
|
} IMAGE_PROPERTIES_PRIVATE_DATA;
|
||||||
|
|
||||||
@ -212,7 +212,10 @@ SmmCoreGetMemoryMapMemoryAttributesTable (
|
|||||||
return EFI_INVALID_PARAMETER;
|
return EFI_INVALID_PARAMETER;
|
||||||
}
|
}
|
||||||
|
|
||||||
AdditionalRecordCount = (2 * mImagePropertiesPrivateData.CodeSegmentCountMax + 3) * mImagePropertiesPrivateData.ImageRecordCount;
|
//
|
||||||
|
// Per image, they may be one trailer. There may be prefixed data.
|
||||||
|
//
|
||||||
|
AdditionalRecordCount = (mImagePropertiesPrivateData.NumberOfSectionsMax + 1) * mImagePropertiesPrivateData.ImageRecordCount + 1;
|
||||||
|
|
||||||
OldMemoryMapSize = *MemoryMapSize;
|
OldMemoryMapSize = *MemoryMapSize;
|
||||||
Status = SmmCoreGetMemoryMap (MemoryMapSize, MemoryMap, MapKey, DescriptorSize, DescriptorVersion);
|
Status = SmmCoreGetMemoryMap (MemoryMapSize, MemoryMap, MapKey, DescriptorSize, DescriptorVersion);
|
||||||
@ -251,6 +254,98 @@ SmmCoreGetMemoryMapMemoryAttributesTable (
|
|||||||
// Below functions are for ImageRecord
|
// Below functions are for ImageRecord
|
||||||
//
|
//
|
||||||
|
|
||||||
|
/**
|
||||||
|
Set MemoryProtectionAttribute according to PE/COFF image section alignment.
|
||||||
|
|
||||||
|
@param[in] SectionAlignment PE/COFF section alignment
|
||||||
|
**/
|
||||||
|
STATIC
|
||||||
|
VOID
|
||||||
|
SetMemoryAttributesTableSectionAlignment (
|
||||||
|
IN UINT32 SectionAlignment
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (((SectionAlignment & (RUNTIME_PAGE_ALLOCATION_GRANULARITY - 1)) != 0) &&
|
||||||
|
((mMemoryProtectionAttribute & EFI_MEMORY_ATTRIBUTES_RUNTIME_MEMORY_PROTECTION_NON_EXECUTABLE_PE_DATA) != 0))
|
||||||
|
{
|
||||||
|
DEBUG ((DEBUG_VERBOSE, "SMM SetMemoryAttributesTableSectionAlignment - Clear\n"));
|
||||||
|
mMemoryProtectionAttribute &= ~((UINT64)EFI_MEMORY_ATTRIBUTES_RUNTIME_MEMORY_PROTECTION_NON_EXECUTABLE_PE_DATA);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Sort image record based upon the ImageBase from low to high.
|
||||||
|
**/
|
||||||
|
STATIC
|
||||||
|
VOID
|
||||||
|
InsertSortImageRecord (
|
||||||
|
IN UEFI_IMAGE_RECORD *NewImageRecord
|
||||||
|
)
|
||||||
|
{
|
||||||
|
UEFI_IMAGE_RECORD *ImageRecord;
|
||||||
|
LIST_ENTRY *PrevImageRecordLink;
|
||||||
|
LIST_ENTRY *ImageRecordLink;
|
||||||
|
LIST_ENTRY *ImageRecordList;
|
||||||
|
|
||||||
|
ImageRecordList = &mImagePropertiesPrivateData.ImageRecordList;
|
||||||
|
|
||||||
|
PrevImageRecordLink = ImageRecordList;
|
||||||
|
for (
|
||||||
|
ImageRecordLink = GetFirstNode (ImageRecordList);
|
||||||
|
!IsNull (ImageRecordLink, ImageRecordList);
|
||||||
|
ImageRecordLink = GetNextNode (ImageRecordList, PrevImageRecordLink)
|
||||||
|
) {
|
||||||
|
ImageRecord = CR (
|
||||||
|
ImageRecordLink,
|
||||||
|
UEFI_IMAGE_RECORD,
|
||||||
|
Link,
|
||||||
|
UEFI_IMAGE_RECORD_SIGNATURE
|
||||||
|
);
|
||||||
|
if (NewImageRecord->StartAddress < ImageRecord->StartAddress) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
PrevImageRecordLink = ImageRecordLink;
|
||||||
|
}
|
||||||
|
|
||||||
|
InsertHeadList (PrevImageRecordLink, &NewImageRecord->Link);
|
||||||
|
mImagePropertiesPrivateData.ImageRecordCount++;
|
||||||
|
|
||||||
|
if (mImagePropertiesPrivateData.NumberOfSectionsMax < NewImageRecord->NumSegments) {
|
||||||
|
mImagePropertiesPrivateData.NumberOfSectionsMax = NewImageRecord->NumSegments;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Dump image record.
|
||||||
|
**/
|
||||||
|
STATIC
|
||||||
|
VOID
|
||||||
|
DumpImageRecord (
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
{
|
||||||
|
UEFI_IMAGE_RECORD *ImageRecord;
|
||||||
|
LIST_ENTRY *ImageRecordLink;
|
||||||
|
LIST_ENTRY *ImageRecordList;
|
||||||
|
UINTN Index;
|
||||||
|
|
||||||
|
ImageRecordList = &mImagePropertiesPrivateData.ImageRecordList;
|
||||||
|
|
||||||
|
for (ImageRecordLink = ImageRecordList->ForwardLink, Index = 0;
|
||||||
|
ImageRecordLink != ImageRecordList;
|
||||||
|
ImageRecordLink = ImageRecordLink->ForwardLink, Index++)
|
||||||
|
{
|
||||||
|
ImageRecord = CR (
|
||||||
|
ImageRecordLink,
|
||||||
|
UEFI_IMAGE_RECORD,
|
||||||
|
Link,
|
||||||
|
UEFI_IMAGE_RECORD_SIGNATURE
|
||||||
|
);
|
||||||
|
DEBUG ((DEBUG_VERBOSE, "SMM Image[%d]: 0x%016lx - 0x%016lx\n", Index, ImageRecord->StartAddress, ImageRecord->EndAddress - ImageRecord->StartAddress));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Insert image record.
|
Insert image record.
|
||||||
|
|
||||||
@ -258,82 +353,60 @@ SmmCoreGetMemoryMapMemoryAttributesTable (
|
|||||||
**/
|
**/
|
||||||
VOID
|
VOID
|
||||||
SmmInsertImageRecord (
|
SmmInsertImageRecord (
|
||||||
IN EFI_SMM_DRIVER_ENTRY *DriverEntry
|
IN EFI_LOADED_IMAGE_PROTOCOL *LoadedImage,
|
||||||
|
IN UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
EFI_STATUS Status;
|
RETURN_STATUS PdbStatus;
|
||||||
IMAGE_PROPERTIES_RECORD *ImageRecord;
|
PHYSICAL_ADDRESS ImageBuffer;
|
||||||
CHAR8 *PdbPointer;
|
UINTN NumberOfPage;
|
||||||
UINT32 RequiredAlignment;
|
UINT32 SectionAlignment;
|
||||||
|
UEFI_IMAGE_RECORD *ImageRecord;
|
||||||
|
CONST CHAR8 *PdbPointer;
|
||||||
|
UINT32 PdbSize;
|
||||||
|
|
||||||
DEBUG ((DEBUG_VERBOSE, "SMM InsertImageRecord - 0x%x\n", DriverEntry));
|
ImageBuffer = (UINTN)LoadedImage->ImageBase;
|
||||||
|
NumberOfPage = EFI_SIZE_TO_PAGES((UINTN)LoadedImage->ImageSize);
|
||||||
|
|
||||||
ImageRecord = AllocatePool (sizeof (*ImageRecord));
|
DEBUG ((DEBUG_VERBOSE, "SMM InsertImageRecord - 0x%016lx - 0x%08x\n", ImageBuffer, NumberOfPage));
|
||||||
|
|
||||||
|
DEBUG ((DEBUG_VERBOSE, "SMM ImageRecordCount - 0x%x\n", mImagePropertiesPrivateData.ImageRecordCount));
|
||||||
|
|
||||||
|
PdbStatus = UefiImageGetSymbolsPath (ImageContext, &PdbPointer, &PdbSize);
|
||||||
|
if (!RETURN_ERROR (PdbStatus)) {
|
||||||
|
DEBUG ((DEBUG_VERBOSE, "SMM Image - %a\n", PdbPointer));
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Get SectionAlignment
|
||||||
|
//
|
||||||
|
SectionAlignment = UefiImageGetSegmentAlignment (ImageContext);
|
||||||
|
|
||||||
|
SetMemoryAttributesTableSectionAlignment (SectionAlignment);
|
||||||
|
if ((SectionAlignment & (RUNTIME_PAGE_ALLOCATION_GRANULARITY - 1)) != 0) {
|
||||||
|
DEBUG ((
|
||||||
|
DEBUG_WARN,
|
||||||
|
"SMM !!!!!!!! InsertImageRecord - Section Alignment(0x%x) is not %dK !!!!!!!!\n",
|
||||||
|
SectionAlignment, RUNTIME_PAGE_ALLOCATION_GRANULARITY >> 10));
|
||||||
|
if (!RETURN_ERROR (PdbStatus)) {
|
||||||
|
DEBUG ((DEBUG_WARN, "SMM !!!!!!!! Image - %a !!!!!!!!\n", PdbPointer));
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// The image headers are not recorded among the sections, allocate one more.
|
||||||
|
//
|
||||||
|
ImageRecord = UefiImageLoaderGetImageRecord (ImageContext);
|
||||||
if (ImageRecord == NULL) {
|
if (ImageRecord == NULL) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
InitializeListHead (&ImageRecord->Link);
|
UefiImageDebugPrintSegments (ImageContext);
|
||||||
InitializeListHead (&ImageRecord->CodeSegmentList);
|
UefiImageDebugPrintImageRecord (ImageRecord);
|
||||||
|
|
||||||
PdbPointer = PeCoffLoaderGetPdbPointer ((VOID *)(UINTN)DriverEntry->ImageBuffer);
|
InsertSortImageRecord (ImageRecord);
|
||||||
if (PdbPointer != NULL) {
|
|
||||||
DEBUG ((DEBUG_VERBOSE, "SMM Image - %a\n", PdbPointer));
|
|
||||||
}
|
|
||||||
|
|
||||||
RequiredAlignment = RUNTIME_PAGE_ALLOCATION_GRANULARITY;
|
|
||||||
Status = CreateImagePropertiesRecord (
|
|
||||||
(VOID *)(UINTN)DriverEntry->ImageBuffer,
|
|
||||||
LShiftU64 (DriverEntry->NumberOfPage, EFI_PAGE_SHIFT),
|
|
||||||
&RequiredAlignment,
|
|
||||||
ImageRecord
|
|
||||||
);
|
|
||||||
|
|
||||||
if (EFI_ERROR (Status)) {
|
|
||||||
if (Status == EFI_ABORTED) {
|
|
||||||
mMemoryProtectionAttribute &=
|
|
||||||
~((UINT64)EFI_MEMORY_ATTRIBUTES_RUNTIME_MEMORY_PROTECTION_NON_EXECUTABLE_PE_DATA);
|
|
||||||
}
|
|
||||||
|
|
||||||
goto Finish;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ImageRecord->CodeSegmentCount == 0) {
|
|
||||||
mMemoryProtectionAttribute &=
|
|
||||||
~((UINT64)EFI_MEMORY_ATTRIBUTES_RUNTIME_MEMORY_PROTECTION_NON_EXECUTABLE_PE_DATA);
|
|
||||||
DEBUG ((DEBUG_ERROR, "SMM !!!!!!!! InsertImageRecord - CodeSegmentCount is 0 !!!!!!!!\n"));
|
|
||||||
if (PdbPointer != NULL) {
|
|
||||||
DEBUG ((DEBUG_ERROR, "SMM !!!!!!!! Image - %a !!!!!!!!\n", PdbPointer));
|
|
||||||
}
|
|
||||||
|
|
||||||
Status = EFI_ABORTED;
|
|
||||||
goto Finish;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Check overlap all section in ImageBase/Size
|
|
||||||
//
|
|
||||||
if (!IsImageRecordCodeSectionValid (ImageRecord)) {
|
|
||||||
DEBUG ((DEBUG_ERROR, "SMM IsImageRecordCodeSectionValid - FAIL\n"));
|
|
||||||
Status = EFI_ABORTED;
|
|
||||||
goto Finish;
|
|
||||||
}
|
|
||||||
|
|
||||||
InsertTailList (&mImagePropertiesPrivateData.ImageRecordList, &ImageRecord->Link);
|
|
||||||
mImagePropertiesPrivateData.ImageRecordCount++;
|
|
||||||
|
|
||||||
if (mImagePropertiesPrivateData.CodeSegmentCountMax < ImageRecord->CodeSegmentCount) {
|
|
||||||
mImagePropertiesPrivateData.CodeSegmentCountMax = ImageRecord->CodeSegmentCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
SortImageRecord (&mImagePropertiesPrivateData.ImageRecordList);
|
|
||||||
|
|
||||||
Finish:
|
|
||||||
if (EFI_ERROR (Status) && (ImageRecord != NULL)) {
|
|
||||||
DeleteImagePropertiesRecord (ImageRecord);
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -418,60 +491,6 @@ PublishMemoryAttributesTable (
|
|||||||
ASSERT_EFI_ERROR (Status);
|
ASSERT_EFI_ERROR (Status);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
This function installs all SMM image record information.
|
|
||||||
**/
|
|
||||||
VOID
|
|
||||||
SmmInstallImageRecord (
|
|
||||||
VOID
|
|
||||||
)
|
|
||||||
{
|
|
||||||
EFI_STATUS Status;
|
|
||||||
UINTN NoHandles;
|
|
||||||
EFI_HANDLE *HandleBuffer;
|
|
||||||
EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;
|
|
||||||
UINTN Index;
|
|
||||||
EFI_SMM_DRIVER_ENTRY DriverEntry;
|
|
||||||
|
|
||||||
Status = SmmLocateHandleBuffer (
|
|
||||||
ByProtocol,
|
|
||||||
&gEfiLoadedImageProtocolGuid,
|
|
||||||
NULL,
|
|
||||||
&NoHandles,
|
|
||||||
&HandleBuffer
|
|
||||||
);
|
|
||||||
if (EFI_ERROR (Status)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (Index = 0; Index < NoHandles; Index++) {
|
|
||||||
Status = gSmst->SmmHandleProtocol (
|
|
||||||
HandleBuffer[Index],
|
|
||||||
&gEfiLoadedImageProtocolGuid,
|
|
||||||
(VOID **)&LoadedImage
|
|
||||||
);
|
|
||||||
if (EFI_ERROR (Status)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
DEBUG ((DEBUG_VERBOSE, "LoadedImage - 0x%x 0x%x ", LoadedImage->ImageBase, LoadedImage->ImageSize));
|
|
||||||
{
|
|
||||||
VOID *PdbPointer;
|
|
||||||
PdbPointer = PeCoffLoaderGetPdbPointer (LoadedImage->ImageBase);
|
|
||||||
if (PdbPointer != NULL) {
|
|
||||||
DEBUG ((DEBUG_VERBOSE, "(%a) ", PdbPointer));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
DEBUG ((DEBUG_VERBOSE, "\n"));
|
|
||||||
ZeroMem (&DriverEntry, sizeof (DriverEntry));
|
|
||||||
DriverEntry.ImageBuffer = (UINTN)LoadedImage->ImageBase;
|
|
||||||
DriverEntry.NumberOfPage = EFI_SIZE_TO_PAGES ((UINTN)LoadedImage->ImageSize);
|
|
||||||
SmmInsertImageRecord (&DriverEntry);
|
|
||||||
}
|
|
||||||
|
|
||||||
FreePool (HandleBuffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Install MemoryAttributesTable.
|
Install MemoryAttributesTable.
|
||||||
|
|
||||||
@ -489,8 +508,6 @@ SmmInstallMemoryAttributesTable (
|
|||||||
IN EFI_HANDLE Handle
|
IN EFI_HANDLE Handle
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
SmmInstallImageRecord ();
|
|
||||||
|
|
||||||
DEBUG ((DEBUG_VERBOSE, "SMM MemoryProtectionAttribute - 0x%016lx\n", mMemoryProtectionAttribute));
|
DEBUG ((DEBUG_VERBOSE, "SMM MemoryProtectionAttribute - 0x%016lx\n", mMemoryProtectionAttribute));
|
||||||
if ((mMemoryProtectionAttribute & EFI_MEMORY_ATTRIBUTES_RUNTIME_MEMORY_PROTECTION_NON_EXECUTABLE_PE_DATA) == 0) {
|
if ((mMemoryProtectionAttribute & EFI_MEMORY_ATTRIBUTES_RUNTIME_MEMORY_PROTECTION_NON_EXECUTABLE_PE_DATA) == 0) {
|
||||||
return EFI_SUCCESS;
|
return EFI_SUCCESS;
|
||||||
@ -500,7 +517,7 @@ SmmInstallMemoryAttributesTable (
|
|||||||
if ( mImagePropertiesPrivateData.ImageRecordCount > 0) {
|
if ( mImagePropertiesPrivateData.ImageRecordCount > 0) {
|
||||||
DEBUG ((DEBUG_INFO, "SMM - Total Runtime Image Count - 0x%x\n", mImagePropertiesPrivateData.ImageRecordCount));
|
DEBUG ((DEBUG_INFO, "SMM - Total Runtime Image Count - 0x%x\n", mImagePropertiesPrivateData.ImageRecordCount));
|
||||||
DEBUG ((DEBUG_INFO, "SMM - Dump Runtime Image Records:\n"));
|
DEBUG ((DEBUG_INFO, "SMM - Dump Runtime Image Records:\n"));
|
||||||
DumpImageRecords (&mImagePropertiesPrivateData.ImageRecordList);
|
DumpImageRecord ();
|
||||||
}
|
}
|
||||||
|
|
||||||
DEBUG_CODE_END ();
|
DEBUG_CODE_END ();
|
||||||
|
@ -815,7 +815,7 @@ SmmCoreInstallLoadedImage (
|
|||||||
mSmmCoreLoadedImage->SystemTable = gST;
|
mSmmCoreLoadedImage->SystemTable = gST;
|
||||||
|
|
||||||
mSmmCoreLoadedImage->ImageBase = (VOID *)(UINTN)gSmmCorePrivate->PiSmmCoreImageBase;
|
mSmmCoreLoadedImage->ImageBase = (VOID *)(UINTN)gSmmCorePrivate->PiSmmCoreImageBase;
|
||||||
mSmmCoreLoadedImage->ImageSize = gSmmCorePrivate->PiSmmCoreImageSize;
|
mSmmCoreLoadedImage->ImageSize = UefiImageGetImageSize (&gSmmCorePrivate->PiSmmCoreImageContext);
|
||||||
mSmmCoreLoadedImage->ImageCodeType = EfiRuntimeServicesCode;
|
mSmmCoreLoadedImage->ImageCodeType = EfiRuntimeServicesCode;
|
||||||
mSmmCoreLoadedImage->ImageDataType = EfiRuntimeServicesData;
|
mSmmCoreLoadedImage->ImageDataType = EfiRuntimeServicesData;
|
||||||
|
|
||||||
@ -847,13 +847,13 @@ SmmCoreInstallLoadedImage (
|
|||||||
mSmmCoreDriverEntry->SmmLoadedImage.SystemTable = gST;
|
mSmmCoreDriverEntry->SmmLoadedImage.SystemTable = gST;
|
||||||
|
|
||||||
mSmmCoreDriverEntry->SmmLoadedImage.ImageBase = (VOID *)(UINTN)gSmmCorePrivate->PiSmmCoreImageBase;
|
mSmmCoreDriverEntry->SmmLoadedImage.ImageBase = (VOID *)(UINTN)gSmmCorePrivate->PiSmmCoreImageBase;
|
||||||
mSmmCoreDriverEntry->SmmLoadedImage.ImageSize = gSmmCorePrivate->PiSmmCoreImageSize;
|
mSmmCoreDriverEntry->SmmLoadedImage.ImageSize = UefiImageGetImageSize (&gSmmCorePrivate->PiSmmCoreImageContext);
|
||||||
mSmmCoreDriverEntry->SmmLoadedImage.ImageCodeType = EfiRuntimeServicesCode;
|
mSmmCoreDriverEntry->SmmLoadedImage.ImageCodeType = EfiRuntimeServicesCode;
|
||||||
mSmmCoreDriverEntry->SmmLoadedImage.ImageDataType = EfiRuntimeServicesData;
|
mSmmCoreDriverEntry->SmmLoadedImage.ImageDataType = EfiRuntimeServicesData;
|
||||||
|
|
||||||
mSmmCoreDriverEntry->ImageEntryPoint = gSmmCorePrivate->PiSmmCoreEntryPoint;
|
mSmmCoreDriverEntry->ImageEntryPoint = UefiImageLoaderGetImageEntryPoint (&gSmmCorePrivate->PiSmmCoreImageContext);
|
||||||
mSmmCoreDriverEntry->ImageBuffer = gSmmCorePrivate->PiSmmCoreImageBase;
|
mSmmCoreDriverEntry->ImageBuffer = gSmmCorePrivate->PiSmmCoreImageBase;
|
||||||
mSmmCoreDriverEntry->NumberOfPage = EFI_SIZE_TO_PAGES ((UINTN)gSmmCorePrivate->PiSmmCoreImageSize);
|
mSmmCoreDriverEntry->NumberOfPage = EFI_SIZE_TO_PAGES ((UINTN)UefiImageGetImageSize (&gSmmCorePrivate->PiSmmCoreImageContext));
|
||||||
|
|
||||||
//
|
//
|
||||||
// Create a new image handle in the SMM handle database for the SMM Driver
|
// Create a new image handle in the SMM handle database for the SMM Driver
|
||||||
@ -867,6 +867,21 @@ SmmCoreInstallLoadedImage (
|
|||||||
);
|
);
|
||||||
ASSERT_EFI_ERROR (Status);
|
ASSERT_EFI_ERROR (Status);
|
||||||
|
|
||||||
|
SmmInsertImageRecord (&mSmmCoreDriverEntry->SmmLoadedImage, &gSmmCorePrivate->PiSmmCoreImageContext);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Create the aligned system table pointer structure that is used by external
|
||||||
|
// debuggers to locate the system table... Also, install debug image info
|
||||||
|
// configuration table.
|
||||||
|
//
|
||||||
|
SmmInitializeDebugImageInfoTable ();
|
||||||
|
SmmNewDebugImageInfoEntry (
|
||||||
|
EFI_DEBUG_IMAGE_INFO_TYPE_NORMAL,
|
||||||
|
&mSmmCoreDriverEntry->SmmLoadedImage,
|
||||||
|
mSmmCoreDriverEntry->SmmImageHandle,
|
||||||
|
&gSmmCorePrivate->PiSmmCoreImageContext
|
||||||
|
);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,11 +37,11 @@
|
|||||||
#include <Guid/SmiHandlerProfile.h>
|
#include <Guid/SmiHandlerProfile.h>
|
||||||
#include <Guid/EndOfS3Resume.h>
|
#include <Guid/EndOfS3Resume.h>
|
||||||
#include <Guid/S3SmmInitDone.h>
|
#include <Guid/S3SmmInitDone.h>
|
||||||
|
#include <Guid/DebugImageInfoTable.h>
|
||||||
|
|
||||||
#include <Library/BaseLib.h>
|
#include <Library/BaseLib.h>
|
||||||
#include <Library/BaseMemoryLib.h>
|
#include <Library/BaseMemoryLib.h>
|
||||||
#include <Library/PeCoffLib.h>
|
#include <Library/UefiImageLib.h>
|
||||||
#include <Library/PeCoffGetEntryPointLib.h>
|
|
||||||
#include <Library/CacheMaintenanceLib.h>
|
#include <Library/CacheMaintenanceLib.h>
|
||||||
#include <Library/DebugLib.h>
|
#include <Library/DebugLib.h>
|
||||||
#include <Library/ReportStatusCodeLib.h>
|
#include <Library/ReportStatusCodeLib.h>
|
||||||
@ -55,6 +55,7 @@
|
|||||||
#include <Library/HobLib.h>
|
#include <Library/HobLib.h>
|
||||||
#include <Library/SmmMemLib.h>
|
#include <Library/SmmMemLib.h>
|
||||||
#include <Library/SafeIntLib.h>
|
#include <Library/SafeIntLib.h>
|
||||||
|
#include <Library/SmmServicesTableLib.h>
|
||||||
|
|
||||||
#include "PiSmmCorePrivateData.h"
|
#include "PiSmmCorePrivateData.h"
|
||||||
#include "HeapGuard.h"
|
#include "HeapGuard.h"
|
||||||
@ -1020,8 +1021,9 @@ SmramProfileInstallProtocol (
|
|||||||
**/
|
**/
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
RegisterSmramProfileImage (
|
RegisterSmramProfileImage (
|
||||||
IN EFI_SMM_DRIVER_ENTRY *DriverEntry,
|
IN EFI_GUID *FileName,
|
||||||
IN BOOLEAN RegisterToDxe
|
IN BOOLEAN RegisterToDxe,
|
||||||
|
IN UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1038,8 +1040,10 @@ RegisterSmramProfileImage (
|
|||||||
**/
|
**/
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
UnregisterSmramProfileImage (
|
UnregisterSmramProfileImage (
|
||||||
IN EFI_SMM_DRIVER_ENTRY *DriverEntry,
|
IN EFI_GUID *FileName,
|
||||||
IN BOOLEAN UnregisterToDxe
|
IN PHYSICAL_ADDRESS ImageBase,
|
||||||
|
IN UINT64 ImageSize,
|
||||||
|
IN BOOLEAN UnregisterFromDxe
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1352,4 +1356,50 @@ SmmEntryPointMemoryManagementHook (
|
|||||||
VOID
|
VOID
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Creates and initializes the DebugImageInfo Table. Also creates the configuration
|
||||||
|
table and registers it into the system table.
|
||||||
|
|
||||||
|
Note:
|
||||||
|
This function allocates memory, frees it, and then allocates memory at an
|
||||||
|
address within the initial allocation. Since this function is called early
|
||||||
|
in DXE core initialization (before drivers are dispatched), this should not
|
||||||
|
be a problem.
|
||||||
|
|
||||||
|
**/
|
||||||
|
VOID
|
||||||
|
SmmInitializeDebugImageInfoTable (
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Adds a new DebugImageInfo structure to the DebugImageInfo Table. Re-Allocates
|
||||||
|
the table if it's not large enough to accomidate another entry.
|
||||||
|
|
||||||
|
@param ImageInfoType type of debug image information
|
||||||
|
@param LoadedImage pointer to the loaded image protocol for the image being
|
||||||
|
loaded
|
||||||
|
@param ImageHandle image handle for the image being loaded
|
||||||
|
|
||||||
|
**/
|
||||||
|
VOID
|
||||||
|
SmmNewDebugImageInfoEntry (
|
||||||
|
IN UINT32 ImageInfoType,
|
||||||
|
IN EFI_LOADED_IMAGE_PROTOCOL *LoadedImage,
|
||||||
|
IN EFI_HANDLE ImageHandle,
|
||||||
|
IN UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Insert image record.
|
||||||
|
|
||||||
|
@param[in] DriverEntry Driver information
|
||||||
|
**/
|
||||||
|
VOID
|
||||||
|
SmmInsertImageRecord (
|
||||||
|
IN EFI_LOADED_IMAGE_PROTOCOL *LoadedImage,
|
||||||
|
IN UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext
|
||||||
|
);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -37,6 +37,8 @@
|
|||||||
SmiHandlerProfile.c
|
SmiHandlerProfile.c
|
||||||
HeapGuard.c
|
HeapGuard.c
|
||||||
HeapGuard.h
|
HeapGuard.h
|
||||||
|
MemoryAllocation.c
|
||||||
|
DebugImageInfo.c
|
||||||
|
|
||||||
[Packages]
|
[Packages]
|
||||||
MdePkg/MdePkg.dec
|
MdePkg/MdePkg.dec
|
||||||
@ -46,8 +48,7 @@
|
|||||||
UefiDriverEntryPoint
|
UefiDriverEntryPoint
|
||||||
BaseLib
|
BaseLib
|
||||||
BaseMemoryLib
|
BaseMemoryLib
|
||||||
PeCoffLib
|
UefiImageLib
|
||||||
PeCoffGetEntryPointLib
|
|
||||||
CacheMaintenanceLib
|
CacheMaintenanceLib
|
||||||
DebugLib
|
DebugLib
|
||||||
ReportStatusCodeLib
|
ReportStatusCodeLib
|
||||||
@ -99,6 +100,7 @@
|
|||||||
gEfiMdeModulePkgTokenSpaceGuid.PcdHeapGuardPoolType ## CONSUMES
|
gEfiMdeModulePkgTokenSpaceGuid.PcdHeapGuardPoolType ## CONSUMES
|
||||||
gEfiMdeModulePkgTokenSpaceGuid.PcdHeapGuardPropertyMask ## CONSUMES
|
gEfiMdeModulePkgTokenSpaceGuid.PcdHeapGuardPropertyMask ## CONSUMES
|
||||||
gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiS3Enable ## CONSUMES
|
gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiS3Enable ## CONSUMES
|
||||||
|
gEfiMdeModulePkgTokenSpaceGuid.PcdMaxEfiSystemTablePointerAddress ## CONSUMES
|
||||||
|
|
||||||
[Guids]
|
[Guids]
|
||||||
gAprioriGuid ## SOMETIMES_CONSUMES ## File
|
gAprioriGuid ## SOMETIMES_CONSUMES ## File
|
||||||
@ -120,6 +122,7 @@
|
|||||||
gSmiHandlerProfileGuid
|
gSmiHandlerProfileGuid
|
||||||
gEdkiiEndOfS3ResumeGuid ## SOMETIMES_PRODUCES ## GUID # Install protocol
|
gEdkiiEndOfS3ResumeGuid ## SOMETIMES_PRODUCES ## GUID # Install protocol
|
||||||
gEdkiiS3SmmInitDoneGuid ## SOMETIMES_PRODUCES ## GUID # Install protocol
|
gEdkiiS3SmmInitDoneGuid ## SOMETIMES_PRODUCES ## GUID # Install protocol
|
||||||
|
gEfiDebugImageInfoTableGuid ## PRODUCES ## SystemTable
|
||||||
|
|
||||||
[UserExtensions.TianoCore."ExtraFiles"]
|
[UserExtensions.TianoCore."ExtraFiles"]
|
||||||
PiSmmCoreExtra.uni
|
PiSmmCoreExtra.uni
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
/// the SMM Entry Point enabling the use of SMM Mode. In this case, the SMM Core
|
/// the SMM Entry Point enabling the use of SMM Mode. In this case, the SMM Core
|
||||||
/// should be notified again to dispatch more SMM Drivers using SMM Mode.
|
/// should be notified again to dispatch more SMM Drivers using SMM Mode.
|
||||||
///
|
///
|
||||||
|
#include "Library/UefiImageLib.h"
|
||||||
#define COMM_BUFFER_SMM_DISPATCH_ERROR 0x00
|
#define COMM_BUFFER_SMM_DISPATCH_ERROR 0x00
|
||||||
#define COMM_BUFFER_SMM_DISPATCH_SUCCESS 0x01
|
#define COMM_BUFFER_SMM_DISPATCH_SUCCESS 0x01
|
||||||
#define COMM_BUFFER_SMM_DISPATCH_RESTART 0x02
|
#define COMM_BUFFER_SMM_DISPATCH_RESTART 0x02
|
||||||
@ -112,8 +113,7 @@ typedef struct {
|
|||||||
EFI_STATUS ReturnStatus;
|
EFI_STATUS ReturnStatus;
|
||||||
|
|
||||||
EFI_PHYSICAL_ADDRESS PiSmmCoreImageBase;
|
EFI_PHYSICAL_ADDRESS PiSmmCoreImageBase;
|
||||||
UINT64 PiSmmCoreImageSize;
|
UEFI_IMAGE_LOADER_IMAGE_CONTEXT PiSmmCoreImageContext;
|
||||||
EFI_PHYSICAL_ADDRESS PiSmmCoreEntryPoint;
|
|
||||||
} SMM_CORE_PRIVATE_DATA;
|
} SMM_CORE_PRIVATE_DATA;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -23,7 +23,7 @@
|
|||||||
|
|
||||||
#include <Library/BaseLib.h>
|
#include <Library/BaseLib.h>
|
||||||
#include <Library/BaseMemoryLib.h>
|
#include <Library/BaseMemoryLib.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/DebugLib.h>
|
#include <Library/DebugLib.h>
|
||||||
@ -36,6 +36,8 @@
|
|||||||
#include <Library/ReportStatusCodeLib.h>
|
#include <Library/ReportStatusCodeLib.h>
|
||||||
#include "PiSmmCorePrivateData.h"
|
#include "PiSmmCorePrivateData.h"
|
||||||
#include <Library/SafeIntLib.h>
|
#include <Library/SafeIntLib.h>
|
||||||
|
#include "ProcessorBind.h"
|
||||||
|
#include "Uefi/UefiBaseType.h"
|
||||||
|
|
||||||
#define SMRAM_CAPABILITIES (EFI_MEMORY_WB | EFI_MEMORY_UC)
|
#define SMRAM_CAPABILITIES (EFI_MEMORY_WB | EFI_MEMORY_UC)
|
||||||
|
|
||||||
@ -913,91 +915,41 @@ SmmIplSetVirtualAddressNotify (
|
|||||||
@retval EFI_NOT_FOUND The image has no assigned fixed loading address.
|
@retval EFI_NOT_FOUND The image has no assigned fixed loading address.
|
||||||
**/
|
**/
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
GetPeCoffImageFixLoadingAssignedAddress (
|
GetUefiImageFixLoadingAssignedAddress (
|
||||||
IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext
|
IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext,
|
||||||
|
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;
|
EFI_PHYSICAL_ADDRESS SmramBase;
|
||||||
UINT16 Index;
|
UINT64 SmmCodeSize;
|
||||||
UINTN Size;
|
|
||||||
UINT16 NumberOfSections;
|
|
||||||
EFI_PHYSICAL_ADDRESS SmramBase;
|
|
||||||
UINT64 SmmCodeSize;
|
|
||||||
UINT64 ValueInSectionHeader;
|
|
||||||
|
|
||||||
|
Status = UefiImageGetFixedAddress (ImageContext, &ValueInSectionHeader);
|
||||||
|
if (RETURN_ERROR (Status)) {
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
//
|
//
|
||||||
// Build tool will calculate the smm code size and then patch the PcdLoadFixAddressSmmCodePageNumber
|
// Build tool will calculate the smm code size and then patch the PcdLoadFixAddressSmmCodePageNumber
|
||||||
//
|
//
|
||||||
SmmCodeSize = EFI_PAGES_TO_SIZE (PcdGet32 (PcdLoadFixAddressSmmCodePageNumber));
|
SmmCodeSize = EFI_PAGES_TO_SIZE (PcdGet32(PcdLoadFixAddressSmmCodePageNumber));
|
||||||
|
SmramBase = mLMFAConfigurationTable->SmramBase;
|
||||||
|
|
||||||
FixLoadingAddress = 0;
|
FixLoadingAddress = SmramBase + ValueInSectionHeader;
|
||||||
Status = EFI_NOT_FOUND;
|
SizeOfImage = UefiImageGetImageSize (ImageContext);
|
||||||
SmramBase = mLMFAConfigurationTable->SmramBase;
|
|
||||||
//
|
|
||||||
// Get PeHeader pointer
|
|
||||||
//
|
|
||||||
ImgHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)((CHAR8 *)ImageContext->Handle + ImageContext->PeCoffHeaderOffset);
|
|
||||||
SectionHeaderOffset = ImageContext->PeCoffHeaderOffset +
|
|
||||||
sizeof (UINT32) +
|
|
||||||
sizeof (EFI_IMAGE_FILE_HEADER) +
|
|
||||||
ImgHdr->Pe32.FileHeader.SizeOfOptionalHeader;
|
|
||||||
NumberOfSections = ImgHdr->Pe32.FileHeader.NumberOfSections;
|
|
||||||
|
|
||||||
//
|
if (SmramBase + SmmCodeSize >= FixLoadingAddress + SizeOfImage
|
||||||
// Get base address from the first section header that doesn't point to code section.
|
&& SmramBase <= FixLoadingAddress) {
|
||||||
//
|
|
||||||
for (Index = 0; Index < NumberOfSections; Index++) {
|
|
||||||
//
|
//
|
||||||
// Read section header from file
|
// The assigned address is valid. Return the specified loading address
|
||||||
//
|
//
|
||||||
Size = sizeof (EFI_IMAGE_SECTION_HEADER);
|
*LoadAddress = FixLoadingAddress;
|
||||||
Status = ImageContext->ImageRead (
|
Status = EFI_SUCCESS;
|
||||||
ImageContext->Handle,
|
|
||||||
SectionHeaderOffset,
|
|
||||||
&Size,
|
|
||||||
&SectionHeader
|
|
||||||
);
|
|
||||||
if (EFI_ERROR (Status)) {
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
Status = EFI_NOT_FOUND;
|
|
||||||
|
|
||||||
if ((SectionHeader.Characteristics & EFI_IMAGE_SCN_CNT_CODE) == 0) {
|
|
||||||
//
|
|
||||||
// Build tool saves the offset to SMRAM base as image base in PointerToRelocations & PointerToLineNumbers fields in the
|
|
||||||
// first section header that doesn't point to code section in image header. And there is an assumption that when the
|
|
||||||
// feature is enabled, if a module is assigned a loading address by tools, PointerToRelocations & PointerToLineNumbers
|
|
||||||
// fields should NOT be Zero, or else, these 2 fields should be set to Zero
|
|
||||||
//
|
|
||||||
ValueInSectionHeader = ReadUnaligned64 ((UINT64 *)&SectionHeader.PointerToRelocations);
|
|
||||||
if (ValueInSectionHeader != 0) {
|
|
||||||
//
|
|
||||||
// Found first section header that doesn't point to code section in which build tool saves the
|
|
||||||
// offset to SMRAM base as image base in PointerToRelocations & PointerToLineNumbers fields
|
|
||||||
//
|
|
||||||
FixLoadingAddress = (EFI_PHYSICAL_ADDRESS)(SmramBase + (INT64)ValueInSectionHeader);
|
|
||||||
|
|
||||||
if ((SmramBase + SmmCodeSize > FixLoadingAddress) && (SmramBase <= FixLoadingAddress)) {
|
|
||||||
//
|
|
||||||
// The assigned address is valid. Return the specified loading address
|
|
||||||
//
|
|
||||||
ImageContext->ImageAddress = FixLoadingAddress;
|
|
||||||
Status = EFI_SUCCESS;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
SectionHeaderOffset += sizeof (EFI_IMAGE_SECTION_HEADER);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DEBUG ((DEBUG_INFO|DEBUG_LOAD, "LOADING MODULE FIXED INFO: Loading module at fixed address %x, Status = %r \n", FixLoadingAddress, Status));
|
DEBUG ((EFI_D_INFO|EFI_D_LOAD, "LOADING MODULE FIXED INFO: Loading module at fixed address %x, Status = %r \n", FixLoadingAddress, Status));
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1024,9 +976,14 @@ ExecuteSmmCoreFromSmram (
|
|||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
VOID *SourceBuffer;
|
VOID *SourceBuffer;
|
||||||
UINTN SourceSize;
|
UINTN SourceSize;
|
||||||
PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;
|
UINT32 ImageSize;
|
||||||
|
UINT32 ImageAlignment;
|
||||||
|
UINT32 DestinationPages;
|
||||||
|
UINT32 DestinationSize;
|
||||||
|
UINT32 AlignSubtrahend;
|
||||||
UINTN PageCount;
|
UINTN PageCount;
|
||||||
EFI_IMAGE_ENTRY_POINT EntryPoint;
|
EFI_IMAGE_ENTRY_POINT EntryPoint;
|
||||||
|
EFI_PHYSICAL_ADDRESS LoadAddress;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Search all Firmware Volumes for a PE/COFF image in a file of type SMM_CORE
|
// Search all Firmware Volumes for a PE/COFF image in a file of type SMM_CORE
|
||||||
@ -1043,20 +1000,26 @@ ExecuteSmmCoreFromSmram (
|
|||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// Initialize ImageContext
|
|
||||||
//
|
|
||||||
ImageContext.Handle = SourceBuffer;
|
|
||||||
ImageContext.ImageRead = PeCoffLoaderImageReadFromMemory;
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Get information about the image being loaded
|
// Get information about the image being loaded
|
||||||
//
|
//
|
||||||
Status = PeCoffLoaderGetImageInfo (&ImageContext);
|
Status = UefiImageInitializeContext (&gSmmCorePrivate->PiSmmCoreImageContext, SourceBuffer, (UINT32) SourceSize);
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Stripped relocations are not supported for both fixed-address and dynamic
|
||||||
|
// loading.
|
||||||
|
//
|
||||||
|
if (UefiImageGetRelocsStripped (&gSmmCorePrivate->PiSmmCoreImageContext)) {
|
||||||
|
return EFI_UNSUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
ImageSize = UefiImageGetImageSize (&gSmmCorePrivate->PiSmmCoreImageContext);
|
||||||
|
DestinationPages = EFI_SIZE_TO_PAGES (ImageSize);
|
||||||
|
DestinationSize = EFI_PAGES_TO_SIZE (DestinationPages);
|
||||||
|
ImageAlignment = UefiImageGetSegmentAlignment (&gSmmCorePrivate->PiSmmCoreImageContext);
|
||||||
//
|
//
|
||||||
// if Loading module at Fixed Address feature is enabled, the SMM core driver will be loaded to
|
// if Loading module at Fixed Address feature is enabled, the SMM core driver will be loaded to
|
||||||
// the address assigned by build tool.
|
// the address assigned by build tool.
|
||||||
@ -1065,7 +1028,7 @@ ExecuteSmmCoreFromSmram (
|
|||||||
//
|
//
|
||||||
// Get the fixed loading address assigned by Build tool
|
// Get the fixed loading address assigned by Build tool
|
||||||
//
|
//
|
||||||
Status = GetPeCoffImageFixLoadingAssignedAddress (&ImageContext);
|
Status = GetUefiImageFixLoadingAssignedAddress (&gSmmCorePrivate->PiSmmCoreImageContext, &LoadAddress);
|
||||||
if (!EFI_ERROR (Status)) {
|
if (!EFI_ERROR (Status)) {
|
||||||
//
|
//
|
||||||
// Since the memory range to load SMM CORE will be cut out in SMM core, so no need to allocate and free this range
|
// Since the memory range to load SMM CORE will be cut out in SMM core, so no need to allocate and free this range
|
||||||
@ -1081,7 +1044,11 @@ ExecuteSmmCoreFromSmram (
|
|||||||
// Allocate memory for the image being loaded from the EFI_SRAM_DESCRIPTOR
|
// Allocate memory for the image being loaded from the EFI_SRAM_DESCRIPTOR
|
||||||
// specified by SmramRange
|
// specified by SmramRange
|
||||||
//
|
//
|
||||||
PageCount = (UINTN)EFI_SIZE_TO_PAGES ((UINTN)ImageContext.ImageSize + ImageContext.SectionAlignment);
|
AlignSubtrahend = ALIGN_VALUE_SUBTRAHEND (
|
||||||
|
SmramRange->CpuStart + SmramRange->PhysicalSize,
|
||||||
|
ImageAlignment
|
||||||
|
);
|
||||||
|
PageCount = (UINTN)DestinationPages + (UINTN)EFI_SIZE_TO_PAGES ((UINTN)AlignSubtrahend);
|
||||||
|
|
||||||
ASSERT ((SmramRange->PhysicalSize & EFI_PAGE_MASK) == 0);
|
ASSERT ((SmramRange->PhysicalSize & EFI_PAGE_MASK) == 0);
|
||||||
ASSERT (SmramRange->PhysicalSize > EFI_PAGES_TO_SIZE (PageCount));
|
ASSERT (SmramRange->PhysicalSize > EFI_PAGES_TO_SIZE (PageCount));
|
||||||
@ -1095,14 +1062,18 @@ ExecuteSmmCoreFromSmram (
|
|||||||
//
|
//
|
||||||
// Align buffer on section boundary
|
// Align buffer on section boundary
|
||||||
//
|
//
|
||||||
ImageContext.ImageAddress = SmramRangeSmmCore->CpuStart;
|
LoadAddress = SmramRangeSmmCore->CpuStart;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
//
|
//
|
||||||
// Allocate memory for the image being loaded from the EFI_SRAM_DESCRIPTOR
|
// Allocate memory for the image being loaded from the EFI_SRAM_DESCRIPTOR
|
||||||
// specified by SmramRange
|
// specified by SmramRange
|
||||||
//
|
//
|
||||||
PageCount = (UINTN)EFI_SIZE_TO_PAGES ((UINTN)ImageContext.ImageSize + ImageContext.SectionAlignment);
|
AlignSubtrahend = ALIGN_VALUE_SUBTRAHEND (
|
||||||
|
SmramRange->CpuStart + SmramRange->PhysicalSize,
|
||||||
|
ImageAlignment
|
||||||
|
);
|
||||||
|
PageCount = (UINTN)DestinationPages + (UINTN)EFI_SIZE_TO_PAGES ((UINTN)AlignSubtrahend);
|
||||||
|
|
||||||
ASSERT ((SmramRange->PhysicalSize & EFI_PAGE_MASK) == 0);
|
ASSERT ((SmramRange->PhysicalSize & EFI_PAGE_MASK) == 0);
|
||||||
ASSERT (SmramRange->PhysicalSize > EFI_PAGES_TO_SIZE (PageCount));
|
ASSERT (SmramRange->PhysicalSize > EFI_PAGES_TO_SIZE (PageCount));
|
||||||
@ -1116,50 +1087,34 @@ ExecuteSmmCoreFromSmram (
|
|||||||
//
|
//
|
||||||
// Align buffer on section boundary
|
// Align buffer on section boundary
|
||||||
//
|
//
|
||||||
ImageContext.ImageAddress = SmramRangeSmmCore->CpuStart;
|
LoadAddress = SmramRangeSmmCore->CpuStart;
|
||||||
}
|
}
|
||||||
|
|
||||||
ImageContext.ImageAddress += ImageContext.SectionAlignment - 1;
|
|
||||||
ImageContext.ImageAddress &= ~((EFI_PHYSICAL_ADDRESS)ImageContext.SectionAlignment - 1);
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Print debug message showing SMM Core load address.
|
// Print debug message showing SMM Core load address.
|
||||||
//
|
//
|
||||||
DEBUG ((DEBUG_INFO, "SMM IPL loading SMM Core at SMRAM address %p\n", (VOID *)(UINTN)ImageContext.ImageAddress));
|
DEBUG ((DEBUG_INFO, "SMM IPL loading SMM Core at SMRAM destination %p\n", (VOID *)(UINTN)LoadAddress));
|
||||||
|
|
||||||
//
|
//
|
||||||
// Load the image to our new buffer
|
// Load the image to our new buffer
|
||||||
//
|
//
|
||||||
Status = PeCoffLoaderLoadImage (&ImageContext);
|
Status = UefiImageLoadImageForExecution (&gSmmCorePrivate->PiSmmCoreImageContext, (VOID *)(UINTN)LoadAddress, DestinationSize, NULL, 0);
|
||||||
if (!EFI_ERROR (Status)) {
|
if (!EFI_ERROR (Status)) {
|
||||||
|
LoadAddress = UefiImageLoaderGetImageAddress (&gSmmCorePrivate->PiSmmCoreImageContext);
|
||||||
//
|
//
|
||||||
// Relocate the image in our new buffer
|
// Print debug message showing SMM Core entry point address.
|
||||||
//
|
//
|
||||||
Status = PeCoffLoaderRelocateImage (&ImageContext);
|
DEBUG ((DEBUG_INFO, "SMM IPL calling SMM Core at SMRAM address %p\n", (VOID *)(UINTN)(UefiImageLoaderGetImageEntryPoint (&gSmmCorePrivate->PiSmmCoreImageContext))));
|
||||||
if (!EFI_ERROR (Status)) {
|
|
||||||
//
|
|
||||||
// Flush the instruction cache so the image data are written before we execute it
|
|
||||||
//
|
|
||||||
InvalidateInstructionCacheRange ((VOID *)(UINTN)ImageContext.ImageAddress, (UINTN)ImageContext.ImageSize);
|
|
||||||
|
|
||||||
//
|
gSmmCorePrivate->PiSmmCoreImageBase = LoadAddress;
|
||||||
// Print debug message showing SMM Core entry point address.
|
DEBUG ((DEBUG_INFO, "PiSmmCoreImageBase - 0x%016lx\n", gSmmCorePrivate->PiSmmCoreImageBase));
|
||||||
//
|
DEBUG ((DEBUG_INFO, "PiSmmCoreImageSize - 0x%016lx\n", UefiImageGetImageSize (&gSmmCorePrivate->PiSmmCoreImageContext)));
|
||||||
DEBUG ((DEBUG_INFO, "SMM IPL calling SMM Core at SMRAM address %p\n", (VOID *)(UINTN)ImageContext.EntryPoint));
|
|
||||||
|
|
||||||
gSmmCorePrivate->PiSmmCoreImageBase = ImageContext.ImageAddress;
|
//
|
||||||
gSmmCorePrivate->PiSmmCoreImageSize = ImageContext.ImageSize;
|
// Execute image
|
||||||
DEBUG ((DEBUG_INFO, "PiSmmCoreImageBase - 0x%016lx\n", gSmmCorePrivate->PiSmmCoreImageBase));
|
//
|
||||||
DEBUG ((DEBUG_INFO, "PiSmmCoreImageSize - 0x%016lx\n", gSmmCorePrivate->PiSmmCoreImageSize));
|
EntryPoint = (EFI_IMAGE_ENTRY_POINT)(UINTN)(UefiImageLoaderGetImageEntryPoint (&gSmmCorePrivate->PiSmmCoreImageContext));
|
||||||
|
Status = EntryPoint ((EFI_HANDLE)Context, gST);
|
||||||
gSmmCorePrivate->PiSmmCoreEntryPoint = ImageContext.EntryPoint;
|
|
||||||
|
|
||||||
//
|
|
||||||
// Execute image
|
|
||||||
//
|
|
||||||
EntryPoint = (EFI_IMAGE_ENTRY_POINT)(UINTN)ImageContext.EntryPoint;
|
|
||||||
Status = EntryPoint ((EFI_HANDLE)Context, gST);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -35,7 +35,7 @@
|
|||||||
UefiDriverEntryPoint
|
UefiDriverEntryPoint
|
||||||
BaseLib
|
BaseLib
|
||||||
BaseMemoryLib
|
BaseMemoryLib
|
||||||
PeCoffLib
|
UefiImageLib
|
||||||
CacheMaintenanceLib
|
CacheMaintenanceLib
|
||||||
MemoryAllocationLib
|
MemoryAllocationLib
|
||||||
DebugLib
|
DebugLib
|
||||||
|
@ -17,7 +17,6 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
|
|||||||
#include <Library/PrintLib.h>
|
#include <Library/PrintLib.h>
|
||||||
#include <Library/UefiLib.h>
|
#include <Library/UefiLib.h>
|
||||||
#include <Library/DevicePathLib.h>
|
#include <Library/DevicePathLib.h>
|
||||||
#include <Library/PeCoffGetEntryPointLib.h>
|
|
||||||
#include <Protocol/LoadedImage.h>
|
#include <Protocol/LoadedImage.h>
|
||||||
#include <Protocol/SmmAccess2.h>
|
#include <Protocol/SmmAccess2.h>
|
||||||
#include <Protocol/SmmReadyToLock.h>
|
#include <Protocol/SmmReadyToLock.h>
|
||||||
@ -74,7 +73,7 @@ BuildSmiHandlerProfileDatabase (
|
|||||||
|
|
||||||
**/
|
**/
|
||||||
RETURN_STATUS
|
RETURN_STATUS
|
||||||
InternalPeCoffGetEntryPoint (
|
InternalUefiImageGetEntryPoint (
|
||||||
IN VOID *Pe32Data,
|
IN VOID *Pe32Data,
|
||||||
OUT VOID **EntryPoint
|
OUT VOID **EntryPoint
|
||||||
);
|
);
|
||||||
@ -264,7 +263,6 @@ GetSmmLoadedImage (
|
|||||||
CHAR16 *PathStr;
|
CHAR16 *PathStr;
|
||||||
EFI_SMM_DRIVER_ENTRY *LoadedImagePrivate;
|
EFI_SMM_DRIVER_ENTRY *LoadedImagePrivate;
|
||||||
PHYSICAL_ADDRESS EntryPoint;
|
PHYSICAL_ADDRESS EntryPoint;
|
||||||
VOID *EntryPointInImage;
|
|
||||||
EFI_GUID Guid;
|
EFI_GUID Guid;
|
||||||
CHAR8 *PdbString;
|
CHAR8 *PdbString;
|
||||||
PHYSICAL_ADDRESS RealImageBase;
|
PHYSICAL_ADDRESS RealImageBase;
|
||||||
@ -324,15 +322,6 @@ GetSmmLoadedImage (
|
|||||||
RealImageBase = (UINTN)LoadedImage->ImageBase;
|
RealImageBase = (UINTN)LoadedImage->ImageBase;
|
||||||
if (LoadedImagePrivate->Signature == EFI_SMM_DRIVER_ENTRY_SIGNATURE) {
|
if (LoadedImagePrivate->Signature == EFI_SMM_DRIVER_ENTRY_SIGNATURE) {
|
||||||
EntryPoint = LoadedImagePrivate->ImageEntryPoint;
|
EntryPoint = LoadedImagePrivate->ImageEntryPoint;
|
||||||
if ((EntryPoint != 0) && ((EntryPoint < (UINTN)LoadedImage->ImageBase) || (EntryPoint >= ((UINTN)LoadedImage->ImageBase + LoadedImage->ImageSize)))) {
|
|
||||||
//
|
|
||||||
// If the EntryPoint is not in the range of image buffer, it should come from emulation environment.
|
|
||||||
// So patch ImageBuffer here to align the EntryPoint.
|
|
||||||
//
|
|
||||||
Status = InternalPeCoffGetEntryPoint (LoadedImage->ImageBase, &EntryPointInImage);
|
|
||||||
ASSERT_EFI_ERROR (Status);
|
|
||||||
RealImageBase = (UINTN)LoadedImage->ImageBase + EntryPoint - (UINTN)EntryPointInImage;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DEBUG ((DEBUG_INFO, "(0x%lx - 0x%lx", RealImageBase, LoadedImage->ImageSize));
|
DEBUG ((DEBUG_INFO, "(0x%lx - 0x%lx", RealImageBase, LoadedImage->ImageSize));
|
||||||
@ -342,10 +331,11 @@ GetSmmLoadedImage (
|
|||||||
|
|
||||||
DEBUG ((DEBUG_INFO, ")\n"));
|
DEBUG ((DEBUG_INFO, ")\n"));
|
||||||
|
|
||||||
if (RealImageBase != 0) {
|
// FIXME:
|
||||||
PdbString = PeCoffLoaderGetPdbPointer ((VOID *)(UINTN)RealImageBase);
|
/*if (RealImageBase != 0) {
|
||||||
|
PdbString = UefiImageLoaderGetPdbPointer ((VOID *)(UINTN)RealImageBase);
|
||||||
DEBUG ((DEBUG_INFO, " pdb - %a\n", PdbString));
|
DEBUG ((DEBUG_INFO, " pdb - %a\n", PdbString));
|
||||||
} else {
|
} else*/ {
|
||||||
PdbString = NULL;
|
PdbString = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -128,8 +128,7 @@ EFIAPI
|
|||||||
SmramProfileProtocolRegisterImage (
|
SmramProfileProtocolRegisterImage (
|
||||||
IN EDKII_SMM_MEMORY_PROFILE_PROTOCOL *This,
|
IN EDKII_SMM_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
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -249,110 +248,6 @@ GetSmramProfileContext (
|
|||||||
return mSmramProfileContextPtr;
|
return mSmramProfileContextPtr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
Retrieves and returns the Subsystem of a PE/COFF image that has been loaded into system memory.
|
|
||||||
If Pe32Data is NULL, then ASSERT().
|
|
||||||
|
|
||||||
@param Pe32Data The pointer to the PE/COFF image that is loaded in system memory.
|
|
||||||
|
|
||||||
@return The Subsystem of the PE/COFF image.
|
|
||||||
|
|
||||||
**/
|
|
||||||
UINT16
|
|
||||||
InternalPeCoffGetSubsystem (
|
|
||||||
IN VOID *Pe32Data
|
|
||||||
)
|
|
||||||
{
|
|
||||||
EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr;
|
|
||||||
EFI_IMAGE_DOS_HEADER *DosHdr;
|
|
||||||
UINT16 Magic;
|
|
||||||
|
|
||||||
ASSERT (Pe32Data != NULL);
|
|
||||||
|
|
||||||
DosHdr = (EFI_IMAGE_DOS_HEADER *)Pe32Data;
|
|
||||||
if (DosHdr->e_magic == EFI_IMAGE_DOS_SIGNATURE) {
|
|
||||||
//
|
|
||||||
// DOS image header is present, so read the PE header after the DOS image header.
|
|
||||||
//
|
|
||||||
Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)((UINTN)Pe32Data + (UINTN)((DosHdr->e_lfanew) & 0x0ffff));
|
|
||||||
} else {
|
|
||||||
//
|
|
||||||
// DOS image header is not present, so PE header is at the image base.
|
|
||||||
//
|
|
||||||
Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)Pe32Data;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Hdr.Te->Signature == EFI_TE_IMAGE_HEADER_SIGNATURE) {
|
|
||||||
return Hdr.Te->Subsystem;
|
|
||||||
} else if (Hdr.Pe32->Signature == EFI_IMAGE_NT_SIGNATURE) {
|
|
||||||
Magic = Hdr.Pe32->OptionalHeader.Magic;
|
|
||||||
if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
|
|
||||||
return Hdr.Pe32->OptionalHeader.Subsystem;
|
|
||||||
} else if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) {
|
|
||||||
return Hdr.Pe32Plus->OptionalHeader.Subsystem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0x0000;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
Retrieves and returns a pointer to the entry point to a PE/COFF image that has been loaded
|
|
||||||
into system memory with the PE/COFF Loader Library functions.
|
|
||||||
|
|
||||||
Retrieves the entry point to the PE/COFF image specified by Pe32Data and returns this entry
|
|
||||||
point in EntryPoint. If the entry point could not be retrieved from the PE/COFF image, then
|
|
||||||
return RETURN_INVALID_PARAMETER. Otherwise return RETURN_SUCCESS.
|
|
||||||
If Pe32Data is NULL, then ASSERT().
|
|
||||||
If EntryPoint is NULL, then ASSERT().
|
|
||||||
|
|
||||||
@param Pe32Data The pointer to the PE/COFF image that is loaded in system memory.
|
|
||||||
@param EntryPoint The pointer to entry point to the PE/COFF image to return.
|
|
||||||
|
|
||||||
@retval RETURN_SUCCESS EntryPoint was returned.
|
|
||||||
@retval RETURN_INVALID_PARAMETER The entry point could not be found in the PE/COFF image.
|
|
||||||
|
|
||||||
**/
|
|
||||||
RETURN_STATUS
|
|
||||||
InternalPeCoffGetEntryPoint (
|
|
||||||
IN VOID *Pe32Data,
|
|
||||||
OUT VOID **EntryPoint
|
|
||||||
)
|
|
||||||
{
|
|
||||||
EFI_IMAGE_DOS_HEADER *DosHdr;
|
|
||||||
EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr;
|
|
||||||
|
|
||||||
ASSERT (Pe32Data != NULL);
|
|
||||||
ASSERT (EntryPoint != NULL);
|
|
||||||
|
|
||||||
DosHdr = (EFI_IMAGE_DOS_HEADER *)Pe32Data;
|
|
||||||
if (DosHdr->e_magic == EFI_IMAGE_DOS_SIGNATURE) {
|
|
||||||
//
|
|
||||||
// DOS image header is present, so read the PE header after the DOS image header.
|
|
||||||
//
|
|
||||||
Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)((UINTN)Pe32Data + (UINTN)((DosHdr->e_lfanew) & 0x0ffff));
|
|
||||||
} else {
|
|
||||||
//
|
|
||||||
// DOS image header is not present, so PE header is at the image base.
|
|
||||||
//
|
|
||||||
Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)Pe32Data;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Calculate the entry point relative to the start of the image.
|
|
||||||
// AddressOfEntryPoint is common for PE32 & PE32+
|
|
||||||
//
|
|
||||||
if (Hdr.Te->Signature == EFI_TE_IMAGE_HEADER_SIGNATURE) {
|
|
||||||
*EntryPoint = (VOID *)((UINTN)Pe32Data + (UINTN)(Hdr.Te->AddressOfEntryPoint & 0x0ffffffff) + sizeof (EFI_TE_IMAGE_HEADER) - Hdr.Te->StrippedSize);
|
|
||||||
return RETURN_SUCCESS;
|
|
||||||
} else if (Hdr.Pe32->Signature == EFI_IMAGE_NT_SIGNATURE) {
|
|
||||||
*EntryPoint = (VOID *)((UINTN)Pe32Data + (UINTN)(Hdr.Pe32->OptionalHeader.AddressOfEntryPoint & 0x0ffffffff));
|
|
||||||
return RETURN_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
return RETURN_UNSUPPORTED;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Build driver info.
|
Build driver info.
|
||||||
|
|
||||||
@ -371,30 +266,26 @@ 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_PHYSICAL_ADDRESS LoadAddress,
|
||||||
IN PHYSICAL_ADDRESS EntryPoint,
|
|
||||||
IN UINT16 ImageSubsystem,
|
|
||||||
IN EFI_FV_FILETYPE FileType
|
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));
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
@ -422,19 +313,10 @@ BuildDriverInfo (
|
|||||||
CopyMem (&DriverInfo->FileName, FileName, sizeof (EFI_GUID));
|
CopyMem (&DriverInfo->FileName, FileName, sizeof (EFI_GUID));
|
||||||
}
|
}
|
||||||
|
|
||||||
DriverInfo->ImageBase = ImageBase;
|
DriverInfo->ImageBase = LoadAddress;
|
||||||
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);
|
||||||
@ -442,7 +324,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);
|
||||||
@ -470,8 +352,7 @@ BuildDriverInfo (
|
|||||||
VOID
|
VOID
|
||||||
RegisterImageToDxe (
|
RegisterImageToDxe (
|
||||||
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 EFI_FV_FILETYPE FileType
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
@ -490,8 +371,7 @@ RegisterImageToDxe (
|
|||||||
Status = ProfileProtocol->RegisterImage (
|
Status = ProfileProtocol->RegisterImage (
|
||||||
ProfileProtocol,
|
ProfileProtocol,
|
||||||
(EFI_DEVICE_PATH_PROTOCOL *)FilePath,
|
(EFI_DEVICE_PATH_PROTOCOL *)FilePath,
|
||||||
ImageBase,
|
ImageContext,
|
||||||
ImageSize,
|
|
||||||
FileType
|
FileType
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -610,7 +490,6 @@ RegisterSmmCore (
|
|||||||
)
|
)
|
||||||
{
|
{
|
||||||
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;
|
||||||
|
|
||||||
@ -622,14 +501,11 @@ RegisterSmmCore (
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
ImageBase = gSmmCorePrivate->PiSmmCoreImageBase;
|
|
||||||
DriverInfoData = BuildDriverInfo (
|
DriverInfoData = BuildDriverInfo (
|
||||||
ContextData,
|
ContextData,
|
||||||
&gEfiCallerIdGuid,
|
&gEfiCallerIdGuid,
|
||||||
ImageBase,
|
&gSmmCorePrivate->PiSmmCoreImageContext,
|
||||||
gSmmCorePrivate->PiSmmCoreImageSize,
|
gSmmCorePrivate->PiSmmCoreImageBase,
|
||||||
gSmmCorePrivate->PiSmmCoreEntryPoint,
|
|
||||||
InternalPeCoffGetSubsystem ((VOID *)(UINTN)ImageBase),
|
|
||||||
EFI_FV_FILETYPE_SMM_CORE
|
EFI_FV_FILETYPE_SMM_CORE
|
||||||
);
|
);
|
||||||
if (DriverInfoData == NULL) {
|
if (DriverInfoData == NULL) {
|
||||||
@ -652,8 +528,7 @@ SmramProfileInit (
|
|||||||
|
|
||||||
RegisterImageToDxe (
|
RegisterImageToDxe (
|
||||||
&gEfiCallerIdGuid,
|
&gEfiCallerIdGuid,
|
||||||
gSmmCorePrivate->PiSmmCoreImageBase,
|
&gSmmCorePrivate->PiSmmCoreImageContext,
|
||||||
gSmmCorePrivate->PiSmmCoreImageSize,
|
|
||||||
EFI_FV_FILETYPE_SMM_CORE
|
EFI_FV_FILETYPE_SMM_CORE
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -754,8 +629,9 @@ GetFileNameFromFilePath (
|
|||||||
**/
|
**/
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
RegisterSmramProfileImage (
|
RegisterSmramProfileImage (
|
||||||
IN EFI_SMM_DRIVER_ENTRY *DriverEntry,
|
IN EFI_GUID *FileName,
|
||||||
IN BOOLEAN RegisterToDxe
|
IN BOOLEAN RegisterToDxe,
|
||||||
|
IN UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
MEMORY_PROFILE_CONTEXT_DATA *ContextData;
|
MEMORY_PROFILE_CONTEXT_DATA *ContextData;
|
||||||
@ -765,9 +641,8 @@ RegisterSmramProfileImage (
|
|||||||
|
|
||||||
if (RegisterToDxe) {
|
if (RegisterToDxe) {
|
||||||
RegisterImageToDxe (
|
RegisterImageToDxe (
|
||||||
&DriverEntry->FileName,
|
FileName,
|
||||||
DriverEntry->ImageBuffer,
|
ImageContext,
|
||||||
EFI_PAGES_TO_SIZE (DriverEntry->NumberOfPage),
|
|
||||||
EFI_FV_FILETYPE_SMM
|
EFI_FV_FILETYPE_SMM
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -777,7 +652,7 @@ RegisterSmramProfileImage (
|
|||||||
}
|
}
|
||||||
|
|
||||||
FilePath = (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *)TempBuffer;
|
FilePath = (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *)TempBuffer;
|
||||||
EfiInitializeFwVolDevicepathNode (FilePath, &DriverEntry->FileName);
|
EfiInitializeFwVolDevicepathNode (FilePath, FileName);
|
||||||
SetDevicePathEndNode (FilePath + 1);
|
SetDevicePathEndNode (FilePath + 1);
|
||||||
|
|
||||||
if (!NeedRecordThisDriver ((EFI_DEVICE_PATH_PROTOCOL *)FilePath)) {
|
if (!NeedRecordThisDriver ((EFI_DEVICE_PATH_PROTOCOL *)FilePath)) {
|
||||||
@ -791,11 +666,9 @@ RegisterSmramProfileImage (
|
|||||||
|
|
||||||
DriverInfoData = BuildDriverInfo (
|
DriverInfoData = BuildDriverInfo (
|
||||||
ContextData,
|
ContextData,
|
||||||
&DriverEntry->FileName,
|
FileName,
|
||||||
DriverEntry->ImageBuffer,
|
ImageContext,
|
||||||
EFI_PAGES_TO_SIZE (DriverEntry->NumberOfPage),
|
UefiImageLoaderGetImageAddress (ImageContext),
|
||||||
DriverEntry->ImageEntryPoint,
|
|
||||||
InternalPeCoffGetSubsystem ((VOID *)(UINTN)DriverEntry->ImageBuffer),
|
|
||||||
EFI_FV_FILETYPE_SMM
|
EFI_FV_FILETYPE_SMM
|
||||||
);
|
);
|
||||||
if (DriverInfoData == NULL) {
|
if (DriverInfoData == NULL) {
|
||||||
@ -909,24 +782,22 @@ GetMemoryProfileDriverInfoFromAddress (
|
|||||||
**/
|
**/
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
UnregisterSmramProfileImage (
|
UnregisterSmramProfileImage (
|
||||||
IN EFI_SMM_DRIVER_ENTRY *DriverEntry,
|
IN EFI_GUID *FileName,
|
||||||
IN BOOLEAN UnregisterFromDxe
|
IN PHYSICAL_ADDRESS ImageBase,
|
||||||
|
IN UINT64 ImageSize,
|
||||||
|
IN BOOLEAN UnregisterFromDxe
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
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;
|
|
||||||
PHYSICAL_ADDRESS ImageAddress;
|
|
||||||
VOID *EntryPointInImage;
|
|
||||||
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;
|
||||||
|
|
||||||
if (UnregisterFromDxe) {
|
if (UnregisterFromDxe) {
|
||||||
UnregisterImageFromDxe (
|
UnregisterImageFromDxe (
|
||||||
&DriverEntry->FileName,
|
FileName,
|
||||||
DriverEntry->ImageBuffer,
|
ImageBase,
|
||||||
EFI_PAGES_TO_SIZE (DriverEntry->NumberOfPage)
|
ImageSize
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -935,7 +806,7 @@ UnregisterSmramProfileImage (
|
|||||||
}
|
}
|
||||||
|
|
||||||
FilePath = (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *)TempBuffer;
|
FilePath = (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *)TempBuffer;
|
||||||
EfiInitializeFwVolDevicepathNode (FilePath, &DriverEntry->FileName);
|
EfiInitializeFwVolDevicepathNode (FilePath, FileName);
|
||||||
SetDevicePathEndNode (FilePath + 1);
|
SetDevicePathEndNode (FilePath + 1);
|
||||||
|
|
||||||
if (!NeedRecordThisDriver ((EFI_DEVICE_PATH_PROTOCOL *)FilePath)) {
|
if (!NeedRecordThisDriver ((EFI_DEVICE_PATH_PROTOCOL *)FilePath)) {
|
||||||
@ -948,24 +819,13 @@ UnregisterSmramProfileImage (
|
|||||||
}
|
}
|
||||||
|
|
||||||
DriverInfoData = NULL;
|
DriverInfoData = NULL;
|
||||||
FileName = &DriverEntry->FileName;
|
|
||||||
ImageAddress = DriverEntry->ImageBuffer;
|
|
||||||
if ((DriverEntry->ImageEntryPoint < ImageAddress) || (DriverEntry->ImageEntryPoint >= (ImageAddress + EFI_PAGES_TO_SIZE (DriverEntry->NumberOfPage)))) {
|
|
||||||
//
|
|
||||||
// If the EntryPoint is not in the range of image buffer, it should come from emulation environment.
|
|
||||||
// So patch ImageAddress here to align the EntryPoint.
|
|
||||||
//
|
|
||||||
Status = InternalPeCoffGetEntryPoint ((VOID *)(UINTN)ImageAddress, &EntryPointInImage);
|
|
||||||
ASSERT_EFI_ERROR (Status);
|
|
||||||
ImageAddress = ImageAddress + (UINTN)DriverEntry->ImageEntryPoint - (UINTN)EntryPointInImage;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (FileName != NULL) {
|
if (FileName != NULL) {
|
||||||
DriverInfoData = GetMemoryProfileDriverInfoByFileNameAndAddress (ContextData, FileName, ImageAddress);
|
DriverInfoData = GetMemoryProfileDriverInfoByFileNameAndAddress (ContextData, FileName, ImageBase);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (DriverInfoData == NULL) {
|
if (DriverInfoData == NULL) {
|
||||||
DriverInfoData = GetMemoryProfileDriverInfoFromAddress (ContextData, ImageAddress);
|
DriverInfoData = GetMemoryProfileDriverInfoFromAddress (ContextData, ImageBase);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (DriverInfoData == NULL) {
|
if (DriverInfoData == NULL) {
|
||||||
@ -1989,29 +1849,20 @@ EFIAPI
|
|||||||
SmramProfileProtocolRegisterImage (
|
SmramProfileProtocolRegisterImage (
|
||||||
IN EDKII_SMM_MEMORY_PROFILE_PROTOCOL *This,
|
IN EDKII_SMM_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;
|
EFI_GUID *FileName;
|
||||||
EFI_SMM_DRIVER_ENTRY DriverEntry;
|
EFI_GUID ZeroGuid;
|
||||||
VOID *EntryPointInImage;
|
|
||||||
EFI_GUID *Name;
|
|
||||||
|
|
||||||
ZeroMem (&DriverEntry, sizeof (DriverEntry));
|
FileName = GetFileNameFromFilePath (FilePath);
|
||||||
Name = GetFileNameFromFilePath (FilePath);
|
if (FileName == NULL) {
|
||||||
if (Name != NULL) {
|
ZeroMem (&ZeroGuid, sizeof (ZeroGuid));
|
||||||
CopyMem (&DriverEntry.FileName, Name, sizeof (EFI_GUID));
|
FileName = &ZeroGuid;
|
||||||
}
|
}
|
||||||
|
|
||||||
DriverEntry.ImageBuffer = ImageBase;
|
return RegisterSmramProfileImage (FileName, FALSE, ImageContext);
|
||||||
DriverEntry.NumberOfPage = EFI_SIZE_TO_PAGES ((UINTN)ImageSize);
|
|
||||||
Status = InternalPeCoffGetEntryPoint ((VOID *)(UINTN)DriverEntry.ImageBuffer, &EntryPointInImage);
|
|
||||||
ASSERT_EFI_ERROR (Status);
|
|
||||||
DriverEntry.ImageEntryPoint = (PHYSICAL_ADDRESS)(UINTN)EntryPointInImage;
|
|
||||||
|
|
||||||
return RegisterSmramProfileImage (&DriverEntry, FALSE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -2037,24 +1888,16 @@ SmramProfileProtocolUnregisterImage (
|
|||||||
IN UINT64 ImageSize
|
IN UINT64 ImageSize
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
EFI_STATUS Status;
|
EFI_GUID *FileName;
|
||||||
EFI_SMM_DRIVER_ENTRY DriverEntry;
|
EFI_GUID ZeroGuid;
|
||||||
VOID *EntryPointInImage;
|
|
||||||
EFI_GUID *Name;
|
|
||||||
|
|
||||||
ZeroMem (&DriverEntry, sizeof (DriverEntry));
|
FileName = GetFileNameFromFilePath (FilePath);
|
||||||
Name = GetFileNameFromFilePath (FilePath);
|
if (FileName == NULL) {
|
||||||
if (Name != NULL) {
|
ZeroMem (&ZeroGuid, sizeof (ZeroGuid));
|
||||||
CopyMem (&DriverEntry.FileName, Name, sizeof (EFI_GUID));
|
FileName = &ZeroGuid;
|
||||||
}
|
}
|
||||||
|
|
||||||
DriverEntry.ImageBuffer = ImageBase;
|
return UnregisterSmramProfileImage (FileName, ImageBase, ImageSize, FALSE);
|
||||||
DriverEntry.NumberOfPage = EFI_SIZE_TO_PAGES ((UINTN)ImageSize);
|
|
||||||
Status = InternalPeCoffGetEntryPoint ((VOID *)(UINTN)DriverEntry.ImageBuffer, &EntryPointInImage);
|
|
||||||
ASSERT_EFI_ERROR (Status);
|
|
||||||
DriverEntry.ImageEntryPoint = (PHYSICAL_ADDRESS)(UINTN)EntryPointInImage;
|
|
||||||
|
|
||||||
return UnregisterSmramProfileImage (&DriverEntry, FALSE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user