\r
**/\r
\r
+//\r
+// Include common header file for this module.\r
+//\r
+#include "CommonHeader.h"\r
\r
-/**\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
- @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
-PeCoffLoaderRelocateImageEx (\r
- IN UINT16 *Reloc,\r
- IN OUT CHAR8 *Fixup,\r
- IN OUT CHAR8 **FixupData,\r
- IN UINT64 Adjust\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
+#include "BasePeCoffLibInternals.h"\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
+ Retrieves the magic value from the PE/COFF header.\r
\r
- @param Machine Machine type from the PE Header.\r
+ @param Hdr The buffer in which to return the PE32, PE32+, or TE header.\r
\r
- @return TRUE if this PE/COFF loader can load the image\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
-BOOLEAN\r
-PeCoffLoaderImageFormatSupported (\r
- IN UINT16 Machine\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 == EFI_IMAGE_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
RETURN_STATUS Status;\r
EFI_IMAGE_DOS_HEADER DosHdr;\r
UINTN Size;\r
+ UINT16 Magic;\r
\r
//\r
// Read the DOS image header to check for it's existance\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
+ Magic = PeCoffLoaderGetPeHeaderMagicValue (Hdr);\r
+\r
+ if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
//\r
// Use PE32 offset\r
//\r
ImageContext->SectionAlignment = Hdr.Pe32->OptionalHeader.SectionAlignment;\r
ImageContext->SizeOfHeaders = Hdr.Pe32->OptionalHeader.SizeOfHeaders;\r
\r
- } else if (Hdr.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) {\r
+ } else if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) {\r
//\r
// Use PE32+ offset\r
//\r
EFI_IMAGE_SECTION_HEADER SectionHeader;\r
EFI_IMAGE_DEBUG_DIRECTORY_ENTRY DebugEntry;\r
UINT32 NumberOfRvaAndSizes;\r
+ UINT16 Magic;\r
\r
if (NULL == ImageContext) {\r
return RETURN_INVALID_PARAMETER;\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
- if (Hdr.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
+ if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
//\r
// Use PE32 offset\r
//\r
ImageContext->ImageAddress = Hdr.Pe32Plus->OptionalHeader.ImageBase;\r
}\r
} else {\r
- ImageContext->ImageAddress = (PHYSICAL_ADDRESS)(Hdr.Te->ImageBase);\r
+ ImageContext->ImageAddress = (PHYSICAL_ADDRESS)(Hdr.Te->ImageBase + Hdr.Te->StrippedSize - sizeof (EFI_TE_IMAGE_HEADER));\r
}\r
\r
//\r
}\r
\r
if (!(ImageContext->IsTeImage)) {\r
- if (Hdr.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
+ if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
//\r
// Use PE32 offset\r
//\r
}\r
\r
if (DebugDirectoryEntryFileOffset != 0) {\r
- for (Index = 0; Index < DebugDirectoryEntry->Size; Index++) {\r
+ for (Index = 0; Index < DebugDirectoryEntry->Size; Index += sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY)) {\r
//\r
// Read next debug directory entry\r
//\r
ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;\r
return Status;\r
}\r
-\r
if (DebugEntry.Type == EFI_IMAGE_DEBUG_TYPE_CODEVIEW) {\r
- ImageContext->DebugDirectoryEntryRva = (UINT32) (DebugDirectoryEntryRva + Index * sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY));\r
+ ImageContext->DebugDirectoryEntryRva = (UINT32) (DebugDirectoryEntryRva + Index);\r
if (DebugEntry.RVA == 0 && DebugEntry.FileOffset != 0) {\r
ImageContext->ImageSize += DebugEntry.SizeOfData;\r
}\r
}\r
\r
if (DebugDirectoryEntryFileOffset != 0) {\r
- for (Index = 0; Index < DebugDirectoryEntry->Size; Index++) {\r
+ for (Index = 0; Index < DebugDirectoryEntry->Size; Index += sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY)) {\r
//\r
// Read next debug directory entry\r
//\r
}\r
\r
if (DebugEntry.Type == EFI_IMAGE_DEBUG_TYPE_CODEVIEW) {\r
- ImageContext->DebugDirectoryEntryRva = (UINT32) (DebugDirectoryEntryRva + Index * sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY));\r
+ ImageContext->DebugDirectoryEntryRva = (UINT32) (DebugDirectoryEntryRva + Index);\r
return RETURN_SUCCESS;\r
}\r
}\r
CHAR8 *FixupData;\r
PHYSICAL_ADDRESS BaseAddress;\r
UINT32 NumberOfRvaAndSizes;\r
+ UINT16 Magic;\r
\r
ASSERT (ImageContext != NULL);\r
\r
//\r
if (ImageContext->DestinationAddress != 0) {\r
BaseAddress = ImageContext->DestinationAddress;\r
- } else {\r
+ } else if (!(ImageContext->IsTeImage)) {\r
BaseAddress = ImageContext->ImageAddress;\r
+ } else {\r
+ Hdr.Te = (EFI_TE_IMAGE_HEADER *)(UINTN)(ImageContext->ImageAddress);\r
+ BaseAddress = ImageContext->ImageAddress + sizeof (EFI_TE_IMAGE_HEADER) - Hdr.Te->StrippedSize; \r
}\r
\r
if (!(ImageContext->IsTeImage)) {\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
+ Magic = PeCoffLoaderGetPeHeaderMagicValue (Hdr);\r
+\r
+ if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
//\r
// Use PE32 offset\r
//\r
UINTN Size;\r
UINT32 TempDebugEntryRva;\r
UINT32 NumberOfRvaAndSizes;\r
+ UINT16 Magic;\r
\r
ASSERT (ImageContext != NULL);\r
\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 (Hdr.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
+ if (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 (Hdr.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
+ if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
//\r
// Use PE32 offset\r
//\r
CHAR8 *FixupData;\r
UINTN Adjust;\r
RETURN_STATUS Status;\r
+ UINT16 Magic;\r
\r
OldBase = (CHAR8 *)((UINTN)ImageBase);\r
NewBase = (CHAR8 *)((UINTN)VirtImageBase);\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
+ Magic = PeCoffLoaderGetPeHeaderMagicValue (Hdr);\r
+\r
+ if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
//\r
// Use PE32 offset\r
//\r