mirror of https://github.com/acidanthera/audk.git
UE: Support UE generation and consumption.
This commit is contained in:
parent
683f4b85cb
commit
21327695a0
|
@ -155,6 +155,11 @@
|
|||
gEfiMdePkgTokenSpaceGuid.PcdReportStatusCodePropertyMask|3
|
||||
gEfiShellPkgTokenSpaceGuid.PcdShellFileOperationSize|0x20000
|
||||
|
||||
#
|
||||
# Firmware volume supports UE, and may require PE.
|
||||
#
|
||||
gEfiMdePkgTokenSpaceGuid.PcdUefiImageFormatSupportFv|0x03
|
||||
|
||||
[PcdsFixedAtBuild.AARCH64]
|
||||
# Clearing BIT0 in this PCD prevents installing a 32-bit SMBIOS entry point,
|
||||
# if the entry point version is >= 3.0. AARCH64 OSes cannot assume the
|
||||
|
|
|
@ -166,6 +166,11 @@
|
|||
gEmbeddedTokenSpaceGuid.PcdPrePiCpuIoSize|16
|
||||
|
||||
gArmTokenSpaceGuid.PcdMonitorConduitHvc|TRUE
|
||||
|
||||
#
|
||||
# Firmware volume supports UE, and may require PE.
|
||||
#
|
||||
gEfiMdePkgTokenSpaceGuid.PcdUefiImageFormatSupportFv|0x03
|
||||
|
||||
[PcdsPatchableInModule.common]
|
||||
#
|
||||
|
|
|
@ -231,6 +231,11 @@
|
|||
# System Memory Size -- 128 MB initially, actual size will be fetched from DT
|
||||
gArmTokenSpaceGuid.PcdSystemMemorySize|0x8000000
|
||||
|
||||
#
|
||||
# Firmware volume supports UE, and may require PE.
|
||||
#
|
||||
gEfiMdePkgTokenSpaceGuid.PcdUefiImageFormatSupportFv|0x03
|
||||
|
||||
[PcdsFixedAtBuild.AARCH64]
|
||||
# Clearing BIT0 in this PCD prevents installing a 32-bit SMBIOS entry point,
|
||||
# if the entry point version is >= 3.0. AARCH64 OSes cannot assume the
|
||||
|
|
|
@ -181,6 +181,11 @@
|
|||
gEfiMdePkgTokenSpaceGuid.PcdReportStatusCodePropertyMask|3
|
||||
gEfiShellPkgTokenSpaceGuid.PcdShellFileOperationSize|0x20000
|
||||
|
||||
#
|
||||
# Firmware volume supports UE, and may require PE.
|
||||
#
|
||||
gEfiMdePkgTokenSpaceGuid.PcdUefiImageFormatSupportFv|0x03
|
||||
|
||||
[PcdsPatchableInModule.common]
|
||||
# we need to provide a resolution for this PCD that supports PcdSet64()
|
||||
# being called from ArmVirtPkg/Library/PlatformPeiLib/PlatformPeiLib.c,
|
||||
|
|
|
@ -35,61 +35,61 @@
|
|||
############################################################################
|
||||
|
||||
[Rule.Common.SEC]
|
||||
FILE SEC = $(NAMED_GUID) RELOCS_STRIPPED FIXED {
|
||||
PE32 PE32 Align = Auto $(INF_OUTPUT)/$(MODULE_NAME).efi
|
||||
FILE SEC = $(NAMED_GUID) {
|
||||
UE UE $(INF_OUTPUT)/$(MODULE_NAME).efi
|
||||
}
|
||||
|
||||
[Rule.Common.SEC.SELF_RELOC]
|
||||
FILE SEC = $(NAMED_GUID) {
|
||||
PE32 PE32 Align = Auto $(INF_OUTPUT)/$(MODULE_NAME).efi
|
||||
UE UE $(INF_OUTPUT)/$(MODULE_NAME).efi
|
||||
}
|
||||
|
||||
[Rule.Common.PEI_CORE]
|
||||
FILE PEI_CORE = $(NAMED_GUID) FIXED {
|
||||
PE32 PE32 Align = Auto $(INF_OUTPUT)/$(MODULE_NAME).efi
|
||||
UI STRING ="$(MODULE_NAME)" Optional
|
||||
FILE PEI_CORE = $(NAMED_GUID) {
|
||||
UE UE $(INF_OUTPUT)/$(MODULE_NAME).efi
|
||||
UI STRING="$(MODULE_NAME)" Optional
|
||||
}
|
||||
|
||||
[Rule.Common.PEIM]
|
||||
FILE PEIM = $(NAMED_GUID) FIXED {
|
||||
PEI_DEPEX PEI_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex
|
||||
PE32 PE32 Align = Auto $(INF_OUTPUT)/$(MODULE_NAME).efi
|
||||
UI STRING="$(MODULE_NAME)" Optional
|
||||
FILE PEIM = $(NAMED_GUID) {
|
||||
PEI_DEPEX PEI_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex
|
||||
UE UE $(INF_OUTPUT)/$(MODULE_NAME).efi
|
||||
UI STRING="$(MODULE_NAME)" Optional
|
||||
}
|
||||
|
||||
[Rule.Common.DXE_CORE]
|
||||
FILE DXE_CORE = $(NAMED_GUID) {
|
||||
PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi
|
||||
UI STRING="$(MODULE_NAME)" Optional
|
||||
UE UE $(INF_OUTPUT)/$(MODULE_NAME).efi
|
||||
UI STRING="$(MODULE_NAME)" Optional
|
||||
}
|
||||
|
||||
[Rule.Common.UEFI_DRIVER]
|
||||
FILE DRIVER = $(NAMED_GUID) {
|
||||
DXE_DEPEX DXE_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex
|
||||
PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi
|
||||
UI STRING="$(MODULE_NAME)" Optional
|
||||
DXE_DEPEX DXE_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex
|
||||
UE UE $(INF_OUTPUT)/$(MODULE_NAME).efi
|
||||
UI STRING="$(MODULE_NAME)" Optional
|
||||
}
|
||||
|
||||
[Rule.Common.DXE_DRIVER]
|
||||
FILE DRIVER = $(NAMED_GUID) {
|
||||
DXE_DEPEX DXE_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex
|
||||
PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi
|
||||
UI STRING="$(MODULE_NAME)" Optional
|
||||
RAW ACPI Optional |.acpi
|
||||
RAW ASL Optional |.aml
|
||||
DXE_DEPEX DXE_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex
|
||||
UE UE $(INF_OUTPUT)/$(MODULE_NAME).efi
|
||||
UI STRING="$(MODULE_NAME)" Optional
|
||||
RAW ACPI Optional |.acpi
|
||||
RAW ASL Optional |.aml
|
||||
}
|
||||
|
||||
[Rule.Common.DXE_RUNTIME_DRIVER]
|
||||
FILE DRIVER = $(NAMED_GUID) {
|
||||
DXE_DEPEX DXE_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex
|
||||
PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi
|
||||
UI STRING="$(MODULE_NAME)" Optional
|
||||
DXE_DEPEX DXE_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex
|
||||
UE UE $(INF_OUTPUT)/$(MODULE_NAME).efi
|
||||
UI STRING="$(MODULE_NAME)" Optional
|
||||
}
|
||||
|
||||
[Rule.Common.UEFI_APPLICATION]
|
||||
FILE APPLICATION = $(NAMED_GUID) {
|
||||
UI STRING ="$(MODULE_NAME)" Optional
|
||||
PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi
|
||||
UI STRING="$(MODULE_NAME)" Optional
|
||||
UE UE $(INF_OUTPUT)/$(MODULE_NAME).efi
|
||||
}
|
||||
|
||||
[Rule.Common.UEFI_DRIVER.BINARY]
|
||||
|
@ -102,7 +102,7 @@
|
|||
|
||||
[Rule.Common.UEFI_APPLICATION.BINARY]
|
||||
FILE APPLICATION = $(NAMED_GUID) {
|
||||
PE32 PE32 |.efi
|
||||
UE UE |.efi
|
||||
UI STRING="$(MODULE_NAME)" Optional
|
||||
VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
|
||||
}
|
||||
|
|
|
@ -103,6 +103,11 @@
|
|||
#
|
||||
gEfiMdeModulePkgTokenSpaceGuid.PcdEmuVariableNvModeEnable|TRUE
|
||||
|
||||
#
|
||||
# Firmware volume supports UE, and may require PE.
|
||||
#
|
||||
gEfiMdePkgTokenSpaceGuid.PcdUefiImageFormatSupportFv|0x03
|
||||
|
||||
[PcdsPatchableInModule.common]
|
||||
# we need to provide a resolution for this PCD that supports PcdSet64()
|
||||
# being called from ArmVirtPkg/Library/PlatformPeiLib/PlatformPeiLib.c,
|
||||
|
|
|
@ -10,7 +10,9 @@
|
|||
#include "ImageTool.h"
|
||||
#include "DynamicBuffer.h"
|
||||
|
||||
#ifndef IMAGE_TOOL_DYNAMIC_BUFFER_GROWTH
|
||||
#define IMAGE_TOOL_DYNAMIC_BUFFER_GROWTH 0x1000
|
||||
#endif // IMAGE_TOOL_DYNAMIC_BUFFER_GROWTH
|
||||
|
||||
void
|
||||
ImageToolBufferInit (
|
||||
|
@ -186,9 +188,11 @@ ImageToolBufferDump (
|
|||
void *Data;
|
||||
uint32_t DataSize;
|
||||
|
||||
// LCOV_EXCL_START
|
||||
if (Buffer->Memory == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
// LCOV_EXCL_STOP
|
||||
|
||||
DataSize = ImageToolBufferGetSize (Buffer);
|
||||
|
||||
|
|
|
@ -7,10 +7,10 @@
|
|||
PROJECT = ImageTool
|
||||
PRODUCT = $(PROJECT)$(INFIX)$(SUFFIX)
|
||||
OBJS = $(PROJECT).o
|
||||
OBJS += Image.o UefiImageScan.o PeEmit32.o PeEmit64.o PeEmitCommon.o PeScan.o ElfScan32.o ElfScan64.o ElfScanCommon.o BinEmit.o ImageToolEmit.o
|
||||
OBJS += UefiImageExtraActionLib.o
|
||||
OBJS += Image.o UefiImageScan.o UeEmit.o UeScan.o PeEmit32.o PeEmit64.o PeEmitCommon.o PeScan.o ElfScan32.o ElfScan64.o ElfScanCommon.o BinEmit.o ImageToolEmit.o
|
||||
OBJS += UeImageLib.o UefiImageExtraActionLib.o
|
||||
OBJS += PeCoffInit.o PeCoffInfo.o PeCoffLoad.o PeCoffRelocate.o PeCoffHii.o PeCoffDebug.o PeCoffHash.o
|
||||
OBJS += PeSupport.o UefiImageLib.o CommonSupport.o DynamicBuffer.o
|
||||
OBJS += PeSupport.o UeSupport.o UefiImageLib.o CommonSupport.o DynamicBuffer.o
|
||||
|
||||
WERROR = 1
|
||||
DEBUG = 1
|
||||
|
@ -20,7 +20,8 @@ UDK_PATH = ../..
|
|||
|
||||
VPATH += ../../MdePkg/Library/BasePeCoffLib2:$\
|
||||
../../MdePkg/Library/BaseUefiImageExtraActionLibNull:$\
|
||||
../../MdePkg/Library/BaseUefiImageLib
|
||||
../../MdePkg/Library/BaseUefiImageLib:$\
|
||||
../../MdePkg/Library/BaseUeImageLib
|
||||
|
||||
include $(OC_USER)/User/Makefile
|
||||
|
||||
|
|
|
@ -16,10 +16,12 @@ CheckToolImageSegment (
|
|||
{
|
||||
bool Overflow;
|
||||
|
||||
// LCOV_EXCL_START
|
||||
if (!IS_ALIGNED (Segment->ImageSize, SegmentInfo->SegmentAlignment)) {
|
||||
DEBUG_RAISE ();
|
||||
assert (false);
|
||||
return false;
|
||||
}
|
||||
// LCOV_EXCL_STOP
|
||||
|
||||
if (Segment->Write && Segment->Execute) {
|
||||
DEBUG_RAISE ();
|
||||
|
@ -32,14 +34,16 @@ CheckToolImageSegment (
|
|||
}
|
||||
|
||||
Overflow = BaseOverflowAddU32 (
|
||||
Segment->ImageAddress,
|
||||
Segment->ImageSize,
|
||||
PreviousEndAddress
|
||||
);
|
||||
Segment->ImageAddress,
|
||||
Segment->ImageSize,
|
||||
PreviousEndAddress
|
||||
);
|
||||
// LCOV_EXCL_START
|
||||
if (Overflow) {
|
||||
DEBUG_RAISE ();
|
||||
assert (false);
|
||||
return false;
|
||||
}
|
||||
// LCOV_EXCL_STOP
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -54,28 +58,32 @@ CheckToolImageSegmentInfo (
|
|||
uint32_t Index;
|
||||
bool Result;
|
||||
|
||||
// LCOV_EXCL_START
|
||||
if (!IS_POW2 (SegmentInfo->SegmentAlignment)) {
|
||||
DEBUG_RAISE ();
|
||||
assert (false);
|
||||
return false;
|
||||
}
|
||||
// LCOV_EXCL_STOP
|
||||
|
||||
if (SegmentInfo->NumSegments == 0) {
|
||||
DEBUG_RAISE ();
|
||||
return false;
|
||||
}
|
||||
|
||||
// LCOV_EXCL_START
|
||||
if (!IS_ALIGNED (SegmentInfo->Segments[0].ImageAddress, SegmentInfo->SegmentAlignment)) {
|
||||
DEBUG_RAISE ();
|
||||
assert (false);
|
||||
return false;
|
||||
}
|
||||
// LCOV_EXCL_STOP
|
||||
|
||||
*ImageSize = SegmentInfo->Segments[0].ImageAddress;
|
||||
for (Index = 0; Index < SegmentInfo->NumSegments; ++Index) {
|
||||
Result = CheckToolImageSegment (
|
||||
SegmentInfo,
|
||||
&SegmentInfo->Segments[Index],
|
||||
ImageSize
|
||||
);
|
||||
SegmentInfo,
|
||||
&SegmentInfo->Segments[Index],
|
||||
ImageSize
|
||||
);
|
||||
if (!Result) {
|
||||
DEBUG_RAISE ();
|
||||
return false;
|
||||
|
@ -99,15 +107,19 @@ CheckToolImageHeaderInfo (
|
|||
return false;
|
||||
}
|
||||
|
||||
// LCOV_EXCL_START
|
||||
if (!IS_ALIGNED (HeaderInfo->BaseAddress, SegmentInfo->SegmentAlignment)) {
|
||||
DEBUG_RAISE ();
|
||||
assert (false);
|
||||
return false;
|
||||
}
|
||||
// LCOV_EXCL_STOP
|
||||
|
||||
// LCOV_EXCL_START
|
||||
if (HeaderInfo->BaseAddress + ImageSize < HeaderInfo->BaseAddress) {
|
||||
DEBUG_RAISE ();
|
||||
assert (false);
|
||||
return false;
|
||||
}
|
||||
// LCOV_EXCL_STOP
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -138,7 +150,9 @@ ToolImageGetRelocSize (
|
|||
uint8_t Type
|
||||
)
|
||||
{
|
||||
// LCOV_EXCL_START
|
||||
switch (Type) {
|
||||
// LCOV_EXCL_STOP
|
||||
case EFI_IMAGE_REL_BASED_HIGHLOW:
|
||||
{
|
||||
return sizeof (UINT32);
|
||||
|
@ -156,11 +170,18 @@ ToolImageGetRelocSize (
|
|||
}
|
||||
#endif
|
||||
|
||||
// LCOV_EXCL_START
|
||||
default:
|
||||
{
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
// LCOV_EXCL_STOP
|
||||
}
|
||||
|
||||
// LCOV_EXCL_START
|
||||
assert (false);
|
||||
return 0;
|
||||
// LCOV_EXCL_STOP
|
||||
}
|
||||
|
||||
static
|
||||
|
@ -214,9 +235,8 @@ CheckToolImageReloc (
|
|||
#endif
|
||||
|
||||
// FIXME: Update drivers?
|
||||
if ((Image->HeaderInfo.Subsystem == EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER ||
|
||||
Image->HeaderInfo.Subsystem == EFI_IMAGE_SUBSYSTEM_SAL_RUNTIME_DRIVER) &&
|
||||
Segment->Write) {
|
||||
if (Image->HeaderInfo.Subsystem == EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER &&
|
||||
Segment->Write) {
|
||||
printf("!!! writable reloc at %x !!!\n", Reloc->Target);
|
||||
//DEBUG_RAISE ();
|
||||
//return false;
|
||||
|
@ -243,10 +263,12 @@ CheckToolImageRelocInfo (
|
|||
return true;
|
||||
}
|
||||
|
||||
// LCOV_EXCL_START
|
||||
if (RelocInfo->RelocsStripped) {
|
||||
DEBUG_RAISE ();
|
||||
assert (false);
|
||||
return false;
|
||||
}
|
||||
// LCOV_EXCL_STOP
|
||||
|
||||
if (RelocInfo->NumRelocs > (MAX_UINT32 / sizeof (UINT16))) {
|
||||
DEBUG_RAISE ();
|
||||
|
@ -262,10 +284,12 @@ CheckToolImageRelocInfo (
|
|||
}
|
||||
|
||||
RelocSize = ToolImageGetRelocSize (RelocInfo->Relocs[Index].Type);
|
||||
// LCOV_EXCL_START
|
||||
if (RelocSize == 0) {
|
||||
DEBUG_RAISE ();
|
||||
assert (false);
|
||||
return false;
|
||||
}
|
||||
// LCOV_EXCL_STOP
|
||||
|
||||
Result = CheckToolImageReloc (Image, &RelocInfo->Relocs[Index], RelocSize);
|
||||
if (!Result) {
|
||||
|
@ -357,33 +381,47 @@ ToolImageDestruct (
|
|||
image_tool_image_info_t *Image
|
||||
)
|
||||
{
|
||||
uint8_t Index;
|
||||
uint16_t Index;
|
||||
|
||||
// LCOV_EXCL_START
|
||||
if (Image->SegmentInfo.Segments != NULL) {
|
||||
// LCOV_EXCL_STOP
|
||||
for (Index = 0; Index < Image->SegmentInfo.NumSegments; ++Index) {
|
||||
// LCOV_EXCL_START
|
||||
if (Image->SegmentInfo.Segments[Index].Name != NULL) {
|
||||
// LCOV_EXCL_STOP
|
||||
FreePool (Image->SegmentInfo.Segments[Index].Name);
|
||||
}
|
||||
|
||||
// LCOV_EXCL_START
|
||||
if (Image->SegmentInfo.Segments[Index].Data != NULL) {
|
||||
// LCOV_EXCL_STOP
|
||||
FreePool (Image->SegmentInfo.Segments[Index].Data);
|
||||
}
|
||||
}
|
||||
|
||||
// LCOV_EXCL_START
|
||||
if (Image->SegmentInfo.Segments != NULL) {
|
||||
// LCOV_EXCL_STOP
|
||||
FreePool (Image->SegmentInfo.Segments);
|
||||
}
|
||||
}
|
||||
|
||||
// LCOV_EXCL_START
|
||||
if (Image->HiiInfo.Data != NULL) {
|
||||
// LCOV_EXCL_STOP
|
||||
FreePool (Image->HiiInfo.Data);
|
||||
}
|
||||
|
||||
// LCOV_EXCL_START
|
||||
if (Image->RelocInfo.Relocs != NULL) {
|
||||
// LCOV_EXCL_STOP
|
||||
FreePool (Image->RelocInfo.Relocs);
|
||||
}
|
||||
|
||||
// LCOV_EXCL_START
|
||||
if (Image->DebugInfo.SymbolsPath != NULL) {
|
||||
// LCOV_EXCL_STOP
|
||||
FreePool (Image->DebugInfo.SymbolsPath);
|
||||
}
|
||||
|
||||
|
@ -443,7 +481,9 @@ ToolImageRelocate (
|
|||
);
|
||||
assert (Segment != NULL);
|
||||
|
||||
// LCOV_EXCL_START
|
||||
switch (Reloc->Type) {
|
||||
// LCOV_EXCL_STOP
|
||||
case EFI_IMAGE_REL_BASED_HIGHLOW:
|
||||
{
|
||||
assert (RemainingSize >= sizeof (UINT32));
|
||||
|
@ -475,11 +515,13 @@ ToolImageRelocate (
|
|||
}
|
||||
#endif
|
||||
|
||||
// LCOV_EXCL_START
|
||||
default:
|
||||
{
|
||||
assert (false);
|
||||
return false;
|
||||
}
|
||||
// LCOV_EXCL_STOP
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -531,14 +573,14 @@ ToolImageSortRelocs (
|
|||
|
||||
bool
|
||||
ToolImageCompare (
|
||||
const image_tool_image_info_t *Image1,
|
||||
const image_tool_image_info_t *Image2
|
||||
const image_tool_image_info_t *DestImage,
|
||||
const image_tool_image_info_t *SourceImage
|
||||
)
|
||||
{
|
||||
int CmpResult;
|
||||
uint32_t SegIndex;
|
||||
const char *Name1;
|
||||
const char *Name2;
|
||||
const char *DestName;
|
||||
const char *SourceName;
|
||||
uint32_t NameIndex;
|
||||
|
||||
//
|
||||
|
@ -546,14 +588,16 @@ ToolImageCompare (
|
|||
//
|
||||
|
||||
CmpResult = memcmp (
|
||||
&Image1->HeaderInfo,
|
||||
&Image2->HeaderInfo,
|
||||
sizeof (Image1->HeaderInfo)
|
||||
&DestImage->HeaderInfo,
|
||||
&SourceImage->HeaderInfo,
|
||||
sizeof (DestImage->HeaderInfo)
|
||||
);
|
||||
// LCOV_EXCL_START
|
||||
if (CmpResult != 0) {
|
||||
DEBUG_RAISE ();
|
||||
return false;
|
||||
}
|
||||
// LCOV_EXCL_STOP
|
||||
|
||||
//
|
||||
// Compare SegmentInfo.
|
||||
|
@ -562,55 +606,78 @@ ToolImageCompare (
|
|||
//
|
||||
|
||||
CmpResult = memcmp (
|
||||
&Image1->SegmentInfo,
|
||||
&Image2->SegmentInfo,
|
||||
&DestImage->SegmentInfo,
|
||||
&SourceImage->SegmentInfo,
|
||||
OFFSET_OF (image_tool_segment_info_t, Segments)
|
||||
);
|
||||
// LCOV_EXCL_START
|
||||
if (CmpResult != 0) {
|
||||
DEBUG_RAISE ();
|
||||
return false;
|
||||
}
|
||||
// LCOV_EXCL_STOP
|
||||
|
||||
for (SegIndex = 0; SegIndex < Image1->SegmentInfo.NumSegments; ++SegIndex) {
|
||||
for (SegIndex = 0; SegIndex < DestImage->SegmentInfo.NumSegments; ++SegIndex) {
|
||||
CmpResult = memcmp (
|
||||
&Image1->SegmentInfo.Segments[SegIndex],
|
||||
&Image2->SegmentInfo.Segments[SegIndex],
|
||||
&DestImage->SegmentInfo.Segments[SegIndex],
|
||||
&SourceImage->SegmentInfo.Segments[SegIndex],
|
||||
OFFSET_OF (image_tool_segment_t, Name)
|
||||
);
|
||||
// LCOV_EXCL_START
|
||||
if (CmpResult != 0) {
|
||||
DEBUG_RAISE ();
|
||||
return false;
|
||||
}
|
||||
// LCOV_EXCL_STOP
|
||||
|
||||
//
|
||||
// Don't assume images generally support arbitrarily long names or names in
|
||||
// general. Check prefix equiality as a best effort.
|
||||
//
|
||||
Name1 = Image1->SegmentInfo.Segments[SegIndex].Name;
|
||||
Name2 = Image2->SegmentInfo.Segments[SegIndex].Name;
|
||||
if (Name1 != NULL && Name2 != NULL) {
|
||||
DestName = DestImage->SegmentInfo.Segments[SegIndex].Name;
|
||||
SourceName = SourceImage->SegmentInfo.Segments[SegIndex].Name;
|
||||
|
||||
// LCOV_EXCL_START
|
||||
if (DestName != NULL && SourceName == NULL) {
|
||||
assert (false);
|
||||
return false;
|
||||
}
|
||||
// LCOV_EXCL_STOP
|
||||
|
||||
//
|
||||
// When omitting the debug info, some file formats (e.g., UE) may not
|
||||
// contain segment names.
|
||||
//
|
||||
if (DestName != NULL) {
|
||||
for (
|
||||
NameIndex = 0;
|
||||
Name1[NameIndex] != '\0' && Name2[NameIndex] != '\0';
|
||||
DestName[NameIndex] != '\0' &&
|
||||
// LCOV_EXCL_START
|
||||
SourceName[NameIndex] != '\0';
|
||||
// LCOV_EXCL_STOP
|
||||
++NameIndex
|
||||
) {
|
||||
if (Name1[NameIndex] != Name2[NameIndex]) {
|
||||
// LCOV_EXCL_START
|
||||
if (DestName[NameIndex] != SourceName[NameIndex]) {
|
||||
DEBUG_RAISE ();
|
||||
return false;
|
||||
}
|
||||
// LCOV_EXCL_STOP
|
||||
}
|
||||
}
|
||||
|
||||
if (Image1->SegmentInfo.Segments[SegIndex].ImageSize != 0) {
|
||||
if (DestImage->SegmentInfo.Segments[SegIndex].ImageSize != 0) {
|
||||
CmpResult = memcmp (
|
||||
Image1->SegmentInfo.Segments[SegIndex].Data,
|
||||
Image2->SegmentInfo.Segments[SegIndex].Data,
|
||||
Image1->SegmentInfo.Segments[SegIndex].ImageSize
|
||||
DestImage->SegmentInfo.Segments[SegIndex].Data,
|
||||
SourceImage->SegmentInfo.Segments[SegIndex].Data,
|
||||
DestImage->SegmentInfo.Segments[SegIndex].ImageSize
|
||||
);
|
||||
// LCOV_EXCL_START
|
||||
if (CmpResult != 0) {
|
||||
DEBUG_RAISE ();
|
||||
return false;
|
||||
}
|
||||
// LCOV_EXCL_STOP
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -619,25 +686,29 @@ ToolImageCompare (
|
|||
//
|
||||
|
||||
CmpResult = memcmp (
|
||||
&Image1->RelocInfo,
|
||||
&Image2->RelocInfo,
|
||||
&DestImage->RelocInfo,
|
||||
&SourceImage->RelocInfo,
|
||||
OFFSET_OF (image_tool_reloc_info_t, Relocs)
|
||||
);
|
||||
// LCOV_EXCL_START
|
||||
if (CmpResult != 0) {
|
||||
DEBUG_RAISE ();
|
||||
return false;
|
||||
}
|
||||
// LCOV_EXCL_STOP
|
||||
|
||||
if (Image1->RelocInfo.NumRelocs != 0) {
|
||||
if (DestImage->RelocInfo.NumRelocs != 0) {
|
||||
CmpResult = memcmp (
|
||||
Image1->RelocInfo.Relocs,
|
||||
Image2->RelocInfo.Relocs,
|
||||
Image1->RelocInfo.NumRelocs * sizeof (*Image1->RelocInfo.Relocs)
|
||||
DestImage->RelocInfo.Relocs,
|
||||
SourceImage->RelocInfo.Relocs,
|
||||
DestImage->RelocInfo.NumRelocs * sizeof (*DestImage->RelocInfo.Relocs)
|
||||
);
|
||||
// LCOV_EXCL_START
|
||||
if (CmpResult != 0) {
|
||||
DEBUG_RAISE ();
|
||||
return false;
|
||||
}
|
||||
// LCOV_EXCL_STOP
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -645,55 +716,65 @@ ToolImageCompare (
|
|||
//
|
||||
|
||||
CmpResult = memcmp (
|
||||
&Image1->HiiInfo,
|
||||
&Image2->HiiInfo,
|
||||
&DestImage->HiiInfo,
|
||||
&SourceImage->HiiInfo,
|
||||
OFFSET_OF (image_tool_hii_info_t, Data)
|
||||
);
|
||||
// LCOV_EXCL_START
|
||||
if (CmpResult != 0) {
|
||||
DEBUG_RAISE ();
|
||||
return false;
|
||||
}
|
||||
// LCOV_EXCL_STOP
|
||||
|
||||
if (Image1->HiiInfo.DataSize != 0) {
|
||||
// LCOV_EXCL_START
|
||||
if (DestImage->HiiInfo.DataSize != 0) {
|
||||
CmpResult = memcmp (
|
||||
Image1->HiiInfo.Data,
|
||||
Image2->HiiInfo.Data,
|
||||
Image1->HiiInfo.DataSize
|
||||
DestImage->HiiInfo.Data,
|
||||
SourceImage->HiiInfo.Data,
|
||||
DestImage->HiiInfo.DataSize
|
||||
);
|
||||
if (CmpResult != 0) {
|
||||
DEBUG_RAISE ();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// LCOV_EXCL_STOP
|
||||
|
||||
//
|
||||
// Compare DebugInfo.
|
||||
//
|
||||
|
||||
CmpResult = memcmp (
|
||||
&Image1->DebugInfo,
|
||||
&Image2->DebugInfo,
|
||||
&DestImage->DebugInfo,
|
||||
&SourceImage->DebugInfo,
|
||||
OFFSET_OF (image_tool_debug_info_t, SymbolsPath)
|
||||
);
|
||||
// LCOV_EXCL_START
|
||||
if (CmpResult != 0) {
|
||||
DEBUG_RAISE ();
|
||||
return false;
|
||||
}
|
||||
// LCOV_EXCL_STOP
|
||||
|
||||
if ((Image1->DebugInfo.SymbolsPath != NULL) != (Image2->DebugInfo.SymbolsPath != NULL)) {
|
||||
// LCOV_EXCL_START
|
||||
if ((DestImage->DebugInfo.SymbolsPath != NULL) != (SourceImage->DebugInfo.SymbolsPath != NULL)) {
|
||||
DEBUG_RAISE ();
|
||||
return false;
|
||||
}
|
||||
// LCOV_EXCL_STOP
|
||||
|
||||
if (Image1->DebugInfo.SymbolsPath != NULL) {
|
||||
if (DestImage->DebugInfo.SymbolsPath != NULL) {
|
||||
CmpResult = strcmp (
|
||||
Image1->DebugInfo.SymbolsPath,
|
||||
Image2->DebugInfo.SymbolsPath
|
||||
DestImage->DebugInfo.SymbolsPath,
|
||||
SourceImage->DebugInfo.SymbolsPath
|
||||
);
|
||||
// LCOV_EXCL_START
|
||||
if (CmpResult != 0) {
|
||||
DEBUG_RAISE ();
|
||||
return false;
|
||||
}
|
||||
// LCOV_EXCL_STOP
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
|
@ -321,11 +321,6 @@ NameToType (
|
|||
return EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER;
|
||||
}
|
||||
|
||||
if ((strcmp (TypeName, "DXE_SAL_DRIVER") == 0)
|
||||
|| (strcmp (TypeName, "SAL_RT_DRIVER") == 0)) {
|
||||
return EFI_IMAGE_SUBSYSTEM_SAL_RUNTIME_DRIVER;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -335,6 +330,10 @@ NameToFormat (
|
|||
IN const char *FormatName
|
||||
)
|
||||
{
|
||||
if (strcmp (FormatName, "UE") == 0) {
|
||||
return UefiImageFormatUe;
|
||||
}
|
||||
|
||||
if (strcmp (FormatName, "PE") == 0) {
|
||||
return UefiImageFormatPe;
|
||||
}
|
||||
|
|
|
@ -13,8 +13,11 @@
|
|||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include <IndustryStandard/UeImage.h>
|
||||
#include <IndustryStandard/PeImage2.h>
|
||||
#include <Library/UeImageLib.h>
|
||||
#include <Library/PeCoffLib2.h>
|
||||
#include <Library/UefiImageLib.h>
|
||||
#include <Library/BaseLib.h>
|
||||
#include <Library/BaseMemoryLib.h>
|
||||
#include <Library/BaseOverflowLib.h>
|
||||
|
@ -135,12 +138,20 @@ ToolImageGetRelocSize (
|
|||
uint8_t Type
|
||||
);
|
||||
|
||||
void *
|
||||
ToolImageEmitUe (
|
||||
image_tool_image_info_t *Image,
|
||||
uint32_t *FileSize,
|
||||
bool Xip,
|
||||
bool Strip
|
||||
);
|
||||
|
||||
RETURN_STATUS
|
||||
ToolContextConstructUefiImage (
|
||||
OUT image_tool_image_info_t *Image,
|
||||
OUT INT8 *Format,
|
||||
IN const void *File,
|
||||
IN size_t FileSize
|
||||
IN uint32_t FileSize
|
||||
);
|
||||
|
||||
bool
|
||||
|
|
|
@ -68,20 +68,24 @@ ValidateOutputFile (
|
|||
}
|
||||
|
||||
Result = CheckToolImage (&OutputImageInfo);
|
||||
// LCOV_EXCL_START
|
||||
if (!Result) {
|
||||
assert (false);
|
||||
ToolImageDestruct (&OutputImageInfo);
|
||||
return RETURN_UNSUPPORTED;
|
||||
}
|
||||
// LCOV_EXCL_STOP
|
||||
|
||||
Result = ToolImageCompare (&OutputImageInfo, ImageInfo);
|
||||
|
||||
ToolImageDestruct (&OutputImageInfo);
|
||||
|
||||
// LCOV_EXCL_START
|
||||
if (!Result) {
|
||||
assert (false);
|
||||
return RETURN_VOLUME_CORRUPTED;
|
||||
}
|
||||
// LCOV_EXCL_STOP
|
||||
|
||||
return RETURN_SUCCESS;
|
||||
}
|
||||
|
@ -115,15 +119,18 @@ ToolImageEmit (
|
|||
SymbolsPath
|
||||
);
|
||||
|
||||
// LCOV_EXCL_START
|
||||
if (SymbolsPath == NULL) {
|
||||
SymbolsPath = "<unknown>";
|
||||
}
|
||||
// LCOV_EXCL_STOP
|
||||
|
||||
if (RETURN_ERROR (Status)) {
|
||||
fprintf (stderr, "ImageTool: Could not parse input file %s - %llx\n", SymbolsPath, (unsigned long long)Status);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// LCOV_EXCL_START
|
||||
if (Format == -1) {
|
||||
Format = SourceFormat;
|
||||
if (Format == -1) {
|
||||
|
@ -136,6 +143,7 @@ ToolImageEmit (
|
|||
if (Type != -1) {
|
||||
ImageInfo.HeaderInfo.Subsystem = (uint16_t)Type;
|
||||
}
|
||||
// LCOV_EXCL_STOP
|
||||
|
||||
ToolImageSortRelocs (&ImageInfo);
|
||||
|
||||
|
@ -160,11 +168,18 @@ ToolImageEmit (
|
|||
}
|
||||
|
||||
OutputFile = NULL;
|
||||
if (Format == UefiImageFormatPe) {
|
||||
// LCOV_EXCL_START
|
||||
if (Format == UefiImageFormatUe) {
|
||||
// LCOV_EXCL_STOP
|
||||
OutputFile = ToolImageEmitUe (&ImageInfo, OutputFileSize, Xip, Strip);
|
||||
}
|
||||
// LCOV_EXCL_START
|
||||
else if (Format == UefiImageFormatPe) {
|
||||
OutputFile = ToolImageEmitPe (&ImageInfo, OutputFileSize, Xip, Strip);
|
||||
} else {
|
||||
assert (false);
|
||||
}
|
||||
// LCOV_EXCL_STOP
|
||||
|
||||
if (OutputFile == NULL) {
|
||||
DEBUG_RAISE ();
|
||||
|
@ -172,6 +187,11 @@ ToolImageEmit (
|
|||
return NULL;
|
||||
}
|
||||
|
||||
if ((Format == UefiImageFormatUe) && Xip) {
|
||||
ToolImageDestruct (&ImageInfo);
|
||||
return OutputFile;
|
||||
}
|
||||
|
||||
Status = ValidateOutputFile (OutputFile, *OutputFileSize, &ImageInfo);
|
||||
|
||||
ToolImageDestruct (&ImageInfo);
|
||||
|
|
|
@ -17,10 +17,11 @@ OUT_DIR = .\Windows
|
|||
|
||||
OV = $(UDK_PATH)\MdePkg\Library\BaseOverflowLib
|
||||
PE = $(UDK_PATH)\MdePkg\Library\BasePeCoffLib2
|
||||
UE = $(UDK_PATH)\MdePkg\Library\BaseUeImageLib
|
||||
UA = $(UDK_PATH)\MdePkg\Library\BaseUefiImageExtraActionLibNull
|
||||
|
||||
OBJECTS = ImageTool.obj Image.obj PeEmit32.obj PeEmit64.obj PeEmitCommon.obj UefiImageScan.obj PeScan.obj ElfScan32.obj ElfScan64.obj ElfScanCommon.obj BinEmit.obj ImageToolEmit.obj
|
||||
OBJECTS = $(OBJECTS) {$(OV)}BaseAlignment.obj BaseBitOverflow.obj {$(UA)}UefiImageExtraActionLib.obj DynamicBuffer.obj
|
||||
OBJECTS = ImageTool.obj Image.obj PeEmit32.obj PeEmit64.obj PeEmitCommon.obj UefiImageScan.obj PeScan.obj UeScan.obj UeEmit.obj ElfScan32.obj ElfScan64.obj ElfScanCommon.obj BinEmit.obj ImageToolEmit.obj
|
||||
OBJECTS = $(OBJECTS) {$(OV)}BaseAlignment.obj BaseBitOverflow.obj {$(UE)}UeImageLib.obj {$(UA)}UefiImageExtraActionLib.obj DynamicBuffer.obj
|
||||
OBJECTS = $(OBJECTS) {$(PE)}PeCoffInit.obj PeCoffInfo.obj PeCoffRelocate.obj PeCoffLoad.obj PeCoffHii.obj PeCoffDebug.obj PeCoffHash.obj
|
||||
|
||||
BASE = $(UDK_PATH)\MdePkg\Library\BaseLib
|
||||
|
@ -33,7 +34,7 @@ CMEM = $(UDK_PATH)\MdeModulePkg\Library\CommonMemoryAllocationLib
|
|||
USER = $(OC_USER)\User\Library
|
||||
OBJECTS = $(OBJECTS) {$(BASE)}SafeString.obj String.obj SwapBytes16.obj SwapBytes32.obj CpuDeadLoop.obj CheckSum.obj QuickSort.obj LinkedList.obj
|
||||
OBJECTS = $(OBJECTS) {$(OUT)}DebugLib.obj {$(PRIN)}PrintLib.obj PrintLibInternal.obj {$(ERRO)}BaseDebugPrintErrorLevelLib.obj
|
||||
OBJECTS = $(OBJECTS) {$(UIMG)}UefiImageLib.obj PeSupport.obj CommonSupport.obj
|
||||
OBJECTS = $(OBJECTS) {$(UIMG)}UefiImageLib.obj UeSupport.obj PeSupport.obj CommonSupport.obj
|
||||
OBJECTS = $(OBJECTS) {$(USER)}UserFile.obj UserBaseMemoryLib.obj UserMath.obj UserPcd.obj UserMisc.obj UserGlobalVar.obj UserBootServices.obj
|
||||
OBJECTS = $(OBJECTS) {$(BMPN)}BaseMemoryProfileLibNull.obj {$(CMEM)}CommonMemoryAllocationLib.obj {$(CMEM)}CommonMemoryAllocationLibEx.obj
|
||||
|
||||
|
@ -73,6 +74,10 @@ cleanall:
|
|||
$(CC) -c $(CFLAGS) $(INC) $< -Fo$@
|
||||
@move $@ $(OUT_DIR)\
|
||||
|
||||
{$(UE)}.c.obj :
|
||||
$(CC) -c $(CFLAGS) $(INC) $< -Fo$@
|
||||
@move $@ $(OUT_DIR)\
|
||||
|
||||
{$(UA)}.c.obj :
|
||||
$(CC) -c $(CFLAGS) $(INC) $< -Fo$@
|
||||
@move $@ $(OUT_DIR)\
|
||||
|
|
|
@ -395,12 +395,14 @@ ToolImageEmitPeSection (
|
|||
SizeOfRawData = Segment->ImageSize;
|
||||
}
|
||||
|
||||
strncpy (
|
||||
(char *)SectionHeader->Name,
|
||||
Segment->Name,
|
||||
sizeof (SectionHeader->Name)
|
||||
);
|
||||
SectionHeader->Name[ARRAY_SIZE (SectionHeader->Name) - 1] = 0;
|
||||
if (Segment->Name != NULL) {
|
||||
strncpy (
|
||||
(char *)SectionHeader->Name,
|
||||
Segment->Name,
|
||||
sizeof (SectionHeader->Name)
|
||||
);
|
||||
SectionHeader->Name[ARRAY_SIZE (SectionHeader->Name) - 1] = 0;
|
||||
}
|
||||
|
||||
SectionHeader->VirtualSize = Segment->ImageSize;
|
||||
SectionHeader->VirtualAddress = Segment->ImageAddress;
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,10 @@
|
|||
#ifndef UE_EMIT_H
|
||||
#define UE_EMIT_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "ImageTool.h"
|
||||
|
||||
void *ToolImageEmitUe(image_tool_image_info_t *Image, uint32_t *FileSize);
|
||||
|
||||
#endif // UE_EMIT_H
|
|
@ -0,0 +1,485 @@
|
|||
/** @file
|
||||
Copyright (c) 2021 - 2023, Marvin Häuser. All rights reserved.
|
||||
Copyright (c) 2022, Mikhail Krichanov. All rights reserved.
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
**/
|
||||
|
||||
#include "ImageTool.h"
|
||||
#include "UeScan.h"
|
||||
#include "DynamicBuffer.h"
|
||||
|
||||
typedef union {
|
||||
UINT32 Value32;
|
||||
UINT64 Value64;
|
||||
} UE_RELOC_FIXUP_VALUE;
|
||||
|
||||
static
|
||||
RETURN_STATUS
|
||||
InternalProcessRelocChain (
|
||||
image_tool_dynamic_buffer *Buffer,
|
||||
const image_tool_segment_info_t *SegmentInfo,
|
||||
UINT16 FirstRelocType,
|
||||
UINT32 *ChainStart
|
||||
)
|
||||
{
|
||||
uint32_t OffsetInSegment;
|
||||
const image_tool_segment_t *Segment;
|
||||
image_tool_reloc_t Reloc;
|
||||
uint32_t Offset;
|
||||
|
||||
UINT16 RelocType;
|
||||
UINT16 RelocOffset;
|
||||
UINT32 RelocTarget;
|
||||
|
||||
UINT32 RemRelocTargetSize;
|
||||
|
||||
VOID *Fixup;
|
||||
UE_RELOC_FIXUP_VALUE FixupInfo;
|
||||
UINT8 FixupSize;
|
||||
UE_RELOC_FIXUP_VALUE FixupValue;
|
||||
|
||||
memset (&Reloc, 0, sizeof (Reloc));
|
||||
|
||||
RelocType = FirstRelocType;
|
||||
RelocTarget = *ChainStart;
|
||||
|
||||
while (TRUE) {
|
||||
OffsetInSegment = RelocTarget;
|
||||
Segment = ImageGetSegmentByAddress (
|
||||
&OffsetInSegment,
|
||||
&RemRelocTargetSize,
|
||||
SegmentInfo
|
||||
);
|
||||
if (Segment == NULL) {
|
||||
DEBUG_RAISE ();
|
||||
return RETURN_VOLUME_CORRUPTED;
|
||||
}
|
||||
|
||||
Fixup = &Segment->Data[OffsetInSegment];
|
||||
|
||||
Reloc.Target = RelocTarget;
|
||||
|
||||
if (RelocType < UeRelocGenericMax) {
|
||||
if (RelocType == UeReloc64) {
|
||||
FixupSize = sizeof (UINT64);
|
||||
//
|
||||
// Verify the relocation fixup target is in bounds of the Image buffer.
|
||||
//
|
||||
if (FixupSize > RemRelocTargetSize) {
|
||||
DEBUG_RAISE ();
|
||||
return RETURN_VOLUME_CORRUPTED;
|
||||
}
|
||||
//
|
||||
// Relocate the target instruction.
|
||||
//
|
||||
FixupInfo.Value64 = ReadUnaligned64 (Fixup);
|
||||
FixupValue.Value64 = UE_CHAINED_RELOC_FIXUP_VALUE (FixupInfo.Value64);
|
||||
WriteUnaligned64 (Fixup, FixupValue.Value64);
|
||||
|
||||
Reloc.Type = EFI_IMAGE_REL_BASED_DIR64;
|
||||
} else if (RelocType == UeReloc32) {
|
||||
FixupSize = sizeof (UINT32);
|
||||
//
|
||||
// Verify the image relocation fixup target is in bounds of the image
|
||||
// buffer.
|
||||
//
|
||||
if (FixupSize > RemRelocTargetSize) {
|
||||
DEBUG_RAISE ();
|
||||
return RETURN_VOLUME_CORRUPTED;
|
||||
}
|
||||
//
|
||||
// Relocate the target instruction.
|
||||
//
|
||||
FixupInfo.Value32 = ReadUnaligned32 (Fixup);
|
||||
FixupValue.Value32 = UE_CHAINED_RELOC_FIXUP_VALUE_32 (FixupInfo.Value32);
|
||||
WriteUnaligned32 (Fixup, FixupValue.Value32);
|
||||
|
||||
Reloc.Type = EFI_IMAGE_REL_BASED_HIGHLOW;
|
||||
//
|
||||
// Imitate the common header of UE chained relocation fixups,
|
||||
// as for 32-bit files all relocs have the same type.
|
||||
//
|
||||
FixupInfo.Value32 = FixupInfo.Value32 << 4;
|
||||
FixupInfo.Value32 |= UeReloc32;
|
||||
} else {
|
||||
//
|
||||
// The Image relocation fixup type is unknown, disallow the Image.
|
||||
//
|
||||
DEBUG_RAISE ();
|
||||
return RETURN_UNSUPPORTED;
|
||||
}
|
||||
} else {
|
||||
//
|
||||
// The Image relocation fixup type is unknown, disallow the Image.
|
||||
//
|
||||
DEBUG_RAISE ();
|
||||
return RETURN_UNSUPPORTED;
|
||||
}
|
||||
|
||||
RelocTarget += FixupSize;
|
||||
|
||||
Offset = ImageToolBufferAppend (Buffer, &Reloc, sizeof (Reloc));
|
||||
if (Offset == MAX_UINT32) {
|
||||
DEBUG_RAISE ();
|
||||
return RETURN_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
RelocOffset = UE_CHAINED_RELOC_FIXUP_NEXT_OFFSET (FixupInfo.Value32);
|
||||
if (RelocOffset == UE_CHAINED_RELOC_FIXUP_OFFSET_END) {
|
||||
*ChainStart = RelocTarget;
|
||||
return RETURN_SUCCESS;
|
||||
}
|
||||
//
|
||||
// It holds that ImageSize mod 4 KiB = 0, thus ImageSize <= 0xFFFFF000.
|
||||
// Furthermore, it holds that RelocTarget <= ImageSize.
|
||||
// Finally, it holds that RelocOffset <= 0xFFE.
|
||||
// It follows that this cannot overflow.
|
||||
//
|
||||
RelocTarget += RelocOffset;
|
||||
assert (RelocOffset <= RelocTarget);
|
||||
|
||||
RelocType = UE_CHAINED_RELOC_FIXUP_NEXT_TYPE (FixupInfo.Value32);
|
||||
}
|
||||
}
|
||||
|
||||
STATIC
|
||||
RETURN_STATUS
|
||||
InternalApplyRelocation (
|
||||
image_tool_dynamic_buffer *Buffer,
|
||||
const image_tool_segment_info_t *SegmentInfo,
|
||||
UINT16 RelocType,
|
||||
UINT32 *RelocTarget
|
||||
)
|
||||
{
|
||||
BOOLEAN Overflow;
|
||||
|
||||
const image_tool_segment_t *LastSegment;
|
||||
uint32_t ImageSize;
|
||||
UINT32 RemRelocTargetSize;
|
||||
|
||||
UINT32 FixupTarget;
|
||||
UINT8 FixupSize;
|
||||
|
||||
image_tool_reloc_t Reloc;
|
||||
uint32_t Offset;
|
||||
|
||||
FixupTarget = *RelocTarget;
|
||||
|
||||
LastSegment = &SegmentInfo->Segments[SegmentInfo->NumSegments - 1];
|
||||
ImageSize = LastSegment->ImageAddress + LastSegment->ImageSize;
|
||||
//
|
||||
// Verify the relocation fixup target address is in bounds of the image buffer.
|
||||
//
|
||||
Overflow = BaseOverflowSubU32 (ImageSize, FixupTarget, &RemRelocTargetSize);
|
||||
if (Overflow) {
|
||||
DEBUG_RAISE ();
|
||||
return RETURN_VOLUME_CORRUPTED;
|
||||
}
|
||||
|
||||
memset (&Reloc, 0, sizeof (Reloc));
|
||||
Reloc.Target = FixupTarget;
|
||||
//
|
||||
// Apply the relocation fixup per type.
|
||||
//
|
||||
if (RelocType < UeRelocGenericMax) {
|
||||
if ((RelocType == UeReloc32) || (RelocType == UeReloc32NoMeta)) {
|
||||
FixupSize = sizeof (UINT32);
|
||||
Reloc.Type = EFI_IMAGE_REL_BASED_HIGHLOW;
|
||||
} else {
|
||||
assert (RelocType == UeReloc64);
|
||||
|
||||
FixupSize = sizeof (UINT64);
|
||||
Reloc.Type = EFI_IMAGE_REL_BASED_DIR64;
|
||||
}
|
||||
} else {
|
||||
//
|
||||
// The image relocation fixup type is unknown, disallow the image.
|
||||
//
|
||||
fprintf (stderr, "ImageTool: Unknown RelocType = 0x%x\n", RelocType);
|
||||
ImageToolBufferFree (Buffer);
|
||||
return RETURN_UNSUPPORTED;
|
||||
}
|
||||
//
|
||||
// Verify the relocation fixup target is in bounds of the image buffer.
|
||||
//
|
||||
if (FixupSize > RemRelocTargetSize) {
|
||||
DEBUG_RAISE ();
|
||||
return RETURN_VOLUME_CORRUPTED;
|
||||
}
|
||||
|
||||
Offset = ImageToolBufferAppend (Buffer, &Reloc, sizeof (Reloc));
|
||||
if (Offset == MAX_UINT32) {
|
||||
DEBUG_RAISE ();
|
||||
ImageToolBufferFree (Buffer);
|
||||
return RETURN_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
*RelocTarget = FixupTarget + FixupSize;
|
||||
|
||||
return RETURN_SUCCESS;
|
||||
}
|
||||
|
||||
RETURN_STATUS
|
||||
ScanUeGetRelocInfo (
|
||||
OUT image_tool_reloc_info_t *RelocInfo,
|
||||
IN const image_tool_segment_info_t *SegmentInfo,
|
||||
IN UE_LOADER_IMAGE_CONTEXT *Context
|
||||
)
|
||||
{
|
||||
RETURN_STATUS Status;
|
||||
BOOLEAN Overflow;
|
||||
CONST UE_HEADER *UeHdr;
|
||||
BOOLEAN Chaining;
|
||||
UINT32 RootOffsetMax;
|
||||
UINT32 EntryOffsetMax;
|
||||
UINT32 EndOfRelocTable;
|
||||
UINT32 TableOffset;
|
||||
const UE_FIXUP_ROOT *RelocRoot;
|
||||
UINT16 FixupInfo;
|
||||
UINT16 RelocType;
|
||||
UINT16 RelocOffset;
|
||||
UINT32 RelocTarget;
|
||||
image_tool_dynamic_buffer Buffer;
|
||||
uint32_t RelocBufferSize;
|
||||
UINT32 OldTableOffset;
|
||||
//
|
||||
// Verify the Relocation Directory is not empty.
|
||||
//
|
||||
if (Context->RelocTableSize == 0) {
|
||||
return RETURN_SUCCESS;
|
||||
}
|
||||
|
||||
ImageToolBufferInit (&Buffer);
|
||||
|
||||
UeHdr = (CONST UE_HEADER *)Context->FileBuffer;
|
||||
Chaining = (UeHdr->ImageInfo & UE_HEADER_IMAGE_INFO_CHAINED_FIXUPS) != 0;
|
||||
|
||||
EndOfRelocTable = Context->LoadTablesFileOffset + Context->RelocTableSize;
|
||||
|
||||
RelocTarget = 0;
|
||||
|
||||
RootOffsetMax = EndOfRelocTable - MIN_SIZE_OF_UE_FIXUP_ROOT;
|
||||
EntryOffsetMax = EndOfRelocTable - sizeof (*RelocRoot->Heads);
|
||||
//
|
||||
// Apply all Base Relocations of the Image.
|
||||
//
|
||||
for (TableOffset = Context->LoadTablesFileOffset; TableOffset <= RootOffsetMax;) {
|
||||
RelocRoot = (CONST UE_FIXUP_ROOT *)(
|
||||
(CONST UINT8 *)Context->FileBuffer + TableOffset
|
||||
);
|
||||
//
|
||||
// This cannot overflow due to the TableOffset upper bound.
|
||||
//
|
||||
TableOffset += sizeof (*RelocRoot);
|
||||
|
||||
Overflow = BaseOverflowAddU32 (
|
||||
RelocTarget,
|
||||
RelocRoot->FirstOffset,
|
||||
&RelocTarget
|
||||
);
|
||||
if (Overflow) {
|
||||
DEBUG_RAISE ();
|
||||
ImageToolBufferFree (&Buffer);
|
||||
return RETURN_VOLUME_CORRUPTED;
|
||||
}
|
||||
//
|
||||
// Process all relocation fixups of the current root.
|
||||
//
|
||||
while (TRUE) {
|
||||
FixupInfo = *(CONST UINT16 *)((CONST UINT8 *)Context->FileBuffer + TableOffset);
|
||||
//
|
||||
// This cannot overflow due to the upper bound of TableOffset.
|
||||
//
|
||||
TableOffset += sizeof (*RelocRoot->Heads);
|
||||
//
|
||||
// Apply the image relocation fixup.
|
||||
//
|
||||
RelocType = UE_RELOC_FIXUP_TYPE (FixupInfo);
|
||||
|
||||
if (Chaining && (RelocType != UeReloc32NoMeta)) {
|
||||
Status = InternalProcessRelocChain (
|
||||
&Buffer,
|
||||
SegmentInfo,
|
||||
RelocType,
|
||||
&RelocTarget
|
||||
);
|
||||
} else {
|
||||
Status = InternalApplyRelocation (
|
||||
&Buffer,
|
||||
SegmentInfo,
|
||||
RelocType,
|
||||
&RelocTarget
|
||||
);
|
||||
}
|
||||
|
||||
if (RETURN_ERROR (Status)) {
|
||||
DEBUG_RAISE ();
|
||||
ImageToolBufferFree (&Buffer);
|
||||
return Status;
|
||||
}
|
||||
|
||||
RelocOffset = UE_RELOC_FIXUP_OFFSET (FixupInfo);
|
||||
if (RelocOffset == UE_HEAD_FIXUP_OFFSET_END) {
|
||||
break;
|
||||
}
|
||||
//
|
||||
// It holds that ImageSize mod 4 KiB = 0, thus ImageSize <= 0xFFFFF000.
|
||||
// Furthermore, it holds that RelocTarget <= ImageSize.
|
||||
// Finally, it holds that RelocOffset <= 0xFFE.
|
||||
// It follows that this cannot overflow.
|
||||
//
|
||||
RelocTarget += RelocOffset;
|
||||
assert (RelocOffset <= RelocTarget);
|
||||
|
||||
if (TableOffset > EntryOffsetMax) {
|
||||
DEBUG_RAISE ();
|
||||
ImageToolBufferFree (&Buffer);
|
||||
return RETURN_VOLUME_CORRUPTED;
|
||||
}
|
||||
}
|
||||
//
|
||||
// This cannot overflow due to the TableOffset upper bounds and the
|
||||
// alignment guarantee of RelocTableSize.
|
||||
//
|
||||
OldTableOffset = TableOffset;
|
||||
TableOffset = ALIGN_VALUE (TableOffset, ALIGNOF (UE_FIXUP_ROOT));
|
||||
assert (OldTableOffset <= TableOffset);
|
||||
}
|
||||
|
||||
RelocInfo->Relocs = ImageToolBufferDump (&RelocBufferSize, &Buffer);
|
||||
|
||||
ImageToolBufferFree (&Buffer);
|
||||
|
||||
if (RelocInfo->Relocs == NULL) {
|
||||
fprintf (stderr, "ImageTool: Could not allocate memory for Relocs[]\n");
|
||||
return RETURN_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
assert (IS_ALIGNED (RelocBufferSize, sizeof (*RelocInfo->Relocs)));
|
||||
RelocInfo->NumRelocs = RelocBufferSize / sizeof (*RelocInfo->Relocs);
|
||||
|
||||
return RETURN_SUCCESS;
|
||||
}
|
||||
|
||||
RETURN_STATUS
|
||||
ScanUeGetSegmentInfo (
|
||||
OUT image_tool_segment_info_t *SegmentInfo,
|
||||
IN UE_LOADER_IMAGE_CONTEXT *Context
|
||||
)
|
||||
{
|
||||
RETURN_STATUS Status;
|
||||
const UE_SEGMENT *Segment;
|
||||
uint16_t NumSegments;
|
||||
image_tool_segment_t *ImageSegment;
|
||||
const char *ImageBuffer;
|
||||
uint16_t Index;
|
||||
uint32_t SegmentAddress;
|
||||
uint32_t SegmentSize;
|
||||
uint8_t SegmentPermissions;
|
||||
const UE_SEGMENT_NAME *SegmentNames;
|
||||
|
||||
NumSegments = UeGetSegments (Context, &Segment);
|
||||
|
||||
STATIC_ASSERT (
|
||||
sizeof (*SegmentInfo->Segments) <= MAX_UINT16 / UE_HEADER_NUM_SEGMENTS_MAX,
|
||||
"The following arithmetics cannot overflow."
|
||||
);
|
||||
|
||||
SegmentInfo->Segments = AllocateZeroPool (
|
||||
NumSegments * sizeof (*SegmentInfo->Segments)
|
||||
);
|
||||
if (SegmentInfo->Segments == NULL) {
|
||||
fprintf (stderr, "ImageTool: Could not allocate memory for Segments[]\n");
|
||||
return RETURN_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
Status = UeGetSegmentNames (Context, &SegmentNames);
|
||||
if (RETURN_ERROR (Status)) {
|
||||
if (Status != RETURN_NOT_FOUND) {
|
||||
DEBUG_RAISE ();
|
||||
return Status;
|
||||
}
|
||||
|
||||
SegmentNames = NULL;
|
||||
}
|
||||
|
||||
ImageBuffer = (char *)UeLoaderGetImageAddress (Context);
|
||||
|
||||
SegmentAddress = 0;
|
||||
ImageSegment = SegmentInfo->Segments;
|
||||
for (Index = 0; Index < NumSegments; ++Index, ++Segment) {
|
||||
if (SegmentNames != NULL) {
|
||||
ImageSegment->Name = AllocateCopyPool (
|
||||
sizeof (SegmentNames[Index]),
|
||||
SegmentNames[Index]
|
||||
);
|
||||
if (ImageSegment->Name == NULL) {
|
||||
fprintf (stderr, "ImageTool: Could not allocate memory for Segment Name\n");
|
||||
return RETURN_OUT_OF_RESOURCES;
|
||||
}
|
||||
} else {
|
||||
assert (ImageSegment->Name == NULL);
|
||||
}
|
||||
|
||||
SegmentSize = UE_SEGMENT_SIZE (Segment->ImageInfo);
|
||||
|
||||
ImageSegment->Data = AllocateCopyPool (
|
||||
SegmentSize,
|
||||
ImageBuffer + SegmentAddress
|
||||
);
|
||||
if (ImageSegment->Data == NULL) {
|
||||
fprintf (stderr, "ImageTool: Could not allocate memory for Segment Data\n");
|
||||
if (ImageSegment->Name != NULL) {
|
||||
FreePool (ImageSegment->Name);
|
||||
}
|
||||
return RETURN_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
ImageSegment->ImageAddress = SegmentAddress;
|
||||
ImageSegment->ImageSize = SegmentSize;
|
||||
|
||||
SegmentPermissions = UE_SEGMENT_PERMISSIONS (Segment->ImageInfo);
|
||||
switch (SegmentPermissions) {
|
||||
case UeSegmentPermX:
|
||||
{
|
||||
ImageSegment->Execute = true;
|
||||
assert (!ImageSegment->Read);
|
||||
assert (!ImageSegment->Write);
|
||||
break;
|
||||
}
|
||||
|
||||
case UeSegmentPermRX:
|
||||
{
|
||||
ImageSegment->Read = true;
|
||||
ImageSegment->Execute = true;
|
||||
assert (!ImageSegment->Write);
|
||||
break;
|
||||
}
|
||||
|
||||
case UeSegmentPermRW:
|
||||
{
|
||||
ImageSegment->Read = true;
|
||||
ImageSegment->Write = true;
|
||||
assert (!ImageSegment->Execute);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
case UeSegmentPermR:
|
||||
{
|
||||
assert (SegmentPermissions == UeSegmentPermR);
|
||||
ImageSegment->Read = true;
|
||||
assert (!ImageSegment->Write);
|
||||
assert (!ImageSegment->Execute);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
SegmentAddress += SegmentSize;
|
||||
|
||||
++SegmentInfo->NumSegments;
|
||||
++ImageSegment;
|
||||
}
|
||||
|
||||
return RETURN_SUCCESS;
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
#ifndef UE_SCAN_H
|
||||
#define UE_SCAN_H
|
||||
|
||||
#include "ImageTool.h"
|
||||
|
||||
RETURN_STATUS
|
||||
ScanUeGetRelocInfo (
|
||||
OUT image_tool_reloc_info_t *RelocInfo,
|
||||
IN const image_tool_segment_info_t *SegmentInfo,
|
||||
IN UE_LOADER_IMAGE_CONTEXT *Context
|
||||
);
|
||||
|
||||
RETURN_STATUS
|
||||
ScanUeGetSegmentInfo (
|
||||
OUT image_tool_segment_info_t *SegmentInfo,
|
||||
IN UE_LOADER_IMAGE_CONTEXT *Context
|
||||
);
|
||||
|
||||
#endif // UE_SCAN_H
|
|
@ -10,6 +10,7 @@
|
|||
#include <Library/UefiImageLib.h>
|
||||
|
||||
#include "PeScan.h"
|
||||
#include "UeScan.h"
|
||||
|
||||
static
|
||||
bool
|
||||
|
@ -24,7 +25,12 @@ ScanUefiImageGetHeaderInfo (
|
|||
HeaderInfo->BaseAddress = UefiImageGetBaseAddress (Context);
|
||||
HeaderInfo->EntryPointAddress = UefiImageGetEntryPointAddress (Context);
|
||||
HeaderInfo->Machine = UefiImageGetMachine (Context);
|
||||
HeaderInfo->Subsystem = UefiImageGetSubsystem (Context);
|
||||
if (HeaderInfo->Machine == 0xFFFF) {
|
||||
DEBUG_RAISE ();
|
||||
return false;
|
||||
}
|
||||
|
||||
HeaderInfo->Subsystem = UefiImageGetSubsystem (Context);
|
||||
|
||||
Status = UefiImageGetFixedAddress (Context, &Address);
|
||||
if (!RETURN_ERROR (Status)) {
|
||||
|
@ -48,6 +54,7 @@ static
|
|||
RETURN_STATUS
|
||||
ScanUefiImageGetRelocInfo (
|
||||
OUT image_tool_reloc_info_t *RelocInfo,
|
||||
IN const image_tool_segment_info_t *SegmentInfo,
|
||||
IN UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context
|
||||
)
|
||||
{
|
||||
|
@ -61,12 +68,21 @@ ScanUefiImageGetRelocInfo (
|
|||
return ScanPeGetRelocInfo (RelocInfo, &Context->Ctx.Pe);
|
||||
}
|
||||
|
||||
// LCOV_EXCL_START
|
||||
if (FormatIndex == UefiImageFormatUe) {
|
||||
// LCOV_EXCL_STOP
|
||||
return ScanUeGetRelocInfo (RelocInfo, SegmentInfo, &Context->Ctx.Ue);
|
||||
}
|
||||
|
||||
// LCOV_EXCL_START
|
||||
fprintf (
|
||||
stderr,
|
||||
"ImageTool: Unsupported UefiImage format %u\n",
|
||||
FormatIndex
|
||||
);
|
||||
assert (false);
|
||||
return RETURN_UNSUPPORTED;
|
||||
// LCOV_EXCL_STOP
|
||||
}
|
||||
|
||||
static
|
||||
|
@ -86,12 +102,21 @@ ScanUefiImageGetSegmentInfo (
|
|||
return ScanPeGetSegmentInfo (SegmentInfo, &Context->Ctx.Pe);
|
||||
}
|
||||
|
||||
// LCOV_EXCL_START
|
||||
if (FormatIndex == UefiImageFormatUe) {
|
||||
// LCOV_EXCL_STOP
|
||||
return ScanUeGetSegmentInfo (SegmentInfo, &Context->Ctx.Ue);
|
||||
}
|
||||
|
||||
// LCOV_EXCL_START
|
||||
fprintf (
|
||||
stderr,
|
||||
"ImageTool: Unsupported UefiImage format %u\n",
|
||||
FormatIndex
|
||||
);
|
||||
assert (false);
|
||||
return RETURN_UNSUPPORTED;
|
||||
// LCOV_EXCL_STOP
|
||||
}
|
||||
|
||||
RETURN_STATUS
|
||||
|
@ -166,7 +191,7 @@ ToolContextConstructUefiImage (
|
|||
OUT image_tool_image_info_t *Image,
|
||||
OUT int8_t *Format,
|
||||
IN const void *File,
|
||||
IN size_t FileSize
|
||||
IN uint32_t FileSize
|
||||
)
|
||||
{
|
||||
RETURN_STATUS Status;
|
||||
|
@ -180,11 +205,6 @@ ToolContextConstructUefiImage (
|
|||
|
||||
assert (File != NULL || FileSize == 0);
|
||||
|
||||
if (FileSize > MAX_UINT32) {
|
||||
fprintf (stderr, "ImageTool: FileSize is too huge\n");
|
||||
return RETURN_UNSUPPORTED;
|
||||
}
|
||||
|
||||
Status = UefiImageInitializeContext (
|
||||
&Context,
|
||||
File,
|
||||
|
@ -209,11 +229,13 @@ ToolContextConstructUefiImage (
|
|||
}
|
||||
|
||||
Status = UefiImageLoadImage (&Context, Destination, DestinationSize);
|
||||
// LCOV_EXCL_START
|
||||
if (RETURN_ERROR (Status)) {
|
||||
fprintf (stderr, "ImageTool: Could not Load Image\n");
|
||||
FreeAlignedPages (Destination, DestinationPages);
|
||||
return Status;
|
||||
}
|
||||
// LCOV_EXCL_STOP
|
||||
|
||||
memset (Image, 0, sizeof (*Image));
|
||||
|
||||
|
@ -233,7 +255,11 @@ ToolContextConstructUefiImage (
|
|||
return Status;
|
||||
}
|
||||
|
||||
Status = ScanUefiImageGetRelocInfo (&Image->RelocInfo, &Context);
|
||||
Status = ScanUefiImageGetRelocInfo (
|
||||
&Image->RelocInfo,
|
||||
&Image->SegmentInfo,
|
||||
&Context
|
||||
);
|
||||
if (RETURN_ERROR (Status)) {
|
||||
fprintf (stderr, "ImageTool: Could not retrieve reloc info\n");
|
||||
ToolImageDestruct (Image);
|
||||
|
|
|
@ -37,6 +37,8 @@ OBJECTS += \
|
|||
$(EDK2_OBJPATH)/BaseTools/ImageTool/ElfScan64.o \
|
||||
$(EDK2_OBJPATH)/BaseTools/ImageTool/ElfScanCommon.o \
|
||||
$(EDK2_OBJPATH)/BaseTools/ImageTool/UefiImageScan.o \
|
||||
$(EDK2_OBJPATH)/BaseTools/ImageTool/UeScan.o \
|
||||
$(EDK2_OBJPATH)/BaseTools/ImageTool/UeEmit.o \
|
||||
$(EDK2_OBJPATH)/BaseTools/ImageTool/PeScan.o \
|
||||
$(EDK2_OBJPATH)/BaseTools/ImageTool/PeEmit32.o \
|
||||
$(EDK2_OBJPATH)/BaseTools/ImageTool/PeEmit64.o \
|
||||
|
@ -121,8 +123,12 @@ OBJECTS += \
|
|||
$(EDK2_OBJPATH)/MdePkg/Library/BasePeCoffLib2/PeCoffLoad.o \
|
||||
$(EDK2_OBJPATH)/MdePkg/Library/BasePeCoffLib2/PeCoffRelocate.o
|
||||
|
||||
OBJECTS += \
|
||||
$(EDK2_OBJPATH)/MdePkg/Library/BaseUeImageLib/UeImageLib.o
|
||||
|
||||
OBJECTS += \
|
||||
$(EDK2_OBJPATH)/MdePkg/Library/BaseUefiImageLib/CommonSupport.o \
|
||||
$(EDK2_OBJPATH)/MdePkg/Library/BaseUefiImageLib/UeSupport.o \
|
||||
$(EDK2_OBJPATH)/MdePkg/Library/BaseUefiImageLib/PeSupport.o \
|
||||
$(EDK2_OBJPATH)/MdePkg/Library/BaseUefiImageLib/UefiImageLib.o
|
||||
|
||||
|
|
|
@ -37,6 +37,8 @@ OBJECTS = $(OBJECTS) \
|
|||
$(EDK2_OBJPATH)\BaseTools\ImageTool\ElfScan64.obj \
|
||||
$(EDK2_OBJPATH)\BaseTools\ImageTool\ElfScanCommon.obj \
|
||||
$(EDK2_OBJPATH)\BaseTools\ImageTool\UefiImageScan.obj \
|
||||
$(EDK2_OBJPATH)\BaseTools\ImageTool\UeScan.obj \
|
||||
$(EDK2_OBJPATH)\BaseTools\ImageTool\UeEmit.obj \
|
||||
$(EDK2_OBJPATH)\BaseTools\ImageTool\PeScan.obj \
|
||||
$(EDK2_OBJPATH)\BaseTools\ImageTool\PeEmit32.obj \
|
||||
$(EDK2_OBJPATH)\BaseTools\ImageTool\PeEmit64.obj \
|
||||
|
@ -120,8 +122,12 @@ OBJECTS = $(OBJECTS) \
|
|||
$(EDK2_OBJPATH)\MdePkg\Library\BasePeCoffLib2\PeCoffLoad.obj \
|
||||
$(EDK2_OBJPATH)\MdePkg\Library\BasePeCoffLib2\PeCoffRelocate.obj
|
||||
|
||||
OBJECTS = $(OBJECTS) \
|
||||
$(EDK2_OBJPATH)\MdePkg\Library\BaseUeImageLib\UeImageLib.obj
|
||||
|
||||
OBJECTS = $(OBJECTS) \
|
||||
$(EDK2_OBJPATH)\MdePkg\Library\BaseUefiImageLib\CommonSupport.obj \
|
||||
$(EDK2_OBJPATH)\MdePkg\Library\BaseUefiImageLib\UeSupport.obj \
|
||||
$(EDK2_OBJPATH)\MdePkg\Library\BaseUefiImageLib\PeSupport.obj \
|
||||
$(EDK2_OBJPATH)\MdePkg\Library\BaseUefiImageLib\UefiImageLib.obj
|
||||
|
||||
|
|
|
@ -846,6 +846,8 @@ Returns:
|
|||
fprintf (FvMapFile, "EntryPoint=0x%010llx, ", (unsigned long long) (ImageBaseAddress + AddressOfEntryPoint));
|
||||
if (Format == UefiImageFormatPe) {
|
||||
fprintf (FvMapFile, "Type=PE");
|
||||
} else if (Format == UefiImageFormatUe) {
|
||||
fprintf (FvMapFile, "Type=UE");
|
||||
} else {
|
||||
assert (FALSE);
|
||||
fprintf (FvMapFile, "Type=Unknown");
|
||||
|
@ -3497,6 +3499,11 @@ Returns:
|
|||
UINT8 ImageFormat;
|
||||
UINT32 RebasedImageSize;
|
||||
VOID *RebasedImage;
|
||||
UINT32 FfsFileLength;
|
||||
UINTN FileOffset;
|
||||
EFI_FFS_INTEGRITY_CHECK *IntegrityCheck;
|
||||
UINT8 *AfterPePart;
|
||||
UINT32 AfterPeSize;
|
||||
|
||||
Index = 0;
|
||||
Cptr = NULL;
|
||||
|
@ -3665,6 +3672,7 @@ Returns:
|
|||
|
||||
UefiImageFileBuffer = (VOID *) ((UINTN) CurrentPe32Section.Pe32Section + CurSecHdrSize);
|
||||
UefiImageFileSize = SectPeSize;
|
||||
FileOffset = (UINTN)UefiImageFileBuffer - (UINTN)(*FfsFile);
|
||||
//
|
||||
// UefiImage has no reloc section. It will try to get reloc data from the original UEFI image.
|
||||
//
|
||||
|
@ -3733,7 +3741,7 @@ Returns:
|
|||
NewBaseAddress,
|
||||
NULL,
|
||||
TRUE,
|
||||
Strip,
|
||||
ImageFormat == UefiImageFormatUe ? (*FfsFile)->Type == EFI_FV_FILETYPE_SECURITY_CORE : Strip,
|
||||
FALSE
|
||||
);
|
||||
|
||||
|
@ -3746,37 +3754,112 @@ Returns:
|
|||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
UefiImageFileBuffer = NULL;
|
||||
UefiImageFileSize = 0;
|
||||
if (ImageFormat == UefiImageFormatUe) {
|
||||
if ((RebasedImageSize + sizeof (EFI_COMMON_SECTION_HEADER)) >= 0x00FFFFFFU) {
|
||||
Error (NULL, 0, 4001, "Invalid", "rebased file is too large (%s)", FileName);
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
if (RebasedImageSize > SectPeSize) {
|
||||
Error (NULL, 0, 4001, "Invalid", "rebased file is too large (%s)", FileName);
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
AfterPeSize = GetFfsFileLength (*FfsFile) - (FileOffset + SectPeSize);
|
||||
AfterPePart = calloc (1, AfterPeSize);
|
||||
if (AfterPePart == NULL) {
|
||||
fprintf (stderr, "GenFv: Could not allocate memory for AfterPePart\n");
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
memmove (
|
||||
(UINT8 *)CurrentPe32Section.Pe32Section + CurSecHdrSize,
|
||||
RebasedImage,
|
||||
RebasedImageSize
|
||||
memmove (
|
||||
AfterPePart,
|
||||
(UINT8 *)((UINTN)(*FfsFile) + FileOffset + SectPeSize),
|
||||
AfterPeSize
|
||||
);
|
||||
|
||||
FfsFileLength = GetFfsFileLength (*FfsFile) - SectPeSize + RebasedImageSize;
|
||||
*FfsFile = realloc (*FfsFile, FfsFileLength);
|
||||
if (*FfsFile == NULL) {
|
||||
fprintf (stderr, "GenFv: Could not reallocate memory for rebased FfsFile\n");
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
*FileSize = FfsFileLength;
|
||||
|
||||
CurrentPe32Section.CommonHeader = (EFI_COMMON_SECTION_HEADER *)((UINTN)(*FfsFile) + FileOffset - CurSecHdrSize);
|
||||
CurrentPe32Section.CommonHeader->Size[0] = (UINT8)((RebasedImageSize + sizeof (EFI_COMMON_SECTION_HEADER)) & 0x000000FF);
|
||||
CurrentPe32Section.CommonHeader->Size[1] = (UINT8)(((RebasedImageSize + sizeof (EFI_COMMON_SECTION_HEADER)) & 0x0000FF00) >> 8);
|
||||
CurrentPe32Section.CommonHeader->Size[2] = (UINT8)(((RebasedImageSize + sizeof (EFI_COMMON_SECTION_HEADER)) & 0x00FF0000) >> 16);
|
||||
|
||||
memmove (
|
||||
(UINT8 *)((UINTN)(*FfsFile) + FileOffset),
|
||||
RebasedImage,
|
||||
RebasedImageSize
|
||||
);
|
||||
|
||||
memmove (
|
||||
(UINT8 *)((UINTN)(*FfsFile) + FileOffset + RebasedImageSize),
|
||||
AfterPePart,
|
||||
AfterPeSize
|
||||
);
|
||||
|
||||
if (FfsHeaderSize > sizeof(EFI_FFS_FILE_HEADER)) {
|
||||
((EFI_FFS_FILE_HEADER2 *)(*FfsFile))->ExtendedSize = FfsFileLength;
|
||||
} else {
|
||||
(*FfsFile)->Size[0] = (UINT8)(FfsFileLength & 0x000000FF);
|
||||
(*FfsFile)->Size[1] = (UINT8)((FfsFileLength & 0x0000FF00) >> 8);
|
||||
(*FfsFile)->Size[2] = (UINT8)((FfsFileLength & 0x00FF0000) >> 16);
|
||||
}
|
||||
|
||||
//
|
||||
// Recalculate the FFS header checksum. Instead of setting Header and State
|
||||
// both to zero, set Header to (UINT8)(-State) so State preserves its original
|
||||
// value
|
||||
//
|
||||
IntegrityCheck = &(*FfsFile)->IntegrityCheck;
|
||||
IntegrityCheck->Checksum.Header = (UINT8) (0x100 - (*FfsFile)->State);
|
||||
IntegrityCheck->Checksum.File = 0;
|
||||
|
||||
IntegrityCheck->Checksum.Header = CalculateChecksum8 (
|
||||
(UINT8 *)(*FfsFile), FfsHeaderSize
|
||||
);
|
||||
|
||||
if ((*FfsFile)->Attributes & FFS_ATTRIB_CHECKSUM) {
|
||||
//
|
||||
// Ffs header checksum = zero, so only need to calculate ffs body.
|
||||
//
|
||||
IntegrityCheck->Checksum.File = CalculateChecksum8 (
|
||||
(UINT8 *)(*FfsFile) + FfsHeaderSize,
|
||||
FfsFileLength - FfsHeaderSize
|
||||
);
|
||||
} else {
|
||||
IntegrityCheck->Checksum.File = FFS_FIXED_CHECKSUM;
|
||||
}
|
||||
} else {
|
||||
if (RebasedImageSize > SectPeSize) {
|
||||
Error (NULL, 0, 4001, "Invalid", "rebased file is too large (%s)", FileName);
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
memmove (
|
||||
(UINT8 *)CurrentPe32Section.Pe32Section + CurSecHdrSize,
|
||||
RebasedImage,
|
||||
RebasedImageSize
|
||||
);
|
||||
memset (
|
||||
(UINT8 *)CurrentPe32Section.Pe32Section + CurSecHdrSize + RebasedImageSize,
|
||||
0,
|
||||
SectPeSize - RebasedImageSize
|
||||
memset (
|
||||
(UINT8 *)CurrentPe32Section.Pe32Section + CurSecHdrSize + RebasedImageSize,
|
||||
0,
|
||||
SectPeSize - RebasedImageSize
|
||||
);
|
||||
|
||||
//
|
||||
// Now update file checksum
|
||||
//
|
||||
if ((*FfsFile)->Attributes & FFS_ATTRIB_CHECKSUM) {
|
||||
SavedState = (*FfsFile)->State;
|
||||
(*FfsFile)->IntegrityCheck.Checksum.File = 0;
|
||||
(*FfsFile)->State = 0;
|
||||
(*FfsFile)->IntegrityCheck.Checksum.File = CalculateChecksum8 (
|
||||
(UINT8 *) ((UINT8 *)(*FfsFile) + FfsHeaderSize),
|
||||
GetFfsFileLength (*FfsFile) - FfsHeaderSize
|
||||
);
|
||||
(*FfsFile)->State = SavedState;
|
||||
//
|
||||
// Now update file checksum
|
||||
//
|
||||
if ((*FfsFile)->Attributes & FFS_ATTRIB_CHECKSUM) {
|
||||
SavedState = (*FfsFile)->State;
|
||||
(*FfsFile)->IntegrityCheck.Checksum.File = 0;
|
||||
(*FfsFile)->State = 0;
|
||||
(*FfsFile)->IntegrityCheck.Checksum.File = CalculateChecksum8 (
|
||||
(UINT8 *) ((UINT8 *)(*FfsFile) + FfsHeaderSize),
|
||||
GetFfsFileLength (*FfsFile) - FfsHeaderSize
|
||||
);
|
||||
(*FfsFile)->State = SavedState;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -3785,7 +3868,7 @@ Returns:
|
|||
|
||||
Status = UefiImageInitializeContext (
|
||||
&ImageContext,
|
||||
(VOID *) ((UINTN) CurrentPe32Section.Pe32Section + CurSecHdrSize),
|
||||
(VOID *) ((UINTN)(*FfsFile) + FileOffset),
|
||||
RebasedImageSize,
|
||||
UEFI_IMAGE_SOURCE_FV
|
||||
);
|
||||
|
@ -3802,7 +3885,12 @@ Returns:
|
|||
&ImageContext
|
||||
);
|
||||
|
||||
free (SymbolsPathCpy);
|
||||
UefiImageFileBuffer = NULL;
|
||||
UefiImageFileSize = 0;
|
||||
|
||||
if (SymbolsPathCpy != NULL) {
|
||||
free (SymbolsPathCpy);
|
||||
}
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
|
|
|
@ -171,7 +171,7 @@ extern UINT64 _gPcd_SkuId_Array[];
|
|||
//#define _PCD_SET_MODE_8_PcdUefiImageFormatSupportNonFv ASSERT(FALSE) // It is not allowed to set value for a FIXED_AT_BUILD PCD
|
||||
|
||||
#define _PCD_TOKEN_PcdUefiImageFormatSupportFv 0U
|
||||
#define _PCD_VALUE_PcdUefiImageFormatSupportFv 0x01
|
||||
#define _PCD_VALUE_PcdUefiImageFormatSupportFv 0x03
|
||||
#define _PCD_SIZE_PcdUefiImageFormatSupportFv 1
|
||||
#define _PCD_GET_MODE_SIZE_PcdUefiImageFormatSupportFv _PCD_SIZE_PcdUefiImageFormatSupportFv
|
||||
#define _PCD_GET_MODE_8_PcdUefiImageFormatSupportFv _PCD_VALUE_PcdUefiImageFormatSupportFv
|
||||
|
|
|
@ -39,6 +39,10 @@
|
|||
-@if not exist $(@D)\ mkdir $(@D)
|
||||
$(CC) -c $(CFLAGS) $(EDK2_INC) $< -Fo$@
|
||||
|
||||
{$(EDK2_PATH)\MdePkg\Library\BaseUeImageLib\}.c{$(EDK2_OBJPATH)\MdePkg\Library\BaseUeImageLib\}.obj :
|
||||
-@if not exist $(@D)\ mkdir $(@D)
|
||||
$(CC) -c $(CFLAGS) $(EDK2_INC) $< -Fo$@
|
||||
|
||||
{$(EDK2_PATH)\MdePkg\Library\BaseUefiImageLib\}.c{$(EDK2_OBJPATH)\MdePkg\Library\BaseUefiImageLib\}.obj :
|
||||
-@if not exist $(@D)\ mkdir $(@D)
|
||||
$(CC) -c $(CFLAGS) -DUEFI_IMAGE_FORMAT_SUPPORT_SOURCES=0x02 $(EDK2_INC) $< -Fo$@
|
||||
|
|
|
@ -122,6 +122,7 @@ BINARY_FILE_TYPE_PIC = 'PIC'
|
|||
BINARY_FILE_TYPE_PEI_DEPEX = 'PEI_DEPEX'
|
||||
BINARY_FILE_TYPE_DXE_DEPEX = 'DXE_DEPEX'
|
||||
BINARY_FILE_TYPE_SMM_DEPEX = 'SMM_DEPEX'
|
||||
BINARY_FILE_TYPE_UE = 'UE'
|
||||
BINARY_FILE_TYPE_VER = 'VER'
|
||||
BINARY_FILE_TYPE_UI = 'UI'
|
||||
BINARY_FILE_TYPE_BIN = 'BIN'
|
||||
|
|
|
@ -79,10 +79,10 @@ class DataSection (DataSectionClassObject):
|
|||
CopyLongFilePath(MapFile, CopyMapFile)
|
||||
|
||||
#Get PE Section alignment when align is set to AUTO
|
||||
if self.Alignment == 'Auto' and self.SecType in (BINARY_FILE_TYPE_PE32):
|
||||
if self.Alignment == 'Auto' and self.SecType in (BINARY_FILE_TYPE_PE32, BINARY_FILE_TYPE_UE):
|
||||
self.Alignment = "0"
|
||||
NoStrip = True
|
||||
if self.SecType in (BINARY_FILE_TYPE_PE32):
|
||||
if self.SecType in (BINARY_FILE_TYPE_PE32, BINARY_FILE_TYPE_UE):
|
||||
if self.KeepReloc is not None:
|
||||
NoStrip = self.KeepReloc
|
||||
|
||||
|
@ -101,6 +101,16 @@ class DataSection (DataSectionClassObject):
|
|||
)
|
||||
self.SectFileName = StrippedFile
|
||||
|
||||
if self.SecType == BINARY_FILE_TYPE_UE:
|
||||
UeFile = os.path.join( OutputPath, ModuleName + 'Ue.raw')
|
||||
GenFdsGlobalVariable.GenerateFirmwareImage(
|
||||
UeFile,
|
||||
GenFdsGlobalVariable.MacroExtend(self.SectFileName, Dict),
|
||||
Format = "UE",
|
||||
IsMakefile = IsMakefile
|
||||
)
|
||||
self.SectFileName = UeFile
|
||||
|
||||
OutputFile = os.path.join (OutputPath, ModuleName + SUP_MODULE_SEC + SecNum + SectionSuffix.get(self.SecType))
|
||||
OutputFile = os.path.normpath(OutputFile)
|
||||
GenFdsGlobalVariable.GenerateSection(OutputFile, [self.SectFileName], Section.Section.SectionType.get(self.SecType), IsMakefile = IsMakefile)
|
||||
|
|
|
@ -62,7 +62,7 @@ class EfiSection (EfiSectionClassObject):
|
|||
StringData = FfsInf.__ExtendMacro__(self.StringData)
|
||||
ModuleNameStr = FfsInf.__ExtendMacro__('$(MODULE_NAME)')
|
||||
NoStrip = True
|
||||
if FfsInf.ModuleType in (SUP_MODULE_SEC, SUP_MODULE_PEI_CORE, SUP_MODULE_PEIM, SUP_MODULE_MM_CORE_STANDALONE) and SectionType in (BINARY_FILE_TYPE_PE32):
|
||||
if FfsInf.ModuleType in (SUP_MODULE_SEC, SUP_MODULE_PEI_CORE, SUP_MODULE_PEIM, SUP_MODULE_MM_CORE_STANDALONE) and SectionType in (BINARY_FILE_TYPE_PE32, BINARY_FILE_TYPE_UE):
|
||||
if FfsInf.KeepReloc is not None:
|
||||
NoStrip = FfsInf.KeepReloc
|
||||
elif FfsInf.KeepRelocFromRule is not None:
|
||||
|
@ -259,7 +259,7 @@ class EfiSection (EfiSectionClassObject):
|
|||
File = GenFdsGlobalVariable.MacroExtend(File, Dict)
|
||||
|
||||
#Get PE Section alignment when align is set to AUTO
|
||||
if self.Alignment == 'Auto' and (SectionType == BINARY_FILE_TYPE_PE32):
|
||||
if self.Alignment == 'Auto' and (SectionType == BINARY_FILE_TYPE_PE32 or SectionType == BINARY_FILE_TYPE_UE):
|
||||
Align = "0"
|
||||
if File[(len(File)-4):] == '.efi' and FfsInf.InfModule.BaseName == os.path.basename(File)[:-4]:
|
||||
MapFile = File.replace('.efi', '.map')
|
||||
|
@ -296,6 +296,16 @@ class EfiSection (EfiSectionClassObject):
|
|||
)
|
||||
File = StrippedFile
|
||||
|
||||
if SectionType == BINARY_FILE_TYPE_UE:
|
||||
UeFile = os.path.join( OutputPath, ModuleName + 'Ue.raw')
|
||||
GenFdsGlobalVariable.GenerateFirmwareImage(
|
||||
UeFile,
|
||||
File,
|
||||
Format = "UE",
|
||||
IsMakefile = IsMakefile
|
||||
)
|
||||
File = UeFile
|
||||
|
||||
"""Call GenSection"""
|
||||
GenFdsGlobalVariable.GenerateSection(OutputFile,
|
||||
[File],
|
||||
|
|
|
@ -2597,7 +2597,7 @@ class FdfParser:
|
|||
#
|
||||
@staticmethod
|
||||
def _SectionCouldHaveRelocFlag (SectionType):
|
||||
if SectionType in {BINARY_FILE_TYPE_PE32}:
|
||||
if SectionType in {BINARY_FILE_TYPE_PE32, BINARY_FILE_TYPE_UE}:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
@ -2923,10 +2923,10 @@ class FdfParser:
|
|||
self.SetFileBufferPos(OldPos)
|
||||
return False
|
||||
|
||||
if self._Token not in {"COMPAT16", BINARY_FILE_TYPE_PE32, BINARY_FILE_TYPE_PIC, "FV_IMAGE", "RAW", BINARY_FILE_TYPE_DXE_DEPEX,\
|
||||
if self._Token not in {"COMPAT16", BINARY_FILE_TYPE_PE32, BINARY_FILE_TYPE_PIC, BINARY_FILE_TYPE_UE, "FV_IMAGE", "RAW", BINARY_FILE_TYPE_DXE_DEPEX,\
|
||||
BINARY_FILE_TYPE_UI, "VERSION", BINARY_FILE_TYPE_PEI_DEPEX, "SUBTYPE_GUID", BINARY_FILE_TYPE_SMM_DEPEX}:
|
||||
raise Warning("Unknown section type '%s'" % self._Token, self.FileName, self.CurrentLineNumber)
|
||||
if AlignValue == 'Auto'and (not self._Token == BINARY_FILE_TYPE_PE32):
|
||||
if AlignValue == 'Auto'and (not self._Token == BINARY_FILE_TYPE_PE32) and (not self._Token == BINARY_FILE_TYPE_UE):
|
||||
raise Warning("Auto alignment can only be used in PE32 section ", self.FileName, self.CurrentLineNumber)
|
||||
|
||||
# DataSection
|
||||
|
@ -3726,7 +3726,7 @@ class FdfParser:
|
|||
|
||||
if SectionName not in {
|
||||
"COMPAT16", BINARY_FILE_TYPE_PE32,
|
||||
BINARY_FILE_TYPE_PIC, "FV_IMAGE",
|
||||
BINARY_FILE_TYPE_PIC, BINARY_FILE_TYPE_UE, "FV_IMAGE",
|
||||
"RAW",BINARY_FILE_TYPE_DXE_DEPEX, BINARY_FILE_TYPE_UI,
|
||||
BINARY_FILE_TYPE_PEI_DEPEX, "VERSION", "SUBTYPE_GUID",
|
||||
BINARY_FILE_TYPE_SMM_DEPEX}:
|
||||
|
@ -3743,7 +3743,7 @@ class FdfParser:
|
|||
if self._GetAlignment():
|
||||
if self._Token not in ALIGNMENTS:
|
||||
raise Warning("Incorrect alignment '%s'" % self._Token, self.FileName, self.CurrentLineNumber)
|
||||
if self._Token == 'Auto' and (not SectionName == BINARY_FILE_TYPE_PE32):
|
||||
if self._Token == 'Auto' and (not SectionName == BINARY_FILE_TYPE_PE32) and (not SectionName == BINARY_FILE_TYPE_UE):
|
||||
raise Warning("Auto alignment can only be used in PE32 section ", self.FileName, self.CurrentLineNumber)
|
||||
SectAlignment = self._Token
|
||||
|
||||
|
@ -3796,7 +3796,7 @@ class FdfParser:
|
|||
|
||||
if SectionName not in {
|
||||
"COMPAT16", BINARY_FILE_TYPE_PE32,
|
||||
BINARY_FILE_TYPE_PIC, "FV_IMAGE",
|
||||
BINARY_FILE_TYPE_PIC, BINARY_FILE_TYPE_UE, "FV_IMAGE",
|
||||
"RAW",BINARY_FILE_TYPE_DXE_DEPEX, BINARY_FILE_TYPE_UI,
|
||||
BINARY_FILE_TYPE_PEI_DEPEX, "VERSION", "SUBTYPE_GUID",
|
||||
BINARY_FILE_TYPE_SMM_DEPEX, BINARY_FILE_TYPE_GUID}:
|
||||
|
@ -3843,7 +3843,7 @@ class FdfParser:
|
|||
elif self._GetNextToken():
|
||||
if self._Token not in {
|
||||
T_CHAR_BRACE_R, "COMPAT16", BINARY_FILE_TYPE_PE32,
|
||||
BINARY_FILE_TYPE_PIC,
|
||||
BINARY_FILE_TYPE_PIC, BINARY_FILE_TYPE_UE,
|
||||
"FV_IMAGE", "RAW", BINARY_FILE_TYPE_DXE_DEPEX,
|
||||
BINARY_FILE_TYPE_UI, "VERSION",
|
||||
BINARY_FILE_TYPE_PEI_DEPEX, BINARY_FILE_TYPE_GUID,
|
||||
|
@ -3907,7 +3907,7 @@ class FdfParser:
|
|||
if self._GetAlignment():
|
||||
if self._Token not in ALIGNMENTS:
|
||||
raise Warning("Incorrect alignment '%s'" % self._Token, self.FileName, self.CurrentLineNumber)
|
||||
if self._Token == 'Auto' and (not SectionName == BINARY_FILE_TYPE_PE32):
|
||||
if self._Token == 'Auto' and (not SectionName == BINARY_FILE_TYPE_PE32) and (not SectionName == BINARY_FILE_TYPE_UE):
|
||||
raise Warning("Auto alignment can only be used in PE32 section ", self.FileName, self.CurrentLineNumber)
|
||||
EfiSectionObj.Alignment = self._Token
|
||||
|
||||
|
@ -3928,7 +3928,7 @@ class FdfParser:
|
|||
elif self._GetNextToken():
|
||||
if self._Token not in {
|
||||
T_CHAR_BRACE_R, "COMPAT16", BINARY_FILE_TYPE_PE32,
|
||||
BINARY_FILE_TYPE_PIC,
|
||||
BINARY_FILE_TYPE_PIC, BINARY_FILE_TYPE_UE,
|
||||
"FV_IMAGE", "RAW", BINARY_FILE_TYPE_DXE_DEPEX,
|
||||
BINARY_FILE_TYPE_UI, "VERSION",
|
||||
BINARY_FILE_TYPE_PEI_DEPEX, BINARY_FILE_TYPE_GUID,
|
||||
|
@ -4020,6 +4020,9 @@ class FdfParser:
|
|||
elif SectionType == BINARY_FILE_TYPE_PIC:
|
||||
if FileType not in {BINARY_FILE_TYPE_PIC, "SEC_PIC"}:
|
||||
raise Warning(WarningString % FileType, self.FileName, self.CurrentLineNumber)
|
||||
elif SectionType == BINARY_FILE_TYPE_UE:
|
||||
if FileType not in {BINARY_FILE_TYPE_UE, "SEC_UE"}:
|
||||
raise Warning(WarningString % FileType, self.FileName, self.CurrentLineNumber)
|
||||
elif SectionType == "RAW":
|
||||
if FileType not in {BINARY_FILE_TYPE_BIN, "SEC_BIN", "RAW", "ASL", "ACPI"}:
|
||||
raise Warning(WarningString % FileType, self.FileName, self.CurrentLineNumber)
|
||||
|
|
|
@ -33,6 +33,7 @@ FdfFvFileTypeToFileType = {
|
|||
SectionSuffix = {
|
||||
BINARY_FILE_TYPE_PE32 : '.pe32',
|
||||
BINARY_FILE_TYPE_PIC : '.pic',
|
||||
BINARY_FILE_TYPE_UE : '.pe32',
|
||||
BINARY_FILE_TYPE_DXE_DEPEX : '.dpx',
|
||||
'VERSION' : '.ver',
|
||||
BINARY_FILE_TYPE_UI : '.ui',
|
||||
|
|
|
@ -775,7 +775,7 @@ class FfsInfStatement(FfsInfStatementClassObject):
|
|||
File = GenFdsGlobalVariable.MacroExtend(File, Dict, self.CurrentArch)
|
||||
|
||||
#Get PE Section alignment when align is set to AUTO
|
||||
if self.Alignment == 'Auto' and (SectionType == BINARY_FILE_TYPE_PE32):
|
||||
if self.Alignment == 'Auto' and (SectionType == BINARY_FILE_TYPE_PE32 or SectionType == BINARY_FILE_TYPE_UE):
|
||||
ImageObj = PeImageClass (File)
|
||||
if ImageObj.SectionAlignment < 0x400:
|
||||
self.Alignment = str (ImageObj.SectionAlignment)
|
||||
|
@ -799,6 +799,16 @@ class FfsInfStatement(FfsInfStatementClassObject):
|
|||
)
|
||||
File = StrippedFile
|
||||
|
||||
if SectionType == BINARY_FILE_TYPE_UE:
|
||||
UeFile = os.path.join( self.OutputPath, self.ModuleGuid + 'Ue.raw')
|
||||
GenFdsGlobalVariable.GenerateFirmwareImage(
|
||||
UeFile,
|
||||
File,
|
||||
Format = "UE",
|
||||
IsMakefile=IsMakefile
|
||||
)
|
||||
File = UeFile
|
||||
|
||||
GenFdsGlobalVariable.GenerateSection(OutputFile, [File], Section.Section.SectionType[SectionType], IsMakefile=IsMakefile)
|
||||
OutputFileList.append(OutputFile)
|
||||
else:
|
||||
|
@ -809,7 +819,7 @@ class FfsInfStatement(FfsInfStatementClassObject):
|
|||
GenSecInputFile = GenFdsGlobalVariable.MacroExtend(GenSecInputFile, Dict, self.CurrentArch)
|
||||
|
||||
#Get PE Section alignment when align is set to AUTO
|
||||
if self.Alignment == 'Auto' and (SectionType == BINARY_FILE_TYPE_PE32):
|
||||
if self.Alignment == 'Auto' and (SectionType == BINARY_FILE_TYPE_PE32 or SectionType == BINARY_FILE_TYPE_UE):
|
||||
ImageObj = PeImageClass (GenSecInputFile)
|
||||
if ImageObj.SectionAlignment < 0x400:
|
||||
self.Alignment = str (ImageObj.SectionAlignment)
|
||||
|
@ -834,6 +844,16 @@ class FfsInfStatement(FfsInfStatementClassObject):
|
|||
)
|
||||
GenSecInputFile = StrippedFile
|
||||
|
||||
if SectionType == BINARY_FILE_TYPE_UE:
|
||||
UeFile = os.path.join( self.OutputPath, self.ModuleGuid + 'Ue.raw')
|
||||
GenFdsGlobalVariable.GenerateFirmwareImage(
|
||||
UeFile,
|
||||
GenSecInputFile,
|
||||
Format = "UE",
|
||||
IsMakefile=IsMakefile
|
||||
)
|
||||
GenSecInputFile = UeFile
|
||||
|
||||
GenFdsGlobalVariable.GenerateSection(OutputFile, [GenSecInputFile], Section.Section.SectionType[SectionType], IsMakefile=IsMakefile)
|
||||
OutputFileList.append(OutputFile)
|
||||
|
||||
|
|
|
@ -733,12 +733,12 @@ class GenFds(object):
|
|||
if not os.path.exists(FfsPath[0]):
|
||||
continue
|
||||
MatchDict = {}
|
||||
ReFileEnds = compile(r'\S+(.ui)$|\S+(fv.sec.txt)$|\S+(.pe32.txt)$|\S+(.pic.txt)$|\S+(.raw.txt)$|\S+(.ffs.txt)$')
|
||||
ReFileEnds = compile(r'\S+(.ui)$|\S+(fv.sec.txt)$|\S+(.pe32.txt)$|\S+(.ue.txt)$|\S+(.pic.txt)$|\S+(.raw.txt)$|\S+(.ffs.txt)$')
|
||||
FileList = os.listdir(FfsPath[0])
|
||||
for File in FileList:
|
||||
Match = ReFileEnds.search(File)
|
||||
if Match:
|
||||
for Index in range(1, 7):
|
||||
for Index in range(1, 8):
|
||||
if Match.group(Index) and Match.group(Index) in MatchDict:
|
||||
MatchDict[Match.group(Index)].append(File)
|
||||
elif Match.group(Index):
|
||||
|
@ -759,6 +759,8 @@ class GenFds(object):
|
|||
FileList = MatchDict['fv.sec.txt']
|
||||
elif '.pe32.txt' in MatchDict:
|
||||
FileList = MatchDict['.pe32.txt']
|
||||
elif '.ue.txt' in MatchDict:
|
||||
FileList = MatchDict['.ue.txt']
|
||||
elif '.pic.txt' in MatchDict:
|
||||
FileList = MatchDict['.pic.txt']
|
||||
elif '.raw.txt' in MatchDict:
|
||||
|
|
|
@ -26,6 +26,7 @@ class Section (SectionClassObject):
|
|||
'FREEFORM' : 'EFI_SECTION_FREEFORM_SUBTYPE_GUID',
|
||||
BINARY_FILE_TYPE_PE32 : 'EFI_SECTION_PE32',
|
||||
BINARY_FILE_TYPE_PIC : 'EFI_SECTION_PIC',
|
||||
BINARY_FILE_TYPE_UE : 'EFI_SECTION_PE32',
|
||||
'FV_IMAGE' : 'EFI_SECTION_FIRMWARE_VOLUME_IMAGE',
|
||||
'COMPAT16' : 'EFI_SECTION_COMPATIBILITY16',
|
||||
BINARY_FILE_TYPE_DXE_DEPEX : 'EFI_SECTION_DXE_DEPEX',
|
||||
|
@ -46,6 +47,7 @@ class Section (SectionClassObject):
|
|||
BINARY_FILE_TYPE_PIC : '.pic',
|
||||
BINARY_FILE_TYPE_PEI_DEPEX : '.depex',
|
||||
'SEC_PEI_DEPEX' : '.depex',
|
||||
BINARY_FILE_TYPE_UE : '.pe32',
|
||||
BINARY_FILE_TYPE_UNI_VER : '.ver',
|
||||
BINARY_FILE_TYPE_VER : '.ver',
|
||||
BINARY_FILE_TYPE_UNI_UI : '.ui',
|
||||
|
@ -121,7 +123,8 @@ class Section (SectionClassObject):
|
|||
for File in FfsInf.BinFileList:
|
||||
if File.Arch == TAB_ARCH_COMMON or FfsInf.CurrentArch == File.Arch:
|
||||
if File.Type == FileType or (int(FfsInf.PiSpecVersion, 16) >= 0x0001000A \
|
||||
and FileType == 'DXE_DPEX' and File.Type == BINARY_FILE_TYPE_SMM_DEPEX):
|
||||
and FileType == 'DXE_DPEX' and File.Type == BINARY_FILE_TYPE_SMM_DEPEX) \
|
||||
or (FileType == BINARY_FILE_TYPE_UE and File.Type == BINARY_FILE_TYPE_PE32):
|
||||
if TAB_STAR in FfsInf.TargetOverrideList or File.Target == TAB_STAR or File.Target in FfsInf.TargetOverrideList or FfsInf.TargetOverrideList == []:
|
||||
FileList.append(FfsInf.PatchEfiFile(File.Path, File.Type))
|
||||
else:
|
||||
|
|
|
@ -424,6 +424,7 @@ BINARY_FILE_TYPE_PIC = 'PIC'
|
|||
BINARY_FILE_TYPE_PEI_DEPEX = 'PEI_DEPEX'
|
||||
BINARY_FILE_TYPE_DXE_DEPEX = 'DXE_DEPEX'
|
||||
BINARY_FILE_TYPE_SMM_DEPEX = 'SMM_DEPEX'
|
||||
BINARY_FILE_TYPE_UE = 'UE'
|
||||
BINARY_FILE_TYPE_VER = 'VER'
|
||||
BINARY_FILE_TYPE_UI = 'UI'
|
||||
BINARY_FILE_TYPE_BIN = 'BIN'
|
||||
|
|
|
@ -35,16 +35,16 @@ RelocateImageUnder4GIfNeeded (
|
|||
IN EFI_SYSTEM_TABLE *SystemTable
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
UINT8 *Buffer;
|
||||
UINTN BufferSize;
|
||||
EFI_HANDLE NewImageHandle;
|
||||
UINT32 ImageSize;
|
||||
UINT32 ImageAlignment;
|
||||
UINTN Pages;
|
||||
EFI_PHYSICAL_ADDRESS FfsBuffer;
|
||||
EFI_STATUS Status;
|
||||
UINT8 *Buffer;
|
||||
UINTN BufferSize;
|
||||
EFI_HANDLE NewImageHandle;
|
||||
UINT32 ImageSize;
|
||||
UINT32 ImageAlignment;
|
||||
UINTN Pages;
|
||||
EFI_PHYSICAL_ADDRESS FfsBuffer;
|
||||
UEFI_IMAGE_LOADER_IMAGE_CONTEXT ImageContext;
|
||||
VOID *Interface;
|
||||
VOID *Interface;
|
||||
|
||||
//
|
||||
// If it is already <4G, no need do relocate
|
||||
|
|
|
@ -72,6 +72,7 @@
|
|||
MdePkg/MdePkg.dec
|
||||
MdeModulePkg/MdeModulePkg.dec
|
||||
UefiCpuPkg/UefiCpuPkg.dec
|
||||
OvmfPkg/OvmfPkg.dec
|
||||
|
||||
[LibraryClasses]
|
||||
BaseMemoryLib
|
||||
|
@ -125,6 +126,7 @@
|
|||
gEfiMemoryAttributesTableGuid ## SOMETIMES_PRODUCES ## SystemTable
|
||||
gEfiEndOfDxeEventGroupGuid ## SOMETIMES_CONSUMES ## Event
|
||||
gEfiHobMemoryAllocStackGuid ## SOMETIMES_CONSUMES ## SystemTable
|
||||
gUefiImageLoaderImageContextGuid ## CONSUMES ## HOB
|
||||
|
||||
[Ppis]
|
||||
gEfiVectorHandoffInfoPpiGuid ## UNDEFINED # HOB
|
||||
|
|
|
@ -205,6 +205,8 @@ CoreInitializeImageServices (
|
|||
UINT64 DxeCoreImageLength;
|
||||
VOID *DxeCoreEntryPoint;
|
||||
EFI_PEI_HOB_POINTERS DxeCoreHob;
|
||||
EFI_HOB_GUID_TYPE *GuidHob;
|
||||
HOB_IMAGE_CONTEXT *Hob;
|
||||
|
||||
//
|
||||
// Searching for image hob
|
||||
|
@ -233,20 +235,43 @@ CoreInitializeImageServices (
|
|||
//
|
||||
Image = &mCorePrivateImage;
|
||||
|
||||
//
|
||||
// FIXME: This is not a proper solution, because DxeCore may not be XIP
|
||||
//
|
||||
Status = UefiImageInitializeContext (
|
||||
ImageContext,
|
||||
(VOID *) (UINTN) DxeCoreImageBaseAddress,
|
||||
(UINT32) DxeCoreImageLength,
|
||||
UEFI_IMAGE_SOURCE_FV
|
||||
);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
GuidHob = GetFirstGuidHob (&gUefiImageLoaderImageContextGuid);
|
||||
if (GuidHob == NULL) {
|
||||
DEBUG ((DEBUG_ERROR, "UefiImageLoaderImageContextGuid HOB is missing!\n"));
|
||||
ASSERT (FALSE);
|
||||
}
|
||||
|
||||
Hob = (HOB_IMAGE_CONTEXT *)GET_GUID_HOB_DATA (GuidHob);
|
||||
|
||||
ImageContext->FormatIndex = Hob->FormatIndex;
|
||||
|
||||
// FIXME: DxeCore is dynamically loaded by DxeIpl, can't it pass the context?
|
||||
if (ImageContext->FormatIndex == UefiImageFormatPe) {
|
||||
ImageContext->Ctx.Pe.ImageBuffer = (VOID *) ImageContext->Ctx.Pe.FileBuffer;
|
||||
ImageContext->Ctx.Pe.ImageBuffer = (VOID *)(UINTN)Hob->Ctx.Pe.ImageBuffer;
|
||||
ImageContext->Ctx.Pe.AddressOfEntryPoint = Hob->Ctx.Pe.AddressOfEntryPoint;
|
||||
ImageContext->Ctx.Pe.ImageType = Hob->Ctx.Pe.ImageType;
|
||||
ImageContext->Ctx.Pe.FileBuffer = (CONST VOID *)(UINTN)Hob->Ctx.Pe.FileBuffer;
|
||||
ImageContext->Ctx.Pe.ExeHdrOffset = Hob->Ctx.Pe.ExeHdrOffset;
|
||||
ImageContext->Ctx.Pe.SizeOfImage = Hob->Ctx.Pe.SizeOfImage;
|
||||
ImageContext->Ctx.Pe.FileSize = Hob->Ctx.Pe.FileSize;
|
||||
ImageContext->Ctx.Pe.Subsystem = Hob->Ctx.Pe.Subsystem;
|
||||
ImageContext->Ctx.Pe.SectionAlignment = Hob->Ctx.Pe.SectionAlignment;
|
||||
ImageContext->Ctx.Pe.SectionsOffset = Hob->Ctx.Pe.SectionsOffset;
|
||||
ImageContext->Ctx.Pe.NumberOfSections = Hob->Ctx.Pe.NumberOfSections;
|
||||
ImageContext->Ctx.Pe.SizeOfHeaders = Hob->Ctx.Pe.SizeOfHeaders;
|
||||
} else if (ImageContext->FormatIndex == UefiImageFormatUe) {
|
||||
ImageContext->Ctx.Ue.ImageBuffer = (VOID *)(UINTN)Hob->Ctx.Ue.ImageBuffer;
|
||||
ImageContext->Ctx.Ue.FileBuffer = (CONST UINT8 *)(UINTN)Hob->Ctx.Ue.FileBuffer;
|
||||
ImageContext->Ctx.Ue.EntryPointAddress = Hob->Ctx.Ue.EntryPointAddress;
|
||||
ImageContext->Ctx.Ue.LoadTablesFileOffset = Hob->Ctx.Ue.LoadTablesFileOffset;
|
||||
ImageContext->Ctx.Ue.NumLoadTables = Hob->Ctx.Ue.NumLoadTables;
|
||||
ImageContext->Ctx.Ue.LoadTables = (CONST UE_LOAD_TABLE *)(UINTN)Hob->Ctx.Ue.LoadTables;
|
||||
ImageContext->Ctx.Ue.Segments = (CONST VOID *)(UINTN)Hob->Ctx.Ue.Segments;
|
||||
ImageContext->Ctx.Ue.LastSegmentIndex = Hob->Ctx.Ue.LastSegmentIndex;
|
||||
ImageContext->Ctx.Ue.SegmentAlignment = Hob->Ctx.Ue.SegmentAlignment;
|
||||
ImageContext->Ctx.Ue.ImageSize = Hob->Ctx.Ue.ImageSize;
|
||||
ImageContext->Ctx.Ue.Subsystem = Hob->Ctx.Ue.Subsystem;
|
||||
ImageContext->Ctx.Ue.SegmentImageInfoIterSize = Hob->Ctx.Ue.SegmentImageInfoIterSize;
|
||||
ImageContext->Ctx.Ue.SegmentsFileOffset = Hob->Ctx.Ue.SegmentsFileOffset;
|
||||
} else {
|
||||
ASSERT (FALSE);
|
||||
}
|
||||
|
@ -426,7 +451,7 @@ GetUefiImageFixLoadingAssignedAddress (
|
|||
Status = CheckAndMarkFixLoadingMemoryUsageBitMap (FixLoadingAddress, ImageDestSize);
|
||||
*LoadAddress = FixLoadingAddress;
|
||||
|
||||
DEBUG ((EFI_D_INFO|EFI_D_LOAD, "LOADING MODULE FIXED INFO: Loading module at fixed address 0x%11p. Status = %r \n", (VOID *)(UINTN)FixLoadingAddress, Status));
|
||||
DEBUG ((EFI_D_INFO|EFI_D_LOAD, "LOADING MODULE FIXED INFO: Loading module at fixed address 0x%11p. Status = %r \n", (VOID *)(UINTN)FixLoadingAddress, Status));
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
@ -715,7 +740,7 @@ CoreLoadPeImage (
|
|||
//
|
||||
// Get the image entry point.
|
||||
//
|
||||
Image->EntryPoint = (EFI_IMAGE_ENTRY_POINT)(UefiImageLoaderGetImageEntryPoint (ImageContext));
|
||||
Image->EntryPoint = (EFI_IMAGE_ENTRY_POINT)(UefiImageLoaderGetImageEntryPoint (ImageContext));
|
||||
|
||||
//
|
||||
// Fill in the image information for the Loaded Image Protocol
|
||||
|
@ -1200,7 +1225,7 @@ CoreLoadImageCommon (
|
|||
&ImageContext,
|
||||
FHand.Source,
|
||||
(UINT32) FHand.SourceSize,
|
||||
ImageIsFromFv
|
||||
ImageIsFromFv ? UEFI_IMAGE_SOURCE_FV : UEFI_IMAGE_SOURCE_NON_FV
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
ASSERT (FALSE);
|
||||
|
@ -1215,8 +1240,8 @@ CoreLoadImageCommon (
|
|||
SecurityStatus = gSecurity2->FileAuthentication (
|
||||
gSecurity2,
|
||||
OriginalFilePath,
|
||||
&ImageContext,
|
||||
sizeof (ImageContext),
|
||||
&ImageContext,
|
||||
sizeof (ImageContext),
|
||||
BootPolicy
|
||||
);
|
||||
if (!EFI_ERROR (SecurityStatus) && ImageIsFromFv) {
|
||||
|
|
|
@ -51,6 +51,7 @@
|
|||
[Packages]
|
||||
MdePkg/MdePkg.dec
|
||||
MdeModulePkg/MdeModulePkg.dec
|
||||
OvmfPkg/OvmfPkg.dec
|
||||
|
||||
[LibraryClasses]
|
||||
PcdLib
|
||||
|
@ -73,7 +74,7 @@
|
|||
gEfiPeiDecompressPpiGuid ## PRODUCES
|
||||
gEfiEndOfPeiSignalPpiGuid ## SOMETIMES_PRODUCES # Not produced on S3 boot path
|
||||
gEfiPeiReadOnlyVariable2PpiGuid ## SOMETIMES_CONSUMES
|
||||
gEfiPeiLoadFilePpiGuid ## SOMETIMES_CONSUMES
|
||||
gEfiPeiLoadFileWithHobPpiGuid ## SOMETIMES_CONSUMES
|
||||
gEfiPeiS3Resume2PpiGuid ## SOMETIMES_CONSUMES # Consumed on S3 boot path
|
||||
gEfiPeiRecoveryModulePpiGuid ## SOMETIMES_CONSUMES # Consumed on recovery boot path
|
||||
## SOMETIMES_CONSUMES
|
||||
|
@ -88,6 +89,7 @@
|
|||
## SOMETIMES_CONSUMES ## Variable:L"MemoryTypeInformation"
|
||||
## SOMETIMES_PRODUCES ## HOB
|
||||
gEfiMemoryTypeInformationGuid
|
||||
gUefiImageLoaderImageContextGuid
|
||||
|
||||
[FeaturePcd.IA32]
|
||||
gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplSwitchToLongMode ## CONSUMES
|
||||
|
@ -116,7 +118,7 @@
|
|||
gEfiMdeModulePkgTokenSpaceGuid.PcdSetNxForStack ## SOMETIMES_CONSUMES
|
||||
|
||||
[Depex]
|
||||
gEfiPeiLoadFilePpiGuid AND gEfiPeiMasterBootModePpiGuid
|
||||
gEfiPeiLoadFileWithHobPpiGuid AND gEfiPeiMasterBootModePpiGuid
|
||||
|
||||
#
|
||||
# [BootMode]
|
||||
|
|
|
@ -10,6 +10,8 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
|
|||
|
||||
#include "DxeIpl.h"
|
||||
|
||||
#include <Library/UefiImageLib.h>
|
||||
|
||||
//
|
||||
// Module Globals used in the DXE to PEI hand off
|
||||
// These must be module globals, so the stack can be switched
|
||||
|
@ -258,7 +260,7 @@ DxeLoadCore (
|
|||
EFI_BOOT_MODE BootMode;
|
||||
EFI_PEI_FILE_HANDLE FileHandle;
|
||||
EFI_PEI_READ_ONLY_VARIABLE2_PPI *Variable;
|
||||
EFI_PEI_LOAD_FILE_PPI *LoadFile;
|
||||
EFI_PEI_LOAD_FILE_WITH_HOB_PPI *LoadFile;
|
||||
UINTN Instance;
|
||||
UINT32 AuthenticationState;
|
||||
UINTN DataSize;
|
||||
|
@ -267,6 +269,7 @@ DxeLoadCore (
|
|||
EDKII_PEI_CAPSULE_ON_DISK_PPI *PeiCapsuleOnDisk;
|
||||
EFI_MEMORY_TYPE_INFORMATION MemoryData[EfiMaxMemoryType + 1];
|
||||
VOID *CapsuleOnDiskModePpi;
|
||||
HOB_IMAGE_CONTEXT *ImageContext;
|
||||
|
||||
//
|
||||
// if in S3 Resume, restore configure
|
||||
|
@ -399,24 +402,27 @@ DxeLoadCore (
|
|||
//
|
||||
FileHandle = DxeIplFindDxeCore ();
|
||||
|
||||
ImageContext = BuildGuidHob (&gUefiImageLoaderImageContextGuid, sizeof (HOB_IMAGE_CONTEXT));
|
||||
ASSERT (ImageContext != NULL);
|
||||
|
||||
//
|
||||
// Load the DXE Core from a Firmware Volume.
|
||||
//
|
||||
Instance = 0;
|
||||
do {
|
||||
Status = PeiServicesLocatePpi (&gEfiPeiLoadFilePpiGuid, Instance++, NULL, (VOID **)&LoadFile);
|
||||
Status = PeiServicesLocatePpi (&gEfiPeiLoadFileWithHobPpiGuid, Instance++, NULL, (VOID **)&LoadFile);
|
||||
//
|
||||
// These must exist an instance of EFI_PEI_LOAD_FILE_PPI to support to load DxeCore file handle successfully.
|
||||
//
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
Status = LoadFile->LoadFile (
|
||||
LoadFile,
|
||||
FileHandle,
|
||||
&DxeCoreAddress,
|
||||
&DxeCoreSize,
|
||||
&DxeCoreEntryPoint,
|
||||
&AuthenticationState
|
||||
&AuthenticationState,
|
||||
ImageContext
|
||||
);
|
||||
} while (EFI_ERROR (Status));
|
||||
|
||||
|
|
|
@ -12,10 +12,21 @@ EFI_PEI_LOAD_FILE_PPI mPeiLoadImagePpi = {
|
|||
PeiLoadImageLoadImageWrapper
|
||||
};
|
||||
|
||||
EFI_PEI_PPI_DESCRIPTOR gPpiLoadFilePpiList = {
|
||||
(EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
|
||||
&gEfiPeiLoadFilePpiGuid,
|
||||
&mPeiLoadImagePpi
|
||||
EFI_PEI_LOAD_FILE_WITH_HOB_PPI mPeiLoadImageWithHobPpi = {
|
||||
PeiLoadImageLoadImageWithHob
|
||||
};
|
||||
|
||||
EFI_PEI_PPI_DESCRIPTOR gPpiLoadFilePpiList[] = {
|
||||
{
|
||||
EFI_PEI_PPI_DESCRIPTOR_PPI,
|
||||
&gEfiPeiLoadFileWithHobPpiGuid,
|
||||
&mPeiLoadImageWithHobPpi
|
||||
},
|
||||
{
|
||||
(EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
|
||||
&gEfiPeiLoadFilePpiGuid,
|
||||
&mPeiLoadImagePpi
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -154,31 +165,31 @@ GetUefiImageFixLoadingAssignedAddress (
|
|||
**/
|
||||
EFI_STATUS
|
||||
LoadAndRelocateUefiImage (
|
||||
IN EFI_PEI_FILE_HANDLE FileHandle,
|
||||
IN VOID *Pe32Data,
|
||||
IN UINT32 Pe32DataSize,
|
||||
OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext,
|
||||
OUT EFI_PHYSICAL_ADDRESS *ImageAddress,
|
||||
OUT UINTN *DebugBase
|
||||
IN EFI_PEI_FILE_HANDLE FileHandle,
|
||||
IN VOID *Pe32Data,
|
||||
IN UINT32 Pe32DataSize,
|
||||
OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext,
|
||||
OUT EFI_PHYSICAL_ADDRESS *ImageAddress,
|
||||
OUT UINTN *DebugBase
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
BOOLEAN Success;
|
||||
PEI_CORE_INSTANCE *Private;
|
||||
UINT32 ImageSize;
|
||||
UINT32 ImageAlignment;
|
||||
UINT64 ValueInSectionHeader;
|
||||
UINT32 ImageSize;
|
||||
UINT32 ImageAlignment;
|
||||
UINT64 ValueInSectionHeader;
|
||||
BOOLEAN IsXipImage;
|
||||
EFI_STATUS ReturnStatus;
|
||||
BOOLEAN IsS3Boot;
|
||||
BOOLEAN IsPeiModule;
|
||||
BOOLEAN IsRegisterForShadow;
|
||||
EFI_FV_FILE_INFO FileInfo;
|
||||
UINT32 DestinationPages;
|
||||
UINT32 DestinationSize;
|
||||
EFI_PHYSICAL_ADDRESS Destination;
|
||||
UINT16 Machine;
|
||||
BOOLEAN LoadDynamically;
|
||||
UINT32 DestinationPages;
|
||||
UINT32 DestinationSize;
|
||||
EFI_PHYSICAL_ADDRESS Destination;
|
||||
UINT16 Machine;
|
||||
BOOLEAN LoadDynamically;
|
||||
|
||||
Private = PEI_CORE_INSTANCE_FROM_PS_THIS (GetPeiServicesTablePointer ());
|
||||
|
||||
|
@ -357,12 +368,12 @@ LoadAndRelocateUefiImage (
|
|||
**/
|
||||
EFI_STATUS
|
||||
LoadAndRelocateUefiImageInPlace (
|
||||
IN VOID *Pe32Data,
|
||||
IN VOID *Pe32Data,
|
||||
IN VOID *ImageAddress,
|
||||
IN UINT32 ImageSize
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_STATUS Status;
|
||||
UEFI_IMAGE_LOADER_IMAGE_CONTEXT ImageContext;
|
||||
|
||||
ASSERT (Pe32Data != ImageAddress);
|
||||
|
@ -455,11 +466,11 @@ PeiLoadImageLoadImage (
|
|||
OUT UINT32 *AuthenticationState
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
VOID *Pe32Data;
|
||||
UINT32 Pe32DataSize;
|
||||
EFI_PHYSICAL_ADDRESS ImageAddress;
|
||||
UINTN DebugBase;
|
||||
EFI_STATUS Status;
|
||||
VOID *Pe32Data;
|
||||
UINT32 Pe32DataSize;
|
||||
EFI_PHYSICAL_ADDRESS ImageAddress;
|
||||
UINTN DebugBase;
|
||||
UEFI_IMAGE_LOADER_IMAGE_CONTEXT ImageContext;
|
||||
|
||||
*EntryPoint = 0;
|
||||
|
@ -492,12 +503,11 @@ PeiLoadImageLoadImage (
|
|||
Status = LoadAndRelocateUefiImage (
|
||||
FileHandle,
|
||||
Pe32Data,
|
||||
Pe32DataSize,
|
||||
&ImageContext,
|
||||
&ImageAddress,
|
||||
&DebugBase
|
||||
Pe32DataSize,
|
||||
&ImageContext,
|
||||
&ImageAddress,
|
||||
&DebugBase
|
||||
);
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
@ -541,7 +551,149 @@ PeiLoadImageLoadImage (
|
|||
EfiFileName,
|
||||
sizeof (EfiFileName)
|
||||
);
|
||||
if (!RETURN_ERROR (Status)) {
|
||||
DEBUG ((DEBUG_INFO | DEBUG_LOAD, "%a", EfiFileName));
|
||||
}
|
||||
|
||||
DEBUG_CODE_END ();
|
||||
|
||||
DEBUG ((DEBUG_INFO | DEBUG_LOAD, "\n"));
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
PeiLoadImageLoadImageWithHob (
|
||||
IN EFI_PEI_FILE_HANDLE FileHandle,
|
||||
OUT EFI_PHYSICAL_ADDRESS *ImageAddressArg OPTIONAL,
|
||||
OUT UINT64 *ImageSizeArg OPTIONAL,
|
||||
OUT EFI_PHYSICAL_ADDRESS *EntryPoint,
|
||||
OUT UINT32 *AuthenticationState,
|
||||
OUT HOB_IMAGE_CONTEXT *Hob
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
VOID *Pe32Data;
|
||||
UINT32 Pe32DataSize;
|
||||
EFI_PHYSICAL_ADDRESS ImageAddress;
|
||||
UINTN DebugBase;
|
||||
UEFI_IMAGE_LOADER_IMAGE_CONTEXT ImageContext;
|
||||
|
||||
*EntryPoint = 0;
|
||||
*AuthenticationState = 0;
|
||||
|
||||
//
|
||||
// Try to find the exe section.
|
||||
//
|
||||
Status = PeiServicesFfsFindSectionData4 (
|
||||
EFI_SECTION_PE32,
|
||||
0,
|
||||
FileHandle,
|
||||
&Pe32Data,
|
||||
&Pe32DataSize,
|
||||
AuthenticationState
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
//
|
||||
// PEI core only carry the loader function for PE32 executables
|
||||
// If this two section does not exist, just return.
|
||||
//
|
||||
return Status;
|
||||
}
|
||||
|
||||
DEBUG ((DEBUG_INFO, "Loading PEIM %g\n", FileHandle));
|
||||
|
||||
//
|
||||
// If memory is installed, perform the shadow operations
|
||||
//
|
||||
Status = LoadAndRelocateUefiImage (
|
||||
FileHandle,
|
||||
Pe32Data,
|
||||
Pe32DataSize,
|
||||
&ImageContext,
|
||||
&ImageAddress,
|
||||
&DebugBase
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
//
|
||||
// Save ImageContext into DXE CORE HOB
|
||||
//
|
||||
Hob->FormatIndex = ImageContext.FormatIndex;
|
||||
|
||||
if (Hob->FormatIndex == UefiImageFormatPe) {
|
||||
Hob->Ctx.Pe.ImageBuffer = (UINT32)(UINTN)ImageContext.Ctx.Pe.ImageBuffer;
|
||||
Hob->Ctx.Pe.AddressOfEntryPoint = ImageContext.Ctx.Pe.AddressOfEntryPoint;
|
||||
Hob->Ctx.Pe.ImageType = ImageContext.Ctx.Pe.ImageType;
|
||||
Hob->Ctx.Pe.FileBuffer = (UINT32)(UINTN)ImageContext.Ctx.Pe.FileBuffer;
|
||||
Hob->Ctx.Pe.ExeHdrOffset = ImageContext.Ctx.Pe.ExeHdrOffset;
|
||||
Hob->Ctx.Pe.SizeOfImage = ImageContext.Ctx.Pe.SizeOfImage;
|
||||
Hob->Ctx.Pe.FileSize = ImageContext.Ctx.Pe.FileSize;
|
||||
Hob->Ctx.Pe.Subsystem = ImageContext.Ctx.Pe.Subsystem;
|
||||
Hob->Ctx.Pe.SectionAlignment = ImageContext.Ctx.Pe.SectionAlignment;
|
||||
Hob->Ctx.Pe.SectionsOffset = ImageContext.Ctx.Pe.SectionsOffset;
|
||||
Hob->Ctx.Pe.NumberOfSections = ImageContext.Ctx.Pe.NumberOfSections;
|
||||
Hob->Ctx.Pe.SizeOfHeaders = ImageContext.Ctx.Pe.SizeOfHeaders;
|
||||
} else if (Hob->FormatIndex == UefiImageFormatUe) {
|
||||
Hob->Ctx.Ue.ImageBuffer = (UINT32)(UINTN)ImageContext.Ctx.Ue.ImageBuffer;
|
||||
Hob->Ctx.Ue.FileBuffer = (UINT32)(UINTN)ImageContext.Ctx.Ue.FileBuffer;
|
||||
Hob->Ctx.Ue.EntryPointAddress = ImageContext.Ctx.Ue.EntryPointAddress;
|
||||
Hob->Ctx.Ue.LoadTablesFileOffset = ImageContext.Ctx.Ue.LoadTablesFileOffset;
|
||||
Hob->Ctx.Ue.NumLoadTables = ImageContext.Ctx.Ue.NumLoadTables;
|
||||
Hob->Ctx.Ue.LoadTables = (UINT32)(UINTN)ImageContext.Ctx.Ue.LoadTables;
|
||||
Hob->Ctx.Ue.Segments = (UINT32)(UINTN)ImageContext.Ctx.Ue.Segments;
|
||||
Hob->Ctx.Ue.LastSegmentIndex = ImageContext.Ctx.Ue.LastSegmentIndex;
|
||||
Hob->Ctx.Ue.SegmentAlignment = ImageContext.Ctx.Ue.SegmentAlignment;
|
||||
Hob->Ctx.Ue.ImageSize = ImageContext.Ctx.Ue.ImageSize;
|
||||
Hob->Ctx.Ue.Subsystem = ImageContext.Ctx.Ue.Subsystem;
|
||||
Hob->Ctx.Ue.SegmentImageInfoIterSize = ImageContext.Ctx.Ue.SegmentImageInfoIterSize;
|
||||
Hob->Ctx.Ue.SegmentsFileOffset = ImageContext.Ctx.Ue.SegmentsFileOffset;
|
||||
} else {
|
||||
ASSERT (FALSE);
|
||||
}
|
||||
|
||||
//
|
||||
// Got the entry point from the loaded Pe32Data
|
||||
//
|
||||
*EntryPoint = UefiImageLoaderGetImageEntryPoint (&ImageContext);
|
||||
|
||||
if (ImageAddressArg != NULL) {
|
||||
*ImageAddressArg = ImageAddress;
|
||||
}
|
||||
|
||||
if (ImageSizeArg != NULL) {
|
||||
*ImageSizeArg =UefiImageGetImageSize (&ImageContext);
|
||||
}
|
||||
|
||||
DEBUG_CODE_BEGIN ();
|
||||
CHAR8 EfiFileName[512];
|
||||
UINT16 Machine;
|
||||
|
||||
Machine = UefiImageGetMachine (&ImageContext);
|
||||
|
||||
//
|
||||
// Print debug message: Loading PEIM at 0x12345678 EntryPoint=0x12345688 Driver.efi
|
||||
//
|
||||
if (Machine != EFI_IMAGE_MACHINE_IA64) {
|
||||
DEBUG ((DEBUG_INFO | DEBUG_LOAD, "Loading PEIM at 0x%11p DebugBase=0x%11p EntryPoint=0x%11p ", (VOID *)(UINTN)ImageAddress, (VOID *)(UINTN)DebugBase, (VOID *)(UINTN)*EntryPoint));
|
||||
} else {
|
||||
//
|
||||
// For IPF Image, the real entry point should be print.
|
||||
//
|
||||
DEBUG ((DEBUG_INFO | DEBUG_LOAD, "Loading PEIM at 0x%11p DebugBase=0x%11p EntryPoint=0x%11p ", (VOID *)(UINTN)ImageAddress, (VOID *)(UINTN)DebugBase, (VOID *)(UINTN)(*(UINT64 *)(UINTN)*EntryPoint)));
|
||||
}
|
||||
|
||||
//
|
||||
// Print Module Name by PeImage PDB file name.
|
||||
//
|
||||
Status = UefiImageGetModuleNameFromSymbolsPath (
|
||||
&ImageContext,
|
||||
EfiFileName,
|
||||
sizeof (EfiFileName)
|
||||
);
|
||||
if (!RETURN_ERROR (Status)) {
|
||||
DEBUG ((DEBUG_INFO | DEBUG_LOAD, "%a", EfiFileName));
|
||||
}
|
||||
|
@ -748,13 +900,13 @@ InitializeImageServices (
|
|||
// The first time we are XIP (running from FLASH). We need to remember the
|
||||
// FLASH address so we can reinstall the memory version that runs faster
|
||||
//
|
||||
PrivateData->XipLoadFile = &gPpiLoadFilePpiList;
|
||||
PrivateData->XipLoadFile = gPpiLoadFilePpiList;
|
||||
PeiServicesInstallPpi (PrivateData->XipLoadFile);
|
||||
} else {
|
||||
//
|
||||
// 2nd time we are running from memory so replace the XIP version with the
|
||||
// new memory version.
|
||||
//
|
||||
PeiServicesReInstallPpi (PrivateData->XipLoadFile, &gPpiLoadFilePpiList);
|
||||
PeiServicesReInstallPpi (PrivateData->XipLoadFile, gPpiLoadFilePpiList);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1417,7 +1417,7 @@ InitializeImageServices (
|
|||
**/
|
||||
EFI_STATUS
|
||||
LoadAndRelocateUefiImageInPlace (
|
||||
IN VOID *Pe32Data,
|
||||
IN VOID *Pe32Data,
|
||||
IN VOID *ImageAddress,
|
||||
IN UINT32 ImageSize
|
||||
);
|
||||
|
@ -1435,8 +1435,8 @@ LoadAndRelocateUefiImageInPlace (
|
|||
EFI_STATUS
|
||||
PeiGetPe32Data (
|
||||
IN EFI_PEI_FILE_HANDLE FileHandle,
|
||||
OUT VOID **Pe32Data,
|
||||
OUT UINT32 *Pe32DataSize
|
||||
OUT VOID **Pe32Data,
|
||||
OUT UINT32 *Pe32DataSize
|
||||
);
|
||||
|
||||
/**
|
||||
|
@ -1463,6 +1463,17 @@ PeiLoadImageLoadImageWrapper (
|
|||
OUT UINT32 *AuthenticationState
|
||||
);
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
PeiLoadImageLoadImageWithHob (
|
||||
IN EFI_PEI_FILE_HANDLE FileHandle,
|
||||
OUT EFI_PHYSICAL_ADDRESS *ImageAddressArg OPTIONAL,
|
||||
OUT UINT64 *ImageSizeArg OPTIONAL,
|
||||
OUT EFI_PHYSICAL_ADDRESS *EntryPoint,
|
||||
OUT UINT32 *AuthenticationState,
|
||||
OUT HOB_IMAGE_CONTEXT *Hob
|
||||
);
|
||||
|
||||
/**
|
||||
|
||||
Provide a callback for when the security PPI is installed.
|
||||
|
|
|
@ -94,6 +94,7 @@
|
|||
## PRODUCES
|
||||
## CONSUMES
|
||||
gEfiPeiLoadFilePpiGuid
|
||||
gEfiPeiLoadFileWithHobPpiGuid
|
||||
gEfiPeiSecurity2PpiGuid ## NOTIFY
|
||||
gEfiTemporaryRamSupportPpiGuid ## SOMETIMES_CONSUMES
|
||||
gEfiTemporaryRamDonePpiGuid ## SOMETIMES_CONSUMES
|
||||
|
|
|
@ -1401,4 +1401,15 @@ SmmInsertImageRecord (
|
|||
IN UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext
|
||||
);
|
||||
|
||||
/**
|
||||
Insert image record.
|
||||
|
||||
@param[in] DriverEntry Driver information
|
||||
**/
|
||||
VOID
|
||||
SmmInsertImageRecord (
|
||||
IN EFI_LOADED_IMAGE_PROTOCOL *LoadedImage,
|
||||
IN UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext
|
||||
);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -317,17 +317,19 @@ ReadyToLockEventNotify (
|
|||
UEFI_IMAGE_SOURCE_FV
|
||||
);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
ImageSize = UefiImageGetImageSize (&ImageContext);
|
||||
ImageAlignment = UefiImageGetSegmentAlignment (&ImageContext);
|
||||
Pages = EFI_SIZE_TO_PAGES (ImageSize);
|
||||
LoadAddress = 0xFFFFFFFF;
|
||||
Status = AllocateAlignedPagesEx (
|
||||
AllocateMaxAddress,
|
||||
EfiReservedMemoryType,
|
||||
Pages,
|
||||
ImageAlignment,
|
||||
&LoadAddress
|
||||
);
|
||||
Pages = EFI_SIZE_TO_PAGES (ImageSize);
|
||||
LoadAddress = 0xFFFFFFFF;
|
||||
|
||||
Status = AllocateAlignedPagesEx (
|
||||
AllocateMaxAddress,
|
||||
EfiReservedMemoryType,
|
||||
Pages,
|
||||
ImageAlignment,
|
||||
&LoadAddress
|
||||
);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
//
|
||||
|
|
|
@ -0,0 +1,667 @@
|
|||
/** @file
|
||||
Definitions of the UEFI Executable (UE) file format.
|
||||
|
||||
Copyright (c) 2021 - 2023, Marvin Häuser. All rights reserved.<BR>
|
||||
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
**/
|
||||
|
||||
#ifndef UE_IMAGE_H_
|
||||
#define UE_IMAGE_H_
|
||||
|
||||
#include <Library/BaseLib.h>
|
||||
|
||||
//
|
||||
// UE segment definitions.
|
||||
//
|
||||
|
||||
///
|
||||
/// Definition of the UE segment permission configurations.
|
||||
///
|
||||
enum {
|
||||
UeSegmentPermX = 0,
|
||||
UeSegmentPermRX = 1,
|
||||
UeSegmentPermRW = 2,
|
||||
//
|
||||
// Read-only is the last value, as this makes it easier to implement it as
|
||||
// the else/default case.
|
||||
//
|
||||
UeSegmentPermR = 3,
|
||||
UeSegmentPermMax
|
||||
};
|
||||
|
||||
///
|
||||
/// The minimum alignment requirement, in bytes, of each UE segment in the UE
|
||||
/// address space.
|
||||
///
|
||||
#define UE_SEGMENT_MIN_ALIGNMENT 0x00001000U
|
||||
|
||||
///
|
||||
/// The maximum alignment requirement, in bytes, of each UE segment in the UE
|
||||
/// address space.
|
||||
///
|
||||
#define UE_SEGMENT_MAX_ALIGNMENT 0x08000000U
|
||||
|
||||
///
|
||||
/// Information about the UE segment in the UE address space.
|
||||
///
|
||||
/// [Bits 19:0] The size, in 4-KiB units, of the UE segment in the UE address
|
||||
/// space.
|
||||
/// [Bits 21:20] The UE segment permissions.
|
||||
/// [Bits 31:22] Reserved for future use. Must be zero.
|
||||
///
|
||||
typedef UINT32 UE_SEGMENT_IMAGE_INFO;
|
||||
|
||||
///
|
||||
/// Definition of a UE segment header.
|
||||
///
|
||||
typedef struct {
|
||||
///
|
||||
/// Information about the UE segment in the UE address space.
|
||||
///
|
||||
UE_SEGMENT_IMAGE_INFO ImageInfo;
|
||||
///
|
||||
/// The size, in bytes, of the UE segment in the UE file.
|
||||
///
|
||||
UINT32 FileSize;
|
||||
} UE_SEGMENT;
|
||||
|
||||
STATIC_ASSERT (
|
||||
sizeof (UE_SEGMENT) == 8 && ALIGNOF (UE_SEGMENT) == 4,
|
||||
"The UE segment definition does not meet the specification."
|
||||
);
|
||||
|
||||
///
|
||||
/// Definition of a UE XIP segment header.
|
||||
///
|
||||
typedef struct {
|
||||
///
|
||||
/// Information about the UE segment in the UE address space.
|
||||
///
|
||||
UE_SEGMENT_IMAGE_INFO ImageInfo;
|
||||
} UE_SEGMENT_XIP;
|
||||
|
||||
STATIC_ASSERT (
|
||||
sizeof (UE_SEGMENT_XIP) == 4 && ALIGNOF (UE_SEGMENT_XIP) == 4,
|
||||
"The UE XIP segment definition does not meet the specification."
|
||||
);
|
||||
|
||||
/**
|
||||
Retrieve the UE segment memory permissions.
|
||||
|
||||
@param[in] ImageInfo The UE segment image information.
|
||||
**/
|
||||
#define UE_SEGMENT_PERMISSIONS(ImageInfo) \
|
||||
((UINT8)(((ImageInfo) >> 20U) & 0x03U))
|
||||
|
||||
/**
|
||||
Retrieve the size, in bytes, of the UE segment in the UE address space.
|
||||
|
||||
@param[in] ImageInfo The UE segment image information.
|
||||
**/
|
||||
#define UE_SEGMENT_SIZE(ImageInfo) ((ImageInfo) << 12U)
|
||||
|
||||
STATIC_ASSERT (
|
||||
IS_ALIGNED (UE_SEGMENT_SIZE (0xFFFFFFFF), UE_SEGMENT_MIN_ALIGNMENT),
|
||||
"The UE segment size definition does not meet the specification."
|
||||
);
|
||||
|
||||
//
|
||||
// UE load table definitions.
|
||||
//
|
||||
|
||||
///
|
||||
/// The alignment, in bytes, of each UE load table in the UE file.
|
||||
///
|
||||
#define UE_LOAD_TABLE_ALIGNMENT 8U
|
||||
|
||||
///
|
||||
/// Definition of the UE load table identifiers.
|
||||
///
|
||||
enum {
|
||||
//
|
||||
// An array of UE fixup roots. Blocks are ordered ascending by their
|
||||
// base address.
|
||||
//
|
||||
UeLoadTableIdReloc = 0x00,
|
||||
//
|
||||
// An instance of the UE debug table..
|
||||
//
|
||||
UeLoadTableIdDebug = 0x01
|
||||
};
|
||||
|
||||
///
|
||||
/// Definition of a UE load table header.
|
||||
///
|
||||
typedef struct {
|
||||
///
|
||||
/// Information about the UE load table.
|
||||
///
|
||||
/// [Bits 28:0] The size, in 8-byte units, of the UE load table in the UE
|
||||
/// file.
|
||||
/// [Bits 31:29] The identifier of the UE load table.
|
||||
///
|
||||
UINT32 FileInfo;
|
||||
} UE_LOAD_TABLE;
|
||||
|
||||
STATIC_ASSERT (
|
||||
sizeof (UE_LOAD_TABLE) == 4 && ALIGNOF (UE_LOAD_TABLE) == 4,
|
||||
"The UE load table definition does not meet the specification."
|
||||
);
|
||||
|
||||
/**
|
||||
Retrieves the UE load table identifier.
|
||||
|
||||
@param[in] FileInfo The UE load table file information.
|
||||
**/
|
||||
#define UE_LOAD_TABLE_ID(FileInfo) ((UINT8)((FileInfo) >> 29U))
|
||||
|
||||
/**
|
||||
Retrieves the size, in bytes, of the UE load table in the UE file.
|
||||
|
||||
@param[in] FileInfo The UE load table file information.
|
||||
**/
|
||||
#define UE_LOAD_TABLE_SIZE(FileInfo) ((FileInfo) << 3U)
|
||||
|
||||
STATIC_ASSERT (
|
||||
IS_ALIGNED (UE_LOAD_TABLE_SIZE (0xFFFFFFFF), UE_LOAD_TABLE_ALIGNMENT),
|
||||
"The UE load table size definition does not meet the specification."
|
||||
);
|
||||
|
||||
//
|
||||
// UE relocation table definitions.
|
||||
//
|
||||
|
||||
///
|
||||
/// Definitions of the generic UE relocation identifiers.
|
||||
///
|
||||
enum {
|
||||
UeReloc32 = 0x00,
|
||||
UeReloc64 = 0x01,
|
||||
UeReloc32NoMeta = 0x02,
|
||||
UeRelocGenericMax
|
||||
};
|
||||
|
||||
#if 0
|
||||
///
|
||||
/// Definition of the ARM UE relocation identifiers.
|
||||
///
|
||||
enum {
|
||||
UeRelocArmMovtMovw = 0x02
|
||||
};
|
||||
#endif
|
||||
|
||||
///
|
||||
/// The alignment requirement for a UE fixup root.
|
||||
///
|
||||
#define UE_FIXUP_ROOT_ALIGNMENT 4U
|
||||
|
||||
STATIC_ASSERT (
|
||||
UE_FIXUP_ROOT_ALIGNMENT <= UE_LOAD_TABLE_ALIGNMENT,
|
||||
"The UE fixup root definition does not meet the specification."
|
||||
);
|
||||
|
||||
///
|
||||
/// Definition of a UE fixup root.
|
||||
///
|
||||
typedef struct {
|
||||
///
|
||||
/// The offset of the first head fixup, in bytes, from the end of the previous
|
||||
/// UE relocation fixup (chained or not). The first UE fixup root is
|
||||
/// relative to 0.
|
||||
///
|
||||
UINT32 FirstOffset;
|
||||
///
|
||||
/// The head fixups of the UE fixup root.
|
||||
///
|
||||
/// [Bits 3:0] The type of the UE relocation fixup.
|
||||
/// [Bits 15:4] The offset of the next UE head fixup from the end of the last
|
||||
/// UE relocation fixup in the chain (if chained). If 0x0FFF, the
|
||||
/// current fixup root is terminated.
|
||||
///
|
||||
UINT16 Heads[];
|
||||
} UE_FIXUP_ROOT;
|
||||
|
||||
STATIC_ASSERT (
|
||||
sizeof (UE_FIXUP_ROOT) == 4 && ALIGNOF (UE_FIXUP_ROOT) == UE_FIXUP_ROOT_ALIGNMENT,
|
||||
"The UE fixup root definition does not meet the specification."
|
||||
);
|
||||
|
||||
STATIC_ASSERT (
|
||||
OFFSET_OF (UE_FIXUP_ROOT, Heads) == sizeof (UE_FIXUP_ROOT),
|
||||
"The UE fixup root definition does not meet the specification."
|
||||
);
|
||||
|
||||
STATIC_ASSERT (
|
||||
sizeof (UE_FIXUP_ROOT) <= UE_LOAD_TABLE_ALIGNMENT,
|
||||
"The UE fixup root definition is misaligned."
|
||||
);
|
||||
|
||||
#define MIN_SIZE_OF_UE_FIXUP_ROOT (sizeof (UE_FIXUP_ROOT) + sizeof (UINT16))
|
||||
|
||||
///
|
||||
/// The maximum offset, in bytes, of the next UE head fixup.
|
||||
///
|
||||
#define UE_HEAD_FIXUP_MAX_OFFSET 0x0FFEU
|
||||
|
||||
///
|
||||
/// UE head fixup offset that terminates a fixup root.
|
||||
///
|
||||
#define UE_HEAD_FIXUP_OFFSET_END 0x0FFFU
|
||||
|
||||
/**
|
||||
Retrieves the target offset of the UE relocation fixup.
|
||||
|
||||
@param[in] FixupInfo The UE relocation fixup information.
|
||||
**/
|
||||
#define UE_RELOC_FIXUP_OFFSET(FixupInfo) ((UINT16)((FixupInfo) >> 4U))
|
||||
|
||||
/**
|
||||
Retrieves the type of the UE relocation fixup.
|
||||
|
||||
@param[in] FixupInfo The UE relocation fixup information.
|
||||
**/
|
||||
#define UE_RELOC_FIXUP_TYPE(FixupInfo) ((FixupInfo) & 0x000FU)
|
||||
|
||||
/**
|
||||
Retrieves the offset of the next UE chained relocation fixup.
|
||||
|
||||
@param[in] FixupInfo The UE relocation fixup information.
|
||||
**/
|
||||
#define UE_CHAINED_RELOC_FIXUP_NEXT_OFFSET(FixupInfo) \
|
||||
((UINT16)((UINT16)(FixupInfo) >> 4U) & 0x0FFFU)
|
||||
|
||||
///
|
||||
/// The maximum offset, in bytes, of the next UE chained relocation fixup.
|
||||
///
|
||||
#define UE_CHAINED_RELOC_FIXUP_MAX_OFFSET 0x0FFEU
|
||||
|
||||
///
|
||||
/// UE chained relocation fixup offset that terminates a chain.
|
||||
///
|
||||
#define UE_CHAINED_RELOC_FIXUP_OFFSET_END 0x0FFFU
|
||||
|
||||
/**
|
||||
Retrieves the type of the next UE chained relocation fixup.
|
||||
|
||||
@param[in] FixupInfo The UE relocation fixup information.
|
||||
**/
|
||||
#define UE_CHAINED_RELOC_FIXUP_NEXT_TYPE(FixupInfo) \
|
||||
((UINT8)((UINT16)(FixupInfo) & 0x0FU))
|
||||
|
||||
///
|
||||
/// The shift exponent for UE chained relocation fixup values.
|
||||
///
|
||||
#define UE_CHAINED_RELOC_FIXUP_VALUE_SHIFT 16U
|
||||
|
||||
/**
|
||||
Retrieves the value of the current UE chained relocation fixup.
|
||||
|
||||
@param[in] FixupInfo The UE relocation fixup information.
|
||||
**/
|
||||
#define UE_CHAINED_RELOC_FIXUP_VALUE(FixupInfo) \
|
||||
RShiftU64 (FixupInfo, UE_CHAINED_RELOC_FIXUP_VALUE_SHIFT)
|
||||
|
||||
///
|
||||
/// Definition of the common header of UE chained relocation fixups.
|
||||
///
|
||||
/// [Bits 3:0] The relocation type of the next chained relocation fixup. Only
|
||||
/// valid when [Bits 15:4] are not 0x0FFF.
|
||||
/// [Bits 15:4] The offset to the next chained relocation fixup from the end
|
||||
/// of the current one. If 0x0FFF, the current chain is terminated.
|
||||
/// Consult the fixup root for further relocation fixups.
|
||||
///
|
||||
typedef UINT16 UE_RELOC_FIXUP_HDR;
|
||||
|
||||
///
|
||||
/// Definition of the generic 64-bit UE chained relocation fixup.
|
||||
///
|
||||
/// [Bits 15:0] The common header of UE chained relocation fixups.
|
||||
/// [Bits 47:16] The address value to relocate.
|
||||
/// [Bits 63:48] Must be zero.
|
||||
///
|
||||
typedef UINT64 UE_RELOC_FIXUP_64;
|
||||
|
||||
///
|
||||
/// The shift exponent for UE chained 32-bit relocation fixup values.
|
||||
///
|
||||
#define UE_CHAINED_RELOC_FIXUP_VALUE_32_SHIFT 12U
|
||||
|
||||
/**
|
||||
Retrieves the value of the current UE chained 32-bit relocation fixup.
|
||||
|
||||
@param[in] FixupInfo The UE relocation fixup information.
|
||||
**/
|
||||
#define UE_CHAINED_RELOC_FIXUP_VALUE_32(FixupInfo) \
|
||||
(UINT32)((UINT32)(FixupInfo) >> UE_CHAINED_RELOC_FIXUP_VALUE_32_SHIFT)
|
||||
|
||||
///
|
||||
/// Definition of the generic 32-bit UE chained relocation fixup.
|
||||
///
|
||||
/// [Bits 11:0] The offset to the next chained relocation fixup from the end
|
||||
/// of the current one. If 0x0FFF, the current chain is terminated.
|
||||
/// Consult the fixup root for further relocation fixups.
|
||||
/// [Bits 31:12] The address value to relocate.
|
||||
///
|
||||
typedef UINT32 UE_RELOC_FIXUP_32;
|
||||
|
||||
#if 0
|
||||
///
|
||||
/// Definition of the ARM Thumb MOVT/MOVW UE chained relocation fixup.
|
||||
///
|
||||
/// [Bits 15:0] The common header of UE chained relocation fixups.
|
||||
/// [Bits 31:16] The 16-bit immediate value to relocate.
|
||||
///
|
||||
typedef UINT32 UE_RELOC_FIXUP_ARM_MOVT_MOVW;
|
||||
#endif
|
||||
|
||||
//
|
||||
// UE debug table definitions.
|
||||
//
|
||||
// NOTE: The UE symbols base address offset is required for conversion of
|
||||
// PE Images that have their first section start after the end of the
|
||||
// Image headers. As PDBs cannot easily be rebased, store the offset.
|
||||
//
|
||||
|
||||
///
|
||||
/// Definition of a UE segment name. Must be \0-terminated.
|
||||
///
|
||||
typedef UINT8 UE_SEGMENT_NAME[8];
|
||||
|
||||
STATIC_ASSERT (
|
||||
sizeof (UE_SEGMENT_NAME) == 8 && ALIGNOF (UE_SEGMENT_NAME) == 1,
|
||||
"The UE segment name definition does not meet the specification."
|
||||
);
|
||||
|
||||
///
|
||||
/// Definition of the UE debug table header.
|
||||
///
|
||||
typedef struct {
|
||||
///
|
||||
/// Information about the image regarding the symbols file.
|
||||
///
|
||||
/// [Bits 1:0] The offset, in image alignment units, to be subtracted from the
|
||||
/// UE base address in order to retrieve the UE symbols base
|
||||
/// address.
|
||||
/// [Bits 7:2] Reserved for future use. Must be zero.
|
||||
///
|
||||
UINT8 ImageInfo;
|
||||
///
|
||||
/// The length, in bytes, of the UE symbols path (excluding the terminator).
|
||||
///
|
||||
UINT8 SymbolsPathLength;
|
||||
///
|
||||
/// The UE symbols path. Must be \0-terminated.
|
||||
///
|
||||
UINT8 SymbolsPath[];
|
||||
///
|
||||
/// The UE segment name table. The order matches the UE segment table.
|
||||
///
|
||||
//UE_SEGMENT_NAME SegmentNames[];
|
||||
} UE_DEBUG_TABLE;
|
||||
|
||||
///
|
||||
/// The minimum size, in bytes, of the UE debug table.
|
||||
///
|
||||
#define MIN_SIZE_OF_UE_DEBUG_TABLE \
|
||||
(OFFSET_OF (UE_DEBUG_TABLE, SymbolsPath) + 1U)
|
||||
|
||||
/**
|
||||
Retrieves the UE symbol address subtrahend in SegmentAlignment-units.
|
||||
|
||||
@param[in] ImageInfo The UE debug table image information.
|
||||
**/
|
||||
#define UE_DEBUG_TABLE_IMAGE_INFO_SYM_SUBTRAHEND_FACTOR(ImageInfo) \
|
||||
((UINT8)((ImageInfo) & 0x03U))
|
||||
|
||||
/**
|
||||
Retrieves the UE segment name table of a UE debug table.
|
||||
|
||||
@param[in] DebugTable The UE debug table.
|
||||
**/
|
||||
#define UE_DEBUG_TABLE_SEGMENT_NAMES(DebugTable) \
|
||||
(CONST UE_SEGMENT_NAME *) ( \
|
||||
(DebugTable)->SymbolsPath + (DebugTable)->SymbolsPathLength + 1 \
|
||||
)
|
||||
|
||||
STATIC_ASSERT (
|
||||
sizeof (UE_DEBUG_TABLE) == 2 && ALIGNOF (UE_DEBUG_TABLE) == 1,
|
||||
"The UE debug table definition does not meet the specification."
|
||||
);
|
||||
|
||||
STATIC_ASSERT (
|
||||
ALIGNOF (UE_DEBUG_TABLE) <= UE_LOAD_TABLE_ALIGNMENT,
|
||||
"The UE debug table definition is misaligned."
|
||||
);
|
||||
|
||||
STATIC_ASSERT (
|
||||
OFFSET_OF (UE_DEBUG_TABLE, SymbolsPath) == sizeof (UE_DEBUG_TABLE),
|
||||
"The UE fixup root definition does not meet the specification."
|
||||
);
|
||||
|
||||
//
|
||||
// UE header definitions.
|
||||
//
|
||||
|
||||
///
|
||||
/// The file magic number of a UE header.
|
||||
///
|
||||
#define UE_HEADER_MAGIC SIGNATURE_16 ('U', 'E')
|
||||
|
||||
///
|
||||
/// Definition of the UE machine identifiers.
|
||||
///
|
||||
enum {
|
||||
UeMachineI386 = 0,
|
||||
UeMachineX64 = 1,
|
||||
UeMachineArmThumbMixed = 2,
|
||||
UeMachineArm64 = 3,
|
||||
UeMachineRiscV32 = 4,
|
||||
UeMachineRiscV64 = 5,
|
||||
UeMachineRiscV128 = 6
|
||||
};
|
||||
|
||||
///
|
||||
/// Definition of the UE subsystem identifiers.
|
||||
///
|
||||
enum {
|
||||
UeSubsystemEfiApplication = 0,
|
||||
UeSubsystemEfiBootServicesDriver = 1,
|
||||
UeSubsystemEfiRuntimeDriver = 2
|
||||
};
|
||||
|
||||
///
|
||||
/// Definition of a UE file header.
|
||||
///
|
||||
typedef struct {
|
||||
///
|
||||
/// The file magic number to identify the UE file format. Must be 'UE'.
|
||||
///
|
||||
UINT16 Magic;
|
||||
///
|
||||
/// Information about the image kind and supported architectures.
|
||||
///
|
||||
/// [Bits 2:0] Indicates the subsystem.
|
||||
/// [Bits 7:3] Indicates the supported architectures.
|
||||
///
|
||||
UINT8 Type;
|
||||
///
|
||||
/// Information about the UE load tables and segments.
|
||||
///
|
||||
/// [Bits 2:0] The number of UE load tables.
|
||||
/// [Bits 7:3] The index of the last segment in the UE segment table.
|
||||
///
|
||||
UINT8 TableCounts;
|
||||
///
|
||||
/// Indicates the offset of the UE entry point in the UE address space.
|
||||
///
|
||||
UINT32 EntryPointAddress;
|
||||
///
|
||||
/// Information about the UE image.
|
||||
///
|
||||
/// [Bits 51:0] The base UEFI page of the UE image, i.e., the base address in
|
||||
/// 4 KiB units.
|
||||
/// [Bits 55:52] Reserved for future use. Must be zero.
|
||||
/// [Bit 56] Indicates whether the UE image is XIP
|
||||
/// [Bit 57] Indicates whether the UE image is designated for a fixed
|
||||
/// address.
|
||||
/// [Bit 58] Indicates whether the UE relocation table has been stripped.
|
||||
/// [Bit 59] Indicates whether UE chained fixups are used.
|
||||
/// [Bits 63:60] The shift exponent, offset by -12, for the UE segment
|
||||
/// alignment in bytes.
|
||||
///
|
||||
UINT64 ImageInfo;
|
||||
///
|
||||
/// The UE segment table. It contains all data of the UE address space.
|
||||
///
|
||||
/// All UE segments are contiguous in the UE address space.
|
||||
/// The offset of the first UE segment in the UE address space is 0.
|
||||
///
|
||||
/// All UE segments' data are contiguous in the UE file.
|
||||
/// The offset of the first UE segment in the UE file is the end of the UE
|
||||
/// file header.
|
||||
///
|
||||
UE_SEGMENT Segments[];
|
||||
///
|
||||
/// The UE load tables. They contain data useful for UE loading.
|
||||
///
|
||||
/// All UE load tables are contiguous in the UE file.
|
||||
/// The offset of the first UE load table in the UE file is the end of the last
|
||||
/// UE segment in the UE file.
|
||||
///
|
||||
/// All UE load tables are ordered ascending by their identifier.
|
||||
///
|
||||
//UE_LOAD_TABLE LoadTables[];
|
||||
} UE_HEADER;
|
||||
|
||||
///
|
||||
/// The minimum size, in bytes, of a valid UE header.
|
||||
///
|
||||
#define MIN_SIZE_OF_UE_HEADER \
|
||||
(OFFSET_OF (UE_HEADER, Segments) + sizeof (UE_SEGMENT))
|
||||
|
||||
STATIC_ASSERT (
|
||||
sizeof (UE_HEADER) == 16 && ALIGNOF (UE_HEADER) == 8,
|
||||
"The UE header definition does not meet the specification."
|
||||
);
|
||||
|
||||
STATIC_ASSERT (
|
||||
ALIGNOF (UE_SEGMENT) <= ALIGNOF (UE_LOAD_TABLE),
|
||||
"The UE header definition is misaligned."
|
||||
);
|
||||
|
||||
STATIC_ASSERT (
|
||||
OFFSET_OF (UE_HEADER, Segments) == sizeof (UE_HEADER),
|
||||
"The UE header definition does not meet the specification."
|
||||
);
|
||||
|
||||
/**
|
||||
Retrieves the UE base address.
|
||||
|
||||
@param[in] ImageInfo The UE header image information.
|
||||
**/
|
||||
#define UE_HEADER_BASE_ADDRESS(ImageInfo) LShiftU64 (ImageInfo, 12)
|
||||
|
||||
/**
|
||||
Retrieves the UE segment alignment, in bytes, as a power of two.
|
||||
|
||||
@param[in] ImageInfo The UE header image information.
|
||||
**/
|
||||
#define UE_HEADER_SEGMENT_ALIGNMENT(ImageInfo) \
|
||||
(1U << ((UINT8)RShiftU64 (ImageInfo, 60) + 12U))
|
||||
|
||||
///
|
||||
/// UE header image information bit that indicates whether the image is XIP.
|
||||
///
|
||||
#define UE_HEADER_IMAGE_INFO_XIP 0x0100000000000000ULL
|
||||
|
||||
///
|
||||
/// UE header image information bit that indicates whether the image is
|
||||
/// designated to be loaded to a fixed address.
|
||||
///
|
||||
#define UE_HEADER_IMAGE_INFO_FIXED_ADDRESS 0x0200000000000000ULL
|
||||
|
||||
///
|
||||
/// UE header image information bit that indicates whether the relocation fixups
|
||||
/// have been stripped.
|
||||
///
|
||||
#define UE_HEADER_IMAGE_INFO_RELOCATION_FIXUPS_STRIPPED 0x0400000000000000ULL
|
||||
|
||||
///
|
||||
/// UE header image information bit that indicates whether UE relocation fixup
|
||||
/// chains are utilized.
|
||||
///
|
||||
#define UE_HEADER_IMAGE_INFO_CHAINED_FIXUPS 0x0800000000000000ULL
|
||||
|
||||
/**
|
||||
Retrieves the UE subsystem.
|
||||
|
||||
@param[in] Type The UE header type information.
|
||||
**/
|
||||
#define UE_HEADER_SUBSYSTEM(Type) ((Type) & 0x07U)
|
||||
|
||||
/**
|
||||
Retrieves the UE supported architectures.
|
||||
|
||||
@param[in] Type The UE header type information.
|
||||
**/
|
||||
#define UE_HEADER_ARCH(Type) ((Type) >> 3U)
|
||||
|
||||
///
|
||||
/// The maximum number of UE load tables.
|
||||
///
|
||||
#define UE_HEADER_NUM_LOAD_TABLES_MAX 7U
|
||||
|
||||
/**
|
||||
Retrieves the number of UE load tables.
|
||||
|
||||
@param[in] TableCounts The UE header segment and load table information.
|
||||
**/
|
||||
#define UE_HEADER_NUM_LOAD_TABLES(TableCounts) ((TableCounts) & 0x07U)
|
||||
|
||||
STATIC_ASSERT (
|
||||
UE_HEADER_NUM_LOAD_TABLES (0xFFU) == UE_HEADER_NUM_LOAD_TABLES_MAX,
|
||||
"The number of load tables violates the specification."
|
||||
);
|
||||
|
||||
///
|
||||
/// The maximum number of UE segments.
|
||||
///
|
||||
#define UE_HEADER_NUM_SEGMENTS_MAX 32U
|
||||
|
||||
/**
|
||||
Retrieves the index of the last UE segment, i.e., their amount minus 1.
|
||||
|
||||
@param[in] TableCounts The UE header segment and load table information.
|
||||
**/
|
||||
#define UE_HEADER_LAST_SEGMENT_INDEX(TableCounts) ((TableCounts) >> 3U)
|
||||
|
||||
STATIC_ASSERT (
|
||||
UE_HEADER_LAST_SEGMENT_INDEX (0xFFU) + 1U == UE_HEADER_NUM_SEGMENTS_MAX,
|
||||
"The number of load tables violates the specification."
|
||||
);
|
||||
|
||||
/**
|
||||
Retrieves the 8 byte aligned UE file size.
|
||||
|
||||
If the file size is larger than this value, the appended data may be the UE
|
||||
certificate table.
|
||||
|
||||
@param[in] FileInfo The UE header file information.
|
||||
**/
|
||||
#define UE_HEADER_FILE_SIZE(FileInfo) ((FileInfo) << 3U)
|
||||
|
||||
STATIC_ASSERT (
|
||||
IS_ALIGNED (UE_HEADER_FILE_SIZE (0xFFFFFFFF), UE_LOAD_TABLE_ALIGNMENT),
|
||||
"The UE file size definition does not meet the specification."
|
||||
);
|
||||
|
||||
///
|
||||
/// The maximum size, in bytes, of a valid UE header.
|
||||
///
|
||||
#define MAX_SIZE_OF_UE_HEADER \
|
||||
MIN_SIZE_OF_UE_HEADER + \
|
||||
UE_HEADER_NUM_SEGMENTS_MAX * sizeof (UE_SEGMENT) + \
|
||||
UE_HEADER_NUM_LOAD_TABLES_MAX * sizeof (UE_LOAD_TABLE)
|
||||
|
||||
#endif // UE_IMAGE_H_
|
|
@ -0,0 +1,181 @@
|
|||
/** @file
|
||||
UEFI Image Loader library implementation for UE Images.
|
||||
|
||||
Copyright (c) 2021 - 2023, Marvin Häuser. All rights reserved.<BR>
|
||||
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
**/
|
||||
|
||||
#ifndef UE_LIB_H_
|
||||
#define UE_LIB_H_
|
||||
|
||||
#include <IndustryStandard/UeImage.h>
|
||||
|
||||
typedef struct {
|
||||
CONST UINT8 *FileBuffer;
|
||||
UINT32 UnsignedFileSize;
|
||||
UINT8 Subsystem;
|
||||
UINT8 Machine;
|
||||
BOOLEAN FixedAddress;
|
||||
BOOLEAN XIP;
|
||||
UINT8 LastSegmentIndex;
|
||||
UINT32 SegmentsFileOffset; // Unused for XIP
|
||||
UINT32 SegmentAlignment;
|
||||
CONST VOID *Segments;
|
||||
UINT8 SegmentImageInfoIterSize;
|
||||
BOOLEAN RelocsStripped;
|
||||
UINT8 NumLoadTables;
|
||||
UINT32 LoadTablesFileOffset;
|
||||
UINT32 RelocTableSize;
|
||||
CONST UE_LOAD_TABLE *LoadTables;
|
||||
VOID *ImageBuffer;
|
||||
UINT32 ImageSize;
|
||||
UINT32 EntryPointAddress;
|
||||
UINT64 BaseAddress; // Unused for XIP
|
||||
} UE_LOADER_IMAGE_CONTEXT;
|
||||
|
||||
typedef struct UE_LOADER_RUNTIME_CONTEXT_ UE_LOADER_RUNTIME_CONTEXT;
|
||||
|
||||
/**
|
||||
Adds the digest of Data to HashContext. This function can be called multiple
|
||||
times to compute the digest of discontinuous data.
|
||||
|
||||
@param[in,out] HashContext The context of the current hash.
|
||||
@param[in] Data The data to be hashed.
|
||||
@param[in] DataSize The size, in Bytes, of Data.
|
||||
|
||||
@returns Whether hashing has been successful.
|
||||
**/
|
||||
typedef
|
||||
BOOLEAN
|
||||
(EFIAPI *UE_LOADER_HASH_UPDATE)(
|
||||
IN OUT VOID *HashContext,
|
||||
IN CONST VOID *Data,
|
||||
IN UINTN DataSize
|
||||
);
|
||||
|
||||
RETURN_STATUS
|
||||
UeInitializeContextPreHash (
|
||||
OUT UE_LOADER_IMAGE_CONTEXT *Context,
|
||||
IN CONST VOID *FileBuffer,
|
||||
IN UINT32 FileSize
|
||||
);
|
||||
|
||||
RETURN_STATUS
|
||||
UeInitializeContextPostHash (
|
||||
IN OUT UE_LOADER_IMAGE_CONTEXT *Context
|
||||
);
|
||||
|
||||
BOOLEAN
|
||||
UeHashImageDefault (
|
||||
IN OUT UE_LOADER_IMAGE_CONTEXT *Context,
|
||||
IN OUT VOID *HashContext,
|
||||
IN UE_LOADER_HASH_UPDATE HashUpdate
|
||||
);
|
||||
|
||||
RETURN_STATUS
|
||||
UeLoadImage (
|
||||
IN OUT UE_LOADER_IMAGE_CONTEXT *Context,
|
||||
OUT VOID *Destination,
|
||||
IN UINT32 DestinationSize
|
||||
);
|
||||
|
||||
RETURN_STATUS
|
||||
UeLoaderGetRuntimeContextSize (
|
||||
IN OUT UE_LOADER_IMAGE_CONTEXT *Context,
|
||||
OUT UINT32 *Size
|
||||
);
|
||||
|
||||
RETURN_STATUS
|
||||
UeRelocateImage (
|
||||
IN OUT UE_LOADER_IMAGE_CONTEXT *Context,
|
||||
IN UINT64 BaseAddress,
|
||||
OUT UE_LOADER_RUNTIME_CONTEXT *RuntimeContext OPTIONAL,
|
||||
IN UINT32 RuntimeContextSize
|
||||
);
|
||||
|
||||
RETURN_STATUS
|
||||
UeRelocateImageForRuntime (
|
||||
IN OUT VOID *Image,
|
||||
IN UINT32 ImageSize,
|
||||
IN CONST UE_LOADER_RUNTIME_CONTEXT *RuntimeContext,
|
||||
IN UINT64 BaseAddress
|
||||
);
|
||||
|
||||
RETURN_STATUS
|
||||
UeGetSymbolsPath (
|
||||
IN CONST UE_LOADER_IMAGE_CONTEXT *Context,
|
||||
OUT CONST CHAR8 **SymbolsPath,
|
||||
OUT UINT32 *SymbolsPathSize
|
||||
);
|
||||
|
||||
UINTN
|
||||
UeLoaderGetImageDebugAddress (
|
||||
IN CONST UE_LOADER_IMAGE_CONTEXT *Context
|
||||
);
|
||||
|
||||
RETURN_STATUS
|
||||
UeGetSegmentNames (
|
||||
IN CONST UE_LOADER_IMAGE_CONTEXT *Context,
|
||||
OUT CONST UE_SEGMENT_NAME **SegmentNames
|
||||
);
|
||||
|
||||
UINT32
|
||||
UeGetEntryPointAddress (
|
||||
IN CONST UE_LOADER_IMAGE_CONTEXT *Context
|
||||
);
|
||||
|
||||
UINT16
|
||||
UeGetMachine (
|
||||
IN OUT UE_LOADER_IMAGE_CONTEXT *Context
|
||||
);
|
||||
|
||||
UINT16
|
||||
UeGetSubsystem (
|
||||
IN OUT UE_LOADER_IMAGE_CONTEXT *Context
|
||||
);
|
||||
|
||||
UINT32
|
||||
UeGetSegmentAlignment (
|
||||
IN OUT UE_LOADER_IMAGE_CONTEXT *Context
|
||||
);
|
||||
|
||||
UINT32
|
||||
UeGetImageSize (
|
||||
IN OUT UE_LOADER_IMAGE_CONTEXT *Context
|
||||
);
|
||||
|
||||
UINT64
|
||||
UeGetBaseAddress (
|
||||
IN OUT UE_LOADER_IMAGE_CONTEXT *Context
|
||||
);
|
||||
|
||||
BOOLEAN
|
||||
UeGetRelocsStripped (
|
||||
IN OUT UE_LOADER_IMAGE_CONTEXT *Context
|
||||
);
|
||||
|
||||
BOOLEAN
|
||||
UeGetFixedAddress(
|
||||
IN OUT UE_LOADER_IMAGE_CONTEXT *Context
|
||||
);
|
||||
|
||||
UINTN
|
||||
UeLoaderGetImageAddress (
|
||||
IN CONST UE_LOADER_IMAGE_CONTEXT *Context
|
||||
);
|
||||
|
||||
UINT16
|
||||
UeGetSegments (
|
||||
IN CONST UE_LOADER_IMAGE_CONTEXT *Context,
|
||||
OUT CONST UE_SEGMENT **Segments
|
||||
);
|
||||
|
||||
UINT16
|
||||
UeGetSegmentImageInfos (
|
||||
IN OUT UE_LOADER_IMAGE_CONTEXT *Context,
|
||||
OUT CONST UINT32 **SegmentImageInfos,
|
||||
OUT UINT8 *SegmentImageInfoIterSize
|
||||
);
|
||||
|
||||
#endif // UE_LIB_H_
|
|
@ -2,10 +2,12 @@
|
|||
#ifndef UEFI_IMAGE_LIB_H_
|
||||
#define UEFI_IMAGE_LIB_H_
|
||||
|
||||
#include <Library/UeImageLib.h>
|
||||
#include <Library/PeCoffLib2.h>
|
||||
|
||||
typedef enum {
|
||||
UefiImageFormatPe = 0,
|
||||
UefiImageFormatUe = 1,
|
||||
UefiImageFormatMax
|
||||
} UEFI_IMAGE_FORMAT;
|
||||
|
||||
|
@ -14,11 +16,52 @@ typedef enum {
|
|||
#define UEFI_IMAGE_SOURCE_ALL 2U
|
||||
#define UEFI_IMAGE_SOURCE_MAX 3U
|
||||
|
||||
// FIXME: Get rid of pointers.
|
||||
typedef struct {
|
||||
UINT32 ImageBuffer;
|
||||
UINT32 AddressOfEntryPoint;
|
||||
UINT8 ImageType;
|
||||
UINT32 FileBuffer;
|
||||
UINT32 ExeHdrOffset;
|
||||
UINT32 SizeOfImage;
|
||||
UINT32 FileSize;
|
||||
UINT16 Subsystem;
|
||||
UINT32 SectionAlignment;
|
||||
UINT32 SectionsOffset;
|
||||
UINT16 NumberOfSections;
|
||||
UINT32 SizeOfHeaders;
|
||||
} PE_HOB_IMAGE_CONTEXT;
|
||||
|
||||
typedef struct {
|
||||
UINT32 ImageBuffer;
|
||||
UINT32 FileBuffer;
|
||||
UINT32 EntryPointAddress;
|
||||
UINT32 LoadTablesFileOffset;
|
||||
UINT8 NumLoadTables;
|
||||
UINT32 LoadTables;
|
||||
UINT32 Segments;
|
||||
UINT8 LastSegmentIndex;
|
||||
UINT32 SegmentAlignment;
|
||||
UINT32 ImageSize;
|
||||
UINT8 Subsystem;
|
||||
UINT8 SegmentImageInfoIterSize;
|
||||
UINT32 SegmentsFileOffset;
|
||||
} UE_HOB_IMAGE_CONTEXT;
|
||||
|
||||
typedef struct {
|
||||
UINT8 FormatIndex;
|
||||
union {
|
||||
UE_HOB_IMAGE_CONTEXT Ue;
|
||||
PE_HOB_IMAGE_CONTEXT Pe;
|
||||
} Ctx;
|
||||
} HOB_IMAGE_CONTEXT;
|
||||
|
||||
typedef UINT8 UEFI_IMAGE_SOURCE;
|
||||
|
||||
typedef struct {
|
||||
UINT8 FormatIndex;
|
||||
union {
|
||||
UE_LOADER_IMAGE_CONTEXT Ue;
|
||||
PE_COFF_LOADER_IMAGE_CONTEXT Pe;
|
||||
} Ctx;
|
||||
} UEFI_IMAGE_LOADER_IMAGE_CONTEXT;
|
||||
|
@ -574,6 +617,22 @@ UefiImageLoaderGetImageAddress (
|
|||
IN CONST UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context
|
||||
);
|
||||
|
||||
/**
|
||||
Retrieves the Image debug address. Due to post-processing, the debug address
|
||||
may deviate from the load address. Symbolication must use this address.
|
||||
|
||||
May be called only after UefiImageLoadImage() has succeeded.
|
||||
|
||||
@param[in,out] Context The context describing the Image. Must have been
|
||||
initialised by UefiImageInitializeContext().
|
||||
|
||||
@returns The Image debug address.
|
||||
**/
|
||||
UINTN
|
||||
UefiImageLoaderGetDebugAddress (
|
||||
IN CONST UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context
|
||||
);
|
||||
|
||||
/**
|
||||
Retrieve the Image entry point address.
|
||||
|
||||
|
|
|
@ -12,10 +12,13 @@
|
|||
#ifndef __LOAD_FILE_PPI_H__
|
||||
#define __LOAD_FILE_PPI_H__
|
||||
|
||||
#include <Library/UefiImageLib.h>
|
||||
|
||||
#define EFI_PEI_LOAD_FILE_PPI_GUID \
|
||||
{ 0xb9e0abfe, 0x5979, 0x4914, { 0x97, 0x7f, 0x6d, 0xee, 0x78, 0xc2, 0x78, 0xa6 } }
|
||||
|
||||
typedef struct _EFI_PEI_LOAD_FILE_PPI EFI_PEI_LOAD_FILE_PPI;
|
||||
typedef struct _EFI_PEI_LOAD_FILE_WITH_HOB_PPI EFI_PEI_LOAD_FILE_WITH_HOB_PPI;
|
||||
|
||||
/**
|
||||
Loads a PEIM into memory for subsequent execution.
|
||||
|
@ -56,6 +59,17 @@ EFI_STATUS
|
|||
OUT UINT32 *AuthenticationState
|
||||
);
|
||||
|
||||
typedef
|
||||
EFI_STATUS
|
||||
(EFIAPI *EFI_PEI_LOAD_FILE_WITH_HOB)(
|
||||
IN EFI_PEI_FILE_HANDLE FileHandle,
|
||||
OUT EFI_PHYSICAL_ADDRESS *ImageAddress,
|
||||
OUT UINT64 *ImageSize,
|
||||
OUT EFI_PHYSICAL_ADDRESS *EntryPoint,
|
||||
OUT UINT32 *AuthenticationState,
|
||||
OUT HOB_IMAGE_CONTEXT *Hob
|
||||
);
|
||||
|
||||
///
|
||||
/// This PPI is a pointer to the Load File service.
|
||||
/// This service will be published by a PEIM. The PEI Foundation
|
||||
|
@ -65,6 +79,11 @@ struct _EFI_PEI_LOAD_FILE_PPI {
|
|||
EFI_PEI_LOAD_FILE LoadFile;
|
||||
};
|
||||
|
||||
struct _EFI_PEI_LOAD_FILE_WITH_HOB_PPI {
|
||||
EFI_PEI_LOAD_FILE_WITH_HOB LoadFile;
|
||||
};
|
||||
|
||||
extern EFI_GUID gEfiPeiLoadFilePpiGuid;
|
||||
extern EFI_GUID gEfiPeiLoadFileWithHobPpiGuid;
|
||||
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
## @file
|
||||
# UEFI Image Loader library implementation for UE Images.
|
||||
#
|
||||
# Copyright (c) 2021, Marvin Häuser. All rights reserved.<BR>
|
||||
#
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
##
|
||||
|
||||
[Defines]
|
||||
INF_VERSION = 0x00010005
|
||||
BASE_NAME = UeImageLib
|
||||
FILE_GUID = 357AD87E-8D6B-468A-B3FA-0D9CC4C725CD
|
||||
MODULE_TYPE = BASE
|
||||
VERSION_STRING = 1.0
|
||||
LIBRARY_CLASS = BaseUeImageLib
|
||||
|
||||
[Sources]
|
||||
UeImageLib.c
|
||||
|
||||
[Packages]
|
||||
MdePkg/MdePkg.dec
|
||||
|
||||
[LibraryClasses]
|
||||
BaseLib
|
||||
BaseMemoryLib
|
||||
BaseOverflowLib
|
||||
DebugLib
|
||||
PcdLib
|
||||
|
||||
[FixedPcd]
|
||||
gEfiMdePkgTokenSpaceGuid.PcdImageLoaderRelocTypePolicy
|
||||
gEfiMdePkgTokenSpaceGuid.PcdDebugRaisePropertyMask
|
||||
gEfiMdePkgTokenSpaceGuid.PcdImageLoaderRtRelocAllowTargetMismatch
|
File diff suppressed because it is too large
Load Diff
|
@ -18,6 +18,7 @@
|
|||
[Sources]
|
||||
CommonSupport.c
|
||||
ExecutionSupport.c
|
||||
UeSupport.c
|
||||
PeSupport.c
|
||||
UefiImageLib.c
|
||||
|
||||
|
@ -32,6 +33,7 @@
|
|||
DebugLib
|
||||
MemoryAllocationLib
|
||||
PeCoffLib2
|
||||
UeImageLib
|
||||
UefiImageExtraActionLib
|
||||
|
||||
[FixedPcd]
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
[Sources]
|
||||
CommonSupport.c
|
||||
ExecutionSupport.c
|
||||
UeSupport.c
|
||||
PeSupport.c
|
||||
UefiImageLib.c
|
||||
|
||||
|
@ -32,6 +33,7 @@
|
|||
DebugLib
|
||||
MemoryAllocationLib
|
||||
PeCoffLib2
|
||||
UeImageLib
|
||||
UefiImageExtraActionLib
|
||||
|
||||
[FixedPcd]
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
[Sources]
|
||||
CommonSupport.c
|
||||
ExecutionSupport.c
|
||||
UeSupport.c
|
||||
PeSupport.c
|
||||
UefiImageLib.c
|
||||
|
||||
|
@ -32,14 +33,14 @@
|
|||
DebugLib
|
||||
MemoryAllocationLib
|
||||
PeCoffLib2
|
||||
UeImageLib
|
||||
UefiImageExtraActionLib
|
||||
|
||||
[FixedPcd]
|
||||
gEfiMdePkgTokenSpaceGuid.PcdImageLoaderAlignmentPolicy
|
||||
gEfiMdePkgTokenSpaceGuid.PcdImageLoaderLoadHeader
|
||||
gEfiMdePkgTokenSpaceGuid.PcdImageLoaderRemoveXForWX
|
||||
gEfiMdePkgTokenSpaceGuid.PcdDebugRaisePropertyMask
|
||||
|
||||
gEfiMdePkgTokenSpaceGuid.PcdImageLoaderRemoveXForWX
|
||||
gEfiMdePkgTokenSpaceGuid.PcdUefiImageFormatSupportNonFv
|
||||
gEfiMdePkgTokenSpaceGuid.PcdUefiImageFormatSupportFv
|
||||
|
||||
|
|
|
@ -92,11 +92,7 @@ UefiImageGetModuleNameFromSymbolsPath (
|
|||
// the debug symbols for the Image.
|
||||
//
|
||||
StartIndex = 0;
|
||||
for (
|
||||
Index = 0;
|
||||
Index < SymbolsPathSize && SymbolsPath[Index] != '\0';
|
||||
++Index
|
||||
) {
|
||||
for (Index = 0; Index < SymbolsPathSize - 1; ++Index) {
|
||||
if (SymbolsPath[Index] == '\\' || SymbolsPath[Index] == '/') {
|
||||
StartIndex = Index + 1;
|
||||
}
|
||||
|
@ -107,7 +103,7 @@ UefiImageGetModuleNameFromSymbolsPath (
|
|||
//
|
||||
for (
|
||||
Index = 0;
|
||||
Index < MIN (ModuleNameSize, SymbolsPathSize);
|
||||
Index < MIN (ModuleNameSize, SymbolsPathSize) - 1;
|
||||
++Index
|
||||
) {
|
||||
ModuleName[Index] = SymbolsPath[Index + StartIndex];
|
||||
|
@ -115,7 +111,7 @@ UefiImageGetModuleNameFromSymbolsPath (
|
|||
ModuleName[Index] = '.';
|
||||
}
|
||||
if (ModuleName[Index] == '.') {
|
||||
if (Index > ModuleNameSize - 3) {
|
||||
if (Index >= ModuleNameSize - 4) {
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -139,7 +135,7 @@ UefiImageDebugPrintImageRecord (
|
|||
IN CONST UEFI_IMAGE_RECORD *ImageRecord
|
||||
)
|
||||
{
|
||||
UINT16 SegmentIndex;
|
||||
UINT32 SegmentIndex;
|
||||
UINTN SegmentAddress;
|
||||
|
||||
ASSERT (ImageRecord != NULL);
|
||||
|
|
|
@ -0,0 +1,560 @@
|
|||
/** @file
|
||||
UEFI Image Loader library implementation for UE Images.
|
||||
|
||||
Copyright (c) 2023, Marvin Häuser. All rights reserved.<BR>
|
||||
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
**/
|
||||
|
||||
#include <Base.h>
|
||||
#include <Uefi/UefiBaseType.h>
|
||||
#include <Uefi/UefiSpec.h>
|
||||
|
||||
#include <Library/BaseLib.h>
|
||||
#include <Library/BaseMemoryLib.h>
|
||||
#include <Library/BaseOverflowLib.h>
|
||||
#include <Library/CacheMaintenanceLib.h>
|
||||
#include <Library/DebugLib.h>
|
||||
#include <Library/MemoryAllocationLib.h>
|
||||
#include <Library/PcdLib.h>
|
||||
#include <Library/UeImageLib.h>
|
||||
#include <Library/UefiImageLib.h>
|
||||
#include <Library/UefiImageExtraActionLib.h>
|
||||
|
||||
#include "UeSupport.h"
|
||||
|
||||
STATIC CONST UINT16 mPeMachines[] = {
|
||||
IMAGE_FILE_MACHINE_I386,
|
||||
IMAGE_FILE_MACHINE_X64,
|
||||
IMAGE_FILE_MACHINE_ARMTHUMB_MIXED,
|
||||
IMAGE_FILE_MACHINE_ARM64,
|
||||
IMAGE_FILE_MACHINE_RISCV32,
|
||||
IMAGE_FILE_MACHINE_RISCV64,
|
||||
IMAGE_FILE_MACHINE_RISCV128
|
||||
};
|
||||
|
||||
RETURN_STATUS
|
||||
UefiImageInitializeContextPreHashUe (
|
||||
OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context,
|
||||
IN CONST VOID *FileBuffer,
|
||||
IN UINT32 FileSize
|
||||
)
|
||||
{
|
||||
return UeInitializeContextPreHash (&Context->Ctx.Ue, FileBuffer, FileSize);
|
||||
}
|
||||
|
||||
RETURN_STATUS
|
||||
UefiImageInitializeContextPostHashUe (
|
||||
OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context
|
||||
)
|
||||
{
|
||||
return UeInitializeContextPostHash (&Context->Ctx.Ue);
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
UefiImageHashImageDefaultUe (
|
||||
IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context,
|
||||
IN OUT VOID *HashContext,
|
||||
IN UEFI_IMAGE_LOADER_HASH_UPDATE HashUpdate
|
||||
)
|
||||
{
|
||||
return UeHashImageDefault (&Context->Ctx.Ue, HashContext, HashUpdate);
|
||||
}
|
||||
|
||||
RETURN_STATUS
|
||||
UefiImageLoadImageUe (
|
||||
IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context,
|
||||
OUT VOID *Destination,
|
||||
IN UINT32 DestinationSize
|
||||
)
|
||||
{
|
||||
return UeLoadImage (&Context->Ctx.Ue, Destination, DestinationSize);
|
||||
}
|
||||
|
||||
//
|
||||
// In-place semantics are currently unsupported.
|
||||
//
|
||||
|
||||
// LCOV_EXCL_START
|
||||
BOOLEAN
|
||||
UefiImageImageIsInplaceUe (
|
||||
IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context
|
||||
)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
RETURN_STATUS
|
||||
UefiImageLoadImageInplaceUe (
|
||||
IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context
|
||||
)
|
||||
{
|
||||
ASSERT (Context != NULL);
|
||||
|
||||
if (Context->Ctx.Ue.XIP) {
|
||||
Context->Ctx.Ue.ImageBuffer = (UINT8 *) Context->Ctx.Ue.FileBuffer;
|
||||
|
||||
return RETURN_SUCCESS;
|
||||
}
|
||||
|
||||
return RETURN_UNSUPPORTED;
|
||||
}
|
||||
|
||||
RETURN_STATUS
|
||||
UefiImageRelocateImageInplaceUe (
|
||||
IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context
|
||||
)
|
||||
{
|
||||
return RETURN_UNSUPPORTED;
|
||||
}
|
||||
// LCOV_EXCL_STOP
|
||||
|
||||
RETURN_STATUS
|
||||
UefiImageLoaderGetRuntimeContextSizeUe (
|
||||
IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context,
|
||||
OUT UINT32 *Size
|
||||
)
|
||||
{
|
||||
return UeLoaderGetRuntimeContextSize (&Context->Ctx.Ue, Size);
|
||||
}
|
||||
|
||||
RETURN_STATUS
|
||||
UefiImageRelocateImageUe (
|
||||
IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context,
|
||||
IN UINT64 BaseAddress,
|
||||
OUT VOID *RuntimeContext OPTIONAL,
|
||||
IN UINT32 RuntimeContextSize
|
||||
)
|
||||
{
|
||||
return UeRelocateImage (
|
||||
&Context->Ctx.Ue,
|
||||
BaseAddress,
|
||||
(UE_LOADER_RUNTIME_CONTEXT *)RuntimeContext,
|
||||
RuntimeContextSize
|
||||
);
|
||||
}
|
||||
|
||||
RETURN_STATUS
|
||||
UefiImageRuntimeRelocateImageUe (
|
||||
IN OUT VOID *Image,
|
||||
IN UINT32 ImageSize,
|
||||
IN UINT64 BaseAddress,
|
||||
IN CONST VOID *RuntimeContext
|
||||
)
|
||||
{
|
||||
return UeRelocateImageForRuntime (
|
||||
Image,
|
||||
ImageSize,
|
||||
(UE_LOADER_RUNTIME_CONTEXT *)RuntimeContext,
|
||||
BaseAddress
|
||||
);
|
||||
}
|
||||
|
||||
VOID
|
||||
UefiImageDiscardSegmentsUe (
|
||||
IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context
|
||||
)
|
||||
{
|
||||
//
|
||||
// Anything discardable is not loaded in the first place.
|
||||
//
|
||||
}
|
||||
|
||||
RETURN_STATUS
|
||||
UefiImageGetSymbolsPathUe (
|
||||
IN CONST UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context,
|
||||
OUT CONST CHAR8 **SymbolsPath,
|
||||
OUT UINT32 *SymbolsPathSize
|
||||
)
|
||||
{
|
||||
return UeGetSymbolsPath (&Context->Ctx.Ue, SymbolsPath, SymbolsPathSize);
|
||||
}
|
||||
|
||||
//
|
||||
// UE does not support embedded certificates (yet).
|
||||
//
|
||||
|
||||
// LCOV_EXCL_START
|
||||
RETURN_STATUS
|
||||
UefiImageGetFirstCertificateUe (
|
||||
IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context,
|
||||
OUT CONST WIN_CERTIFICATE **Certificate
|
||||
)
|
||||
{
|
||||
return RETURN_UNSUPPORTED;
|
||||
}
|
||||
|
||||
RETURN_STATUS
|
||||
UefiImageGetNextCertificateUe (
|
||||
IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context,
|
||||
IN OUT CONST WIN_CERTIFICATE **Certificate
|
||||
)
|
||||
{
|
||||
return RETURN_UNSUPPORTED;
|
||||
}
|
||||
|
||||
RETURN_STATUS
|
||||
UefiImageGetHiiDataRvaUe (
|
||||
IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context,
|
||||
OUT UINT32 *HiiRva,
|
||||
OUT UINT32 *HiiSize
|
||||
)
|
||||
{
|
||||
//
|
||||
// UE does not support legacy HII.
|
||||
//
|
||||
return RETURN_NOT_FOUND;
|
||||
}
|
||||
// LCOV_EXCL_STOP
|
||||
|
||||
UINT32
|
||||
UefiImageGetEntryPointAddressUe (
|
||||
IN CONST UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context
|
||||
)
|
||||
{
|
||||
return UeGetEntryPointAddress (&Context->Ctx.Ue);
|
||||
}
|
||||
|
||||
UINT16
|
||||
UefiImageGetMachineUe (
|
||||
IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context
|
||||
)
|
||||
{
|
||||
UINT16 UeMachine;
|
||||
|
||||
UeMachine = UeGetMachine (&Context->Ctx.Ue);
|
||||
if (UeMachine >= ARRAY_SIZE (mPeMachines)) {
|
||||
DEBUG_RAISE ();
|
||||
return 0xFFFF;
|
||||
}
|
||||
|
||||
return mPeMachines[UeMachine];
|
||||
}
|
||||
|
||||
UINT16
|
||||
UefiImageGetSubsystemUe (
|
||||
IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context
|
||||
)
|
||||
{
|
||||
return UeGetSubsystem (&Context->Ctx.Ue) + 10;
|
||||
}
|
||||
|
||||
UINT32
|
||||
UefiImageGetSegmentAlignmentUe (
|
||||
IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context
|
||||
)
|
||||
{
|
||||
return UeGetSegmentAlignment (&Context->Ctx.Ue);
|
||||
}
|
||||
|
||||
UINT32
|
||||
UefiImageGetImageSizeUe (
|
||||
IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context
|
||||
)
|
||||
{
|
||||
return UeGetImageSize (&Context->Ctx.Ue);
|
||||
}
|
||||
|
||||
UINT64
|
||||
UefiImageGetBaseAddressUe (
|
||||
IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context
|
||||
)
|
||||
{
|
||||
return UeGetBaseAddress (&Context->Ctx.Ue);
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
UefiImageGetRelocsStrippedUe (
|
||||
IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context
|
||||
)
|
||||
{
|
||||
return UeGetRelocsStripped (&Context->Ctx.Ue);
|
||||
}
|
||||
|
||||
UINTN
|
||||
UefiImageLoaderGetImageAddressUe (
|
||||
IN CONST UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context
|
||||
)
|
||||
{
|
||||
return UeLoaderGetImageAddress (&Context->Ctx.Ue);
|
||||
}
|
||||
|
||||
UINTN
|
||||
UefiImageLoaderGetDebugAddressUe (
|
||||
IN CONST UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context
|
||||
)
|
||||
{
|
||||
return UeLoaderGetImageDebugAddress (&Context->Ctx.Ue);
|
||||
}
|
||||
|
||||
STATIC
|
||||
UINT32
|
||||
InternalPermissionsToAttributes (
|
||||
IN UINT8 Permissions
|
||||
)
|
||||
{
|
||||
switch (Permissions) {
|
||||
case UeSegmentPermX:
|
||||
{
|
||||
return EFI_MEMORY_RP | EFI_MEMORY_RO;
|
||||
}
|
||||
|
||||
case UeSegmentPermRX:
|
||||
{
|
||||
return EFI_MEMORY_RO;
|
||||
}
|
||||
|
||||
case UeSegmentPermRW:
|
||||
{
|
||||
return EFI_MEMORY_XP;
|
||||
}
|
||||
|
||||
case UeSegmentPermR:
|
||||
default:
|
||||
{
|
||||
ASSERT (Permissions == UeSegmentPermR);
|
||||
return EFI_MEMORY_XP | EFI_MEMORY_RO;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
UEFI_IMAGE_RECORD *
|
||||
UefiImageLoaderGetImageRecordUe (
|
||||
IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context
|
||||
)
|
||||
{
|
||||
UEFI_IMAGE_RECORD *ImageRecord;
|
||||
UINTN ImageAddress;
|
||||
UINT32 ImageSize;
|
||||
UINT32 ImageSizeRecord;
|
||||
UINT32 NumRecordSegments;
|
||||
UEFI_IMAGE_RECORD_SEGMENT *RecordSegment;
|
||||
UINT16 NumSegments;
|
||||
UINT8 SegmentIterSize;
|
||||
CONST UINT32 *SegmentImageInfos;
|
||||
CONST UINT8 *SegmentImageInfoPtr;
|
||||
UINT32 SegmentImageInfo;
|
||||
UINT32 SegmentSize;
|
||||
UINT8 SegmentPermissions;
|
||||
UINT32 RangeSize;
|
||||
UINT8 Permissions;
|
||||
|
||||
ASSERT (Context != NULL);
|
||||
|
||||
NumSegments = UeGetSegmentImageInfos (
|
||||
&Context->Ctx.Ue,
|
||||
&SegmentImageInfos,
|
||||
&SegmentIterSize
|
||||
);
|
||||
|
||||
ImageRecord = AllocatePool (
|
||||
sizeof (*ImageRecord)
|
||||
+ NumSegments * sizeof (*ImageRecord->Segments)
|
||||
);
|
||||
if (ImageRecord == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ImageRecord->Signature = UEFI_IMAGE_RECORD_SIGNATURE;
|
||||
InitializeListHead (&ImageRecord->Link);
|
||||
|
||||
SegmentImageInfo = *SegmentImageInfos;
|
||||
|
||||
RangeSize = UE_SEGMENT_SIZE (SegmentImageInfo);
|
||||
Permissions = UE_SEGMENT_PERMISSIONS (SegmentImageInfo);
|
||||
|
||||
ImageSizeRecord = RangeSize;
|
||||
NumRecordSegments = 0;
|
||||
|
||||
STATIC_ASSERT (
|
||||
OFFSET_OF (UE_SEGMENT, ImageInfo) == 0 &&
|
||||
OFFSET_OF (UE_SEGMENT, ImageInfo) == OFFSET_OF (UE_SEGMENT_XIP, ImageInfo),
|
||||
"Below's logic assumes the given layout."
|
||||
);
|
||||
|
||||
for (
|
||||
SegmentImageInfoPtr = (CONST UINT8 *) SegmentImageInfos + SegmentIterSize;
|
||||
SegmentImageInfoPtr < (CONST UINT8 *) SegmentImageInfos + (UINT32) SegmentIterSize * NumSegments;
|
||||
ImageSizeRecord += SegmentSize,
|
||||
SegmentImageInfoPtr += SegmentIterSize
|
||||
) {
|
||||
SegmentImageInfo = *(CONST UINT32 *) SegmentImageInfoPtr;
|
||||
|
||||
SegmentSize = UE_SEGMENT_SIZE (SegmentImageInfo);
|
||||
SegmentPermissions = UE_SEGMENT_PERMISSIONS (SegmentImageInfo);
|
||||
//
|
||||
// Skip Image segments with the same memory permissions as the current range
|
||||
// as they can be merged.
|
||||
//
|
||||
if (SegmentPermissions == Permissions) {
|
||||
RangeSize += SegmentSize;
|
||||
continue;
|
||||
}
|
||||
//
|
||||
// Create an Image record LoadTable for the current memory permission range.
|
||||
//
|
||||
RecordSegment = &ImageRecord->Segments[NumRecordSegments];
|
||||
RecordSegment->Size = RangeSize;
|
||||
RecordSegment->Attributes = InternalPermissionsToAttributes (Permissions);
|
||||
++NumRecordSegments;
|
||||
//
|
||||
// Start a Image record LoadTable with the current Image LoadTable.
|
||||
//
|
||||
RangeSize = SegmentSize;
|
||||
Permissions = SegmentPermissions;
|
||||
}
|
||||
//
|
||||
// Create an Image record LoadTable for the current memory permission range.
|
||||
//
|
||||
RecordSegment = &ImageRecord->Segments[NumRecordSegments];
|
||||
RecordSegment->Size = RangeSize;
|
||||
RecordSegment->Attributes = InternalPermissionsToAttributes (Permissions);
|
||||
++NumRecordSegments;
|
||||
|
||||
ImageAddress = UeLoaderGetImageAddress (&Context->Ctx.Ue);
|
||||
ImageSize = UeGetImageSize (&Context->Ctx.Ue);
|
||||
ASSERT (ImageSize == ImageSizeRecord);
|
||||
|
||||
ImageRecord->NumSegments = NumRecordSegments;
|
||||
ImageRecord->StartAddress = ImageAddress;
|
||||
ImageRecord->EndAddress = ImageAddress + ImageSize;
|
||||
//
|
||||
// Zero the remaining array entries to avoid uninitialised data.
|
||||
//
|
||||
ZeroMem (
|
||||
ImageRecord->Segments + NumRecordSegments,
|
||||
(NumSegments - NumRecordSegments) * sizeof (*ImageRecord->Segments)
|
||||
);
|
||||
|
||||
return ImageRecord;
|
||||
}
|
||||
|
||||
// LCOV_EXCL_START
|
||||
RETURN_STATUS
|
||||
UefiImageDebugLocateImageUe (
|
||||
OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context,
|
||||
IN UINTN Address
|
||||
)
|
||||
{
|
||||
ASSERT (Context != NULL);
|
||||
(VOID) Address;
|
||||
//
|
||||
// UE does not support this feature.
|
||||
//
|
||||
return RETURN_NOT_FOUND;
|
||||
}
|
||||
// LCOV_EXCL_STOP
|
||||
|
||||
RETURN_STATUS
|
||||
UefiImageGetFixedAddressUe (
|
||||
IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context,
|
||||
OUT UINT64 *Address
|
||||
)
|
||||
{
|
||||
BOOLEAN FixedAddress;
|
||||
|
||||
ASSERT (Context != NULL);
|
||||
ASSERT (Address != NULL);
|
||||
|
||||
FixedAddress = UeGetFixedAddress (&Context->Ctx.Ue);
|
||||
if (!FixedAddress) {
|
||||
return RETURN_NOT_FOUND;
|
||||
}
|
||||
|
||||
*Address = Context->Ctx.Ue.BaseAddress;
|
||||
return RETURN_SUCCESS;
|
||||
}
|
||||
|
||||
VOID
|
||||
UefiImageDebugPrintSegmentsUe (
|
||||
IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context
|
||||
)
|
||||
{
|
||||
RETURN_STATUS Status;
|
||||
CONST CHAR8 *Name;
|
||||
CONST UE_SEGMENT *Segments;
|
||||
UINT16 NumSegments;
|
||||
UINT16 SegmentIndex;
|
||||
UINT32 SegmentFileOffset;
|
||||
UINT32 SegmentImageAddress;
|
||||
CONST UE_SEGMENT_NAME *NameTable;
|
||||
UINT32 ImageSize;
|
||||
|
||||
NumSegments = UeGetSegments (&Context->Ctx.Ue, &Segments);
|
||||
|
||||
Status = UeGetSegmentNames (&Context->Ctx.Ue, &NameTable);
|
||||
if (RETURN_ERROR (Status)) {
|
||||
NameTable = NULL;
|
||||
}
|
||||
|
||||
SegmentFileOffset = Context->Ctx.Ue.SegmentsFileOffset;
|
||||
//
|
||||
// The first Image segment must begin the Image memory space.
|
||||
//
|
||||
SegmentImageAddress = 0;
|
||||
|
||||
for (SegmentIndex = 0; SegmentIndex < NumSegments; ++SegmentIndex) {
|
||||
if (NameTable != NULL) {
|
||||
Name = (CONST CHAR8 *)NameTable[SegmentIndex];
|
||||
} else {
|
||||
STATIC_ASSERT (
|
||||
sizeof (*NameTable) == sizeof ("Unknown"),
|
||||
"The following may cause prohibited memory accesses."
|
||||
);
|
||||
|
||||
Name = "Unknown";
|
||||
}
|
||||
|
||||
ImageSize = UE_SEGMENT_SIZE (Segments[SegmentIndex].ImageInfo);
|
||||
|
||||
DEBUG ((
|
||||
DEBUG_VERBOSE,
|
||||
" Segment - '%c%c%c%c%c%c%c%c'\n"
|
||||
" ImageAddress - 0x%08x\n"
|
||||
" ImageSize - 0x%08x\n"
|
||||
" FileOffset - 0x%08x\n"
|
||||
" FileSize - 0x%08x\n"
|
||||
" Permissions - 0x%08x\n",
|
||||
Name[0], Name[1], Name[2], Name[3], Name[4], Name[5], Name[6], Name[7],
|
||||
SegmentImageAddress,
|
||||
ImageSize,
|
||||
SegmentFileOffset,
|
||||
Segments[SegmentIndex].FileSize,
|
||||
UE_SEGMENT_PERMISSIONS (Segments[SegmentIndex].ImageInfo)
|
||||
));
|
||||
|
||||
SegmentImageAddress += ImageSize;
|
||||
SegmentFileOffset += Segments[SegmentIndex].FileSize;
|
||||
}
|
||||
}
|
||||
|
||||
GLOBAL_REMOVE_IF_UNREFERENCED CONST UEFI_IMAGE_FORMAT_SUPPORT mUeSupport = {
|
||||
UefiImageInitializeContextPreHashUe,
|
||||
UefiImageHashImageDefaultUe,
|
||||
UefiImageInitializeContextPostHashUe,
|
||||
UefiImageLoadImageUe,
|
||||
UefiImageImageIsInplaceUe,
|
||||
UefiImageLoadImageInplaceUe,
|
||||
UefiImageRelocateImageInplaceUe,
|
||||
UefiImageLoaderGetRuntimeContextSizeUe,
|
||||
UefiImageRelocateImageUe,
|
||||
UefiImageRuntimeRelocateImageUe,
|
||||
UefiImageDiscardSegmentsUe,
|
||||
UefiImageGetSymbolsPathUe,
|
||||
UefiImageGetFirstCertificateUe,
|
||||
UefiImageGetNextCertificateUe,
|
||||
UefiImageGetHiiDataRvaUe,
|
||||
UefiImageGetEntryPointAddressUe,
|
||||
UefiImageGetMachineUe,
|
||||
UefiImageGetSubsystemUe,
|
||||
UefiImageGetSegmentAlignmentUe,
|
||||
UefiImageGetImageSizeUe,
|
||||
UefiImageGetBaseAddressUe,
|
||||
UefiImageGetRelocsStrippedUe,
|
||||
UefiImageLoaderGetImageAddressUe,
|
||||
UefiImageLoaderGetDebugAddressUe,
|
||||
UefiImageLoaderGetImageRecordUe,
|
||||
UefiImageDebugLocateImageUe,
|
||||
UefiImageGetFixedAddressUe,
|
||||
UefiImageDebugPrintSegmentsUe
|
||||
};
|
|
@ -0,0 +1,16 @@
|
|||
/** @file
|
||||
UEFI Image Loader library implementation for UE Images.
|
||||
|
||||
Copyright (c) 2023, Marvin Häuser. All rights reserved.<BR>
|
||||
|
||||
SPDX-License-Identifier: BSD-3-Clause
|
||||
**/
|
||||
|
||||
#ifndef UE_SUPPORT_H
|
||||
#define UE_SUPPORT_H
|
||||
|
||||
#include "UefiImageFormat.h"
|
||||
|
||||
extern CONST UEFI_IMAGE_FORMAT_SUPPORT mUeSupport;
|
||||
|
||||
#endif // UE_SUPPORT_H
|
|
@ -20,6 +20,7 @@
|
|||
#include <Library/UefiImageLib.h>
|
||||
#include <Library/UefiImageExtraActionLib.h>
|
||||
|
||||
#include "UeSupport.h"
|
||||
#include "PeSupport.h"
|
||||
|
||||
STATIC_ASSERT (
|
||||
|
@ -39,34 +40,50 @@ STATIC_ASSERT (
|
|||
#define UEFI_IMAGE_FORMAT_SUPPORT_FV 0
|
||||
#endif
|
||||
|
||||
#define UEFI_IMAGE_SUPPORT \
|
||||
#define UEFI_IMAGE_FORMAT_SUPPORT \
|
||||
(UEFI_IMAGE_FORMAT_SUPPORT_NON_FV | UEFI_IMAGE_FORMAT_SUPPORT_FV)
|
||||
|
||||
#define FORMAT_EQ(FormatIndex, Format) \
|
||||
(UEFI_IMAGE_SUPPORT == (1U << (Format)) || \
|
||||
((UEFI_IMAGE_SUPPORT & (1U << (Format))) != 0 && \
|
||||
#define FORMAT_EQ(FormatIndex, Format) \
|
||||
(UEFI_IMAGE_FORMAT_SUPPORT == (1U << (Format)) || \
|
||||
((UEFI_IMAGE_FORMAT_SUPPORT & (1U << (Format))) != 0 && \
|
||||
(FormatIndex) == (Format)))
|
||||
|
||||
#define UEFI_IMAGE_EXEC(Result, FormatIndex, Func, ...) \
|
||||
do { \
|
||||
ASSERT ((FormatIndex) == UefiImageFormatPe); \
|
||||
Result = mPeSupport.Func (__VA_ARGS__); \
|
||||
if (FORMAT_EQ ((FormatIndex), UefiImageFormatUe)) { \
|
||||
ASSERT ((FormatIndex) == UefiImageFormatUe); \
|
||||
Result = mUeSupport.Func (__VA_ARGS__); \
|
||||
} else { \
|
||||
ASSERT ((FormatIndex) == UefiImageFormatPe); \
|
||||
Result = mPeSupport.Func (__VA_ARGS__); \
|
||||
} \
|
||||
} while (FALSE)
|
||||
|
||||
#define UEFI_IMAGE_EXEC_VOID(FormatIndex, Func, ...) \
|
||||
do { \
|
||||
ASSERT ((FormatIndex) == UefiImageFormatPe); \
|
||||
mPeSupport.Func (__VA_ARGS__); \
|
||||
#define UEFI_IMAGE_EXEC_VOID(FormatIndex, Func, ...) \
|
||||
do { \
|
||||
if (FORMAT_EQ ((FormatIndex), UefiImageFormatUe)) { \
|
||||
ASSERT ((FormatIndex) == UefiImageFormatUe); \
|
||||
mUeSupport.Func (__VA_ARGS__); \
|
||||
} else { \
|
||||
ASSERT ((FormatIndex) == UefiImageFormatPe); \
|
||||
mPeSupport.Func (__VA_ARGS__); \
|
||||
} \
|
||||
} while (FALSE)
|
||||
|
||||
STATIC_ASSERT (
|
||||
UefiImageFormatPe == UefiImageFormatMax - 1,
|
||||
UefiImageFormatMax == 2,
|
||||
"Support for more formats needs to be added above."
|
||||
);
|
||||
|
||||
#define FORMAT_SUPPORTED(Format, Source) \
|
||||
((UEFI_IMAGE_SUPPORT & (1U << (Format))) != 0 && \
|
||||
(mUefiImageSupportSource[Source] & (1U << (Format))) != 0)
|
||||
#define FORMAT_SUPPORTED(Format, Source) \
|
||||
((UEFI_IMAGE_FORMAT_SUPPORT & (1U << (Format))) != 0 && \
|
||||
(((Source) == UEFI_IMAGE_SOURCE_NON_FV && (UEFI_IMAGE_FORMAT_SUPPORT_NON_FV & (1U << (Format))) != 0) || \
|
||||
((Source) == UEFI_IMAGE_SOURCE_FV && (UEFI_IMAGE_FORMAT_SUPPORT_FV & (1U << (Format))) != 0)))
|
||||
|
||||
STATIC_ASSERT (
|
||||
UEFI_IMAGE_SOURCE_MAX == 3,
|
||||
"Support for more sources needs to be added above."
|
||||
);
|
||||
|
||||
STATIC
|
||||
RETURN_STATUS
|
||||
|
@ -99,12 +116,6 @@ UefiImageInitializeContextPreHash (
|
|||
IN UEFI_IMAGE_SOURCE Source
|
||||
)
|
||||
{
|
||||
CONST UINT8 mUefiImageSupportSource[UEFI_IMAGE_SOURCE_MAX] = {
|
||||
UEFI_IMAGE_FORMAT_SUPPORT_NON_FV,
|
||||
UEFI_IMAGE_FORMAT_SUPPORT_FV,
|
||||
UEFI_IMAGE_SUPPORT
|
||||
};
|
||||
|
||||
RETURN_STATUS Status;
|
||||
|
||||
#if (UEFI_IMAGE_FORMAT_SUPPORT_SOURCES & (1U << UEFI_IMAGE_SOURCE_NON_FV)) != 0
|
||||
|
@ -124,11 +135,23 @@ UefiImageInitializeContextPreHash (
|
|||
Status = RETURN_UNSUPPORTED;
|
||||
|
||||
STATIC_ASSERT (
|
||||
UefiImageFormatPe == UefiImageFormatMax - 1,
|
||||
UefiImageFormatUe == UefiImageFormatMax - 1,
|
||||
"Support for more formats needs to be added above."
|
||||
);
|
||||
|
||||
if (FORMAT_SUPPORTED (UefiImageFormatPe, Source)) {
|
||||
if (FORMAT_SUPPORTED (UefiImageFormatUe, Source)) {
|
||||
Status = InternalInitializeContextPreHash (
|
||||
Context,
|
||||
FileBuffer,
|
||||
FileSize,
|
||||
UefiImageFormatUe
|
||||
);
|
||||
if (!RETURN_ERROR (Status)) {
|
||||
Context->FormatIndex = UefiImageFormatUe;
|
||||
}
|
||||
}
|
||||
|
||||
if (RETURN_ERROR (Status) && FORMAT_SUPPORTED (UefiImageFormatPe, Source)) {
|
||||
Status = InternalInitializeContextPreHash (
|
||||
Context,
|
||||
FileBuffer,
|
||||
|
@ -137,7 +160,6 @@ UefiImageInitializeContextPreHash (
|
|||
);
|
||||
if (!RETURN_ERROR (Status)) {
|
||||
Context->FormatIndex = UefiImageFormatPe;
|
||||
return RETURN_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -50,6 +50,7 @@
|
|||
UefiImageOnlyNonFvLib|MdePkg/Library/BaseUefiImageLib/BaseUefiImageOnlyNonFvLib.inf
|
||||
UefiImageOnlyFvLib|MdePkg/Library/BaseUefiImageLib/BaseUefiImageOnlyFvLib.inf
|
||||
UefiImageAllLib|MdePkg/Library/BaseUefiImageLib/BaseUefiImageAllLib.inf
|
||||
UeImageLib|MdePkg/Library/BaseUeImageLib/BaseUeImageLib.inf
|
||||
|
||||
[LibraryClasses.common.USER_DEFINED, LibraryClasses.common.SEC, LibraryClasses.common.PEI_CORE, LibraryClasses.common.PEIM, LibraryClasses.common.SMM_CORE, LibraryClasses.common.MM_CORE_STANDALONE, LibraryClasses.common.DXE_SMM_DRIVER, LibraryClasses.common.MM_STANDALONE]
|
||||
UefiImageLib|MdePkg/Library/BaseUefiImageLib/BaseUefiImageOnlyFvLib.inf
|
||||
|
|
|
@ -960,6 +960,7 @@
|
|||
|
||||
## Include/Ppi/LoadFile.h
|
||||
gEfiPeiLoadFilePpiGuid = { 0xb9e0abfe, 0x5979, 0x4914, { 0x97, 0x7f, 0x6d, 0xee, 0x78, 0xc2, 0x78, 0xa6 } }
|
||||
gEfiPeiLoadFileWithHobPpiGuid = { 0x14c2d0d0, 0xccfd, 0x40e5, { 0xae, 0xa7, 0x57, 0x23, 0x58, 0xdd, 0xbf, 0xe8 } }
|
||||
|
||||
## Include/Ppi/Decompress.h
|
||||
gEfiPeiDecompressPpiGuid = { 0x1a36e4e7, 0xfab6, 0x476a, { 0x8e, 0x75, 0x69, 0x5a, 0x5, 0x76, 0xfd, 0xd7 } }
|
||||
|
@ -2311,13 +2312,21 @@
|
|||
# @Prompt Remove X permission from WX sections.
|
||||
gEfiMdePkgTokenSpaceGuid.PcdImageLoaderRemoveXForWX|FALSE|BOOLEAN|0x40001021
|
||||
|
||||
## Indicates the UEFI image file formats supported outside FVs.<BR><BR>
|
||||
## Indicates the UEFI image file formats supported outside FVs.
|
||||
# UE is experimental and not enabled by default.
|
||||
# For correct usage in a platform which opts in to UE support, this should
|
||||
# be overridden globally, not within individual modules.<BR><BR>
|
||||
# BIT0 - PE.<BR>
|
||||
# BIT1 - UE.<BR>
|
||||
# @Prompt Supported UEFI image file formats outside FVs.
|
||||
gEfiMdePkgTokenSpaceGuid.PcdUefiImageFormatSupportNonFv|0x01|UINT8|0x40002000
|
||||
|
||||
## Indicates the UEFI image file formats supported inside FVs.<BR><BR>
|
||||
## Indicates the UEFI image file formats supported inside FVs.
|
||||
# UE is experimental and not enabled by default.
|
||||
# For correct usage in a platform which opts in to UE support, this should
|
||||
# be overridden globally, not within individual modules.<BR><BR>
|
||||
# BIT0 - PE.<BR>
|
||||
# BIT1 - UE.<BR>
|
||||
# @Prompt Supported UEFI image file formats inside FVs.
|
||||
gEfiMdePkgTokenSpaceGuid.PcdUefiImageFormatSupportFv|0x01|UINT8|0x40002001
|
||||
|
||||
|
|
|
@ -58,6 +58,7 @@
|
|||
MdePkg/Library/PciSegmentLibSegmentInfo/DxeRuntimePciSegmentLibSegmentInfo.inf
|
||||
MdePkg/Library/BaseS3PciSegmentLib/BaseS3PciSegmentLib.inf
|
||||
MdePkg/Library/BaseArmTrngLibNull/BaseArmTrngLibNull.inf
|
||||
MdePkg/Library/BaseUeImageLib/BaseUeImageLib.inf
|
||||
MdePkg/Library/BasePeCoffLib2/BasePeCoffLib2.inf
|
||||
MdePkg/Library/BaseUefiImageLib/BaseUefiImageOnlyNonFvLib.inf
|
||||
MdePkg/Library/BaseUefiImageLib/BaseUefiImageOnlyFvLib.inf
|
||||
|
|
|
@ -62,9 +62,9 @@ DEFINE FW_BLOCKS = 0x400
|
|||
DEFINE CODE_BASE_ADDRESS = 0xFFC84000
|
||||
DEFINE CODE_SIZE = 0x0037C000
|
||||
DEFINE CODE_BLOCKS = 0x37C
|
||||
DEFINE FVMAIN_SIZE = 0x00345000
|
||||
DEFINE SECFV_OFFSET = 0x003C9000
|
||||
DEFINE SECFV_SIZE = 0x37000
|
||||
DEFINE FVMAIN_SIZE = 0x00342000
|
||||
DEFINE SECFV_OFFSET = 0x003C6000
|
||||
DEFINE SECFV_SIZE = 0x3a000
|
||||
!endif
|
||||
|
||||
SET gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFdBaseAddress = $(FW_BASE_ADDRESS)
|
||||
|
|
|
@ -485,6 +485,11 @@
|
|||
gEfiMdeModulePkgTokenSpaceGuid.PcdDxeNxMemoryProtectionPolicy|0xFFFFFFFFFFFFFF45
|
||||
!endif
|
||||
|
||||
#
|
||||
# Firmware volume is PE.
|
||||
#
|
||||
gEfiMdePkgTokenSpaceGuid.PcdUefiImageFormatSupportFv|0x01
|
||||
|
||||
################################################################################
|
||||
#
|
||||
# Pcd Dynamic Section - list of all EDK II PCD Entries defined by this Platform
|
||||
|
|
|
@ -168,6 +168,7 @@
|
|||
gEfiNonCcFvGuid = {0xae047c6d, 0xbce9, 0x426c, {0xae, 0x03, 0xa6, 0x8e, 0x3b, 0x8a, 0x04, 0x88}}
|
||||
gOvmfVariableGuid = {0x50bea1e5, 0xa2c5, 0x46e9, {0x9b, 0x3a, 0x59, 0x59, 0x65, 0x16, 0xb0, 0x0a}}
|
||||
gQemuFirmwareResourceHobGuid = {0x3cc47b04, 0x0d3e, 0xaa64, {0x06, 0xa6, 0x4b, 0xdc, 0x9a, 0x2c, 0x61, 0x19}}
|
||||
gUefiImageLoaderImageContextGuid = {0x05cc29cc, 0xfbdf, 0x4cc8, {0x98, 0x25, 0x71, 0x76, 0x08, 0x5b, 0x05, 0x01}}
|
||||
|
||||
[Ppis]
|
||||
# PPI whose presence in the PPI database signals that the TPM base address
|
||||
|
|
|
@ -593,6 +593,11 @@
|
|||
gEfiMdeModulePkgTokenSpaceGuid.PcdImageProtectionPolicy|0x0
|
||||
!endif
|
||||
|
||||
#
|
||||
# Firmware volume supports UE, and may require PE.
|
||||
#
|
||||
gEfiMdePkgTokenSpaceGuid.PcdUefiImageFormatSupportFv|0x03
|
||||
|
||||
################################################################################
|
||||
#
|
||||
# Pcd Dynamic Section - list of all EDK II PCD Entries defined by this Platform
|
||||
|
|
|
@ -402,57 +402,57 @@ FILE FV_IMAGE = 9E21FD93-9C72-4c15-8C4B-E77F1DB2D792 {
|
|||
|
||||
[Rule.Common.SEC]
|
||||
FILE SEC = $(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)
|
||||
}
|
||||
|
||||
[Rule.Common.PEI_CORE]
|
||||
FILE PEI_CORE = $(NAMED_GUID) {
|
||||
PE32 PE32 Align=Auto $(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)
|
||||
}
|
||||
|
||||
[Rule.Common.PEIM]
|
||||
FILE PEIM = $(NAMED_GUID) {
|
||||
PEI_DEPEX PEI_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex
|
||||
PE32 PE32 Align=Auto $(INF_OUTPUT)/$(MODULE_NAME).efi
|
||||
UI STRING="$(MODULE_NAME)" Optional
|
||||
VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
|
||||
PEI_DEPEX PEI_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex
|
||||
UE UE $(INF_OUTPUT)/$(MODULE_NAME).efi
|
||||
UI STRING="$(MODULE_NAME)" Optional
|
||||
VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
|
||||
}
|
||||
|
||||
[Rule.Common.DXE_CORE]
|
||||
FILE DXE_CORE = $(NAMED_GUID) {
|
||||
PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi
|
||||
UI STRING="$(MODULE_NAME)" Optional
|
||||
VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
|
||||
UE UE $(INF_OUTPUT)/$(MODULE_NAME).efi
|
||||
UI STRING="$(MODULE_NAME)" Optional
|
||||
VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
|
||||
}
|
||||
|
||||
[Rule.Common.DXE_DRIVER]
|
||||
FILE DRIVER = $(NAMED_GUID) {
|
||||
DXE_DEPEX DXE_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex
|
||||
PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi
|
||||
UI STRING="$(MODULE_NAME)" Optional
|
||||
VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
|
||||
RAW ACPI Optional |.acpi
|
||||
RAW ASL Optional |.aml
|
||||
DXE_DEPEX DXE_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex
|
||||
UE UE $(INF_OUTPUT)/$(MODULE_NAME).efi
|
||||
UI STRING="$(MODULE_NAME)" Optional
|
||||
VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
|
||||
RAW ACPI Optional |.acpi
|
||||
RAW ASL Optional |.aml
|
||||
}
|
||||
|
||||
[Rule.Common.DXE_RUNTIME_DRIVER]
|
||||
FILE DRIVER = $(NAMED_GUID) {
|
||||
DXE_DEPEX DXE_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex
|
||||
PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi
|
||||
UI STRING="$(MODULE_NAME)" Optional
|
||||
VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
|
||||
DXE_DEPEX DXE_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex
|
||||
UE UE $(INF_OUTPUT)/$(MODULE_NAME).efi
|
||||
UI STRING="$(MODULE_NAME)" Optional
|
||||
VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
|
||||
}
|
||||
|
||||
[Rule.Common.UEFI_DRIVER]
|
||||
FILE DRIVER = $(NAMED_GUID) {
|
||||
DXE_DEPEX DXE_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex
|
||||
PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi
|
||||
UI STRING="$(MODULE_NAME)" Optional
|
||||
VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
|
||||
DXE_DEPEX DXE_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex
|
||||
UE UE $(INF_OUTPUT)/$(MODULE_NAME).efi
|
||||
UI STRING="$(MODULE_NAME)" Optional
|
||||
VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
|
||||
}
|
||||
|
||||
[Rule.Common.UEFI_DRIVER.BINARY]
|
||||
|
@ -465,14 +465,14 @@ FILE FV_IMAGE = 9E21FD93-9C72-4c15-8C4B-E77F1DB2D792 {
|
|||
|
||||
[Rule.Common.UEFI_APPLICATION]
|
||||
FILE APPLICATION = $(NAMED_GUID) {
|
||||
PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi
|
||||
UI STRING="$(MODULE_NAME)" Optional
|
||||
VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
|
||||
UE UE $(INF_OUTPUT)/$(MODULE_NAME).efi
|
||||
UI STRING="$(MODULE_NAME)" Optional
|
||||
VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
|
||||
}
|
||||
|
||||
[Rule.Common.UEFI_APPLICATION.BINARY]
|
||||
FILE APPLICATION = $(NAMED_GUID) {
|
||||
PE32 PE32 |.efi
|
||||
UE UE |.efi
|
||||
UI STRING="$(MODULE_NAME)" Optional
|
||||
VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
|
||||
}
|
||||
|
@ -484,15 +484,15 @@ FILE FV_IMAGE = 9E21FD93-9C72-4c15-8C4B-E77F1DB2D792 {
|
|||
|
||||
[Rule.Common.SMM_CORE]
|
||||
FILE SMM_CORE = $(NAMED_GUID) {
|
||||
PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi
|
||||
UI STRING="$(MODULE_NAME)" Optional
|
||||
VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
|
||||
UE UE $(INF_OUTPUT)/$(MODULE_NAME).efi
|
||||
UI STRING="$(MODULE_NAME)" Optional
|
||||
VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
|
||||
}
|
||||
|
||||
[Rule.Common.DXE_SMM_DRIVER]
|
||||
FILE SMM = $(NAMED_GUID) {
|
||||
SMM_DEPEX SMM_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex
|
||||
PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi
|
||||
UI STRING="$(MODULE_NAME)" Optional
|
||||
VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
|
||||
SMM_DEPEX SMM_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex
|
||||
UE UE $(INF_OUTPUT)/$(MODULE_NAME).efi
|
||||
UI STRING="$(MODULE_NAME)" Optional
|
||||
VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
|
||||
}
|
||||
|
|
|
@ -564,6 +564,11 @@
|
|||
gEfiMdePkgTokenSpaceGuid.PcdControlFlowEnforcementPropertyMask|0x1
|
||||
gEfiMdeModulePkgTokenSpaceGuid.PcdImageProtectionPolicy|0x00000003
|
||||
|
||||
#
|
||||
# Firmware volume supports UE, and may require PE.
|
||||
#
|
||||
gEfiMdePkgTokenSpaceGuid.PcdUefiImageFormatSupportFv|0x03
|
||||
|
||||
[PcdsFixedAtBuild.IA32]
|
||||
#
|
||||
# The NumberOfPages values below are ad-hoc. They are updated sporadically at
|
||||
|
|
|
@ -305,7 +305,7 @@ INF SecurityPkg/Hash2DxeCrypto/Hash2DxeCrypto.inf
|
|||
#
|
||||
!if $(E1000_ENABLE)
|
||||
FILE DRIVER = 5D695E11-9B3F-4b83-B25F-4A8D5D69BE07 {
|
||||
SECTION PE32 = Intel3.5/EFIX64/E3522X2.EFI
|
||||
SECTION UE = Intel3.5/EFIX64/E3522X2.EFI
|
||||
}
|
||||
!endif
|
||||
!include NetworkPkg/Network.fdf.inc
|
||||
|
@ -405,57 +405,57 @@ FILE FV_IMAGE = 9E21FD93-9C72-4c15-8C4B-E77F1DB2D792 {
|
|||
|
||||
[Rule.Common.SEC]
|
||||
FILE SEC = $(NAMED_GUID) {
|
||||
PE32 PE32 Align=Auto $(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)
|
||||
}
|
||||
|
||||
[Rule.Common.PEI_CORE]
|
||||
FILE PEI_CORE = $(NAMED_GUID) {
|
||||
PE32 PE32 Align=Auto $(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)
|
||||
}
|
||||
|
||||
[Rule.Common.PEIM]
|
||||
FILE PEIM = $(NAMED_GUID) {
|
||||
PEI_DEPEX PEI_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex
|
||||
PE32 PE32 Align=Auto $(INF_OUTPUT)/$(MODULE_NAME).efi
|
||||
UI STRING="$(MODULE_NAME)" Optional
|
||||
VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
|
||||
PEI_DEPEX PEI_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex
|
||||
UE UE $(INF_OUTPUT)/$(MODULE_NAME).efi
|
||||
UI STRING="$(MODULE_NAME)" Optional
|
||||
VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
|
||||
}
|
||||
|
||||
[Rule.Common.DXE_CORE]
|
||||
FILE DXE_CORE = $(NAMED_GUID) {
|
||||
PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi
|
||||
UI STRING="$(MODULE_NAME)" Optional
|
||||
VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
|
||||
UE UE $(INF_OUTPUT)/$(MODULE_NAME).efi
|
||||
UI STRING="$(MODULE_NAME)" Optional
|
||||
VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
|
||||
}
|
||||
|
||||
[Rule.Common.DXE_DRIVER]
|
||||
FILE DRIVER = $(NAMED_GUID) {
|
||||
DXE_DEPEX DXE_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex
|
||||
PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi
|
||||
UI STRING="$(MODULE_NAME)" Optional
|
||||
VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
|
||||
RAW ACPI Optional |.acpi
|
||||
RAW ASL Optional |.aml
|
||||
DXE_DEPEX DXE_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex
|
||||
UE UE $(INF_OUTPUT)/$(MODULE_NAME).efi
|
||||
UI STRING="$(MODULE_NAME)" Optional
|
||||
VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
|
||||
RAW ACPI Optional |.acpi
|
||||
RAW ASL Optional |.aml
|
||||
}
|
||||
|
||||
[Rule.Common.DXE_RUNTIME_DRIVER]
|
||||
FILE DRIVER = $(NAMED_GUID) {
|
||||
DXE_DEPEX DXE_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex
|
||||
PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi
|
||||
UI STRING="$(MODULE_NAME)" Optional
|
||||
VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
|
||||
DXE_DEPEX DXE_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex
|
||||
UE UE $(INF_OUTPUT)/$(MODULE_NAME).efi
|
||||
UI STRING="$(MODULE_NAME)" Optional
|
||||
VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
|
||||
}
|
||||
|
||||
[Rule.Common.UEFI_DRIVER]
|
||||
FILE DRIVER = $(NAMED_GUID) {
|
||||
DXE_DEPEX DXE_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex
|
||||
PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi
|
||||
UI STRING="$(MODULE_NAME)" Optional
|
||||
VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
|
||||
DXE_DEPEX DXE_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex
|
||||
UE UE $(INF_OUTPUT)/$(MODULE_NAME).efi
|
||||
UI STRING="$(MODULE_NAME)" Optional
|
||||
VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
|
||||
}
|
||||
|
||||
[Rule.Common.UEFI_DRIVER.BINARY]
|
||||
|
@ -468,14 +468,14 @@ FILE FV_IMAGE = 9E21FD93-9C72-4c15-8C4B-E77F1DB2D792 {
|
|||
|
||||
[Rule.Common.UEFI_APPLICATION]
|
||||
FILE APPLICATION = $(NAMED_GUID) {
|
||||
PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi
|
||||
UI STRING="$(MODULE_NAME)" Optional
|
||||
VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
|
||||
UE UE $(INF_OUTPUT)/$(MODULE_NAME).efi
|
||||
UI STRING="$(MODULE_NAME)" Optional
|
||||
VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
|
||||
}
|
||||
|
||||
[Rule.Common.UEFI_APPLICATION.BINARY]
|
||||
FILE APPLICATION = $(NAMED_GUID) {
|
||||
PE32 PE32 |.efi
|
||||
UE UE |.efi
|
||||
UI STRING="$(MODULE_NAME)" Optional
|
||||
VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
|
||||
}
|
||||
|
@ -487,15 +487,15 @@ FILE FV_IMAGE = 9E21FD93-9C72-4c15-8C4B-E77F1DB2D792 {
|
|||
|
||||
[Rule.Common.SMM_CORE]
|
||||
FILE SMM_CORE = $(NAMED_GUID) {
|
||||
PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi
|
||||
UI STRING="$(MODULE_NAME)" Optional
|
||||
VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
|
||||
UE UE $(INF_OUTPUT)/$(MODULE_NAME).efi
|
||||
UI STRING="$(MODULE_NAME)" Optional
|
||||
VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
|
||||
}
|
||||
|
||||
[Rule.Common.DXE_SMM_DRIVER]
|
||||
FILE SMM = $(NAMED_GUID) {
|
||||
SMM_DEPEX SMM_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex
|
||||
PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi
|
||||
UI STRING="$(MODULE_NAME)" Optional
|
||||
VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
|
||||
SMM_DEPEX SMM_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex
|
||||
UE UE $(INF_OUTPUT)/$(MODULE_NAME).efi
|
||||
UI STRING="$(MODULE_NAME)" Optional
|
||||
VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
|
||||
}
|
||||
|
|
|
@ -619,6 +619,11 @@
|
|||
gEfiMdePkgTokenSpaceGuid.PcdImageLoaderAllowMisalignedOffset|TRUE
|
||||
!endif
|
||||
|
||||
#
|
||||
# Firmware volume supports UE, and may require PE.
|
||||
#
|
||||
gEfiMdePkgTokenSpaceGuid.PcdUefiImageFormatSupportFv|0x03
|
||||
|
||||
################################################################################
|
||||
#
|
||||
# Pcd Dynamic Section - list of all EDK II PCD Entries defined by this Platform
|
||||
|
|
|
@ -336,7 +336,7 @@ INF SecurityPkg/Hash2DxeCrypto/Hash2DxeCrypto.inf
|
|||
#
|
||||
!if $(E1000_ENABLE)
|
||||
FILE DRIVER = 5D695E11-9B3F-4b83-B25F-4A8D5D69BE07 {
|
||||
SECTION PE32 = Intel3.5/EFIX64/E3522X2.EFI
|
||||
SECTION UE = Intel3.5/EFIX64/E3522X2.EFI
|
||||
}
|
||||
!endif
|
||||
!include NetworkPkg/Network.fdf.inc
|
||||
|
@ -443,57 +443,57 @@ FILE FV_IMAGE = 9E21FD93-9C72-4c15-8C4B-E77F1DB2D792 {
|
|||
|
||||
[Rule.Common.SEC]
|
||||
FILE SEC = $(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)
|
||||
}
|
||||
|
||||
[Rule.Common.PEI_CORE]
|
||||
FILE PEI_CORE = $(NAMED_GUID) {
|
||||
PE32 PE32 Align=Auto $(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)
|
||||
}
|
||||
|
||||
[Rule.Common.PEIM]
|
||||
FILE PEIM = $(NAMED_GUID) {
|
||||
PEI_DEPEX PEI_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex
|
||||
PE32 PE32 Align=Auto $(INF_OUTPUT)/$(MODULE_NAME).efi
|
||||
UI STRING="$(MODULE_NAME)" Optional
|
||||
VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
|
||||
PEI_DEPEX PEI_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex
|
||||
UE UE $(INF_OUTPUT)/$(MODULE_NAME).efi
|
||||
UI STRING="$(MODULE_NAME)" Optional
|
||||
VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
|
||||
}
|
||||
|
||||
[Rule.Common.DXE_CORE]
|
||||
FILE DXE_CORE = $(NAMED_GUID) {
|
||||
PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi
|
||||
UI STRING="$(MODULE_NAME)" Optional
|
||||
VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
|
||||
UE UE $(INF_OUTPUT)/$(MODULE_NAME).efi
|
||||
UI STRING="$(MODULE_NAME)" Optional
|
||||
VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
|
||||
}
|
||||
|
||||
[Rule.Common.DXE_DRIVER]
|
||||
FILE DRIVER = $(NAMED_GUID) {
|
||||
DXE_DEPEX DXE_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex
|
||||
PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi
|
||||
UI STRING="$(MODULE_NAME)" Optional
|
||||
VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
|
||||
RAW ACPI Optional |.acpi
|
||||
RAW ASL Optional |.aml
|
||||
DXE_DEPEX DXE_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex
|
||||
UE UE $(INF_OUTPUT)/$(MODULE_NAME).efi
|
||||
UI STRING="$(MODULE_NAME)" Optional
|
||||
VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
|
||||
RAW ACPI Optional |.acpi
|
||||
RAW ASL Optional |.aml
|
||||
}
|
||||
|
||||
[Rule.Common.DXE_RUNTIME_DRIVER]
|
||||
FILE DRIVER = $(NAMED_GUID) {
|
||||
DXE_DEPEX DXE_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex
|
||||
PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi
|
||||
UI STRING="$(MODULE_NAME)" Optional
|
||||
VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
|
||||
DXE_DEPEX DXE_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex
|
||||
UE UE $(INF_OUTPUT)/$(MODULE_NAME).efi
|
||||
UI STRING="$(MODULE_NAME)" Optional
|
||||
VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
|
||||
}
|
||||
|
||||
[Rule.Common.UEFI_DRIVER]
|
||||
FILE DRIVER = $(NAMED_GUID) {
|
||||
DXE_DEPEX DXE_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex
|
||||
PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi
|
||||
UI STRING="$(MODULE_NAME)" Optional
|
||||
VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
|
||||
DXE_DEPEX DXE_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex
|
||||
UE UE $(INF_OUTPUT)/$(MODULE_NAME).efi
|
||||
UI STRING="$(MODULE_NAME)" Optional
|
||||
VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
|
||||
}
|
||||
|
||||
[Rule.Common.UEFI_DRIVER.BINARY]
|
||||
|
@ -506,14 +506,14 @@ FILE FV_IMAGE = 9E21FD93-9C72-4c15-8C4B-E77F1DB2D792 {
|
|||
|
||||
[Rule.Common.UEFI_APPLICATION]
|
||||
FILE APPLICATION = $(NAMED_GUID) {
|
||||
PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi
|
||||
UI STRING="$(MODULE_NAME)" Optional
|
||||
VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
|
||||
UE UE $(INF_OUTPUT)/$(MODULE_NAME).efi
|
||||
UI STRING="$(MODULE_NAME)" Optional
|
||||
VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
|
||||
}
|
||||
|
||||
[Rule.Common.UEFI_APPLICATION.BINARY]
|
||||
FILE APPLICATION = $(NAMED_GUID) {
|
||||
PE32 PE32 |.efi
|
||||
UE UE |.efi
|
||||
UI STRING="$(MODULE_NAME)" Optional
|
||||
VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
|
||||
}
|
||||
|
@ -525,15 +525,15 @@ FILE FV_IMAGE = 9E21FD93-9C72-4c15-8C4B-E77F1DB2D792 {
|
|||
|
||||
[Rule.Common.SMM_CORE]
|
||||
FILE SMM_CORE = $(NAMED_GUID) {
|
||||
PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi
|
||||
UI STRING="$(MODULE_NAME)" Optional
|
||||
VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
|
||||
UE UE $(INF_OUTPUT)/$(MODULE_NAME).efi
|
||||
UI STRING="$(MODULE_NAME)" Optional
|
||||
VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
|
||||
}
|
||||
|
||||
[Rule.Common.DXE_SMM_DRIVER]
|
||||
FILE SMM = $(NAMED_GUID) {
|
||||
SMM_DEPEX SMM_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex
|
||||
PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi
|
||||
UI STRING="$(MODULE_NAME)" Optional
|
||||
VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
|
||||
SMM_DEPEX SMM_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex
|
||||
UE UE $(INF_OUTPUT)/$(MODULE_NAME).efi
|
||||
UI STRING="$(MODULE_NAME)" Optional
|
||||
VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
|
||||
}
|
||||
|
|
|
@ -150,10 +150,20 @@ getEntryPointOfFfsFileLoopForSections:
|
|||
jmp getEntryPointOfFfsFileLoopForSections
|
||||
|
||||
getEntryPointOfFfsFileFoundPe32Section:
|
||||
add eax, 4 ; EAX = Start of PE32 image
|
||||
add eax, 4 ; EAX = Start of PE or UE image
|
||||
|
||||
cmp word [eax], 'MZ'
|
||||
je getEntryPointOfFfsFileFoundPeFile
|
||||
|
||||
cmp word [eax], 'UE'
|
||||
jne getEntryPointOfFfsFileErrorReturn
|
||||
|
||||
; *EntryPoint = (VOID *)((UINTN)UeData + UeHdr.EntryPointAddress)
|
||||
mov ebx, dword [eax + 0x4]
|
||||
add eax, ebx
|
||||
jmp getEntryPointOfFfsFileReturn
|
||||
|
||||
getEntryPointOfFfsFileFoundPeFile:
|
||||
movzx ebx, word [eax + 0x3c]
|
||||
add ebx, eax
|
||||
|
||||
|
@ -171,4 +181,3 @@ getEntryPointOfFfsFileErrorReturn:
|
|||
|
||||
getEntryPointOfFfsFileReturn:
|
||||
OneTimeCallRet GetEntryPointOfFfsFile
|
||||
|
||||
|
|
|
@ -28,13 +28,13 @@ LoadUefiImage (
|
|||
OUT EFI_PHYSICAL_ADDRESS *EntryPoint
|
||||
)
|
||||
{
|
||||
RETURN_STATUS Status;
|
||||
UEFI_IMAGE_LOADER_IMAGE_CONTEXT ImageContext;
|
||||
UINT32 ImageSize;
|
||||
UINT32 ImageAlignment;
|
||||
UINT32 BufferPages;
|
||||
UINT32 BufferSize;
|
||||
VOID *Buffer;
|
||||
RETURN_STATUS Status;
|
||||
UEFI_IMAGE_LOADER_IMAGE_CONTEXT ImageContext;
|
||||
UINT32 ImageSize;
|
||||
UINT32 ImageAlignment;
|
||||
UINT32 BufferPages;
|
||||
UINT32 BufferSize;
|
||||
VOID *Buffer;
|
||||
|
||||
Status = UefiImageInitializeContext (
|
||||
&ImageContext,
|
||||
|
|
|
@ -508,6 +508,11 @@
|
|||
!endif
|
||||
!endif
|
||||
|
||||
#
|
||||
# Firmware volume supports UE, and may require PE.
|
||||
#
|
||||
gEfiMdePkgTokenSpaceGuid.PcdUefiImageFormatSupportFv|0x03
|
||||
|
||||
[PcdsPatchableInModule.X64]
|
||||
!if $(NETWORK_DRIVER_ENABLE) == TRUE
|
||||
gEfiNetworkPkgTokenSpaceGuid.PcdAllowHttpConnections|TRUE
|
||||
|
|
|
@ -372,7 +372,7 @@ INF ShellPkg/Application/Shell/Shell.inf
|
|||
[Rule.Common.DXE_DRIVER]
|
||||
FILE DRIVER = $(NAMED_GUID) {
|
||||
DXE_DEPEX DXE_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex
|
||||
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)
|
||||
}
|
||||
|
@ -380,21 +380,21 @@ INF ShellPkg/Application/Shell/Shell.inf
|
|||
[Rule.Common.DXE_RUNTIME_DRIVER]
|
||||
FILE DRIVER = $(NAMED_GUID) {
|
||||
DXE_DEPEX DXE_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex
|
||||
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)
|
||||
}
|
||||
[Rule.Common.DXE_SMM_DRIVER]
|
||||
FILE SMM = $(NAMED_GUID) {
|
||||
SMM_DEPEX SMM_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex
|
||||
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)
|
||||
}
|
||||
|
||||
[Rule.Common.SMM_CORE]
|
||||
FILE SMM_CORE = $(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)
|
||||
}
|
||||
|
@ -402,7 +402,7 @@ INF ShellPkg/Application/Shell/Shell.inf
|
|||
[Rule.Common.UEFI_DRIVER]
|
||||
FILE DRIVER = $(NAMED_GUID) {
|
||||
DXE_DEPEX DXE_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex
|
||||
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)
|
||||
}
|
||||
|
@ -410,21 +410,21 @@ INF ShellPkg/Application/Shell/Shell.inf
|
|||
[Rule.Common.UEFI_DRIVER.BINARY]
|
||||
FILE DRIVER = $(NAMED_GUID) {
|
||||
DXE_DEPEX DXE_DEPEX Optional |.depex
|
||||
PE32 PE32 |.efi
|
||||
UE UE |.efi
|
||||
UI STRING="$(MODULE_NAME)" Optional
|
||||
VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
|
||||
}
|
||||
|
||||
[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)
|
||||
}
|
||||
|
||||
[Rule.Common.UEFI_APPLICATION.BINARY]
|
||||
FILE APPLICATION = $(NAMED_GUID) {
|
||||
PE32 PE32 |.efi
|
||||
UE UE |.efi
|
||||
UI STRING="$(MODULE_NAME)" Optional
|
||||
VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
|
||||
}
|
||||
|
@ -447,7 +447,7 @@ INF ShellPkg/Application/Shell/Shell.inf
|
|||
|
||||
[Rule.Common.UEFI_APPLICATION.UI]
|
||||
FILE APPLICATION = $(NAMED_GUID) {
|
||||
PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi
|
||||
UE UE $(INF_OUTPUT)/$(MODULE_NAME).efi
|
||||
UI STRING="Enter Setup"
|
||||
VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue