/*++\r
\r
-Copyright (c) 2005 - 2007, Intel Corporation \r
-All rights reserved. This program and the accompanying materials \r
+Copyright (c) 2005 - 2010, Intel Corporation. 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
which accompanies this distribution. The full text of the license may be found at \r
http://opensource.org/licenses/bsd-license.php \r
ImageContext->ImageAddress = Hdr.Pe32Plus->OptionalHeader.ImageBase;\r
}\r
} else {\r
- ImageContext->ImageAddress = (EFI_PHYSICAL_ADDRESS)(Hdr.Te->ImageBase);\r
+ ImageContext->ImageAddress = (EFI_PHYSICAL_ADDRESS)(Hdr.Te->ImageBase + Hdr.Te->StrippedSize - sizeof (EFI_TE_IMAGE_HEADER));\r
}\r
\r
//\r
// Pe image and in Te image header there is not a field to describe the imagesize,\r
// we use the largest VirtualAddress plus Size in each directory entry to describe the imagesize\r
//\r
- ImageContext->ImageSize = (UINT64) (Hdr.Te->DataDirectory[0].VirtualAddress + Hdr.Te->DataDirectory[0].Size);\r
+ ImageContext->ImageSize = (UINT64) (Hdr.Te->DataDirectory[0].VirtualAddress + Hdr.Te->DataDirectory[0].Size);\r
+ if(Hdr.Te->DataDirectory[1].VirtualAddress > Hdr.Te->DataDirectory[0].VirtualAddress) {\r
+ ImageContext->ImageSize = (UINT64) (Hdr.Te->DataDirectory[1].VirtualAddress + Hdr.Te->DataDirectory[1].Size);\r
+ }\r
ImageContext->SectionAlignment = 4096;\r
ImageContext->SizeOfHeaders = sizeof (EFI_TE_IMAGE_HEADER) + (UINTN) Hdr.Te->BaseOfCode - (UINTN) Hdr.Te->StrippedSize;\r
\r
// the optional header to verify a desired directory entry is there.\r
//\r
\r
- if (NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC) {\r
+ if (NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC && 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)) {\r
+ //\r
+ // If the base start or end address resolved to 0, then fail.\r
+ //\r
+ return EFI_LOAD_ERROR;\r
+ }\r
} else {\r
//\r
// Set base and end to bypass processing below.\r
}\r
} else {\r
Hdr.Te = (EFI_TE_IMAGE_HEADER *)(UINTN)(ImageContext->ImageAddress);\r
- Adjust = (UINT64) (BaseAddress - Hdr.Te->ImageBase);\r
- Hdr.Te->ImageBase = (UINT64) (BaseAddress);\r
+ Adjust = (UINT64) (BaseAddress - Hdr.Te->StrippedSize + sizeof (EFI_TE_IMAGE_HEADER) - Hdr.Te->ImageBase);\r
+ Hdr.Te->ImageBase = (UINT64) (BaseAddress - Hdr.Te->StrippedSize + sizeof (EFI_TE_IMAGE_HEADER));\r
\r
//\r
// Find the relocation block\r
//\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
- Hdr.Te->StrippedSize\r
- );\r
- RelocBaseEnd = (EFI_IMAGE_BASE_RELOCATION *) ((UINTN) RelocBase + (UINTN) RelocDir->Size - 1);\r
+ if (RelocDir->Size > 0) {\r
+ RelocBase = (EFI_IMAGE_BASE_RELOCATION *)(UINTN)(\r
+ ImageContext->ImageAddress +\r
+ RelocDir->VirtualAddress +\r
+ sizeof(EFI_TE_IMAGE_HEADER) -\r
+ Hdr.Te->StrippedSize\r
+ );\r
+ RelocBaseEnd = (EFI_IMAGE_BASE_RELOCATION *) ((UINTN) RelocBase + (UINTN) RelocDir->Size - 1);\r
+ } else {\r
+ //\r
+ // Set base and end to bypass processing below.\r
+ //\r
+ RelocBase = NULL;\r
+ RelocBaseEnd = NULL;\r
+ }\r
}\r
\r
//\r
RelocEnd = (UINT16 *) ((CHAR8 *) RelocBase + RelocBase->SizeOfBlock);\r
if (!(ImageContext->IsTeImage)) {\r
FixupBase = PeCoffLoaderImageAddress (ImageContext, RelocBase->VirtualAddress);\r
+\r
+ if (FixupBase == NULL) {\r
+ //\r
+ // If the FixupBase address resolved to 0, then fail.\r
+ //\r
+ return EFI_LOAD_ERROR;\r
+ }\r
} else {\r
FixupBase = (CHAR8 *)(UINTN)(ImageContext->ImageAddress +\r
RelocBase->VirtualAddress +\r
UINT32 TempDebugEntryRva;\r
UINT32 NumberOfRvaAndSizes;\r
UINT16 Magic;\r
+#if (EFI_SPECIFICATION_VERSION >= 0x0002000A)\r
+ EFI_IMAGE_RESOURCE_DIRECTORY *ResourceDirectory;\r
+ EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY *ResourceDirectoryEntry;\r
+ EFI_IMAGE_RESOURCE_DIRECTORY_STRING *ResourceDirectoryString;\r
+ EFI_IMAGE_RESOURCE_DATA_ENTRY *ResourceDataEntry;\r
+#endif\r
\r
if (NULL == ImageContext) {\r
return EFI_INVALID_PARAMETER;\r
}\r
}\r
\r
+#if (EFI_SPECIFICATION_VERSION >= 0x0002000A)\r
+ //\r
+ // Get Image's HII resource section\r
+ //\r
+ if (!(ImageContext->IsTeImage)) {\r
+ if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
+ //\r
+ // Use PE32 offset\r
+ //\r
+ DirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *)&Hdr.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE];\r
+ } else {\r
+ //\r
+ // Use PE32+ offset\r
+ //\r
+ DirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *)&Hdr.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE];\r
+ }\r
+\r
+ if (DirectoryEntry->Size != 0) {\r
+ Base = PeCoffLoaderImageAddress (ImageContext, DirectoryEntry->VirtualAddress);\r
+\r
+ ResourceDirectory = (EFI_IMAGE_RESOURCE_DIRECTORY *) Base;\r
+ ResourceDirectoryEntry = (EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY *) (ResourceDirectory + 1);\r
+\r
+ for (Index = 0; Index < ResourceDirectory->NumberOfNamedEntries; Index++) {\r
+ if (ResourceDirectoryEntry->u1.s.NameIsString) {\r
+ ResourceDirectoryString = (EFI_IMAGE_RESOURCE_DIRECTORY_STRING *) (Base + ResourceDirectoryEntry->u1.s.NameOffset);\r
+\r
+ if (ResourceDirectoryString->Length == 3 &&\r
+ ResourceDirectoryString->String[0] == L'H' &&\r
+ ResourceDirectoryString->String[1] == L'I' &&\r
+ ResourceDirectoryString->String[2] == L'I') {\r
+ //\r
+ // Resource Type "HII" found\r
+ //\r
+ if (ResourceDirectoryEntry->u2.s.DataIsDirectory) {\r
+ //\r
+ // Move to next level - resource Name\r
+ //\r
+ ResourceDirectory = (EFI_IMAGE_RESOURCE_DIRECTORY *) (Base + ResourceDirectoryEntry->u2.s.OffsetToDirectory);\r
+ ResourceDirectoryEntry = (EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY *) (ResourceDirectory + 1);\r
+\r
+ if (ResourceDirectoryEntry->u2.s.DataIsDirectory) {\r
+ //\r
+ // Move to next level - resource Language\r
+ //\r
+ ResourceDirectory = (EFI_IMAGE_RESOURCE_DIRECTORY *) (Base + ResourceDirectoryEntry->u2.s.OffsetToDirectory);\r
+ ResourceDirectoryEntry = (EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY *) (ResourceDirectory + 1);\r
+ }\r
+ }\r
+\r
+ //\r
+ // Now it ought to be resource Data\r
+ //\r
+ if (!ResourceDirectoryEntry->u2.s.DataIsDirectory) {\r
+ ResourceDataEntry = (EFI_IMAGE_RESOURCE_DATA_ENTRY *) (Base + ResourceDirectoryEntry->u2.OffsetToData);\r
+ ImageContext->HiiResourceData = (EFI_PHYSICAL_ADDRESS) (UINTN) PeCoffLoaderImageAddress (ImageContext, ResourceDataEntry->OffsetToData);\r
+ break;\r
+ }\r
+ }\r
+ }\r
+\r
+ ResourceDirectoryEntry++;\r
+ }\r
+ }\r
+ }\r
+#endif\r
+\r
#if defined (EFI_DEBUG_ITP_BREAK) && !defined (_CONSOLE)\r
AsmEfiSetBreakSupport ((UINTN)(ImageContext->ImageAddress));\r
#endif\r