StandaloneMmPkg/StandaloneMmCoreEntryPoint: permit the use of TE images

TE images take up less space when using 4 KB section alignment, since
the FFS/FV generation code optimizes away the redundant, nested padding.
This saves 4 KB of space, which is a worthwhile improvement for code
that executes in place in secure context.

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Reviewed-by: Achin Gupta <achin.gupta@arm.com>
This commit is contained in:
Ard Biesheuvel 2019-01-16 21:22:35 +01:00
parent 877013d0a5
commit 4b28452d98

View File

@ -143,9 +143,12 @@ LocateStandaloneMmCorePeCoffData (
Status = FfsFindSectionData (EFI_SECTION_PE32, FileHeader, TeData, TeDataSize); Status = FfsFindSectionData (EFI_SECTION_PE32, FileHeader, TeData, TeDataSize);
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "Unable to locate Standalone MM Section data - 0x%x\n", Status = FfsFindSectionData (EFI_SECTION_TE, FileHeader, TeData, TeDataSize);
Status)); if (EFI_ERROR (Status)) {
return Status; DEBUG ((DEBUG_ERROR, "Unable to locate Standalone MM Section data - %r\n",
Status));
return Status;
}
} }
DEBUG ((DEBUG_INFO, "Found Standalone MM PE data - 0x%x\n", *TeData)); DEBUG ((DEBUG_INFO, "Found Standalone MM PE data - 0x%x\n", *TeData));
@ -155,10 +158,9 @@ LocateStandaloneMmCorePeCoffData (
STATIC STATIC
EFI_STATUS EFI_STATUS
GetPeCoffSectionInformation ( GetPeCoffSectionInformation (
IN CONST PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext, IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext,
IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *TmpContext, OUT UINT32 *SectionHeaderOffset,
IN OUT UINT32 *SectionHeaderOffset, OUT UINT16 *NumberOfSections
IN OUT UINT16 *NumberOfSections
) )
{ {
RETURN_STATUS Status; RETURN_STATUS Status;
@ -168,44 +170,29 @@ GetPeCoffSectionInformation (
UINTN ReadSize; UINTN ReadSize;
ASSERT (ImageContext != NULL); ASSERT (ImageContext != NULL);
ASSERT (TmpContext != NULL);
ASSERT (SectionHeaderOffset != NULL); ASSERT (SectionHeaderOffset != NULL);
ASSERT (NumberOfSections != NULL); ASSERT (NumberOfSections != NULL);
// Status = PeCoffLoaderGetImageInfo (ImageContext);
// We need to copy ImageContext since PeCoffLoaderGetImageInfo () if (RETURN_ERROR (Status)) {
// will mangle the ImageAddress field DEBUG ((DEBUG_ERROR,
// "%a: PeCoffLoaderGetImageInfo () failed (Status == %r)\n",
CopyMem (TmpContext, ImageContext, sizeof (*TmpContext)); __FUNCTION__, Status));
return Status;
if (TmpContext->PeCoffHeaderOffset == 0) {
Status = PeCoffLoaderGetImageInfo (TmpContext);
if (RETURN_ERROR (Status)) {
DEBUG ((DEBUG_ERROR,
"%a: PeCoffLoaderGetImageInfo () failed (Status = %r)\n",
__FUNCTION__, Status));
return Status;
}
} }
if (TmpContext->IsTeImage && if (ImageContext->SectionAlignment < EFI_PAGE_SIZE) {
TmpContext->ImageAddress == ImageContext->ImageAddress) {
DEBUG ((DEBUG_INFO, "%a: ignoring XIP TE image at 0x%lx\n", __FUNCTION__,
ImageContext->ImageAddress));
return RETURN_UNSUPPORTED;
}
if (TmpContext->SectionAlignment < EFI_PAGE_SIZE) {
// //
// The sections need to be at least 4 KB aligned, since that is the // The sections need to be at least 4 KB aligned, since that is the
// granularity at which we can tighten permissions. // granularity at which we can tighten permissions.
// //
if (!TmpContext->IsTeImage) { if (!ImageContext->IsTeImage) {
DEBUG ((DEBUG_WARN, DEBUG ((DEBUG_WARN,
"%a: non-TE Image at 0x%lx has SectionAlignment < 4 KB (%lu)\n", "%a: non-TE Image at 0x%lx has SectionAlignment < 4 KB (%lu)\n",
__FUNCTION__, ImageContext->ImageAddress, TmpContext->SectionAlignment)); __FUNCTION__, ImageContext->ImageAddress, ImageContext->SectionAlignment));
return RETURN_UNSUPPORTED;
} }
return RETURN_UNSUPPORTED; ImageContext->SectionAlignment = EFI_PAGE_SIZE;
} }
// //
@ -217,9 +204,9 @@ GetPeCoffSectionInformation (
Hdr.Union = &HdrData; Hdr.Union = &HdrData;
Size = sizeof (EFI_IMAGE_OPTIONAL_HEADER_UNION); Size = sizeof (EFI_IMAGE_OPTIONAL_HEADER_UNION);
ReadSize = Size; ReadSize = Size;
Status = TmpContext->ImageRead ( Status = ImageContext->ImageRead (
TmpContext->Handle, ImageContext->Handle,
TmpContext->PeCoffHeaderOffset, ImageContext->PeCoffHeaderOffset,
&Size, &Size,
Hdr.Pe32 Hdr.Pe32
); );
@ -231,23 +218,28 @@ GetPeCoffSectionInformation (
return Status; return Status;
} }
ASSERT (Hdr.Pe32->Signature == EFI_IMAGE_NT_SIGNATURE); if (!ImageContext->IsTeImage) {
ASSERT (Hdr.Pe32->Signature == EFI_IMAGE_NT_SIGNATURE);
*SectionHeaderOffset = TmpContext->PeCoffHeaderOffset + sizeof (UINT32) + *SectionHeaderOffset = ImageContext->PeCoffHeaderOffset + sizeof (UINT32) +
sizeof (EFI_IMAGE_FILE_HEADER); sizeof (EFI_IMAGE_FILE_HEADER);
*NumberOfSections = Hdr.Pe32->FileHeader.NumberOfSections; *NumberOfSections = Hdr.Pe32->FileHeader.NumberOfSections;
switch (Hdr.Pe32->OptionalHeader.Magic) { switch (Hdr.Pe32->OptionalHeader.Magic) {
case EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC: case EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC:
*SectionHeaderOffset += Hdr.Pe32->FileHeader.SizeOfOptionalHeader; *SectionHeaderOffset += Hdr.Pe32->FileHeader.SizeOfOptionalHeader;
break; break;
case EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC: case EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC:
*SectionHeaderOffset += Hdr.Pe32Plus->FileHeader.SizeOfOptionalHeader; *SectionHeaderOffset += Hdr.Pe32Plus->FileHeader.SizeOfOptionalHeader;
break; break;
default: default:
ASSERT (FALSE); ASSERT (FALSE);
}
} else {
*SectionHeaderOffset = (UINTN)(sizeof (EFI_TE_IMAGE_HEADER));
*NumberOfSections = Hdr.Te->NumberOfSections;
ImageContext->ImageAddress -= (UINT32)Hdr.Te->StrippedSize - sizeof (EFI_TE_IMAGE_HEADER);
} }
return RETURN_SUCCESS; return RETURN_SUCCESS;
} }
@ -261,7 +253,6 @@ GetStandaloneMmCorePeCoffSections (
) )
{ {
EFI_STATUS Status; EFI_STATUS Status;
PE_COFF_LOADER_IMAGE_CONTEXT TmpContext;
// Initialize the Image Context // Initialize the Image Context
ZeroMem (ImageContext, sizeof (PE_COFF_LOADER_IMAGE_CONTEXT)); ZeroMem (ImageContext, sizeof (PE_COFF_LOADER_IMAGE_CONTEXT));
@ -270,15 +261,9 @@ GetStandaloneMmCorePeCoffSections (
DEBUG ((DEBUG_INFO, "Found Standalone MM PE data - 0x%x\n", TeData)); DEBUG ((DEBUG_INFO, "Found Standalone MM PE data - 0x%x\n", TeData));
Status = PeCoffLoaderGetImageInfo (ImageContext); Status = GetPeCoffSectionInformation (ImageContext, SectionHeaderOffset, NumberOfSections);
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "Unable to locate Standalone MM Core PE-COFF Image information - 0x%x\n", Status)); DEBUG ((DEBUG_ERROR, "Unable to locate Standalone MM Core PE-COFF Section information - %r\n", Status));
return Status;
}
Status = GetPeCoffSectionInformation (ImageContext, &TmpContext, SectionHeaderOffset, NumberOfSections);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "Unable to locate Standalone MM Core PE-COFF Section information - 0x%x\n", Status));
return Status; return Status;
} }