\r
**/\r
\r
-#include <DxeMain.h>\r
+#include "DxeMain.h"\r
+#include "Image.h"\r
+\r
//\r
// Module Globals\r
//\r
-\r
LOADED_IMAGE_PRIVATE_DATA *mCurrentImage = NULL;\r
\r
LOAD_PE32_IMAGE_PRIVATE_DATA mLoadPe32PrivateData = {\r
Add the Image Services to EFI Boot Services Table and install the protocol\r
interfaces for this image.\r
\r
- @param HobStart The HOB to initialize \r
+ @param HobStart The HOB to initialize\r
\r
@return Status code.\r
\r
/**\r
Loads, relocates, and invokes a PE/COFF image\r
\r
- @param BootPolicy If TRUE, indicates that the request originates \r
- from the boot manager, and that the boot \r
- manager is attempting to load FilePath as a \r
- boot selection. \r
- @param Pe32Handle The handle of PE32 image \r
- @param Image PE image to be loaded \r
- @param DstBuffer The buffer to store the image \r
- @param EntryPoint A pointer to the entry point \r
- @param Attribute The bit mask of attributes to set for the load \r
- PE image \r
-\r
- @retval EFI_SUCCESS The file was loaded, relocated, and invoked \r
- @retval EFI_OUT_OF_RESOURCES There was not enough memory to load and \r
- relocate the PE/COFF file \r
- @retval EFI_INVALID_PARAMETER Invalid parameter \r
+ @param BootPolicy If TRUE, indicates that the request originates\r
+ from the boot manager, and that the boot\r
+ manager is attempting to load FilePath as a\r
+ boot selection.\r
+ @param Pe32Handle The handle of PE32 image\r
+ @param Image PE image to be loaded\r
+ @param DstBuffer The buffer to store the image\r
+ @param EntryPoint A pointer to the entry point\r
+ @param Attribute The bit mask of attributes to set for the load\r
+ PE image\r
+\r
+ @retval EFI_SUCCESS The file was loaded, relocated, and invoked\r
+ @retval EFI_OUT_OF_RESOURCES There was not enough memory to load and\r
+ relocate the PE/COFF file\r
+ @retval EFI_INVALID_PARAMETER Invalid parameter\r
@retval EFI_BUFFER_TOO_SMALL Buffer for image is too small\r
\r
**/\r
EFI_STATUS\r
CoreLoadPeImage (\r
- IN BOOLEAN BootPolicy, \r
+ IN BOOLEAN BootPolicy,\r
IN VOID *Pe32Handle,\r
IN LOADED_IMAGE_PRIVATE_DATA *Image,\r
IN EFI_PHYSICAL_ADDRESS DstBuffer OPTIONAL,\r
EFI_STATUS Status;\r
BOOLEAN DstBufAlocated;\r
UINTN Size;\r
- UINTN LinkTimeBase;\r
- EFI_TCG_PLATFORM_PROTOCOL *TcgPlatformProtocol;\r
- IMAGE_FILE_HANDLE *FHandle;\r
\r
- FHandle = NULL;\r
ZeroMem (&Image->ImageContext, sizeof (Image->ImageContext));\r
\r
Image->ImageContext.Handle = Pe32Handle;\r
return EFI_UNSUPPORTED;\r
}\r
}\r
- \r
+\r
//\r
// Set EFI memory type based on ImageType\r
//\r
Image->ImageContext.ImageError = IMAGE_ERROR_INVALID_SUBSYSTEM;\r
return EFI_UNSUPPORTED;\r
}\r
- //\r
- // Get the image base address in the original PeImage.\r
- //\r
- LinkTimeBase = (UINTN) Image->ImageContext.ImageAddress;\r
\r
//\r
// Allocate memory of the correct memory type aligned on the required image boundry\r
}\r
\r
Image->ImageBasePage = Image->ImageContext.ImageAddress;\r
- Image->ImageContext.ImageAddress =\r
- (Image->ImageContext.ImageAddress + Image->ImageContext.SectionAlignment - 1) &\r
- ~((UINTN)Image->ImageContext.SectionAlignment - 1);\r
+ if (!Image->ImageContext.IsTeImage) {\r
+ Image->ImageContext.ImageAddress =\r
+ (Image->ImageContext.ImageAddress + Image->ImageContext.SectionAlignment - 1) &\r
+ ~((UINTN)Image->ImageContext.SectionAlignment - 1);\r
+ }\r
\r
//\r
// Load the image from the file into the allocated memory\r
//\r
if ((Attribute & EFI_LOAD_PE_IMAGE_ATTRIBUTE_RUNTIME_REGISTRATION) != 0) {\r
if (Image->ImageContext.ImageType == EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER) {\r
- Image->ImageContext.FixupData = CoreAllocateRuntimePool ((UINTN)(Image->ImageContext.FixupDataSize));\r
+ Image->ImageContext.FixupData = AllocateRuntimePool ((UINTN)(Image->ImageContext.FixupDataSize));\r
if (Image->ImageContext.FixupData == NULL) {\r
Status = EFI_OUT_OF_RESOURCES;\r
goto Done;\r
}\r
}\r
\r
- //\r
- // Measure the image before applying fixup\r
- //\r
- Status = CoreLocateProtocol (\r
- &gEfiTcgPlatformProtocolGuid,\r
- NULL,\r
- (VOID **) &TcgPlatformProtocol\r
- );\r
- if (!EFI_ERROR (Status)) {\r
- FHandle = (IMAGE_FILE_HANDLE *) Image->ImageContext.Handle;\r
- Status = TcgPlatformProtocol->MeasurePeImage (\r
- BootPolicy,\r
- (EFI_PHYSICAL_ADDRESS) (UINTN) FHandle->Source,\r
- FHandle->SourceSize,\r
- LinkTimeBase,\r
- Image->ImageContext.ImageType,\r
- Image->Info.DeviceHandle,\r
- Image->Info.FilePath\r
- );\r
-\r
- ASSERT_EFI_ERROR (Status);\r
- }\r
-\r
//\r
// Relocate the image in memory\r
//\r
//\r
Status = CoreLocateProtocol (&gEfiEbcProtocolGuid, NULL, (VOID **)&Image->Ebc);\r
if (EFI_ERROR(Status)) {\r
+ DEBUG ((DEBUG_LOAD | DEBUG_ERROR, "CoreLoadPeImage: There is no EBC interpreter for an EBC image.\n"));\r
goto Done;\r
}\r
\r
Status = Image->Ebc->CreateThunk (\r
Image->Ebc,\r
Image->Handle,\r
- (VOID *)(UINTN)Image->ImageContext.EntryPoint,\r
- (VOID **)&Image->EntryPoint\r
+ (VOID *)(UINTN) Image->ImageContext.EntryPoint,\r
+ (VOID **) &Image->EntryPoint\r
);\r
if (EFI_ERROR(Status)) {\r
goto Done;\r
//\r
// Make a list off all the RT images so we can let the RT AP know about them.\r
//\r
- Image->RuntimeData = CoreAllocateRuntimePool (sizeof(EFI_RUNTIME_IMAGE_ENTRY));\r
+ Image->RuntimeData = AllocateRuntimePool (sizeof(EFI_RUNTIME_IMAGE_ENTRY));\r
if (Image->RuntimeData == NULL) {\r
goto Done;\r
}\r
UINTN Index;\r
UINTN StartIndex;\r
CHAR8 EfiFileName[256];\r
- \r
- if (Image->ImageContext.Machine != IMAGE_FILE_MACHINE_IA64) {\r
- DEBUG ((DEBUG_INFO | DEBUG_LOAD, \r
- "Loading driver at 0x%10p EntryPoint=0x%10p ", \r
- (VOID *)(UINTN)Image->ImageContext.ImageAddress, \r
- (VOID *)(UINTN)Image->ImageContext.EntryPoint));\r
- } else {\r
- //\r
- // For IPF Image, the real entry point should be print.\r
- // \r
- DEBUG ((DEBUG_INFO | DEBUG_LOAD, \r
- "Loading driver at 0x%10p EntryPoint=0x%10p ", \r
- (VOID *)(UINTN)Image->ImageContext.ImageAddress, \r
- (VOID *)(UINTN)(*(UINT64 *)(UINTN)Image->ImageContext.EntryPoint)));\r
- }\r
- \r
+\r
+\r
+ DEBUG ((DEBUG_INFO | DEBUG_LOAD,\r
+ "Loading driver at 0x%11p EntryPoint=0x%11p ",\r
+ (VOID *)(UINTN) Image->ImageContext.ImageAddress,\r
+ FUNCTION_ENTRY_POINT (Image->ImageContext.EntryPoint)));\r
+\r
+\r
//\r
- // Print Module Name by Pdb file path\r
+ // Print Module Name by Pdb file path.\r
+ // Windows and Unix style file path are all trimmed correctly.\r
//\r
if (Image->ImageContext.PdbPointer != NULL) {\r
StartIndex = 0;\r
for (Index = 0; Image->ImageContext.PdbPointer[Index] != 0; Index++) {\r
- if (Image->ImageContext.PdbPointer[Index] == '\\') {\r
+ if ((Image->ImageContext.PdbPointer[Index] == '\\') || (Image->ImageContext.PdbPointer[Index] == '/')) {\r
StartIndex = Index + 1;\r
}\r
}\r
//\r
// Copy the PDB file name to our temporary string, and replace .pdb with .efi\r
+ // The PDB file name is limited in the range of 0~255.\r
+ // If the length is bigger than 255, trim the redudant characters to avoid overflow in array boundary.\r
//\r
- for (Index = 0; Index < sizeof (EfiFileName); Index++) {\r
+ for (Index = 0; Index < sizeof (EfiFileName) - 4; Index++) {\r
EfiFileName[Index] = Image->ImageContext.PdbPointer[Index + StartIndex];\r
if (EfiFileName[Index] == 0) {\r
EfiFileName[Index] = '.';\r
break;\r
}\r
}\r
+\r
+ if (Index == sizeof (EfiFileName) - 4) {\r
+ EfiFileName[Index] = 0;\r
+ }\r
DEBUG ((DEBUG_INFO | DEBUG_LOAD, "%a", EfiFileName)); // &Image->ImageContext.PdbPointer[StartIndex]));\r
}\r
DEBUG ((DEBUG_INFO | DEBUG_LOAD, "\n"));\r
/**\r
Get the image's private data from its handle.\r
\r
- @param ImageHandle The image handle \r
+ @param ImageHandle The image handle\r
\r
@return Return the image private data associated with ImageHandle.\r
\r
if (!EFI_ERROR (Status)) {\r
Image = LOADED_IMAGE_PRIVATE_DATA_FROM_THIS (LoadedImage);\r
} else {\r
- DEBUG ((DEBUG_LOAD, "CoreLoadedImageInfo: Not an ImageHandle %x\n", ImageHandle));\r
+ DEBUG ((DEBUG_LOAD, "CoreLoadedImageInfo: Not an ImageHandle %p\n", ImageHandle));\r
Image = NULL;\r
}\r
\r
}\r
\r
\r
+/**\r
+ Unloads EFI image from memory.\r
+\r
+ @param Image EFI image\r
+ @param FreePage Free allocated pages\r
+\r
+**/\r
+VOID\r
+CoreUnloadAndCloseImage (\r
+ IN LOADED_IMAGE_PRIVATE_DATA *Image,\r
+ IN BOOLEAN FreePage\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ UINTN HandleCount;\r
+ EFI_HANDLE *HandleBuffer;\r
+ UINTN HandleIndex;\r
+ EFI_GUID **ProtocolGuidArray;\r
+ UINTN ArrayCount;\r
+ UINTN ProtocolIndex;\r
+ EFI_OPEN_PROTOCOL_INFORMATION_ENTRY *OpenInfo;\r
+ UINTN OpenInfoCount;\r
+ UINTN OpenInfoIndex;\r
+\r
+ if (Image->Ebc != NULL) {\r
+ //\r
+ // If EBC protocol exists we must perform cleanups for this image.\r
+ //\r
+ Image->Ebc->UnloadImage (Image->Ebc, Image->Handle);\r
+ }\r
+\r
+ //\r
+ // Unload image, free Image->ImageContext->ModHandle\r
+ //\r
+ PeCoffLoaderUnloadImage (&Image->ImageContext);\r
+\r
+ //\r
+ // Free our references to the image handle\r
+ //\r
+ if (Image->Handle != NULL) {\r
+\r
+ Status = CoreLocateHandleBuffer (\r
+ AllHandles,\r
+ NULL,\r
+ NULL,\r
+ &HandleCount,\r
+ &HandleBuffer\r
+ );\r
+ if (!EFI_ERROR (Status)) {\r
+ for (HandleIndex = 0; HandleIndex < HandleCount; HandleIndex++) {\r
+ Status = CoreProtocolsPerHandle (\r
+ HandleBuffer[HandleIndex],\r
+ &ProtocolGuidArray,\r
+ &ArrayCount\r
+ );\r
+ if (!EFI_ERROR (Status)) {\r
+ for (ProtocolIndex = 0; ProtocolIndex < ArrayCount; ProtocolIndex++) {\r
+ Status = CoreOpenProtocolInformation (\r
+ HandleBuffer[HandleIndex],\r
+ ProtocolGuidArray[ProtocolIndex],\r
+ &OpenInfo,\r
+ &OpenInfoCount\r
+ );\r
+ if (!EFI_ERROR (Status)) {\r
+ for (OpenInfoIndex = 0; OpenInfoIndex < OpenInfoCount; OpenInfoIndex++) {\r
+ if (OpenInfo[OpenInfoIndex].AgentHandle == Image->Handle) {\r
+ Status = CoreCloseProtocol (\r
+ HandleBuffer[HandleIndex],\r
+ ProtocolGuidArray[ProtocolIndex],\r
+ Image->Handle,\r
+ OpenInfo[OpenInfoIndex].ControllerHandle\r
+ );\r
+ }\r
+ }\r
+ if (OpenInfo != NULL) {\r
+ CoreFreePool(OpenInfo);\r
+ }\r
+ }\r
+ }\r
+ if (ProtocolGuidArray != NULL) {\r
+ CoreFreePool(ProtocolGuidArray);\r
+ }\r
+ }\r
+ }\r
+ if (HandleBuffer != NULL) {\r
+ CoreFreePool (HandleBuffer);\r
+ }\r
+ }\r
+\r
+ CoreRemoveDebugImageInfoEntry (Image->Handle);\r
+\r
+ Status = CoreUninstallProtocolInterface (\r
+ Image->Handle,\r
+ &gEfiLoadedImageDevicePathProtocolGuid,\r
+ Image->LoadedImageDevicePath\r
+ );\r
+\r
+ Status = CoreUninstallProtocolInterface (\r
+ Image->Handle,\r
+ &gEfiLoadedImageProtocolGuid,\r
+ &Image->Info\r
+ );\r
+\r
+ if (Image->ImageContext.HiiResourceData != 0) {\r
+ Status = CoreUninstallProtocolInterface (\r
+ Image->Handle,\r
+ &gEfiHiiPackageListProtocolGuid,\r
+ (VOID *) (UINTN) Image->ImageContext.HiiResourceData\r
+ );\r
+ }\r
+\r
+ }\r
+\r
+ if (Image->RuntimeData != NULL) {\r
+ if (Image->RuntimeData->Link.ForwardLink != NULL) {\r
+ //\r
+ // Remove the Image from the Runtime Image list as we are about to Free it!\r
+ //\r
+ RemoveEntryList (&Image->RuntimeData->Link);\r
+ }\r
+ CoreFreePool (Image->RuntimeData);\r
+ }\r
+\r
+ //\r
+ // Free the Image from memory\r
+ //\r
+ if ((Image->ImageBasePage != 0) && FreePage) {\r
+ CoreFreePages (Image->ImageBasePage, Image->NumberOfPages);\r
+ }\r
+\r
+ //\r
+ // Done with the Image structure\r
+ //\r
+ if (Image->Info.FilePath != NULL) {\r
+ CoreFreePool (Image->Info.FilePath);\r
+ }\r
+\r
+ if (Image->LoadedImageDevicePath != NULL) {\r
+ CoreFreePool (Image->LoadedImageDevicePath);\r
+ }\r
+\r
+ if (Image->FixupData != NULL) {\r
+ CoreFreePool (Image->FixupData);\r
+ }\r
+\r
+ CoreFreePool (Image);\r
+}\r
+\r
+\r
/**\r
Loads an EFI image into memory and returns a handle to the image.\r
\r
- @param BootPolicy If TRUE, indicates that the request originates \r
- from the boot manager, and that the boot \r
- manager is attempting to load FilePath as a \r
- boot selection. \r
- @param ParentImageHandle The caller's image handle. \r
- @param FilePath The specific file path from which the image is \r
- loaded. \r
- @param SourceBuffer If not NULL, a pointer to the memory location \r
- containing a copy of the image to be loaded. \r
- @param SourceSize The size in bytes of SourceBuffer. \r
- @param DstBuffer The buffer to store the image \r
- @param NumberOfPages If not NULL, it inputs a pointer to the page \r
- number of DstBuffer and outputs a pointer to \r
- the page number of the image. If this number is \r
- not enough, return EFI_BUFFER_TOO_SMALL and \r
- this parameter contains the required number. \r
- @param ImageHandle Pointer to the returned image handle that is \r
- created when the image is successfully loaded. \r
- @param EntryPoint A pointer to the entry point \r
- @param Attribute The bit mask of attributes to set for the load \r
- PE image \r
-\r
- @retval EFI_SUCCESS The image was loaded into memory. \r
- @retval EFI_NOT_FOUND The FilePath was not found. \r
- @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value. \r
- @retval EFI_BUFFER_TOO_SMALL The buffer is too small \r
- @retval EFI_UNSUPPORTED The image type is not supported, or the device \r
- path cannot be parsed to locate the proper \r
- protocol for loading the file. \r
- @retval EFI_OUT_OF_RESOURCES Image was not loaded due to insufficient \r
+ @param BootPolicy If TRUE, indicates that the request originates\r
+ from the boot manager, and that the boot\r
+ manager is attempting to load FilePath as a\r
+ boot selection.\r
+ @param ParentImageHandle The caller's image handle.\r
+ @param FilePath The specific file path from which the image is\r
+ loaded.\r
+ @param SourceBuffer If not NULL, a pointer to the memory location\r
+ containing a copy of the image to be loaded.\r
+ @param SourceSize The size in bytes of SourceBuffer.\r
+ @param DstBuffer The buffer to store the image\r
+ @param NumberOfPages If not NULL, it inputs a pointer to the page\r
+ number of DstBuffer and outputs a pointer to\r
+ the page number of the image. If this number is\r
+ not enough, return EFI_BUFFER_TOO_SMALL and\r
+ this parameter contains the required number.\r
+ @param ImageHandle Pointer to the returned image handle that is\r
+ created when the image is successfully loaded.\r
+ @param EntryPoint A pointer to the entry point\r
+ @param Attribute The bit mask of attributes to set for the load\r
+ PE image\r
+\r
+ @retval EFI_SUCCESS The image was loaded into memory.\r
+ @retval EFI_NOT_FOUND The FilePath was not found.\r
+ @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value.\r
+ @retval EFI_BUFFER_TOO_SMALL The buffer is too small\r
+ @retval EFI_UNSUPPORTED The image type is not supported, or the device\r
+ path cannot be parsed to locate the proper\r
+ protocol for loading the file.\r
+ @retval EFI_OUT_OF_RESOURCES Image was not loaded due to insufficient\r
resources.\r
\r
**/\r
//\r
// Allocate a new image structure\r
//\r
- Image = CoreAllocateZeroBootServicesPool (sizeof(LOADED_IMAGE_PRIVATE_DATA));\r
+ Image = AllocateZeroPool (sizeof(LOADED_IMAGE_PRIVATE_DATA));\r
if (Image == NULL) {\r
return EFI_OUT_OF_RESOURCES;\r
}\r
FilePath = OriginalFilePath;\r
Status = CoreHandleProtocol (DeviceHandle, &gEfiDevicePathProtocolGuid, (VOID **)&HandleFilePath);\r
if (!EFI_ERROR (Status)) {\r
- FilePathSize = CoreDevicePathSize (HandleFilePath) - sizeof(EFI_DEVICE_PATH_PROTOCOL);\r
- FilePath = (EFI_DEVICE_PATH_PROTOCOL *) ( ((UINT8 *)FilePath) + FilePathSize );\r
+ FilePathSize = GetDevicePathSize (HandleFilePath) - sizeof(EFI_DEVICE_PATH_PROTOCOL);\r
+ FilePath = (EFI_DEVICE_PATH_PROTOCOL *) (((UINT8 *)FilePath) + FilePathSize );\r
}\r
\r
//\r
Image->Info.SystemTable = gDxeCoreST;\r
Image->Info.DeviceHandle = DeviceHandle;\r
Image->Info.Revision = EFI_LOADED_IMAGE_PROTOCOL_REVISION;\r
- Image->Info.FilePath = CoreDuplicateDevicePath (FilePath);\r
+ Image->Info.FilePath = DuplicateDevicePath (FilePath);\r
Image->Info.ParentHandle = ParentImageHandle;\r
\r
\r
\r
if (NumberOfPages != NULL) {\r
*NumberOfPages = Image->NumberOfPages;\r
- } \r
+ }\r
\r
//\r
// Register the image in the Debug Image Info Table if the attribute is set\r
// otherwise Loaded Image Device Path Protocol is installed with a NULL interface pointer.\r
//\r
if (OriginalFilePath != NULL) {\r
- Image->LoadedImageDevicePath = CoreDuplicateDevicePath (OriginalFilePath);\r
+ Image->LoadedImageDevicePath = DuplicateDevicePath (OriginalFilePath);\r
}\r
\r
//\r
goto Done;\r
}\r
\r
+ //\r
+ // Install HII Package List Protocol onto the image handle\r
+ //\r
+ if (Image->ImageContext.HiiResourceData != 0) {\r
+ Status = CoreInstallProtocolInterface (\r
+ &Image->Handle,\r
+ &gEfiHiiPackageListProtocolGuid,\r
+ EFI_NATIVE_INTERFACE,\r
+ (VOID *) (UINTN) Image->ImageContext.HiiResourceData\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ goto Done;\r
+ }\r
+ }\r
+\r
//\r
// Success. Return the image handle\r
//\r
/**\r
Loads an EFI image into memory and returns a handle to the image.\r
\r
- @param BootPolicy If TRUE, indicates that the request originates \r
- from the boot manager, and that the boot \r
- manager is attempting to load FilePath as a \r
- boot selection. \r
- @param ParentImageHandle The caller's image handle. \r
- @param FilePath The specific file path from which the image is \r
- loaded. \r
- @param SourceBuffer If not NULL, a pointer to the memory location \r
- containing a copy of the image to be loaded. \r
- @param SourceSize The size in bytes of SourceBuffer. \r
- @param ImageHandle Pointer to the returned image handle that is \r
- created when the image is successfully loaded. \r
-\r
- @retval EFI_SUCCESS The image was loaded into memory. \r
- @retval EFI_NOT_FOUND The FilePath was not found. \r
- @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value. \r
- @retval EFI_UNSUPPORTED The image type is not supported, or the device \r
- path cannot be parsed to locate the proper \r
- protocol for loading the file. \r
- @retval EFI_OUT_OF_RESOURCES Image was not loaded due to insufficient \r
+ @param BootPolicy If TRUE, indicates that the request originates\r
+ from the boot manager, and that the boot\r
+ manager is attempting to load FilePath as a\r
+ boot selection.\r
+ @param ParentImageHandle The caller's image handle.\r
+ @param FilePath The specific file path from which the image is\r
+ loaded.\r
+ @param SourceBuffer If not NULL, a pointer to the memory location\r
+ containing a copy of the image to be loaded.\r
+ @param SourceSize The size in bytes of SourceBuffer.\r
+ @param ImageHandle Pointer to the returned image handle that is\r
+ created when the image is successfully loaded.\r
+\r
+ @retval EFI_SUCCESS The image was loaded into memory.\r
+ @retval EFI_NOT_FOUND The FilePath was not found.\r
+ @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value.\r
+ @retval EFI_UNSUPPORTED The image type is not supported, or the device\r
+ path cannot be parsed to locate the proper\r
+ protocol for loading the file.\r
+ @retval EFI_OUT_OF_RESOURCES Image was not loaded due to insufficient\r
resources.\r
\r
**/\r
)\r
{\r
EFI_STATUS Status;\r
+ UINT64 Tick;\r
\r
- PERF_START (NULL, "LoadImage", NULL, 0);\r
+ Tick = 0;\r
+ PERF_CODE (\r
+ Tick = GetPerformanceCounter ();\r
+ );\r
\r
Status = CoreLoadImageCommon (\r
BootPolicy,\r
EFI_LOAD_PE_IMAGE_ATTRIBUTE_RUNTIME_REGISTRATION | EFI_LOAD_PE_IMAGE_ATTRIBUTE_DEBUG_IMAGE_INFO_TABLE_REGISTRATION\r
);\r
\r
- PERF_END (NULL, "LoadImage", NULL, 0);\r
+ PERF_START (*ImageHandle, "LoadImage:", NULL, Tick);\r
+ PERF_END (*ImageHandle, "LoadImage:", NULL, 0);\r
\r
return Status;\r
}\r
/**\r
Loads an EFI image into memory and returns a handle to the image with extended parameters.\r
\r
- @param This Calling context \r
- @param ParentImageHandle The caller's image handle. \r
- @param FilePath The specific file path from which the image is \r
- loaded. \r
- @param SourceBuffer If not NULL, a pointer to the memory location \r
- containing a copy of the image to be loaded. \r
- @param SourceSize The size in bytes of SourceBuffer. \r
- @param DstBuffer The buffer to store the image. \r
- @param NumberOfPages For input, specifies the space size of the \r
- image by caller if not NULL. For output, \r
- specifies the actual space size needed. \r
- @param ImageHandle Image handle for output. \r
- @param EntryPoint Image entry point for output. \r
- @param Attribute The bit mask of attributes to set for the load \r
- PE image. \r
-\r
- @retval EFI_SUCCESS The image was loaded into memory. \r
- @retval EFI_NOT_FOUND The FilePath was not found. \r
- @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value. \r
- @retval EFI_UNSUPPORTED The image type is not supported, or the device \r
- path cannot be parsed to locate the proper \r
- protocol for loading the file. \r
- @retval EFI_OUT_OF_RESOURCES Image was not loaded due to insufficient \r
+ @param This Calling context\r
+ @param ParentImageHandle The caller's image handle.\r
+ @param FilePath The specific file path from which the image is\r
+ loaded.\r
+ @param SourceBuffer If not NULL, a pointer to the memory location\r
+ containing a copy of the image to be loaded.\r
+ @param SourceSize The size in bytes of SourceBuffer.\r
+ @param DstBuffer The buffer to store the image.\r
+ @param NumberOfPages For input, specifies the space size of the\r
+ image by caller if not NULL. For output,\r
+ specifies the actual space size needed.\r
+ @param ImageHandle Image handle for output.\r
+ @param EntryPoint Image entry point for output.\r
+ @param Attribute The bit mask of attributes to set for the load\r
+ PE image.\r
+\r
+ @retval EFI_SUCCESS The image was loaded into memory.\r
+ @retval EFI_NOT_FOUND The FilePath was not found.\r
+ @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value.\r
+ @retval EFI_UNSUPPORTED The image type is not supported, or the device\r
+ path cannot be parsed to locate the proper\r
+ protocol for loading the file.\r
+ @retval EFI_OUT_OF_RESOURCES Image was not loaded due to insufficient\r
resources.\r
\r
**/\r
/**\r
Transfer control to a loaded image's entry point.\r
\r
- @param ImageHandle Handle of image to be started. \r
- @param ExitDataSize Pointer of the size to ExitData \r
- @param ExitData Pointer to a pointer to a data buffer that \r
- includes a Null-terminated Unicode string, \r
- optionally followed by additional binary data. \r
- The string is a description that the caller may \r
- use to further indicate the reason for the \r
- image's exit. \r
-\r
- @retval EFI_INVALID_PARAMETER Invalid parameter \r
- @retval EFI_OUT_OF_RESOURCES No enough buffer to allocate \r
- @retval EFI_SUCCESS Successfully transfer control to the image's \r
+ @param ImageHandle Handle of image to be started.\r
+ @param ExitDataSize Pointer of the size to ExitData\r
+ @param ExitData Pointer to a pointer to a data buffer that\r
+ includes a Null-terminated Unicode string,\r
+ optionally followed by additional binary data.\r
+ The string is a description that the caller may\r
+ use to further indicate the reason for the\r
+ image's exit.\r
+\r
+ @retval EFI_INVALID_PARAMETER Invalid parameter\r
+ @retval EFI_OUT_OF_RESOURCES No enough buffer to allocate\r
+ @retval EFI_SUCCESS Successfully transfer control to the image's\r
entry point.\r
\r
**/\r
UINTN SetJumpFlag;\r
\r
Image = CoreLoadedImageInfo (ImageHandle);\r
- if (Image == NULL_HANDLE || Image->Started) {\r
+ if (Image == NULL || Image->Started) {\r
return EFI_INVALID_PARAMETER;\r
}\r
\r
//\r
// Don't profile Objects or invalid start requests\r
//\r
- PERF_START (ImageHandle, START_IMAGE_TOK, NULL, 0);\r
+ PERF_START (ImageHandle, "StartImage:", NULL, 0);\r
\r
\r
//\r
// JumpContext must be aligned on a CPU specific boundary.\r
// Overallocate the buffer and force the required alignment\r
//\r
- Image->JumpBuffer = CoreAllocateBootServicesPool (sizeof (BASE_LIBRARY_JUMP_BUFFER) + BASE_LIBRARY_JUMP_BUFFER_ALIGNMENT);\r
+ Image->JumpBuffer = AllocatePool (sizeof (BASE_LIBRARY_JUMP_BUFFER) + BASE_LIBRARY_JUMP_BUFFER_ALIGNMENT);\r
if (Image->JumpBuffer == NULL) {\r
- PERF_END (ImageHandle, START_IMAGE_TOK, NULL, 0);\r
+ PERF_END (ImageHandle, "StartImage:", NULL, 0);\r
return EFI_OUT_OF_RESOURCES;\r
}\r
Image->JumpContext = ALIGN_POINTER (Image->JumpBuffer, BASE_LIBRARY_JUMP_BUFFER_ALIGNMENT);\r
//\r
DEBUG_CODE_BEGIN ();\r
if (EFI_ERROR (Image->Status)) {\r
- DEBUG ((DEBUG_ERROR, "Error: Image at %10p start failed: %r\n", Image->Info.ImageBase, Image->Status));\r
+ DEBUG ((DEBUG_ERROR, "Error: Image at %11p start failed: %r\n", Image->Info.ImageBase, Image->Status));\r
}\r
DEBUG_CODE_END ();\r
\r
DEBUG_CODE_BEGIN ();\r
if (Image->ExitDataSize != 0 || Image->ExitData != NULL) {\r
\r
- DEBUG (\r
- (DEBUG_LOAD,\r
- "StartImage: ExitDataSize %d, ExitData %x",\r
- Image->ExitDataSize,\r
- Image->ExitData)\r
- );\r
+ DEBUG ((DEBUG_LOAD, "StartImage: ExitDataSize %d, ExitData %p", (UINT32)Image->ExitDataSize, Image->ExitData));\r
if (Image->ExitData != NULL) {\r
DEBUG ((DEBUG_LOAD, " (%hs)", Image->ExitData));\r
}\r
//\r
// Done\r
//\r
- PERF_END (ImageHandle, START_IMAGE_TOK, NULL, 0);\r
+ PERF_END (ImageHandle, "StartImage:", NULL, 0);\r
return Status;\r
}\r
\r
-\r
-\r
-/**\r
- Unloads EFI image from memory.\r
-\r
- @param Image EFI image \r
- @param FreePage Free allocated pages\r
-\r
-**/\r
-VOID\r
-CoreUnloadAndCloseImage (\r
- IN LOADED_IMAGE_PRIVATE_DATA *Image,\r
- IN BOOLEAN FreePage\r
- )\r
-{\r
- EFI_STATUS Status;\r
- UINTN HandleCount;\r
- EFI_HANDLE *HandleBuffer;\r
- UINTN HandleIndex;\r
- EFI_GUID **ProtocolGuidArray;\r
- UINTN ArrayCount;\r
- UINTN ProtocolIndex;\r
- EFI_OPEN_PROTOCOL_INFORMATION_ENTRY *OpenInfo;\r
- UINTN OpenInfoCount;\r
- UINTN OpenInfoIndex;\r
-\r
- if (Image->Ebc != NULL) {\r
- //\r
- // If EBC protocol exists we must perform cleanups for this image.\r
- //\r
- Image->Ebc->UnloadImage (Image->Ebc, Image->Handle);\r
- }\r
-\r
- //\r
- // Unload image, free Image->ImageContext->ModHandle\r
- //\r
- PeCoffLoaderUnloadImage (&Image->ImageContext);\r
-\r
- //\r
- // Free our references to the image handle\r
- //\r
- if (Image->Handle != NULL_HANDLE) {\r
-\r
- Status = CoreLocateHandleBuffer (\r
- AllHandles,\r
- NULL,\r
- NULL,\r
- &HandleCount,\r
- &HandleBuffer\r
- );\r
- if (!EFI_ERROR (Status)) {\r
- for (HandleIndex = 0; HandleIndex < HandleCount; HandleIndex++) {\r
- Status = CoreProtocolsPerHandle (\r
- HandleBuffer[HandleIndex],\r
- &ProtocolGuidArray,\r
- &ArrayCount\r
- );\r
- if (!EFI_ERROR (Status)) {\r
- for (ProtocolIndex = 0; ProtocolIndex < ArrayCount; ProtocolIndex++) {\r
- Status = CoreOpenProtocolInformation (\r
- HandleBuffer[HandleIndex],\r
- ProtocolGuidArray[ProtocolIndex],\r
- &OpenInfo,\r
- &OpenInfoCount\r
- );\r
- if (!EFI_ERROR (Status)) {\r
- for (OpenInfoIndex = 0; OpenInfoIndex < OpenInfoCount; OpenInfoIndex++) {\r
- if (OpenInfo[OpenInfoIndex].AgentHandle == Image->Handle) {\r
- Status = CoreCloseProtocol (\r
- HandleBuffer[HandleIndex],\r
- ProtocolGuidArray[ProtocolIndex],\r
- Image->Handle,\r
- OpenInfo[OpenInfoIndex].ControllerHandle\r
- );\r
- }\r
- }\r
- if (OpenInfo != NULL) {\r
- CoreFreePool(OpenInfo);\r
- }\r
- }\r
- }\r
- if (ProtocolGuidArray != NULL) {\r
- CoreFreePool(ProtocolGuidArray);\r
- }\r
- }\r
- }\r
- if (HandleBuffer != NULL) {\r
- CoreFreePool (HandleBuffer);\r
- }\r
- }\r
-\r
- CoreRemoveDebugImageInfoEntry (Image->Handle);\r
-\r
- Status = CoreUninstallProtocolInterface (\r
- Image->Handle,\r
- &gEfiLoadedImageDevicePathProtocolGuid,\r
- Image->LoadedImageDevicePath\r
- );\r
-\r
- Status = CoreUninstallProtocolInterface (\r
- Image->Handle,\r
- &gEfiLoadedImageProtocolGuid,\r
- &Image->Info\r
- );\r
-\r
- }\r
-\r
- if (Image->RuntimeData != NULL) {\r
- if (Image->RuntimeData->Link.ForwardLink != NULL) {\r
- //\r
- // Remove the Image from the Runtime Image list as we are about to Free it!\r
- //\r
- RemoveEntryList (&Image->RuntimeData->Link);\r
- }\r
- CoreFreePool (Image->RuntimeData);\r
- }\r
-\r
- //\r
- // Free the Image from memory\r
- //\r
- if ((Image->ImageBasePage != 0) && FreePage) {\r
- CoreFreePages (Image->ImageBasePage, Image->NumberOfPages);\r
- }\r
-\r
- //\r
- // Done with the Image structure\r
- //\r
- if (Image->Info.FilePath != NULL) {\r
- CoreFreePool (Image->Info.FilePath);\r
- }\r
-\r
- if (Image->LoadedImageDevicePath != NULL) {\r
- CoreFreePool (Image->LoadedImageDevicePath);\r
- }\r
-\r
- if (Image->FixupData != NULL) {\r
- CoreFreePool (Image->FixupData);\r
- }\r
-\r
- CoreFreePool (Image);\r
-}\r
-\r
-\r
-\r
-\r
/**\r
Terminates the currently loaded EFI image and returns control to boot services.\r
\r
- @param ImageHandle Handle that identifies the image. This \r
- parameter is passed to the image on entry. \r
- @param Status The image's exit code. \r
- @param ExitDataSize The size, in bytes, of ExitData. Ignored if \r
- ExitStatus is EFI_SUCCESS. \r
- @param ExitData Pointer to a data buffer that includes a \r
- Null-terminated Unicode string, optionally \r
- followed by additional binary data. The string \r
- is a description that the caller may use to \r
- further indicate the reason for the image's \r
- exit. \r
-\r
- @retval EFI_INVALID_PARAMETER Image handle is NULL or it is not current \r
- image. \r
- @retval EFI_SUCCESS Successfully terminates the currently loaded \r
- EFI image. \r
- @retval EFI_ACCESS_DENIED Should never reach there. \r
+ @param ImageHandle Handle that identifies the image. This\r
+ parameter is passed to the image on entry.\r
+ @param Status The image's exit code.\r
+ @param ExitDataSize The size, in bytes, of ExitData. Ignored if\r
+ ExitStatus is EFI_SUCCESS.\r
+ @param ExitData Pointer to a data buffer that includes a\r
+ Null-terminated Unicode string, optionally\r
+ followed by additional binary data. The string\r
+ is a description that the caller may use to\r
+ further indicate the reason for the image's\r
+ exit.\r
+\r
+ @retval EFI_INVALID_PARAMETER Image handle is NULL or it is not current\r
+ image.\r
+ @retval EFI_SUCCESS Successfully terminates the currently loaded\r
+ EFI image.\r
+ @retval EFI_ACCESS_DENIED Should never reach there.\r
@retval EFI_OUT_OF_RESOURCES Could not allocate pool\r
\r
**/\r
//\r
// Prevent possible reentrance to this function\r
// for the same ImageHandle\r
- // \r
- OldTpl = CoreRaiseTpl (TPL_NOTIFY); \r
- \r
+ //\r
+ OldTpl = CoreRaiseTpl (TPL_NOTIFY);\r
+\r
Image = CoreLoadedImageInfo (ImageHandle);\r
- if (Image == NULL_HANDLE) {\r
+ if (Image == NULL) {\r
Status = EFI_INVALID_PARAMETER;\r
goto Done;\r
}\r
//\r
if (ExitData != NULL) {\r
Image->ExitDataSize = ExitDataSize;\r
- Image->ExitData = CoreAllocateBootServicesPool (Image->ExitDataSize);\r
+ Image->ExitData = AllocatePool (Image->ExitDataSize);\r
if (Image->ExitData == NULL) {\r
Status = EFI_OUT_OF_RESOURCES;\r
goto Done;\r
/**\r
Unloads an image.\r
\r
- @param ImageHandle Handle that identifies the image to be \r
- unloaded. \r
+ @param ImageHandle Handle that identifies the image to be\r
+ unloaded.\r
\r
- @retval EFI_SUCCESS The image has been unloaded. \r
- @retval EFI_UNSUPPORTED The image has been sarted, and does not support \r
- unload. \r
+ @retval EFI_SUCCESS The image has been unloaded.\r
+ @retval EFI_UNSUPPORTED The image has been sarted, and does not support\r
+ unload.\r
@retval EFI_INVALID_PARAMPETER ImageHandle is not a valid image handle.\r
\r
**/\r
{\r
EFI_STATUS Status;\r
LOADED_IMAGE_PRIVATE_DATA *Image;\r
- EFI_TPL OldTpl;\r
\r
- //\r
- // Prevent possible reentrance to this function\r
- // for the same ImageHandle\r
- // \r
- OldTpl = CoreRaiseTpl (TPL_NOTIFY);\r
- \r
Image = CoreLoadedImageInfo (ImageHandle);\r
if (Image == NULL ) {\r
//\r
}\r
\r
Done:\r
- CoreRestoreTpl (OldTpl);\r
return Status;\r
}\r
\r
/**\r
Unload the specified image.\r
\r
- @param This Indicates the calling context. \r
- @param ImageHandle The specified image handle. \r
+ @param This Indicates the calling context.\r
+ @param ImageHandle The specified image handle.\r
\r
- @retval EFI_INVALID_PARAMETER Image handle is NULL. \r
- @retval EFI_UNSUPPORTED Attempt to unload an unsupported image. \r
+ @retval EFI_INVALID_PARAMETER Image handle is NULL.\r
+ @retval EFI_UNSUPPORTED Attempt to unload an unsupported image.\r
@retval EFI_SUCCESS Image successfully unloaded.\r
\r
**/\r