StandaloneMmPkg/StandaloneMmCoreEntryPoint: relocate StMM core on the fly

Apply PE/COFF fixups when starting up the standalone MM core, so that
it can execute at any address regardless of the link time address.

Note that this requires the PE/COFF image to be emitted with its
relocation section preserved. Special care is taken to ensure that
TE images are dealt with correctly as well.

Signed-off-by: Ard Biesheuvel <ard.biesheuvel@arm.com>
Acked-by: Jiewen Yao <Jiewen.yao@intel.com>
Reviewed-by: Sami Mujawar <sami.mujawar@arm.com>
Tested-by: Ilias Apalodimas <ilias.apalodimas@linaro.org>
This commit is contained in:
Ard Biesheuvel
2020-06-09 10:34:27 +02:00
committed by mergify[bot]
parent cdc686223a
commit 493f2c6931
3 changed files with 34 additions and 3 deletions

View File

@@ -225,6 +225,7 @@ _ModuleEntryPoint (
VOID *HobStart;
VOID *TeData;
UINTN TeDataSize;
EFI_PHYSICAL_ADDRESS ImageBase;
// Get Secure Partition Manager Version Information
Status = GetSpmVersion ();
@@ -253,6 +254,7 @@ _ModuleEntryPoint (
Status = GetStandaloneMmCorePeCoffSections (
TeData,
&ImageContext,
&ImageBase,
&SectionHeaderOffset,
&NumberOfSections
);
@@ -261,10 +263,21 @@ _ModuleEntryPoint (
goto finish;
}
//
// 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
// Standalone MM core module
Status = UpdateMmFoundationPeCoffPermissions (
&ImageContext,
ImageBase,
SectionHeaderOffset,
NumberOfSections,
ArmSetMemoryRegionNoExec,
@@ -276,6 +289,15 @@ _ModuleEntryPoint (
goto finish;
}
if (ImageContext.ImageAddress != (UINTN)TeData) {
ImageContext.ImageAddress = (UINTN)TeData;
ArmSetMemoryRegionNoExec (ImageBase, SIZE_4KB);
ArmClearMemoryRegionReadOnly (ImageBase, SIZE_4KB);
Status = PeCoffLoaderRelocateImage (&ImageContext);
ASSERT_EFI_ERROR (Status);
}
//
// Create Hoblist based upon boot information passed by privileged software
//