\r
Functions to get info and load PE/COFF image.\r
\r
-Copyright (c) 2004 - 2010, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2004 - 2017, Intel Corporation. All rights reserved.<BR>\r
Portions Copyright (c) 2011 - 2013, ARM Ltd. All rights reserved.<BR>\r
This program and the accompanying materials \r
are licensed and made available under the terms and conditions of the BSD License \r
IN UINT64 Adjust\r
);\r
\r
-RETURN_STATUS\r
-PeCoffLoaderRelocateX64Image (\r
- IN UINT16 *Reloc,\r
- IN OUT CHAR8 *Fixup,\r
- IN OUT CHAR8 **FixupData,\r
- IN UINT64 Adjust\r
- );\r
-\r
RETURN_STATUS\r
PeCoffLoaderRelocateIpfImage (\r
IN UINT16 *Reloc,\r
IN UINT64 Adjust\r
);\r
\r
-RETURN_STATUS\r
-PeCoffLoaderRelocateAArch64Image (\r
- IN UINT16 *Reloc,\r
- IN OUT CHAR8 *Fixup,\r
- IN OUT CHAR8 **FixupData,\r
- IN UINT64 Adjust\r
- );\r
-\r
STATIC\r
RETURN_STATUS\r
PeCoffLoaderGetPeHeader (\r
//\r
if ((!(ImageContext->IsTeImage)) && ((PeHdr->Pe32.FileHeader.Characteristics & EFI_IMAGE_FILE_RELOCS_STRIPPED) != 0)) {\r
ImageContext->RelocationsStripped = TRUE;\r
- } else if ((ImageContext->IsTeImage) && (TeHdr->DataDirectory[0].Size == 0)) {\r
+ } else if ((ImageContext->IsTeImage) && (TeHdr->DataDirectory[0].Size == 0) && (TeHdr->DataDirectory[0].VirtualAddress == 0)) {\r
ImageContext->RelocationsStripped = TRUE;\r
} else {\r
ImageContext->RelocationsStripped = FALSE;\r
CHAR8 *FixupBase;\r
UINT16 *F16;\r
UINT32 *F32;\r
+ UINT64 *F64;\r
CHAR8 *FixupData;\r
PHYSICAL_ADDRESS BaseAddress;\r
UINT16 MachineType;\r
//\r
if (OptionHeader.Optional32->NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC) {\r
RelocDir = &OptionHeader.Optional32->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC];\r
- RelocBase = PeCoffLoaderImageAddress (ImageContext, RelocDir->VirtualAddress);\r
- RelocBaseEnd = PeCoffLoaderImageAddress (\r
- ImageContext,\r
- RelocDir->VirtualAddress + RelocDir->Size - 1\r
- );\r
+ if ((RelocDir != NULL) && (RelocDir->Size > 0)) {\r
+ RelocBase = PeCoffLoaderImageAddress (ImageContext, RelocDir->VirtualAddress);\r
+ RelocBaseEnd = PeCoffLoaderImageAddress (\r
+ ImageContext,\r
+ RelocDir->VirtualAddress + RelocDir->Size - 1\r
+ );\r
+ if (RelocBase == NULL || RelocBaseEnd == NULL || RelocBaseEnd < RelocBase) {\r
+ ImageContext->ImageError = IMAGE_ERROR_FAILED_RELOCATION;\r
+ return RETURN_LOAD_ERROR;\r
+ }\r
+ } else {\r
+ //\r
+ // Set base and end to bypass processing below.\r
+ //\r
+ RelocBase = RelocBaseEnd = 0;\r
+ }\r
} else {\r
//\r
// Set base and end to bypass processing below.\r
//\r
if (OptionHeader.Optional64->NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC) {\r
RelocDir = &OptionHeader.Optional64->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC];\r
- RelocBase = PeCoffLoaderImageAddress (ImageContext, RelocDir->VirtualAddress);\r
- RelocBaseEnd = PeCoffLoaderImageAddress (\r
- ImageContext,\r
- RelocDir->VirtualAddress + RelocDir->Size - 1\r
- );\r
+ if ((RelocDir != NULL) && (RelocDir->Size > 0)) {\r
+ RelocBase = PeCoffLoaderImageAddress (ImageContext, RelocDir->VirtualAddress);\r
+ RelocBaseEnd = PeCoffLoaderImageAddress (\r
+ ImageContext,\r
+ RelocDir->VirtualAddress + RelocDir->Size - 1\r
+ );\r
+ if (RelocBase == NULL || RelocBaseEnd == NULL || RelocBaseEnd < RelocBase) {\r
+ ImageContext->ImageError = IMAGE_ERROR_FAILED_RELOCATION;\r
+ return RETURN_LOAD_ERROR;\r
+ }\r
+ } else {\r
+ //\r
+ // Set base and end to bypass processing below.\r
+ //\r
+ RelocBase = RelocBaseEnd = 0;\r
+ }\r
} else {\r
//\r
// Set base and end to bypass processing below.\r
RelocEnd = (UINT16 *) ((CHAR8 *) RelocBase + RelocBase->SizeOfBlock);\r
if (!(ImageContext->IsTeImage)) {\r
FixupBase = PeCoffLoaderImageAddress (ImageContext, RelocBase->VirtualAddress);\r
+ if (FixupBase == NULL) {\r
+ ImageContext->ImageError = IMAGE_ERROR_FAILED_RELOCATION;\r
+ return RETURN_LOAD_ERROR;\r
+ }\r
} else {\r
FixupBase = (CHAR8 *)(UINTN)(ImageContext->ImageAddress +\r
RelocBase->VirtualAddress +\r
}\r
break;\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_HIGHADJ:\r
//\r
// Return the same EFI_UNSUPPORTED return code as\r
case EFI_IMAGE_MACHINE_ARMT:\r
Status = PeCoffLoaderRelocateArmImage (&Reloc, Fixup, &FixupData, Adjust);\r
break;\r
- case EFI_IMAGE_MACHINE_X64:\r
- Status = PeCoffLoaderRelocateX64Image (Reloc, Fixup, &FixupData, Adjust);\r
- break;\r
case EFI_IMAGE_MACHINE_IA64:\r
Status = PeCoffLoaderRelocateIpfImage (Reloc, Fixup, &FixupData, Adjust);\r
break;\r
- case EFI_IMAGE_MACHINE_AARCH64:\r
- Status = PeCoffLoaderRelocateAArch64Image (Reloc, Fixup, &FixupData, Adjust);\r
- break;\r
default:\r
Status = RETURN_UNSUPPORTED;\r
break;\r
PeHdr->Pe32.OptionalHeader.AddressOfEntryPoint\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
+ ImageContext->EntryPoint = (UINTN)ImageContext->ImageAddress +\r
+ (UINTN)TeHdr->AddressOfEntryPoint +\r
+ (UINTN)sizeof(EFI_TE_IMAGE_HEADER) -\r
+ (UINTN) TeHdr->StrippedSize;\r
}\r
\r
//\r