MdePkg/UefiImageLib: Require callers to allocate aligned memory

This commit is contained in:
Marvin Häuser 2023-03-26 22:36:45 +02:00 committed by Mikhail Krichanov
parent 91f0ea84f1
commit 9ef906f695
16 changed files with 133 additions and 243 deletions

View File

@ -36,17 +36,18 @@ LoadUefiImage (
UEFI_IMAGE_LOADER_IMAGE_CONTEXT ImageContext; UEFI_IMAGE_LOADER_IMAGE_CONTEXT ImageContext;
VOID *Buffer; VOID *Buffer;
UINT32 BufferSize; UINT32 BufferSize;
UINT32 BufferAlignment;
Status = UefiImageInitializeContext (&ImageContext, UefiImage, UefiImageSize); Status = UefiImageInitializeContext (&ImageContext, UefiImage, UefiImageSize);
ASSERT_EFI_ERROR (Status); ASSERT_EFI_ERROR (Status);
Status = UefiImageLoaderGetDestinationSize (&ImageContext, &BufferSize); BufferSize = UefiImageGetImageSize (&ImageContext);
ASSERT_EFI_ERROR (Status); BufferAlignment = UefiImageGetSegmentAlignment (&ImageContext);
// //
// Allocate Memory for the image // Allocate Memory for the image
// //
Buffer = AllocateCodePages (EFI_SIZE_TO_PAGES (BufferSize)); Buffer = AllocateAlignedCodePages (EFI_SIZE_TO_PAGES (BufferSize), BufferAlignment);
ASSERT (Buffer != 0); ASSERT (Buffer != 0);
// //
@ -55,8 +56,8 @@ LoadUefiImage (
Status = UefiImageLoadImageForExecution (&ImageContext, Buffer, BufferSize, NULL, 0); Status = UefiImageLoadImageForExecution (&ImageContext, Buffer, BufferSize, NULL, 0);
ASSERT_EFI_ERROR (Status); ASSERT_EFI_ERROR (Status);
*ImageAddress = (UINTN) UefiImageLoaderGetImageAddress (&ImageContext); *ImageAddress = (UINTN) Buffer;
*ImageSize = UefiImageGetImageSize (&ImageContext); *ImageSize = BufferSize;
*EntryPoint = (UINTN) UefiImageLoaderGetImageEntryPoint (&ImageContext); *EntryPoint = (UINTN) UefiImageLoaderGetImageEntryPoint (&ImageContext);
return Status; return Status;

View File

@ -45,6 +45,7 @@
PerformanceLib PerformanceLib
HobLib HobLib
FspWrapperPlatformLib FspWrapperPlatformLib
MemoryAllocationLib
[Protocols] [Protocols]
gEfiPciEnumerationCompleteProtocolGuid ## CONSUMES gEfiPciEnumerationCompleteProtocolGuid ## CONSUMES

View File

@ -16,6 +16,8 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#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,7 +39,8 @@ RelocateImageUnder4GIfNeeded (
UINT8 *Buffer; UINT8 *Buffer;
UINTN BufferSize; UINTN BufferSize;
EFI_HANDLE NewImageHandle; EFI_HANDLE NewImageHandle;
UINT32 DestinationSize; UINT32 ImageSize;
UINT32 ImageAlignment;
UINTN Pages; UINTN Pages;
EFI_PHYSICAL_ADDRESS FfsBuffer; EFI_PHYSICAL_ADDRESS FfsBuffer;
UEFI_IMAGE_LOADER_IMAGE_CONTEXT ImageContext; UEFI_IMAGE_LOADER_IMAGE_CONTEXT ImageContext;
@ -89,15 +92,16 @@ RelocateImageUnder4GIfNeeded (
// //
Status = UefiImageInitializeContext (&ImageContext, Buffer, (UINT32) BufferSize); Status = UefiImageInitializeContext (&ImageContext, Buffer, (UINT32) BufferSize);
ASSERT_EFI_ERROR (Status); ASSERT_EFI_ERROR (Status);
Status = UefiImageLoaderGetDestinationSize (&ImageContext, &DestinationSize); ImageSize = UefiImageGetImageSize (&ImageContext);
ASSERT_EFI_ERROR (Status); ImageAlignment = UefiImageGetSegmentAlignment (&ImageContext);
Pages = EFI_SIZE_TO_PAGES (DestinationSize); Pages = EFI_SIZE_TO_PAGES (ImageSize);
FfsBuffer = 0xFFFFFFFF; FfsBuffer = 0xFFFFFFFF;
Status = gBS->AllocatePages ( Status = AllocateAlignedPagesEx (
AllocateMaxAddress, AllocateMaxAddress,
EfiBootServicesCode, EfiBootServicesCode,
Pages, Pages,
ImageAlignment,
&FfsBuffer &FfsBuffer
); );
ASSERT_EFI_ERROR (Status); ASSERT_EFI_ERROR (Status);
@ -107,7 +111,7 @@ RelocateImageUnder4GIfNeeded (
Status = UefiImageLoadImageForExecution ( Status = UefiImageLoadImageForExecution (
&ImageContext, &ImageContext,
(VOID *) (UINTN) FfsBuffer, (VOID *) (UINTN) FfsBuffer,
DestinationSize, ImageSize,
NULL, NULL,
0 0
); );
@ -118,11 +122,11 @@ RelocateImageUnder4GIfNeeded (
// //
gBS->FreePool (Buffer); gBS->FreePool (Buffer);
DEBUG ((DEBUG_INFO, "Loading driver at 0x%08x EntryPoint=0x%08x\n", UefiImageLoaderGetImageAddress (&ImageContext), UefiImageLoaderGetImageEntryPoint (&ImageContext))); DEBUG ((DEBUG_INFO, "Loading driver at 0x%08llx EntryPoint=0x%08x\n", FfsBuffer, UefiImageLoaderGetImageEntryPoint (&ImageContext)));
Status = ((EFI_IMAGE_ENTRY_POINT)(UefiImageLoaderGetImageEntryPoint (&ImageContext)))(NewImageHandle, gST); Status = ((EFI_IMAGE_ENTRY_POINT)(UefiImageLoaderGetImageEntryPoint (&ImageContext)))(NewImageHandle, gST);
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "Error: Image at 0x%08x start failed: %r\n", UefiImageLoaderGetImageAddress (&ImageContext), Status)); DEBUG ((DEBUG_ERROR, "Error: Image at 0x%08llx start failed: %r\n", FfsBuffer, Status));
gBS->FreePages (FfsBuffer, Pages); FreeAlignedPages ((VOID *)(UINTN)FfsBuffer, Pages);
} }
// //

View File

@ -77,6 +77,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#include <Library/UefiImageExtraActionLib.h> #include <Library/UefiImageExtraActionLib.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>

View File

@ -8,8 +8,6 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#include "DxeMain.h" #include "DxeMain.h"
#include "Image.h" #include "Image.h"
#include "Library/UefiImageLib.h"
#include "Uefi/UefiBaseType.h"
// //
// Module Globals // Module Globals
@ -514,11 +512,11 @@ CoreLoadPeImage (
EFI_STATUS Status; EFI_STATUS Status;
BOOLEAN DstBufAlocated; BOOLEAN DstBufAlocated;
UINT32 Size; UINT32 Size;
UINT32 Alignment;
EFI_MEMORY_TYPE ImageCodeMemoryType; EFI_MEMORY_TYPE ImageCodeMemoryType;
EFI_MEMORY_TYPE ImageDataMemoryType; EFI_MEMORY_TYPE ImageDataMemoryType;
UEFI_IMAGE_LOADER_RUNTIME_CONTEXT *RelocationData; UEFI_IMAGE_LOADER_RUNTIME_CONTEXT *RelocationData;
EFI_PHYSICAL_ADDRESS BufferAddress; EFI_PHYSICAL_ADDRESS BufferAddress;
UINTN LoadAddress;
UINT32 RelocDataSize; UINT32 RelocDataSize;
RelocationData = NULL; RelocationData = NULL;
@ -560,10 +558,8 @@ CoreLoadPeImage (
return EFI_UNSUPPORTED; return EFI_UNSUPPORTED;
} }
Status = UefiImageLoaderGetDestinationSize (ImageContext, &Size); Size = UefiImageGetImageSize (ImageContext);
if (RETURN_ERROR (Status)) { Alignment = UefiImageGetSegmentAlignment (ImageContext);
return Status;
}
BufferAddress = 0; BufferAddress = 0;
// //
@ -606,7 +602,7 @@ CoreLoadPeImage (
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {
BufferAddress = UefiImageGetPreferredAddress (ImageContext); BufferAddress = UefiImageGetPreferredAddress (ImageContext);
if ((BufferAddress >= 0x100000) || UefiImageGetRelocsStripped (ImageContext)) { if ((BufferAddress >= 0x100000) || UefiImageGetRelocsStripped (ImageContext)) {
Status = CoreAllocatePages ( Status = AllocatePagesEx (
AllocateAddress, AllocateAddress,
ImageCodeMemoryType, ImageCodeMemoryType,
Image->NumberOfPages, Image->NumberOfPages,
@ -615,10 +611,11 @@ CoreLoadPeImage (
} }
if (EFI_ERROR (Status) && !UefiImageGetRelocsStripped (ImageContext)) { if (EFI_ERROR (Status) && !UefiImageGetRelocsStripped (ImageContext)) {
Status = CoreAllocatePages ( Status = AllocateAlignedPagesEx (
AllocateAnyPages, AllocateAnyPages,
ImageCodeMemoryType, ImageCodeMemoryType,
Image->NumberOfPages, Image->NumberOfPages,
Alignment,
&BufferAddress &BufferAddress
); );
} }
@ -703,8 +700,6 @@ CoreLoadPeImage (
goto Done; goto Done;
} }
LoadAddress = UefiImageLoaderGetImageAddress (ImageContext);
// //
// Copy the machine type from the context to the image private data. // Copy the machine type from the context to the image private data.
// //
@ -719,7 +714,7 @@ CoreLoadPeImage (
// Fill in the image information for the Loaded Image Protocol // Fill in the image information for the Loaded Image Protocol
// //
Image->Type = UefiImageGetSubsystem (ImageContext); Image->Type = UefiImageGetSubsystem (ImageContext);
Image->Info.ImageBase = (VOID *)(UINTN)LoadAddress; Image->Info.ImageBase = (VOID *)(UINTN)BufferAddress;
Image->Info.ImageSize = UefiImageGetImageSize (ImageContext); Image->Info.ImageSize = UefiImageGetImageSize (ImageContext);
Image->Info.ImageCodeType = ImageCodeMemoryType; Image->Info.ImageCodeType = ImageCodeMemoryType;
Image->Info.ImageDataType = ImageDataMemoryType; Image->Info.ImageDataType = ImageDataMemoryType;
@ -756,7 +751,7 @@ CoreLoadPeImage (
ASSERT_EFI_ERROR (Status); ASSERT_EFI_ERROR (Status);
} }
if (!EFI_ERROR (Status)) { if (!EFI_ERROR (Status)) {
Image->HiiData = (VOID *)(UINTN)(LoadAddress + Hiioff); Image->HiiData = (VOID *)((UINTN)BufferAddress + Hiioff);
} }
// //
@ -769,7 +764,7 @@ CoreLoadPeImage (
DEBUG ((DEBUG_INFO | DEBUG_LOAD, DEBUG ((DEBUG_INFO | DEBUG_LOAD,
"Loading driver at 0x%11p EntryPoint=0x%11p \n", "Loading driver at 0x%11p EntryPoint=0x%11p \n",
(VOID *)(UINTN)LoadAddress, (VOID *)(UINTN)BufferAddress,
FUNCTION_ENTRY_POINT (UefiImageLoaderGetImageEntryPoint (ImageContext)))); FUNCTION_ENTRY_POINT (UefiImageLoaderGetImageEntryPoint (ImageContext))));
Status = UefiImageGetModuleNameFromSymbolsPath ( Status = UefiImageGetModuleNameFromSymbolsPath (
@ -798,7 +793,7 @@ Done:
if (DstBufAlocated) { if (DstBufAlocated) {
ZeroMem ((VOID *)(UINTN)BufferAddress, EFI_PAGES_TO_SIZE (Image->NumberOfPages)); ZeroMem ((VOID *)(UINTN)BufferAddress, EFI_PAGES_TO_SIZE (Image->NumberOfPages));
CoreFreePages (BufferAddress, Image->NumberOfPages); FreeAlignedPages ((VOID *)(UINTN)BufferAddress, Image->NumberOfPages);
Image->ImageBasePage = 0; Image->ImageBasePage = 0;
} }

View File

@ -169,8 +169,10 @@ LoadAndRelocateUefiImage (
) )
{ {
EFI_STATUS Status; EFI_STATUS Status;
BOOLEAN Success;
PEI_CORE_INSTANCE *Private; PEI_CORE_INSTANCE *Private;
UINT32 DynamicImageSize; UINT32 DynamicImageSize;
UINT32 DynamicImageAlignment;
BOOLEAN IsXipImage; BOOLEAN IsXipImage;
EFI_STATUS ReturnStatus; EFI_STATUS ReturnStatus;
BOOLEAN IsS3Boot; BOOLEAN IsS3Boot;
@ -261,38 +263,38 @@ LoadAndRelocateUefiImage (
(IsS3Boot && PcdGetBool (PcdShadowPeimOnS3Boot))) (IsS3Boot && PcdGetBool (PcdShadowPeimOnS3Boot)))
) )
{ {
Status = EFI_UNSUPPORTED; Success = FALSE;
if (PcdGet64(PcdLoadModuleAtFixAddressEnable) != 0 && (Private->HobList.HandoffInformationTable->BootMode != BOOT_ON_S3_RESUME)) { if (PcdGet64(PcdLoadModuleAtFixAddressEnable) != 0 && (Private->HobList.HandoffInformationTable->BootMode != BOOT_ON_S3_RESUME)) {
Status = GetUefiImageFixLoadingAssignedAddress(ImageContext, Private, &LoadAddress); Status = GetUefiImageFixLoadingAssignedAddress(ImageContext, Private, &LoadAddress);
if (!EFI_ERROR (Status)){ if (!EFI_ERROR (Status)){
DynamicImageSize = UefiImageGetImageSize (ImageContext); DynamicImageSize = UefiImageGetImageSize (ImageContext);
if (LoadAddress != UefiImageGetPreferredAddress (ImageContext)) { Success = LoadAddress == UefiImageGetPreferredAddress (ImageContext);
Status = EFI_UNSUPPORTED;
if (!Success) {
DEBUG ((DEBUG_INFO|DEBUG_LOAD, "LOADING MODULE FIXED ERROR: Loading module at fixed address failed since relocs have been stripped.\n")); DEBUG ((DEBUG_INFO|DEBUG_LOAD, "LOADING MODULE FIXED ERROR: Loading module at fixed address failed since relocs have been stripped.\n"));
} }
} else { } else {
DEBUG ((EFI_D_INFO|EFI_D_LOAD, "LOADING MODULE FIXED ERROR: Failed to load module at fixed address. \n")); DEBUG ((EFI_D_INFO|EFI_D_LOAD, "LOADING MODULE FIXED ERROR: Failed to load module at fixed address. \n"));
} }
} }
if (EFI_ERROR (Status)) {
if (!Success) {
// //
// Allocate more buffer to avoid buffer overflow. // Allocate more buffer to avoid buffer overflow.
// //
Status = UefiImageLoaderGetDestinationSize (ImageContext, &DynamicImageSize); DynamicImageSize = UefiImageGetImageSize (ImageContext);
if (RETURN_ERROR (Status)) { DynamicImageAlignment = UefiImageGetSegmentAlignment (ImageContext);
return Status;
}
Status = PeiServicesAllocatePages ( LoadAddress = (UINTN)AllocateAlignedCodePages (
EfiBootServicesCode,
EFI_SIZE_TO_PAGES (DynamicImageSize), EFI_SIZE_TO_PAGES (DynamicImageSize),
&LoadAddress DynamicImageAlignment
); );
Success = LoadAddress != 0;
} }
if (!EFI_ERROR (Status)) { if (Success) {
LoadDynamically = TRUE; LoadDynamically = TRUE;
// //
// Load the image to our new buffer // Load the image to our new buffer

View File

@ -274,8 +274,9 @@ SmmLoadImage (
EFI_STATUS Status; EFI_STATUS Status;
EFI_STATUS SecurityStatus; EFI_STATUS SecurityStatus;
EFI_HANDLE DeviceHandle; EFI_HANDLE DeviceHandle;
EFI_PHYSICAL_ADDRESS DstBuffer; VOID *DstBuffer;
UINT32 DstBufferSize; UINT32 DstBufferSize;
UINT32 DstBufferAlignment;
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;
@ -425,10 +426,8 @@ SmmLoadImage (
return EFI_UNSUPPORTED; return EFI_UNSUPPORTED;
} }
Status = UefiImageLoaderGetDestinationSize (ImageContext, &DstBufferSize); DstBufferSize = UefiImageGetImageSize (ImageContext);
if (RETURN_ERROR (Status)) { DstBufferAlignment = UefiImageGetSegmentAlignment (ImageContext);
return Status;
}
// //
// 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
@ -444,45 +443,33 @@ SmmLoadImage (
// following statements is to bypass SmmFreePages // following statements is to bypass SmmFreePages
// //
PageCount = 0; PageCount = 0;
DstBuffer = LoadAddress; 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)DstBufferSize); PageCount = (UINTN)EFI_SIZE_TO_PAGES ((UINTN)DstBufferSize);
DstBuffer = (UINTN)(-1);
Status = SmmAllocatePages ( DstBuffer = AllocateAlignedCodePages (PageCount, DstBufferAlignment);
AllocateMaxAddress, if (DstBuffer == NULL) {
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;
} }
} }
} else { } else {
PageCount = (UINTN)EFI_SIZE_TO_PAGES ((UINTN)DstBufferSize); PageCount = (UINTN)EFI_SIZE_TO_PAGES ((UINTN)DstBufferSize);
DstBuffer = (UINTN)(-1);
Status = SmmAllocatePages ( DstBuffer = AllocateAlignedCodePages (PageCount, DstBufferAlignment);
AllocateMaxAddress, if (DstBuffer == NULL) {
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;
} }
} }
@ -491,7 +478,7 @@ SmmLoadImage (
// //
Status = UefiImageLoadImageForExecution ( Status = UefiImageLoadImageForExecution (
ImageContext, ImageContext,
(VOID *) (UINTN) DstBuffer, DstBuffer,
DstBufferSize, DstBufferSize,
NULL, NULL,
0 0
@ -501,17 +488,15 @@ SmmLoadImage (
gBS->FreePool (Buffer); gBS->FreePool (Buffer);
} }
SmmFreePages (DstBuffer, PageCount); FreeAlignedPages (DstBuffer, PageCount);
return Status; return Status;
} }
LoadAddress = UefiImageLoaderGetImageAddress (ImageContext);
// //
// Save Image EntryPoint in DriverEntry // Save Image EntryPoint in DriverEntry
// //
DriverEntry->ImageEntryPoint = UefiImageLoaderGetImageEntryPoint (ImageContext); DriverEntry->ImageEntryPoint = UefiImageLoaderGetImageEntryPoint (ImageContext);
DriverEntry->ImageBuffer = DstBuffer; DriverEntry->ImageBuffer = (UINTN)DstBuffer;
DriverEntry->NumberOfPage = PageCount; DriverEntry->NumberOfPage = PageCount;
// //
@ -523,7 +508,7 @@ SmmLoadImage (
gBS->FreePool (Buffer); gBS->FreePool (Buffer);
} }
SmmFreePages (DstBuffer, PageCount); FreeAlignedPages (DstBuffer, PageCount);
return Status; return Status;
} }
@ -551,13 +536,13 @@ SmmLoadImage (
gBS->FreePool (Buffer); gBS->FreePool (Buffer);
} }
SmmFreePages (DstBuffer, PageCount); FreeAlignedPages (DstBuffer, PageCount);
return Status; return Status;
} }
CopyMem (DriverEntry->LoadedImage->FilePath, FilePath, GetDevicePathSize (FilePath)); CopyMem (DriverEntry->LoadedImage->FilePath, FilePath, GetDevicePathSize (FilePath));
DriverEntry->LoadedImage->ImageBase = (VOID *)(UINTN)LoadAddress; DriverEntry->LoadedImage->ImageBase = DstBuffer;
DriverEntry->LoadedImage->ImageSize = UefiImageGetImageSize (ImageContext); DriverEntry->LoadedImage->ImageSize = UefiImageGetImageSize (ImageContext);
DriverEntry->LoadedImage->ImageCodeType = EfiRuntimeServicesCode; DriverEntry->LoadedImage->ImageCodeType = EfiRuntimeServicesCode;
DriverEntry->LoadedImage->ImageDataType = EfiRuntimeServicesData; DriverEntry->LoadedImage->ImageDataType = EfiRuntimeServicesData;
@ -572,13 +557,13 @@ SmmLoadImage (
} }
gBS->FreePool (DriverEntry->LoadedImage->FilePath); gBS->FreePool (DriverEntry->LoadedImage->FilePath);
SmmFreePages (DstBuffer, PageCount); FreeAlignedPages (DstBuffer, PageCount);
return Status; return Status;
} }
CopyMem (DriverEntry->SmmLoadedImage.FilePath, FilePath, GetDevicePathSize(FilePath)); CopyMem (DriverEntry->SmmLoadedImage.FilePath, FilePath, GetDevicePathSize(FilePath));
DriverEntry->SmmLoadedImage.ImageBase = (VOID *)(UINTN)LoadAddress; DriverEntry->SmmLoadedImage.ImageBase = DstBuffer;
DriverEntry->SmmLoadedImage.ImageSize = UefiImageGetImageSize (ImageContext); DriverEntry->SmmLoadedImage.ImageSize = UefiImageGetImageSize (ImageContext);
DriverEntry->SmmLoadedImage.ImageCodeType = EfiRuntimeServicesCode; DriverEntry->SmmLoadedImage.ImageCodeType = EfiRuntimeServicesCode;
DriverEntry->SmmLoadedImage.ImageDataType = EfiRuntimeServicesData; DriverEntry->SmmLoadedImage.ImageDataType = EfiRuntimeServicesData;
@ -629,7 +614,7 @@ SmmLoadImage (
DEBUG ((DEBUG_INFO | DEBUG_LOAD, DEBUG ((DEBUG_INFO | DEBUG_LOAD,
"Loading SMM driver at 0x%11p EntryPoint=0x%11p ", "Loading SMM driver at 0x%11p EntryPoint=0x%11p ",
(VOID *)(UINTN)LoadAddress, DstBuffer,
FUNCTION_ENTRY_POINT (UefiImageLoaderGetImageEntryPoint (ImageContext)))); FUNCTION_ENTRY_POINT (UefiImageLoaderGetImageEntryPoint (ImageContext))));
// //

View File

@ -977,6 +977,8 @@ ExecuteSmmCoreFromSmram (
VOID *SourceBuffer; VOID *SourceBuffer;
UINTN SourceSize; UINTN SourceSize;
UINT32 DestinationSize; UINT32 DestinationSize;
UINT32 DestinationAlignment;
UINT32 AlignSubtrahend;
UINTN PageCount; UINTN PageCount;
EFI_IMAGE_ENTRY_POINT EntryPoint; EFI_IMAGE_ENTRY_POINT EntryPoint;
EFI_PHYSICAL_ADDRESS LoadAddress; EFI_PHYSICAL_ADDRESS LoadAddress;
@ -1012,13 +1014,8 @@ ExecuteSmmCoreFromSmram (
return EFI_UNSUPPORTED; return EFI_UNSUPPORTED;
} }
Status = UefiImageLoaderGetDestinationSize ( DestinationSize = UefiImageGetImageSize (&gSmmCorePrivate->PiSmmCoreImageContext);
&gSmmCorePrivate->PiSmmCoreImageContext, DestinationAlignment = UefiImageGetSegmentAlignment (&gSmmCorePrivate->PiSmmCoreImageContext);
&DestinationSize
);
if (RETURN_ERROR (Status)) {
return Status;
}
// //
// 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.
@ -1043,7 +1040,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)DestinationSize); AlignSubtrahend = ALIGN_VALUE_SUBTRAHEND (
SmramRange->CpuStart + SmramRange->PhysicalSize,
DestinationAlignment
);
PageCount = (UINTN)EFI_SIZE_TO_PAGES ((UINTN)DestinationSize) + (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));
@ -1064,7 +1065,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)DestinationSize); AlignSubtrahend = ALIGN_VALUE_SUBTRAHEND (
SmramRange->CpuStart + SmramRange->PhysicalSize,
DestinationAlignment
);
PageCount = (UINTN)EFI_SIZE_TO_PAGES ((UINTN)DestinationSize) + (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));

