diff --git a/BaseTools/ImageTool/UeEmit.c b/BaseTools/ImageTool/UeEmit.c index ad7cb347c7..b945db6457 100644 --- a/BaseTools/ImageTool/UeEmit.c +++ b/BaseTools/ImageTool/UeEmit.c @@ -430,6 +430,16 @@ ToolImageEmitUeRelocTable ( if (ChainInProgress) { ChainInProgress = ChainSupported && (RelocOffset <= UE_CHAINED_RELOC_FIXUP_MAX_OFFSET) && (PrevRelocType == RelocType); + if (ChainInProgress && (RelocType == UeReloc32)) { + ChainRelocInfo32 = UE_CHAINED_RELOC_FIXUP_OFFSET_END; + ChainRelocInfo32 |= RelocValue << UE_CHAINED_RELOC_FIXUP_VALUE_32_SHIFT; + if ((ChainRelocInfo32 >> UE_CHAINED_RELOC_FIXUP_VALUE_32_SHIFT) != RelocValue) { + ChainInProgress = false; + ChainSupported = false; + RelocType = UeReloc32NoMeta; + } + } + if (ChainInProgress && (RelocType == UeReloc64)) { PrevChainRelocInfo = RelocType; PrevChainRelocInfo |= RelocOffset << 4U; @@ -490,24 +500,25 @@ ToolImageEmitUeRelocTable ( ChainRelocInfo32 = UE_CHAINED_RELOC_FIXUP_OFFSET_END; ChainRelocInfo32 |= RelocValue << UE_CHAINED_RELOC_FIXUP_VALUE_32_SHIFT; if ((ChainRelocInfo32 >> UE_CHAINED_RELOC_FIXUP_VALUE_32_SHIFT) != RelocValue) { - DEBUG_RAISE (); - return false; - } + ChainInProgress = false; + ChainSupported = false; + RelocType = UeReloc32NoMeta; + } else { + assert (RelocSize <= sizeof (ChainRelocInfo32)); - assert (RelocSize <= sizeof (ChainRelocInfo32)); - - ImageToolBufferWrite ( - Buffer, - RelocFileOffset, - &ChainRelocInfo32, - RelocSize + ImageToolBufferWrite ( + Buffer, + RelocFileOffset, + &ChainRelocInfo32, + RelocSize ); - if (ChainInProgress) { - continue; - } + if (ChainInProgress) { + continue; + } - ChainInProgress = true; + ChainInProgress = true; + } } if (Index > 0 && RelocOffset <= UE_HEAD_FIXUP_MAX_OFFSET) { diff --git a/BaseTools/ImageTool/UeScan.c b/BaseTools/ImageTool/UeScan.c index a69d4fb288..880d8bd02d 100644 --- a/BaseTools/ImageTool/UeScan.c +++ b/BaseTools/ImageTool/UeScan.c @@ -182,7 +182,7 @@ InternalApplyRelocation ( // Apply the relocation fixup per type. // if (RelocType < UeRelocGenericMax) { - if (RelocType == UeReloc32) { + if ((RelocType == UeReloc32) || (RelocType == UeReloc32NoMeta)) { FixupSize = sizeof (UINT32); Reloc.Type = EFI_IMAGE_REL_BASED_HIGHLOW; } else { @@ -296,7 +296,7 @@ ScanUeGetRelocInfo ( // RelocType = UE_RELOC_FIXUP_TYPE (FixupInfo); - if (Chaining) { + if (Chaining && (RelocType != UeReloc32NoMeta)) { Status = InternalProcessRelocChain ( &Buffer, SegmentInfo, diff --git a/MdePkg/Include/IndustryStandard/UeImage.h b/MdePkg/Include/IndustryStandard/UeImage.h index 42e337abf3..f65e341d8a 100644 --- a/MdePkg/Include/IndustryStandard/UeImage.h +++ b/MdePkg/Include/IndustryStandard/UeImage.h @@ -176,8 +176,9 @@ STATIC_ASSERT ( /// Definitions of the generic UE relocation identifiers. /// enum { - UeReloc32 = 0x00, - UeReloc64 = 0x01, + UeReloc32 = 0x00, + UeReloc64 = 0x01, + UeReloc32NoMeta = 0x02, UeRelocGenericMax }; diff --git a/MdePkg/Library/BaseUeImageLib/UeImageLib.c b/MdePkg/Library/BaseUeImageLib/UeImageLib.c index 2ef011281b..e4736c4ed2 100644 --- a/MdePkg/Library/BaseUeImageLib/UeImageLib.c +++ b/MdePkg/Library/BaseUeImageLib/UeImageLib.c @@ -462,7 +462,8 @@ InternalApplyRelocation ( IN UINT16 RelocType, IN UINT32 *RelocTarget, IN UINT64 Adjust, - IN UINT64 *FixupData + IN OUT UINT64 *FixupData, + IN BOOLEAN IsRuntime ) { BOOLEAN Overflow; @@ -492,34 +493,32 @@ InternalApplyRelocation ( // if (RelocType < UeRelocGenericMax) { if (RelocType == UeReloc32) { - FixupSize = sizeof (UINT32); - // - // Verify the relocation fixup target is in bounds of the image buffer. - // - if (FixupSize > RemFixupTargetSize) { - DEBUG_RAISE (); - return RETURN_VOLUME_CORRUPTED; - } - // - // Relocate the target instruction. - // - FixupValue.Value32 = ReadUnaligned32 (Fixup); - // - // If the Image relocation target value mismatches, skip or abort. - // - if (FixupValue.Value32 != (UINT32)*FixupData) { - if (PcdGetBool (PcdImageLoaderRtRelocAllowTargetMismatch)) { - return RETURN_SUCCESS; - } - - return RETURN_VOLUME_CORRUPTED; + FixupSize = sizeof (UINT32); + // + // Verify the relocation fixup target is in bounds of the image buffer. + // + if (FixupSize > RemFixupTargetSize) { + DEBUG_RAISE (); + return RETURN_VOLUME_CORRUPTED; + } + // + // Relocate the target instruction. + // + FixupValue.Value32 = ReadUnaligned32 (Fixup); + // + // If the Image relocation target value mismatches, skip or abort. + // + if (FixupValue.Value32 != (UINT32)*FixupData) { + if (PcdGetBool (PcdImageLoaderRtRelocAllowTargetMismatch)) { + return RETURN_SUCCESS; } - FixupValue.Value32 += (UINT32) Adjust; - WriteUnaligned32 (Fixup, FixupValue.Value32); - } else { - ASSERT (RelocType == UeReloc64); + return RETURN_VOLUME_CORRUPTED; + } + FixupValue.Value32 += (UINT32) Adjust; + WriteUnaligned32 (Fixup, FixupValue.Value32); + } else if (RelocType == UeReloc64) { FixupSize = sizeof (UINT64); // // Verify the image relocation fixup target is in bounds of the image @@ -546,6 +545,42 @@ InternalApplyRelocation ( FixupValue.Value64 += Adjust; WriteUnaligned64 (Fixup, FixupValue.Value64); + } else if (RelocType == UeReloc32NoMeta) { + FixupSize = sizeof (UINT32); + // + // Verify the relocation fixup target is in bounds of the image buffer. + // + if (FixupSize > RemFixupTargetSize) { + DEBUG_RAISE (); + return RETURN_VOLUME_CORRUPTED; + } + // + // Relocate the target instruction. + // + FixupValue.Value32 = ReadUnaligned32 (Fixup); + // + // If the Image relocation target value mismatches, skip or abort. + // + if (IsRuntime && (FixupValue.Value32 != (UINT32)*FixupData)) { + if (PcdGetBool (PcdImageLoaderRtRelocAllowTargetMismatch)) { + return RETURN_SUCCESS; + } + + return RETURN_VOLUME_CORRUPTED; + } + + FixupValue.Value32 += (UINT32) Adjust; + WriteUnaligned32 (Fixup, FixupValue.Value32); + + if (!IsRuntime) { + *FixupData = FixupValue.Value32; + } + } else { + // + // The image relocation fixup type is unknown, disallow the image. + // + DEBUG_RAISE (); + return RETURN_UNSUPPORTED; } } else { #if 0 @@ -842,7 +877,8 @@ InternaRelocateImage ( UINT32 RelocTarget; UINT32 OldTableOffset; - UINT64 *FixupData; + UINT64 FixupData; + UINT64 *FixupPointer; ASSERT (Image != NULL); ASSERT (RelocTable != NULL || RelocTableSize == 0); @@ -868,7 +904,10 @@ InternaRelocateImage ( } RelocTarget = 0; - FixupData = RuntimeContext != NULL ? RuntimeContext->FixupData : NULL; + + if (IsRuntime) { + FixupPointer = RuntimeContext->FixupData; + } STATIC_ASSERT ( MIN_SIZE_OF_UE_FIXUP_ROOT <= UE_LOAD_TABLE_ALIGNMENT, @@ -921,7 +960,7 @@ InternaRelocateImage ( // RelocType = UE_RELOC_FIXUP_TYPE (FixupInfo); - if (!IsRuntime) { + if (!IsRuntime && (RelocType != UeReloc32NoMeta)) { Status = InternalProcessRelocChain ( Image, ImageSize, @@ -939,10 +978,26 @@ InternaRelocateImage ( RelocType, &RelocTarget, Adjust, - FixupData + IsRuntime ? FixupPointer : &FixupData, + IsRuntime ); - ++FixupData; + if (RETURN_ERROR (Status)) { + return Status; + } + + Status = UnchainReloc ( + RuntimeContext, + (CONST UINT8 *)&FixupInfo, + sizeof (FixupInfo), + IsRuntime, + 0, + &FixupData + ); + + if (IsRuntime) { + ++FixupPointer; + } } if (RETURN_ERROR (Status)) { diff --git a/OvmfPkg/OvmfPkgIa32.fdf b/OvmfPkg/OvmfPkgIa32.fdf index 09b727b39c..204a43fb16 100644 --- a/OvmfPkg/OvmfPkgIa32.fdf +++ b/OvmfPkg/OvmfPkgIa32.fdf @@ -479,7 +479,7 @@ FILE FV_IMAGE = 9E21FD93-9C72-4c15-8C4B-E77F1DB2D792 { [Rule.Common.UEFI_APPLICATION] FILE APPLICATION = $(NAMED_GUID) { - PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi + UE UE $(INF_OUTPUT)/$(MODULE_NAME).efi UI STRING="$(MODULE_NAME)" Optional VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER) }