)\r
{\r
UINT8 StatusRegister;\r
-\r
-//#ifdef EFI_DEBUG\r
-\r
UINT8 ErrorRegister;\r
\r
-//#endif\r
-\r
StatusRegister = ReadPortB (\r
AtapiScsiPrivate->PciIo,\r
AtapiScsiPrivate->IoPort->Reg.Status\r
);\r
- DEBUG_CODE (\r
+ \r
+ DEBUG_CODE_BEGIN ();\r
\r
if (StatusRegister & DWF) {\r
- DEBUG (\r
- (EFI_D_BLKIO,\r
- "AtapiPassThruCheckErrorStatus()-- %02x : Error : Write Fault\n",\r
- StatusRegister)\r
- );\r
- }\r
+ DEBUG (\r
+ (EFI_D_BLKIO,\r
+ "AtapiPassThruCheckErrorStatus()-- %02x : Error : Write Fault\n",\r
+ StatusRegister)\r
+ );\r
+ }\r
\r
- if (StatusRegister & CORR) {\r
- DEBUG (\r
- (EFI_D_BLKIO,\r
- "AtapiPassThruCheckErrorStatus()-- %02x : Error : Corrected Data\n",\r
- StatusRegister)\r
- );\r
- }\r
+ if (StatusRegister & CORR) {\r
+ DEBUG (\r
+ (EFI_D_BLKIO,\r
+ "AtapiPassThruCheckErrorStatus()-- %02x : Error : Corrected Data\n",\r
+ StatusRegister)\r
+ );\r
+ }\r
\r
- if (StatusRegister & ERR) {\r
- ErrorRegister = ReadPortB (AtapiScsiPrivate->PciIo, AtapiScsiPrivate->IoPort->Reg1.Error);\r
+ if (StatusRegister & ERR) {\r
+ ErrorRegister = ReadPortB (AtapiScsiPrivate->PciIo, AtapiScsiPrivate->IoPort->Reg1.Error);\r
+ \r
\r
- if (ErrorRegister & BBK_ERR) {\r
- DEBUG (\r
- (EFI_D_BLKIO,\r
- "AtapiPassThruCheckErrorStatus()-- %02x : Error : Bad Block Detected\n",\r
- ErrorRegister)\r
- );\r
- }\r
+ if (ErrorRegister & BBK_ERR) {\r
+ DEBUG (\r
+ (EFI_D_BLKIO,\r
+ "AtapiPassThruCheckErrorStatus()-- %02x : Error : Bad Block Detected\n",\r
+ ErrorRegister)\r
+ );\r
+ }\r
\r
- if (ErrorRegister & UNC_ERR) {\r
- DEBUG (\r
- (EFI_D_BLKIO,\r
- "AtapiPassThruCheckErrorStatus()-- %02x : Error : Uncorrectable Data\n",\r
- ErrorRegister)\r
- );\r
- }\r
+ if (ErrorRegister & UNC_ERR) {\r
+ DEBUG (\r
+ (EFI_D_BLKIO,\r
+ "AtapiPassThruCheckErrorStatus()-- %02x : Error : Uncorrectable Data\n",\r
+ ErrorRegister)\r
+ );\r
+ }\r
\r
- if (ErrorRegister & MC_ERR) {\r
- DEBUG (\r
- (EFI_D_BLKIO,\r
- "AtapiPassThruCheckErrorStatus()-- %02x : Error : Media Change\n",\r
- ErrorRegister)\r
- );\r
- }\r
+ if (ErrorRegister & MC_ERR) {\r
+ DEBUG (\r
+ (EFI_D_BLKIO,\r
+ "AtapiPassThruCheckErrorStatus()-- %02x : Error : Media Change\n",\r
+ ErrorRegister)\r
+ );\r
+ }\r
\r
- if (ErrorRegister & ABRT_ERR) {\r
- DEBUG (\r
- (EFI_D_BLKIO,\r
- "AtapiPassThruCheckErrorStatus()-- %02x : Error : Abort\n",\r
- ErrorRegister)\r
- );\r
- }\r
+ if (ErrorRegister & ABRT_ERR) {\r
+ DEBUG (\r
+ (EFI_D_BLKIO,\r
+ "AtapiPassThruCheckErrorStatus()-- %02x : Error : Abort\n",\r
+ ErrorRegister)\r
+ );\r
+ }\r
\r
- if (ErrorRegister & TK0NF_ERR) {\r
- DEBUG (\r
- (EFI_D_BLKIO,\r
- "AtapiPassThruCheckErrorStatus()-- %02x : Error : Track 0 Not Found\n",\r
- ErrorRegister)\r
- );\r
- }\r
+ if (ErrorRegister & TK0NF_ERR) {\r
+ DEBUG (\r
+ (EFI_D_BLKIO,\r
+ "AtapiPassThruCheckErrorStatus()-- %02x : Error : Track 0 Not Found\n",\r
+ ErrorRegister)\r
+ );\r
+ }\r
\r
- if (ErrorRegister & AMNF_ERR) {\r
- DEBUG (\r
- (EFI_D_BLKIO,\r
- "AtapiPassThruCheckErrorStatus()-- %02x : Error : Address Mark Not Found\n",\r
- ErrorRegister)\r
- );\r
- }\r
+ if (ErrorRegister & AMNF_ERR) {\r
+ DEBUG (\r
+ (EFI_D_BLKIO,\r
+ "AtapiPassThruCheckErrorStatus()-- %02x : Error : Address Mark Not Found\n",\r
+ ErrorRegister)\r
+ );\r
+ }\r
+ }\r
\r
- }\r
- );\r
+ DEBUG_CODE_END ();\r
\r
if ((StatusRegister & (ERR | DWF | CORR)) == 0) {\r
-\r
return EFI_SUCCESS;\r
}\r
\r
+ \r
return EFI_DEVICE_ERROR;\r
-\r
-}\r
+}
\ No newline at end of file
\r
StatusRegister = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Status);\r
\r
- DEBUG_CODE (\r
+ DEBUG_CODE_BEGIN ();\r
\r
if (StatusRegister & DWF) {\r
- DEBUG (\r
- (EFI_D_BLKIO,\r
- "CheckErrorStatus()-- %02x : Error : Write Fault\n",\r
- StatusRegister)\r
- );\r
- }\r
+ DEBUG (\r
+ (EFI_D_BLKIO,\r
+ "CheckErrorStatus()-- %02x : Error : Write Fault\n",\r
+ StatusRegister)\r
+ );\r
+ }\r
\r
- if (StatusRegister & CORR) {\r
- DEBUG (\r
- (EFI_D_BLKIO,\r
- "CheckErrorStatus()-- %02x : Error : Corrected Data\n",\r
- StatusRegister)\r
- );\r
- }\r
+ if (StatusRegister & CORR) {\r
+ DEBUG (\r
+ (EFI_D_BLKIO,\r
+ "CheckErrorStatus()-- %02x : Error : Corrected Data\n",\r
+ StatusRegister)\r
+ );\r
+ }\r
\r
- if (StatusRegister & ERR) {\r
- ErrorRegister = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Error);\r
+ if (StatusRegister & ERR) {\r
+ ErrorRegister = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Error);\r
\r
- if (ErrorRegister & BBK_ERR) {\r
- DEBUG (\r
- (EFI_D_BLKIO,\r
- "CheckErrorStatus()-- %02x : Error : Bad Block Detected\n",\r
- ErrorRegister)\r
- );\r
- }\r
+ if (ErrorRegister & BBK_ERR) {\r
+ DEBUG (\r
+ (EFI_D_BLKIO,\r
+ "CheckErrorStatus()-- %02x : Error : Bad Block Detected\n",\r
+ ErrorRegister)\r
+ );\r
+ }\r
\r
- if (ErrorRegister & UNC_ERR) {\r
- DEBUG (\r
- (EFI_D_BLKIO,\r
- "CheckErrorStatus()-- %02x : Error : Uncorrectable Data\n",\r
- ErrorRegister)\r
- );\r
- }\r
+ if (ErrorRegister & UNC_ERR) {\r
+ DEBUG (\r
+ (EFI_D_BLKIO,\r
+ "CheckErrorStatus()-- %02x : Error : Uncorrectable Data\n",\r
+ ErrorRegister)\r
+ );\r
+ }\r
\r
- if (ErrorRegister & MC_ERR) {\r
- DEBUG (\r
- (EFI_D_BLKIO,\r
- "CheckErrorStatus()-- %02x : Error : Media Change\n",\r
- ErrorRegister)\r
- );\r
- }\r
+ if (ErrorRegister & MC_ERR) {\r
+ DEBUG (\r
+ (EFI_D_BLKIO,\r
+ "CheckErrorStatus()-- %02x : Error : Media Change\n",\r
+ ErrorRegister)\r
+ );\r
+ }\r
\r
- if (ErrorRegister & ABRT_ERR) {\r
- DEBUG (\r
- (EFI_D_BLKIO,\r
- "CheckErrorStatus()-- %02x : Error : Abort\n",\r
- ErrorRegister)\r
- );\r
- }\r
+ if (ErrorRegister & ABRT_ERR) {\r
+ DEBUG (\r
+ (EFI_D_BLKIO,\r
+ "CheckErrorStatus()-- %02x : Error : Abort\n",\r
+ ErrorRegister)\r
+ );\r
+ }\r
\r
- if (ErrorRegister & TK0NF_ERR) {\r
- DEBUG (\r
- (EFI_D_BLKIO,\r
- "CheckErrorStatus()-- %02x : Error : Track 0 Not Found\n",\r
- ErrorRegister)\r
- );\r
- }\r
+ if (ErrorRegister & TK0NF_ERR) {\r
+ DEBUG (\r
+ (EFI_D_BLKIO,\r
+ "CheckErrorStatus()-- %02x : Error : Track 0 Not Found\n",\r
+ ErrorRegister)\r
+ );\r
+ }\r
\r
- if (ErrorRegister & AMNF_ERR) {\r
- DEBUG (\r
- (EFI_D_BLKIO,\r
- "CheckErrorStatus()-- %02x : Error : Address Mark Not Found\n",\r
- ErrorRegister)\r
- );\r
- }\r
+ if (ErrorRegister & AMNF_ERR) {\r
+ DEBUG (\r
+ (EFI_D_BLKIO,\r
+ "CheckErrorStatus()-- %02x : Error : Address Mark Not Found\n",\r
+ ErrorRegister)\r
+ );\r
+ }\r
+ }\r
\r
- }\r
- );\r
+ DEBUG_CODE_END ();\r
\r
if ((StatusRegister & (ERR | DWF | CORR)) == 0) {\r
return EFI_SUCCESS;\r
-<?xml version="1.0" encoding="UTF-8"?>\r
-<!--Copyright (c) 2006, Intel Corporation
-All rights reserved. This program and the accompanying materials
-are licensed and made available under the terms and conditions of the BSD License
-which accompanies this distribution. The full text of the license may be found at
-http://opensource.org/licenses/bsd-license.php
-
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.-->\r
-<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0">\r
+<?xml version="1.0" encoding="UTF-8"?>\r
+<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">\r
<MsaHeader>\r
<ModuleName>PciBus</ModuleName>\r
<ModuleType>DXE_DRIVER</ModuleType>\r
<GuidValue>93B80004-9FB3-11d4-9A3A-0090273FC14D</GuidValue>\r
<Version>1.0</Version>\r
<Abstract>Component description file for PciBus module.</Abstract>\r
- <Description>\r
- PCI bus driver. This module will probe all PCI devices and allocate MMIO and IO\r
- space for these devices.\r
- </Description>\r
+ <Description>PCI bus driver. This module will probe all PCI devices and allocate MMIO and IO
+ space for these devices.</Description>\r
<Copyright>Copyright (c) 2006, Intel Corporation</Copyright>\r
<License>All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
<LibraryClass Usage="ALWAYS_CONSUMED">\r
<Keyword>DevicePathLib</Keyword>\r
</LibraryClass>\r
+ <LibraryClass Usage="ALWAYS_CONSUMED">\r
+ <Keyword>PeCoffGetEntryPointLib</Keyword>\r
+ </LibraryClass>\r
</LibraryClassDefinitions>\r
<SourceFiles>\r
<Filename>PciBus.h</Filename>\r
// TODO: EFI_SUCCESS - add return value to function comment\r
{\r
EFI_STATUS Status;\r
- EFI_IMAGE_DOS_HEADER *DosHdr;\r
- EFI_IMAGE_NT_HEADERS *PeHdr;\r
EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;\r
PCI_DRIVER_OVERRIDE_LIST *Node;\r
EFI_DRIVER_OS_HANDOFF_HEADER *DriverOsHandoffHeader;\r
\r
PciIoDevice->BusOverride = TRUE;\r
\r
- DosHdr = (EFI_IMAGE_DOS_HEADER *) LoadedImage->ImageBase;\r
- if (DosHdr->e_magic != EFI_IMAGE_DOS_SIGNATURE) {\r
- return EFI_SUCCESS;\r
- }\r
-\r
- PeHdr = (EFI_IMAGE_NT_HEADERS *) ((UINTN) LoadedImage->ImageBase + DosHdr->e_lfanew);\r
-\r
- if (PeHdr->FileHeader.Machine != EFI_IMAGE_MACHINE_EBC) {\r
+ if (PeCoffLoaderGetMachineType ((VOID *)(UINTN)LoadedImage->ImageBase) != EFI_IMAGE_MACHINE_EBC) {\r
return EFI_SUCCESS;\r
}\r
\r
//\r
// Display Architectural protocols that were not loaded if this is DEBUG build\r
//\r
- DEBUG_CODE (\r
+ DEBUG_CODE_BEGIN ();\r
CoreDisplayMissingArchProtocols ();\r
- );\r
+ DEBUG_CODE_END ();\r
\r
//\r
// Assert if the Architectural Protocols are not present.\r
// Display any drivers that were not dispatched because dependency expression\r
// evaluated to false if this is a debug build\r
//\r
- DEBUG_CODE (\r
+ DEBUG_CODE_BEGIN ();\r
CoreDisplayDiscoveredNotDispatched ();\r
- );\r
+ DEBUG_CODE_END ();\r
\r
//\r
// Transfer control to the BDS Architectural Protocol\r
return Status;\r
}\r
\r
+ if (!EFI_IMAGE_MACHINE_TYPE_SUPPORTED (Image->ImageContext.Machine)) {\r
+ //\r
+ // The PE/COFF loader can support loading image types that can be executed. \r
+ // If we loaded an image type that we can not execute return EFI_UNSUPORTED. \r
+ //\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+\r
+\r
//\r
// Allocate memory of the correct memory type aligned on the required image boundry\r
//\r
// Print the load address and the PDB file name if it is available\r
//\r
\r
- DEBUG_CODE (\r
- {\r
+ DEBUG_CODE_BEGIN ();\r
+ \r
UINTN Index;\r
UINTN StartIndex;\r
CHAR8 EfiFileName[256];\r
DEBUG ((EFI_D_INFO | EFI_D_LOAD, "%a", EfiFileName)); // &Image->ImageContext.PdbPointer[StartIndex]));\r
}\r
DEBUG ((EFI_D_INFO | EFI_D_LOAD, "\n"));\r
- }\r
- );\r
+ \r
+ DEBUG_CODE_END ();\r
\r
return EFI_SUCCESS;\r
\r
//\r
PERF_START (ImageHandle, START_IMAGE_TOK, NULL, 0);\r
\r
- if (sizeof (UINTN) == 4 && Image->Machine == EFI_IMAGE_MACHINE_X64) {\r
- return EFI_UNSUPPORTED;\r
- } else if (sizeof (UINTN) == 8 && Image->Machine == EFI_IMAGE_MACHINE_IA32) {\r
- return EFI_UNSUPPORTED;\r
- } else {\r
- //\r
- // For orther possible cases\r
- //\r
- }\r
\r
//\r
// Push the current start image context, and\r
// link the current image to the head. This is the\r
// only image that can call Exit()\r
//\r
- HandleDatabaseKey = CoreGetHandleDatabaseKey();\r
+ HandleDatabaseKey = CoreGetHandleDatabaseKey ();\r
LastImage = mCurrentImage;\r
mCurrentImage = Image;\r
Image->Tpl = gEfiCurrentTpl;\r
// This make the user aware and check if the driver image have already released\r
// all the resource in this situation.\r
//\r
- DEBUG_CODE (\r
+ DEBUG_CODE_BEGIN ();\r
if (EFI_ERROR (Image->Status)) {\r
DEBUG ((EFI_D_ERROR, "Error: Image at %08X start failed: %x\n", Image->Info.ImageBase, Image->Status));\r
}\r
- );\r
+ DEBUG_CODE_END ();\r
\r
//\r
// If the image returns, exit it through Exit()\r
//\r
// Handle the image's returned ExitData\r
//\r
- DEBUG_CODE (\r
+ DEBUG_CODE_BEGIN ();\r
if (Image->ExitDataSize != 0 || Image->ExitData != NULL) {\r
\r
DEBUG (\r
}\r
DEBUG ((EFI_D_LOAD, "\n"));\r
}\r
- );\r
+ DEBUG_CODE_END ();\r
\r
//\r
// Return the exit data to the caller\r
//\r
if (Status == EFI_SUCCESS) {\r
\r
- DEBUG_CODE (\r
+ DEBUG_CODE_BEGIN ();\r
\r
//\r
// Fill list of found Peims for later list of those not installed\r
sizeof (EFI_GUID)\r
);\r
\r
- );\r
+ DEBUG_CODE_END ();\r
\r
if (!Dispatched (\r
DispatchData->CurrentPeim,\r
DispatchData->CurrentFvAddress = DefaultFvAddress;\r
}\r
\r
- DEBUG_CODE (\r
+ DEBUG_CODE_BEGIN ();\r
//\r
// Debug data for uninstalled Peim list\r
//\r
DebugFoundPeimPoint++;\r
DebugNotDispatchedBitmap >>= 1;\r
}\r
+ \r
+ DEBUG_CODE_END ();\r
\r
- );\r
-\r
- return EFI_NOT_FOUND;\r
+ return EFI_NOT_FOUND;\r
}\r
\r
VOID\r
// Only check this parameter in debug mode\r
//\r
\r
- DEBUG_CODE ( \r
+ DEBUG_CODE_BEGIN (); \r
if (HobList == NULL) {\r
return EFI_INVALID_PARAMETER;\r
}\r
- );\r
+ DEBUG_CODE_END ();\r
\r
PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS(PeiServices);\r
\r
\r
#include <PeiMain.h>\r
\r
+\r
+\r
EFI_STATUS\r
PeiLoadImage (\r
IN EFI_PEI_SERVICES **PeiServices,\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 ", Pe32Data, *EntryPoint));\r
- DEBUG_CODE (\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_NT_HEADERS *PeHeader;\r
+ DEBUG_CODE_BEGIN ();\r
+ PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;\r
+ UINTN Index;\r
+ CHAR8 *PdbStr;\r
+ CHAR8 AsciiBuffer[512];\r
\r
- //\r
- // Pe32Data is NULL when load TE image \r
- // \r
- PeHeader = 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
- PeHeader = (EFI_IMAGE_NT_HEADERS *) ((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
- PeHeader = (EFI_IMAGE_NT_HEADERS *) Pe32Data;\r
- }\r
- }\r
\r
- //\r
- // Find the codeview info in the image and display the file name\r
- // being loaded.\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
- //\r
- DebugEntry = NULL;\r
- DirectoryEntry = NULL;\r
- TEImageAdjust = 0;\r
- if (TEImageHeader == NULL) {\r
- if (PeHeader->OptionalHeader.NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_DEBUG) {\r
- DirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *) &(PeHeader->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG]);\r
- DebugEntry = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *) ((UINTN) ImageAddress + DirectoryEntry->VirtualAddress);\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
- }\r
- }\r
+ ZeroMem (&ImageContext, sizeof (ImageContext));\r
+ ImageContext.Handle = Pe32Data;\r
+ ImageContext.ImageRead = PeCoffLoaderImageReadFromMemory;\r
\r
- if (DebugEntry != NULL && DirectoryEntry != NULL) {\r
- for (DirCount = 0; DirCount < DirectoryEntry->Size; DirCount++, 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
+ PeCoffLoaderGetImageInfo (&ImageContext);\r
+ \r
+ if (ImageContext.PdbPointer != NULL) {\r
+ //\r
+ // Copy PDB pointer to AsciiBuffer and replace .PDB with .EFI\r
+ //\r
+ PdbStr = ImageContext.PdbPointer;\r
+ for (Index = 0; PdbStr != 0; Index++, PdbStr++) {\r
+ AsciiBuffer[Index] = *PdbStr;\r
+ if (*PdbStr == '.') {\r
+ AsciiBuffer[Index] = '\0'; \r
}\r
}\r
+ \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
SizeOfCarHeap = (UINT64) PeiStartupDescriptor->SizeOfCacheAsRam;\r
SizeOfCarHeap = RShiftU64 (SizeOfCarHeap, 1);\r
\r
- DEBUG_CODE (\r
- PrivateData->SizeOfCacheAsRam = PeiStartupDescriptor->SizeOfCacheAsRam;\r
- PrivateData->MaxTopOfCarHeap = (VOID *) ((UINTN) PrivateData->BottomOfCarHeap + (UINTN) SizeOfCarHeap);\r
- );\r
+ DEBUG_CODE_BEGIN ();\r
+ PrivateData->SizeOfCacheAsRam = PeiStartupDescriptor->SizeOfCacheAsRam;\r
+ PrivateData->MaxTopOfCarHeap = (VOID *) ((UINTN) PrivateData->BottomOfCarHeap + (UINTN) SizeOfCarHeap);\r
+ DEBUG_CODE_END ();\r
\r
PrivateData->HobList.Raw = PrivateData->BottomOfCarHeap;\r
\r
-<?xml version="1.0" encoding="UTF-8"?>\r
-<!--Copyright (c) 2006, Intel Corporation
-All rights reserved. This program and the accompanying materials
-are licensed and made available under the terms and conditions of the BSD License
-which accompanies this distribution. The full text of the license may be found at
-http://opensource.org/licenses/bsd-license.php
-
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.-->\r
-<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0">\r
+<?xml version="1.0" encoding="UTF-8"?>\r
+<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">\r
<MsaHeader>\r
<ModuleName>PeiMain</ModuleName>\r
<ModuleType>PEI_CORE</ModuleType>\r
<LibraryClass Usage="ALWAYS_CONSUMED">\r
<Keyword>TimerLib</Keyword>\r
</LibraryClass>\r
+ <LibraryClass Usage="SOMETIMES_CONSUMED">\r
+ <Keyword>PeCoffLib</Keyword>\r
+ </LibraryClass>\r
</LibraryClassDefinitions>\r
<SourceFiles>\r
<Filename>PeiMain.h</Filename>\r
//\r
// The following code dumps out interesting cache as RAM usage information\r
// so we can keep tabs on how the cache as RAM is being utilized. The\r
- // DEBUG_CODE macro is used to prevent this code from being compiled\r
+ // DEBUG_CODE_BEGIN macro is used to prevent this code from being compiled\r
// on a debug build.\r
//\r
- DEBUG_CODE (\r
+ DEBUG_CODE_BEGIN ();\r
UINTN *StackPointer;\r
UINTN StackValue;\r
\r
((UINTN) OldCoreData->HobList.HandoffInformationTable->EfiFreeMemoryBottom -\r
(UINTN) OldCoreData->HobList.Raw)\r
));\r
- );\r
+ DEBUG_CODE_END ();\r
\r
//\r
// Alert any listeners that there is permanent memory available\r
<Instance ModuleGuid="bda39d3a-451b-4350-8266-81ab10fa0523" PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>
<Instance ModuleGuid="FC120ED3-40E1-46dc-8C9C-AAE3CA139ACF" PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>
<Instance ModuleGuid="be490364-73d2-420d-950e-f6450ca75dfb" PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>
+ <Instance ModuleGuid="556f5d10-7309-4af4-b80a-8196bd60946f" PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>
</Libraries>
<PcdBuildDefinition>
<PcdData ItemType="FIXED_AT_BUILD">
<Instance ModuleGuid="b1ee6c28-54aa-4d17-b705-3e28ccb27b2e" PackageGuid="B6EC423C-21D2-490D-85C6-DD5864EAA674"/>
<Instance ModuleGuid="331deb15-454b-48d8-9b74-70d01f3f3556" PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>
<Instance ModuleGuid="bda39d3a-451b-4350-8266-81ab10fa0523" PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>
+ <Instance ModuleGuid="556f5d10-7309-4af4-b80a-8196bd60946f" PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>
<Instance ModuleGuid="3ddc3b12-99ea-4364-b315-6310a2050be5" PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>
</Libraries>
<PcdBuildDefinition>
<Instance ModuleGuid="27d67720-ea68-48ae-93da-a3a074c90e30" PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>
<Instance ModuleGuid="4674739d-3195-4fb2-8094-ac1d22d00194" PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>
<Instance ModuleGuid="91c1677a-e57f-4191-8b8e-eb7711a716e0" PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>
- </Libraries>
+ <Instance ModuleGuid="be490364-73d2-420d-950e-f6450ca75dfb" PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>
+ </Libraries>
<PcdBuildDefinition>
<PcdData ItemType="FIXED_AT_BUILD">
<C_Name>PcdMaximumUnicodeStringLength</C_Name>
<Instance ModuleGuid="bda39d3a-451b-4350-8266-81ab10fa0523" PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>
<Instance ModuleGuid="FC120ED3-40E1-46dc-8C9C-AAE3CA139ACF" PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>
<Instance ModuleGuid="be490364-73d2-420d-950e-f6450ca75dfb" PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>
+ <Instance ModuleGuid="556f5d10-7309-4af4-b80a-8196bd60946f" PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>
</Libraries>
<PcdBuildDefinition>
<PcdData ItemType="FIXED_AT_BUILD">
<Instance ModuleGuid="331deb15-454b-48d8-9b74-70d01f3f3556" PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>
<Instance ModuleGuid="bda39d3a-451b-4350-8266-81ab10fa0523" PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>
<Instance ModuleGuid="3ddc3b12-99ea-4364-b315-6310a2050be5" PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>
+ <Instance ModuleGuid="556f5d10-7309-4af4-b80a-8196bd60946f" PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>
</Libraries>
<PcdBuildDefinition>
<PcdData ItemType="FIXED_AT_BUILD">
<Instance ModuleGuid="27d67720-ea68-48ae-93da-a3a074c90e30" PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>
<Instance ModuleGuid="4674739d-3195-4fb2-8094-ac1d22d00194" PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>
<Instance ModuleGuid="91c1677a-e57f-4191-8b8e-eb7711a716e0" PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>
+ <Instance ModuleGuid="be490364-73d2-420d-950e-f6450ca75dfb" PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>
</Libraries>
<PcdBuildDefinition>
<PcdData ItemType="FIXED_AT_BUILD">
<Instance ModuleGuid="bda39d3a-451b-4350-8266-81ab10fa0523" PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>
<Instance ModuleGuid="FC120ED3-40E1-46dc-8C9C-AAE3CA139ACF" PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>
<Instance ModuleGuid="be490364-73d2-420d-950e-f6450ca75dfb" PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>
+ <Instance ModuleGuid="556f5d10-7309-4af4-b80a-8196bd60946f" PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>
</Libraries>
<PcdBuildDefinition>
<PcdData ItemType="FIXED_AT_BUILD">
<Instance ModuleGuid="bda39d3a-451b-4350-8266-81ab10fa0523" PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>
<Instance ModuleGuid="3ddc3b12-99ea-4364-b315-6310a2050be5" PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>
<Instance ModuleGuid="61999c3c-72a5-4506-a4ff-4271d18a1d14" PackageGuid="B6EC423C-21D2-490D-85C6-DD5864EAA674"/>
+ <Instance ModuleGuid="556f5d10-7309-4af4-b80a-8196bd60946f" PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>
</Libraries>
<PcdBuildDefinition>
<PcdData ItemType="FIXED_AT_BUILD">
<Instance ModuleGuid="27d67720-ea68-48ae-93da-a3a074c90e30" PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>
<Instance ModuleGuid="4674739d-3195-4fb2-8094-ac1d22d00194" PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>
<Instance ModuleGuid="91c1677a-e57f-4191-8b8e-eb7711a716e0" PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>
+ <Instance ModuleGuid="be490364-73d2-420d-950e-f6450ca75dfb" PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>
</Libraries>
<PcdBuildDefinition>
<PcdData ItemType="FIXED_AT_BUILD">
<Instance ModuleGuid="bda39d3a-451b-4350-8266-81ab10fa0523" PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>
<Instance ModuleGuid="FC120ED3-40E1-46dc-8C9C-AAE3CA139ACF" PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>
<Instance ModuleGuid="be490364-73d2-420d-950e-f6450ca75dfb" PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>
+ <Instance ModuleGuid="556f5d10-7309-4af4-b80a-8196bd60946f" PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>
</Libraries>
<PcdBuildDefinition>
<PcdData ItemType="FIXED_AT_BUILD">
<Instance ModuleGuid="27d67720-ea68-48ae-93da-a3a074c90e30" PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>
<Instance ModuleGuid="4674739d-3195-4fb2-8094-ac1d22d00194" PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>
<Instance ModuleGuid="91c1677a-e57f-4191-8b8e-eb7711a716e0" PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>
+ <Instance ModuleGuid="be490364-73d2-420d-950e-f6450ca75dfb" PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>
</Libraries>
<PcdBuildDefinition>
<PcdData ItemType="FIXED_AT_BUILD">
goto Error;\r
}\r
\r
- DEBUG_CODE (\r
+ DEBUG_CODE_BEGIN ();\r
GraphicsConsoleConOutOutputString (&Private->SimpleTextOutput, (CHAR16 *)L"Graphics Console Started\n\r");\r
- );\r
+ DEBUG_CODE_END ();\r
\r
//\r
// Install protocol interfaces for the Graphics Console device.\r
{\r
static BOOLEAN InHandler = FALSE;\r
\r
- DEBUG_CODE (\r
+ DEBUG_CODE_BEGIN ();\r
if (InHandler) {\r
EfiDebugPrint (EFI_D_GENERIC, "ERROR: Re-entered debugger!\n"\r
" ExceptionType == %X\n"\r
Context.SystemContextIpf->CrIpsr,\r
InHandler);\r
}\r
- )\r
+ DEBUG_CODE_END ();\r
+\r
ASSERT (!InHandler);\r
InHandler = TRUE;\r
if (IvtEntryTable[ExceptionType].RegisteredCallback != NULL) {\r
);\r
\r
if (EFI_ERROR (Status)) {\r
- DEBUG_CODE (\r
+ DEBUG_CODE_BEGIN ();\r
UINTN BufferSize;\r
\r
BufferSize = 48;\r
&BufferSize,\r
"DebugPort driver failed to open child controller\n\n"\r
);\r
- );\r
+ DEBUG_CODE_END ();\r
\r
gBS->CloseProtocol (\r
ControllerHandle,\r
return Status;\r
}\r
\r
- DEBUG_CODE (\r
+ DEBUG_CODE_BEGIN ();\r
UINTN BufferSize;\r
\r
BufferSize = 38;\r
&BufferSize,\r
"Hello World from the DebugPort driver\n\n"\r
);\r
- );\r
+ DEBUG_CODE_END ();\r
\r
return EFI_SUCCESS;\r
}\r
//\r
// return status\r
//\r
- DEBUG_CODE (\r
+ DEBUG_CODE_BEGIN ();\r
if (OrgCrc != Crc) {\r
DEBUG ((EFI_D_ERROR, "CheckCrc32: Crc check failed\n"));\r
}\r
- );\r
+ DEBUG_CODE_END ();\r
\r
return (BOOLEAN) (OrgCrc == Crc);\r
}\r
EFI_STATUS Status;\r
EFI_EBC_SIMPLE_DEBUGGER_PROTOCOL *EbcSimpleDebugger;\r
\r
- //\r
- // end DEBUG_CODE\r
- //\r
EbcSimpleDebugger = NULL;\r
Status = EFI_SUCCESS;\r
StackCorrupted = 0;\r
//\r
// Try to get the debug support for EBC\r
//\r
- DEBUG_CODE (\r
+ DEBUG_CODE_BEGIN ();\r
Status = gBS->LocateProtocol (\r
&mEbcSimpleDebuggerProtocolGuid,\r
NULL,\r
if (EFI_ERROR (Status)) {\r
EbcSimpleDebugger = NULL;\r
}\r
- );\r
+ DEBUG_CODE_END ();\r
\r
//\r
// Save the start IP for debug. For example, if we take an exception we\r
//\r
// If we've found a simple debugger protocol, call it\r
//\r
- DEBUG_CODE (\r
+ DEBUG_CODE_BEGIN ();\r
if (EbcSimpleDebugger != NULL) {\r
EbcSimpleDebugger->Debugger (EbcSimpleDebugger, VmPtr);\r
}\r
- );\r
+ DEBUG_CODE_END ();\r
\r
//\r
// Verify the opcode is in range. Otherwise generate an exception.\r
//\r
// Produce a VM test interface protocol. Not required for execution.\r
//\r
- DEBUG_CODE (\r
+ DEBUG_CODE_BEGIN ();\r
InitEbcVmTestProtocol (&ImageHandle);\r
- );\r
+ DEBUG_CODE_END ();\r
\r
return Status;\r
}\r
}\r
EbcVmTestProtocol->Execute = (EBC_VM_TEST_EXECUTE) EbcExecuteInstructions;\r
\r
- DEBUG_CODE(\r
+ DEBUG_CODE_BEGIN ();\r
EbcVmTestProtocol->Assemble = (EBC_VM_TEST_ASM) EbcVmTestUnsupported;\r
EbcVmTestProtocol->Disassemble = (EBC_VM_TEST_DASM) EbcVmTestUnsupported;\r
- );\r
+ DEBUG_CODE_END ();\r
\r
//\r
// Publish the protocol\r
Status = PciRootBridgeIo->Pci.Write (\r
PciRootBridgeIo,\r
EfiPciWidthUint32,\r
- EFI_PCI_ADDRESS (LPC_BUS_NUMBER,\r
- LPC_DEVICE_NUMBER,\r
- LPC_IF,\r
- GEN_STATUS),\r
+ EFI_PCI_ADDRESS (\r
+ LPC_BUS_NUMBER,\r
+ LPC_DEVICE_NUMBER,\r
+ LPC_IF,\r
+ GEN_STATUS\r
+ ),\r
1,\r
&GenStatus\r
);\r
\r
- DEBUG_CODE (\r
+ DEBUG_CODE_BEGIN ();\r
if (TopSwap) {\r
DEBUG ((EFI_D_ERROR, "SAR: Set top swap\n"));\r
} else {\r
DEBUG ((EFI_D_ERROR, "SAR: Clear top swap\n"));\r
}\r
- );\r
+ DEBUG_CODE_END ();\r
\r
return EFI_SUCCESS;\r
}\r
\r
#include "Runtime.h"\r
\r
-EFI_STATUS\r
-PeHotRelocateImageEx (\r
- IN UINT16 *Reloc,\r
- IN OUT CHAR8 *Fixup,\r
- IN OUT CHAR8 **FixupData,\r
- IN UINT64 Adjust\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Performs an Itanium-based platform specific relocation fixup\r
-\r
-Arguments:\r
-\r
- Reloc - Pointer to the relocation record\r
-\r
- Fixup - Pointer to the address to fix up\r
-\r
- FixupData - Pointer to a buffer to log the fixups\r
-\r
- Adjust - The offset to adjust the fixup\r
-\r
-Returns:\r
-\r
- EFI_SUCCESS\r
-\r
---*/\r
-{\r
- return EFI_SUCCESS;\r
-\r
-}\r
\r
//\r
// Cache Flush Routine.\r
--*/\r
\r
#include "Runtime.h"\r
-#include "PeHotRelocateEx.h"\r
-\r
-EFI_STATUS\r
-PeHotRelocateImageEx (\r
- IN UINT16 *Reloc,\r
- IN OUT CHAR8 *Fixup,\r
- IN OUT CHAR8 **FixupData,\r
- IN UINT64 Adjust\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Performs an IPF specific relocation fixup\r
-\r
-Arguments:\r
-\r
- Reloc - Pointer to the relocation record\r
-\r
- Fixup - Pointer to the address to fix up\r
-\r
- FixupData - Pointer to a buffer to log the fixups\r
-\r
- Adjust - The offset to adjust the fixup\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-{\r
- UINT64 *F64;\r
- UINT64 FixupVal;\r
-\r
- switch ((*Reloc) >> 12) {\r
- case EFI_IMAGE_REL_BASED_DIR64:\r
- F64 = (UINT64 *) Fixup;\r
- *FixupData = ALIGN_POINTER (*FixupData, sizeof (UINT64));\r
- if (*(UINT64 *) (*FixupData) == *F64) {\r
- *F64 = *F64 + (UINT64) Adjust;\r
- }\r
-\r
- *FixupData = *FixupData + sizeof (UINT64);\r
- break;\r
-\r
- case EFI_IMAGE_REL_BASED_IA64_IMM64:\r
- F64 = (UINT64 *) Fixup;\r
- *FixupData = ALIGN_POINTER (*FixupData, sizeof (UINT64));\r
- if (*(UINT64 *) (*FixupData) == *F64) {\r
- //\r
- // Align it to bundle address before fixing up the\r
- // 64-bit immediate value of the movl instruction.\r
- //\r
- //\r
- Fixup = (CHAR8 *) ((UINT64) Fixup & (UINT64)~(15));\r
- FixupVal = (UINT64) 0;\r
-\r
- //\r
- // Extract the lower 32 bits of IMM64 from bundle\r
- //\r
- EXT_IMM64 (\r
- FixupVal,\r
- (UINT32 *) Fixup + IMM64_IMM7B_INST_WORD_X,\r
- IMM64_IMM7B_SIZE_X,\r
- IMM64_IMM7B_INST_WORD_POS_X,\r
- IMM64_IMM7B_VAL_POS_X\r
- );\r
-\r
- EXT_IMM64 (\r
- FixupVal,\r
- (UINT32 *) Fixup + IMM64_IMM9D_INST_WORD_X,\r
- IMM64_IMM9D_SIZE_X,\r
- IMM64_IMM9D_INST_WORD_POS_X,\r
- IMM64_IMM9D_VAL_POS_X\r
- );\r
-\r
- EXT_IMM64 (\r
- FixupVal,\r
- (UINT32 *) Fixup + IMM64_IMM5C_INST_WORD_X,\r
- IMM64_IMM5C_SIZE_X,\r
- IMM64_IMM5C_INST_WORD_POS_X,\r
- IMM64_IMM5C_VAL_POS_X\r
- );\r
-\r
- EXT_IMM64 (\r
- FixupVal,\r
- (UINT32 *) Fixup + IMM64_IC_INST_WORD_X,\r
- IMM64_IC_SIZE_X,\r
- IMM64_IC_INST_WORD_POS_X,\r
- IMM64_IC_VAL_POS_X\r
- );\r
-\r
- EXT_IMM64 (\r
- FixupVal,\r
- (UINT32 *) Fixup + IMM64_IMM41a_INST_WORD_X,\r
- IMM64_IMM41a_SIZE_X,\r
- IMM64_IMM41a_INST_WORD_POS_X,\r
- IMM64_IMM41a_VAL_POS_X\r
- );\r
-\r
- //\r
- // Update 64-bit address\r
- //\r
- FixupVal += Adjust;\r
-\r
- //\r
- // Insert IMM64 into bundle\r
- //\r
- INS_IMM64 (\r
- FixupVal,\r
- ((UINT32 *) Fixup + IMM64_IMM7B_INST_WORD_X),\r
- IMM64_IMM7B_SIZE_X,\r
- IMM64_IMM7B_INST_WORD_POS_X,\r
- IMM64_IMM7B_VAL_POS_X\r
- );\r
-\r
- INS_IMM64 (\r
- FixupVal,\r
- ((UINT32 *) Fixup + IMM64_IMM9D_INST_WORD_X),\r
- IMM64_IMM9D_SIZE_X,\r
- IMM64_IMM9D_INST_WORD_POS_X,\r
- IMM64_IMM9D_VAL_POS_X\r
- );\r
-\r
- INS_IMM64 (\r
- FixupVal,\r
- ((UINT32 *) Fixup + IMM64_IMM5C_INST_WORD_X),\r
- IMM64_IMM5C_SIZE_X,\r
- IMM64_IMM5C_INST_WORD_POS_X,\r
- IMM64_IMM5C_VAL_POS_X\r
- );\r
-\r
- INS_IMM64 (\r
- FixupVal,\r
- ((UINT32 *) Fixup + IMM64_IC_INST_WORD_X),\r
- IMM64_IC_SIZE_X,\r
- IMM64_IC_INST_WORD_POS_X,\r
- IMM64_IC_VAL_POS_X\r
- );\r
-\r
- INS_IMM64 (\r
- FixupVal,\r
- ((UINT32 *) Fixup + IMM64_IMM41a_INST_WORD_X),\r
- IMM64_IMM41a_SIZE_X,\r
- IMM64_IMM41a_INST_WORD_POS_X,\r
- IMM64_IMM41a_VAL_POS_X\r
- );\r
-\r
- INS_IMM64 (\r
- FixupVal,\r
- ((UINT32 *) Fixup + IMM64_IMM41b_INST_WORD_X),\r
- IMM64_IMM41b_SIZE_X,\r
- IMM64_IMM41b_INST_WORD_POS_X,\r
- IMM64_IMM41b_VAL_POS_X\r
- );\r
-\r
- INS_IMM64 (\r
- FixupVal,\r
- ((UINT32 *) Fixup + IMM64_IMM41c_INST_WORD_X),\r
- IMM64_IMM41c_SIZE_X,\r
- IMM64_IMM41c_INST_WORD_POS_X,\r
- IMM64_IMM41c_VAL_POS_X\r
- );\r
-\r
- INS_IMM64 (\r
- FixupVal,\r
- ((UINT32 *) Fixup + IMM64_SIGN_INST_WORD_X),\r
- IMM64_SIGN_SIZE_X,\r
- IMM64_SIGN_INST_WORD_POS_X,\r
- IMM64_SIGN_VAL_POS_X\r
- );\r
-\r
- *(UINT64 *) (*FixupData) = *F64;\r
- }\r
-\r
- *FixupData = *FixupData + sizeof (UINT64);\r
- break;\r
-\r
- default:\r
- DEBUG ((EFI_D_ERROR, "PeHotRelocateEx:unknown fixed type\n"));\r
- return EFI_UNSUPPORTED;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
\r
//\r
// Cache Flush Routine.\r
return (CHAR8 *) ((UINTN) Image->ImageBase + Address);\r
}\r
\r
-VOID\r
-RelocatePeImageForRuntime (\r
- RUNTIME_IMAGE_RELOCATION_DATA *Image\r
- )\r
-{\r
- CHAR8 *OldBase;\r
- CHAR8 *NewBase;\r
- EFI_IMAGE_DOS_HEADER *DosHdr;\r
- EFI_IMAGE_NT_HEADERS *PeHdr;\r
- UINT32 NumberOfRvaAndSizes;\r
- EFI_IMAGE_DATA_DIRECTORY *DataDirectory;\r
- EFI_IMAGE_DATA_DIRECTORY *RelocDir;\r
- EFI_IMAGE_BASE_RELOCATION *RelocBase;\r
- EFI_IMAGE_BASE_RELOCATION *RelocBaseEnd;\r
- UINT16 *Reloc;\r
- UINT16 *RelocEnd;\r
- CHAR8 *Fixup;\r
- CHAR8 *FixupBase;\r
- UINT16 *F16;\r
- UINT32 *F32;\r
- CHAR8 *FixupData;\r
- UINTN Adjust;\r
- EFI_STATUS Status;\r
-\r
- OldBase = (CHAR8 *) ((UINTN) Image->ImageBase);\r
- NewBase = (CHAR8 *) ((UINTN) Image->ImageBase);\r
-\r
- Status = RuntimeDriverConvertPointer (0, (VOID **) &NewBase);\r
- ASSERT_EFI_ERROR (Status);\r
-\r
- Adjust = (UINTN) NewBase - (UINTN) OldBase;\r
-\r
- //\r
- // Find the image's relocate dir info\r
- //\r
- DosHdr = (EFI_IMAGE_DOS_HEADER *) OldBase;\r
- if (DosHdr->e_magic == EFI_IMAGE_DOS_SIGNATURE) {\r
- //\r
- // Valid DOS header so get address of PE header\r
- //\r
- PeHdr = (EFI_IMAGE_NT_HEADERS *) (((CHAR8 *) DosHdr) + DosHdr->e_lfanew);\r
- } else {\r
- //\r
- // No Dos header so assume image starts with PE header.\r
- //\r
- PeHdr = (EFI_IMAGE_NT_HEADERS *) OldBase;\r
- }\r
-\r
- if (PeHdr->Signature != EFI_IMAGE_NT_SIGNATURE) {\r
- //\r
- // Not a valid PE image so Exit\r
- //\r
- return ;\r
- }\r
- //\r
- // Get some data from the PE type dependent data\r
- //\r
- NumberOfRvaAndSizes = PeHdr->OptionalHeader.NumberOfRvaAndSizes;\r
- DataDirectory = &PeHdr->OptionalHeader.DataDirectory[0];\r
-\r
- //\r
- // Find the relocation block\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
- //\r
- if (NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC) {\r
- RelocDir = DataDirectory + EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC;\r
- RelocBase = RuntimePeImageAddress (Image, RelocDir->VirtualAddress);\r
- RelocBaseEnd = RuntimePeImageAddress (Image, RelocDir->VirtualAddress + RelocDir->Size);\r
- } else {\r
- //\r
- // Cannot find relocations, cannot continue\r
- //\r
- ASSERT (FALSE);\r
- return ;\r
- }\r
-\r
- ASSERT (RelocBase != NULL && RelocBaseEnd != NULL);\r
-\r
- //\r
- // Run the whole relocation block. And re-fixup data that has not been\r
- // modified. The FixupData is used to see if the image has been modified\r
- // since it was relocated. This is so data sections that have been updated\r
- // by code will not be fixed up, since that would set them back to\r
- // defaults.\r
- //\r
- FixupData = Image->RelocationData;\r
- while (RelocBase < RelocBaseEnd) {\r
-\r
- Reloc = (UINT16 *) ((UINT8 *) RelocBase + sizeof (EFI_IMAGE_BASE_RELOCATION));\r
- RelocEnd = (UINT16 *) ((UINT8 *) RelocBase + RelocBase->SizeOfBlock);\r
- FixupBase = (CHAR8 *) ((UINTN) Image->ImageBase) + RelocBase->VirtualAddress;\r
-\r
- //\r
- // Run this relocation record\r
- //\r
- while (Reloc < RelocEnd) {\r
-\r
- Fixup = FixupBase + (*Reloc & 0xFFF);\r
- switch ((*Reloc) >> 12) {\r
-\r
- case EFI_IMAGE_REL_BASED_ABSOLUTE:\r
- break;\r
-\r
- case EFI_IMAGE_REL_BASED_HIGH:\r
- F16 = (UINT16 *) Fixup;\r
- if (*(UINT16 *) FixupData == *F16) {\r
- *F16 = (UINT16) ((*F16 << 16) + ((UINT16) Adjust & 0xffff));\r
- }\r
-\r
- FixupData = FixupData + sizeof (UINT16);\r
- break;\r
-\r
- case EFI_IMAGE_REL_BASED_LOW:\r
- F16 = (UINT16 *) Fixup;\r
- if (*(UINT16 *) FixupData == *F16) {\r
- *F16 = (UINT16) (*F16 + ((UINT16) Adjust & 0xffff));\r
- }\r
-\r
- FixupData = FixupData + sizeof (UINT16);\r
- break;\r
-\r
- case EFI_IMAGE_REL_BASED_HIGHLOW:\r
- F32 = (UINT32 *) Fixup;\r
- FixupData = ALIGN_POINTER (FixupData, sizeof (UINT32));\r
- if (*(UINT32 *) FixupData == *F32) {\r
- *F32 = *F32 + (UINT32) Adjust;\r
- }\r
-\r
- FixupData = FixupData + sizeof (UINT32);\r
- break;\r
-\r
- case EFI_IMAGE_REL_BASED_HIGHADJ:\r
- //\r
- // Not implemented, but not used in EFI 1.0\r
- //\r
- ASSERT (FALSE);\r
- break;\r
-\r
- default:\r
- //\r
- // Only Itanium requires ConvertPeImage_Ex\r
- //\r
- Status = PeHotRelocateImageEx (Reloc, Fixup, &FixupData, Adjust);\r
- if (EFI_ERROR (Status)) {\r
- return ;\r
- }\r
- }\r
- //\r
- // Next relocation record\r
- //\r
- Reloc += 1;\r
- }\r
- //\r
- // next reloc block\r
- //\r
- RelocBase = (EFI_IMAGE_BASE_RELOCATION *) RelocEnd;\r
- }\r
-\r
- FlushCpuCache (Image->ImageBase, (UINT64) Image->ImageSize);\r
-}\r
IN EFI_MEMORY_DESCRIPTOR *VirtualMap\r
)\r
{\r
+ EFI_STATUS Status;\r
RUNTIME_NOTIFY_EVENT_DATA *RuntimeEvent;\r
RUNTIME_IMAGE_RELOCATION_DATA *RuntimeImage;\r
LIST_ENTRY *Link;\r
UINTN Index1;\r
EFI_DRIVER_OS_HANDOFF_HEADER *DriverOsHandoffHeader;\r
EFI_DRIVER_OS_HANDOFF *DriverOsHandoff;\r
+ EFI_PHYSICAL_ADDRESS VirtImageBase;\r
#if (EFI_SPECIFICATION_VERSION >= 0x00020000)\r
EFI_CAPSULE_TABLE *CapsuleTable; \r
#endif\r
for (Link = mRelocationList.ForwardLink; Link != &mRelocationList; Link = Link->ForwardLink) {\r
RuntimeImage = _CR (Link, RUNTIME_IMAGE_RELOCATION_DATA, Link);\r
if (RuntimeImage->Valid) {\r
- RelocatePeImageForRuntime (RuntimeImage);\r
+\r
+ VirtImageBase = RuntimeImage->ImageBase;\r
+ Status = RuntimeDriverConvertPointer (0, (VOID **) &VirtImageBase);\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
+ PeCoffLoaderRelocateImageForRuntime (\r
+ RuntimeImage->ImageBase,\r
+ VirtImageBase,\r
+ RuntimeImage->ImageSize,\r
+ RuntimeImage->RelocationData\r
+ );\r
+ \r
+ FlushCpuCache (RuntimeImage->ImageBase, (UINT64)RuntimeImage->ImageSize);\r
}\r
}\r
//\r
)\r
;\r
\r
-EFI_STATUS\r
-PeHotRelocateImageEx (\r
- IN UINT16 *Reloc,\r
- IN OUT CHAR8 *Fixup,\r
- IN OUT CHAR8 **FixupData,\r
- IN UINT64 Adjust\r
- )\r
-;\r
-\r
EFI_STATUS\r
EFIAPI\r
RuntimeDriverCalculateCrc32 (\r
</LibraryClassDefinitions>\r
<SourceFiles>\r
<Filename>Runtime.dxs</Filename>\r
- <Filename>PeHotRelocate.c</Filename>\r
<Filename>Runtime.c</Filename>\r
<Filename>Runtime.h</Filename>\r
<Filename>Crc32.c</Filename>\r
\r
#include "Runtime.h"\r
\r
-EFI_STATUS\r
-PeHotRelocateImageEx (\r
- IN UINT16 *Reloc,\r
- IN OUT CHAR8 *Fixup,\r
- IN OUT CHAR8 **FixupData,\r
- IN UINT64 Adjust\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Performs an Itanium-based platform specific relocation fixup\r
-\r
-Arguments:\r
-\r
- Reloc - Pointer to the relocation record\r
-\r
- Fixup - Pointer to the address to fix up\r
-\r
- FixupData - Pointer to a buffer to log the fixups\r
-\r
- Adjust - The offset to adjust the fixup\r
-\r
-Returns:\r
-\r
- EFI_SUCCESS\r
-\r
---*/\r
-{\r
- return EFI_SUCCESS;\r
-\r
-}\r
\r
//\r
// Cache Flush Routine.\r
return FALSE;\r
}\r
\r
+\r
+RETURN_STATUS\r
+EFIAPI\r
+IsEfiAppReadFromFile (\r
+ IN VOID *FileHandle,\r
+ IN UINTN FileOffset,\r
+ IN OUT UINTN *ReadSize,\r
+ OUT VOID *Buffer\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_FILE_HANDLE File;\r
+ \r
+ File = (EFI_FILE_HANDLE)FileHandle;\r
+ Status = File->SetPosition (File, FileOffset);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ return File->Read (File, ReadSize, Buffer);\r
+}\r
+\r
+\r
+\r
BOOLEAN\r
BOpt_IsEfiApp (\r
IN EFI_FILE_HANDLE Dir,\r
\r
--*/\r
{\r
- UINTN BufferSize;\r
- EFI_IMAGE_DOS_HEADER DosHdr;\r
- EFI_IMAGE_NT_HEADERS PeHdr;\r
- EFI_IMAGE_OPTIONAL_HEADER32 *PeOpt32;\r
- EFI_IMAGE_OPTIONAL_HEADER64 *PeOpt64;\r
- UINT16 Subsystem;\r
- EFI_FILE_HANDLE File;\r
- EFI_STATUS Status;\r
+ EFI_STATUS Status;\r
+ PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;\r
+ EFI_FILE_HANDLE File;\r
\r
Status = Dir->Open (Dir, &File, FileName, EFI_FILE_MODE_READ, 0);\r
-\r
if (EFI_ERROR (Status)) {\r
return FALSE;\r
}\r
\r
- BufferSize = sizeof (EFI_IMAGE_DOS_HEADER);\r
- File->Read (File, &BufferSize, &DosHdr);\r
- if (DosHdr.e_magic != EFI_IMAGE_DOS_SIGNATURE) {\r
- File->Close (File);\r
- return FALSE;\r
- }\r
+ ZeroMem (&ImageContext, sizeof (ImageContext));\r
+ ImageContext.Handle = (VOID *)File;\r
+ ImageContext.ImageRead = IsEfiAppReadFromFile;\r
\r
- File->SetPosition (File, DosHdr.e_lfanew);\r
- BufferSize = sizeof (EFI_IMAGE_NT_HEADERS);\r
- File->Read (File, &BufferSize, &PeHdr);\r
- if (PeHdr.Signature != EFI_IMAGE_NT_SIGNATURE) {\r
- File->Close (File);\r
- return FALSE;\r
- }\r
- //\r
- // Determine PE type and read subsytem\r
- // BugBug : We should be using EFI_IMAGE_MACHINE_TYPE_SUPPORTED (machine)\r
- // macro to detect the machine type.\r
- // We should not be using EFI_IMAGE_OPTIONAL_HEADER32 and\r
- // EFI_IMAGE_OPTIONAL_HEADER64\r
- //\r
- if (PeHdr.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
- PeOpt32 = (EFI_IMAGE_OPTIONAL_HEADER32 *) &(PeHdr.OptionalHeader);\r
- Subsystem = PeOpt32->Subsystem;\r
- } else if (PeHdr.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) {\r
- PeOpt64 = (EFI_IMAGE_OPTIONAL_HEADER64 *) &(PeHdr.OptionalHeader);\r
- Subsystem = PeOpt64->Subsystem;\r
- } else {\r
+ Status = PeCoffLoaderGetImageInfo (&ImageContext);\r
+ File->Close (File);\r
+ if (EFI_ERROR (Status)) {\r
return FALSE;\r
}\r
\r
- if (Subsystem == EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION) {\r
- File->Close (File);\r
+ if (ImageContext.ImageType == EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION) {\r
return TRUE;\r
} else {\r
- File->Close (File);\r
return FALSE;\r
}\r
-}\r
+ }\r
+\r
\r
EFI_STATUS\r
BOpt_FindDrivers (\r
VOID\r
)\r
{\r
+ //\r
+ // BugBug: We should not need to do this. We need to root cause this bug!!!!\r
+ //\r
AsmWriteDr0 (0);\r
AsmWriteDr1 (0);\r
}\r
return ;\r
}\r
\r
+\r
+\r
STATIC\r
CHAR8 *\r
GetPdbPath (\r
\r
--*/\r
{\r
- CHAR8 *PdbPath;\r
- UINT32 DirCount;\r
- EFI_IMAGE_DOS_HEADER *DosHdr;\r
- EFI_IMAGE_NT_HEADERS *NtHdr;\r
- EFI_IMAGE_OPTIONAL_HEADER *OptionalHdr;\r
- EFI_IMAGE_DATA_DIRECTORY *DirectoryEntry;\r
- EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *DebugEntry;\r
- VOID *CodeViewEntryPointer;\r
-\r
- CodeViewEntryPointer = NULL;\r
- PdbPath = NULL;\r
- DosHdr = ImageBase;\r
-\r
- if (DosHdr->e_magic == EFI_IMAGE_DOS_SIGNATURE) {\r
- NtHdr = (EFI_IMAGE_NT_HEADERS *) ((UINT8 *) DosHdr + DosHdr->e_lfanew);\r
- OptionalHdr = (VOID *) &NtHdr->OptionalHeader;\r
- DirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *) &(OptionalHdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG]);\r
- if (DirectoryEntry->VirtualAddress != 0) {\r
- for (DirCount = 0;\r
- (DirCount < DirectoryEntry->Size / sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY)) && CodeViewEntryPointer == NULL;\r
- DirCount++\r
- ) {\r
- DebugEntry = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *) (DirectoryEntry->VirtualAddress + (UINTN) ImageBase + DirCount * sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY));\r
- if (DebugEntry->Type == EFI_IMAGE_DEBUG_TYPE_CODEVIEW) {\r
- CodeViewEntryPointer = (VOID *) ((UINTN) DebugEntry->RVA + (UINTN) ImageBase);\r
- switch (*(UINT32 *) CodeViewEntryPointer) {\r
- case CODEVIEW_SIGNATURE_NB10:\r
- PdbPath = (CHAR8 *) CodeViewEntryPointer + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY);\r
- break;\r
-\r
- case CODEVIEW_SIGNATURE_RSDS:\r
- PdbPath = (CHAR8 *) CodeViewEntryPointer + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_RSDS_ENTRY);\r
- break;\r
-\r
- default:\r
- break;\r
- }\r
- }\r
- }\r
- }\r
- }\r
+ PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;\r
+\r
+ ZeroMem (&ImageContext, sizeof (ImageContext));\r
+ ImageContext.Handle = ImageBase;\r
+ ImageContext.ImageRead = PeCoffLoaderImageReadFromMemory;\r
\r
- return PdbPath;\r
+ PeCoffLoaderGetImageInfo (&ImageContext);\r
+\r
+ return ImageContext.PdbPointer;\r
}\r
\r
+\r
STATIC\r
VOID\r
GetNameFromHandle (\r
<Instance ModuleGuid="8c690838-7a22-45c4-aa58-a33e3e515cd4" PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>
<Instance ModuleGuid="bda39d3a-451b-4350-8266-81ab10fa0523" PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>
<Instance ModuleGuid="FC120ED3-40E1-46dc-8C9C-AAE3CA139ACF" PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>
+ <Instance ModuleGuid="556f5d10-7309-4af4-b80a-8196bd60946f" PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>
</Libraries>
<PcdBuildDefinition>
<PcdData ItemType="FIXED_AT_BUILD">
<Instance ModuleGuid="4674739d-3195-4fb2-8094-ac1d22d00194" PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>
<Instance ModuleGuid="91c1677a-e57f-4191-8b8e-eb7711a716e0" PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>
<Instance ModuleGuid="FC120ED3-40E1-46dc-8C9C-AAE3CA139ACF" PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>
+ <Instance ModuleGuid="556f5d10-7309-4af4-b80a-8196bd60946f" PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>
+
</Libraries>
<PcdBuildDefinition>
<PcdData ItemType="FIXED_AT_BUILD">
<Instance ModuleGuid="331deb15-454b-48d8-9b74-70d01f3f3556" PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>
<Instance ModuleGuid="bda39d3a-451b-4350-8266-81ab10fa0523" PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>
<Instance ModuleGuid="3ddc3b12-99ea-4364-b315-6310a2050be5" PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>
+ <Instance ModuleGuid="556f5d10-7309-4af4-b80a-8196bd60946f" PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>
</Libraries>
<PcdBuildDefinition>
<PcdData ItemType="FIXED_AT_BUILD">
<Instance ModuleGuid="27d67720-ea68-48ae-93da-a3a074c90e30" PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>
<Instance ModuleGuid="4674739d-3195-4fb2-8094-ac1d22d00194" PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>
<Instance ModuleGuid="91c1677a-e57f-4191-8b8e-eb7711a716e0" PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>
+ <Instance ModuleGuid="be490364-73d2-420d-950e-f6450ca75dfb" PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>
</Libraries>
<PcdBuildDefinition>
<PcdData ItemType="FIXED_AT_BUILD">
/** @file\r
- EFI image format for PE32+. Please note some data structures are different\r
- for IA-32 and Itanium-based images, look for UINTN and the #ifdef EFI_IA64\r
+ EFI image format for PE32 and PE32+. Please note some data structures are \r
+ different for PE32 and PE32+. EFI_IMAGE_NT_HEADERS32 is for PE32 and \r
+ EFI_IMAGE_NT_HEADERS64 is for PE32+. \r
\r
- @bug Fix text - doc as defined in MSFT EFI specification.\r
+ This file is coded to the Visual Studio, Microsoft Portable Executable and \r
+ Common Object File Format Specification, Revision 8.0 - May 16, 2006. \r
\r
Copyright (c) 2006, Intel Corporation \r
All rights reserved. This program and the accompanying materials \r
#define EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION 10\r
#define EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER 11\r
#define EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER 12\r
+#define EFI_IMAGE_SUBSYSTEM_EFI_EFI_ROM 13\r
+\r
#define EFI_IMAGE_SUBSYSTEM_SAL_RUNTIME_DRIVER 13\r
\r
-//\r
-// BugBug: Need to get a real answer for this problem. This is not in the\r
-// PE specification.\r
-//\r
-// A SAL runtime driver does not get fixed up when a transition to\r
-// virtual mode is made. In all other cases it should be treated\r
-// like a EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER image\r
-//\r
-#define EFI_IMAGE_SUBSYSTEM_SAL_RUNTIME_DRIVER 13\r
\r
//\r
// PE32+ Machine type for EFI images\r
#define EFI_IMAGE_OS2_SIGNATURE 0x454E // NE\r
#define EFI_IMAGE_OS2_SIGNATURE_LE 0x454C // LE\r
#define EFI_IMAGE_NT_SIGNATURE 0x00004550 // PE00\r
-#define EFI_IMAGE_EDOS_SIGNATURE 0x44454550 // PEED\r
\r
///\r
/// PE images can start with an optional DOS header, so if an image is run\r
\r
///\r
/// @attention\r
-/// EFI_IMAGE_OPTIONAL_HEADER32 and EFI_IMAGE_OPTIONAL_HEADER64\r
-/// are for use ONLY by tools. All proper EFI code MUST use\r
-/// EFI_IMAGE_OPTIONAL_HEADER ONLY!!!\r
+/// EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC means PE32 and \r
+/// EFI_IMAGE_OPTIONAL_HEADER32 must be used. The data structures only vary\r
+/// after NT additional fields.\r
///\r
#define EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC 0x10b\r
\r
\r
///\r
/// @attention\r
-/// EFI_IMAGE_OPTIONAL_HEADER32 and EFI_IMAGE_OPTIONAL_HEADER64\r
-/// are for use ONLY by tools. All proper EFI code MUST use\r
-/// EFI_IMAGE_OPTIONAL_HEADER ONLY!!!\r
+/// EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC means PE32+ and \r
+/// EFI_IMAGE_OPTIONAL_HEADER64 must be used. The data structures only vary\r
+/// after NT additional fields.\r
///\r
#define EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC 0x20b\r
\r
EFI_IMAGE_DATA_DIRECTORY DataDirectory[EFI_IMAGE_NUMBER_OF_DIRECTORY_ENTRIES];\r
} EFI_IMAGE_OPTIONAL_HEADER64;\r
\r
+\r
///\r
/// @attention\r
/// EFI_IMAGE_NT_HEADERS32 and EFI_IMAGE_HEADERS64 are for use ONLY\r
\r
#define EFI_IMAGE_SIZEOF_NT_OPTIONAL64_HEADER sizeof (EFI_IMAGE_NT_HEADERS64)\r
\r
+\r
//\r
// Processor specific definition of EFI_IMAGE_OPTIONAL_HEADER so the\r
// type name EFI_IMAGE_OPTIONAL_HEADER is appropriate to the build. Same for\r
//\r
#if defined (MDE_CPU_IA32)\r
\r
-typedef EFI_IMAGE_OPTIONAL_HEADER32 EFI_IMAGE_OPTIONAL_HEADER;\r
-typedef EFI_IMAGE_NT_HEADERS32 EFI_IMAGE_NT_HEADERS;\r
-\r
-#define EFI_IMAGE_NT_OPTIONAL_HDR_MAGIC EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC\r
#define EFI_IMAGE_MACHINE_TYPE_SUPPORTED(Machine) \\r
(((Machine) == EFI_IMAGE_MACHINE_IA32) || ((Machine) == EFI_IMAGE_MACHINE_EBC))\r
\r
-#elif defined (MDE_CPU_IPF)\r
+#define EFI_IMAGE_MACHINE_CROSS_TYPE_SUPPORTED(Machine) ((Machine) == EFI_IMAGE_MACHINE_X64) \r
+\r
+//\r
+// @bug - Remove me when other package updated. \r
+//\r
+typedef EFI_IMAGE_NT_HEADERS32 EFI_IMAGE_NT_HEADERS;\r
\r
-typedef EFI_IMAGE_OPTIONAL_HEADER64 EFI_IMAGE_OPTIONAL_HEADER;\r
-typedef EFI_IMAGE_NT_HEADERS64 EFI_IMAGE_NT_HEADERS;\r
+#elif defined (MDE_CPU_IPF)\r
\r
-#define EFI_IMAGE_NT_OPTIONAL_HDR_MAGIC EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC\r
#define EFI_IMAGE_MACHINE_TYPE_SUPPORTED(Machine) \\r
(((Machine) == EFI_IMAGE_MACHINE_IPF) || ((Machine) == EFI_IMAGE_MACHINE_EBC))\r
\r
-#elif defined (MDE_CPU_X64)\r
+#define EFI_IMAGE_MACHINE_CROSS_TYPE_SUPPORTED(Machine) (FALSE) \r
\r
-typedef EFI_IMAGE_OPTIONAL_HEADER64 EFI_IMAGE_OPTIONAL_HEADER;\r
-typedef EFI_IMAGE_NT_HEADERS64 EFI_IMAGE_NT_HEADERS;\r
+#elif defined (MDE_CPU_X64)\r
\r
-#define EFI_IMAGE_NT_OPTIONAL_HDR_MAGIC EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC\r
#define EFI_IMAGE_MACHINE_TYPE_SUPPORTED(Machine) \\r
(((Machine) == EFI_IMAGE_MACHINE_X64) || ((Machine) == EFI_IMAGE_MACHINE_EBC))\r
\r
+#define EFI_IMAGE_MACHINE_CROSS_TYPE_SUPPORTED(Machine) ((Machine) == EFI_IMAGE_MACHINE_IA32) \r
+\r
+//\r
+// @bug - Remove me when other package updated. \r
+//\r
+typedef EFI_IMAGE_NT_HEADERS32 EFI_IMAGE_NT_HEADERS;\r
+\r
#elif defined (MDE_CPU_EBC)\r
\r
//\r
// It does not make sense to have a PE loader coded in EBC. You need to \r
// understand the basic \r
//\r
-typedef EFI_IMAGE_OPTIONAL_HEADER64 EFI_IMAGE_OPTIONAL_HEADER;\r
-typedef EFI_IMAGE_NT_HEADERS64 EFI_IMAGE_NT_HEADERS;\r
-\r
-#define EFI_IMAGE_NT_OPTIONAL_HDR_MAGIC EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC\r
#define EFI_IMAGE_MACHINE_TYPE_SUPPORTED(Machine) ((Machine) == EFI_IMAGE_MACHINE_EBC)\r
\r
+#define EFI_IMAGE_MACHINE_CROSS_TYPE_SUPPORTED(Machine) (FALSE) \r
+\r
#else\r
#error Unknown Processor Type\r
#endif\r
//\r
// I386 relocation types.\r
//\r
-#define EFI_IMAGE_REL_I386_ABSOLUTE 0 // Reference is absolute, no relocation is necessary\r
-#define EFI_IMAGE_REL_I386_DIR16 01 // Direct 16-bit reference to the symbols virtual address\r
-#define EFI_IMAGE_REL_I386_REL16 02 // PC-relative 16-bit reference to the symbols virtual address\r
-#define EFI_IMAGE_REL_I386_DIR32 06 // Direct 32-bit reference to the symbols virtual address\r
-#define EFI_IMAGE_REL_I386_DIR32NB 07 // Direct 32-bit reference to the symbols virtual address, base not included\r
-#define EFI_IMAGE_REL_I386_SEG12 011 // Direct 16-bit reference to the segment-selector bits of a 32-bit virtual address\r
-#define EFI_IMAGE_REL_I386_SECTION 012\r
-#define EFI_IMAGE_REL_I386_SECREL 013\r
-#define EFI_IMAGE_REL_I386_REL32 024 // PC-relative 32-bit reference to the symbols virtual address\r
+#define EFI_IMAGE_REL_I386_ABSOLUTE 0x0000 // Reference is absolute, no relocation is necessary\r
+#define EFI_IMAGE_REL_I386_DIR16 0x0001 // Direct 16-bit reference to the symbols virtual address\r
+#define EFI_IMAGE_REL_I386_REL16 0x0002 // PC-relative 16-bit reference to the symbols virtual address\r
+#define EFI_IMAGE_REL_I386_DIR32 0x0006 // Direct 32-bit reference to the symbols virtual address\r
+#define EFI_IMAGE_REL_I386_DIR32NB 0x0007 // Direct 32-bit reference to the symbols virtual address, base not included\r
+#define EFI_IMAGE_REL_I386_SEG12 0x0009 // Direct 16-bit reference to the segment-selector bits of a 32-bit virtual address\r
+#define EFI_IMAGE_REL_I386_SECTION 0x001a\r
+#define EFI_IMAGE_REL_I386_SECREL 0x000b\r
+#define EFI_IMAGE_REL_I386_REL32 0x0014 // PC-relative 32-bit reference to the symbols virtual address\r
+\r
+//\r
+// x64 processor relocation types.\r
+//\r
+#define IMAGE_REL_AMD64_ABSOLUTE 0x0000\r
+#define IMAGE_REL_AMD64_ADDR64 0x0001\r
+#define IMAGE_REL_AMD64_ADDR32 0x0002\r
+#define IMAGE_REL_AMD64_ADDR32NB 0x0003\r
+#define IMAGE_REL_AMD64_REL32 0x0004\r
+#define IMAGE_REL_AMD64_REL32_1 0x0005\r
+#define IMAGE_REL_AMD64_REL32_2 0x0006\r
+#define IMAGE_REL_AMD64_REL32_3 0x0007\r
+#define IMAGE_REL_AMD64_REL32_4 0x0008\r
+#define IMAGE_REL_AMD64_REL32_5 0x0009\r
+#define IMAGE_REL_AMD64_SECTION 0x000A\r
+#define IMAGE_REL_AMD64_SECREL 0x000B\r
+#define IMAGE_REL_AMD64_SECREL7 0x000C\r
+#define IMAGE_REL_AMD64_TOKEN 0x000D\r
+#define IMAGE_REL_AMD64_SREL32 0x000E\r
+#define IMAGE_REL_AMD64_PAIR 0x000F\r
+#define IMAGE_REL_AMD64_SSPAN32 0x0010\r
\r
///\r
/// Based relocation format.\r
#define EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC 0\r
#define EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG 1\r
\r
+\r
+//\r
+// Union of PE32, PE32+, and TE headers\r
+//\r
+typedef union {\r
+ EFI_IMAGE_NT_HEADERS32 Pe32;\r
+ EFI_IMAGE_NT_HEADERS64 Pe32Plus;\r
+ EFI_TE_IMAGE_HEADER Te;\r
+} EFI_IMAGE_OPTIONAL_HEADER_UNION;\r
+\r
+typedef union {\r
+ EFI_IMAGE_NT_HEADERS32 *Pe32;\r
+ EFI_IMAGE_NT_HEADERS64 *Pe32Plus;\r
+ EFI_TE_IMAGE_HEADER *Te;\r
+ EFI_IMAGE_OPTIONAL_HEADER_UNION *Union;\r
+} EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION;\r
+\r
#endif\r
#ifndef __PCI_CF8_LIB_H__\r
#define __PCI_CF8_LIB_H__\r
\r
-#include <Library/PciLib.h>\r
\r
/**\r
Macro that converts PCI Bus, PCI Device, PCI Function and PCI Register to an\r
\r
**/\r
#define PCI_CF8_LIB_ADDRESS(Bus,Device,Function,Offset) \\r
- PCI_LIB_ADDRESS (Bus, Device, Function, Offset)\r
+ (((Offset) & 0xfff) | (((Function) & 0x07) << 12) | (((Device) & 0x1f) << 15) | (((Bus) & 0xff) << 20))\r
\r
/**\r
Reads an 8-bit PCI configuration register.\r
\r
**/\r
#define PCI_EXPRESS_LIB_ADDRESS(Bus,Device,Function,Offset) \\r
- PCI_LIB_ADDRESS (Bus, Device, Function, Offset)\r
+ (((Offset) & 0xfff) | (((Function) & 0x07) << 12) | (((Device) & 0x1f) << 15) | (((Bus) & 0xff) << 20))\r
\r
/**\r
Reads an 8-bit PCI configuration register.\r
OUT VOID **EntryPoint\r
);\r
\r
+/**\r
+ Returns the machine type of PE/COFF image. \r
+\r
+ @param Image Pointer to a PE/COFF header\r
+\r
+ @return Machine type or zero if not a valid iamge\r
+\r
+**/\r
+UINT16\r
+EFIAPI\r
+PeCoffLoaderGetMachineType (\r
+ IN VOID *Image\r
+ );\r
+\r
+\r
#endif\r
/** @file\r
- Memory Only PE COFF loader\r
+ Memory Only PE COFF loader. \r
\r
Copyright (c) 2006, Intel Corporation \r
All rights reserved. This program and the accompanying materials \r
)\r
;\r
\r
+\r
+/**\r
+ ImageRead function that operates on a memory buffer whos base is passed into\r
+ FileHandle. \r
+\r
+ @param FileHandle Ponter to baes of the input stream\r
+ @param FileOffset Offset to the start of the buffer\r
+ @param ReadSize Number of bytes to copy into the buffer\r
+ @param Buffer Location to place results of read\r
+\r
+ @retval RETURN_SUCCESS Data is read from FileOffset from the Handle into \r
+ the buffer.\r
+**/\r
+RETURN_STATUS\r
+EFIAPI\r
+PeCoffLoaderImageReadFromMemory (\r
+ IN VOID *FileHandle,\r
+ IN UINTN FileOffset,\r
+ IN OUT UINTN *ReadSize,\r
+ OUT VOID *Buffer\r
+ )\r
+;\r
+\r
+\r
+/**\r
+ Reapply fixups on a fixed up PE32/PE32+ image to allow virutal calling at EFI\r
+ runtime. \r
+ \r
+ PE_COFF_LOADER_IMAGE_CONTEXT.FixupData stores information needed to reapply\r
+ the fixups with a virtual mapping.\r
+\r
+\r
+ @param ImageBase Base address of relocated image\r
+ @param VirtImageBase Virtual mapping for ImageBase\r
+ @param ImageSize Size of the image to relocate\r
+ @param RelocationData Location to place results of read\r
+ \r
+**/\r
+VOID\r
+EFIAPI\r
+PeCoffLoaderRelocateImageForRuntime (\r
+ IN PHYSICAL_ADDRESS ImageBase,\r
+ IN PHYSICAL_ADDRESS VirtImageBase,\r
+ IN UINTN ImageSize,\r
+ IN VOID *RelocationData\r
+ )\r
+;\r
+\r
+\r
#endif\r
return 0;\r
}\r
\r
-/**\r
- Reads an 8-bit MMIO register.\r
-\r
- Reads the 8-bit MMIO register specified by Address. The 8-bit read value is\r
- returned. This function must guarantee that all MMIO read and write\r
- operations are serialized.\r
-\r
- If 8-bit MMIO register operations are not supported, then ASSERT().\r
-\r
- @param Address The MMIO register to read.\r
-\r
- @return The value read.\r
-\r
-**/\r
-UINT8\r
-EFIAPI\r
-MmioRead8 (\r
- IN UINTN Address\r
- )\r
-{\r
- return *(volatile UINT8*)Address;\r
-}\r
-\r
-/**\r
- Writes an 8-bit MMIO register.\r
-\r
- Writes the 8-bit MMIO register specified by Address with the value specified\r
- by Value and returns Value. This function must guarantee that all MMIO read\r
- and write operations are serialized.\r
-\r
- If 8-bit MMIO register operations are not supported, then ASSERT().\r
-\r
- @param Address The MMIO register to write.\r
- @param Value The value to write to the MMIO register.\r
-\r
-**/\r
-UINT8\r
-EFIAPI\r
-MmioWrite8 (\r
- IN UINTN Address,\r
- IN UINT8 Value\r
- )\r
-{\r
- return *(volatile UINT8*)Address = Value;\r
-}\r
-\r
-/**\r
- Reads a 16-bit MMIO register.\r
-\r
- Reads the 16-bit MMIO register specified by Address. The 16-bit read value is\r
- returned. This function must guarantee that all MMIO read and write\r
- operations are serialized.\r
-\r
- If 16-bit MMIO register operations are not supported, then ASSERT().\r
-\r
- @param Address The MMIO register to read.\r
-\r
- @return The value read.\r
-\r
-**/\r
-UINT16\r
-EFIAPI\r
-MmioRead16 (\r
- IN UINTN Address\r
- )\r
-{\r
- ASSERT ((Address & 1) == 0);\r
- return *(volatile UINT16*)Address;\r
-}\r
-\r
-/**\r
- Writes a 16-bit MMIO register.\r
-\r
- Writes the 16-bit MMIO register specified by Address with the value specified\r
- by Value and returns Value. This function must guarantee that all MMIO read\r
- and write operations are serialized.\r
-\r
- If 16-bit MMIO register operations are not supported, then ASSERT().\r
-\r
- @param Address The MMIO register to write.\r
- @param Value The value to write to the MMIO register.\r
-\r
-**/\r
-UINT16\r
-EFIAPI\r
-MmioWrite16 (\r
- IN UINTN Address,\r
- IN UINT16 Value\r
- )\r
-{\r
- ASSERT ((Address & 1) == 0);\r
- return *(volatile UINT16*)Address = Value;\r
-}\r
-\r
-/**\r
- Reads a 32-bit MMIO register.\r
-\r
- Reads the 32-bit MMIO register specified by Address. The 32-bit read value is\r
- returned. This function must guarantee that all MMIO read and write\r
- operations are serialized.\r
-\r
- If 32-bit MMIO register operations are not supported, then ASSERT().\r
-\r
- @param Address The MMIO register to read.\r
-\r
- @return The value read.\r
-\r
-**/\r
-UINT32\r
-EFIAPI\r
-MmioRead32 (\r
- IN UINTN Address\r
- )\r
-{\r
- ASSERT ((Address & 3) == 0);\r
- return *(volatile UINT32*)Address;\r
-}\r
-\r
-/**\r
- Writes a 32-bit MMIO register.\r
-\r
- Writes the 32-bit MMIO register specified by Address with the value specified\r
- by Value and returns Value. This function must guarantee that all MMIO read\r
- and write operations are serialized.\r
-\r
- If 32-bit MMIO register operations are not supported, then ASSERT().\r
-\r
- @param Address The MMIO register to write.\r
- @param Value The value to write to the MMIO register.\r
-\r
-**/\r
-UINT32\r
-EFIAPI\r
-MmioWrite32 (\r
- IN UINTN Address,\r
- IN UINT32 Value\r
- )\r
-{\r
- ASSERT ((Address & 3) == 0);\r
- return *(volatile UINT32*)Address = Value;\r
-}\r
-\r
-/**\r
- Reads a 64-bit MMIO register.\r
-\r
- Reads the 64-bit MMIO register specified by Address. The 64-bit read value is\r
- returned. This function must guarantee that all MMIO read and write\r
- operations are serialized.\r
-\r
- If 64-bit MMIO register operations are not supported, then ASSERT().\r
-\r
- @param Address The MMIO register to read.\r
-\r
- @return The value read.\r
-\r
-**/\r
-UINT64\r
-EFIAPI\r
-MmioRead64 (\r
- IN UINTN Address\r
- )\r
-{\r
- ASSERT ((Address & 7) == 0);\r
- return *(volatile UINT64*)Address;\r
-}\r
-\r
-/**\r
- Writes a 64-bit MMIO register.\r
-\r
- Writes the 64-bit MMIO register specified by Address with the value specified\r
- by Value and returns Value. This function must guarantee that all MMIO read\r
- and write operations are serialized.\r
-\r
- If 64-bit MMIO register operations are not supported, then ASSERT().\r
-\r
- @param Address The MMIO register to write.\r
- @param Value The value to write to the MMIO register.\r
-\r
-**/\r
-UINT64\r
-EFIAPI\r
-MmioWrite64 (\r
- IN UINTN Address,\r
- IN UINT64 Value\r
- )\r
-{\r
- ASSERT ((Address & 7) == 0);\r
- return *(volatile UINT64*)Address = Value;\r
-}\r
\r
#ifdef __GNUC__\r
\r
+/**\r
+ Reads an 8-bit MMIO register.\r
+\r
+ Reads the 8-bit MMIO register specified by Address. The 8-bit read value is\r
+ returned. This function must guarantee that all MMIO read and write\r
+ operations are serialized.\r
+\r
+ If 8-bit MMIO register operations are not supported, then ASSERT().\r
+\r
+ @param Address The MMIO register to read.\r
+\r
+ @return The value read.\r
+\r
+**/\r
+UINT8\r
+EFIAPI\r
+MmioRead8 (\r
+ IN UINTN Address\r
+ )\r
+{\r
+ return *(volatile UINT8*)Address;\r
+}\r
+\r
+/**\r
+ Writes an 8-bit MMIO register.\r
+\r
+ Writes the 8-bit MMIO register specified by Address with the value specified\r
+ by Value and returns Value. This function must guarantee that all MMIO read\r
+ and write operations are serialized.\r
+\r
+ If 8-bit MMIO register operations are not supported, then ASSERT().\r
+\r
+ @param Address The MMIO register to write.\r
+ @param Value The value to write to the MMIO register.\r
+\r
+**/\r
+UINT8\r
+EFIAPI\r
+MmioWrite8 (\r
+ IN UINTN Address,\r
+ IN UINT8 Value\r
+ )\r
+{\r
+ return *(volatile UINT8*)Address = Value;\r
+}\r
+\r
+/**\r
+ Reads a 16-bit MMIO register.\r
+\r
+ Reads the 16-bit MMIO register specified by Address. The 16-bit read value is\r
+ returned. This function must guarantee that all MMIO read and write\r
+ operations are serialized.\r
+\r
+ If 16-bit MMIO register operations are not supported, then ASSERT().\r
+\r
+ @param Address The MMIO register to read.\r
+\r
+ @return The value read.\r
+\r
+**/\r
+UINT16\r
+EFIAPI\r
+MmioRead16 (\r
+ IN UINTN Address\r
+ )\r
+{\r
+ ASSERT ((Address & 1) == 0);\r
+ return *(volatile UINT16*)Address;\r
+}\r
+\r
+/**\r
+ Writes a 16-bit MMIO register.\r
+\r
+ Writes the 16-bit MMIO register specified by Address with the value specified\r
+ by Value and returns Value. This function must guarantee that all MMIO read\r
+ and write operations are serialized.\r
+\r
+ If 16-bit MMIO register operations are not supported, then ASSERT().\r
+\r
+ @param Address The MMIO register to write.\r
+ @param Value The value to write to the MMIO register.\r
+\r
+**/\r
+UINT16\r
+EFIAPI\r
+MmioWrite16 (\r
+ IN UINTN Address,\r
+ IN UINT16 Value\r
+ )\r
+{\r
+ ASSERT ((Address & 1) == 0);\r
+ return *(volatile UINT16*)Address = Value;\r
+}\r
+\r
+/**\r
+ Reads a 32-bit MMIO register.\r
+\r
+ Reads the 32-bit MMIO register specified by Address. The 32-bit read value is\r
+ returned. This function must guarantee that all MMIO read and write\r
+ operations are serialized.\r
+\r
+ If 32-bit MMIO register operations are not supported, then ASSERT().\r
+\r
+ @param Address The MMIO register to read.\r
+\r
+ @return The value read.\r
+\r
+**/\r
+UINT32\r
+EFIAPI\r
+MmioRead32 (\r
+ IN UINTN Address\r
+ )\r
+{\r
+ ASSERT ((Address & 3) == 0);\r
+ return *(volatile UINT32*)Address;\r
+}\r
+\r
+/**\r
+ Writes a 32-bit MMIO register.\r
+\r
+ Writes the 32-bit MMIO register specified by Address with the value specified\r
+ by Value and returns Value. This function must guarantee that all MMIO read\r
+ and write operations are serialized.\r
+\r
+ If 32-bit MMIO register operations are not supported, then ASSERT().\r
+\r
+ @param Address The MMIO register to write.\r
+ @param Value The value to write to the MMIO register.\r
+\r
+**/\r
+UINT32\r
+EFIAPI\r
+MmioWrite32 (\r
+ IN UINTN Address,\r
+ IN UINT32 Value\r
+ )\r
+{\r
+ ASSERT ((Address & 3) == 0);\r
+ return *(volatile UINT32*)Address = Value;\r
+}\r
+\r
+/**\r
+ Reads a 64-bit MMIO register.\r
+\r
+ Reads the 64-bit MMIO register specified by Address. The 64-bit read value is\r
+ returned. This function must guarantee that all MMIO read and write\r
+ operations are serialized.\r
+\r
+ If 64-bit MMIO register operations are not supported, then ASSERT().\r
+\r
+ @param Address The MMIO register to read.\r
+\r
+ @return The value read.\r
+\r
+**/\r
+UINT64\r
+EFIAPI\r
+MmioRead64 (\r
+ IN UINTN Address\r
+ )\r
+{\r
+ ASSERT ((Address & 7) == 0);\r
+ return *(volatile UINT64*)Address;\r
+}\r
+\r
+/**\r
+ Writes a 64-bit MMIO register.\r
+\r
+ Writes the 64-bit MMIO register specified by Address with the value specified\r
+ by Value and returns Value. This function must guarantee that all MMIO read\r
+ and write operations are serialized.\r
+\r
+ If 64-bit MMIO register operations are not supported, then ASSERT().\r
+\r
+ @param Address The MMIO register to write.\r
+ @param Value The value to write to the MMIO register.\r
+\r
+**/\r
+UINT64\r
+EFIAPI\r
+MmioWrite64 (\r
+ IN UINTN Address,\r
+ IN UINT64 Value\r
+ )\r
+{\r
+ ASSERT ((Address & 7) == 0);\r
+ return *(volatile UINT64*)Address = Value;\r
+}\r
+\r
+\r
+\r
/**\r
Reads an 8-bit I/O port.\r
\r
//\r
// Microsoft Visual Studio 7.1 Function Prototypes for I/O Intrinsics\r
//\r
-int _inp (unsigned short port);\r
+int _inp (unsigned short port);\r
unsigned short _inpw (unsigned short port);\r
unsigned long _inpd (unsigned short port);\r
int _outp (unsigned short port, int databyte );\r
-unsigned short _outpw(unsigned short port, unsigned short dataword );\r
-unsigned long _outpd(unsigned short port, unsigned long dataword );\r
+unsigned short _outpw (unsigned short port, unsigned short dataword );\r
+unsigned long _outpd (unsigned short port, unsigned long dataword );\r
+void _ReadWriteBarrier (void);\r
\r
#pragma intrinsic(_inp)\r
#pragma intrinsic(_inpw)\r
#pragma intrinsic(_outp)\r
#pragma intrinsic(_outpw)\r
#pragma intrinsic(_outpd)\r
+#pragma intrinsic(_ReadWriteBarrier)\r
\r
+//\r
+// _ReadWriteBarrier() forces memory reads and writes to complete at the point\r
+// in the call. This is only a hint to the compiler and does emit code.\r
+// In past versions of the compiler, _ReadWriteBarrier was enforced only \r
+// locally and did not affect functions up the call tree. In Visual C++ \r
+// 2005, _ReadWriteBarrier is enforced all the way up the call tree.\r
+//\r
\r
/**\r
Reads an 8-bit I/O port.\r
IN UINTN Port\r
)\r
{\r
+ _ReadWriteBarrier ();\r
return (UINT8)_inp ((UINT16)Port);\r
}\r
\r
IN UINT8 Value\r
)\r
{\r
+ _ReadWriteBarrier ();\r
return (UINT8)_outp ((UINT16)Port, Value);\r
}\r
\r
)\r
{\r
ASSERT ((Port & 1) == 0);\r
+ _ReadWriteBarrier ();\r
return _inpw((UINT16)Port);\r
}\r
\r
)\r
{\r
ASSERT ((Port & 1) == 0);\r
+ _ReadWriteBarrier ();\r
return _outpw ((UINT16)Port, Value);\r
}\r
\r
)\r
{\r
ASSERT ((Port & 3) == 0);\r
+ _ReadWriteBarrier ();\r
return _inpd((UINT16)Port);\r
}\r
\r
)\r
{\r
ASSERT ((Port & 3) == 0);\r
+ _ReadWriteBarrier ();\r
return _outpd ((UINT16)Port, Value);\r
}\r
\r
+\r
+/**\r
+ Reads an 8-bit MMIO register.\r
+\r
+ Reads the 8-bit MMIO register specified by Address. The 8-bit read value is\r
+ returned. This function must guarantee that all MMIO read and write\r
+ operations are serialized.\r
+\r
+ If 8-bit MMIO register operations are not supported, then ASSERT().\r
+\r
+ @param Address The MMIO register to read.\r
+\r
+ @return The value read.\r
+\r
+**/\r
+UINT8\r
+EFIAPI\r
+MmioRead8 (\r
+ IN UINTN Address\r
+ )\r
+{\r
+ _ReadWriteBarrier ();\r
+ return *(volatile UINT8 *)Address;\r
+}\r
+\r
+/**\r
+ Writes an 8-bit MMIO register.\r
+\r
+ Writes the 8-bit MMIO register specified by Address with the value specified\r
+ by Value and returns Value. This function must guarantee that all MMIO read\r
+ and write operations are serialized.\r
+\r
+ If 8-bit MMIO register operations are not supported, then ASSERT().\r
+\r
+ @param Address The MMIO register to write.\r
+ @param Value The value to write to the MMIO register.\r
+\r
+**/\r
+UINT8\r
+EFIAPI\r
+MmioWrite8 (\r
+ IN UINTN Address,\r
+ IN UINT8 Value\r
+ )\r
+{\r
+ _ReadWriteBarrier ();\r
+ return *(volatile UINT8 *)Address = Value;\r
+}\r
+\r
+/**\r
+ Reads a 16-bit MMIO register.\r
+\r
+ Reads the 16-bit MMIO register specified by Address. The 16-bit read value is\r
+ returned. This function must guarantee that all MMIO read and write\r
+ operations are serialized.\r
+\r
+ If 16-bit MMIO register operations are not supported, then ASSERT().\r
+\r
+ @param Address The MMIO register to read.\r
+\r
+ @return The value read.\r
+\r
+**/\r
+UINT16\r
+EFIAPI\r
+MmioRead16 (\r
+ IN UINTN Address\r
+ )\r
+{\r
+ ASSERT ((Address & 1) == 0);\r
+ _ReadWriteBarrier ();\r
+ return *(volatile UINT16 *)Address;\r
+}\r
+\r
+/**\r
+ Writes a 16-bit MMIO register.\r
+\r
+ Writes the 16-bit MMIO register specified by Address with the value specified\r
+ by Value and returns Value. This function must guarantee that all MMIO read\r
+ and write operations are serialized.\r
+\r
+ If 16-bit MMIO register operations are not supported, then ASSERT().\r
+\r
+ @param Address The MMIO register to write.\r
+ @param Value The value to write to the MMIO register.\r
+\r
+**/\r
+UINT16\r
+EFIAPI\r
+MmioWrite16 (\r
+ IN UINTN Address,\r
+ IN UINT16 Value\r
+ )\r
+{\r
+ ASSERT ((Address & 1) == 0);\r
+ _ReadWriteBarrier ();\r
+ return *(volatile UINT16 *)Address = Value;\r
+}\r
+\r
+/**\r
+ Reads a 32-bit MMIO register.\r
+\r
+ Reads the 32-bit MMIO register specified by Address. The 32-bit read value is\r
+ returned. This function must guarantee that all MMIO read and write\r
+ operations are serialized.\r
+\r
+ If 32-bit MMIO register operations are not supported, then ASSERT().\r
+\r
+ @param Address The MMIO register to read.\r
+\r
+ @return The value read.\r
+\r
+**/\r
+UINT32\r
+EFIAPI\r
+MmioRead32 (\r
+ IN UINTN Address\r
+ )\r
+{\r
+ ASSERT ((Address & 3) == 0);\r
+ _ReadWriteBarrier ();\r
+ return *(volatile UINT32 *)Address;\r
+}\r
+\r
+/**\r
+ Writes a 32-bit MMIO register.\r
+\r
+ Writes the 32-bit MMIO register specified by Address with the value specified\r
+ by Value and returns Value. This function must guarantee that all MMIO read\r
+ and write operations are serialized.\r
+\r
+ If 32-bit MMIO register operations are not supported, then ASSERT().\r
+\r
+ @param Address The MMIO register to write.\r
+ @param Value The value to write to the MMIO register.\r
+\r
+**/\r
+UINT32\r
+EFIAPI\r
+MmioWrite32 (\r
+ IN UINTN Address,\r
+ IN UINT32 Value\r
+ )\r
+{\r
+ ASSERT ((Address & 3) == 0);\r
+ _ReadWriteBarrier ();\r
+ return *(volatile UINT32 *)Address = Value;\r
+}\r
+\r
+/**\r
+ Reads a 64-bit MMIO register.\r
+\r
+ Reads the 64-bit MMIO register specified by Address. The 64-bit read value is\r
+ returned. This function must guarantee that all MMIO read and write\r
+ operations are serialized.\r
+\r
+ If 64-bit MMIO register operations are not supported, then ASSERT().\r
+\r
+ @param Address The MMIO register to read.\r
+\r
+ @return The value read.\r
+\r
+**/\r
+UINT64\r
+EFIAPI\r
+MmioRead64 (\r
+ IN UINTN Address\r
+ )\r
+{\r
+ ASSERT ((Address & 7) == 0);\r
+ _ReadWriteBarrier ();\r
+ return *(volatile UINT64 *)Address;\r
+}\r
+\r
+/**\r
+ Writes a 64-bit MMIO register.\r
+\r
+ Writes the 64-bit MMIO register specified by Address with the value specified\r
+ by Value and returns Value. This function must guarantee that all MMIO read\r
+ and write operations are serialized.\r
+\r
+ If 64-bit MMIO register operations are not supported, then ASSERT().\r
+\r
+ @param Address The MMIO register to write.\r
+ @param Value The value to write to the MMIO register.\r
+\r
+**/\r
+UINT64\r
+EFIAPI\r
+MmioWrite64 (\r
+ IN UINTN Address,\r
+ IN UINT64 Value\r
+ )\r
+{\r
+ ASSERT ((Address & 7) == 0);\r
+ _ReadWriteBarrier ();\r
+ return *(volatile UINT64 *)Address = Value;\r
+}\r
+\r
#endif\r
//\r
// Read a byte if StartAddress is byte aligned\r
//\r
- *(UINT8*)Buffer = PciCf8Read8 (StartAddress);\r
+ *(volatile UINT8 *)Buffer = PciCf8Read8 (StartAddress);\r
StartAddress += sizeof (UINT8);\r
Size -= sizeof (UINT8);\r
Buffer = (UINT8*)Buffer + 1;\r
//\r
// Read a word if StartAddress is word aligned\r
//\r
- *(UINT16*)Buffer = PciCf8Read16 (StartAddress);\r
+ *(volatile UINT16 *)Buffer = PciCf8Read16 (StartAddress);\r
StartAddress += sizeof (UINT16);\r
Size -= sizeof (UINT16);\r
Buffer = (UINT16*)Buffer + 1;\r
//\r
// Read as many double words as possible\r
//\r
- *(UINT32*)Buffer = PciCf8Read32 (StartAddress);\r
+ *(volatile UINT32 *)Buffer = PciCf8Read32 (StartAddress);\r
StartAddress += sizeof (UINT32);\r
Size -= sizeof (UINT32);\r
Buffer = (UINT32*)Buffer + 1;\r
//\r
// Read the last remaining word if exist\r
//\r
- *(UINT16*)Buffer = PciCf8Read16 (StartAddress);\r
+ *(volatile UINT16 *)Buffer = PciCf8Read16 (StartAddress);\r
StartAddress += sizeof (UINT16);\r
Size -= sizeof (UINT16);\r
Buffer = (UINT16*)Buffer + 1;\r
//\r
// Read the last remaining byte if exist\r
//\r
- *(UINT8*)Buffer = PciCf8Read8 (StartAddress);\r
+ *(volatile UINT8 *)Buffer = PciCf8Read8 (StartAddress);\r
}\r
\r
return ReturnValue;\r
@return The base address of PCI Express.\r
\r
**/\r
-UINTN\r
+volatile UINTN\r
GetPciExpressBaseAddress (\r
VOID\r
)\r
//\r
// Read a byte if StartAddress is byte aligned\r
//\r
- *(UINT8*)Buffer = PciExpressRead8 (StartAddress);\r
+ *(volatile UINT8 *)Buffer = PciExpressRead8 (StartAddress);\r
StartAddress += sizeof (UINT8);\r
Size -= sizeof (UINT8);\r
Buffer = (UINT8*)Buffer + 1;\r
//\r
// Read a word if StartAddress is word aligned\r
//\r
- *(UINT16*)Buffer = PciExpressRead16 (StartAddress);\r
+ *(volatile UINT16 *)Buffer = PciExpressRead16 (StartAddress);\r
StartAddress += sizeof (UINT16);\r
Size -= sizeof (UINT16);\r
Buffer = (UINT16*)Buffer + 1;\r
//\r
// Read as many double words as possible\r
//\r
- *(UINT32*)Buffer = PciExpressRead32 (StartAddress);\r
+ *(volatile UINT32 *)Buffer = PciExpressRead32 (StartAddress);\r
StartAddress += sizeof (UINT32);\r
Size -= sizeof (UINT32);\r
Buffer = (UINT32*)Buffer + 1;\r
//\r
// Read the last remaining word if exist\r
//\r
- *(UINT16*)Buffer = PciExpressRead16 (StartAddress);\r
+ *(volatile UINT16 *)Buffer = PciExpressRead16 (StartAddress);\r
StartAddress += sizeof (UINT16);\r
Size -= sizeof (UINT16);\r
Buffer = (UINT16*)Buffer + 1;\r
//\r
// Read the last remaining byte if exist\r
//\r
- *(UINT8*)Buffer = PciExpressRead8 (StartAddress);\r
+ *(volatile UINT8 *)Buffer = PciExpressRead8 (StartAddress);\r
}\r
\r
return ReturnValue;\r
OUT VOID **EntryPoint\r
)\r
{\r
- EFI_IMAGE_DOS_HEADER *DosHeader;\r
- EFI_IMAGE_NT_HEADERS *PeHeader;\r
+ EFI_IMAGE_DOS_HEADER *DosHeader;\r
+ EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Header;\r
\r
ASSERT (Pe32Data != NULL);\r
ASSERT (EntryPoint != NULL);\r
\r
DosHeader = (EFI_IMAGE_DOS_HEADER *)Pe32Data;\r
-\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
- PeHeader = (EFI_IMAGE_NT_HEADERS *) ((UINTN) Pe32Data + (UINTN) ((DosHeader->e_lfanew) & 0x0ffff));\r
+ Header.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
- PeHeader = (EFI_IMAGE_NT_HEADERS *) Pe32Data;\r
+ Header.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)Pe32Data;\r
}\r
\r
- *EntryPoint = (VOID *) ((UINTN) Pe32Data + (UINTN) (PeHeader->OptionalHeader.AddressOfEntryPoint & 0x0ffffffff));\r
+ //\r
+ // Calculate the entry point relative to the start of the image. \r
+ // AddressOfEntryPoint is common for PE32 & PE32+\r
+ //\r
+ *EntryPoint = (VOID *)((UINTN)Pe32Data + (UINTN)(Header.Pe32->OptionalHeader.AddressOfEntryPoint & 0x0ffffffff));\r
return RETURN_SUCCESS;\r
}\r
+\r
+\r
+/**\r
+ Returns the machine type of PE/COFF image. \r
+\r
+ @param Image Pointer to a PE/COFF header\r
+\r
+ @return Machine type or zero if not a valid iamge\r
+\r
+**/\r
+UINT16\r
+EFIAPI\r
+PeCoffLoaderGetMachineType (\r
+ IN VOID *Pe32Data\r
+ )\r
+{\r
+ EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr;\r
+ EFI_IMAGE_DOS_HEADER *DosHdr;\r
+\r
+ DosHdr = (EFI_IMAGE_DOS_HEADER *)Pe32Data;\r
+ if (DosHdr->e_magic == EFI_IMAGE_DOS_SIGNATURE) {\r
+ Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)((UINTN)Pe32Data + DosHdr->e_lfanew);\r
+ } else {\r
+ Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)((UINTN)Pe32Data);\r
+ }\r
+\r
+ if (Hdr.Pe32->Signature == EFI_IMAGE_NT_SIGNATURE) {\r
+ return Hdr.Pe32->FileHeader.Machine;\r
+ }\r
+\r
+ return 0x0000;\r
+}\r
+\r
+\r
/** @file\r
Tiano PE/COFF loader.\r
\r
+ This PE/COFF loader supports loading any PE32 or PE32+ image type, but\r
+ only supports relocating IA32, X64, IPF, and EBC images.\r
+\r
Copyright (c) 2006, Intel Corporation\r
All rights reserved. This program and the accompanying materials\r
are licensed and made available under the terms and conditions of the BSD License\r
\r
**/\r
\r
+\r
/**\r
- Performs an Itanium-based specific relocation fixup.\r
+ Performs an Itanium-based specific relocation fixup and is a no-op on other\r
+ instruction sets.\r
\r
@param Reloc Pointer to the relocation record.\r
@param Fixup Pointer to the address to fix up.\r
);\r
\r
\r
+/**\r
+ Performs an Itanium-based specific re-relocation fixup and is a no-op on other\r
+ instruction sets. This is used to re-relocated the image into the EFI virtual\r
+ space for runtime calls.\r
+\r
+ @param Reloc Pointer to the relocation record.\r
+ @param Fixup Pointer to the address to fix up.\r
+ @param FixupData Pointer to a buffer to log the fixups.\r
+ @param Adjust The offset to adjust the fixup.\r
+\r
+ @return Status code.\r
+\r
+**/\r
+RETURN_STATUS\r
+PeHotRelocateImageEx (\r
+ IN UINT16 *Reloc,\r
+ IN OUT CHAR8 *Fixup,\r
+ IN OUT CHAR8 **FixupData,\r
+ IN UINT64 Adjust\r
+ );\r
+\r
+\r
+/**\r
+ Returns TRUE if the machine type of PE/COFF image is supported. Supported \r
+ does not mean the image can be executed it means the PE/COFF loader supports\r
+ loading and relocating of the image type. It's up to the caller to support\r
+ the entry point. \r
+\r
+ @param Machine Machine type from the PE Header.\r
+\r
+ @return TRUE if this PE/COFF loader can load the image\r
+\r
+**/\r
+BOOLEAN\r
+PeCoffLoaderImageFormatSupported (\r
+ IN UINT16 Machine\r
+ );\r
+\r
+\r
\r
/**\r
Retrieves the PE or TE Header from a PE/COFF or TE image.\r
\r
@param ImageContext The context of the image being loaded.\r
- @param PeHdr The buffer in which to return the PE header.\r
- @param TeHdr The buffer in which to return the TE header.\r
+ @param Hdr The buffer in which to return the PE32, PE32+, or TE header.\r
\r
@retval RETURN_SUCCESS The PE or TE Header is read.\r
@retval Other The error status from reading the PE/COFF or TE image using the ImageRead function.\r
\r
**/\r
-STATIC\r
RETURN_STATUS\r
PeCoffLoaderGetPeHeader (\r
- IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext,\r
- OUT EFI_IMAGE_NT_HEADERS *PeHdr,\r
- OUT EFI_TE_IMAGE_HEADER *TeHdr\r
+ IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext,\r
+ OUT EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr\r
)\r
{\r
RETURN_STATUS Status;\r
EFI_IMAGE_DOS_HEADER DosHdr;\r
UINTN Size;\r
\r
- ImageContext->IsTeImage = FALSE;\r
//\r
- // Read the DOS image headers\r
+ // Read the DOS image header to check for it's existance\r
//\r
Size = sizeof (EFI_IMAGE_DOS_HEADER);\r
Status = ImageContext->ImageRead (\r
ImageContext->PeCoffHeaderOffset = 0;\r
if (DosHdr.e_magic == EFI_IMAGE_DOS_SIGNATURE) {\r
//\r
- // DOS image header is present, so read the PE header after the DOS image header\r
+ // DOS image header is present, so read the PE header after the DOS image \r
+ // header\r
//\r
ImageContext->PeCoffHeaderOffset = DosHdr.e_lfanew;\r
}\r
+\r
//\r
- // Read the PE/COFF Header\r
+ // Read the PE/COFF Header. For PE32 (32-bit) this will read in too much \r
+ // data, but that should not hurt anythine. Hdr.Pe32->OptionalHeader.Magic\r
+ // determins if this is a PE32 or PE32+ image. The magic is in the same \r
+ // location in both images.\r
//\r
- Size = sizeof (EFI_IMAGE_NT_HEADERS);\r
+ Size = sizeof (EFI_IMAGE_OPTIONAL_HEADER_UNION);\r
Status = ImageContext->ImageRead (\r
ImageContext->Handle,\r
ImageContext->PeCoffHeaderOffset,\r
&Size,\r
- PeHdr\r
+ Hdr.Pe32\r
);\r
if (RETURN_ERROR (Status)) {\r
ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;\r
return Status;\r
}\r
+\r
//\r
- // Check the PE/COFF Header Signature. If not, then try to read a TE header\r
+ // Use Signature to figure out if we understand the image format\r
//\r
- if (PeHdr->Signature != EFI_IMAGE_NT_SIGNATURE) {\r
- Size = sizeof (EFI_TE_IMAGE_HEADER);\r
- Status = ImageContext->ImageRead (\r
- ImageContext->Handle,\r
- 0,\r
- &Size,\r
- TeHdr\r
- );\r
- if (TeHdr->Signature != EFI_TE_IMAGE_HEADER_SIGNATURE) {\r
- return RETURN_UNSUPPORTED;\r
- }\r
-\r
- ImageContext->IsTeImage = TRUE;\r
- }\r
-\r
- return RETURN_SUCCESS;\r
-}\r
-\r
-/**\r
- Checks the PE or TE header of a PE/COFF or TE image to determine if it supported.\r
-\r
- @param ImageContext The context of the image being loaded.\r
- @param PeHdr The buffer in which to return the PE header.\r
- @param TeHdr The buffer in which to return the TE header.\r
+ if (Hdr.Pe32->Signature == EFI_TE_IMAGE_HEADER_SIGNATURE) {\r
+ ImageContext->IsTeImage = TRUE;\r
+ ImageContext->Machine = Hdr.Te->Machine;\r
+ ImageContext->ImageType = (UINT16)(Hdr.Te->Subsystem);\r
+ ImageContext->ImageSize = 0;\r
+ ImageContext->SectionAlignment = 4096;\r
+ ImageContext->SizeOfHeaders = sizeof (EFI_TE_IMAGE_HEADER) + (UINTN)Hdr.Te->BaseOfCode - (UINTN)Hdr.Te->StrippedSize;\r
\r
- @retval RETURN_SUCCESS The PE/COFF or TE image is supported.\r
- @retval RETURN_UNSUPPORTED The PE/COFF or TE image is not supported.\r
+ } else if (Hdr.Pe32->Signature == EFI_IMAGE_NT_SIGNATURE) {\r
+ ImageContext->IsTeImage = FALSE;\r
+ ImageContext->Machine = Hdr.Pe32->FileHeader.Machine;\r
+ \r
+ if (Hdr.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
+ //\r
+ // Use PE32 offset\r
+ //\r
+ ImageContext->ImageType = Hdr.Pe32->OptionalHeader.Subsystem;\r
+ ImageContext->ImageSize = (UINT64)Hdr.Pe32->OptionalHeader.SizeOfImage;\r
+ ImageContext->SectionAlignment = Hdr.Pe32->OptionalHeader.SectionAlignment;\r
+ ImageContext->SizeOfHeaders = Hdr.Pe32->OptionalHeader.SizeOfHeaders;\r
\r
-**/\r
-STATIC\r
-RETURN_STATUS\r
-PeCoffLoaderCheckImageType (\r
- IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext,\r
- IN EFI_IMAGE_NT_HEADERS *PeHdr,\r
- IN EFI_TE_IMAGE_HEADER *TeHdr\r
- )\r
-{\r
- //\r
- // See if the machine type is supported. We support a native machine type (IA-32/Itanium-based)\r
- // and the machine type for the Virtual Machine.\r
- //\r
- if (ImageContext->IsTeImage == FALSE) {\r
- ImageContext->Machine = PeHdr->FileHeader.Machine;\r
+ } else if (Hdr.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) {\r
+ //\r
+ // Use PE32+ offset\r
+ //\r
+ ImageContext->ImageType = Hdr.Pe32Plus->OptionalHeader.Subsystem;\r
+ ImageContext->ImageSize = (UINT64) Hdr.Pe32Plus->OptionalHeader.SizeOfImage;\r
+ ImageContext->SectionAlignment = Hdr.Pe32Plus->OptionalHeader.SectionAlignment;\r
+ ImageContext->SizeOfHeaders = Hdr.Pe32Plus->OptionalHeader.SizeOfHeaders;\r
+ } else {\r
+ ImageContext->ImageError = IMAGE_ERROR_INVALID_MACHINE_TYPE;\r
+ return RETURN_UNSUPPORTED; \r
+ }\r
} else {\r
- ImageContext->Machine = TeHdr->Machine;\r
- }\r
-\r
- if (!(EFI_IMAGE_MACHINE_TYPE_SUPPORTED (ImageContext->Machine))) {\r
ImageContext->ImageError = IMAGE_ERROR_INVALID_MACHINE_TYPE;\r
return RETURN_UNSUPPORTED;\r
}\r
\r
- //\r
- // See if the image type is supported. We support EFI Applications,\r
- // EFI Boot Service Drivers, and EFI Runtime Drivers.\r
- //\r
- if (ImageContext->IsTeImage == FALSE) {\r
- ImageContext->ImageType = PeHdr->OptionalHeader.Subsystem;\r
- } else {\r
- ImageContext->ImageType = (UINT16) (TeHdr->Subsystem);\r
+ if (!PeCoffLoaderImageFormatSupported (ImageContext->Machine)) {\r
+ //\r
+ // If the PE/COFF loader does not support the image type return\r
+ // unsupported. This library can suport lots of types of images\r
+ // this does not mean the user of this library can call the entry\r
+ // point of the image. \r
+ //\r
+ return RETURN_UNSUPPORTED;\r
}\r
\r
-\r
return RETURN_SUCCESS;\r
}\r
\r
+\r
/**\r
Retrieves information about a PE/COFF image.\r
\r
IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext\r
)\r
{\r
- RETURN_STATUS Status;\r
- EFI_IMAGE_NT_HEADERS PeHdr;\r
- EFI_TE_IMAGE_HEADER TeHdr;\r
- EFI_IMAGE_DATA_DIRECTORY *DebugDirectoryEntry;\r
- UINTN Size;\r
- UINTN Index;\r
- UINTN DebugDirectoryEntryRva;\r
- UINTN DebugDirectoryEntryFileOffset;\r
- UINTN SectionHeaderOffset;\r
- EFI_IMAGE_SECTION_HEADER SectionHeader;\r
- EFI_IMAGE_DEBUG_DIRECTORY_ENTRY DebugEntry;\r
+ RETURN_STATUS Status;\r
+ EFI_IMAGE_OPTIONAL_HEADER_UNION HdrData;\r
+ EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr;\r
+ EFI_IMAGE_DATA_DIRECTORY *DebugDirectoryEntry;\r
+ UINTN Size;\r
+ UINTN Index;\r
+ UINTN DebugDirectoryEntryRva;\r
+ UINTN DebugDirectoryEntryFileOffset;\r
+ UINTN SectionHeaderOffset;\r
+ EFI_IMAGE_SECTION_HEADER SectionHeader;\r
+ EFI_IMAGE_DEBUG_DIRECTORY_ENTRY DebugEntry;\r
+ UINT32 NumberOfRvaAndSizes;\r
\r
if (NULL == ImageContext) {\r
return RETURN_INVALID_PARAMETER;\r
//\r
ImageContext->ImageError = IMAGE_ERROR_SUCCESS;\r
\r
- Status = PeCoffLoaderGetPeHeader (ImageContext, &PeHdr, &TeHdr);\r
- if (RETURN_ERROR (Status)) {\r
- return Status;\r
- }\r
- //\r
- // Verify machine type\r
- //\r
- Status = PeCoffLoaderCheckImageType (ImageContext, &PeHdr, &TeHdr);\r
+ Hdr.Union = &HdrData;\r
+ Status = PeCoffLoaderGetPeHeader (ImageContext, Hdr);\r
if (RETURN_ERROR (Status)) {\r
return Status;\r
}\r
+\r
//\r
// Retrieve the base address of the image\r
//\r
if (!(ImageContext->IsTeImage)) {\r
- ImageContext->ImageAddress = PeHdr.OptionalHeader.ImageBase;\r
+ if (Hdr.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
+ //\r
+ // Use PE32 offset\r
+ //\r
+ ImageContext->ImageAddress = Hdr.Pe32->OptionalHeader.ImageBase;\r
+ } else {\r
+ //\r
+ // Use PE32+ offset\r
+ //\r
+ ImageContext->ImageAddress = Hdr.Pe32Plus->OptionalHeader.ImageBase;\r
+ }\r
} else {\r
- ImageContext->ImageAddress = (PHYSICAL_ADDRESS) (TeHdr.ImageBase);\r
+ ImageContext->ImageAddress = (PHYSICAL_ADDRESS)(Hdr.Te->ImageBase);\r
}\r
+\r
//\r
// Initialize the alternate destination address to 0 indicating that it\r
// should not be used.\r
// Look at the file header to determine if relocations have been stripped, and\r
// save this info in the image context for later use.\r
//\r
- if ((!(ImageContext->IsTeImage)) && ((PeHdr.FileHeader.Characteristics & EFI_IMAGE_FILE_RELOCS_STRIPPED) != 0)) {\r
+ if ((!(ImageContext->IsTeImage)) && ((Hdr.Pe32->FileHeader.Characteristics & EFI_IMAGE_FILE_RELOCS_STRIPPED) != 0)) {\r
ImageContext->RelocationsStripped = TRUE;\r
} else {\r
ImageContext->RelocationsStripped = FALSE;\r
}\r
\r
if (!(ImageContext->IsTeImage)) {\r
- ImageContext->ImageSize = (UINT64) PeHdr.OptionalHeader.SizeOfImage;\r
- ImageContext->SectionAlignment = PeHdr.OptionalHeader.SectionAlignment;\r
- ImageContext->SizeOfHeaders = PeHdr.OptionalHeader.SizeOfHeaders;\r
-\r
- //\r
- // Modify ImageSize to contain .PDB file name if required and initialize\r
- // PdbRVA field...\r
- //\r
- if (PeHdr.OptionalHeader.NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_DEBUG) {\r
- DebugDirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *) &(PeHdr.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG]);\r
+ if (Hdr.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
+ // \r
+ // Use PE32 offset\r
+ //\r
+ NumberOfRvaAndSizes = Hdr.Pe32->OptionalHeader.NumberOfRvaAndSizes;\r
+ DebugDirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *)&(Hdr.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG]);\r
+ } else {\r
+ // \r
+ // Use PE32+ offset\r
+ //\r
+ NumberOfRvaAndSizes = Hdr.Pe32Plus->OptionalHeader.NumberOfRvaAndSizes;\r
+ DebugDirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *)&(Hdr.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG]);\r
+ } \r
+ \r
+ if (NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_DEBUG) {\r
\r
DebugDirectoryEntryRva = DebugDirectoryEntry->VirtualAddress;\r
\r
ImageContext->PeCoffHeaderOffset +\r
sizeof (UINT32) + \r
sizeof (EFI_IMAGE_FILE_HEADER) + \r
- PeHdr.FileHeader.SizeOfOptionalHeader\r
+ Hdr.Pe32->FileHeader.SizeOfOptionalHeader\r
);\r
\r
- for (Index = 0; Index < PeHdr.FileHeader.NumberOfSections; Index++) {\r
+ for (Index = 0; Index < Hdr.Pe32->FileHeader.NumberOfSections; Index++) {\r
//\r
// Read section header from file\r
//\r
\r
if (DebugDirectoryEntryRva >= SectionHeader.VirtualAddress &&\r
DebugDirectoryEntryRva < SectionHeader.VirtualAddress + SectionHeader.Misc.VirtualSize) {\r
- DebugDirectoryEntryFileOffset =\r
- DebugDirectoryEntryRva - SectionHeader.VirtualAddress + SectionHeader.PointerToRawData;\r
+\r
+ DebugDirectoryEntryFileOffset = DebugDirectoryEntryRva - SectionHeader.VirtualAddress + SectionHeader.PointerToRawData;\r
break;\r
}\r
\r
}\r
}\r
} else {\r
- ImageContext->ImageSize = 0;\r
- ImageContext->SectionAlignment = 4096;\r
- ImageContext->SizeOfHeaders = sizeof (EFI_TE_IMAGE_HEADER) + (UINTN) TeHdr.BaseOfCode - (UINTN) TeHdr.StrippedSize;\r
\r
- DebugDirectoryEntry = &TeHdr.DataDirectory[1];\r
+ DebugDirectoryEntry = &Hdr.Te->DataDirectory[1];\r
DebugDirectoryEntryRva = DebugDirectoryEntry->VirtualAddress;\r
- SectionHeaderOffset = (UINTN) (sizeof (EFI_TE_IMAGE_HEADER));\r
+ SectionHeaderOffset = (UINTN)(sizeof (EFI_TE_IMAGE_HEADER));\r
\r
DebugDirectoryEntryFileOffset = 0;\r
\r
- for (Index = 0; Index < TeHdr.NumberOfSections;) {\r
+ for (Index = 0; Index < Hdr.Te->NumberOfSections;) {\r
//\r
// Read section header from file\r
//\r
SectionHeader.VirtualAddress +\r
SectionHeader.PointerToRawData +\r
sizeof (EFI_TE_IMAGE_HEADER) -\r
- TeHdr.StrippedSize;\r
+ Hdr.Te->StrippedSize;\r
\r
//\r
// File offset of the debug directory was found, if this is not the last\r
// section, then skip to the last section for calculating the image size.\r
//\r
- if (Index < (UINTN) TeHdr.NumberOfSections - 1) {\r
- SectionHeaderOffset += (TeHdr.NumberOfSections - 1 - Index) * sizeof (EFI_IMAGE_SECTION_HEADER);\r
- Index = TeHdr.NumberOfSections - 1;\r
+ if (Index < (UINTN) Hdr.Te->NumberOfSections - 1) {\r
+ SectionHeaderOffset += (Hdr.Te->NumberOfSections - 1 - Index) * sizeof (EFI_IMAGE_SECTION_HEADER);\r
+ Index = Hdr.Te->NumberOfSections - 1;\r
continue;\r
}\r
}\r
// by the RVA and the VirtualSize of the last section header in the\r
// Section Table.\r
//\r
- if ((++Index) == (UINTN) TeHdr.NumberOfSections) {\r
+ if ((++Index) == (UINTN)Hdr.Te->NumberOfSections) {\r
ImageContext->ImageSize = (SectionHeader.VirtualAddress + SectionHeader.Misc.VirtualSize +\r
ImageContext->SectionAlignment - 1) & ~(ImageContext->SectionAlignment - 1);\r
}\r
return RETURN_SUCCESS;\r
}\r
\r
+\r
/**\r
Converts an image address to the loaded address.\r
\r
@return The converted address or NULL if the address can not be converted.\r
\r
**/\r
-STATIC\r
VOID *\r
PeCoffLoaderImageAddress (\r
IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext,\r
IN UINTN Address\r
)\r
{\r
- if (Address >= ImageContext->ImageSize) {\r
- ImageContext->ImageError = IMAGE_ERROR_INVALID_IMAGE_ADDRESS;\r
- return NULL;\r
- }\r
-\r
- return (CHAR8 *) ((UINTN) ImageContext->ImageAddress + Address);\r
+ return (CHAR8 *)((UINTN) ImageContext->ImageAddress + Address);\r
}\r
\r
/**\r
IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext\r
)\r
{\r
- RETURN_STATUS Status;\r
- EFI_IMAGE_NT_HEADERS *PeHdr;\r
- EFI_TE_IMAGE_HEADER *TeHdr;\r
- EFI_IMAGE_DATA_DIRECTORY *RelocDir;\r
- UINT64 Adjust;\r
- EFI_IMAGE_BASE_RELOCATION *RelocBase;\r
- EFI_IMAGE_BASE_RELOCATION *RelocBaseEnd;\r
- UINT16 *Reloc;\r
- UINT16 *RelocEnd;\r
- CHAR8 *Fixup;\r
- CHAR8 *FixupBase;\r
- UINT16 *F16;\r
- UINT32 *F32;\r
- CHAR8 *FixupData;\r
- PHYSICAL_ADDRESS BaseAddress;\r
+ RETURN_STATUS Status;\r
+ EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr;\r
+ EFI_IMAGE_DATA_DIRECTORY *RelocDir;\r
+ UINT64 Adjust;\r
+ EFI_IMAGE_BASE_RELOCATION *RelocBase;\r
+ EFI_IMAGE_BASE_RELOCATION *RelocBaseEnd;\r
+ UINT16 *Reloc;\r
+ UINT16 *RelocEnd;\r
+ CHAR8 *Fixup;\r
+ CHAR8 *FixupBase;\r
+ UINT16 *F16;\r
+ UINT32 *F32; \r
+ UINT64 *F64;\r
+ CHAR8 *FixupData;\r
+ PHYSICAL_ADDRESS BaseAddress;\r
+ UINT32 NumberOfRvaAndSizes;\r
\r
ASSERT (ImageContext != NULL);\r
\r
- PeHdr = NULL;\r
- TeHdr = NULL;\r
//\r
// Assume success\r
//\r
}\r
\r
if (!(ImageContext->IsTeImage)) {\r
- PeHdr = (EFI_IMAGE_NT_HEADERS *)((UINTN)ImageContext->ImageAddress + \r
- ImageContext->PeCoffHeaderOffset);\r
- \r
- Adjust = (UINT64) BaseAddress - PeHdr->OptionalHeader.ImageBase;\r
- PeHdr->OptionalHeader.ImageBase = (UINTN)BaseAddress;\r
+ Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)((UINTN)ImageContext->ImageAddress + ImageContext->PeCoffHeaderOffset);\r
+ if (Hdr.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
+ //\r
+ // Use PE32 offset\r
+ //\r
+ Adjust = (UINT64)BaseAddress - Hdr.Pe32->OptionalHeader.ImageBase;\r
+ Hdr.Pe32->OptionalHeader.ImageBase = (UINT32)BaseAddress;\r
+ \r
+ NumberOfRvaAndSizes = Hdr.Pe32->OptionalHeader.NumberOfRvaAndSizes;\r
+ RelocDir = &Hdr.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC];\r
+ } else {\r
+ //\r
+ // Use PE32+ offset\r
+ //\r
+ Adjust = (UINT64) BaseAddress - Hdr.Pe32Plus->OptionalHeader.ImageBase;\r
+ Hdr.Pe32Plus->OptionalHeader.ImageBase = (UINT64)BaseAddress;\r
+\r
+ NumberOfRvaAndSizes = Hdr.Pe32Plus->OptionalHeader.NumberOfRvaAndSizes;\r
+ RelocDir = &Hdr.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC];\r
+ }\r
\r
//\r
// Find the relocation block\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
//\r
- if (PeHdr->OptionalHeader.NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC) {\r
- RelocDir = &PeHdr->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC];\r
+\r
+ if (NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC) {\r
RelocBase = PeCoffLoaderImageAddress (ImageContext, RelocDir->VirtualAddress);\r
RelocBaseEnd = PeCoffLoaderImageAddress (\r
ImageContext,\r
RelocBase = RelocBaseEnd = 0;\r
}\r
} else {\r
- TeHdr = (EFI_TE_IMAGE_HEADER *) (UINTN) (ImageContext->ImageAddress);\r
- Adjust = (UINT64) (BaseAddress - TeHdr->ImageBase);\r
- TeHdr->ImageBase = (UINT64) (BaseAddress);\r
+ Hdr.Te = (EFI_TE_IMAGE_HEADER *)(UINTN)(ImageContext->ImageAddress);\r
+ Adjust = (UINT64) (BaseAddress - Hdr.Te->ImageBase);\r
+ Hdr.Te->ImageBase = (UINT64) (BaseAddress);\r
\r
//\r
// Find the relocation block\r
//\r
- RelocDir = &TeHdr->DataDirectory[0];\r
+ RelocDir = &Hdr.Te->DataDirectory[0];\r
RelocBase = (EFI_IMAGE_BASE_RELOCATION *)(UINTN)(\r
ImageContext->ImageAddress + \r
RelocDir->VirtualAddress +\r
sizeof(EFI_TE_IMAGE_HEADER) - \r
- TeHdr->StrippedSize\r
+ Hdr.Te->StrippedSize\r
);\r
RelocBaseEnd = (EFI_IMAGE_BASE_RELOCATION *) ((UINTN) RelocBase + (UINTN) RelocDir->Size - 1);\r
}\r
FixupBase = (CHAR8 *)(UINTN)(ImageContext->ImageAddress +\r
RelocBase->VirtualAddress +\r
sizeof(EFI_TE_IMAGE_HEADER) - \r
- TeHdr->StrippedSize\r
+ Hdr.Te->StrippedSize\r
);\r
}\r
\r
*F32 = *F32 + (UINT32) Adjust;\r
if (FixupData != NULL) {\r
FixupData = ALIGN_POINTER (FixupData, sizeof (UINT32));\r
- *(UINT32 *) FixupData = *F32;\r
+ *(UINT32 *)FixupData = *F32;\r
FixupData = FixupData + sizeof (UINT32);\r
}\r
break;\r
\r
- case EFI_IMAGE_REL_BASED_HIGHADJ:\r
- //\r
- // Return the same EFI_UNSUPPORTED return code as\r
- // PeCoffLoaderRelocateImageEx() returns if it does not recognize\r
- // the relocation type.\r
- //\r
- ImageContext->ImageError = IMAGE_ERROR_FAILED_RELOCATION;\r
- return RETURN_UNSUPPORTED;\r
+ case EFI_IMAGE_REL_BASED_DIR64:\r
+ F64 = (UINT64 *) Fixup;\r
+ *F64 = *F64 + (UINT64) Adjust;\r
+ if (FixupData != NULL) {\r
+ FixupData = ALIGN_POINTER (FixupData, sizeof(UINT64));\r
+ *(UINT64 *)(FixupData) = *F64;\r
+ FixupData = FixupData + sizeof(UINT64);\r
+ }\r
+ break;\r
\r
default:\r
+ //\r
+ // The common code does not handle some of the stranger IPF relocations\r
+ // PeCoffLoaderRelocateImageEx () addes support for these complex fixups\r
+ // on IPF and is a No-Op on other archtiectures.\r
+ //\r
Status = PeCoffLoaderRelocateImageEx (Reloc, Fixup, &FixupData, Adjust);\r
if (RETURN_ERROR (Status)) {\r
ImageContext->ImageError = IMAGE_ERROR_FAILED_RELOCATION;\r
)\r
{\r
RETURN_STATUS Status;\r
- EFI_IMAGE_NT_HEADERS *PeHdr;\r
- EFI_TE_IMAGE_HEADER *TeHdr;\r
+ EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr;\r
PE_COFF_LOADER_IMAGE_CONTEXT CheckContext;\r
EFI_IMAGE_SECTION_HEADER *FirstSection;\r
EFI_IMAGE_SECTION_HEADER *Section;\r
EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *DebugEntry;\r
UINTN Size;\r
UINT32 TempDebugEntryRva;\r
+ UINT32 NumberOfRvaAndSizes;\r
\r
ASSERT (ImageContext != NULL);\r
\r
- PeHdr = NULL;\r
- TeHdr = NULL;\r
-\r
//\r
// Assume success\r
//\r
(VOID *) (UINTN) ImageContext->ImageAddress\r
);\r
\r
- PeHdr = (EFI_IMAGE_NT_HEADERS *)\r
- ((UINTN)ImageContext->ImageAddress + ImageContext->PeCoffHeaderOffset);\r
+ Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)((UINTN)ImageContext->ImageAddress + ImageContext->PeCoffHeaderOffset);\r
\r
FirstSection = (EFI_IMAGE_SECTION_HEADER *) (\r
(UINTN)ImageContext->ImageAddress +\r
ImageContext->PeCoffHeaderOffset +\r
sizeof(UINT32) + \r
sizeof(EFI_IMAGE_FILE_HEADER) + \r
- PeHdr->FileHeader.SizeOfOptionalHeader\r
+ Hdr.Pe32->FileHeader.SizeOfOptionalHeader\r
);\r
- NumberOfSections = (UINTN) (PeHdr->FileHeader.NumberOfSections);\r
+ NumberOfSections = (UINTN) (Hdr.Pe32->FileHeader.NumberOfSections);\r
} else {\r
Status = ImageContext->ImageRead (\r
ImageContext->Handle,\r
0,\r
&ImageContext->SizeOfHeaders,\r
- (void *) (UINTN) ImageContext->ImageAddress\r
+ (void *)(UINTN)ImageContext->ImageAddress\r
);\r
\r
- TeHdr = (EFI_TE_IMAGE_HEADER *) (UINTN) (ImageContext->ImageAddress);\r
+ Hdr.Te = (EFI_TE_IMAGE_HEADER *)(UINTN)(ImageContext->ImageAddress);\r
\r
FirstSection = (EFI_IMAGE_SECTION_HEADER *) (\r
- (UINTN)ImageContext->ImageAddress +\r
- sizeof(EFI_TE_IMAGE_HEADER)\r
- );\r
- NumberOfSections = (UINTN) (TeHdr->NumberOfSections);\r
+ (UINTN)ImageContext->ImageAddress +\r
+ sizeof(EFI_TE_IMAGE_HEADER)\r
+ );\r
+ NumberOfSections = (UINTN) (Hdr.Te->NumberOfSections);\r
\r
}\r
\r
Section->VirtualAddress + Section->Misc.VirtualSize - 1\r
);\r
if (ImageContext->IsTeImage) {\r
- Base = (CHAR8 *) ((UINTN) Base + sizeof (EFI_TE_IMAGE_HEADER) - (UINTN) TeHdr->StrippedSize);\r
- End = (CHAR8 *) ((UINTN) End + sizeof (EFI_TE_IMAGE_HEADER) - (UINTN) TeHdr->StrippedSize);\r
+ Base = (CHAR8 *)((UINTN) Base + sizeof (EFI_TE_IMAGE_HEADER) - (UINTN)Hdr.Te->StrippedSize);\r
+ End = (CHAR8 *)((UINTN) End + sizeof (EFI_TE_IMAGE_HEADER) - (UINTN)Hdr.Te->StrippedSize);\r
}\r
\r
if (End > MaxEnd) {\r
} else {\r
Status = ImageContext->ImageRead (\r
ImageContext->Handle,\r
- Section->PointerToRawData + sizeof (EFI_TE_IMAGE_HEADER) - (UINTN) TeHdr->StrippedSize,\r
+ Section->PointerToRawData + sizeof (EFI_TE_IMAGE_HEADER) - (UINTN)Hdr.Te->StrippedSize,\r
&Size,\r
Base\r
);\r
// Get image's entry point\r
//\r
if (!(ImageContext->IsTeImage)) {\r
- ImageContext->EntryPoint = (PHYSICAL_ADDRESS) (UINTN) PeCoffLoaderImageAddress (\r
- ImageContext,\r
- PeHdr->OptionalHeader.AddressOfEntryPoint\r
- );\r
+ //\r
+ // Sizes of AddressOfEntryPoint are different so we need to do this safely\r
+ //\r
+ if (Hdr.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
+ //\r
+ // Use PE32 offset\r
+ // \r
+ ImageContext->EntryPoint = (PHYSICAL_ADDRESS)(UINTN)PeCoffLoaderImageAddress (\r
+ ImageContext,\r
+ (UINTN)Hdr.Pe32->OptionalHeader.AddressOfEntryPoint\r
+ );\r
+ } else {\r
+ //\r
+ // Use PE32+ offset\r
+ //\r
+ ImageContext->EntryPoint = (PHYSICAL_ADDRESS)(UINTN)PeCoffLoaderImageAddress (\r
+ ImageContext,\r
+ (UINTN)Hdr.Pe32Plus->OptionalHeader.AddressOfEntryPoint\r
+ );\r
+ }\r
} else {\r
ImageContext->EntryPoint = (PHYSICAL_ADDRESS) (\r
- (UINTN)ImageContext->ImageAddress +\r
- (UINTN)TeHdr->AddressOfEntryPoint +\r
- (UINTN)sizeof(EFI_TE_IMAGE_HEADER) -\r
- (UINTN) TeHdr->StrippedSize\r
- );\r
+ (UINTN)ImageContext->ImageAddress +\r
+ (UINTN)Hdr.Te->AddressOfEntryPoint +\r
+ (UINTN)sizeof(EFI_TE_IMAGE_HEADER) -\r
+ (UINTN)Hdr.Te->StrippedSize\r
+ );\r
}\r
\r
//\r
// the optional header to verify a desired directory entry is there.\r
//\r
if (!(ImageContext->IsTeImage)) {\r
- if (PeHdr->OptionalHeader.NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC) {\r
- DirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *)\r
- &PeHdr->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC];\r
+ if (Hdr.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
+ //\r
+ // Use PE32 offset\r
+ //\r
+ NumberOfRvaAndSizes = Hdr.Pe32->OptionalHeader.NumberOfRvaAndSizes;\r
+ DirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *)&Hdr.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC];\r
+ } else {\r
+ //\r
+ // Use PE32+ offset\r
+ //\r
+ NumberOfRvaAndSizes = Hdr.Pe32Plus->OptionalHeader.NumberOfRvaAndSizes;\r
+ DirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *)&Hdr.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC];\r
+ }\r
+ \r
+ if (NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC) {\r
ImageContext->FixupDataSize = DirectoryEntry->Size / sizeof (UINT16) * sizeof (UINTN);\r
} else {\r
ImageContext->FixupDataSize = 0;\r
}\r
} else {\r
- DirectoryEntry = &TeHdr->DataDirectory[0];\r
+ DirectoryEntry = &Hdr.Te->DataDirectory[0];\r
ImageContext->FixupDataSize = DirectoryEntry->Size / sizeof (UINT16) * sizeof (UINTN);\r
}\r
//\r
);\r
} else {\r
DebugEntry = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *)(UINTN)(\r
- ImageContext->ImageAddress +\r
- ImageContext->DebugDirectoryEntryRva +\r
- sizeof(EFI_TE_IMAGE_HEADER) -\r
- TeHdr->StrippedSize\r
- );\r
+ ImageContext->ImageAddress +\r
+ ImageContext->DebugDirectoryEntryRva +\r
+ sizeof(EFI_TE_IMAGE_HEADER) -\r
+ Hdr.Te->StrippedSize\r
+ );\r
}\r
\r
if (DebugEntry != NULL) {\r
TempDebugEntryRva = DebugEntry->RVA;\r
if (DebugEntry->RVA == 0 && DebugEntry->FileOffset != 0) {\r
Section--;\r
- if ((UINTN) Section->SizeOfRawData < Section->Misc.VirtualSize) {\r
+ if ((UINTN)Section->SizeOfRawData < Section->Misc.VirtualSize) {\r
TempDebugEntryRva = Section->VirtualAddress + Section->Misc.VirtualSize;\r
} else {\r
TempDebugEntryRva = Section->VirtualAddress + Section->SizeOfRawData;\r
ImageContext->CodeView = PeCoffLoaderImageAddress (ImageContext, TempDebugEntryRva);\r
} else {\r
ImageContext->CodeView = (VOID *)(\r
- (UINTN)ImageContext->ImageAddress +\r
- (UINTN)TempDebugEntryRva +\r
- (UINTN)sizeof(EFI_TE_IMAGE_HEADER) -\r
- (UINTN) TeHdr->StrippedSize\r
- );\r
+ (UINTN)ImageContext->ImageAddress +\r
+ (UINTN)TempDebugEntryRva +\r
+ (UINTN)sizeof (EFI_TE_IMAGE_HEADER) -\r
+ (UINTN) Hdr.Te->StrippedSize\r
+ );\r
}\r
\r
if (ImageContext->CodeView == NULL) {\r
} else {\r
Status = ImageContext->ImageRead (\r
ImageContext->Handle,\r
- DebugEntry->FileOffset + sizeof (EFI_TE_IMAGE_HEADER) - TeHdr->StrippedSize,\r
+ DebugEntry->FileOffset + sizeof (EFI_TE_IMAGE_HEADER) - Hdr.Te->StrippedSize,\r
&Size,\r
ImageContext->CodeView\r
);\r
\r
switch (*(UINT32 *) ImageContext->CodeView) {\r
case CODEVIEW_SIGNATURE_NB10:\r
- ImageContext->PdbPointer = (CHAR8 *) ImageContext->CodeView + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY);\r
+ ImageContext->PdbPointer = (CHAR8 *)ImageContext->CodeView + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY);\r
break;\r
\r
case CODEVIEW_SIGNATURE_RSDS:\r
- ImageContext->PdbPointer = (CHAR8 *) ImageContext->CodeView + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_RSDS_ENTRY);\r
+ ImageContext->PdbPointer = (CHAR8 *)ImageContext->CodeView + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_RSDS_ENTRY);\r
break;\r
\r
default:\r
\r
return Status;\r
}\r
+\r
+\r
+/**\r
+ Reapply fixups on a fixed up PE32/PE32+ image to allow virutal calling at EFI\r
+ runtime. \r
+ \r
+ PE_COFF_LOADER_IMAGE_CONTEXT.FixupData stores information needed to reapply\r
+ the fixups with a virtual mapping.\r
+\r
+\r
+ @param ImageBase Base address of relocated image\r
+ @param VirtImageBase Virtual mapping for ImageBase\r
+ @param ImageSize Size of the image to relocate\r
+ @param RelocationData Location to place results of read\r
+ \r
+**/\r
+VOID\r
+EFIAPI\r
+PeCoffLoaderRelocateImageForRuntime (\r
+ IN PHYSICAL_ADDRESS ImageBase,\r
+ IN PHYSICAL_ADDRESS VirtImageBase,\r
+ IN UINTN ImageSize,\r
+ IN VOID *RelocationData\r
+ )\r
+{\r
+ CHAR8 *OldBase;\r
+ CHAR8 *NewBase;\r
+ EFI_IMAGE_DOS_HEADER *DosHdr;\r
+ EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr;\r
+ UINT32 NumberOfRvaAndSizes;\r
+ EFI_IMAGE_DATA_DIRECTORY *DataDirectory;\r
+ EFI_IMAGE_DATA_DIRECTORY *RelocDir;\r
+ EFI_IMAGE_BASE_RELOCATION *RelocBase;\r
+ EFI_IMAGE_BASE_RELOCATION *RelocBaseEnd;\r
+ UINT16 *Reloc;\r
+ UINT16 *RelocEnd;\r
+ CHAR8 *Fixup;\r
+ CHAR8 *FixupBase;\r
+ UINT16 *F16;\r
+ UINT32 *F32;\r
+ UINT64 *F64;\r
+ CHAR8 *FixupData;\r
+ UINTN Adjust;\r
+ RETURN_STATUS Status;\r
+\r
+ OldBase = (CHAR8 *)((UINTN)ImageBase);\r
+ NewBase = (CHAR8 *)((UINTN)VirtImageBase);\r
+ Adjust = (UINTN) NewBase - (UINTN) OldBase;\r
+\r
+ //\r
+ // Find the image's relocate dir info\r
+ //\r
+ DosHdr = (EFI_IMAGE_DOS_HEADER *)OldBase;\r
+ if (DosHdr->e_magic == EFI_IMAGE_DOS_SIGNATURE) {\r
+ //\r
+ // Valid DOS header so get address of PE header\r
+ //\r
+ Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)(((CHAR8 *)DosHdr) + DosHdr->e_lfanew);\r
+ } else {\r
+ //\r
+ // No Dos header so assume image starts with PE header.\r
+ //\r
+ Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)OldBase;\r
+ }\r
+\r
+ if (Hdr.Pe32->Signature != EFI_IMAGE_NT_SIGNATURE) {\r
+ //\r
+ // Not a valid PE image so Exit\r
+ //\r
+ return ;\r
+ }\r
+\r
+ //\r
+ // Get some data from the PE type dependent data\r
+ //\r
+ if (Hdr.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
+ // \r
+ // Use PE32 offset\r
+ //\r
+ NumberOfRvaAndSizes = Hdr.Pe32->OptionalHeader.NumberOfRvaAndSizes;\r
+ DataDirectory = (EFI_IMAGE_DATA_DIRECTORY *)&(Hdr.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG]);\r
+ } else {\r
+ // \r
+ // Use PE32+ offset\r
+ //\r
+ NumberOfRvaAndSizes = Hdr.Pe32Plus->OptionalHeader.NumberOfRvaAndSizes;\r
+ DataDirectory = (EFI_IMAGE_DATA_DIRECTORY *)&(Hdr.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG]);\r
+ } \r
+\r
+ //\r
+ // Find the relocation block\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
+ // \r
+ if (NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC) {\r
+ RelocDir = DataDirectory + EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC;\r
+ RelocBase = (EFI_IMAGE_BASE_RELOCATION *)(UINTN)(ImageBase + RelocDir->VirtualAddress);\r
+ RelocBaseEnd = (EFI_IMAGE_BASE_RELOCATION *)(UINTN)(ImageBase + RelocDir->VirtualAddress + RelocDir->Size);\r
+ } else {\r
+ //\r
+ // Cannot find relocations, cannot continue\r
+ //\r
+ ASSERT (FALSE);\r
+ return ;\r
+ }\r
+\r
+ ASSERT (RelocBase != NULL && RelocBaseEnd != NULL);\r
+\r
+ //\r
+ // Run the whole relocation block. And re-fixup data that has not been\r
+ // modified. The FixupData is used to see if the image has been modified\r
+ // since it was relocated. This is so data sections that have been updated\r
+ // by code will not be fixed up, since that would set them back to\r
+ // defaults.\r
+ //\r
+ FixupData = RelocationData;\r
+ while (RelocBase < RelocBaseEnd) {\r
+\r
+ Reloc = (UINT16 *) ((UINT8 *) RelocBase + sizeof (EFI_IMAGE_BASE_RELOCATION));\r
+ RelocEnd = (UINT16 *) ((UINT8 *) RelocBase + RelocBase->SizeOfBlock);\r
+ FixupBase = (CHAR8 *) ((UINTN)ImageBase) + RelocBase->VirtualAddress;\r
+\r
+ //\r
+ // Run this relocation record\r
+ //\r
+ while (Reloc < RelocEnd) {\r
+\r
+ Fixup = FixupBase + (*Reloc & 0xFFF);\r
+ switch ((*Reloc) >> 12) {\r
+\r
+ case EFI_IMAGE_REL_BASED_ABSOLUTE:\r
+ break;\r
+\r
+ case EFI_IMAGE_REL_BASED_HIGH:\r
+ F16 = (UINT16 *) Fixup;\r
+ if (*(UINT16 *) FixupData == *F16) {\r
+ *F16 = (UINT16) ((*F16 << 16) + ((UINT16) Adjust & 0xffff));\r
+ }\r
+\r
+ FixupData = FixupData + sizeof (UINT16);\r
+ break;\r
+\r
+ case EFI_IMAGE_REL_BASED_LOW:\r
+ F16 = (UINT16 *) Fixup;\r
+ if (*(UINT16 *) FixupData == *F16) {\r
+ *F16 = (UINT16) (*F16 + ((UINT16) Adjust & 0xffff));\r
+ }\r
+\r
+ FixupData = FixupData + sizeof (UINT16);\r
+ break;\r
+\r
+ case EFI_IMAGE_REL_BASED_HIGHLOW:\r
+ F32 = (UINT32 *) Fixup;\r
+ FixupData = ALIGN_POINTER (FixupData, sizeof (UINT32));\r
+ if (*(UINT32 *) FixupData == *F32) {\r
+ *F32 = *F32 + (UINT32) Adjust;\r
+ }\r
+\r
+ FixupData = FixupData + sizeof (UINT32);\r
+ break;\r
+\r
+ case EFI_IMAGE_REL_BASED_DIR64:\r
+ F64 = (UINT64 *)Fixup;\r
+ FixupData = ALIGN_POINTER (FixupData, sizeof (UINT64));\r
+ if (*(UINT32 *) FixupData == *F64) {\r
+ *F64 = *F64 + (UINT64)Adjust;\r
+ }\r
+ break;\r
+\r
+ case EFI_IMAGE_REL_BASED_HIGHADJ:\r
+ //\r
+ // Not implemented, but not used in EFI 1.0\r
+ //\r
+ ASSERT (FALSE);\r
+ break;\r
+\r
+ default:\r
+ //\r
+ // Only Itanium requires ConvertPeImage_Ex\r
+ //\r
+ Status = PeHotRelocateImageEx (Reloc, Fixup, &FixupData, Adjust);\r
+ if (RETURN_ERROR (Status)) {\r
+ return ;\r
+ }\r
+ }\r
+ //\r
+ // Next relocation record\r
+ //\r
+ Reloc += 1;\r
+ }\r
+ //\r
+ // next reloc block\r
+ //\r
+ RelocBase = (EFI_IMAGE_BASE_RELOCATION *) RelocEnd;\r
+ }\r
+}\r
+\r
+\r
+/**\r
+ ImageRead function that operates on a memory buffer whos base is passed into\r
+ FileHandle. \r
+\r
+ @param FileHandle Ponter to baes of the input stream\r
+ @param FileOffset Offset to the start of the buffer\r
+ @param ReadSize Number of bytes to copy into the buffer\r
+ @param Buffer Location to place results of read\r
+\r
+ @retval RETURN_SUCCESS Data is read from FileOffset from the Handle into \r
+ the buffer.\r
+**/\r
+RETURN_STATUS\r
+EFIAPI\r
+PeCoffLoaderImageReadFromMemory (\r
+ IN VOID *FileHandle,\r
+ IN UINTN FileOffset,\r
+ IN OUT UINTN *ReadSize,\r
+ OUT VOID *Buffer\r
+ )\r
+{\r
+ CopyMem (Buffer, ((UINT8 *)FileHandle) + FileOffset, *ReadSize);\r
+ return RETURN_SUCCESS;\r
+}\r
+\r
<?xml version="1.0" encoding="UTF-8"?>\r
-<!--\r
-Copyright (c) 2006, Intel Corporation\r
-All rights reserved. This program and the accompanying materials\r
-are licensed and made available under the terms and conditions of the BSD License\r
-which accompanies this distribution. The full text of the license may be found at\r
-http://opensource.org/licenses/bsd-license.php\r
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
--->\r
-<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0">\r
+<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">\r
<MsaHeader>\r
<ModuleName>BasePeCoffLib</ModuleName>\r
<ModuleType>BASE</ModuleType>\r
<Abstract>Component description file for Base PE/COFF Library</Abstract>\r
<Description>PE/COFF Loader Library implementation.</Description>\r
<Copyright>Copyright (c) 2006, Intel Corporation.</Copyright>\r
- <License>All rights reserved. This program and the accompanying materials\r
- are licensed and made available under the terms and conditions of the BSD License\r
- which accompanies this distribution. The full text of the license may be found at\r
- http://opensource.org/licenses/bsd-license.php\r
- THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+ <License>All rights reserved. This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.</License>\r
<Specification>FRAMEWORK_BUILD_PACKAGING_SPECIFICATION 0x00000052</Specification>\r
</MsaHeader>\r
<LibraryClass Usage="ALWAYS_CONSUMED">\r
<Keyword>DebugLib</Keyword>\r
</LibraryClass>\r
+ <LibraryClass Usage="ALWAYS_CONSUMED">\r
+ <Keyword>PcdLib</Keyword>\r
+ </LibraryClass>\r
</LibraryClassDefinitions>\r
<SourceFiles>\r
<Filename>BasePeCoff.c</Filename>\r
{\r
return RETURN_UNSUPPORTED;\r
}\r
+\r
+/**\r
+ Returns TRUE if the machine type of PE/COFF image is supported. Supported \r
+ does not mean the image can be executed it means the PE/COFF loader supports\r
+ loading and relocating of the image type. It's up to the caller to support\r
+ the entry point. \r
+\r
+ This function implies the basic PE/COFF loader/relocator supports IA32, EBC,\r
+ & X64 images. Calling the entry point in a correct mannor is up to the \r
+ consumer of this library.\r
+\r
+ @param Machine Machine type from the PE Header.\r
+\r
+ @return TRUE if this PE/COFF loader can load the image\r
+\r
+**/\r
+BOOLEAN\r
+PeCoffLoaderImageFormatSupported (\r
+ IN UINT16 Machine\r
+ )\r
+{\r
+ if ((Machine == EFI_IMAGE_MACHINE_IA32) || (Machine == EFI_IMAGE_MACHINE_X64) || \r
+ (Machine == EFI_IMAGE_MACHINE_EBC)) {\r
+ return TRUE; \r
+ }\r
+\r
+ return FALSE;\r
+}\r
+\r
+\r
+/**\r
+ Performs an Itanium-based specific re-relocation fixup and is a no-op on other\r
+ instruction sets. This is used to re-relocated the image into the EFI virtual\r
+ space for runtime calls.\r
+\r
+ @param Reloc Pointer to the relocation record.\r
+ @param Fixup Pointer to the address to fix up.\r
+ @param FixupData Pointer to a buffer to log the fixups.\r
+ @param Adjust The offset to adjust the fixup.\r
+\r
+ @return Status code.\r
+\r
+**/\r
+RETURN_STATUS\r
+PeHotRelocateImageEx (\r
+ IN UINT16 *Reloc,\r
+ IN OUT CHAR8 *Fixup,\r
+ IN OUT CHAR8 **FixupData,\r
+ IN UINT64 Adjust\r
+ )\r
+{\r
+ return RETURN_UNSUPPORTED;\r
+}\r
{\r
return RETURN_UNSUPPORTED;\r
}\r
+\r
+/**\r
+ Returns TRUE if the machine type of PE/COFF image is supported. Supported \r
+ does not mean the image can be executed it means the PE/COFF loader supports\r
+ loading and relocating of the image type. It's up to the caller to support\r
+ the entry point. \r
+\r
+ This function implies the basic PE/COFF loader/relocator supports IA32, EBC,\r
+ & X64 images. Calling the entry point in a correct mannor is up to the \r
+ consumer of this library.\r
+\r
+ @param Machine Machine type from the PE Header.\r
+\r
+ @return TRUE if this PE/COFF loader can load the image\r
+\r
+**/\r
+BOOLEAN\r
+PeCoffLoaderImageFormatSupported (\r
+ IN UINT16 Machine\r
+ )\r
+{\r
+ if ((Machine == EFI_IMAGE_MACHINE_IA32) || (Machine == EFI_IMAGE_MACHINE_X64) || \r
+ (Machine == EFI_IMAGE_MACHINE_EBC)) {\r
+ return TRUE; \r
+ }\r
+\r
+ return FALSE;\r
+}\r
+\r
+/**\r
+ Performs an Itanium-based specific re-relocation fixup and is a no-op on other\r
+ instruction sets. This is used to re-relocated the image into the EFI virtual\r
+ space for runtime calls.\r
+\r
+ @param Reloc Pointer to the relocation record.\r
+ @param Fixup Pointer to the address to fix up.\r
+ @param FixupData Pointer to a buffer to log the fixups.\r
+ @param Adjust The offset to adjust the fixup.\r
+\r
+ @return Status code.\r
+\r
+**/\r
+RETURN_STATUS\r
+PeHotRelocateImageEx (\r
+ IN UINT16 *Reloc,\r
+ IN OUT CHAR8 *Fixup,\r
+ IN OUT CHAR8 **FixupData,\r
+ IN UINT64 Adjust\r
+ )\r
+{\r
+ return RETURN_UNSUPPORTED;\r
+}\r
+\r
UINT64 FixupVal;\r
\r
switch ((*Reloc) >> 12) {\r
-\r
- case EFI_IMAGE_REL_BASED_DIR64:\r
- F64 = (UINT64 *) Fixup;\r
- *F64 = *F64 + (UINT64) Adjust;\r
- if (*FixupData != NULL) {\r
- *FixupData = ALIGN_POINTER(*FixupData, sizeof(UINT64));\r
- *(UINT64 *)(*FixupData) = *F64;\r
- *FixupData = *FixupData + sizeof(UINT64);\r
- }\r
- break;\r
-\r
case EFI_IMAGE_REL_BASED_IA64_IMM64:\r
\r
//\r
\r
return RETURN_SUCCESS;\r
}\r
+\r
+/**\r
+ Returns TRUE if the machine type of PE/COFF image is supported. Supported \r
+ does not mean the image can be executed it means the PE/COFF loader supports\r
+ loading and relocating of the image type. It's up to the caller to support\r
+ the entry point. \r
+\r
+ This function implies the basic PE/COFF loader/relocator supports IA32, EBC,\r
+ & X64 images. Calling the entry point in a correct mannor is up to the \r
+ consumer of this library. This version also supports the special relocations\r
+ for Itanium. \r
+\r
+ @param Machine Machine type from the PE Header.\r
+\r
+ @return TRUE if this PE/COFF loader can load the image\r
+\r
+**/\r
+BOOLEAN\r
+PeCoffLoaderImageFormatSupported (\r
+ IN UINT16 Machine\r
+ )\r
+{\r
+ if ((Machine == EFI_IMAGE_MACHINE_IPF) || (Machine == EFI_IMAGE_MACHINE_IA32) ||\r
+ (Machine == EFI_IMAGE_MACHINE_EBC) || (Machine == EFI_IMAGE_MACHINE_X64)) {\r
+ return TRUE; \r
+ }\r
+\r
+ return FALSE;\r
+}\r
+\r
+\r
+/**\r
+ ImageRead function that operates on a memory buffer whos base is passed into\r
+ FileHandle. \r
+\r
+ @param Reloc Ponter to baes of the input stream\r
+ @param Fixup Offset to the start of the buffer\r
+ @param FixupData Number of bytes to copy into the buffer\r
+ @param Adjust Location to place results of read\r
+\r
+ @retval RETURN_SUCCESS Data is read from FileOffset from the Handle into \r
+ the buffer.\r
+**/\r
+RETURN_STATUS\r
+PeHotRelocateImageEx (\r
+ IN UINT16 *Reloc,\r
+ IN OUT CHAR8 *Fixup,\r
+ IN OUT CHAR8 **FixupData,\r
+ IN UINT64 Adjust\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Performs an IPF specific relocation fixup\r
+\r
+Arguments:\r
+\r
+ Reloc - Pointer to the relocation record\r
+\r
+ Fixup - Pointer to the address to fix up\r
+\r
+ FixupData - Pointer to a buffer to log the fixups\r
+\r
+ Adjust - The offset to adjust the fixup\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+{\r
+ UINT64 *F64;\r
+ UINT64 FixupVal;\r
+\r
+ switch ((*Reloc) >> 12) {\r
+ case EFI_IMAGE_REL_BASED_DIR64:\r
+ F64 = (UINT64 *) Fixup;\r
+ *FixupData = ALIGN_POINTER (*FixupData, sizeof (UINT64));\r
+ if (*(UINT64 *) (*FixupData) == *F64) {\r
+ *F64 = *F64 + (UINT64) Adjust;\r
+ }\r
+\r
+ *FixupData = *FixupData + sizeof (UINT64);\r
+ break;\r
+\r
+ case EFI_IMAGE_REL_BASED_IA64_IMM64:\r
+ F64 = (UINT64 *) Fixup;\r
+ *FixupData = ALIGN_POINTER (*FixupData, sizeof (UINT64));\r
+ if (*(UINT64 *) (*FixupData) == *F64) {\r
+ //\r
+ // Align it to bundle address before fixing up the\r
+ // 64-bit immediate value of the movl instruction.\r
+ //\r
+ //\r
+ Fixup = (CHAR8 *) ((UINT64) Fixup & (UINT64)~(15));\r
+ FixupVal = (UINT64) 0;\r
+\r
+ //\r
+ // Extract the lower 32 bits of IMM64 from bundle\r
+ //\r
+ EXT_IMM64 (\r
+ FixupVal,\r
+ (UINT32 *) Fixup + IMM64_IMM7B_INST_WORD_X,\r
+ IMM64_IMM7B_SIZE_X,\r
+ IMM64_IMM7B_INST_WORD_POS_X,\r
+ IMM64_IMM7B_VAL_POS_X\r
+ );\r
+\r
+ EXT_IMM64 (\r
+ FixupVal,\r
+ (UINT32 *) Fixup + IMM64_IMM9D_INST_WORD_X,\r
+ IMM64_IMM9D_SIZE_X,\r
+ IMM64_IMM9D_INST_WORD_POS_X,\r
+ IMM64_IMM9D_VAL_POS_X\r
+ );\r
+\r
+ EXT_IMM64 (\r
+ FixupVal,\r
+ (UINT32 *) Fixup + IMM64_IMM5C_INST_WORD_X,\r
+ IMM64_IMM5C_SIZE_X,\r
+ IMM64_IMM5C_INST_WORD_POS_X,\r
+ IMM64_IMM5C_VAL_POS_X\r
+ );\r
+\r
+ EXT_IMM64 (\r
+ FixupVal,\r
+ (UINT32 *) Fixup + IMM64_IC_INST_WORD_X,\r
+ IMM64_IC_SIZE_X,\r
+ IMM64_IC_INST_WORD_POS_X,\r
+ IMM64_IC_VAL_POS_X\r
+ );\r
+\r
+ EXT_IMM64 (\r
+ FixupVal,\r
+ (UINT32 *) Fixup + IMM64_IMM41a_INST_WORD_X,\r
+ IMM64_IMM41a_SIZE_X,\r
+ IMM64_IMM41a_INST_WORD_POS_X,\r
+ IMM64_IMM41a_VAL_POS_X\r
+ );\r
+\r
+ //\r
+ // Update 64-bit address\r
+ //\r
+ FixupVal += Adjust;\r
+\r
+ //\r
+ // Insert IMM64 into bundle\r
+ //\r
+ INS_IMM64 (\r
+ FixupVal,\r
+ ((UINT32 *) Fixup + IMM64_IMM7B_INST_WORD_X),\r
+ IMM64_IMM7B_SIZE_X,\r
+ IMM64_IMM7B_INST_WORD_POS_X,\r
+ IMM64_IMM7B_VAL_POS_X\r
+ );\r
+\r
+ INS_IMM64 (\r
+ FixupVal,\r
+ ((UINT32 *) Fixup + IMM64_IMM9D_INST_WORD_X),\r
+ IMM64_IMM9D_SIZE_X,\r
+ IMM64_IMM9D_INST_WORD_POS_X,\r
+ IMM64_IMM9D_VAL_POS_X\r
+ );\r
+\r
+ INS_IMM64 (\r
+ FixupVal,\r
+ ((UINT32 *) Fixup + IMM64_IMM5C_INST_WORD_X),\r
+ IMM64_IMM5C_SIZE_X,\r
+ IMM64_IMM5C_INST_WORD_POS_X,\r
+ IMM64_IMM5C_VAL_POS_X\r
+ );\r
+\r
+ INS_IMM64 (\r
+ FixupVal,\r
+ ((UINT32 *) Fixup + IMM64_IC_INST_WORD_X),\r
+ IMM64_IC_SIZE_X,\r
+ IMM64_IC_INST_WORD_POS_X,\r
+ IMM64_IC_VAL_POS_X\r
+ );\r
+\r
+ INS_IMM64 (\r
+ FixupVal,\r
+ ((UINT32 *) Fixup + IMM64_IMM41a_INST_WORD_X),\r
+ IMM64_IMM41a_SIZE_X,\r
+ IMM64_IMM41a_INST_WORD_POS_X,\r
+ IMM64_IMM41a_VAL_POS_X\r
+ );\r
+\r
+ INS_IMM64 (\r
+ FixupVal,\r
+ ((UINT32 *) Fixup + IMM64_IMM41b_INST_WORD_X),\r
+ IMM64_IMM41b_SIZE_X,\r
+ IMM64_IMM41b_INST_WORD_POS_X,\r
+ IMM64_IMM41b_VAL_POS_X\r
+ );\r
+\r
+ INS_IMM64 (\r
+ FixupVal,\r
+ ((UINT32 *) Fixup + IMM64_IMM41c_INST_WORD_X),\r
+ IMM64_IMM41c_SIZE_X,\r
+ IMM64_IMM41c_INST_WORD_POS_X,\r
+ IMM64_IMM41c_VAL_POS_X\r
+ );\r
+\r
+ INS_IMM64 (\r
+ FixupVal,\r
+ ((UINT32 *) Fixup + IMM64_SIGN_INST_WORD_X),\r
+ IMM64_SIGN_SIZE_X,\r
+ IMM64_SIGN_INST_WORD_POS_X,\r
+ IMM64_SIGN_VAL_POS_X\r
+ );\r
+\r
+ *(UINT64 *) (*FixupData) = *F64;\r
+ }\r
+\r
+ *FixupData = *FixupData + sizeof (UINT64);\r
+ break;\r
+\r
+ default:\r
+ DEBUG ((EFI_D_ERROR, "PeHotRelocateEx:unknown fixed type\n"));\r
+ return RETURN_UNSUPPORTED;\r
+ }\r
+\r
+ return RETURN_SUCCESS;\r
+}\r
+\r
+\r
+\r
IN UINT64 Adjust\r
)\r
{\r
- UINT64 *F64;\r
-\r
- switch ((*Reloc) >> 12) {\r
-\r
- case EFI_IMAGE_REL_BASED_DIR64:\r
- F64 = (UINT64 *) Fixup;\r
- *F64 = *F64 + (UINT64) Adjust;\r
- if (*FixupData != NULL) {\r
- *FixupData = ALIGN_POINTER(*FixupData, sizeof(UINT64));\r
- *(UINT64 *)(*FixupData) = *F64;\r
- *FixupData = *FixupData + sizeof(UINT64);\r
- }\r
- break;\r
-\r
- default:\r
- return RETURN_UNSUPPORTED;\r
+ return RETURN_UNSUPPORTED;\r
+}\r
+\r
+/**\r
+ Returns TRUE if the machine type of PE/COFF image is supported. Supported \r
+ does not mean the image can be executed it means the PE/COFF loader supports\r
+ loading and relocating of the image type. It's up to the caller to support\r
+ the entry point. \r
+\r
+ This function implies the basic PE/COFF loader/relocator supports IA32, EBC,\r
+ & X64 images. Calling the entry point in a correct mannor is up to the \r
+ consumer of this library.\r
+\r
+ @param Machine Machine type from the PE Header.\r
+\r
+ @return TRUE if this PE/COFF loader can load the image\r
+\r
+**/\r
+BOOLEAN\r
+PeCoffLoaderImageFormatSupported (\r
+ IN UINT16 Machine\r
+ )\r
+{\r
+ if ((Machine == EFI_IMAGE_MACHINE_IA32) || (Machine == EFI_IMAGE_MACHINE_X64) || \r
+ (Machine == EFI_IMAGE_MACHINE_EBC)) {\r
+ return TRUE; \r
}\r
\r
- return RETURN_SUCCESS;\r
+ return FALSE;\r
+}\r
+\r
+\r
+/**\r
+ Performs an Itanium-based specific re-relocation fixup and is a no-op on other\r
+ instruction sets. This is used to re-relocated the image into the EFI virtual\r
+ space for runtime calls.\r
+\r
+ @param Reloc Pointer to the relocation record.\r
+ @param Fixup Pointer to the address to fix up.\r
+ @param FixupData Pointer to a buffer to log the fixups.\r
+ @param Adjust The offset to adjust the fixup.\r
+\r
+ @return Status code.\r
+\r
+**/\r
+RETURN_STATUS\r
+PeHotRelocateImageEx (\r
+ IN UINT16 *Reloc,\r
+ IN OUT CHAR8 *Fixup,\r
+ IN OUT CHAR8 **FixupData,\r
+ IN UINT64 Adjust\r
+ )\r
+{\r
+ return RETURN_UNSUPPORTED;\r
}\r