View File

@ -59,6 +59,7 @@
CpuExceptionHandlerLib CpuExceptionHandlerLib
DevicePathLib DevicePathLib
DxeServicesTableLib DxeServicesTableLib
MemoryAllocationLib
[Guids] [Guids]
gEfiBootScriptExecutorVariableGuid ## PRODUCES ## UNDEFINED # SaveLockBox gEfiBootScriptExecutorVariableGuid ## PRODUCES ## UNDEFINED # SaveLockBox

View File

@ -12,8 +12,6 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
**/ **/
#include "ScriptExecute.h" #include "ScriptExecute.h"
#include "Library/UefiImageLib.h"
#include "Uefi/UefiBaseType.h"
EFI_GUID mBootScriptExecutorImageGuid = { EFI_GUID mBootScriptExecutorImageGuid = {
0x9a8d3433, 0x9fe8, 0x42b6, { 0x87, 0xb, 0x1e, 0x31, 0xc8, 0x4e, 0xbe, 0x3b } 0x9a8d3433, 0x9fe8, 0x42b6, { 0x87, 0xb, 0x1e, 0x31, 0xc8, 0x4e, 0xbe, 0x3b }
@ -275,8 +273,9 @@ ReadyToLockEventNotify (
UINTN BufferSize; UINTN BufferSize;
EFI_HANDLE NewImageHandle; EFI_HANDLE NewImageHandle;
UINTN Pages; UINTN Pages;
EFI_PHYSICAL_ADDRESS FfsBuffer;
UEFI_IMAGE_LOADER_IMAGE_CONTEXT ImageContext; UEFI_IMAGE_LOADER_IMAGE_CONTEXT ImageContext;
UINT32 ImageSize;
UINT32 ImageAlignment;
EFI_GCD_MEMORY_SPACE_DESCRIPTOR MemDesc; EFI_GCD_MEMORY_SPACE_DESCRIPTOR MemDesc;
EFI_PHYSICAL_ADDRESS LoadAddress; EFI_PHYSICAL_ADDRESS LoadAddress;
@ -313,40 +312,37 @@ ReadyToLockEventNotify (
// //
Status = UefiImageInitializeContext (&ImageContext, Buffer, (UINT32) BufferSize); Status = UefiImageInitializeContext (&ImageContext, Buffer, (UINT32) BufferSize);
ASSERT_EFI_ERROR (Status); ASSERT_EFI_ERROR (Status);
UINT32 Size; ImageSize = UefiImageGetImageSize (&ImageContext);
Status = UefiImageLoaderGetDestinationSize (&ImageContext, &Size); ImageAlignment = UefiImageGetSegmentAlignment (&ImageContext);
ASSERT_EFI_ERROR (Status); Pages = EFI_SIZE_TO_PAGES (ImageSize);
Pages = EFI_SIZE_TO_PAGES (Size); LoadAddress = 0xFFFFFFFF;
FfsBuffer = 0xFFFFFFFF; Status = AllocateAlignedPagesEx (
Status = gBS->AllocatePages (
AllocateMaxAddress, AllocateMaxAddress,
EfiReservedMemoryType, EfiReservedMemoryType,
Pages, Pages,
&FfsBuffer ImageAlignment,
&LoadAddress
); );
ASSERT_EFI_ERROR (Status); ASSERT_EFI_ERROR (Status);
// //
// Make sure that the buffer can be used to store code. // Make sure that the buffer can be used to store code.
// //
Status = gDS->GetMemorySpaceDescriptor (FfsBuffer, &MemDesc); Status = gDS->GetMemorySpaceDescriptor (LoadAddress, &MemDesc);
if (!EFI_ERROR (Status) && ((MemDesc.Attributes & EFI_MEMORY_XP) != 0)) { if (!EFI_ERROR (Status) && ((MemDesc.Attributes & EFI_MEMORY_XP) != 0)) {
gDS->SetMemorySpaceAttributes ( gDS->SetMemorySpaceAttributes (
FfsBuffer, LoadAddress,
EFI_PAGES_TO_SIZE (Pages), EFI_PAGES_TO_SIZE (Pages),
MemDesc.Attributes & (~EFI_MEMORY_XP) MemDesc.Attributes & (~EFI_MEMORY_XP)
); );
} }
LoadAddress = (PHYSICAL_ADDRESS)(UINTN)FfsBuffer;
// //
// Load the image to our new buffer // Load the image to our new buffer
// //
Status = UefiImageLoadImageForExecution (&ImageContext, (VOID *)(UINTN)LoadAddress, Size, NULL, 0); Status = UefiImageLoadImageForExecution (&ImageContext, (VOID *)(UINTN)LoadAddress, ImageSize, NULL, 0);
ASSERT_EFI_ERROR (Status); ASSERT_EFI_ERROR (Status);
LoadAddress = UefiImageLoaderGetImageAddress (&ImageContext);
// //
// Free the buffer allocated by ReadSection since the image has been relocated in the new buffer // Free the buffer allocated by ReadSection since the image has been relocated in the new buffer
// //

View File

@ -34,6 +34,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#include <Library/CpuExceptionHandlerLib.h> #include <Library/CpuExceptionHandlerLib.h>
#include <Library/DevicePathLib.h> #include <Library/DevicePathLib.h>
#include <Library/DxeServicesTableLib.h> #include <Library/DxeServicesTableLib.h>
#include <Library/MemoryAllocationLibEx.h>
#include <Guid/AcpiS3Context.h> #include <Guid/AcpiS3Context.h>
#include <Guid/BootScriptExecutorVariable.h> #include <Guid/BootScriptExecutorVariable.h>

View File

@ -139,26 +139,6 @@ UefiImageHashImageDefault (
IN UEFI_IMAGE_LOADER_HASH_UPDATE HashUpdate IN UEFI_IMAGE_LOADER_HASH_UPDATE HashUpdate
); );
/**
Calculate the size, in Bytes, required for the destination Image memory space
to load into with UefiImageLoadImage(). This potentially includes additional
space to internally align the Image within the destination buffer.
@param[in,out] Context The context describing the Image. Must have been
initialised by UefiImageInitializeContext().
@param[out] Size On output, the size, in Bytes, required to allocate
the Image destination buffer.
@retval RETURN_SUCCESS The Image destination size has been calculated
successfully.
@retval other The Image destination cannot be calculated.
**/
RETURN_STATUS
UefiImageLoaderGetDestinationSize (
IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context,
OUT UINT32 *Size
);
/** /**
Load the Image into the destination memory space. Load the Image into the destination memory space.
@ -168,7 +148,7 @@ UefiImageLoaderGetDestinationSize (
from page memory. from page memory.
@param[in] DestinationSize The size, in Bytes, of Destination. Must be at @param[in] DestinationSize The size, in Bytes, of Destination. Must be at
least as large as the size returned by least as large as the size returned by
UefiImageLoaderGetDestinationSize(). UefiImageGetImageSize().
@retval RETURN_SUCCESS The Image was loaded successfully. @retval RETURN_SUCCESS The Image was loaded successfully.
@retval other The Image could not be loaded successfully. @retval other The Image could not be loaded successfully.
@ -275,7 +255,7 @@ UefiImageRelocateImage (
allocated from page memory. allocated from page memory.
@param[in] DestinationSize The size, in Bytes, of Destination. Must be @param[in] DestinationSize The size, in Bytes, of Destination. Must be
at least as large as the size returned by at least as large as the size returned by
UefiImageLoaderGetDestinationSize(). UefiImageGetImageSize().
@param[out] RuntimeContext If not NULL, on output, a buffer @param[out] RuntimeContext If not NULL, on output, a buffer
bookkeeping data required for Image runtime bookkeeping data required for Image runtime
relocation. relocation.

View File

@ -12,7 +12,6 @@
**/ **/
#include <Base.h> #include <Base.h>
#include <Uefi/UefiBaseType.h>
#include <IndustryStandard/PeImage2.h> #include <IndustryStandard/PeImage2.h>
@ -107,42 +106,15 @@ PeCoffLoadImage (
IN UINT32 DestinationSize IN UINT32 DestinationSize
) )
{ {
UINT32 AlignOffset;
UINT32 AlignedSize;
UINT32 LoadedHeaderSize; UINT32 LoadedHeaderSize;
CONST EFI_IMAGE_SECTION_HEADER *Sections; CONST EFI_IMAGE_SECTION_HEADER *Sections;
UINTN DestAddress;
ASSERT (Context != NULL); ASSERT (Context != NULL);
ASSERT (Destination != NULL); ASSERT (Destination != NULL);
ASSERT (Context->SectionAlignment <= DestinationSize); ASSERT (ADDRESS_IS_ALIGNED (Destination, Context->SectionAlignment));
// ASSERT (Context->SizeOfImage <= DestinationSize);
// Sufficiently align the Image data in memory.
//
if (Context->SectionAlignment <= EFI_PAGE_SIZE) {
//
// The caller is required to allocate page memory, hence we have at least
// 4 KB alignment guaranteed.
//
AlignOffset = 0;
AlignedSize = DestinationSize;
Context->ImageBuffer = Destination; Context->ImageBuffer = Destination;
} else {
//
// Images aligned stricter than by the UEFI page size have an increased
// destination size to internally align the Image.
//
DestAddress = (UINTN) Destination;
AlignOffset = ALIGN_VALUE_ADDEND ((UINT32) DestAddress, Context->SectionAlignment);
AlignedSize = DestinationSize - AlignOffset;
Context->ImageBuffer = (CHAR8 *) Destination + AlignOffset;
ASSERT (Context->SizeOfImage <= AlignedSize);
ZeroMem (Destination, AlignOffset);
}
ASSERT (AlignedSize >= Context->SizeOfImage);
// //
// Load the Image Headers into the memory space, if the policy demands it. // Load the Image Headers into the memory space, if the policy demands it.
// //
@ -158,7 +130,7 @@ PeCoffLoadImage (
// //
// Load all Image sections into the memory space. // Load all Image sections into the memory space.
// //
InternalLoadSections (Context, LoadedHeaderSize, AlignedSize); InternalLoadSections (Context, LoadedHeaderSize, DestinationSize);
return RETURN_SUCCESS; return RETURN_SUCCESS;
} }

View File

@ -32,42 +32,6 @@ UefiImageInitializeContext (
return UefiImageInitializeContextPostHash (Context); return UefiImageInitializeContextPostHash (Context);
} }
RETURN_STATUS
UefiImageLoaderGetDestinationSize (
IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context,
OUT UINT32 *Size
)
{
BOOLEAN Overflow;
UINT32 AlignedSize;
UINT32 SegmentAlignment;
ASSERT (Context != NULL);
ASSERT (Size != NULL);
AlignedSize = UefiImageGetImageSize (Context);
SegmentAlignment = UefiImageGetSegmentAlignment (Context);
//
// If the Image segment alignment is larger than the UEFI page size,
// sufficient alignment cannot be guaranteed by the allocater. Allodate an
// additional Image page to be able to manually align within the buffer.
//
if (SegmentAlignment > EFI_PAGE_SIZE) {
Overflow = BaseOverflowAddU32 (
AlignedSize,
SegmentAlignment - EFI_PAGE_SIZE,
&AlignedSize
);
if (Overflow) {
return RETURN_UNSUPPORTED;
}
}
*Size = AlignedSize;
return RETURN_SUCCESS;
}
UINTN UINTN
UefiImageLoaderGetImageEntryPoint ( UefiImageLoaderGetImageEntryPoint (
IN CONST UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context IN CONST UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context

View File

@ -272,12 +272,11 @@ MmLoadImage (
IN OUT EFI_MM_DRIVER_ENTRY *DriverEntry IN OUT EFI_MM_DRIVER_ENTRY *DriverEntry
) )
{ {
UINT32 DestinationSize; UINT32 ImageSize;
UINTN ImageSize; UINT32 ImageAlignment;
UINTN PageCount; UINTN PageCount;
EFI_STATUS Status; EFI_STATUS Status;
EFI_PHYSICAL_ADDRESS DstBuffer; VOID *DstBuffer;
UINTN ImageBase;
UEFI_IMAGE_LOADER_IMAGE_CONTEXT ImageContext; UEFI_IMAGE_LOADER_IMAGE_CONTEXT ImageContext;
DEBUG ((DEBUG_INFO, "MmLoadImage - %g\n", &DriverEntry->FileName)); DEBUG ((DEBUG_INFO, "MmLoadImage - %g\n", &DriverEntry->FileName));
@ -292,45 +291,30 @@ MmLoadImage (
return Status; return Status;
} }
Status = UefiImageLoaderGetDestinationSize (&ImageContext, &DestinationSize); ImageSize = UefiImageGetImageSize (&ImageContext, &ImageSize);
if (RETURN_ERROR (Status)) { ImageAlignment = UefiImageGetSegmentAlignment (&ImageContext);
return Status;
}
PageCount = (UINTN)EFI_SIZE_TO_PAGES ((UINTN) DestinationSize); PageCount = (UINTN)EFI_SIZE_TO_PAGES ((UINTN) ImageSize);
DstBuffer = (UINTN)(-1);
Status = MmAllocatePages ( DstBuffer = AllocateAlignedCodePages (PageCount, ImageAlignment);
AllocateMaxAddress, if (DstBuffer == NULL) {
EfiRuntimeServicesCode, return EFI_OUT_OF_RESOURCES;
PageCount,
&DstBuffer
);
if (EFI_ERROR (Status)) {
return Status;
} }
// //
// Load the image to our new buffer // Load the image to our new buffer
// //
Status = UefiImageLoadImageForExecution (&ImageContext, (VOID *) (UINTN) DstBuffer, DestinationSize, NULL, 0); Status = UefiImageLoadImageForExecution (&ImageContext, (VOID *) (UINTN) DstBuffer, ImageSize, NULL, 0);
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {
MmFreePages (DstBuffer, PageCount); FreeAlignedPages (DstBuffer, PageCount);
return Status; return Status;
} }
ImageBase = UefiImageLoaderGetImageAddress (&ImageContext);
//
// Flush the instruction cache so the image data are written before we execute it
//
ImageSize = UefiImageGetImageSize (&ImageContext);
// //
// Save Image EntryPoint in DriverEntry // Save Image EntryPoint in DriverEntry
// //
DriverEntry->ImageEntryPoint = UefiImageLoaderGetImageEntryPoint (&ImageContext); DriverEntry->ImageEntryPoint = UefiImageLoaderGetImageEntryPoint (&ImageContext);
DriverEntry->ImageBuffer = DstBuffer; DriverEntry->ImageBuffer = (UINTN)DstBuffer;
DriverEntry->NumberOfPage = PageCount; DriverEntry->NumberOfPage = PageCount;
if (mEfiSystemTable != NULL) { if (mEfiSystemTable != NULL) {
@ -340,7 +324,7 @@ MmLoadImage (
(VOID **)&DriverEntry->LoadedImage (VOID **)&DriverEntry->LoadedImage
); );
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {
MmFreePages (DstBuffer, PageCount); FreeAlignedPages (DstBuffer, PageCount);
return Status; return Status;
} }
@ -355,7 +339,7 @@ MmLoadImage (
DriverEntry->LoadedImage->DeviceHandle = NULL; DriverEntry->LoadedImage->DeviceHandle = NULL;
DriverEntry->LoadedImage->FilePath = NULL; DriverEntry->LoadedImage->FilePath = NULL;
DriverEntry->LoadedImage->ImageBase = (VOID *) ImageBase; DriverEntry->LoadedImage->ImageBase = DstBuffer;
DriverEntry->LoadedImage->ImageSize = ImageSize; DriverEntry->LoadedImage->ImageSize = ImageSize;
DriverEntry->LoadedImage->ImageCodeType = EfiRuntimeServicesCode; DriverEntry->LoadedImage->ImageCodeType = EfiRuntimeServicesCode;
DriverEntry->LoadedImage->ImageDataType = EfiRuntimeServicesData; DriverEntry->LoadedImage->ImageDataType = EfiRuntimeServicesData;

View File

@ -31,6 +31,7 @@ LoadUefiImage (
RETURN_STATUS Status; RETURN_STATUS Status;
UEFI_IMAGE_LOADER_IMAGE_CONTEXT ImageContext; UEFI_IMAGE_LOADER_IMAGE_CONTEXT ImageContext;
UINT32 BufferSize; UINT32 BufferSize;
UINT32 BufferAlignment;
VOID *Buffer; VOID *Buffer;
Status = UefiImageInitializeContext (&ImageContext, UefiImage, UefiImageSize); Status = UefiImageInitializeContext (&ImageContext, UefiImage, UefiImageSize);
@ -39,16 +40,13 @@ LoadUefiImage (
return Status; return Status;
} }
Status = UefiImageLoaderGetDestinationSize (&ImageContext, &BufferSize); BufferSize = UefiImageGetImageSize (&ImageContext);
if (EFI_ERROR (Status)) { BufferAlignment = UefiImageGetSegmentAlignment (&ImageContext);
ASSERT_EFI_ERROR (Status);
return Status;
}
// //
// Allocate Memory for the image // Allocate Memory for the image
// //
Buffer = AllocateCodePages (EFI_SIZE_TO_PAGES (BufferSize)); Buffer = AllocateAlignedCodePages (EFI_SIZE_TO_PAGES (BufferSize), BufferAlignment);
if (Buffer == NULL) { if (Buffer == NULL) {
return EFI_OUT_OF_RESOURCES; return EFI_OUT_OF_RESOURCES;
} }
@ -68,8 +66,8 @@ LoadUefiImage (
return Status; return Status;
} }
*ImageAddress = UefiImageLoaderGetImageAddress (&ImageContext); *ImageAddress = (UINTN)Buffer;
*ImageSize = UefiImageGetImageSize (&ImageContext); *ImageSize = BufferSize;
*EntryPoint = UefiImageLoaderGetImageEntryPoint (&ImageContext); *EntryPoint = UefiImageLoaderGetImageEntryPoint (&ImageContext);
return EFI_SUCCESS; return EFI_SUCCESS;