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

View File

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

View File

@ -16,6 +16,8 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#include <Library/DxeServicesLib.h>
#include <Library/CacheMaintenanceLib.h>
#include <Library/UefiLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/MemoryAllocationLibEx.h>
/**
Relocate this image under 4G memory.
@ -37,10 +39,11 @@ RelocateImageUnder4GIfNeeded (
UINT8 *Buffer;
UINTN BufferSize;
EFI_HANDLE NewImageHandle;
UINT32 DestinationSize;
UINT32 ImageSize;
UINT32 ImageAlignment;
UINTN Pages;
EFI_PHYSICAL_ADDRESS FfsBuffer;
UEFI_IMAGE_LOADER_IMAGE_CONTEXT ImageContext;
UEFI_IMAGE_LOADER_IMAGE_CONTEXT ImageContext;
VOID *Interface;
//
@ -89,17 +92,18 @@ RelocateImageUnder4GIfNeeded (
//
Status = UefiImageInitializeContext (&ImageContext, Buffer, (UINT32) BufferSize);
ASSERT_EFI_ERROR (Status);
Status = UefiImageLoaderGetDestinationSize (&ImageContext, &DestinationSize);
ASSERT_EFI_ERROR (Status);
Pages = EFI_SIZE_TO_PAGES (DestinationSize);
ImageSize = UefiImageGetImageSize (&ImageContext);
ImageAlignment = UefiImageGetSegmentAlignment (&ImageContext);
Pages = EFI_SIZE_TO_PAGES (ImageSize);
FfsBuffer = 0xFFFFFFFF;
Status = gBS->AllocatePages (
AllocateMaxAddress,
EfiBootServicesCode,
Pages,
&FfsBuffer
);
Status = AllocateAlignedPagesEx (
AllocateMaxAddress,
EfiBootServicesCode,
Pages,
ImageAlignment,
&FfsBuffer
);
ASSERT_EFI_ERROR (Status);
//
// Load and relocate the image to our new buffer
@ -107,7 +111,7 @@ RelocateImageUnder4GIfNeeded (
Status = UefiImageLoadImageForExecution (
&ImageContext,
(VOID *) (UINTN) FfsBuffer,
DestinationSize,
ImageSize,
NULL,
0
);
@ -118,11 +122,11 @@ RelocateImageUnder4GIfNeeded (
//
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);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "Error: Image at 0x%08x start failed: %r\n", UefiImageLoaderGetImageAddress (&ImageContext), Status));
gBS->FreePages (FfsBuffer, Pages);
DEBUG ((DEBUG_ERROR, "Error: Image at 0x%08llx start failed: %r\n", FfsBuffer, Status));
FreeAlignedPages ((VOID *)(UINTN)FfsBuffer, Pages);
}
//

View File

@ -77,6 +77,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#include <Library/UefiImageExtraActionLib.h>
#include <Library/PcdLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/MemoryAllocationLibEx.h>
#include <Library/DevicePathLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/ReportStatusCodeLib.h>

View File

@ -8,8 +8,6 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#include "DxeMain.h"
#include "Image.h"
#include "Library/UefiImageLib.h"
#include "Uefi/UefiBaseType.h"
//
// Module Globals
@ -514,11 +512,11 @@ CoreLoadPeImage (
EFI_STATUS Status;
BOOLEAN DstBufAlocated;
UINT32 Size;
UINT32 Alignment;
EFI_MEMORY_TYPE ImageCodeMemoryType;
EFI_MEMORY_TYPE ImageDataMemoryType;
UEFI_IMAGE_LOADER_RUNTIME_CONTEXT *RelocationData;
EFI_PHYSICAL_ADDRESS BufferAddress;
UINTN LoadAddress;
UINT32 RelocDataSize;
RelocationData = NULL;
@ -560,10 +558,8 @@ CoreLoadPeImage (
return EFI_UNSUPPORTED;
}
Status = UefiImageLoaderGetDestinationSize (ImageContext, &Size);
if (RETURN_ERROR (Status)) {
return Status;
}
Size = UefiImageGetImageSize (ImageContext);
Alignment = UefiImageGetSegmentAlignment (ImageContext);
BufferAddress = 0;
//
@ -606,7 +602,7 @@ CoreLoadPeImage (
if (EFI_ERROR (Status)) {
BufferAddress = UefiImageGetPreferredAddress (ImageContext);
if ((BufferAddress >= 0x100000) || UefiImageGetRelocsStripped (ImageContext)) {
Status = CoreAllocatePages (
Status = AllocatePagesEx (
AllocateAddress,
ImageCodeMemoryType,
Image->NumberOfPages,
@ -615,10 +611,11 @@ CoreLoadPeImage (
}
if (EFI_ERROR (Status) && !UefiImageGetRelocsStripped (ImageContext)) {
Status = CoreAllocatePages (
Status = AllocateAlignedPagesEx (
AllocateAnyPages,
ImageCodeMemoryType,
Image->NumberOfPages,
Alignment,
&BufferAddress
);
}
@ -703,8 +700,6 @@ CoreLoadPeImage (
goto Done;
}
LoadAddress = UefiImageLoaderGetImageAddress (ImageContext);
//
// 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
//
Image->Type = UefiImageGetSubsystem (ImageContext);
Image->Info.ImageBase = (VOID *)(UINTN)LoadAddress;
Image->Info.ImageBase = (VOID *)(UINTN)BufferAddress;
Image->Info.ImageSize = UefiImageGetImageSize (ImageContext);
Image->Info.ImageCodeType = ImageCodeMemoryType;
Image->Info.ImageDataType = ImageDataMemoryType;
@ -756,7 +751,7 @@ CoreLoadPeImage (
ASSERT_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,
"Loading driver at 0x%11p EntryPoint=0x%11p \n",
(VOID *)(UINTN)LoadAddress,
(VOID *)(UINTN)BufferAddress,
FUNCTION_ENTRY_POINT (UefiImageLoaderGetImageEntryPoint (ImageContext))));
Status = UefiImageGetModuleNameFromSymbolsPath (
@ -798,7 +793,7 @@ Done:
if (DstBufAlocated) {
ZeroMem ((VOID *)(UINTN)BufferAddress, EFI_PAGES_TO_SIZE (Image->NumberOfPages));
CoreFreePages (BufferAddress, Image->NumberOfPages);
FreeAlignedPages ((VOID *)(UINTN)BufferAddress, Image->NumberOfPages);
Image->ImageBasePage = 0;
}

View File

@ -169,8 +169,10 @@ LoadAndRelocateUefiImage (
)
{
EFI_STATUS Status;
BOOLEAN Success;
PEI_CORE_INSTANCE *Private;
UINT32 DynamicImageSize;
UINT32 DynamicImageAlignment;
BOOLEAN IsXipImage;
EFI_STATUS ReturnStatus;
BOOLEAN IsS3Boot;
@ -261,38 +263,38 @@ LoadAndRelocateUefiImage (
(IsS3Boot && PcdGetBool (PcdShadowPeimOnS3Boot)))
)
{
Status = EFI_UNSUPPORTED;
Success = FALSE;
if (PcdGet64(PcdLoadModuleAtFixAddressEnable) != 0 && (Private->HobList.HandoffInformationTable->BootMode != BOOT_ON_S3_RESUME)) {
Status = GetUefiImageFixLoadingAssignedAddress(ImageContext, Private, &LoadAddress);
if (!EFI_ERROR (Status)){
DynamicImageSize = UefiImageGetImageSize (ImageContext);
if (LoadAddress != UefiImageGetPreferredAddress (ImageContext)) {
Status = EFI_UNSUPPORTED;
Success = LoadAddress == 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 (EFI_ERROR (Status)) {
if (!Success) {
//
// Allocate more buffer to avoid buffer overflow.
//
Status = UefiImageLoaderGetDestinationSize (ImageContext, &DynamicImageSize);
if (RETURN_ERROR (Status)) {
return Status;
}
DynamicImageSize = UefiImageGetImageSize (ImageContext);
DynamicImageAlignment = UefiImageGetSegmentAlignment (ImageContext);
Status = PeiServicesAllocatePages (
EfiBootServicesCode,
EFI_SIZE_TO_PAGES (DynamicImageSize),
&LoadAddress
);
LoadAddress = (UINTN)AllocateAlignedCodePages (
EFI_SIZE_TO_PAGES (DynamicImageSize),
DynamicImageAlignment
);
Success = LoadAddress != 0;
}
if (!EFI_ERROR (Status)) {
if (Success) {
LoadDynamically = TRUE;
//
// Load the image to our new buffer

View File

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

View File

@ -977,6 +977,8 @@ ExecuteSmmCoreFromSmram (
VOID *SourceBuffer;
UINTN SourceSize;
UINT32 DestinationSize;
UINT32 DestinationAlignment;
UINT32 AlignSubtrahend;
UINTN PageCount;
EFI_IMAGE_ENTRY_POINT EntryPoint;
EFI_PHYSICAL_ADDRESS LoadAddress;
@ -1012,13 +1014,8 @@ ExecuteSmmCoreFromSmram (
return EFI_UNSUPPORTED;
}
Status = UefiImageLoaderGetDestinationSize (
&gSmmCorePrivate->PiSmmCoreImageContext,
&DestinationSize
);
if (RETURN_ERROR (Status)) {
return Status;
}
DestinationSize = UefiImageGetImageSize (&gSmmCorePrivate->PiSmmCoreImageContext);
DestinationAlignment = UefiImageGetSegmentAlignment (&gSmmCorePrivate->PiSmmCoreImageContext);
//
// if Loading module at Fixed Address feature is enabled, the SMM core driver will be loaded to
// the address assigned by build tool.
@ -1043,7 +1040,11 @@ ExecuteSmmCoreFromSmram (
// Allocate memory for the image being loaded from the EFI_SRAM_DESCRIPTOR
// 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_PAGES_TO_SIZE (PageCount));
@ -1064,7 +1065,11 @@ ExecuteSmmCoreFromSmram (
// Allocate memory for the image being loaded from the EFI_SRAM_DESCRIPTOR
// 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_PAGES_TO_SIZE (PageCount));

View File

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

View File

@ -12,8 +12,6 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include "ScriptExecute.h"
#include "Library/UefiImageLib.h"
#include "Uefi/UefiBaseType.h"
EFI_GUID mBootScriptExecutorImageGuid = {
0x9a8d3433, 0x9fe8, 0x42b6, { 0x87, 0xb, 0x1e, 0x31, 0xc8, 0x4e, 0xbe, 0x3b }
@ -275,8 +273,9 @@ ReadyToLockEventNotify (
UINTN BufferSize;
EFI_HANDLE NewImageHandle;
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_PHYSICAL_ADDRESS LoadAddress;
@ -313,40 +312,37 @@ ReadyToLockEventNotify (
//
Status = UefiImageInitializeContext (&ImageContext, Buffer, (UINT32) BufferSize);
ASSERT_EFI_ERROR (Status);
UINT32 Size;
Status = UefiImageLoaderGetDestinationSize (&ImageContext, &Size);
ASSERT_EFI_ERROR (Status);
Pages = EFI_SIZE_TO_PAGES (Size);
FfsBuffer = 0xFFFFFFFF;
Status = gBS->AllocatePages (
AllocateMaxAddress,
EfiReservedMemoryType,
Pages,
&FfsBuffer
);
ImageSize = UefiImageGetImageSize (&ImageContext);
ImageAlignment = UefiImageGetSegmentAlignment (&ImageContext);
Pages = EFI_SIZE_TO_PAGES (ImageSize);
LoadAddress = 0xFFFFFFFF;
Status = AllocateAlignedPagesEx (
AllocateMaxAddress,
EfiReservedMemoryType,
Pages,
ImageAlignment,
&LoadAddress
);
ASSERT_EFI_ERROR (Status);
//
// 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)) {
gDS->SetMemorySpaceAttributes (
FfsBuffer,
LoadAddress,
EFI_PAGES_TO_SIZE (Pages),
MemDesc.Attributes & (~EFI_MEMORY_XP)
);
}
LoadAddress = (PHYSICAL_ADDRESS)(UINTN)FfsBuffer;
//
// 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);
LoadAddress = UefiImageLoaderGetImageAddress (&ImageContext);
//
// 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/DevicePathLib.h>
#include <Library/DxeServicesTableLib.h>
#include <Library/MemoryAllocationLibEx.h>
#include <Guid/AcpiS3Context.h>
#include <Guid/BootScriptExecutorVariable.h>

View File

@ -139,26 +139,6 @@ UefiImageHashImageDefault (
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.
@ -168,7 +148,7 @@ UefiImageLoaderGetDestinationSize (
from page memory.
@param[in] DestinationSize The size, in Bytes, of Destination. Must be at
least as large as the size returned by
UefiImageLoaderGetDestinationSize().
UefiImageGetImageSize().
@retval RETURN_SUCCESS The Image was loaded successfully.
@retval other The Image could not be loaded successfully.
@ -275,7 +255,7 @@ UefiImageRelocateImage (
allocated from page memory.
@param[in] DestinationSize The size, in Bytes, of Destination. Must be
at least as large as the size returned by
UefiImageLoaderGetDestinationSize().
UefiImageGetImageSize().
@param[out] RuntimeContext If not NULL, on output, a buffer
bookkeeping data required for Image runtime
relocation.

View File

@ -12,7 +12,6 @@
**/
#include <Base.h>
#include <Uefi/UefiBaseType.h>
#include <IndustryStandard/PeImage2.h>
@ -107,42 +106,15 @@ PeCoffLoadImage (
IN UINT32 DestinationSize
)
{
UINT32 AlignOffset;
UINT32 AlignedSize;
UINT32 LoadedHeaderSize;
CONST EFI_IMAGE_SECTION_HEADER *Sections;
UINTN DestAddress;
ASSERT (Context != NULL);
ASSERT (Destination != NULL);
ASSERT (Context->SectionAlignment <= 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;
} 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 (ADDRESS_IS_ALIGNED (Destination, Context->SectionAlignment));
ASSERT (Context->SizeOfImage <= DestinationSize);
ASSERT (Context->SizeOfImage <= AlignedSize);
ZeroMem (Destination, AlignOffset);
}
ASSERT (AlignedSize >= Context->SizeOfImage);
Context->ImageBuffer = Destination;
//
// 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.
//
InternalLoadSections (Context, LoadedHeaderSize, AlignedSize);
InternalLoadSections (Context, LoadedHeaderSize, DestinationSize);
return RETURN_SUCCESS;
}

View File

@ -32,42 +32,6 @@ UefiImageInitializeContext (
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
UefiImageLoaderGetImageEntryPoint (
IN CONST UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context

View File

@ -272,12 +272,11 @@ MmLoadImage (
IN OUT EFI_MM_DRIVER_ENTRY *DriverEntry
)
{
UINT32 DestinationSize;
UINTN ImageSize;
UINT32 ImageSize;
UINT32 ImageAlignment;
UINTN PageCount;
EFI_STATUS Status;
EFI_PHYSICAL_ADDRESS DstBuffer;
UINTN ImageBase;
VOID *DstBuffer;
UEFI_IMAGE_LOADER_IMAGE_CONTEXT ImageContext;
DEBUG ((DEBUG_INFO, "MmLoadImage - %g\n", &DriverEntry->FileName));
@ -292,45 +291,30 @@ MmLoadImage (
return Status;
}
Status = UefiImageLoaderGetDestinationSize (&ImageContext, &DestinationSize);
if (RETURN_ERROR (Status)) {
return Status;
}
ImageSize = UefiImageGetImageSize (&ImageContext, &ImageSize);
ImageAlignment = UefiImageGetSegmentAlignment (&ImageContext);
PageCount = (UINTN)EFI_SIZE_TO_PAGES ((UINTN) DestinationSize);
DstBuffer = (UINTN)(-1);
PageCount = (UINTN)EFI_SIZE_TO_PAGES ((UINTN) ImageSize);
Status = MmAllocatePages (
AllocateMaxAddress,
EfiRuntimeServicesCode,
PageCount,
&DstBuffer
);
if (EFI_ERROR (Status)) {
return Status;
DstBuffer = AllocateAlignedCodePages (PageCount, ImageAlignment);
if (DstBuffer == NULL) {
return EFI_OUT_OF_RESOURCES;
}
//
// 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)) {
MmFreePages (DstBuffer, PageCount);
FreeAlignedPages (DstBuffer, PageCount);
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
//
DriverEntry->ImageEntryPoint = UefiImageLoaderGetImageEntryPoint (&ImageContext);
DriverEntry->ImageBuffer = DstBuffer;
DriverEntry->ImageEntryPoint = UefiImageLoaderGetImageEntryPoint (&ImageContext);
DriverEntry->ImageBuffer = (UINTN)DstBuffer;
DriverEntry->NumberOfPage = PageCount;
if (mEfiSystemTable != NULL) {
@ -340,7 +324,7 @@ MmLoadImage (
(VOID **)&DriverEntry->LoadedImage
);
if (EFI_ERROR (Status)) {
MmFreePages (DstBuffer, PageCount);
FreeAlignedPages (DstBuffer, PageCount);
return Status;
}
@ -355,7 +339,7 @@ MmLoadImage (
DriverEntry->LoadedImage->DeviceHandle = NULL;
DriverEntry->LoadedImage->FilePath = NULL;
DriverEntry->LoadedImage->ImageBase = (VOID *) ImageBase;
DriverEntry->LoadedImage->ImageBase = DstBuffer;
DriverEntry->LoadedImage->ImageSize = ImageSize;
DriverEntry->LoadedImage->ImageCodeType = EfiRuntimeServicesCode;
DriverEntry->LoadedImage->ImageDataType = EfiRuntimeServicesData;

View File

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