ImageTool, BaseUeImageLib:

Added support for UeReloc32NoMeta relocation type to remove limitation 
of 1MiB, formerly imposed on UE files by chaining relocations.
This commit is contained in:
Mikhail Krichanov 2023-09-18 20:29:56 +03:00 committed by MikhailKrichanov
parent 0fca8bb634
commit e33395096c
5 changed files with 117 additions and 50 deletions

View File

@ -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) {

View File

@ -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,

View File

@ -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
};

View File

@ -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)) {

View File

@ -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)
}