Image.c revision 4fd606d1f5abe38e1f42c38de1d2e895166bd0f4
c892d0dfeda5c022104813bf59275f840923551bCraig McDonnell Core image handling services to load and unload PeImage.
c892d0dfeda5c022104813bf59275f840923551bCraig McDonnellCopyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>
c892d0dfeda5c022104813bf59275f840923551bCraig McDonnellThis program and the accompanying materials
c892d0dfeda5c022104813bf59275f840923551bCraig McDonnellare licensed and made available under the terms and conditions of the BSD License
c892d0dfeda5c022104813bf59275f840923551bCraig McDonnellwhich accompanies this distribution. The full text of the license may be found at
c892d0dfeda5c022104813bf59275f840923551bCraig McDonnellhttp://opensource.org/licenses/bsd-license.php
c892d0dfeda5c022104813bf59275f840923551bCraig McDonnellTHE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
c892d0dfeda5c022104813bf59275f840923551bCraig McDonnellWITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
c892d0dfeda5c022104813bf59275f840923551bCraig McDonnell// Module Globals
c892d0dfeda5c022104813bf59275f840923551bCraig McDonnellLOADED_IMAGE_PRIVATE_DATA *mCurrentImage = NULL;
c892d0dfeda5c022104813bf59275f840923551bCraig McDonnellLOAD_PE32_IMAGE_PRIVATE_DATA mLoadPe32PrivateData = {
c892d0dfeda5c022104813bf59275f840923551bCraig McDonnell// This code is needed to build the Image handle for the DXE Core
c892d0dfeda5c022104813bf59275f840923551bCraig McDonnellLOADED_IMAGE_PRIVATE_DATA mCorePrivateImage = {
c892d0dfeda5c022104813bf59275f840923551bCraig McDonnell LOADED_IMAGE_PRIVATE_DATA_SIGNATURE, // Signature
c892d0dfeda5c022104813bf59275f840923551bCraig McDonnell EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER, // Image type
c892d0dfeda5c022104813bf59275f840923551bCraig McDonnell EFI_LOADED_IMAGE_INFORMATION_REVISION, // Revision
c892d0dfeda5c022104813bf59275f840923551bCraig McDonnell 0, // LoadOptionsSize
c892d0dfeda5c022104813bf59275f840923551bCraig McDonnell 0, // ImageSize
c892d0dfeda5c022104813bf59275f840923551bCraig McDonnell 0, // NumberOfPages
c892d0dfeda5c022104813bf59275f840923551bCraig McDonnell 0, // ExitDataSize
c892d0dfeda5c022104813bf59275f840923551bCraig McDonnell 0, // Machine
c892d0dfeda5c022104813bf59275f840923551bCraig McDonnell// The field is define for Loading modules at fixed address feature to tracker the PEI code
c892d0dfeda5c022104813bf59275f840923551bCraig McDonnell// memory range usage. It is a bit mapped array in which every bit indicates the correspoding memory page
c892d0dfeda5c022104813bf59275f840923551bCraig McDonnell// available or not.
c892d0dfeda5c022104813bf59275f840923551bCraig McDonnellGLOBAL_REMOVE_IF_UNREFERENCED UINT64 *mDxeCodeMemoryRangeUsageBitMap=NULL;
c892d0dfeda5c022104813bf59275f840923551bCraig McDonnelltypedef struct {
c892d0dfeda5c022104813bf59275f840923551bCraig McDonnell// EBC machine is not listed in this table, because EBC is in the default supported scopes of other machine type.
c892d0dfeda5c022104813bf59275f840923551bCraig McDonnellGLOBAL_REMOVE_IF_UNREFERENCED MACHINE_TYPE_INFO mMachineTypeInfo[] = {
c892d0dfeda5c022104813bf59275f840923551bCraig McDonnell Return machine type name.
CHAR16 *
if (CompareGuid (&DxeCoreHob.MemoryAllocationModule->MemoryAllocationHeader.Name, &gEfiHobMemoryAllocModuleGuid)) {
DxeCoreImageBaseAddress = DxeCoreHob.MemoryAllocationModule->MemoryAllocationHeader.MemoryBaseAddress;
return Status;
return EFI_INVALID_PARAMETER;
return EFI_INVALID_PARAMETER;
*ReadSize = 0;
return EFI_SUCCESS;
To check memory usage bit map arry to figure out if the memory range the image will be loaded in is available or not. If
memory range is avaliable, the function will mark the correponding bits to 1 which indicates the memory range is used.
// If the Dxe code memory range is not allocated or the bit map array allocation failed, return EFI_NOT_FOUND
return EFI_NOT_FOUND;
return EFI_NOT_FOUND;
return EFI_NOT_FOUND;
return EFI_SUCCESS;
Get the fixed loadding address from image header assigned by build tool. This function only be called
ImgHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)((CHAR8* )Handle->Source + ImageContext->PeCoffHeaderOffset);
sizeof (UINT32) +
sizeof (EFI_IMAGE_FILE_HEADER) +
&Size,
return Status;
// 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. And there is an
// assumption that when the feature is enabled, if a module is assigned a loading address by tools, PointerToRelocations
if (ValueInSectionHeader != 0) {
// When the feature is configured as load module at fixed absolute address, the ImageAddress field of ImageContext
// hold the spcified address. If the feature is configured as load module at fixed offset, ImageAddress hold an offset
ImageContext->ImageAddress = gLoadModuleAtFixAddressConfigurationTable.DxeCodeTopAddress + (INT64)(INTN)ImageContext->ImageAddress;
Status = CheckAndMarkFixLoadingMemoryUsageBitMap (ImageContext->ImageAddress, (UINTN)(ImageContext->ImageSize + ImageContext->SectionAlignment));
DEBUG ((EFI_D_INFO|EFI_D_LOAD, "LOADING MODULE FIXED INFO: Loading module at fixed address 0x%11p. Status = %r \n", (VOID *)(UINTN)(ImageContext->ImageAddress), Status));
return Status;
return Status;
DEBUG ((EFI_D_ERROR, "Image type %s can't be loaded ", GetMachineTypeName(Image->ImageContext.Machine)));
return EFI_UNSUPPORTED;
return EFI_UNSUPPORTED;
if (DstBuffer == 0) {
// If the code memory is not ready, invoke CoreAllocatePage with AllocateAnyPages to load the driver.
DEBUG ((EFI_D_INFO|EFI_D_LOAD, "LOADING MODULE FIXED ERROR: Loading module at fixed address failed since specified memory is not available.\n"));
return Status;
return EFI_INVALID_PARAMETER;
(EFI_SIZE_TO_PAGES ((UINTN)Image->ImageContext.ImageSize + Image->ImageContext.SectionAlignment))) {
Image->NumberOfPages = EFI_SIZE_TO_PAGES ((UINTN)Image->ImageContext.ImageSize + Image->ImageContext.SectionAlignment);
return EFI_BUFFER_TOO_SMALL;
Image->NumberOfPages = EFI_SIZE_TO_PAGES ((UINTN)Image->ImageContext.ImageSize + Image->ImageContext.SectionAlignment);
goto Done;
goto Done;
goto Done;
InvalidateInstructionCacheRange ((VOID *)(UINTN)Image->ImageContext.ImageAddress, (UINTN)Image->ImageContext.ImageSize);
DEBUG ((DEBUG_LOAD | DEBUG_ERROR, "CoreLoadPeImage: There is no EBC interpreter for an EBC image.\n"));
goto Done;
Status = Image->Ebc->RegisterICacheFlush (Image->Ebc, (EBC_ICACHE_FLUSH)InvalidateInstructionCacheRange);
goto Done;
goto Done;
goto Done;
DEBUG_CODE_BEGIN ();
StartIndex = 0;
if ((Image->ImageContext.PdbPointer[Index] == '\\') || (Image->ImageContext.PdbPointer[Index] == '/')) {
// If the length is bigger than 255, trim the redudant characters to avoid overflow in array boundary.
DEBUG ((DEBUG_INFO | DEBUG_LOAD, "%a", EfiFileName)); // &Image->ImageContext.PdbPointer[StartIndex]));
DEBUG_CODE_END ();
return EFI_SUCCESS;
Done:
if (DstBufAlocated) {
return Status;
return Image;
NULL,
NULL,
&OpenInfo,
return EFI_INVALID_PARAMETER;
return EFI_INVALID_PARAMETER;
AuthenticationStatus = 0;
if (SourceSize > 0) {
return EFI_INVALID_PARAMETER;
if (!BootPolicy) {
goto Done;
return Status;
goto Done;
return EFI_OUT_OF_RESOURCES;
goto Done;
goto Done;
goto Done;
goto Done;
goto Done;
Done:
return Status;
Tick = 0;
NULL,
NULL,
EFI_LOAD_PE_IMAGE_ATTRIBUTE_RUNTIME_REGISTRATION | EFI_LOAD_PE_IMAGE_ATTRIBUTE_DEBUG_IMAGE_INFO_TABLE_REGISTRATION
return Status;
return CoreLoadImageCommon (
TRUE,
return EFI_INVALID_PARAMETER;
return EFI_UNSUPPORTED;
Image->JumpBuffer = AllocatePool (sizeof (BASE_LIBRARY_JUMP_BUFFER) + BASE_LIBRARY_JUMP_BUFFER_ALIGNMENT);
return EFI_OUT_OF_RESOURCES;
if (SetJumpFlag == 0) {
DEBUG_CODE_BEGIN ();
DEBUG ((DEBUG_ERROR, "Error: Image at %11p start failed: %r\n", Image->Info.ImageBase, Image->Status));
DEBUG_CODE_END ();
DEBUG_CODE_BEGIN ();
DEBUG ((DEBUG_LOAD, "StartImage: ExitDataSize %d, ExitData %p", (UINT32)Image->ExitDataSize, Image->ExitData));
DEBUG_CODE_END ();
return Status;
CoreExit (
goto Done;
goto Done;
goto Done;
goto Done;
Done:
return Status;
goto Done;
Done:
return Status;