-/*++\r
+/** @file\r
\r
Copyright (c) 2006 - 2007, Intel Corporation \r
All rights reserved. This program and the accompanying materials \r
\r
Pei Core Load Image Support\r
\r
+**/\r
+\r
+#include <PeiMain.h>\r
+\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Support routine for the PE/COFF Loader that reads a buffer from a PE/COFF file\r
+\r
+Arguments:\r
+\r
+ FileHandle - The handle to the PE/COFF file\r
+ FileOffset - The offset, in bytes, into the file to read\r
+ ReadSize - The number of bytes to read from the file starting at FileOffset\r
+ Buffer - A pointer to the buffer to read the data into.\r
+\r
+Returns:\r
+\r
+ EFI_SUCCESS - ReadSize bytes of data were read into Buffer from the PE/COFF file starting at FileOffset\r
+\r
+--*/ \r
+\r
+EFI_STATUS\r
+PeiLoadImageLoadImage (\r
+ IN EFI_PEI_SERVICES **PeiServices,\r
+ IN EFI_PEI_FILE_HANDLE FileHandle,\r
+ OUT EFI_PHYSICAL_ADDRESS *ImageAddressArg, OPTIONAL\r
+ OUT UINT64 *ImageSizeArg, OPTIONAL\r
+ OUT EFI_PHYSICAL_ADDRESS *EntryPoint,\r
+ OUT UINT32 *AuthenticationState\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Routine for loading file image.\r
+\r
+Arguments:\r
+\r
+ PeiServices - The PEI core services table.\r
+ FileHandle - Pointer to the FFS file header of the image.\r
+ ImageAddressArg - Pointer to PE/TE image.\r
+ ImageSizeArg - Size of PE/TE image.\r
+ EntryPoint - Pointer to entry point of specified image file for output.\r
+ AuthenticationState - Pointer to attestation authentication state of image.\r
+\r
+Returns:\r
+\r
+ Status - EFI_SUCCESS - Image is successfully loaded.\r
+ EFI_NOT_FOUND - Fail to locate necessary PPI\r
+ Others - Fail to load file.\r
+\r
--*/\r
+;\r
\r
-//\r
-// Include common header file for this module.\r
-//\r
-#include "CommonHeader.h"\r
+EFI_STATUS\r
+EFIAPI\r
+PeiLoadImageLoadImageWrapper (\r
+ IN CONST EFI_PEI_LOAD_FILE_PPI *This,\r
+ IN EFI_PEI_FILE_HANDLE FileHandle,\r
+ OUT EFI_PHYSICAL_ADDRESS *ImageAddressArg, OPTIONAL\r
+ OUT UINT64 *ImageSizeArg, OPTIONAL\r
+ OUT EFI_PHYSICAL_ADDRESS *EntryPoint,\r
+ OUT UINT32 *AuthenticationState\r
+ )\r
+/*++\r
\r
-#include <PeiMain.h>\r
+Routine Description:\r
+\r
+ The wrapper function of PeiLoadImageLoadImage().\r
+\r
+Arguments:\r
\r
+ This - Pointer to EFI_PEI_LOAD_FILE_PPI.\r
+ PeiServices - The PEI core services table.\r
+ FileHandle - Pointer to the FFS file header of the image.\r
+ ImageAddressArg - Pointer to PE/TE image.\r
+ ImageSizeArg - Size of PE/TE image.\r
+ EntryPoint - Pointer to entry point of specified image file for output.\r
+ AuthenticationState - Pointer to attestation authentication state of image.\r
\r
+Returns:\r
+\r
+ EFI_STATUS.\r
+ \r
+--*/ \r
+;\r
+\r
+STATIC EFI_PEI_LOAD_FILE_PPI mPeiLoadImagePpi = {\r
+ PeiLoadImageLoadImageWrapper\r
+};\r
+\r
+\r
+STATIC EFI_PEI_PPI_DESCRIPTOR gPpiLoadFilePpiList = {\r
+ (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),\r
+ &gEfiPeiLoadFilePpiGuid,\r
+ &mPeiLoadImagePpi\r
+};\r
\r
EFI_STATUS\r
-PeiLoadImage (\r
- IN EFI_PEI_SERVICES **PeiServices,\r
- IN EFI_FFS_FILE_HEADER *PeimFileHeader,\r
- OUT VOID **EntryPoint\r
+EFIAPI\r
+PeiImageRead (\r
+ IN VOID *FileHandle,\r
+ IN UINTN FileOffset,\r
+ IN OUT UINTN *ReadSize,\r
+ OUT VOID *Buffer\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Support routine for the PE/COFF Loader that reads a buffer from a PE/COFF file\r
+\r
+Arguments:\r
+\r
+ FileHandle - The handle to the PE/COFF file\r
+ FileOffset - The offset, in bytes, into the file to read\r
+ ReadSize - The number of bytes to read from the file starting at FileOffset\r
+ Buffer - A pointer to the buffer to read the data into.\r
+\r
+Returns:\r
+\r
+ EFI_SUCCESS - ReadSize bytes of data were read into Buffer from the PE/COFF file starting at FileOffset\r
+\r
+--*/\r
+{\r
+ CHAR8 *Destination8;\r
+ CHAR8 *Source8;\r
+ UINTN Length;\r
+\r
+ Destination8 = Buffer;\r
+ Source8 = (CHAR8 *) ((UINTN) FileHandle + FileOffset);\r
+ Length = *ReadSize;\r
+ while (Length--) {\r
+ *(Destination8++) = *(Source8++);\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+GetImageReadFunction (\r
+ IN PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Support routine to return the Image Read\r
+\r
+Arguments:\r
+\r
+ PeiServices - PEI Services Table\r
+\r
+ ImageContext - The context of the image being loaded\r
+\r
+Returns:\r
+\r
+ EFI_SUCCESS - If Image function location is found\r
+\r
+--*/\r
+{\r
+ VOID* MemoryBuffer;\r
+\r
+ MemoryBuffer = AllocatePages (0x400 / EFI_PAGE_SIZE + 1);\r
+ ASSERT (MemoryBuffer != NULL);\r
+\r
+ CopyMem (MemoryBuffer, (CONST VOID *) (UINTN) PeiImageRead, 0x400);\r
+\r
+ ImageContext->ImageRead = (PE_COFF_LOADER_READ_FILE) (UINTN) MemoryBuffer;\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+STATIC\r
+EFI_STATUS\r
+LoadAndRelocatePeCoffImage (\r
+ IN VOID *Pe32Data,\r
+ OUT EFI_PHYSICAL_ADDRESS *ImageAddress,\r
+ OUT UINT64 *ImageSize,\r
+ OUT EFI_PHYSICAL_ADDRESS *EntryPoint\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Loads and relocates a PE/COFF image into memory.\r
+\r
+Arguments:\r
+\r
+ Pe32Data - The base address of the PE/COFF file that is to be loaded and relocated\r
+\r
+ ImageAddress - The base address of the relocated PE/COFF image\r
+\r
+ ImageSize - The size of the relocated PE/COFF image\r
+\r
+ EntryPoint - The entry point of the relocated PE/COFF image\r
+\r
+Returns:\r
+\r
+ EFI_SUCCESS - The file was loaded and relocated\r
+\r
+ EFI_OUT_OF_RESOURCES - There was not enough memory to load and relocate the PE/COFF file\r
+\r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;\r
+\r
+ ZeroMem (&ImageContext, sizeof (ImageContext));\r
+ ImageContext.Handle = Pe32Data;\r
+ Status = GetImageReadFunction (&ImageContext);\r
+\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
+ Status = PeCoffLoaderGetImageInfo (&ImageContext);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+ //\r
+ // When Image has no reloc section, it can't be relocated into memory.\r
+ //\r
+ if (ImageContext.RelocationsStripped) {\r
+ DEBUG ((EFI_D_ERROR, "The image at 0x%08x without reloc section can't be loaded into memory\n", (UINTN) Pe32Data));\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+ //\r
+ // Allocate Memory for the image\r
+ //\r
+ ImageContext.ImageAddress = (EFI_PHYSICAL_ADDRESS)(UINTN) AllocatePages (EFI_SIZE_TO_PAGES ((UINT32) ImageContext.ImageSize));\r
+ ASSERT (ImageContext.ImageAddress != 0);\r
+ \r
+ //\r
+ // Skip the reserved space for the stripped PeHeader when load TeImage into memory.\r
+ //\r
+ if (ImageContext.IsTeImage) {\r
+ ImageContext.ImageAddress = ImageContext.ImageAddress + \r
+ ((EFI_TE_IMAGE_HEADER *) Pe32Data)->StrippedSize -\r
+ sizeof (EFI_TE_IMAGE_HEADER);\r
+ }\r
+\r
+ //\r
+ // Load the image to our new buffer\r
+ //\r
+ Status = PeCoffLoaderLoadImage (&ImageContext);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+ //\r
+ // Relocate the image in our new buffer\r
+ //\r
+ Status = PeCoffLoaderRelocateImage (&ImageContext);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ //\r
+ // Flush the instruction cache so the image data is written before we execute it\r
+ //\r
+ InvalidateInstructionCacheRange ((VOID *)(UINTN)ImageContext.ImageAddress, (UINTN)ImageContext.ImageSize);\r
+\r
+ *ImageAddress = ImageContext.ImageAddress;\r
+ *ImageSize = ImageContext.ImageSize;\r
+ *EntryPoint = ImageContext.EntryPoint;\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+PeiLoadImageLoadImage (\r
+ IN EFI_PEI_SERVICES **PeiServices,\r
+ IN EFI_PEI_FILE_HANDLE FileHandle,\r
+ OUT EFI_PHYSICAL_ADDRESS *ImageAddressArg, OPTIONAL\r
+ OUT UINT64 *ImageSizeArg, OPTIONAL\r
+ OUT EFI_PHYSICAL_ADDRESS *EntryPoint,\r
+ OUT UINT32 *AuthenticationState\r
)\r
/*++\r
\r
\r
Arguments:\r
\r
- PeiServices - The PEI core services table.\r
- PeimFileHeader - Pointer to the FFS file header of the image.\r
- EntryPoint - Pointer to entry point of specified image file for output.\r
+ PeiServices - The PEI core services table.\r
+ FileHandle - Pointer to the FFS file header of the image.\r
+ ImageAddressArg - Pointer to PE/TE image.\r
+ ImageSizeArg - Size of PE/TE image.\r
+ EntryPoint - Pointer to entry point of specified image file for output.\r
+ AuthenticationState - Pointer to attestation authentication state of image.\r
\r
Returns:\r
\r
{\r
EFI_STATUS Status;\r
VOID *Pe32Data;\r
- EFI_PEI_FV_FILE_LOADER_PPI *FvLoadFilePpi;\r
EFI_PHYSICAL_ADDRESS ImageAddress;\r
UINT64 ImageSize;\r
EFI_PHYSICAL_ADDRESS ImageEntryPoint;\r
- EFI_TE_IMAGE_HEADER *TEImageHeader;\r
UINT16 Machine;\r
-\r
- *EntryPoint = NULL;\r
- TEImageHeader = NULL;\r
-\r
+ PEI_CORE_INSTANCE *Private;\r
+ VOID *EntryPointArg;\r
+ EFI_SECTION_TYPE SearchType1;\r
+ EFI_SECTION_TYPE SearchType2;\r
+\r
+ *EntryPoint = 0;\r
+ ImageSize = 0;\r
+ *AuthenticationState = 0;\r
+\r
+ if (FeaturePcdGet (PcdPeiCoreImageLoaderSearchTeSectionFirst)) {\r
+ SearchType1 = EFI_SECTION_TE;\r
+ SearchType2 = EFI_SECTION_PE32;\r
+ } else {\r
+ SearchType1 = EFI_SECTION_PE32;\r
+ SearchType2 = EFI_SECTION_TE;\r
+ }\r
//\r
- // Try to find a PE32 section.\r
+ // Try to find a first exe section (if PcdPeiCoreImageLoaderSearchTeSectionFirst \r
+ // is true, TE will be searched first).\r
//\r
Status = PeiServicesFfsFindSectionData (\r
- EFI_SECTION_PE32,\r
- PeimFileHeader,\r
+ SearchType1,\r
+ FileHandle,\r
&Pe32Data\r
);\r
//\r
- // If we didn't find a PE32 section, try to find a TE section.\r
+ // If we didn't find a first exe section, try to find the second exe section.\r
//\r
if (EFI_ERROR (Status)) {\r
Status = PeiServicesFfsFindSectionData (\r
- EFI_SECTION_TE,\r
- PeimFileHeader,\r
- (VOID **) &TEImageHeader\r
+ SearchType2,\r
+ FileHandle,\r
+ &Pe32Data\r
);\r
- if (EFI_ERROR (Status) || TEImageHeader == NULL) {\r
+ if (EFI_ERROR (Status)) {\r
//\r
- // There was not a PE32 or a TE section, so assume that it's a Compressed section\r
- // and use the LoadFile\r
+ // PEI core only carry the loader function fro TE and PE32 executables\r
+ // If this two section does not exist, just return.\r
//\r
- Status = PeiServicesLocatePpi (\r
- &gEfiPeiFvFileLoaderPpiGuid,\r
- 0,\r
- NULL,\r
- (VOID **)&FvLoadFilePpi\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return EFI_NOT_FOUND;\r
- }\r
-\r
- Status = FvLoadFilePpi->FvLoadFile (\r
- FvLoadFilePpi,\r
- PeimFileHeader,\r
- &ImageAddress,\r
- &ImageSize,\r
- &ImageEntryPoint\r
- );\r
+ return Status;\r
+ }\r
+ }\r
+ \r
+ Private = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);\r
\r
- if (EFI_ERROR (Status)) {\r
- return EFI_NOT_FOUND;\r
- }\r
+ if (Private->PeiMemoryInstalled && \r
+ (Private->HobList.HandoffInformationTable->BootMode != BOOT_ON_S3_RESUME)) {\r
+ //\r
+ // If memory is installed, perform the shadow operations\r
+ //\r
+ Status = LoadAndRelocatePeCoffImage (\r
+ Pe32Data,\r
+ &ImageAddress,\r
+ &ImageSize,\r
+ &ImageEntryPoint\r
+ );\r
\r
- //\r
- // Got the entry point from ImageEntryPoint and ImageStartAddress\r
- //\r
- Pe32Data = (VOID *) ((UINTN) ImageAddress);\r
- *EntryPoint = (VOID *) ((UINTN) ImageEntryPoint);\r
- } else {\r
- //\r
- // Retrieve the entry point from the TE image header\r
- //\r
- ImageAddress = (EFI_PHYSICAL_ADDRESS) (UINTN) TEImageHeader;\r
- *EntryPoint = (VOID *)((UINTN) TEImageHeader + sizeof (EFI_TE_IMAGE_HEADER) +\r
- TEImageHeader->AddressOfEntryPoint - TEImageHeader->StrippedSize);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
}\r
+\r
+ //\r
+ // Got the entry point from the loaded Pe32Data\r
+ //\r
+ Pe32Data = (VOID *) ((UINTN) ImageAddress);\r
+ *EntryPoint = ImageEntryPoint;\r
} else {\r
//\r
- // Retrieve the entry point from the PE/COFF image header\r
+ // Retrieve the entry point from the PE/COFF or TE image header\r
//\r
ImageAddress = (EFI_PHYSICAL_ADDRESS) (UINTN) Pe32Data;\r
- Status = PeCoffLoaderGetEntryPoint (Pe32Data, EntryPoint);\r
+ Status = PeCoffLoaderGetEntryPoint (Pe32Data, &EntryPointArg);\r
if (EFI_ERROR (Status)) {\r
- return EFI_NOT_FOUND;\r
+ return Status;\r
}\r
+ *EntryPoint = (EFI_PHYSICAL_ADDRESS) (UINTN) EntryPointArg;\r
}\r
-\r
- if (((EFI_TE_IMAGE_HEADER *) (UINTN) ImageAddress)->Signature == EFI_TE_IMAGE_HEADER_SIGNATURE) {\r
- TEImageHeader = (EFI_TE_IMAGE_HEADER *) (UINTN) ImageAddress;\r
- Machine = TEImageHeader->Machine;\r
- } else {\r
- Machine = PeCoffLoaderGetMachineType (Pe32Data);\r
- } \r
+ \r
+ Machine = PeCoffLoaderGetMachineType (Pe32Data);\r
\r
if (!EFI_IMAGE_MACHINE_TYPE_SUPPORTED (Machine)) {\r
return EFI_UNSUPPORTED; \r
}\r
\r
- //\r
- // Print debug message: Loading PEIM at 0x12345678 EntryPoint=0x12345688 Driver.efi\r
- //\r
- DEBUG ((EFI_D_INFO | EFI_D_LOAD, "Loading PEIM at 0x%08x EntryPoint=0x%08x ", (UINTN) ImageAddress, *EntryPoint));\r
+ if (ImageAddressArg != NULL) {\r
+ *ImageAddressArg = ImageAddress;\r
+ }\r
+\r
+ if (ImageSizeArg != NULL) {\r
+ *ImageSizeArg = ImageSize;\r
+ }\r
+ \r
DEBUG_CODE_BEGIN ();\r
- EFI_IMAGE_DATA_DIRECTORY *DirectoryEntry;\r
- EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *DebugEntry;\r
- UINTN DirCount;\r
- UINTN Index;\r
- UINTN Index1;\r
- BOOLEAN FileNameFound;\r
- CHAR8 *AsciiString;\r
- CHAR8 AsciiBuffer[512];\r
- VOID *CodeViewEntryPointer;\r
- INTN TEImageAdjust;\r
- EFI_IMAGE_DOS_HEADER *DosHeader;\r
- EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr;\r
- UINT32 NumberOfRvaAndSizes;\r
-\r
- Hdr.Pe32 = NULL;\r
- if (TEImageHeader == NULL) {\r
- DosHeader = (EFI_IMAGE_DOS_HEADER *)Pe32Data;\r
- if (DosHeader->e_magic == EFI_IMAGE_DOS_SIGNATURE) {\r
- //\r
- // DOS image header is present, so read the PE header after the DOS image header\r
- //\r
- Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)((UINTN)Pe32Data + (UINTN)((DosHeader->e_lfanew) & 0x0ffff));\r
- } else {\r
- //\r
- // DOS image header is not present, so PE header is at the image base\r
- //\r
- Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)Pe32Data;\r
- }\r
- }\r
+ CHAR8 *AsciiString;\r
+ CHAR8 AsciiBuffer[512];\r
+ INT32 Index;\r
+ INT32 Index1;\r
\r
//\r
- // Find the codeview info in the image and display the file name\r
- // being loaded.\r
+ // Print debug message: Loading PEIM at 0x12345678 EntryPoint=0x12345688 Driver.efi\r
+ //\r
+ if (Machine != IMAGE_FILE_MACHINE_IA64) {\r
+ DEBUG ((EFI_D_INFO | EFI_D_LOAD, "Loading PEIM at 0x%10p EntryPoint=0x%10p ", (VOID *)(UINTN)ImageAddress, (VOID *)(UINTN)*EntryPoint));\r
+ } else {\r
+ //\r
+ // For IPF Image, the real entry point should be print.\r
+ //\r
+ DEBUG ((EFI_D_INFO | EFI_D_LOAD, "Loading PEIM at 0x%10p EntryPoint=0x%10p ", (VOID *)(UINTN)ImageAddress, (VOID *)(UINTN)(*(UINT64 *)(UINTN)*EntryPoint)));\r
+ }\r
+ \r
//\r
- // Per the PE/COFF spec, you can't assume that a given data directory\r
- // is present in the image. You have to check the NumberOfRvaAndSizes in\r
- // the optional header to verify a desired directory entry is there.\r
+ // Print Module Name by PeImage PDB file name.\r
//\r
- DebugEntry = NULL;\r
- DirectoryEntry = NULL;\r
- NumberOfRvaAndSizes = 0;\r
- TEImageAdjust = 0;\r
+ AsciiString = PeCoffLoaderGetPdbPointer (Pe32Data);\r
\r
- if (TEImageHeader == NULL) {\r
- if (Hdr.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
- // \r
- // Use PE32 offset get Debug Directory Entry\r
- //\r
- NumberOfRvaAndSizes = Hdr.Pe32->OptionalHeader.NumberOfRvaAndSizes;\r
- DirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *)&(Hdr.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG]);\r
- DebugEntry = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *) ((UINTN) Pe32Data + DirectoryEntry->VirtualAddress);\r
- } else if (Hdr.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) {\r
- // \r
- // Use PE32+ offset get Debug Directory Entry\r
- //\r
- NumberOfRvaAndSizes = Hdr.Pe32Plus->OptionalHeader.NumberOfRvaAndSizes;\r
- DirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *)&(Hdr.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG]);\r
- DebugEntry = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *) ((UINTN) Pe32Data + DirectoryEntry->VirtualAddress);\r
- }\r
-\r
- if (NumberOfRvaAndSizes <= EFI_IMAGE_DIRECTORY_ENTRY_DEBUG) {\r
- DirectoryEntry = NULL;\r
- DebugEntry = NULL;\r
- }\r
- } else {\r
- if (TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress != 0) {\r
- DirectoryEntry = &TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG];\r
- TEImageAdjust = sizeof (EFI_TE_IMAGE_HEADER) - TEImageHeader->StrippedSize;\r
- DebugEntry = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *)((UINTN) TEImageHeader +\r
- TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress +\r
- TEImageAdjust);\r
+ if (AsciiString != NULL) {\r
+ for (Index = (INT32) AsciiStrLen (AsciiString) - 1; Index >= 0; Index --) {\r
+ if (AsciiString[Index] == '\\') {\r
+ break;\r
+ }\r
}\r
- }\r
\r
- if (DebugEntry != NULL && DirectoryEntry != NULL) {\r
- for (DirCount = 0; DirCount < DirectoryEntry->Size; DirCount += sizeof(EFI_IMAGE_DEBUG_DIRECTORY_ENTRY), DebugEntry++) {\r
- if (DebugEntry->Type == EFI_IMAGE_DEBUG_TYPE_CODEVIEW) {\r
- if (DebugEntry->SizeOfData > 0) {\r
- CodeViewEntryPointer = (VOID *) ((UINTN) DebugEntry->RVA + (UINTN) ImageAddress + (UINTN)TEImageAdjust);\r
- switch (* (UINT32 *) CodeViewEntryPointer) {\r
- case CODEVIEW_SIGNATURE_NB10:\r
- AsciiString = (CHAR8 *)CodeViewEntryPointer + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY);\r
- break;\r
-\r
- case CODEVIEW_SIGNATURE_RSDS:\r
- AsciiString = (CHAR8 *)CodeViewEntryPointer + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_RSDS_ENTRY);\r
- break;\r
-\r
- default:\r
- AsciiString = NULL;\r
- break;\r
- }\r
- if (AsciiString != NULL) {\r
- FileNameFound = FALSE;\r
- for (Index = 0, Index1 = 0; AsciiString[Index] != '\0'; Index++) {\r
- if (AsciiString[Index] == '\\') {\r
- Index1 = Index;\r
- FileNameFound = TRUE;\r
- }\r
- }\r
-\r
- if (FileNameFound) {\r
- for (Index = Index1 + 1; AsciiString[Index] != '.'; Index++) {\r
- AsciiBuffer[Index - (Index1 + 1)] = AsciiString[Index];\r
- }\r
- AsciiBuffer[Index - (Index1 + 1)] = 0;\r
- DEBUG ((EFI_D_INFO | EFI_D_LOAD, "%a.efi", AsciiBuffer));\r
- break;\r
- }\r
- }\r
- }\r
+ if (Index != 0) {\r
+ for (Index1 = 0; AsciiString[Index + 1 + Index1] != '.'; Index1 ++) {\r
+ AsciiBuffer [Index1] = AsciiString[Index + 1 + Index1];\r
}\r
+ AsciiBuffer [Index1] = '\0';\r
+ DEBUG ((EFI_D_INFO | EFI_D_LOAD, "%a.efi", AsciiBuffer));\r
}\r
}\r
+\r
DEBUG_CODE_END ();\r
\r
DEBUG ((EFI_D_INFO | EFI_D_LOAD, "\n"));\r
\r
return EFI_SUCCESS;\r
+\r
}\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PeiLoadImageLoadImageWrapper (\r
+ IN CONST EFI_PEI_LOAD_FILE_PPI *This,\r
+ IN EFI_PEI_FILE_HANDLE FileHandle,\r
+ OUT EFI_PHYSICAL_ADDRESS *ImageAddressArg, OPTIONAL\r
+ OUT UINT64 *ImageSizeArg, OPTIONAL\r
+ OUT EFI_PHYSICAL_ADDRESS *EntryPoint,\r
+ OUT UINT32 *AuthenticationState\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ The wrapper function of PeiLoadImageLoadImage().\r
+\r
+Arguments:\r
+\r
+ This - Pointer to EFI_PEI_LOAD_FILE_PPI.\r
+ PeiServices - The PEI core services table.\r
+ FileHandle - Pointer to the FFS file header of the image.\r
+ ImageAddressArg - Pointer to PE/TE image.\r
+ ImageSizeArg - Size of PE/TE image.\r
+ EntryPoint - Pointer to entry point of specified image file for output.\r
+ AuthenticationState - Pointer to attestation authentication state of image.\r
+\r
+Returns:\r
+\r
+ EFI_STATUS.\r
+ \r
+--*/ \r
+{\r
+ return PeiLoadImageLoadImage (\r
+ GetPeiServicesTablePointer (),\r
+ FileHandle,\r
+ ImageAddressArg,\r
+ ImageSizeArg,\r
+ EntryPoint,\r
+ AuthenticationState\r
+ );\r
+}\r
+\r
+EFI_STATUS\r
+PeiLoadImage (\r
+ IN EFI_PEI_SERVICES **PeiServices,\r
+ IN EFI_PEI_FILE_HANDLE FileHandle,\r
+ OUT EFI_PHYSICAL_ADDRESS *EntryPoint,\r
+ OUT UINT32 *AuthenticationState\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Routine for load image file.\r
+\r
+Arguments:\r
+\r
+ PeiServices - The PEI core services table.\r
+ FileHandle - Pointer to the FFS file header of the image.\r
+ EntryPoint - Pointer to entry point of specified image file for output.\r
+ AuthenticationState - Pointer to attestation authentication state of image.\r
+\r
+Returns:\r
+\r
+ Status - EFI_SUCCESS - Image is successfully loaded.\r
+ EFI_NOT_FOUND - Fail to locate necessary PPI\r
+ Others - Fail to load file.\r
+ \r
+--*/ \r
+{\r
+ EFI_STATUS PpiStatus;\r
+ EFI_STATUS Status;\r
+ UINTN Index;\r
+ EFI_PEI_LOAD_FILE_PPI *LoadFile;\r
+ EFI_PHYSICAL_ADDRESS ImageAddress;\r
+ UINT64 ImageSize;\r
+\r
+ //\r
+ // If any instances of PEI_LOAD_FILE_PPI are installed, they are called.\r
+ // one at a time, until one reports EFI_SUCCESS.\r
+ //\r
+ Index = 0;\r
+ do {\r
+ PpiStatus = PeiServicesLocatePpi (\r
+ &gEfiPeiLoadFilePpiGuid,\r
+ Index,\r
+ NULL,\r
+ (VOID **)&LoadFile\r
+ );\r
+ if (!EFI_ERROR (PpiStatus)) {\r
+ Status = LoadFile->LoadFile (\r
+ LoadFile, \r
+ FileHandle, \r
+ &ImageAddress, \r
+ &ImageSize,\r
+ EntryPoint,\r
+ AuthenticationState\r
+ );\r
+ if (!EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+ }\r
+ Index++;\r
+ } while (!EFI_ERROR (PpiStatus));\r
+\r
+ //\r
+ // If no instances reports EFI_SUCCESS, then build-in support for\r
+ // the PE32+/TE XIP image format is used.\r
+ //\r
+ Status = PeiLoadImageLoadImage (\r
+ PeiServices, \r
+ FileHandle, \r
+ NULL, \r
+ NULL, \r
+ EntryPoint, \r
+ AuthenticationState\r
+ );\r
+ return Status;\r
+}\r
+\r
+\r
+VOID\r
+InitializeImageServices (\r
+ IN PEI_CORE_INSTANCE *PrivateData,\r
+ IN PEI_CORE_INSTANCE *OldCoreData\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Install Pei Load File PPI.\r
+\r
+Arguments:\r
+\r
+ PrivateData - Pointer to PEI_CORE_INSTANCE.\r
+ OldCoreData - Pointer to PEI_CORE_INSTANCE.\r
+\r
+Returns:\r
+\r
+ NONE.\r
+ \r
+--*/ \r
+{\r
+ if (OldCoreData == NULL) {\r
+ //\r
+ // The first time we are XIP (running from FLASH). We need to remember the\r
+ // FLASH address so we can reinstall the memory version that runs faster\r
+ //\r
+ PrivateData->XipLoadFile = &gPpiLoadFilePpiList;\r
+ PeiServicesInstallPpi (PrivateData->XipLoadFile);\r
+ } else {\r
+ //\r
+ // 2nd time we are running from memory so replace the XIP version with the \r
+ // new memory version. \r
+ //\r
+ PeiServicesReInstallPpi (PrivateData->XipLoadFile, &gPpiLoadFilePpiList); \r
+ }\r
+}\r
+\r
+\r
+\r