Skip to content

Commit

Permalink
ImageTool, BaseUeImageLib:
Browse files Browse the repository at this point in the history
Added support for UeReloc32NoMeta relocation type to remove limitation 
of 1MiB,
formerly imposed on UE files by chaining relocations.
  • Loading branch information
Mikhail Krichanov committed Sep 18, 2023
1 parent 594f429 commit 38600a0
Show file tree
Hide file tree
Showing 5 changed files with 117 additions and 50 deletions.
39 changes: 25 additions & 14 deletions BaseTools/ImageTool/UeEmit.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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) {
Expand Down
4 changes: 2 additions & 2 deletions BaseTools/ImageTool/UeScan.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -296,7 +296,7 @@ ScanUeGetRelocInfo (
//
RelocType = UE_RELOC_FIXUP_TYPE (FixupInfo);

if (Chaining) {
if (Chaining && (RelocType != UeReloc32NoMeta)) {
Status = InternalProcessRelocChain (
&Buffer,
SegmentInfo,
Expand Down
5 changes: 3 additions & 2 deletions MdePkg/Include/IndustryStandard/UeImage.h
Original file line number Diff line number Diff line change
Expand Up @@ -176,8 +176,9 @@ STATIC_ASSERT (
/// Definitions of the generic UE relocation identifiers.
///
enum {
UeReloc32 = 0x00,
UeReloc64 = 0x01,
UeReloc32 = 0x00,
UeReloc64 = 0x01,
UeReloc32NoMeta = 0x03,
UeRelocGenericMax
};

Expand Down
117 changes: 86 additions & 31 deletions MdePkg/Library/BaseUeImageLib/UeImageLib.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -842,7 +877,8 @@ InternaRelocateImage (
UINT32 RelocTarget;

UINT32 OldTableOffset;
UINT64 *FixupData;
UINT64 FixupData;
UINT64 *FixupPointer;

ASSERT (Image != NULL);
ASSERT (RelocTable != NULL || RelocTableSize == 0);
Expand All @@ -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,
Expand Down Expand Up @@ -921,7 +960,7 @@ InternaRelocateImage (
//
RelocType = UE_RELOC_FIXUP_TYPE (FixupInfo);

if (!IsRuntime) {
if (!IsRuntime && (RelocType != UeReloc32NoMeta)) {
Status = InternalProcessRelocChain (
Image,
ImageSize,
Expand All @@ -939,10 +978,26 @@ InternaRelocateImage (
RelocType,
&RelocTarget,
Adjust,
FixupData
IsRuntime ? FixupPointer : &FixupData,
IsRuntime
);

if (RETURN_ERROR (Status)) {
return Status;
}

Status = UnchainReloc (
RuntimeContext,
(CONST UINT8 *)&FixupInfo,
sizeof (FixupInfo),
IsRuntime,
0,
&FixupData
);

++FixupData;
if (IsRuntime) {
++FixupPointer;
}
}

if (RETURN_ERROR (Status)) {
Expand Down
2 changes: 1 addition & 1 deletion OvmfPkg/OvmfPkgIa32.fdf
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
Expand Down

0 comments on commit 38600a0

Please sign in to comment.