PeCoffLoaderGetPeHeader() routine will do basic check for PE/COFF header.\r
PeCoffLoaderGetImageInfo() routine will do basic check for whole PE/COFF image.\r
\r
- Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>\r
+ Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.<BR>\r
Portions copyright (c) 2008 - 2009, Apple Inc. 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
SectionHeader->PointerToRawData -= TeStrippedOffset;\r
}\r
\r
-/**\r
- Retrieves the magic value from the PE/COFF header.\r
-\r
- @param Hdr The buffer in which to return the PE32, PE32+, or TE header.\r
-\r
- @return EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC - Image is PE32\r
- @return EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC - Image is PE32+\r
-\r
-**/\r
-UINT16\r
-PeCoffLoaderGetPeHeaderMagicValue (\r
- IN EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr\r
- )\r
-{\r
- //\r
- // NOTE: Some versions of Linux ELILO for Itanium have an incorrect magic value\r
- // in the PE/COFF Header. If the MachineType is Itanium(IA64) and the\r
- // Magic value in the OptionalHeader is EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC\r
- // then override the returned value to EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC\r
- //\r
- if (Hdr.Pe32->FileHeader.Machine == IMAGE_FILE_MACHINE_IA64 && Hdr.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
- return EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC;\r
- }\r
- //\r
- // Return the magic value from the PC/COFF Optional Header\r
- //\r
- return Hdr.Pe32->OptionalHeader.Magic;\r
-}\r
-\r
-\r
/**\r
Retrieves the PE or TE Header from a PE/COFF or TE image.\r
\r
EFI_IMAGE_DOS_HEADER DosHdr;\r
UINTN Size;\r
UINTN ReadSize;\r
- UINT16 Magic;\r
UINT32 SectionHeaderOffset;\r
UINT32 Index;\r
UINT32 HeaderWithoutDataDir;\r
ImageContext->IsTeImage = FALSE;\r
ImageContext->Machine = Hdr.Pe32->FileHeader.Machine;\r
\r
- Magic = PeCoffLoaderGetPeHeaderMagicValue (Hdr);\r
-\r
- if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
+ if (Hdr.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
//\r
// 1. Check OptionalHeader.NumberOfRvaAndSizes filed.\r
//\r
ImageContext->SectionAlignment = Hdr.Pe32->OptionalHeader.SectionAlignment;\r
ImageContext->SizeOfHeaders = Hdr.Pe32->OptionalHeader.SizeOfHeaders;\r
\r
- } else if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) {\r
+ } else if (Hdr.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) {\r
//\r
// 1. Check FileHeader.NumberOfRvaAndSizes filed.\r
//\r
EFI_IMAGE_SECTION_HEADER SectionHeader;\r
EFI_IMAGE_DEBUG_DIRECTORY_ENTRY DebugEntry;\r
UINT32 NumberOfRvaAndSizes;\r
- UINT16 Magic;\r
UINT32 TeStrippedOffset;\r
\r
if (ImageContext == NULL) {\r
return Status;\r
}\r
\r
- Magic = PeCoffLoaderGetPeHeaderMagicValue (Hdr);\r
-\r
//\r
// Retrieve the base address of the image\r
//\r
if (!(ImageContext->IsTeImage)) {\r
TeStrippedOffset = 0;\r
- if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
+ if (Hdr.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
//\r
// Use PE32 offset\r
//\r
}\r
\r
if (!(ImageContext->IsTeImage)) {\r
- if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
+ if (Hdr.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
//\r
// Use PE32 offset\r
//\r
CHAR8 *FixupData;\r
PHYSICAL_ADDRESS BaseAddress;\r
UINT32 NumberOfRvaAndSizes;\r
- UINT16 Magic;\r
UINT32 TeStrippedOffset;\r
\r
ASSERT (ImageContext != NULL);\r
if (!(ImageContext->IsTeImage)) {\r
Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)((UINTN)ImageContext->ImageAddress + ImageContext->PeCoffHeaderOffset);\r
TeStrippedOffset = 0;\r
- Magic = PeCoffLoaderGetPeHeaderMagicValue (Hdr);\r
\r
- if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
+ if (Hdr.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
//\r
// Use PE32 offset\r
//\r
RelocDir->VirtualAddress + RelocDir->Size - 1,\r
TeStrippedOffset\r
);\r
- if (RelocBase == NULL || RelocBaseEnd == NULL || RelocBaseEnd < RelocBase) {\r
+ if (RelocBase == NULL || RelocBaseEnd == NULL || (UINTN) RelocBaseEnd < (UINTN) RelocBase) {\r
ImageContext->ImageError = IMAGE_ERROR_FAILED_RELOCATION;\r
return RETURN_LOAD_ERROR;\r
}\r
// Run the relocation information and apply the fixups\r
//\r
FixupData = ImageContext->FixupData;\r
- while (RelocBase < RelocBaseEnd) {\r
+ while ((UINTN) RelocBase < (UINTN) RelocBaseEnd) {\r
\r
Reloc = (UINT16 *) ((CHAR8 *) RelocBase + sizeof (EFI_IMAGE_BASE_RELOCATION));\r
//\r
//\r
// Run this relocation record\r
//\r
- while (Reloc < RelocEnd) {\r
+ while ((UINTN) Reloc < (UINTN) RelocEnd) {\r
Fixup = PeCoffLoaderImageAddress (ImageContext, RelocBase->VirtualAddress + (*Reloc & 0xFFF), TeStrippedOffset);\r
if (Fixup == NULL) {\r
ImageContext->ImageError = IMAGE_ERROR_FAILED_RELOCATION;\r
UINTN Size;\r
UINT32 TempDebugEntryRva;\r
UINT32 NumberOfRvaAndSizes;\r
- UINT16 Magic;\r
EFI_IMAGE_RESOURCE_DIRECTORY *ResourceDirectory;\r
EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY *ResourceDirectoryEntry;\r
EFI_IMAGE_RESOURCE_DIRECTORY_STRING *ResourceDirectoryString;\r
//\r
// Get image's entry point\r
//\r
- Magic = PeCoffLoaderGetPeHeaderMagicValue (Hdr);\r
if (!(ImageContext->IsTeImage)) {\r
//\r
// Sizes of AddressOfEntryPoint are different so we need to do this safely\r
//\r
- if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
+ if (Hdr.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
//\r
// Use PE32 offset\r
//\r
// the optional header to verify a desired directory entry is there.\r
//\r
if (!(ImageContext->IsTeImage)) {\r
- if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
+ if (Hdr.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
//\r
// Use PE32 offset\r
//\r
//\r
ImageContext->HiiResourceData = 0;\r
if (!(ImageContext->IsTeImage)) {\r
- if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
+ if (Hdr.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
//\r
// Use PE32 offset\r
//\r
EFI_IMAGE_DATA_DIRECTORY *RelocDir;\r
EFI_IMAGE_BASE_RELOCATION *RelocBase;\r
EFI_IMAGE_BASE_RELOCATION *RelocBaseEnd;\r
+ EFI_IMAGE_BASE_RELOCATION *RelocBaseOrig;\r
UINT16 *Reloc;\r
UINT16 *RelocEnd;\r
CHAR8 *Fixup;\r
CHAR8 *FixupData;\r
UINTN Adjust;\r
RETURN_STATUS Status;\r
- UINT16 Magic;\r
+ PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;\r
+\r
+ if (RelocationData == NULL || ImageBase == 0x0 || VirtImageBase == 0x0) {\r
+ return;\r
+ }\r
\r
OldBase = (CHAR8 *)((UINTN)ImageBase);\r
NewBase = (CHAR8 *)((UINTN)VirtImageBase);\r
Adjust = (UINTN) NewBase - (UINTN) OldBase;\r
\r
+ ImageContext.ImageAddress = ImageBase;\r
+ ImageContext.ImageSize = ImageSize;\r
+\r
//\r
// Find the image's relocate dir info\r
//\r
return ;\r
}\r
\r
- Magic = PeCoffLoaderGetPeHeaderMagicValue (Hdr);\r
-\r
- if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
+ if (Hdr.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
//\r
// Use PE32 offset\r
//\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
+ RelocBase = NULL;\r
+ RelocBaseEnd = NULL;\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
+ if ((RelocDir != NULL) && (RelocDir->Size > 0)) {\r
+ RelocBase = (EFI_IMAGE_BASE_RELOCATION *) PeCoffLoaderImageAddress (&ImageContext, RelocDir->VirtualAddress, 0);\r
+ RelocBaseEnd = (EFI_IMAGE_BASE_RELOCATION *) PeCoffLoaderImageAddress (&ImageContext,\r
+ RelocDir->VirtualAddress + RelocDir->Size - 1,\r
+ 0\r
+ );\r
+ }\r
+ if (RelocBase == NULL || RelocBaseEnd == NULL || (UINTN) RelocBaseEnd < (UINTN) RelocBase) {\r
+ //\r
+ // relocation block is not valid, just return\r
+ //\r
+ return;\r
+ }\r
} else {\r
//\r
// Cannot find relocations, cannot continue to relocate the image, ASSERT for this invalid image.\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
+ if (Adjust != 0) {\r
//\r
- // Add check for RelocBase->SizeOfBlock field.\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
- if ((RelocBase->SizeOfBlock == 0) || (RelocBase->SizeOfBlock > RelocDir->Size)) {\r
+ FixupData = RelocationData;\r
+ RelocBaseOrig = RelocBase;\r
+ while ((UINTN) RelocBase < (UINTN) RelocBaseEnd) {\r
//\r
- // Data invalid, cannot continue to relocate the image, just return.\r
+ // Add check for RelocBase->SizeOfBlock field.\r
//\r
- return;\r
- }\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
+ if ((RelocBase->SizeOfBlock == 0) || (RelocBase->SizeOfBlock > RelocDir->Size)) {\r
+ //\r
+ // Data invalid, cannot continue to relocate the image, just return.\r
+ //\r
+ return;\r
+ }\r
\r
- //\r
- // Run this relocation record\r
- //\r
- while (Reloc < RelocEnd) {\r
+ Reloc = (UINT16 *) ((UINT8 *) RelocBase + sizeof (EFI_IMAGE_BASE_RELOCATION));\r
+ RelocEnd = (UINT16 *) ((UINT8 *) RelocBase + RelocBase->SizeOfBlock);\r
+ if ((UINTN)RelocEnd > (UINTN)RelocBaseOrig + RelocDir->Size) {\r
+ return;\r
+ }\r
\r
- Fixup = FixupBase + (*Reloc & 0xFFF);\r
- switch ((*Reloc) >> 12) {\r
+ FixupBase = PeCoffLoaderImageAddress (&ImageContext, RelocBase->VirtualAddress, 0);\r
+ if (FixupBase == NULL) {\r
+ return;\r
+ }\r
\r
- case EFI_IMAGE_REL_BASED_ABSOLUTE:\r
- break;\r
+ //\r
+ // Run this relocation record\r
+ //\r
+ while ((UINTN) Reloc < (UINTN) RelocEnd) {\r
\r
- case EFI_IMAGE_REL_BASED_HIGH:\r
- Fixup16 = (UINT16 *) Fixup;\r
- if (*(UINT16 *) FixupData == *Fixup16) {\r
- *Fixup16 = (UINT16) (*Fixup16 + ((UINT16) ((UINT32) Adjust >> 16)));\r
+ Fixup = PeCoffLoaderImageAddress (&ImageContext, RelocBase->VirtualAddress + (*Reloc & 0xFFF), 0);\r
+ if (Fixup == NULL) {\r
+ return;\r
}\r
+ switch ((*Reloc) >> 12) {\r
\r
- FixupData = FixupData + sizeof (UINT16);\r
- break;\r
+ case EFI_IMAGE_REL_BASED_ABSOLUTE:\r
+ break;\r
\r
- case EFI_IMAGE_REL_BASED_LOW:\r
- Fixup16 = (UINT16 *) Fixup;\r
- if (*(UINT16 *) FixupData == *Fixup16) {\r
- *Fixup16 = (UINT16) (*Fixup16 + ((UINT16) Adjust & 0xffff));\r
- }\r
+ case EFI_IMAGE_REL_BASED_HIGH:\r
+ Fixup16 = (UINT16 *) Fixup;\r
+ if (*(UINT16 *) FixupData == *Fixup16) {\r
+ *Fixup16 = (UINT16) (*Fixup16 + ((UINT16) ((UINT32) Adjust >> 16)));\r
+ }\r
\r
- FixupData = FixupData + sizeof (UINT16);\r
- break;\r
+ FixupData = FixupData + sizeof (UINT16);\r
+ break;\r
\r
- case EFI_IMAGE_REL_BASED_HIGHLOW:\r
- Fixup32 = (UINT32 *) Fixup;\r
- FixupData = ALIGN_POINTER (FixupData, sizeof (UINT32));\r
- if (*(UINT32 *) FixupData == *Fixup32) {\r
- *Fixup32 = *Fixup32 + (UINT32) Adjust;\r
- }\r
+ case EFI_IMAGE_REL_BASED_LOW:\r
+ Fixup16 = (UINT16 *) Fixup;\r
+ if (*(UINT16 *) FixupData == *Fixup16) {\r
+ *Fixup16 = (UINT16) (*Fixup16 + ((UINT16) Adjust & 0xffff));\r
+ }\r
\r
- FixupData = FixupData + sizeof (UINT32);\r
- break;\r
+ FixupData = FixupData + sizeof (UINT16);\r
+ break;\r
\r
- case EFI_IMAGE_REL_BASED_DIR64:\r
- Fixup64 = (UINT64 *)Fixup;\r
- FixupData = ALIGN_POINTER (FixupData, sizeof (UINT64));\r
- if (*(UINT64 *) FixupData == *Fixup64) {\r
- *Fixup64 = *Fixup64 + (UINT64)Adjust;\r
- }\r
+ case EFI_IMAGE_REL_BASED_HIGHLOW:\r
+ Fixup32 = (UINT32 *) Fixup;\r
+ FixupData = ALIGN_POINTER (FixupData, sizeof (UINT32));\r
+ if (*(UINT32 *) FixupData == *Fixup32) {\r
+ *Fixup32 = *Fixup32 + (UINT32) Adjust;\r
+ }\r
\r
- FixupData = FixupData + sizeof (UINT64);\r
- break;\r
+ FixupData = FixupData + sizeof (UINT32);\r
+ break;\r
\r
- default:\r
+ case EFI_IMAGE_REL_BASED_DIR64:\r
+ Fixup64 = (UINT64 *)Fixup;\r
+ FixupData = ALIGN_POINTER (FixupData, sizeof (UINT64));\r
+ if (*(UINT64 *) FixupData == *Fixup64) {\r
+ *Fixup64 = *Fixup64 + (UINT64)Adjust;\r
+ }\r
+\r
+ FixupData = FixupData + sizeof (UINT64);\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
- // Only Itanium requires ConvertPeImage_Ex\r
+ // Next relocation record\r
//\r
- Status = PeHotRelocateImageEx (Reloc, Fixup, &FixupData, Adjust);\r
- if (RETURN_ERROR (Status)) {\r
- return ;\r
- }\r
+ Reloc += 1;\r
}\r
//\r
- // Next relocation record\r
+ // next reloc block\r
//\r
- Reloc += 1;\r
+ RelocBase = (EFI_IMAGE_BASE_RELOCATION *) RelocEnd;\r
}\r
- //\r
- // next reloc block\r
- //\r
- RelocBase = (EFI_IMAGE_BASE_RELOCATION *) RelocEnd;\r
}\r
}\r
\r