mirror of
https://github.com/acidanthera/audk.git
synced 2025-09-25 18:48:42 +02:00
BaseUeImageLib: Added support for Runtime chaining relocs.
This commit is contained in:
parent
c3ffeb1985
commit
33ef407f5e
@ -822,8 +822,7 @@ ToolImageEmitUeFile (
|
|||||||
LastSegmentIndex = (uint8_t)(Image->SegmentInfo.NumSegments - 1U);
|
LastSegmentIndex = (uint8_t)(Image->SegmentInfo.NumSegments - 1U);
|
||||||
|
|
||||||
Chaining = Image->HeaderInfo.BaseAddress == 0 &&
|
Chaining = Image->HeaderInfo.BaseAddress == 0 &&
|
||||||
!Image->HeaderInfo.FixedAddress &&
|
!Image->HeaderInfo.FixedAddress;
|
||||||
Image->HeaderInfo.Subsystem != EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER;
|
|
||||||
|
|
||||||
UeHdr.Magic = UE_HEADER_MAGIC;
|
UeHdr.Magic = UE_HEADER_MAGIC;
|
||||||
|
|
||||||
|
@ -19,13 +19,14 @@
|
|||||||
#include <Library/PeCoffLib2.h>
|
#include <Library/PeCoffLib2.h>
|
||||||
#include <Library/UefiImageLib.h>
|
#include <Library/UefiImageLib.h>
|
||||||
#include <Library/UeImageLib.h>
|
#include <Library/UeImageLib.h>
|
||||||
#include <Library/PcdLib.h>
|
|
||||||
|
|
||||||
struct UE_LOADER_RUNTIME_CONTEXT_ {
|
struct UE_LOADER_RUNTIME_CONTEXT_ {
|
||||||
UINT8 Machine;
|
UINT8 Machine;
|
||||||
UINT8 Reserved[7];
|
UINT8 Reserved[7];
|
||||||
UINT32 FixupSize;
|
UINT32 FixupSize;
|
||||||
UINT64 *FixupData;
|
UINT64 *FixupData;
|
||||||
|
UINT32 UnchainedRelocsSize;
|
||||||
|
UINT8 *UnchainedRelocs;
|
||||||
UINT32 RelocTableSize;
|
UINT32 RelocTableSize;
|
||||||
UINT8 RelocTable[];
|
UINT8 RelocTable[];
|
||||||
};
|
};
|
||||||
@ -461,8 +462,7 @@ InternalApplyRelocation (
|
|||||||
IN UINT16 RelocType,
|
IN UINT16 RelocType,
|
||||||
IN UINT32 *RelocTarget,
|
IN UINT32 *RelocTarget,
|
||||||
IN UINT64 Adjust,
|
IN UINT64 Adjust,
|
||||||
OUT UINT64 *FixupData OPTIONAL,
|
IN UINT64 *FixupData
|
||||||
IN BOOLEAN IsRuntime
|
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
BOOLEAN Overflow;
|
BOOLEAN Overflow;
|
||||||
@ -474,6 +474,8 @@ InternalApplyRelocation (
|
|||||||
UINT8 FixupSize;
|
UINT8 FixupSize;
|
||||||
UE_RELOC_FIXUP_VALUE FixupValue;
|
UE_RELOC_FIXUP_VALUE FixupValue;
|
||||||
|
|
||||||
|
ASSERT (FixupData != NULL);
|
||||||
|
|
||||||
FixupTarget = *RelocTarget;
|
FixupTarget = *RelocTarget;
|
||||||
//
|
//
|
||||||
// Verify the relocation fixup target address is in bounds of the image buffer.
|
// Verify the relocation fixup target address is in bounds of the image buffer.
|
||||||
@ -505,7 +507,7 @@ InternalApplyRelocation (
|
|||||||
//
|
//
|
||||||
// If the Image relocation target value mismatches, skip or abort.
|
// If the Image relocation target value mismatches, skip or abort.
|
||||||
//
|
//
|
||||||
if (IsRuntime && (FixupValue.Value32 != (UINT32)*FixupData)) {
|
if (FixupValue.Value32 != (UINT32)*FixupData) {
|
||||||
if (PcdGetBool (PcdImageLoaderRtRelocAllowTargetMismatch)) {
|
if (PcdGetBool (PcdImageLoaderRtRelocAllowTargetMismatch)) {
|
||||||
return RETURN_SUCCESS;
|
return RETURN_SUCCESS;
|
||||||
}
|
}
|
||||||
@ -515,10 +517,6 @@ InternalApplyRelocation (
|
|||||||
|
|
||||||
FixupValue.Value32 += (UINT32) Adjust;
|
FixupValue.Value32 += (UINT32) Adjust;
|
||||||
WriteUnaligned32 (Fixup, FixupValue.Value32);
|
WriteUnaligned32 (Fixup, FixupValue.Value32);
|
||||||
|
|
||||||
if (!IsRuntime) {
|
|
||||||
*FixupData = FixupValue.Value32;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
ASSERT (RelocType == UeReloc64);
|
ASSERT (RelocType == UeReloc64);
|
||||||
|
|
||||||
@ -538,7 +536,7 @@ InternalApplyRelocation (
|
|||||||
//
|
//
|
||||||
// If the Image relocation target value mismatches, skip or abort.
|
// If the Image relocation target value mismatches, skip or abort.
|
||||||
//
|
//
|
||||||
if (IsRuntime && (FixupValue.Value64 != *FixupData)) {
|
if (FixupValue.Value64 != *FixupData) {
|
||||||
if (PcdGetBool (PcdImageLoaderRtRelocAllowTargetMismatch)) {
|
if (PcdGetBool (PcdImageLoaderRtRelocAllowTargetMismatch)) {
|
||||||
return RETURN_SUCCESS;
|
return RETURN_SUCCESS;
|
||||||
}
|
}
|
||||||
@ -548,10 +546,6 @@ InternalApplyRelocation (
|
|||||||
|
|
||||||
FixupValue.Value64 += Adjust;
|
FixupValue.Value64 += Adjust;
|
||||||
WriteUnaligned64 (Fixup, FixupValue.Value64);
|
WriteUnaligned64 (Fixup, FixupValue.Value64);
|
||||||
|
|
||||||
if (!IsRuntime) {
|
|
||||||
*FixupData = FixupValue.Value64;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
#if 0
|
#if 0
|
||||||
@ -606,6 +600,67 @@ InternalApplyRelocation (
|
|||||||
return RETURN_SUCCESS;
|
return RETURN_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
STATIC
|
||||||
|
RETURN_STATUS
|
||||||
|
UnchainReloc (
|
||||||
|
IN OUT UE_LOADER_RUNTIME_CONTEXT *RuntimeContext OPTIONAL,
|
||||||
|
IN CONST UINT8 *MetaSource OPTIONAL,
|
||||||
|
IN UINT32 MetaSize,
|
||||||
|
IN BOOLEAN IsRuntime,
|
||||||
|
IN UINT16 RelocOffset,
|
||||||
|
IN UINT64 *FixupData
|
||||||
|
)
|
||||||
|
{
|
||||||
|
UINT32 OldSize;
|
||||||
|
UINT16 FixupHdr;
|
||||||
|
UINT32 FixupIndex;
|
||||||
|
|
||||||
|
if ((RuntimeContext != NULL) && !IsRuntime) {
|
||||||
|
if (MetaSource == NULL) {
|
||||||
|
FixupIndex = RuntimeContext->UnchainedRelocsSize - sizeof (UINT16);
|
||||||
|
|
||||||
|
FixupHdr = *(UINT16 *)&RuntimeContext->UnchainedRelocs[FixupIndex];
|
||||||
|
FixupHdr = (RelocOffset << 4U) | UE_RELOC_FIXUP_TYPE(FixupHdr);
|
||||||
|
|
||||||
|
*(UINT16 *)&RuntimeContext->UnchainedRelocs[FixupIndex] = FixupHdr;
|
||||||
|
|
||||||
|
return RETURN_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
OldSize = RuntimeContext->UnchainedRelocsSize;
|
||||||
|
RuntimeContext->UnchainedRelocs = ReallocateRuntimePool (
|
||||||
|
OldSize,
|
||||||
|
OldSize + MetaSize,
|
||||||
|
RuntimeContext->UnchainedRelocs
|
||||||
|
);
|
||||||
|
if (RuntimeContext->UnchainedRelocs == NULL) {
|
||||||
|
return RETURN_OUT_OF_RESOURCES;
|
||||||
|
}
|
||||||
|
|
||||||
|
CopyMem (RuntimeContext->UnchainedRelocs + OldSize, MetaSource, MetaSize);
|
||||||
|
|
||||||
|
RuntimeContext->UnchainedRelocsSize += MetaSize;
|
||||||
|
|
||||||
|
if (FixupData != NULL) {
|
||||||
|
OldSize = RuntimeContext->FixupSize;
|
||||||
|
RuntimeContext->FixupData = ReallocateRuntimePool (
|
||||||
|
OldSize,
|
||||||
|
OldSize + sizeof (*FixupData),
|
||||||
|
RuntimeContext->FixupData
|
||||||
|
);
|
||||||
|
if (RuntimeContext->FixupData == NULL) {
|
||||||
|
return RETURN_OUT_OF_RESOURCES;
|
||||||
|
}
|
||||||
|
|
||||||
|
CopyMem ((UINT8 *)RuntimeContext->FixupData + OldSize, FixupData, sizeof (*FixupData));
|
||||||
|
|
||||||
|
RuntimeContext->FixupSize += sizeof (*FixupData);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return RETURN_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
STATIC
|
STATIC
|
||||||
RETURN_STATUS
|
RETURN_STATUS
|
||||||
InternalProcessRelocChain (
|
InternalProcessRelocChain (
|
||||||
@ -614,9 +669,11 @@ InternalProcessRelocChain (
|
|||||||
IN UINT8 Machine,
|
IN UINT8 Machine,
|
||||||
IN UINT16 FirstRelocType,
|
IN UINT16 FirstRelocType,
|
||||||
IN UINT32 *ChainStart,
|
IN UINT32 *ChainStart,
|
||||||
IN UINT64 Adjust
|
IN UINT64 Adjust,
|
||||||
|
IN OUT UE_LOADER_RUNTIME_CONTEXT *RuntimeContext OPTIONAL
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
RETURN_STATUS Status;
|
||||||
UINT16 RelocType;
|
UINT16 RelocType;
|
||||||
UINT16 RelocOffset;
|
UINT16 RelocOffset;
|
||||||
UINT32 RelocTarget;
|
UINT32 RelocTarget;
|
||||||
@ -628,6 +685,8 @@ InternalProcessRelocChain (
|
|||||||
UE_RELOC_FIXUP_VALUE FixupInfo;
|
UE_RELOC_FIXUP_VALUE FixupInfo;
|
||||||
UINT8 FixupSize;
|
UINT8 FixupSize;
|
||||||
UE_RELOC_FIXUP_VALUE FixupValue;
|
UE_RELOC_FIXUP_VALUE FixupValue;
|
||||||
|
UINT16 FixupHdr;
|
||||||
|
UINT64 FixupData;
|
||||||
|
|
||||||
RelocType = FirstRelocType;
|
RelocType = FirstRelocType;
|
||||||
RelocTarget = *ChainStart;
|
RelocTarget = *ChainStart;
|
||||||
@ -658,6 +717,8 @@ InternalProcessRelocChain (
|
|||||||
FixupValue.Value64 = UE_CHAINED_RELOC_FIXUP_VALUE (FixupInfo.Value64);
|
FixupValue.Value64 = UE_CHAINED_RELOC_FIXUP_VALUE (FixupInfo.Value64);
|
||||||
FixupValue.Value64 += Adjust;
|
FixupValue.Value64 += Adjust;
|
||||||
WriteUnaligned64 ((VOID *)Fixup, FixupValue.Value64);
|
WriteUnaligned64 ((VOID *)Fixup, FixupValue.Value64);
|
||||||
|
|
||||||
|
FixupData = FixupValue.Value64;
|
||||||
} else if (RelocType == UeReloc32) {
|
} else if (RelocType == UeReloc32) {
|
||||||
FixupSize = sizeof (UINT32);
|
FixupSize = sizeof (UINT32);
|
||||||
//
|
//
|
||||||
@ -675,6 +736,8 @@ InternalProcessRelocChain (
|
|||||||
FixupValue.Value32 = UE_CHAINED_RELOC_FIXUP_VALUE_32 (FixupInfo.Value32);
|
FixupValue.Value32 = UE_CHAINED_RELOC_FIXUP_VALUE_32 (FixupInfo.Value32);
|
||||||
FixupValue.Value32 += (UINT32) Adjust;
|
FixupValue.Value32 += (UINT32) Adjust;
|
||||||
WriteUnaligned32 ((VOID *)Fixup, FixupValue.Value32);
|
WriteUnaligned32 ((VOID *)Fixup, FixupValue.Value32);
|
||||||
|
|
||||||
|
FixupData = FixupValue.Value32;
|
||||||
//
|
//
|
||||||
// Imitate the common header of UE chained relocation fixups,
|
// Imitate the common header of UE chained relocation fixups,
|
||||||
// as for 32-bit files all relocs have the same type.
|
// as for 32-bit files all relocs have the same type.
|
||||||
@ -699,6 +762,20 @@ InternalProcessRelocChain (
|
|||||||
RelocTarget += FixupSize;
|
RelocTarget += FixupSize;
|
||||||
|
|
||||||
RelocOffset = UE_CHAINED_RELOC_FIXUP_NEXT_OFFSET (FixupInfo.Value32);
|
RelocOffset = UE_CHAINED_RELOC_FIXUP_NEXT_OFFSET (FixupInfo.Value32);
|
||||||
|
FixupHdr = (RelocOffset << 4) | RelocType;
|
||||||
|
|
||||||
|
Status = UnchainReloc (
|
||||||
|
RuntimeContext,
|
||||||
|
(CONST UINT8 *)&FixupHdr,
|
||||||
|
sizeof (FixupHdr),
|
||||||
|
FALSE,
|
||||||
|
0,
|
||||||
|
&FixupData
|
||||||
|
);
|
||||||
|
if (RETURN_ERROR (Status)) {
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
if (RelocOffset == UE_CHAINED_RELOC_FIXUP_OFFSET_END) {
|
if (RelocOffset == UE_CHAINED_RELOC_FIXUP_OFFSET_END) {
|
||||||
*ChainStart = RelocTarget;
|
*ChainStart = RelocTarget;
|
||||||
return RETURN_SUCCESS;
|
return RETURN_SUCCESS;
|
||||||
@ -727,7 +804,7 @@ InternaRelocateImage (
|
|||||||
IN UINT32 RelocTableSize,
|
IN UINT32 RelocTableSize,
|
||||||
IN BOOLEAN Chaining,
|
IN BOOLEAN Chaining,
|
||||||
IN UINT64 BaseAddress,
|
IN UINT64 BaseAddress,
|
||||||
OUT UINT64 *FixupData OPTIONAL,
|
OUT UE_LOADER_RUNTIME_CONTEXT *RuntimeContext OPTIONAL,
|
||||||
IN BOOLEAN IsRuntime
|
IN BOOLEAN IsRuntime
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
@ -748,6 +825,7 @@ InternaRelocateImage (
|
|||||||
UINT32 RelocTarget;
|
UINT32 RelocTarget;
|
||||||
|
|
||||||
UINT32 OldTableOffset;
|
UINT32 OldTableOffset;
|
||||||
|
UINT64 *FixupData;
|
||||||
|
|
||||||
ASSERT (Image != NULL);
|
ASSERT (Image != NULL);
|
||||||
ASSERT (RelocTable != NULL || RelocTableSize == 0);
|
ASSERT (RelocTable != NULL || RelocTableSize == 0);
|
||||||
@ -773,6 +851,7 @@ InternaRelocateImage (
|
|||||||
}
|
}
|
||||||
|
|
||||||
RelocTarget = 0;
|
RelocTarget = 0;
|
||||||
|
FixupData = RuntimeContext != NULL ? RuntimeContext->FixupData : NULL;
|
||||||
|
|
||||||
STATIC_ASSERT (
|
STATIC_ASSERT (
|
||||||
MIN_SIZE_OF_UE_FIXUP_ROOT <= UE_LOAD_TABLE_ALIGNMENT,
|
MIN_SIZE_OF_UE_FIXUP_ROOT <= UE_LOAD_TABLE_ALIGNMENT,
|
||||||
@ -799,6 +878,18 @@ InternaRelocateImage (
|
|||||||
DEBUG_RAISE ();
|
DEBUG_RAISE ();
|
||||||
return RETURN_VOLUME_CORRUPTED;
|
return RETURN_VOLUME_CORRUPTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Status = UnchainReloc (
|
||||||
|
RuntimeContext,
|
||||||
|
(CONST UINT8 *)RelocRoot,
|
||||||
|
sizeof (*RelocRoot),
|
||||||
|
IsRuntime,
|
||||||
|
0,
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
if (RETURN_ERROR (Status)) {
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
//
|
//
|
||||||
// Process all relocation fixups of the current root.
|
// Process all relocation fixups of the current root.
|
||||||
//
|
//
|
||||||
@ -813,14 +904,15 @@ InternaRelocateImage (
|
|||||||
//
|
//
|
||||||
RelocType = UE_RELOC_FIXUP_TYPE (FixupInfo);
|
RelocType = UE_RELOC_FIXUP_TYPE (FixupInfo);
|
||||||
|
|
||||||
if (Chaining) {
|
if (!IsRuntime) {
|
||||||
Status = InternalProcessRelocChain (
|
Status = InternalProcessRelocChain (
|
||||||
Image,
|
Image,
|
||||||
ImageSize,
|
ImageSize,
|
||||||
Machine,
|
Machine,
|
||||||
RelocType,
|
RelocType,
|
||||||
&RelocTarget,
|
&RelocTarget,
|
||||||
Adjust
|
Adjust,
|
||||||
|
RuntimeContext
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
Status = InternalApplyRelocation (
|
Status = InternalApplyRelocation (
|
||||||
@ -830,8 +922,7 @@ InternaRelocateImage (
|
|||||||
RelocType,
|
RelocType,
|
||||||
&RelocTarget,
|
&RelocTarget,
|
||||||
Adjust,
|
Adjust,
|
||||||
FixupData,
|
FixupData
|
||||||
IsRuntime
|
|
||||||
);
|
);
|
||||||
|
|
||||||
++FixupData;
|
++FixupData;
|
||||||
@ -842,6 +933,19 @@ InternaRelocateImage (
|
|||||||
}
|
}
|
||||||
|
|
||||||
RelocOffset = UE_RELOC_FIXUP_OFFSET (FixupInfo);
|
RelocOffset = UE_RELOC_FIXUP_OFFSET (FixupInfo);
|
||||||
|
|
||||||
|
Status = UnchainReloc (
|
||||||
|
RuntimeContext,
|
||||||
|
NULL,
|
||||||
|
0,
|
||||||
|
IsRuntime,
|
||||||
|
RelocOffset,
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
if (RETURN_ERROR (Status)) {
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
if (RelocOffset == UE_HEAD_FIXUP_OFFSET_END) {
|
if (RelocOffset == UE_HEAD_FIXUP_OFFSET_END) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -901,11 +1005,6 @@ UeRelocateImage (
|
|||||||
Chaining = (UeHdr->ImageInfo & UE_HEADER_IMAGE_INFO_CHAINED_FIXUPS) != 0;
|
Chaining = (UeHdr->ImageInfo & UE_HEADER_IMAGE_INFO_CHAINED_FIXUPS) != 0;
|
||||||
|
|
||||||
if (RuntimeContext != NULL) {
|
if (RuntimeContext != NULL) {
|
||||||
if (Chaining) {
|
|
||||||
DEBUG_RAISE ();
|
|
||||||
return RETURN_VOLUME_CORRUPTED;
|
|
||||||
}
|
|
||||||
|
|
||||||
RuntimeContext->Machine = Context->Machine;
|
RuntimeContext->Machine = Context->Machine;
|
||||||
RuntimeContext->RelocTableSize = Context->RelocTableSize;
|
RuntimeContext->RelocTableSize = Context->RelocTableSize;
|
||||||
|
|
||||||
@ -915,12 +1014,6 @@ UeRelocateImage (
|
|||||||
Context->FileBuffer + Context->LoadTablesFileOffset,
|
Context->FileBuffer + Context->LoadTablesFileOffset,
|
||||||
Context->RelocTableSize
|
Context->RelocTableSize
|
||||||
);
|
);
|
||||||
|
|
||||||
RuntimeContext->FixupSize = Context->RelocTableSize / sizeof (UINT16) * sizeof (UINT64);
|
|
||||||
RuntimeContext->FixupData = AllocateRuntimeZeroPool (RuntimeContext->FixupSize);
|
|
||||||
if (RuntimeContext->FixupData == NULL) {
|
|
||||||
ASSERT (FALSE);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return InternaRelocateImage (
|
return InternaRelocateImage (
|
||||||
@ -932,7 +1025,7 @@ UeRelocateImage (
|
|||||||
Context->RelocTableSize,
|
Context->RelocTableSize,
|
||||||
Chaining,
|
Chaining,
|
||||||
BaseAddress,
|
BaseAddress,
|
||||||
RuntimeContext != NULL ? RuntimeContext->FixupData : NULL,
|
RuntimeContext,
|
||||||
FALSE
|
FALSE
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -953,11 +1046,11 @@ UeRelocateImageForRuntime (
|
|||||||
ImageSize,
|
ImageSize,
|
||||||
RuntimeContext->Machine,
|
RuntimeContext->Machine,
|
||||||
(UINTN)Image,
|
(UINTN)Image,
|
||||||
RuntimeContext->RelocTable,
|
RuntimeContext->UnchainedRelocs,
|
||||||
RuntimeContext->RelocTableSize,
|
RuntimeContext->UnchainedRelocsSize,
|
||||||
FALSE,
|
FALSE,
|
||||||
BaseAddress,
|
BaseAddress,
|
||||||
RuntimeContext->FixupData,
|
(UE_LOADER_RUNTIME_CONTEXT *)RuntimeContext,
|
||||||
TRUE
|
TRUE
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user