UE: Support UE generation and consumption.

This commit is contained in:
Mikhail Krichanov 2024-07-01 12:18:06 +03:00
parent 683f4b85cb
commit 21327695a0
72 changed files with 5567 additions and 398 deletions

View File

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

View File

@ -166,6 +166,11 @@
gEmbeddedTokenSpaceGuid.PcdPrePiCpuIoSize|16
gArmTokenSpaceGuid.PcdMonitorConduitHvc|TRUE
#
# Firmware volume supports UE, and may require PE.
#
gEfiMdePkgTokenSpaceGuid.PcdUefiImageFormatSupportFv|0x03
[PcdsPatchableInModule.common]
#

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

1118
BaseTools/ImageTool/UeEmit.c Normal file

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View 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)

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -94,6 +94,7 @@
## PRODUCES
## CONSUMES
gEfiPeiLoadFilePpiGuid
gEfiPeiLoadFileWithHobPpiGuid
gEfiPeiSecurity2PpiGuid ## NOTIFY
gEfiTemporaryRamSupportPpiGuid ## SOMETIMES_CONSUMES
gEfiTemporaryRamDonePpiGuid ## SOMETIMES_CONSUMES

View File

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

View File

@ -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);
//

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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