Converts an image address to the loaded address.\r
\r
@param ImageContext The context of the image being loaded.\r
- @param Address The address to be converted to the loaded address.\r
+ @param Address The relative virtual address to be converted to the loaded address.\r
\r
@return The converted address or NULL if the address can not be converted.\r
\r
)\r
{\r
//\r
- // @bug Check to make sure ImageSize is correct for the relocated image.\r
- // it may only work for the file we start with and not the relocated image\r
+ // Make sure that Address and ImageSize is correct for the loaded image.\r
//\r
if (Address >= ImageContext->ImageSize) {\r
ImageContext->ImageError = IMAGE_ERROR_INVALID_IMAGE_ADDRESS;\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
+ return RETURN_LOAD_ERROR;\r
+ }\r
} else {\r
//\r
// Set base and end to bypass processing below.\r
//\r
- RelocBase = RelocBaseEnd = 0;\r
+ RelocBase = RelocBaseEnd = NULL;\r
}\r
} else {\r
Hdr.Te = (EFI_TE_IMAGE_HEADER *)(UINTN)(ImageContext->ImageAddress);\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 = RelocBaseEnd = NULL; \r
+ }\r
}\r
\r
//\r
\r
Reloc = (UINT16 *) ((CHAR8 *) RelocBase + sizeof (EFI_IMAGE_BASE_RELOCATION));\r
RelocEnd = (UINT16 *) ((CHAR8 *) RelocBase + RelocBase->SizeOfBlock);\r
+ \r
+ //\r
+ // Make sure RelocEnd is in the Image range.\r
+ //\r
+ if ((CHAR8 *) RelocEnd < (CHAR8 *)((UINTN) ImageContext->ImageAddress) ||\r
+ (CHAR8 *) RelocEnd > (CHAR8 *)((UINTN)ImageContext->ImageAddress + (UINTN)ImageContext->ImageSize)) {\r
+ ImageContext->ImageError = IMAGE_ERROR_FAILED_RELOCATION;\r
+ return RETURN_LOAD_ERROR;\r
+ }\r
+\r
if (!(ImageContext->IsTeImage)) {\r
FixupBase = PeCoffLoaderImageAddress (ImageContext, RelocBase->VirtualAddress);\r
+ if (FixupBase == NULL) {\r
+ return RETURN_LOAD_ERROR;\r
+ }\r
} else {\r
FixupBase = (CHAR8 *)(UINTN)(ImageContext->ImageAddress +\r
RelocBase->VirtualAddress +\r
sizeof(EFI_TE_IMAGE_HEADER) -\r
Hdr.Te->StrippedSize\r
);\r
- }\r
-\r
- if ((CHAR8 *) RelocEnd < (CHAR8 *) ((UINTN) ImageContext->ImageAddress) ||\r
- (CHAR8 *) RelocEnd > (CHAR8 *)((UINTN)ImageContext->ImageAddress +\r
- (UINTN)ImageContext->ImageSize)) {\r
- ImageContext->ImageError = IMAGE_ERROR_FAILED_RELOCATION;\r
- return RETURN_LOAD_ERROR;\r
- }\r
+ } \r
\r
//\r
// Run this relocation record\r
//\r
Section = FirstSection;\r
for (Index = 0, MaxEnd = NULL; Index < NumberOfSections; Index++) {\r
-\r
//\r
// Compute sections address\r
//\r
ImageContext,\r
Section->VirtualAddress + Section->Misc.VirtualSize - 1\r
);\r
- if (ImageContext->IsTeImage) {\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
- MaxEnd = End;\r
- }\r
//\r
// If the base start or end address resolved to 0, then fail.\r
//\r
return RETURN_LOAD_ERROR;\r
}\r
\r
+ if (ImageContext->IsTeImage) {\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
+ MaxEnd = End;\r
+ }\r
+\r
//\r
// Read the section\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
+ This function reapplies relocation fixups to the PE/COFF image specified by ImageBase \r
+ and ImageSize so the image will execute correctly when the PE/COFF image is mapped \r
+ to the address specified by VirtualImageBase. RelocationData must be identical \r
+ to the FiuxupData buffer from the PE_COFF_LOADER_IMAGE_CONTEXT structure \r
+ after this PE/COFF image was relocated with PeCoffLoaderRelocateImage().\r
\r
@param ImageBase Base address of a PE/COFF image that has been loaded \r
and relocated into system memory.\r