Do not apply relocation fixups if the Adjust value is zero, which means the image is XIP.
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@9333 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
parent
d40d3ba499
commit
01e1171ebd
@ -635,115 +635,120 @@ PeCoffLoaderRelocateImage (
|
|||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Run the relocation information and apply the fixups
|
// If Adjust is not zero, then apply fix ups to the image
|
||||||
//
|
//
|
||||||
FixupData = ImageContext->FixupData;
|
if (Adjust != 0) {
|
||||||
while (RelocBase < RelocBaseEnd) {
|
|
||||||
|
|
||||||
Reloc = (UINT16 *) ((CHAR8 *) RelocBase + sizeof (EFI_IMAGE_BASE_RELOCATION));
|
|
||||||
RelocEnd = (UINT16 *) ((CHAR8 *) RelocBase + RelocBase->SizeOfBlock);
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Make sure RelocEnd is in the Image range.
|
// Run the relocation information and apply the fixups
|
||||||
//
|
//
|
||||||
if ((CHAR8 *) RelocEnd < (CHAR8 *)((UINTN) ImageContext->ImageAddress) ||
|
FixupData = ImageContext->FixupData;
|
||||||
(CHAR8 *) RelocEnd > (CHAR8 *)((UINTN)ImageContext->ImageAddress + (UINTN)ImageContext->ImageSize)) {
|
while (RelocBase < RelocBaseEnd) {
|
||||||
ImageContext->ImageError = IMAGE_ERROR_FAILED_RELOCATION;
|
|
||||||
return RETURN_LOAD_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(ImageContext->IsTeImage)) {
|
Reloc = (UINT16 *) ((CHAR8 *) RelocBase + sizeof (EFI_IMAGE_BASE_RELOCATION));
|
||||||
FixupBase = PeCoffLoaderImageAddress (ImageContext, RelocBase->VirtualAddress);
|
RelocEnd = (UINT16 *) ((CHAR8 *) RelocBase + RelocBase->SizeOfBlock);
|
||||||
if (FixupBase == NULL) {
|
|
||||||
|
//
|
||||||
|
// Make sure RelocEnd is in the Image range.
|
||||||
|
//
|
||||||
|
if ((CHAR8 *) RelocEnd < (CHAR8 *)((UINTN) ImageContext->ImageAddress) ||
|
||||||
|
(CHAR8 *) RelocEnd > (CHAR8 *)((UINTN)ImageContext->ImageAddress + (UINTN)ImageContext->ImageSize)) {
|
||||||
|
ImageContext->ImageError = IMAGE_ERROR_FAILED_RELOCATION;
|
||||||
return RETURN_LOAD_ERROR;
|
return RETURN_LOAD_ERROR;
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
FixupBase = (CHAR8 *)(UINTN)(ImageContext->ImageAddress +
|
|
||||||
RelocBase->VirtualAddress +
|
|
||||||
sizeof(EFI_TE_IMAGE_HEADER) -
|
|
||||||
Hdr.Te->StrippedSize
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
if (!(ImageContext->IsTeImage)) {
|
||||||
// Run this relocation record
|
FixupBase = PeCoffLoaderImageAddress (ImageContext, RelocBase->VirtualAddress);
|
||||||
//
|
if (FixupBase == NULL) {
|
||||||
while (Reloc < RelocEnd) {
|
return RETURN_LOAD_ERROR;
|
||||||
|
|
||||||
Fixup = FixupBase + (*Reloc & 0xFFF);
|
|
||||||
switch ((*Reloc) >> 12) {
|
|
||||||
case EFI_IMAGE_REL_BASED_ABSOLUTE:
|
|
||||||
break;
|
|
||||||
|
|
||||||
case EFI_IMAGE_REL_BASED_HIGH:
|
|
||||||
Fixup16 = (UINT16 *) Fixup;
|
|
||||||
*Fixup16 = (UINT16) (*Fixup16 + ((UINT16) ((UINT32) Adjust >> 16)));
|
|
||||||
if (FixupData != NULL) {
|
|
||||||
*(UINT16 *) FixupData = *Fixup16;
|
|
||||||
FixupData = FixupData + sizeof (UINT16);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case EFI_IMAGE_REL_BASED_LOW:
|
|
||||||
Fixup16 = (UINT16 *) Fixup;
|
|
||||||
*Fixup16 = (UINT16) (*Fixup16 + (UINT16) Adjust);
|
|
||||||
if (FixupData != NULL) {
|
|
||||||
*(UINT16 *) FixupData = *Fixup16;
|
|
||||||
FixupData = FixupData + sizeof (UINT16);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case EFI_IMAGE_REL_BASED_HIGHLOW:
|
|
||||||
Fixup32 = (UINT32 *) Fixup;
|
|
||||||
*Fixup32 = *Fixup32 + (UINT32) Adjust;
|
|
||||||
if (FixupData != NULL) {
|
|
||||||
FixupData = ALIGN_POINTER (FixupData, sizeof (UINT32));
|
|
||||||
*(UINT32 *)FixupData = *Fixup32;
|
|
||||||
FixupData = FixupData + sizeof (UINT32);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case EFI_IMAGE_REL_BASED_DIR64:
|
|
||||||
Fixup64 = (UINT64 *) Fixup;
|
|
||||||
*Fixup64 = *Fixup64 + (UINT64) Adjust;
|
|
||||||
if (FixupData != NULL) {
|
|
||||||
FixupData = ALIGN_POINTER (FixupData, sizeof(UINT64));
|
|
||||||
*(UINT64 *)(FixupData) = *Fixup64;
|
|
||||||
FixupData = FixupData + sizeof(UINT64);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
//
|
|
||||||
// The common code does not handle some of the stranger IPF relocations
|
|
||||||
// PeCoffLoaderRelocateImageEx () adds support for these complex fixups
|
|
||||||
// on IPF and is a No-Op on other architectures.
|
|
||||||
//
|
|
||||||
Status = PeCoffLoaderRelocateImageEx (Reloc, Fixup, &FixupData, Adjust);
|
|
||||||
if (RETURN_ERROR (Status)) {
|
|
||||||
ImageContext->ImageError = IMAGE_ERROR_FAILED_RELOCATION;
|
|
||||||
return Status;
|
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
FixupBase = (CHAR8 *)(UINTN)(ImageContext->ImageAddress +
|
||||||
|
RelocBase->VirtualAddress +
|
||||||
|
sizeof(EFI_TE_IMAGE_HEADER) -
|
||||||
|
Hdr.Te->StrippedSize
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Next relocation record
|
// Run this relocation record
|
||||||
//
|
//
|
||||||
Reloc += 1;
|
while (Reloc < RelocEnd) {
|
||||||
|
|
||||||
|
Fixup = FixupBase + (*Reloc & 0xFFF);
|
||||||
|
switch ((*Reloc) >> 12) {
|
||||||
|
case EFI_IMAGE_REL_BASED_ABSOLUTE:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EFI_IMAGE_REL_BASED_HIGH:
|
||||||
|
Fixup16 = (UINT16 *) Fixup;
|
||||||
|
*Fixup16 = (UINT16) (*Fixup16 + ((UINT16) ((UINT32) Adjust >> 16)));
|
||||||
|
if (FixupData != NULL) {
|
||||||
|
*(UINT16 *) FixupData = *Fixup16;
|
||||||
|
FixupData = FixupData + sizeof (UINT16);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EFI_IMAGE_REL_BASED_LOW:
|
||||||
|
Fixup16 = (UINT16 *) Fixup;
|
||||||
|
*Fixup16 = (UINT16) (*Fixup16 + (UINT16) Adjust);
|
||||||
|
if (FixupData != NULL) {
|
||||||
|
*(UINT16 *) FixupData = *Fixup16;
|
||||||
|
FixupData = FixupData + sizeof (UINT16);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EFI_IMAGE_REL_BASED_HIGHLOW:
|
||||||
|
Fixup32 = (UINT32 *) Fixup;
|
||||||
|
*Fixup32 = *Fixup32 + (UINT32) Adjust;
|
||||||
|
if (FixupData != NULL) {
|
||||||
|
FixupData = ALIGN_POINTER (FixupData, sizeof (UINT32));
|
||||||
|
*(UINT32 *)FixupData = *Fixup32;
|
||||||
|
FixupData = FixupData + sizeof (UINT32);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EFI_IMAGE_REL_BASED_DIR64:
|
||||||
|
Fixup64 = (UINT64 *) Fixup;
|
||||||
|
*Fixup64 = *Fixup64 + (UINT64) Adjust;
|
||||||
|
if (FixupData != NULL) {
|
||||||
|
FixupData = ALIGN_POINTER (FixupData, sizeof(UINT64));
|
||||||
|
*(UINT64 *)(FixupData) = *Fixup64;
|
||||||
|
FixupData = FixupData + sizeof(UINT64);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
//
|
||||||
|
// The common code does not handle some of the stranger IPF relocations
|
||||||
|
// PeCoffLoaderRelocateImageEx () adds support for these complex fixups
|
||||||
|
// on IPF and is a No-Op on other architectures.
|
||||||
|
//
|
||||||
|
Status = PeCoffLoaderRelocateImageEx (Reloc, Fixup, &FixupData, Adjust);
|
||||||
|
if (RETURN_ERROR (Status)) {
|
||||||
|
ImageContext->ImageError = IMAGE_ERROR_FAILED_RELOCATION;
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Next relocation record
|
||||||
|
//
|
||||||
|
Reloc += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Next reloc block
|
||||||
|
//
|
||||||
|
RelocBase = (EFI_IMAGE_BASE_RELOCATION *) RelocEnd;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Next reloc block
|
// Adjust the EntryPoint to match the linked-to address
|
||||||
//
|
//
|
||||||
RelocBase = (EFI_IMAGE_BASE_RELOCATION *) RelocEnd;
|
if (ImageContext->DestinationAddress != 0) {
|
||||||
}
|
ImageContext->EntryPoint -= (UINT64) ImageContext->ImageAddress;
|
||||||
|
ImageContext->EntryPoint += (UINT64) ImageContext->DestinationAddress;
|
||||||
//
|
}
|
||||||
// Adjust the EntryPoint to match the linked-to address
|
|
||||||
//
|
|
||||||
if (ImageContext->DestinationAddress != 0) {
|
|
||||||
ImageContext->EntryPoint -= (UINT64) ImageContext->ImageAddress;
|
|
||||||
ImageContext->EntryPoint += (UINT64) ImageContext->DestinationAddress;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Applies additional environment specific actions to relocate fixups
|
// Applies additional environment specific actions to relocate fixups
|
||||||
|
Loading…
x
Reference in New Issue
Block a user