\r
**/\r
\r
+/**\r
+ Performs an Itanium-based specific relocation fixup.\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
-STATIC\r
-RETURN_STATUS\r
-PeCoffLoaderGetPeHeader (\r
- IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext,\r
- OUT EFI_IMAGE_NT_HEADERS *PeHdr,\r
- OUT EFI_TE_IMAGE_HEADER *TeHdr\r
- );\r
-\r
-STATIC\r
-RETURN_STATUS\r
-PeCoffLoaderCheckImageType (\r
- IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext,\r
- IN EFI_IMAGE_NT_HEADERS *PeHdr,\r
- IN EFI_TE_IMAGE_HEADER *TeHdr\r
- );\r
-\r
-STATIC\r
-VOID *\r
-PeCoffLoaderImageAddress (\r
- IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext,\r
- IN UINTN Address\r
- );\r
-\r
+**/\r
RETURN_STATUS\r
PeCoffLoaderRelocateImageEx (\r
IN UINT16 *Reloc,\r
/**\r
Retrieves the PE or TE Header from a PE/COFF or TE image.\r
\r
- @param ImageContext The context of the image being loaded.\r
- \r
- @param PeHdr The buffer in which to return the PE header.\r
- \r
- @param TeHdr The buffer in which to return the TE header.\r
+ @param ImageContext The context of the image being loaded.\r
+ @param PeHdr The buffer in which to return the PE header.\r
+ @param TeHdr The buffer in which to return the TE header.\r
\r
- @return\r
- RETURN_SUCCESS if the PE or TE Header is read,\r
- Otherwise, the error status from reading the PE/COFF or TE image using the ImageRead function.\r
+ @retval RETURN_SUCCESS The PE or TE Header is read.\r
+ @retval Other The error status from reading the PE/COFF or TE image using the ImageRead function.\r
\r
**/\r
STATIC\r
OUT EFI_TE_IMAGE_HEADER *TeHdr\r
)\r
{\r
- RETURN_STATUS Status;\r
+ RETURN_STATUS Status;\r
EFI_IMAGE_DOS_HEADER DosHdr;\r
UINTN Size;\r
\r
//\r
Size = sizeof (EFI_IMAGE_DOS_HEADER);\r
Status = ImageContext->ImageRead (\r
- ImageContext->Handle,\r
- 0,\r
- &Size,\r
- &DosHdr\r
- );\r
+ ImageContext->Handle,\r
+ 0,\r
+ &Size,\r
+ &DosHdr\r
+ );\r
if (RETURN_ERROR (Status)) {\r
ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;\r
return Status;\r
//\r
Size = sizeof (EFI_IMAGE_NT_HEADERS);\r
Status = ImageContext->ImageRead (\r
- ImageContext->Handle,\r
- ImageContext->PeCoffHeaderOffset,\r
- &Size,\r
- PeHdr\r
- );\r
+ ImageContext->Handle,\r
+ ImageContext->PeCoffHeaderOffset,\r
+ &Size,\r
+ PeHdr\r
+ );\r
if (RETURN_ERROR (Status)) {\r
ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;\r
return Status;\r
if (PeHdr->Signature != EFI_IMAGE_NT_SIGNATURE) {\r
Size = sizeof (EFI_TE_IMAGE_HEADER);\r
Status = ImageContext->ImageRead (\r
- ImageContext->Handle,\r
- 0,\r
- &Size,\r
- TeHdr\r
- );\r
+ ImageContext->Handle,\r
+ 0,\r
+ &Size,\r
+ TeHdr\r
+ );\r
if (TeHdr->Signature != EFI_TE_IMAGE_HEADER_SIGNATURE) {\r
return RETURN_UNSUPPORTED;\r
}\r
/**\r
Checks the PE or TE header of a PE/COFF or TE image to determine if it supported.\r
\r
- @param ImageContext The context of the image being loaded.\r
- \r
- @param PeHdr The buffer in which to return the PE header.\r
- \r
- @param TeHdr The buffer in which to return the TE header.\r
+ @param ImageContext The context of the image being loaded.\r
+ @param PeHdr The buffer in which to return the PE header.\r
+ @param TeHdr The buffer in which to return the TE header.\r
\r
- @retval RETURN_SUCCESS if the PE/COFF or TE image is supported\r
- @retval RETURN_UNSUPPORTED of the PE/COFF or TE image is not supported.\r
+ @retval RETURN_SUCCESS The PE/COFF or TE image is supported.\r
+ @retval RETURN_UNSUPPORTED The PE/COFF or TE image is not supported.\r
\r
**/\r
STATIC\r
}\r
\r
/**\r
- Retrieves information on a PE/COFF image.\r
+ Retrieves information about a PE/COFF image.\r
+\r
+ Computes the PeCoffHeaderOffset, ImageAddress, ImageSize, DestinationAddress, CodeView,\r
+ PdbPointer, RelocationsStripped, SectionAlignment, SizeOfHeaders, and DebugDirectoryEntryRva\r
+ fields of the ImageContext structure. If ImageContext is NULL, then return RETURN_INVALID_PARAMETER.\r
+ If the PE/COFF image accessed through the ImageRead service in the ImageContext structure is not\r
+ a supported PE/COFF image type, then return RETURN_UNSUPPORTED. If any errors occur while\r
+ computing the fields of ImageContext, then the error status is returned in the ImageError field of\r
+ ImageContext. \r
\r
- @param This Calling context\r
- @param ImageContext The context of the image being loaded\r
+ @param ImageContext Pointer to the image context structure that describes the PE/COFF\r
+ image that needs to be examined by this function.\r
\r
- @retval RETURN_SUCCESS The information on the PE/COFF image was collected.\r
- @retval RETURN_INVALID_PARAMETER ImageContext is NULL.\r
- @retval RETURN_UNSUPPORTED The PE/COFF image is not supported.\r
- @retval Otherwise The error status from reading the PE/COFF image using the\r
- ImageContext->ImageRead() function\r
+ @retval RETURN_SUCCESS The information on the PE/COFF image was collected.\r
+ @retval RETURN_INVALID_PARAMETER ImageContext is NULL.\r
+ @retval RETURN_UNSUPPORTED The PE/COFF image is not supported.\r
\r
**/\r
RETURN_STATUS\r
IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext\r
)\r
{\r
- RETURN_STATUS Status;\r
+ RETURN_STATUS Status;\r
EFI_IMAGE_NT_HEADERS PeHdr;\r
EFI_TE_IMAGE_HEADER TeHdr;\r
EFI_IMAGE_DATA_DIRECTORY *DebugDirectoryEntry;\r
//\r
// Read section header from file\r
//\r
- Size = sizeof (EFI_IMAGE_SECTION_HEADER);\r
+ Size = sizeof (EFI_IMAGE_SECTION_HEADER);\r
Status = ImageContext->ImageRead (\r
ImageContext->Handle,\r
SectionHeaderOffset,\r
if (DebugDirectoryEntryRva >= SectionHeader.VirtualAddress &&\r
DebugDirectoryEntryRva < SectionHeader.VirtualAddress + SectionHeader.Misc.VirtualSize) {\r
DebugDirectoryEntryFileOffset = DebugDirectoryEntryRva -\r
- SectionHeader.VirtualAddress +\r
- SectionHeader.PointerToRawData +\r
- sizeof (EFI_TE_IMAGE_HEADER) -\r
- TeHdr.StrippedSize;\r
+ SectionHeader.VirtualAddress +\r
+ SectionHeader.PointerToRawData +\r
+ sizeof (EFI_TE_IMAGE_HEADER) -\r
+ TeHdr.StrippedSize;\r
\r
//\r
// File offset of the debug directory was found, if this is not the last\r
/**\r
Converts an image address to the loaded address.\r
\r
- @param ImageContext The context of the image being loaded.\r
- \r
- @param Address The address to be converted to the loaded address.\r
+ @param ImageContext The context of the image being loaded.\r
+ @param Address The address to be converted to the loaded address.\r
\r
- @return NULL if the address can not be converted, otherwise, the converted address\r
+ @return The converted address or NULL if the address can not be converted.\r
\r
**/\r
STATIC\r
}\r
\r
/**\r
- Relocates a PE/COFF image in memory.\r
+ Applies relocation fixups to a PE/COFF image that was loaded with PeCoffLoaderLoadImage().\r
\r
- @param This Calling context.\r
- \r
- @param ImageContext Contains information on the loaded image to relocate.\r
+ If the DestinationAddress field of ImageContext is 0, then use the ImageAddress field of\r
+ ImageContext as the relocation base address. Otherwise, use the DestinationAddress field\r
+ of ImageContext as the relocation base address. The caller must allocate the relocation\r
+ fixup log buffer and fill in the FixupData field of ImageContext prior to calling this function. \r
+ If ImageContext is NULL, then ASSERT().\r
+\r
+ @param ImageContext Pointer to the image context structure that describes the PE/COFF\r
+ image that is being relocated.\r
\r
- @retval RETURN_SUCCESS if the PE/COFF image was relocated.\r
- @retval RETURN_LOAD_ERROR if the image is not a valid PE/COFF image.\r
- @retval RETURN_UNSUPPORTED not support.\r
+ @retval RETURN_SUCCESS The PE/COFF image was relocated.\r
+ Extended status information is in the ImageError field of ImageContext.\r
+ @retval RETURN_LOAD_ERROR The image in not a valid PE/COFF image.\r
+ Extended status information is in the ImageError field of ImageContext.\r
+ @retval RETURN_UNSUPPORTED A relocation record type is not supported.\r
+ Extended status information is in the ImageError field of ImageContext.\r
\r
**/\r
RETURN_STATUS\r
CHAR8 *FixupData;\r
PHYSICAL_ADDRESS BaseAddress;\r
\r
+ ASSERT (ImageContext != NULL);\r
+\r
PeHdr = NULL;\r
TeHdr = NULL;\r
//\r
// If the destination address is not 0, use that rather than the\r
// image address as the relocation target.\r
//\r
- if (ImageContext->DestinationAddress) {\r
+ if (ImageContext->DestinationAddress != 0) {\r
BaseAddress = ImageContext->DestinationAddress;\r
} else {\r
BaseAddress = ImageContext->ImageAddress;\r
if (!(ImageContext->IsTeImage)) {\r
PeHdr = (EFI_IMAGE_NT_HEADERS *)((UINTN)ImageContext->ImageAddress + \r
ImageContext->PeCoffHeaderOffset);\r
+ \r
Adjust = (UINT64) BaseAddress - PeHdr->OptionalHeader.ImageBase;\r
PeHdr->OptionalHeader.ImageBase = (UINTN)BaseAddress;\r
\r
//\r
RelocDir = &TeHdr->DataDirectory[0];\r
RelocBase = (EFI_IMAGE_BASE_RELOCATION *)(UINTN)(\r
- ImageContext->ImageAddress + \r
- RelocDir->VirtualAddress +\r
- sizeof(EFI_TE_IMAGE_HEADER) - \r
- TeHdr->StrippedSize\r
- );\r
+ ImageContext->ImageAddress + \r
+ RelocDir->VirtualAddress +\r
+ sizeof(EFI_TE_IMAGE_HEADER) - \r
+ TeHdr->StrippedSize\r
+ );\r
RelocBaseEnd = (EFI_IMAGE_BASE_RELOCATION *) ((UINTN) RelocBase + (UINTN) RelocDir->Size - 1);\r
}\r
\r
FixupBase = PeCoffLoaderImageAddress (ImageContext, RelocBase->VirtualAddress);\r
} else {\r
FixupBase = (CHAR8 *)(UINTN)(ImageContext->ImageAddress +\r
- RelocBase->VirtualAddress +\r
- sizeof(EFI_TE_IMAGE_HEADER) - \r
- TeHdr->StrippedSize\r
- );\r
+ RelocBase->VirtualAddress +\r
+ sizeof(EFI_TE_IMAGE_HEADER) - \r
+ TeHdr->StrippedSize\r
+ );\r
}\r
\r
if ((CHAR8 *) RelocEnd < (CHAR8 *) ((UINTN) ImageContext->ImageAddress) ||\r
/**\r
Loads a PE/COFF image into memory.\r
\r
- @param This Calling context.\r
- \r
- @param ImageContext Contains information on image to load into memory.\r
-\r
- @retval RETURN_SUCCESS if the PE/COFF image was loaded.\r
- @retval RETURN_BUFFER_TOO_SMALL if the caller did not provide a large enough buffer.\r
- @retval RETURN_LOAD_ERROR if the image is a runtime driver with no relocations.\r
- @retval RETURN_INVALID_PARAMETER if the image address is invalid.\r
+ Loads the PE/COFF image accessed through the ImageRead service of ImageContext into the buffer\r
+ specified by the ImageAddress and ImageSize fields of ImageContext. The caller must allocate\r
+ the load buffer and fill in the ImageAddress and ImageSize fields prior to calling this function.\r
+ The EntryPoint, FixupDataSize, CodeView, and PdbPointer fields of ImageContext are computed.\r
+ If ImageContext is NULL, then ASSERT().\r
+\r
+ @param ImageContext Pointer to the image context structure that describes the PE/COFF\r
+ image that is being loaded.\r
+\r
+ @retval RETURN_SUCCESS The PE/COFF image was loaded into the buffer specified by\r
+ the ImageAddress and ImageSize fields of ImageContext.\r
+ Extended status information is in the ImageError field of ImageContext.\r
+ @retval RETURN_BUFFER_TOO_SMALL The caller did not provide a large enough buffer.\r
+ Extended status information is in the ImageError field of ImageContext.\r
+ @retval RETURN_LOAD_ERROR The PE/COFF image is an EFI Runtime image with no relocations.\r
+ Extended status information is in the ImageError field of ImageContext.\r
+ @retval RETURN_INVALID_PARAMETER The image address is invalid.\r
+ Extended status information is in the ImageError field of ImageContext.\r
\r
**/\r
RETURN_STATUS\r
IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext\r
)\r
{\r
- RETURN_STATUS Status;\r
+ RETURN_STATUS Status;\r
EFI_IMAGE_NT_HEADERS *PeHdr;\r
EFI_TE_IMAGE_HEADER *TeHdr;\r
- PE_COFF_LOADER_IMAGE_CONTEXT CheckContext;\r
+ PE_COFF_LOADER_IMAGE_CONTEXT CheckContext;\r
EFI_IMAGE_SECTION_HEADER *FirstSection;\r
EFI_IMAGE_SECTION_HEADER *Section;\r
UINTN NumberOfSections;\r
UINTN Size;\r
UINT32 TempDebugEntryRva;\r
\r
+ ASSERT (ImageContext != NULL);\r
+\r
PeHdr = NULL;\r
TeHdr = NULL;\r
+\r
//\r
// Assume success\r
//\r
ImageContext->ImageError = IMAGE_ERROR_INVALID_IMAGE_SIZE;\r
return RETURN_BUFFER_TOO_SMALL;\r
}\r
-\r
+ if (ImageContext->ImageAddress == 0) {\r
+ //\r
+ // Image cannot be loaded into 0 address.\r
+ //\r
+ ImageContext->ImageError = IMAGE_ERROR_INVALID_IMAGE_ADDRESS;\r
+ return RETURN_INVALID_PARAMETER;\r
+ }\r
//\r
// If there's no relocations, then make sure it's not a runtime driver,\r
// and that it's being loaded at the linked address.\r
TeHdr = (EFI_TE_IMAGE_HEADER *) (UINTN) (ImageContext->ImageAddress);\r
\r
FirstSection = (EFI_IMAGE_SECTION_HEADER *) (\r
- (UINTN)ImageContext->ImageAddress +\r
- sizeof(EFI_TE_IMAGE_HEADER)\r
- );\r
+ (UINTN)ImageContext->ImageAddress +\r
+ sizeof(EFI_TE_IMAGE_HEADER)\r
+ );\r
NumberOfSections = (UINTN) (TeHdr->NumberOfSections);\r
\r
}\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)ImageContext->ImageAddress +\r
+ (UINTN)TeHdr->AddressOfEntryPoint +\r
+ (UINTN)sizeof(EFI_TE_IMAGE_HEADER) -\r
(UINTN) TeHdr->StrippedSize\r
);\r
}\r
);\r
} else {\r
DebugEntry = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *)(UINTN)(\r
- ImageContext->ImageAddress +\r
- ImageContext->DebugDirectoryEntryRva +\r
- sizeof(EFI_TE_IMAGE_HEADER) -\r
- TeHdr->StrippedSize\r
- );\r
+ ImageContext->ImageAddress +\r
+ ImageContext->DebugDirectoryEntryRva +\r
+ sizeof(EFI_TE_IMAGE_HEADER) -\r
+ TeHdr->StrippedSize\r
+ );\r
}\r
\r
if (DebugEntry != NULL) {\r
ImageContext->CodeView = PeCoffLoaderImageAddress (ImageContext, TempDebugEntryRva);\r
} else {\r
ImageContext->CodeView = (VOID *)(\r
- (UINTN)ImageContext->ImageAddress +\r
- (UINTN)TempDebugEntryRva +\r
- (UINTN)sizeof(EFI_TE_IMAGE_HEADER) -\r
+ (UINTN)ImageContext->ImageAddress +\r
+ (UINTN)TempDebugEntryRva +\r
+ (UINTN)sizeof(EFI_TE_IMAGE_HEADER) -\r
(UINTN) TeHdr->StrippedSize\r
);\r
}\r