Drop premature UE support

This commit is contained in:
Marvin Häuser 2023-04-08 21:06:04 +02:00
parent cd0e8aa6ad
commit 2f91fddf99
15 changed files with 5 additions and 3764 deletions

View File

@ -6,8 +6,8 @@
PROJECT = ImageTool
OBJS = $(PROJECT).o
OBJS += Image.o PeEmit.o PeScan.o UeEmit.o ElfScan.o BinEmit.o
OBJS += BaseAlignment.o BaseBitOverflow.o UeImageLib.o UefiImageExtraActionLib.o
OBJS += Image.o PeEmit.o PeScan.o ElfScan.o BinEmit.o
OBJS += BaseAlignment.o BaseBitOverflow.o UefiImageExtraActionLib.o
OBJS += PeCoffInit.o PeCoffInfo.o PeCoffLoad.o PeCoffRelocate.o PeCoffHii.o PeCoffDebug.o
DEBUG = 1
@ -23,8 +23,7 @@ CFLAGS += -include Pcds.h -Werror
VPATH += ../../MdePkg/Library/BaseOverflowLib:$\
../../MdePkg/Library/BasePeCoffLib2:$\
../../MdePkg/Library/BaseUefiImageExtraActionLibNull:$\
../../MdePkg/Library/BaseUeImageLib
../../MdePkg/Library/BaseUefiImageExtraActionLibNull
Tools: Tool32 Tool64

View File

@ -13,70 +13,6 @@
image_tool_image_info_t mImageInfo;
static
RETURN_STATUS
PeToUe (
IN const char *PeName,
IN const char *UeName
)
{
void *Pe;
uint32_t PeSize;
void *Ue;
uint32_t UeSize;
bool Result;
image_tool_image_info_t Image;
assert (PeName != NULL);
assert (UeName != NULL);
Pe = UserReadFile (PeName, &PeSize);
if (Pe == NULL) {
return RETURN_ABORTED;
}
Result = ToolContextConstructPe (&Image, Pe, PeSize, NULL);
free (Pe);
Pe = NULL;
if (!Result) {
return RETURN_ABORTED;
}
Result = CheckToolImage (&Image);
if (!Result) {
ToolImageDestruct (&Image);
return RETURN_ABORTED;
}
Result = ImageConvertToXip (&Image);
if (!Result) {
ToolImageDestruct (&Image);
return RETURN_ABORTED;
}
Ue = ToolImageEmitUe (&Image, &UeSize);
if (Ue == NULL) {
ToolImageDestruct (&Image);
return RETURN_ABORTED;
}
ToolImageDestruct (&Image);
/*UE_LOADER_IMAGE_CONTEXT UeContext;
RETURN_STATUS Status = UeInitializeContext(&UeContext, Ue, UeSize);
printf("UE status - %llu\n", Status);*/
UserWriteFile (UeName, Ue, UeSize);
free (Ue);
Ue = NULL;
return RETURN_SUCCESS;
}
static
RETURN_STATUS
@ -533,19 +469,6 @@ int main (int argc, const char *argv[])
raise ();
return -1;
}
} else if (strcmp (argv[1], "PeToUe") == 0) {
if (argc < 4) {
fprintf (stderr, "ImageTool: Command arguments are missing\n");
fprintf (stderr, " Usage: ImageTool PeToUe InputFile OutputFile\n");
raise ();
return -1;
}
Status = PeToUe (argv[2], argv[3]);
if (RETURN_ERROR (Status)) {
raise ();
return -1;
}
}
return 0;

View File

@ -12,9 +12,7 @@
#include <assert.h>
#include <IndustryStandard/PeImage2.h>
#include <IndustryStandard/UeImage.h>
#include <Library/PeCoffLib2.h>
#include <Library/UeImageLib.h>
#include <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/BaseOverflowLib.h>
@ -150,12 +148,6 @@ ImageConvertToXip (
image_tool_image_info_t *Image
);
void *
ToolImageEmitUe (
const image_tool_image_info_t *Image,
uint32_t *FileSize
);
bool
ToolContextConstructPe (
OUT image_tool_image_info_t *Image,

View File

@ -17,11 +17,10 @@ OUT_DIR = .\Windows_$(INFIX)
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 PeEmit.obj PeScan.obj UeEmit.obj ElfScan.obj BinEmit.obj
OBJECTS = $(OBJECTS) {$(OV)}BaseAlignment.obj BaseBitOverflow.obj {$(UE)}UeImageLib.obj {$(UA)}UefiImageExtraActionLib.obj
OBJECTS = ImageTool.obj Image.obj PeEmit.obj PeScan.obj ElfScan.obj BinEmit.obj
OBJECTS = $(OBJECTS) {$(OV)}BaseAlignment.obj BaseBitOverflow.obj {$(UA)}UefiImageExtraActionLib.obj
OBJECTS = $(OBJECTS) {$(PE)}PeCoffInit.obj PeCoffInfo.obj PeCoffRelocate.obj PeCoffLoad.obj PeCoffHii.obj PeCoffDebug.obj
BASE = $(UDK_PATH)\MdePkg\Library\BaseLib
@ -74,10 +73,6 @@ cleanall:
$(CC) -c $(CFLAGS) $(INC) /FI Pcds.h $< -Fo$@
@move $@ $(OUT_DIR)\
{$(UE)}.c.obj :
$(CC) -c $(CFLAGS) $(INC) /FI Pcds.h $< -Fo$@
@move $@ $(OUT_DIR)\
{$(UA)}.c.obj :
$(CC) -c $(CFLAGS) $(INC) $< -Fo$@
@move $@ $(OUT_DIR)\

View File

@ -1,892 +0,0 @@
/** @file
Copyright (c) 2021, Marvin Häuser. All rights reserved.
SPDX-License-Identifier: BSD-3-Clause
**/
#include "ImageTool.h"
// FIXME: NumSegments <= MAX_UINT8
typedef struct {
uint8_t NumSections;
uint32_t HeaderSize;
uint32_t SegmentHeadersSize;
uint32_t SectionHeadersSize;
} image_tool_emit_ue_hdr_info_t;
typedef struct {
const image_tool_image_info_t *Image;
image_tool_emit_ue_hdr_info_t HdrInfo;
uint32_t SegmentsSize;
uint8_t SegmentsEndPadding;
uint32_t SectionsSize;
uint32_t UnsignedFileSize;
uint32_t RelocTableSize;
uint32_t HiiTableSize;
uint32_t DebugTableSize;
} image_tool_ue_emit_context_t;
static
bool
EmitUeGetHeaderSizes (
const image_tool_image_info_t *Image,
image_tool_emit_ue_hdr_info_t *HdrInfo
)
{
assert (Image != NULL);
assert (HdrInfo != NULL);
if (Image->RelocInfo.NumRelocs > 0) {
++HdrInfo->NumSections;
}
if (Image->HiiInfo.DataSize > 0) {
++HdrInfo->NumSections;
}
//
// A debug section can always be generated; make conditional based on tool arg.
//
++HdrInfo->NumSections;
HdrInfo->SegmentHeadersSize = (uint32_t)Image->SegmentInfo.NumSegments * sizeof (UE_SEGMENT);
HdrInfo->SectionHeadersSize = (uint32_t)HdrInfo->NumSections * sizeof (UE_SECTION);
HdrInfo->HeaderSize = sizeof (UE_HEADER)
+ HdrInfo->SegmentHeadersSize
+ HdrInfo->SectionHeadersSize;
return true;
}
static
bool
EmitUeGetSegmentsSize (
const image_tool_image_info_t *Image,
uint32_t *SegmentsSize
)
{
uint8_t Index;
assert (Image != NULL);
assert (SegmentsSize != NULL);
*SegmentsSize = 0;
for (Index = 0; Index < Image->SegmentInfo.NumSegments; ++Index) {
*SegmentsSize += Image->SegmentInfo.Segments[Index].DataSize;
}
return true;
}
static
bool
EmitUeGetRelocSectionSize (
const image_tool_image_info_t *Image,
uint32_t *RelocsSize
)
{
uint32_t RelocTableSize;
uint32_t BlockAddress;
uint32_t BlockSize;
uint32_t Index;
uint32_t RelocAddress;
assert (Image != NULL);
assert (RelocsSize != NULL);
if (Image->RelocInfo.NumRelocs == 0) {
*RelocsSize = 0;
return true;
}
assert (Image->RelocInfo.NumRelocs <= MAX_UINT32);
RelocTableSize = 0;
BlockAddress = (uint32_t)PAGE (Image->RelocInfo.Relocs[0].Target);
BlockSize = sizeof (UE_RELOCATION_BLOCK);
for (Index = 0; Index < Image->RelocInfo.NumRelocs; ++Index) {
RelocAddress = PAGE (Image->RelocInfo.Relocs[Index].Target);
if (RelocAddress != BlockAddress) {
BlockSize = ALIGN_VALUE (BlockSize, UE_RELOCATION_BLOCK_ALIGNMENT);
RelocTableSize += BlockSize;
BlockAddress = RelocAddress;
BlockSize = sizeof (UE_RELOCATION_BLOCK);
}
BlockSize += sizeof (UINT16);
}
RelocTableSize += BlockSize;
*RelocsSize = RelocTableSize;
return true;
}
static
bool
EmitUeGetHiiSectionSize (
const image_tool_image_info_t *Image,
uint32_t *HiiSize
)
{
assert (Image != NULL);
assert (HiiSize != NULL);
*HiiSize = Image->HiiInfo.DataSize;
return true;
}
static
bool
EmitUeGetDebugSectionSize (
const image_tool_image_info_t *Image,
uint32_t *DebugSize
)
{
assert (Image != NULL);
assert (DebugSize != NULL);
static_assert (
MAX_UINT8 <= (MAX_UINT32 - MAX_UINT8 - sizeof (UE_DEBUG_TABLE)) / sizeof (UE_SEGMENT_NAME),
"The following arithmetics may overflow."
);
*DebugSize = sizeof (UE_DEBUG_TABLE) + Image->SegmentInfo.NumSegments * sizeof (UE_SEGMENT_NAME);
if (Image->DebugInfo.SymbolsPath != NULL) {
assert (Image->DebugInfo.SymbolsPathLen <= MAX_UINT8);
*DebugSize += Image->DebugInfo.SymbolsPathLen;
}
return true;
}
static
bool
EmitUeGetSectionsSize (
image_tool_ue_emit_context_t *Context,
uint32_t *SectionsSize
)
{
const image_tool_image_info_t *Image;
bool Result;
uint32_t AlignedRelocTableSize;
bool Overflow;
uint32_t AlignedDebugTableSize;
uint32_t AlignedHiiTableSize;
assert (Context != NULL);
assert (SectionsSize != NULL);
Image = Context->Image;
Result = EmitUeGetRelocSectionSize (Image, &Context->RelocTableSize);
if (!Result) {
raise ();
return false;
}
Result = EmitUeGetDebugSectionSize (Image, &Context->DebugTableSize);
if (!Result) {
raise ();
return false;
}
Result = EmitUeGetHiiSectionSize (Image, &Context->HiiTableSize);
if (!Result) {
raise ();
return false;
}
Overflow = BaseOverflowAlignUpU32 (
Context->RelocTableSize,
UE_SECTION_ALIGNMENT,
&AlignedRelocTableSize
);
if (Overflow) {
raise ();
return false;
}
Overflow = BaseOverflowAlignUpU32 (
Context->DebugTableSize,
UE_SECTION_ALIGNMENT,
&AlignedDebugTableSize
);
if (Overflow) {
raise ();
return false;
}
Overflow = BaseOverflowAlignUpU32 (
Context->HiiTableSize,
UE_SECTION_ALIGNMENT,
&AlignedHiiTableSize
);
if (Overflow) {
raise ();
return false;
}
Overflow = BaseOverflowAddU32 (
AlignedRelocTableSize,
AlignedDebugTableSize,
SectionsSize
);
if (Overflow) {
raise ();
return false;
}
assert (IS_ALIGNED (*SectionsSize, UE_SECTION_ALIGNMENT));
Overflow = BaseOverflowAddU32 (
*SectionsSize,
AlignedHiiTableSize,
SectionsSize
);
if (Overflow) {
raise ();
return false;
}
assert (IS_ALIGNED (*SectionsSize, UE_SECTION_ALIGNMENT));
return true;
}
static
uint8_t
AlignmentToExponent (
uint64_t Alignment
)
{
uint8_t Index;
assert (IS_POW2 (Alignment));
for (Index = 0; Index < 64; ++Index) {
if ((Alignment & (1ULL << Index)) == Alignment) {
return Index;
}
}
return 0;
}
static
bool
ToolImageEmitUeSegmentHeaders (
const image_tool_ue_emit_context_t *Context,
uint8_t **Buffer,
uint32_t *BufferSize
)
{
const image_tool_image_info_t *Image;
uint16_t SegmentHeadersSize;
UE_SEGMENT *Segments;
uint8_t Index;
assert (Context != NULL);
assert (Buffer != NULL);
assert (BufferSize != NULL);
Image = Context->Image;
SegmentHeadersSize = (uint16_t)(Image->SegmentInfo.NumSegments * sizeof (UE_SEGMENT));
assert (SegmentHeadersSize <= *BufferSize);
Segments = (void *)*Buffer;
for (Index = 0; Index < Image->SegmentInfo.NumSegments; ++Index) {
// FIXME:
Image->SegmentInfo.Segments[Index].ImageSize = ALIGN_VALUE (Image->SegmentInfo.Segments[Index].ImageSize, Image->SegmentInfo.SegmentAlignment);
Segments[Index].ImageInfo = Image->SegmentInfo.Segments[Index].ImageSize;
if (!Image->SegmentInfo.Segments[Index].Read) {
Segments[Index].ImageInfo |= UE_SEGMENT_INFO_RP;
}
if (!Image->SegmentInfo.Segments[Index].Write) {
Segments[Index].ImageInfo |= UE_SEGMENT_INFO_RO;
}
if (!Image->SegmentInfo.Segments[Index].Execute) {
Segments[Index].ImageInfo |= UE_SEGMENT_INFO_XP;
}
assert (UE_SEGMENT_SIZE (Segments[Index].ImageInfo) == Image->SegmentInfo.Segments[Index].ImageSize);
Segments[Index].FileSize = Image->SegmentInfo.Segments[Index].DataSize;
}
*BufferSize -= SegmentHeadersSize;
*Buffer += SegmentHeadersSize;
assert (SegmentHeadersSize == Context->HdrInfo.SegmentHeadersSize);
return true;
}
static
bool
ToolImageEmitUeSectionHeaders (
const image_tool_ue_emit_context_t *Context,
uint8_t **Buffer,
uint32_t *BufferSize
)
{
uint32_t SectionHeadersSize;
UE_SECTION *Section;
uint32_t AlignedRelocTableSize;
uint32_t AlignedDebugTableSize;
uint32_t AlignedHiiTableSize;
assert (Context != NULL);
assert (Buffer != NULL);
assert (BufferSize != NULL);
SectionHeadersSize = 0;
if (Context->RelocTableSize > 0) {
assert (sizeof (UE_SECTION) <= *BufferSize);
Section = (void *)*Buffer;
AlignedRelocTableSize = ALIGN_VALUE (Context->RelocTableSize, UE_SECTION_ALIGNMENT);
Section->FileInfo = AlignedRelocTableSize;
Section->FileInfo |= UeSectionIdRelocTable;
assert (UE_SECTION_ID (Section->FileInfo) == UeSectionIdRelocTable);
assert (UE_SECTION_SIZE (Section->FileInfo) == AlignedRelocTableSize);
*BufferSize -= sizeof (UE_SECTION);
*Buffer += sizeof (UE_SECTION);
SectionHeadersSize += sizeof (UE_SECTION);
}
if (Context->DebugTableSize > 0) {
assert (sizeof (UE_SECTION) <= *BufferSize);
Section = (void *)*Buffer;
AlignedDebugTableSize = ALIGN_VALUE (Context->DebugTableSize, UE_SECTION_ALIGNMENT);
Section->FileInfo = AlignedDebugTableSize;
Section->FileInfo |= UeSectionIdDebugTable;
assert (UE_SECTION_ID (Section->FileInfo) == UeSectionIdDebugTable);
assert (UE_SECTION_SIZE (Section->FileInfo) == AlignedDebugTableSize);
*BufferSize -= sizeof (UE_SECTION);
*Buffer += sizeof (UE_SECTION);
SectionHeadersSize += sizeof (UE_SECTION);
}
if (Context->HiiTableSize > 0) {
assert (sizeof (UE_SECTION) <= *BufferSize);
Section = (void *)*Buffer;
AlignedHiiTableSize = ALIGN_VALUE (Context->HiiTableSize, UE_SECTION_ALIGNMENT);
Section->FileInfo = AlignedHiiTableSize;
Section->FileInfo |= UeSectionIdHiiTable;
assert (UE_SECTION_ID (Section->FileInfo) == UeSectionIdHiiTable);
assert (UE_SECTION_SIZE (Section->FileInfo) == AlignedHiiTableSize);
*BufferSize -= sizeof (UE_SECTION);
*Buffer += sizeof (UE_SECTION);
SectionHeadersSize += sizeof (UE_SECTION);
}
assert (Context->HdrInfo.SectionHeadersSize == SectionHeadersSize);
return true;
}
static
bool
ToolImageEmitUeHeader (
const image_tool_ue_emit_context_t *Context,
uint8_t **Buffer,
uint32_t *BufferSize
)
{
UE_HEADER *UeHdr;
const image_tool_image_info_t *Image;
uint8_t AlignmentExponent;
bool Result;
assert (Context != NULL);
assert (Buffer != NULL);
assert (BufferSize != NULL);
assert (sizeof(UE_HEADER) <= *BufferSize);
UeHdr = (void *)*Buffer;
UeHdr->Signature = UE_HEADER_SIGNATURE;
Image = Context->Image;
AlignmentExponent = AlignmentToExponent (Image->SegmentInfo.SegmentAlignment);
UeHdr->ImageInfo = AlignmentExponent;
if (Image->RelocInfo.RelocsStripped) {
UeHdr->ImageInfo |= UE_HEADER_FLAG_RELOCS_STRIPPED;
}
assert (UE_HEADER_ALIGNMENT (UeHdr->ImageInfo) == 1U << AlignmentExponent);
assert (Image->SegmentInfo.NumSegments > 0);
UeHdr->LastSegmentIndex = (UINT8)(Image->SegmentInfo.NumSegments - 1);
UeHdr->NumSections = Context->HdrInfo.NumSections;
UeHdr->Subsystem = (UINT8)Image->HeaderInfo.Subsystem;
UeHdr->Machine = (UINT8)Image->HeaderInfo.Machine;
UeHdr->PreferredAddress = Image->HeaderInfo.BaseAddress;
UeHdr->EntryPointAddress = Image->HeaderInfo.EntryPointAddress;
UeHdr->ImageInfo2 = Context->UnsignedFileSize;
assert (UeHdr->ImageInfo2 == UE_HEADER_UNSIGNED_SIZE (UeHdr->ImageInfo2));
assert (UeHdr->Reserved == 0);
STATIC_ASSERT (
OFFSET_OF (UE_HEADER, Segments) == sizeof (UE_HEADER),
"The following code needs to be updated to consider padding."
);
*BufferSize -= sizeof (UE_HEADER);
*Buffer += sizeof (UE_HEADER);
Result = ToolImageEmitUeSegmentHeaders (Context, Buffer, BufferSize);
if (!Result) {
return false;
}
Result = ToolImageEmitUeSectionHeaders (Context, Buffer, BufferSize);
if (!Result) {
return false;
}
return true;
}
static
bool
ToolImageEmitUeSegments (
const image_tool_ue_emit_context_t *Context,
uint8_t **Buffer,
uint32_t *BufferSize
)
{
const image_tool_image_info_t *Image;
uint32_t SegmentsSize;
uint8_t Index;
size_t DataSize;
assert (Context != NULL);
assert (Buffer != NULL);
assert (BufferSize != NULL);
Image = Context->Image;
SegmentsSize = 0;
for (Index = 0; Index < Image->SegmentInfo.NumSegments; ++Index) {
assert (Image->SegmentInfo.Segments[Index].DataSize <= *BufferSize);
DataSize = Image->SegmentInfo.Segments[Index].DataSize;
memmove (*Buffer, Image->SegmentInfo.Segments[Index].Data, DataSize);
*BufferSize -= DataSize;
*Buffer += DataSize;
SegmentsSize += DataSize;
}
assert (SegmentsSize == Context->SegmentsSize);
*BufferSize -= Context->SegmentsEndPadding;
*Buffer += Context->SegmentsEndPadding;
return true;
}
static
bool
ToolImageEmitUeRelocTable (
const image_tool_ue_emit_context_t *Context,
uint8_t **Buffer,
uint32_t *BufferSize
)
{
const image_tool_image_info_t *Image;
uint32_t RelocTableSize;
UE_RELOCATION_BLOCK *RelocBlock;
uint32_t BlockAddress;
uint32_t BlockNumRelocs;
uint32_t BlockSize;
uint32_t Index;
uint32_t RelocAddress;
uint32_t RelocTablePadding;
assert (Context != NULL);
assert (Buffer != NULL);
assert (BufferSize != NULL);
if (Context->RelocTableSize == 0) {
return true;
}
Image = Context->Image;
assert (Image->RelocInfo.NumRelocs > 0);
assert (Image->RelocInfo.NumRelocs <= MAX_UINT32);
assert (sizeof(UE_RELOCATION_BLOCK) <= *BufferSize);
RelocTableSize = 0;
RelocBlock = (void *)*Buffer;
BlockAddress = (uint32_t)PAGE (Image->RelocInfo.Relocs[0].Target);
BlockNumRelocs = 0;
BlockSize = sizeof (*RelocBlock);
RelocBlock->BlockInfo = BlockAddress;
for (Index = 0; Index < Image->RelocInfo.NumRelocs; ++Index) {
RelocAddress = PAGE (Image->RelocInfo.Relocs[Index].Target);
if (RelocAddress != BlockAddress) {
BlockSize = ALIGN_VALUE (BlockSize, UE_RELOCATION_BLOCK_ALIGNMENT);
assert (BlockSize <= *BufferSize);
*BufferSize -= BlockSize;
*Buffer += BlockSize;
RelocTableSize += BlockSize;
RelocBlock = (void *)*Buffer;
BlockAddress = RelocAddress;
BlockNumRelocs = 0;
BlockSize = sizeof (*RelocBlock);
RelocBlock->BlockInfo = BlockAddress;
}
BlockSize += sizeof (*RelocBlock->RelocInfo);
assert (BlockSize <= *BufferSize);
RelocBlock->RelocInfo[BlockNumRelocs] = PAGE_OFF (Image->RelocInfo.Relocs[Index].Target);
RelocBlock->RelocInfo[BlockNumRelocs] |= Image->RelocInfo.Relocs[Index].Type << 12U;
assert (UE_RELOC_OFFSET (RelocBlock->RelocInfo[BlockNumRelocs]) == PAGE_OFF (Image->RelocInfo.Relocs[Index].Target));
assert (UE_RELOC_TYPE (RelocBlock->RelocInfo[BlockNumRelocs]) == Image->RelocInfo.Relocs[Index].Type);
++BlockNumRelocs;
if (BlockNumRelocs > UE_RELOCATION_BLOCK_MAX_RELOCS) {
return false;
}
++RelocBlock->BlockInfo;
assert (BlockNumRelocs == UE_RELOC_BLOCK_NUM (RelocBlock->BlockInfo));
assert (BlockAddress == UE_RELOC_BLOCK_ADDRESS (RelocBlock->BlockInfo));
}
*BufferSize -= BlockSize;
*Buffer += BlockSize;
RelocTableSize += BlockSize;
assert (RelocTableSize == Context->RelocTableSize);
RelocTablePadding = ALIGN_VALUE_ADDEND (RelocTableSize, UE_SECTION_ALIGNMENT);
assert (RelocTablePadding <= *BufferSize);
*BufferSize -= RelocTablePadding;
*Buffer += RelocTablePadding;
return true;
}
static
bool
ToolImageEmitUeDebugTable (
const image_tool_ue_emit_context_t *Context,
uint8_t **Buffer,
uint32_t *BufferSize
)
{
uint32_t DebugTableSize;
UE_DEBUG_TABLE *DebugTable;
const image_tool_image_info_t *Image;
uint8_t Index;
UE_SEGMENT_NAME *SectionName;
uint32_t DebugTablePadding;
assert (Context != NULL);
assert (Buffer != NULL);
assert (BufferSize != NULL);
assert (sizeof (UE_DEBUG_TABLE) <= *BufferSize);
DebugTableSize = sizeof (UE_DEBUG_TABLE);
DebugTable = (void *)*Buffer;
assert (DebugTable->SymbolsBaseOffset == 0);
assert (DebugTable->Reserved == 0);
Image = Context->Image;
*BufferSize -= sizeof (UE_DEBUG_TABLE);
*Buffer += sizeof (UE_DEBUG_TABLE);
if (Image->DebugInfo.SymbolsPath != NULL) {
assert (Image->DebugInfo.SymbolsPathLen <= MAX_UINT8);
DebugTable->SymbolsPathSize = (uint8_t)Image->DebugInfo.SymbolsPathLen;
assert (Image->DebugInfo.SymbolsPathLen <= *BufferSize);
DebugTableSize += Image->DebugInfo.SymbolsPathLen;
memmove (*Buffer, Image->DebugInfo.SymbolsPath, Image->DebugInfo.SymbolsPathLen);
*BufferSize -= Image->DebugInfo.SymbolsPathLen;
*Buffer += Image->DebugInfo.SymbolsPathLen;
} else {
assert (DebugTable->SymbolsPathSize == 0);
}
for (Index = 0; Index < Image->SegmentInfo.NumSegments; ++Index) {
assert (sizeof (UE_SEGMENT_NAME) <= *BufferSize);
DebugTableSize += sizeof (UE_SEGMENT_NAME);
SectionName = (void *)*Buffer;
strncpy (
(char *)SectionName,
Image->SegmentInfo.Segments[Index].Name,
sizeof (*SectionName)
);
*BufferSize -= sizeof (*SectionName);
*Buffer += sizeof (*SectionName);
}
assert (DebugTableSize == Context->DebugTableSize);
DebugTablePadding = ALIGN_VALUE_ADDEND (DebugTableSize, UE_SECTION_ALIGNMENT);
assert (DebugTablePadding <= *BufferSize);
*BufferSize -= DebugTablePadding;
*Buffer += DebugTablePadding;
return true;
}
static
bool
ToolImageEmitUeHiiTable (
const image_tool_ue_emit_context_t *Context,
uint8_t **Buffer,
uint32_t *BufferSize
)
{
const image_tool_image_info_t *Image;
uint32_t HiiTablePadding;
assert (Context != NULL);
assert (Buffer != NULL);
assert (BufferSize != NULL);
Image = Context->Image;
if (Context->HiiTableSize == 0) {
return true;
}
assert (Image->HiiInfo.DataSize == Context->HiiTableSize);
assert (Context->HiiTableSize <= *BufferSize);
memmove (*Buffer, Image->HiiInfo.Data, Image->HiiInfo.DataSize);
*BufferSize -= Image->HiiInfo.DataSize;
*Buffer += Image->HiiInfo.DataSize;
HiiTablePadding = ALIGN_VALUE_ADDEND (Image->HiiInfo.DataSize, UE_SECTION_ALIGNMENT);
assert (HiiTablePadding <= *BufferSize);
*BufferSize -= HiiTablePadding;
*Buffer += HiiTablePadding;
return true;
}
static
bool
ToolImageEmitUeSections (
const image_tool_ue_emit_context_t *Context,
uint8_t **Buffer,
uint32_t *BufferSize
)
{
uint32_t OldBufferSize;
bool Result;
assert (Context != NULL);
assert (Buffer != NULL);
assert (BufferSize != NULL);
OldBufferSize = *BufferSize;
Result = ToolImageEmitUeRelocTable (Context, Buffer, BufferSize);
if (!Result) {
return false;
}
Result = ToolImageEmitUeDebugTable (Context, Buffer, BufferSize);
if (!Result) {
return false;
}
Result = ToolImageEmitUeHiiTable (Context, Buffer, BufferSize);
if (!Result) {
return false;
}
assert ((OldBufferSize - *BufferSize) == Context->SectionsSize);
return true;
}
void *
ToolImageEmitUe (
const image_tool_image_info_t *Image,
uint32_t *FileSize
)
{
image_tool_ue_emit_context_t Context;
bool Result;
uint32_t SectionsOffset;
bool Overflow;
void *FileBuffer;
uint8_t *Buffer;
uint32_t RemainingSize;
uint32_t ExpectedSize;
assert (Image != NULL);
assert (FileSize != NULL);
memset (&Context, 0, sizeof (Context));
Context.Image = Image;
Result = EmitUeGetHeaderSizes (Image, &Context.HdrInfo);
if (!Result) {
raise ();
return NULL;
}
Result = EmitUeGetSegmentsSize (Image, &Context.SegmentsSize);
if (!Result) {
raise ();
return NULL;
}
Overflow = BaseOverflowAddU32 (
Context.HdrInfo.HeaderSize,
Context.SegmentsSize,
&SectionsOffset
);
if (Overflow) {
raise ();
return NULL;
}
Context.SegmentsEndPadding = ALIGN_VALUE_ADDEND (SectionsOffset, UE_SECTION_ALIGNMENT);
Overflow = BaseOverflowAddU32 (
SectionsOffset,
Context.SegmentsEndPadding,
&SectionsOffset
);
if (Overflow) {
raise ();
return NULL;
}
Result = EmitUeGetSectionsSize (&Context, &Context.SectionsSize);
if (!Result) {
raise ();
return NULL;
}
assert (IS_ALIGNED (Context.SectionsSize, UE_SECTION_ALIGNMENT));
Overflow = BaseOverflowAddU32 (
SectionsOffset,
Context.SectionsSize,
&Context.UnsignedFileSize
);
if (Overflow) {
raise ();
return NULL;
}
assert (IS_ALIGNED (Context.UnsignedFileSize, UE_SECTION_ALIGNMENT));
FileBuffer = calloc (1, Context.UnsignedFileSize);
if (FileBuffer == NULL) {
raise ();
return NULL;
}
Buffer = FileBuffer;
RemainingSize = Context.UnsignedFileSize;
ExpectedSize = Context.UnsignedFileSize;
Result = ToolImageEmitUeHeader (&Context, &Buffer, &RemainingSize);
if (!Result) {
raise ();
free (FileBuffer);
return NULL;
}
ExpectedSize -= Context.HdrInfo.HeaderSize;
assert (RemainingSize == ExpectedSize);
Result = ToolImageEmitUeSegments (&Context, &Buffer, &RemainingSize);
if (!Result) {
raise ();
free (FileBuffer);
return NULL;
}
ExpectedSize -= Context.SegmentsSize + Context.SegmentsEndPadding;
assert (RemainingSize == ExpectedSize);
Result = ToolImageEmitUeSections (&Context, &Buffer, &RemainingSize);
if (!Result) {
raise ();
free (FileBuffer);
return NULL;
}
ExpectedSize -= Context.SectionsSize;
assert (RemainingSize == ExpectedSize);
assert (RemainingSize == 0);
*FileSize = Context.UnsignedFileSize;
return FileBuffer;
}

View File

@ -1,219 +0,0 @@
/** @file
Definitions of the UE certificate store format.
Copyright (c) 2021, Marvin Häuser. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#ifndef UE_CERT_STORE_H_
#define UE_CERT_STORE_H_
///
/// Definition of an UE certificate (PKCS).
///
typedef struct {
///
/// The UE certificate (PKCS) information.
///
/// [Bits 23:0] The size, in Bytes, of TbsData.
/// [Bits 31:24] Reserved for future usage. Must be set to 0.
///
UINT32 Info;
///
/// The size, in Bytes, of Signature.
///
UINT32 SignatureSize;
///
/// The ASN.1 DER encoded X.509 tbsCertificate field.
///
UINT8 TbsData[];
///
/// The signature of TbsData, signed by the certificate identified by
/// TbsData.issuer, with the algorithm identified by SignatureAlgorithm. Its
/// size is strictly defined by the signature algorithm.
///
//UINT8 Signature[];
} UE_CERT_PKCS;
/**
Retrieves the size, in Bytes, of TbsData of an UE certificate (PKCS).
@param[in] Info The UE certificate (PKCS) information.
**/
#define UE_CERT_PKCS_TBS_SIZE(Info) ((Info) & 0x00FFFFFFU)
STATIC_ASSERT (
sizeof (UE_CERT_PKCS) == 8 && ALIGNOF (UE_CERT_PKCS) == 4,
"The UE certificate (PKCS) definition does not meet the specification."
);
STATIC_ASSERT (
OFFSET_OF (UE_CERT_PKCS, TbsData) == sizeof (UE_CERT_PKCS),
"The UE certificate (PKCS) definition does not meet the specification."
);
///
/// Definition of the UE certificate (minimal RSA) purpose identifiers.
///
enum {
UeCertMinRsaPurposeExecutable = 0x00U,
UeCertMinRsaPurposeVariables = 0x01U,
UeCertMinRsaPurposeConfig = 0x02U
};
///
/// Definition of an UE certificate (minimal RSA).
/// The RSA exponent is always 65537.
///
typedef struct {
///
/// The certificate subject identifier GUID.
///
GUID SubjectId;
///
/// [Bits 28:0] The time the certificate expires. It is calculated by:
/// S + M * 60 + H * 3600 + D * 86400 + m * 2678400 + Y * 32140800, with
/// S [0,59]: The number of full seconds into the current minute,
/// M [0,59]: The number of full minutes into the current hour,
/// H [0,23]: The number of full hours into the current day,
/// D [0,30]: The number of full days into the current month,
/// m [0,11]: The number of full months into the current year,
/// Y [0,16]: The number of full years since 2021.
/// [Bits 29:31] Reserved for future usage. Must be set to 0.
///
UINT32 ExpiryTime;
///
/// [Bits 1:0] The purpose identifier of the certificate.
/// [Bits 7:1] Reserved for future usage. Must be set to 0.
///
UINT8 Purpose;
///
/// Reserved for future usage. Must be set to 0.
///
UINT8 Reserved;
///
/// [Bits 11:0] The size, in 8 Byte units, of the RSA modulus.
/// [Bits 15:12] Reserved for future usage. Must be set to 0.
///
UINT16 NumQwords;
///
/// The Montgomery Inverse in the 64-bit space: -1 / N[0] mod 2^64.
///
UINT64 N0Inv;
///
/// The RSA parameters. If the number of significant Bits is less than the
/// number of available Bits, the remaining Bits must be set to 0. Storage
/// happens in reverse byte order.
///
/// [0 .. 8 * NumQwords) The RSA key.
/// [8 * NumQwords .. 16 * NumQwords) Montgomery R^2 mod N.
///
UINT8 Data[];
} UE_CERT_MIN_RSA;
STATIC_ASSERT (
sizeof (UE_CERT_MIN_RSA) == 32 && ALIGNOF (UE_CERT_MIN_RSA) == 8,
"The UE certificate (minimal RSA) definition does not meet the specification."
);
STATIC_ASSERT (
OFFSET_OF (UE_CERT_MIN_RSA, Data) == sizeof (UE_CERT_MIN_RSA),
"The UE certificate (minimal RSA) definition does not meet the specification."
);
STATIC_ASSERT (
IS_ALIGNED (OFFSET_OF (UE_CERT_MIN_RSA, Data), ALIGNOF (UINT64)),
"The UE certificate (minimal RSA) definition does not meet the specification."
);
///
/// Definition of the UE certificate store types.
///
enum {
UeCertChainTypePkcs = 0x00
};
///
/// The alignment, in Bytes, of each UE certificate chain in the UE certificate
/// store.
///
#define UE_CERT_CHAIN_ALIGNMENT 8U
///
/// Definition of an UE certificate chain.
///
typedef struct {
///
/// The signature algorithm used to sign the data.
///
GUID Algorithm;
///
/// The UE certificate chain information.
///
/// [Bit 0] If set, the certificate chain is empty and the data may be
/// directly signed by a trusted certificate. In this case,
/// instead of a certificate chain structure, the type-specific
/// issuer information is stored.
/// [Bits 2:1] Reserved for future usage. Must be set to 0.
/// [Bits 23:3] The size, in Bytes, of this UE certificate chain, or of the
/// type-specific issuer information.
/// [Bit 24] The type of the UE certificate store.
/// [Bits 31:25] Reserved for future usage. Must be set to 0.
///
UINT32 Info;
///
/// The size, in Bytes, of Signature.
///
UINT32 SignatureSize;
///
/// The signature of the signed data, signed by the first certificate of the
/// chain, with the algorithm identified by SignatureAlgorithm. Its size is
/// strictly defined by the signature algorithm.
///
UINT8 Signature[];
///
/// The certficate chain. The first certificate signs the data.
///
//UE_CERT Chain[];
} UE_CERT_CHAIN;
/**
Retrieves whether the UE certificate chain is routed, i.e. whether there is
no chain of certificates but a type-specific issuer identifier for the trusted
certificate that signs the data.
@param[in] Info The UE certificate chain information.
**/
#define UE_CERT_CHAIN_ROOTED(Info) ((Info) & 0x00000001U)
/**
Retrieves the size, in Bytes, of the UE certificate chain.
@param[in] Info The UE certificate chain information.
**/
#define UE_CERT_CHAIN_SIZE(Info) ((Info) & 0x00FFFFF8U)
/**
Retrieves the type of the UE certificate chain.
@param[in] Info The UE certificate chain information.
**/
#define UE_CERT_CHAIN_TYPE(Info) (((Info) & 0x1000000U) >> 24U)
STATIC_ASSERT (
IS_ALIGNED (UE_CERT_CHAIN_SIZE (0xFFFFFFFF), UE_CERT_CHAIN_ALIGNMENT),
"The UE certificate chain definition does not meet the specification."
);
STATIC_ASSERT (
sizeof (UE_CERT_CHAIN) == 24 && ALIGNOF (UE_CERT_CHAIN) == 4,
"The UE certificate chain definition does not meet the specification."
);
STATIC_ASSERT (
OFFSET_OF (UE_CERT_CHAIN, Signature) == sizeof (UE_CERT_CHAIN),
"The UE certificate chain definition does not meet the specification."
);
#endif // UE_CERT_STORE_H_

View File

@ -1,580 +0,0 @@
/** @file
Definitions of the UEFI Executable file format.
Copyright (c) 2021, Marvin Häuser. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#ifndef UE_IMAGE_H_
#define UE_IMAGE_H_
//
// UEFI Executable segment definitions.
//
// NOTE: To guarantee all data is sufficiently aligned, no matter what it is,
// all UE segments are at least 8 Byte aligned in the UE memory space.
// This leaves the bottom 3 Bits unused for valid values. Use them to
// indicate the UE segment permissions.
//
///
/// The alignment, in Bytes, of each UE segment in the UE memory space.
///
#define UE_SEGMENT_ALIGNMENT 8U
///
/// Definition of an UEFI Executable segment header.
///
typedef struct {
///
/// Information about the UE segment in the UE memory space.
///
/// [Bit 0] Indicates whether the UE segment is read-protected.
/// [Bit 1] Indicates whether the UE segment is execute-protected.
/// [Bit 2] Indicates whether the UE segment is write-protected.
/// [Bits 31:3] The size, in 8 Byte units, of the UE segment in the UE memory
/// space.
///
UINT32 ImageInfo;
///
/// The size, in Bytes, of the UE segment in the UE raw file.
///
UINT32 FileSize;
} UE_SEGMENT;
#define UE_SEGMENT_INFO_RP BIT0
#define UE_SEGMENT_INFO_XP BIT1
#define UE_SEGMENT_INFO_RO BIT2
STATIC_ASSERT (
sizeof (UE_SEGMENT) == 8 && ALIGNOF (UE_SEGMENT) == 4,
"The UE segment definition does not meet the specification."
);
///
/// Definition of an UEFI Executable XIP segment header.
///
typedef struct {
///
/// Information about the UE segment in the UE memory space.
///
/// [Bit 0] Indicates whether the UE segment is read-protected.
/// [Bit 1] Indicates whether the UE segment is execute-protected.
/// [Bit 2] Indicates whether the UE segment is write-protected.
/// [Bits 31:3] The size, in 8 Byte units, of the UE segment in the UE memory
/// space.
///
UINT32 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."
);
STATIC_ASSERT (
OFFSET_OF (UE_SEGMENT, ImageInfo) == OFFSET_OF (UE_SEGMENT_XIP, ImageInfo),
"The UE and UE XIP segment definitions do not align."
);
/**
Retrieve the UE segment memory permissions.
@param[in] ImageInfo The UE segment memory information.
**/
#define UE_SEGMENT_PERMISSIONS(ImageInfo) ((ImageInfo) & 0x00000007U)
/**
Retrieve the size, in Bytes, of the UE segment in the UE memory space.
@param[in] ImageInfo The UE segment image information.
**/
#define UE_SEGMENT_SIZE(ImageInfo) ((ImageInfo) & 0xFFFFFFF8U)
STATIC_ASSERT (
IS_ALIGNED (UE_SEGMENT_SIZE (0xFFFFFFFF), UE_SEGMENT_ALIGNMENT),
"The UE segment size definition does not meet the specification."
);
//
// UEFI Executable section definitions.
//
// NOTE: To guarantee all data is sufficiently aligned, no matter what it is,
// all UE sections are at least 8 Byte aligned.
//
// UE sections are identified by ID and can be omitted to save space.
//
// UE sections are ordered by ID to allow efficient lookups.
//
// UE relocation table will likely be close to PE/COFF.
//
// UE HII support needs discussion, REF: https://bugzilla.tianocore.org/show_bug.cgi?id=557
//
// UE certificate table will likely be a stripped version of PE/COFF.
//
// UE sections are not loaded into the UE memory space as their data is
// only required by the loader.
//
// UE section Bit 2 is reserved in case more UE section IDs are required
// in the future. If it is set, an extended structure should be used.
//
///
/// The alignment, in Bytes, of each UE section in the UE raw file.
///
#define UE_SECTION_ALIGNMENT 8U
///
/// Definition of UE section identifiers.
///
enum {
UeSectionIdRelocTable = 0x00U,
UeSectionIdDebugTable = 0x01U,
UeSectionIdHiiTable = 0x02U
};
//
// Definition of an UE section header.
//
typedef struct {
///
/// Information about the UE section.
///
/// [Bits 1:0] The identifier of the UE section.
/// [Bit 2] Reserved for future usage. Must be set to 0.
/// [Bits 31:3] The size, in 8 Byte units, of the UE section in the UE raw
/// file.
///
UINT32 FileInfo;
} UE_SECTION;
STATIC_ASSERT (
sizeof (UE_SECTION) == 4 && ALIGNOF (UE_SECTION) == 4,
"The UE section definition does not meet the specification."
);
/**
Retrieves the UE section identifier.
@param[in] FileInfo The UE section raw file information.
**/
#define UE_SECTION_ID(FileInfo) ((FileInfo) & 0x00000003U)
/**
Retrieves the size, in Bytes, of the UE section in the UE raw file.
@param[in] FileInfo The UE section raw file information.
**/
#define UE_SECTION_SIZE(FileInfo) ((FileInfo) & 0xFFFFFFF8U)
STATIC_ASSERT (
IS_ALIGNED (UE_SECTION_SIZE (0xFFFFFFFF), UE_SECTION_ALIGNMENT),
"The UE section size definition does not meet the specification."
);
//
// UEFI Executable relocation table definitions.
//
// NOTE: The rest of the definitions should be close to PE/COFF.
// PE/COFF SizeOfBlock allows for a lot more relocations, however forcing
// 4 KB blocks still allows for one relocation per Byte with this design.
//
///
/// Definition of the UEFI Executable relocation identifiers.
///
enum {
UeRelocRel32 = 0x00U,
UeRelocRel64 = 0x01U,
UeRelocArmMov32t = 0x02U
};
#define UE_RELOCATION_BLOCK_ALIGNMENT 4U
#define UE_RELOCATION_BLOCK_MAX_RELOCS 4095U
///
/// Definition of an UEFI Executable relocation block.
///
typedef struct {
///
/// Information about the UE relocation block.
///
/// [Bits 11:0] The amount of relocations of the UE relocation block.
/// [Bits 31:12] The base address, in 4 KB units, of the UE relocation block.
///
UINT32 BlockInfo;
///
/// The relocations of the UE relocation block.
///
/// [Bits 11:0] The offset of the UE relocation in the UE relocation block.
/// [Bits 31:12] The type of the UE relocation.
///
UINT16 RelocInfo[];
} UE_RELOCATION_BLOCK;
STATIC_ASSERT (
sizeof (UE_RELOCATION_BLOCK) == 4 && ALIGNOF (UE_RELOCATION_BLOCK) == UE_RELOCATION_BLOCK_ALIGNMENT,
"The UE relocation block definition does not meet the specification."
);
STATIC_ASSERT (
ALIGNOF (UE_RELOCATION_BLOCK) <= UE_SECTION_ALIGNMENT,
"The UE relocation block definition does not meet the specification."
);
STATIC_ASSERT (
OFFSET_OF (UE_RELOCATION_BLOCK, RelocInfo) == sizeof (UE_RELOCATION_BLOCK),
"The UE relocation block definition does not meet the specification."
);
/**
Retrieves the target offset of the UE relocation.
@param[in] RelocInfo The UE relocation information.
**/
#define UE_RELOC_OFFSET(RelocInfo) ((RelocInfo) & 0x0FFFU)
/**
Retrieves the type of the UE relocation.
@param[in] RelocInfo The UE relocation information.
**/
#define UE_RELOC_TYPE(RelocInfo) ((RelocInfo) >> 12U)
/**
Retrieves the amount of relocations in the UE relocation block.
@param[in] BlockInfo The UE relocation block information.
**/
#define UE_RELOC_BLOCK_NUM(BlockInfo) ((BlockInfo) & 0x00000FFFU)
/**
Retrieves the base address of the UE relocation block.
@param[in] BlockInfo The UE relocation block information.
**/
#define UE_RELOC_BLOCK_ADDRESS(BlockInfo) ((BlockInfo) & 0xFFFFF000U)
//
// UEFI Executable debug table definitions.
//
// NOTE: The UE symbols base address offset is required for conversion of
// PE/COFF 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 an UEFI Executable segment name.
///
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 an UEFI Executable section header.
///
typedef struct {
///
/// The offset to be added to the UE base address in order to retrieve the
/// UE symbols base address.
/// FIXME: Can we rely on equal layouts for all source file formats?
///
INT16 SymbolsBaseOffset;
//
// Reserved for future usage. Must be set to 0.
//
UINT8 Reserved;
///
/// The size, in Bytes, of the UE symbols path.
///
UINT8 SymbolsPathSize;
///
/// The UE symbols path.
///
UINT8 SymbolsPath[];
///
/// The UE segment name table. In the same order as 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)
/**
Retrieves the segment name table of an UE debug table.
@param[in] DebugTable The UE debug table.
**/
#define UE_DEBUG_TABLE_SEGMENT_NAMES(DebugTable) \
(CONST UE_SEGMENT_NAME *) ( \
(DebugTable)->SymbolsPath + (DebugTable)->SymbolsPathSize \
)
STATIC_ASSERT (
sizeof (UE_DEBUG_TABLE) == 4 && ALIGNOF (UE_DEBUG_TABLE) == 2,
"The UE debug table definition does not meet the specification."
);
STATIC_ASSERT (
ALIGNOF (UE_DEBUG_TABLE) <= UE_SECTION_ALIGNMENT,
"The UE debug table definition is misaligned."
);
STATIC_ASSERT (
OFFSET_OF (UE_DEBUG_TABLE, SymbolsPath) == sizeof (UE_DEBUG_TABLE),
"The UE relocation block definition does not meet the specification."
);
//
// UEFI Executable header definitions.
//
// NOTE: The UE segment alignment is stored as shift exponent to save up to
// 3 Bytes. This also guarantees it to be a power fo two.
//
// UE fixed-address loading needs reconsideration.
//
// The UE header can be contained in a separate FFS section to save space.
//
// The UE segment table overlaps the UE header padding. However, as there
// must always be at least one segment, the padding can be ignored.
//
// The index of the last UE segment is stored over the number of segments
// to avoid the check against 0, and to allow for one more segment.
//
// The remaining reserved fields may be used to indicate revision.
//
// The certificate table is not stored as an UE section to both omit its
// size from the headers (allows for multi-step-signing without having to
// hash the certificate table size), and to allow immediate hashing.
//
// The UE XIP header omits all data that can be derived from platform
// constraints. This header is not guaranteed to be backwards-compatible.
//
///
/// The signature of an UEFI Executable header.
///
#define UE_HEADER_SIGNATURE SIGNATURE_16 ('U', 'E')
#define UE_HEADER_FLAG_RELOCS_STRIPPED BIT7
///
/// Definition of the UEFI Executable machine identifiers.
///
enum {
UeMachineI386 = 0x00U,
UeMachineEbc = 0x01U,
UeMachineX64 = 0x02U,
UeMachineArmThumbMixed = 0x03U,
UeMachineArm64 = 0x04U,
UeMachineRiscV32 = 0x05U,
UeMachineRiscV64 = 0x06U,
UeMachineRiscV128 = 0x07U
};
///
/// Definition of the UEFI Executable subsystem identifiers.
///
enum {
UeSubsystemEfiApplication = 0x00U,
UeSubsystemEfiBootServicesDriver = 0x01U,
UeSubsystemEfiRuntimeDriver = 0x02U,
UeSubsystemSalRuntimeDriver = 0x03U,
};
///
/// Definition of an UEFI Executable header.
///
typedef struct {
///
/// The signature to identify the UE raw file format. Must match 'UE'.
///
UINT16 Signature;
///
/// [Bits 7:0] Reserved for future usage. Must be set to 0.
///
UINT8 Reserved;
///
/// Information about the UE Image.
///
/// [Bits 4:0] The shift exponent for the UE segment alignment in Bytes.
/// [Bits 6:5] Reserved for future usage. Must be set to 0.
/// [Bit 7] Indicates whether the UE relocation table has been stripped.
///
UINT8 ImageInfo;
///
/// The index of the last segment in the UE segment table.
///
UINT8 LastSegmentIndex;
///
/// The number of sections in the UE section table.
///
UINT8 NumSections;
///
/// Indicates the subsystem identifier the UE targets.
///
UINT8 Subsystem;
///
/// Indicates the machine identifier the UE targets.
///
UINT8 Machine;
///
/// Indicates the UE preferred load address.
///
UINT64 PreferredAddress;
///
/// Indicates the offset of the UE entry point in the UE memory space.
///
UINT32 EntryPointAddress;
///
/// Extended information about the UE Image.
///
/// [Bits 2:0] Reserved for future usage. Must be set to 0.
/// [Bits 31:3] The size, in 8 Byte units, of the unsigned UE raw file. If the
/// UE raw file size is larger than this value, the appended data
/// is the UE certificate table.
///
UINT32 ImageInfo2;
///
/// The UE segment table. It contains all data of the UE memory space.
///
/// All UE segments are contiguous in the UE memory space.
/// The offset of the first UE segment in the UE memory space is 0.
///
/// All UE segments are contiguous in the UE raw file.
/// The offset of the first UE segment in the UE raw file is the end of the
/// UEFI Executable header in the UE raw file.
///
UE_SEGMENT Segments[];
///
/// The UE section table. It contains data useful for UE loading.
///
/// All UE sections are contiguous in the UE raw file.
/// The offset of the first UE section in the UE raw file is the end of the
/// last UE segment in the UE raw file.
///
/// All UE sections are ordered by their UE section identifier.
///
//UE_SECTION Sections[];
} 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) == 24 && ALIGNOF (UE_HEADER) == 8,
"The UE header definition does not meet the specification."
);
STATIC_ASSERT (
ALIGNOF (UE_SEGMENT) <= ALIGNOF (UE_SECTION),
"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 segment alignment, in Bytes, as a power of two.
@param[in] ImageInfo The UE header image information.
**/
#define UE_HEADER_ALIGNMENT(ImageInfo) ((UINT32) 1U << ((ImageInfo) & 0x1FU))
/**
Retrieves the 8 Byte aligned unsigned UE raw file size.
If the UE raw file size is larger than this value, the appended data is the UE
certificate table.
@param[in] ImageInfo2 The UE header image information.
**/
#define UE_HEADER_UNSIGNED_SIZE(ImageInfo2) ((ImageInfo2) & 0xFFFFFFF8U)
STATIC_ASSERT (
IS_ALIGNED (UE_HEADER_UNSIGNED_SIZE (0xFFFFFFFF), UE_SECTION_ALIGNMENT),
"The unsigned UE raw file size definition does not meet the specification."
);
///
/// Definition of an UEFI Executable XIP header.
///
typedef struct {
///
/// [Bits 7:0] Reserved for future usage. Must be set to 0.
///
UINT8 Reserved;
///
/// Information about the UE Image.
///
/// [Bits 4:0] The shift exponent for the UE segment alignment.
/// [Bits 6:5] Reserved for future usage. Must be set to 0.
/// [Bit 7] Indicates whether the UE relocation table has been stripped.
///
UINT8 ImageInfo;
///
/// The index of the last segment in the UE segment table.
///
UINT8 LastSegmentIndex;
///
/// The number of sections in the UE section table.
///
UINT8 NumSections;
///
/// Indicates the offset of the UE entry point in the UE memory space.
///
UINT32 EntryPointAddress;
///
/// The UE segment table. It contains all data of the UE memory space.
///
/// All UE segments are contiguous in the UE memory space.
/// The offset of the first UE segment in the UE memory space is 0.
///
/// The UE segments are stored separately in XIP memory.
///
UE_SEGMENT_XIP Segments[];
///
/// The UE section table. It contains data useful for UE loading.
///
/// All UE sections are contiguous in the UE raw file.
/// The offset of the first UE section in the UE raw file is the end of the
/// UEFI Executable XIP header in the UE raw file.
///
/// All UE sections are ordered by their UE section identifier.
///
//UE_SECTION Sections[];
} UE_HEADER_XIP;
///
/// The minimum size, in Bytes, of a valid UE XIP header.
///
#define MIN_SIZE_OF_UE_HEADER_XIP \
(OFFSET_OF (UE_HEADER_XIP, Segments) + sizeof (UE_SEGMENT_XIP))
STATIC_ASSERT (
sizeof (UE_HEADER_XIP) == 8 && ALIGNOF (UE_HEADER_XIP) == 4,
"The UE XIP header definition does not meet the specification."
);
STATIC_ASSERT (
ALIGNOF (UE_SEGMENT_XIP) <= ALIGNOF (UE_SECTION),
"The UE XIP header definition is misaligned."
);
STATIC_ASSERT (
OFFSET_OF (UE_HEADER_XIP, Segments) == sizeof (UE_HEADER_XIP),
"The UE XIP header definition does not meet the specification."
);
#endif // UE_IMAGE_H_

View File

@ -1,250 +0,0 @@
/** @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
**/
#ifndef UE_LIB_H_
#define UE_LIB_H_
#include <IndustryStandard/UeImage.h>
// FIXME: Deduplicate?
//
// PcdImageLoaderAlignmentPolicy bits.
//
///
/// If set, unaligned Image sections are permitted.
///
#define PCD_ALIGNMENT_POLICY_CONTIGUOUS_SECTIONS BIT0
///
/// If set, unaligned Image Relocation Block sizes are permitted.
///
#define PCD_ALIGNMENT_POLICY_RELOCATION_BLOCK_SIZES BIT1
///
/// If set, unaligned Image certificate sizes are permitted.
///
#define PCD_ALIGNMENT_POLICY_CERTIFICATE_SIZES BIT2
//
// PcdImageLoaderRelocTypePolicy bits.
//
///
/// If set, ARM Thumb Image relocations are supported.
///
#define PCD_RELOC_TYPE_POLICY_ARM BIT0
// FIXME: Add RISC-V support.
/**
Returns whether the Base Relocation type is supported by this loader.
@param[in] Type The type of the Base Relocation.
**/
#define UE_RELOC_TYPE_SUPPORTED(Type) \
(((Type) == EFI_IMAGE_REL_BASED_ABSOLUTE) || \
((Type) == EFI_IMAGE_REL_BASED_HIGHLOW) || \
((Type) == EFI_IMAGE_REL_BASED_DIR64) || \
((PcdGet32 (PcdImageLoaderRelocTypePolicy) & PCD_RELOC_TYPE_POLICY_ARM) != 0 && (Type) == EFI_IMAGE_REL_BASED_ARM_MOV32T))
/**
Returns whether the Base Relocation is supported by this loader.
@param[in] Relocation The composite Base Relocation value.
**/
#define UE_RELOC_SUPPORTED(RelocInfo) \
UE_RELOC_TYPE_SUPPORTED (UE_RELOC_TYPE (RelocInfo))
typedef struct {
CONST VOID *FileBuffer;
UINT32 SegmentAlignment;
VOID *ImageBuffer;
UINT32 SegmentsFileOffset; // Unused for XIP
CONST UE_SECTION *Sections;
CONST VOID *Segments;
UINT32 SectionsFileOffset;
UINT32 ImageSize;
UINT32 UnsignedFileSize;
UINT32 CertTableSize;
UINT32 RelocTableSize;
UINT8 ImageInfo;
UINT8 LastSegmentIndex;
UINT8 NumSections;
UINT8 Subsystem;
UINT8 Machine;
UINT64 PreferredAddress; // Unused for XIP
UINT32 EntryPointAddress;
UINT8 SegmentImageInfoIterSize;
} 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
);
RETURN_STATUS
UeInitializeContext (
OUT UE_LOADER_IMAGE_CONTEXT *Context,
IN CONST VOID *FileBuffer,
IN UINT32 FileSize
);
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
UeLoadImageInplace (
IN OUT UE_LOADER_IMAGE_CONTEXT *Context
);
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
);
RETURN_STATUS
UeRelocateImageForRuntime (
IN OUT VOID *Image,
IN UINT32 ImageSize,
IN UINT64 BaseAddress,
IN CONST UE_LOADER_RUNTIME_CONTEXT *RuntimeContext
);
RETURN_STATUS
UeGetSymbolsPath (
IN CONST UE_LOADER_IMAGE_CONTEXT *Context,
OUT CONST CHAR8 **SymbolsPath,
OUT UINT32 *SymbolsPathSize
);
RETURN_STATUS
UeGetFirstCertificate (
IN OUT UE_LOADER_IMAGE_CONTEXT *Context,
OUT CONST WIN_CERTIFICATE **Certificate
);
RETURN_STATUS
UeGetNextCertificate (
IN OUT UE_LOADER_IMAGE_CONTEXT *Context,
IN OUT CONST WIN_CERTIFICATE **Certificate
);
RETURN_STATUS
UeGetHiiDataRva (
IN OUT UE_LOADER_IMAGE_CONTEXT *Context,
OUT UINT32 *HiiRva,
OUT UINT32 *HiiSize
);
UINT32
UeGetAddressOfEntryPoint (
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
);
UINT32
UeGetImageSizeInplace (
IN OUT UE_LOADER_IMAGE_CONTEXT *Context
);
UINT64
UeGetPreferredAddress (
IN OUT UE_LOADER_IMAGE_CONTEXT *Context
);
BOOLEAN
UeGetRelocsStripped (
IN OUT UE_LOADER_IMAGE_CONTEXT *Context
);
UINTN
UeLoaderGetImageAddress (
IN CONST UE_LOADER_IMAGE_CONTEXT *Context
);
UINT8
UeGetSegments (
IN OUT UE_LOADER_IMAGE_CONTEXT *Context,
OUT CONST UE_SEGMENT **Segments
);
UINT8
UeGetSegmentImageInfos (
IN OUT UE_LOADER_IMAGE_CONTEXT *Context,
OUT CONST UINT32 **SegmentImageInfos,
OUT UINT8 *SegmentImageInfoIterSize
);
UINT32
UeGetSectionsFileOffset (
IN OUT UE_LOADER_IMAGE_CONTEXT *Context
);
#endif // UE_LIB_H_

View File

@ -1,32 +0,0 @@
## @file
# UEFI Image Loader library implementation for PE/COFF and TE 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

File diff suppressed because it is too large Load Diff

View File

@ -1,37 +0,0 @@
## @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 = BaseUefiImageLibUe
FILE_GUID = 25BC78F1-426B-4C9D-A60D-173A56FB28C1
MODULE_TYPE = BASE
VERSION_STRING = 1.0
LIBRARY_CLASS = UefiImageLib
[Sources]
CommonSupport.c
UeSupport.h
UeSupport.c
UefiImageLibUe.c
[Packages]
MdePkg/MdePkg.dec
[LibraryClasses]
BaseLib
BaseMemoryLib
BaseOverflowLib
CacheMaintenanceLib
DebugLib
MemoryAllocationLib
UeImageLib
UefiImageExtraActionLib
[FixedPcd]
gEfiMdePkgTokenSpaceGuid.PcdDebugRaisePropertyMask

View File

@ -1,234 +0,0 @@
#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/DebugLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/UefiImageLib.h>
#include <Library/UeImageLib.h>
STATIC
UINT32
InternalPermissionsToAttributes (
IN UINT32 ImageInfo
)
{
UINT32 Attributes;
STATIC_ASSERT (
(UE_SEGMENT_INFO_RP << 13U) == EFI_MEMORY_RP &&
(UE_SEGMENT_INFO_XP << 13U) == EFI_MEMORY_XP &&
(UE_SEGMENT_INFO_RO << 15U) == EFI_MEMORY_RO,
"The following conversion is incorrect."
);
Attributes = (ImageInfo & (UE_SEGMENT_INFO_RP | UE_SEGMENT_INFO_XP)) << 13U;
Attributes |= (ImageInfo & UE_SEGMENT_INFO_RO) << 15U;
return Attributes;
}
UEFI_IMAGE_RECORD *
UefiImageLoaderGetImageRecordUe (
IN OUT UE_LOADER_IMAGE_CONTEXT *Context
)
{
UEFI_IMAGE_RECORD *ImageRecord;
UINTN ImageAddress;
UINT32 NumRecordSegments;
UEFI_IMAGE_RECORD_SEGMENT *RecordSegment;
UINT16 NumSegments;
UINT8 SegmentIterSize;
CONST UINT32 *SegmentImageInfos;
CONST UINT32 *SegmentImageInfoPtr;
UINT32 SegmentImageInfo;
UINTN SegmentImageAddress;
UINT32 SegmentSize;
UINT32 SegmentPermissions;
UINT32 RangeSize;
UINT32 Permissions;
ASSERT (Context != NULL);
NumSegments = 1 + (UINT16) UeGetSegmentImageInfos (
Context,
&SegmentImageInfos,
&SegmentIterSize
);
ImageRecord = AllocatePool (
sizeof (*ImageRecord)
+ NumSegments * sizeof (*ImageRecord->Segments)
);
if (ImageRecord == NULL) {
DEBUG_RAISE ();
return NULL;
}
ImageRecord->Signature = UEFI_IMAGE_RECORD_SIGNATURE;
InitializeListHead (&ImageRecord->Link);
SegmentImageInfo = *SegmentImageInfos;
RangeSize = UE_SEGMENT_SIZE (SegmentImageInfo);
Permissions = UE_SEGMENT_PERMISSIONS (SegmentImageInfo);
SegmentImageAddress = 0;
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 VOID *) ((CONST CHAR8 *) SegmentImageInfos + SegmentIterSize);
(CONST CHAR8 *) SegmentImageInfoPtr < (CONST CHAR8 *) SegmentImageInfos + (UINT32) SegmentIterSize * NumSegments;
SegmentImageAddress += SegmentSize,
SegmentImageInfoPtr = (CONST VOID *) ((CONST CHAR8 *) SegmentImageInfoPtr + SegmentIterSize)
) {
SegmentImageInfo = *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 section for the current memory permission range.
//
RecordSegment = &ImageRecord->Segments[NumRecordSegments];
RecordSegment->Size = RangeSize;
RecordSegment->Attributes = InternalPermissionsToAttributes (Permissions);
++NumRecordSegments;
//
// Start a Image record section with the current Image section.
//
RangeSize = SegmentSize;
Permissions = SegmentPermissions;
}
ImageAddress = UeLoaderGetImageAddress (Context);
ImageRecord->NumSegments = NumRecordSegments;
ImageRecord->StartAddress = ImageAddress;
ImageRecord->EndAddress = ImageAddress + SegmentImageAddress;
//
// Zero the remaining array entries to avoid uninitialised data.
//
ZeroMem (
ImageRecord->Segments + NumRecordSegments,
(NumSegments - NumRecordSegments) * sizeof (*ImageRecord->Segments)
);
return ImageRecord;
}
RETURN_STATUS
UefiImageDebugLocateImageUe (
OUT UE_LOADER_IMAGE_CONTEXT *Context,
IN UINTN Address
)
{
ASSERT (Context != NULL);
(VOID) Address;
//
// FIXME:
// This feature is currently unsupported.
//
DEBUG_RAISE ();
return RETURN_NOT_FOUND;
}
RETURN_STATUS
UefiImageGetFixedAddressUe (
IN OUT UE_LOADER_IMAGE_CONTEXT *Context,
OUT UINT64 *Address
)
{
ASSERT (Context != NULL);
ASSERT (Address != NULL);
//
// This feature is currently unsupported.
//
DEBUG_RAISE ();
return RETURN_NOT_FOUND;
}
// FIXME:
RETURN_STATUS
InternalGetDebugTable (
IN CONST UE_LOADER_IMAGE_CONTEXT *Context,
OUT CONST UE_DEBUG_TABLE **DebugTable
);
RETURN_STATUS
UefiImageDebugPrintSegmentsUe (
IN OUT UE_LOADER_IMAGE_CONTEXT *Context
)
{
RETURN_STATUS DebugStatus;
CONST UE_DEBUG_TABLE *DebugTable;
CONST CHAR8 *Name;
CONST UE_SEGMENT *Segments;
UINT8 LastSegmentIndex;
UINT8 SegmentIndex;
UINT32 SectionFileOffset;
UINT32 SegmentImageAddress;
CONST UE_SEGMENT_NAME *NameTable;
UINT32 ImageSize;
DebugStatus = InternalGetDebugTable (Context, &DebugTable);
LastSegmentIndex = UeGetSegments (Context, &Segments);
NameTable = UE_DEBUG_TABLE_SEGMENT_NAMES (DebugTable);
SectionFileOffset = UeGetSectionsFileOffset (Context);
//
// The first Image segment must begin the Image memory space.
//
SegmentImageAddress = 0;
for (SegmentIndex = 0; SegmentIndex <= LastSegmentIndex; ++SegmentIndex) {
if (!RETURN_ERROR (DebugStatus)) {
Name = (CONST CHAR8 *) NameTable[DebugTable->SymbolsPathSize];
} 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",
" ImageSize - 0x%08x\n"
" ImageAddress - 0x%08x\n"
" FileSize - 0x%08x\n"
" FileOffset - 0x%08x\n"
" Permissions - 0x%08x\n",
Name[0], Name[1], Name[2], Name[3], Name[4], Name[5], Name[6], Name[7],
ImageSize,
SegmentImageAddress,
Segments[SegmentIndex].FileSize,
SectionFileOffset,
UE_SEGMENT_PERMISSIONS (Segments[SegmentIndex].ImageInfo)
));
SegmentImageAddress += ImageSize;
SectionFileOffset += Segments[SegmentIndex].FileSize;
}
return RETURN_SUCCESS;
}

View File

@ -1,29 +0,0 @@
#ifndef UE_SUPPORT_H_
#define UE_SUPPORT_H_
#include <Library/UeImageLib.h>
#include <Library/UefiImageLib.h>
UEFI_IMAGE_RECORD *
UefiImageLoaderGetImageRecordUe (
IN OUT UE_LOADER_IMAGE_CONTEXT *Context
);
RETURN_STATUS
UefiImageDebugLocateImageUe (
OUT UE_LOADER_IMAGE_CONTEXT *Context,
IN UINTN Address
);
RETURN_STATUS
UefiImageGetFixedAddressUe (
IN OUT UE_LOADER_IMAGE_CONTEXT *Context,
OUT UINT64 *Address
);
RETURN_STATUS
UefiImageDebugPrintSegmentsUe (
IN OUT UE_LOADER_IMAGE_CONTEXT *Context
);
#endif // UE_SUPPORT_H_

View File

@ -1,286 +0,0 @@
/** @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
**/
#define UEFI_IMAGE_LOADER_IMAGE_CONTEXT UE_LOADER_IMAGE_CONTEXT
#define UEFI_IMAGE_LOADER_RUNTIME_CONTEXT UE_LOADER_RUNTIME_CONTEXT
#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"
RETURN_STATUS
UefiImageInitializeContextPreHash (
OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context,
IN CONST VOID *FileBuffer,
IN UINT32 FileSize
)
{
return UeInitializeContextPreHash (Context, FileBuffer, FileSize);
}
RETURN_STATUS
UefiImageInitializeContextPostHash (
OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context
)
{
return UeInitializeContextPostHash (Context);
}
BOOLEAN
UefiImageHashImageDefault (
IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context,
IN OUT VOID *HashContext,
IN UEFI_IMAGE_LOADER_HASH_UPDATE HashUpdate
)
{
return UeHashImageDefault (Context, HashContext, HashUpdate);
}
RETURN_STATUS
UefiImageLoadImage (
IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context,
OUT VOID *Destination,
IN UINT32 DestinationSize
)
{
return UeLoadImage (Context, Destination, DestinationSize);
}
BOOLEAN
UefiImageImageIsInplace (
IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context
)
{
ASSERT (Context != NULL);
//
// FIXME: Implement
//
return FALSE;
}
RETURN_STATUS
UefiImageLoadImageInplace (
IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context
)
{
return UeLoadImageInplace (Context);
}
RETURN_STATUS
UefiImageLoaderGetRuntimeContextSize (
IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context,
OUT UINT32 *Size
)
{
return UeLoaderGetRuntimeContextSize (Context, Size);
}
RETURN_STATUS
UefiImageRelocateImage (
IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context,
IN UINT64 BaseAddress,
OUT UEFI_IMAGE_LOADER_RUNTIME_CONTEXT *RuntimeContext OPTIONAL,
IN UINT32 RuntimeContextSize
)
{
RETURN_STATUS Status;
Status = UeRelocateImage (Context, BaseAddress);
if (!RETURN_ERROR (Status)) {
UefiImageLoaderRelocateImageExtraAction (Context);
}
return Status;
}
RETURN_STATUS
UefiImageRuntimeRelocateImage (
IN OUT VOID *Image,
IN UINT32 ImageSize,
IN UINT64 BaseAddress,
IN CONST UEFI_IMAGE_LOADER_RUNTIME_CONTEXT *RuntimeContext
)
{
return UeRelocateImageForRuntime (
Image,
ImageSize,
BaseAddress,
RuntimeContext
);
}
VOID
UefiImageDiscardSegments (
IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context
)
{
ASSERT (Context != NULL);
//
// Anything discardable is not loaded in the first place.
//
}
RETURN_STATUS
UefiImageGetSymbolsPath (
IN CONST UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context,
OUT CONST CHAR8 **SymbolsPath,
OUT UINT32 *SymbolsPathSize
)
{
return UeGetSymbolsPath (Context, SymbolsPath, SymbolsPathSize);
}
RETURN_STATUS
UefiImageGetFirstCertificate (
IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context,
OUT CONST WIN_CERTIFICATE **Certificate
)
{
return UeGetFirstCertificate (Context, Certificate);
}
RETURN_STATUS
UefiImageGetNextCertificate (
IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context,
IN OUT CONST WIN_CERTIFICATE **Certificate
)
{
return UeGetNextCertificate (Context, Certificate);
}
RETURN_STATUS
UefiImageGetHiiDataRva (
IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context,
OUT UINT32 *HiiRva,
OUT UINT32 *HiiSize
)
{
return UeGetHiiDataRva (Context, HiiRva, HiiSize);
}
UINT32
UefiImageGetEntryPointAddress (
IN CONST UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context
)
{
return UeGetAddressOfEntryPoint (Context);
}
UINT16
UefiImageGetMachine (
IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context
)
{
return UeGetMachine (Context);
}
UINT16
UefiImageGetSubsystem (
IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context
)
{
return UeGetSubsystem (Context);
}
UINT32
UefiImageGetSegmentAlignment (
IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context
)
{
return UeGetSegmentAlignment (Context);
}
UINT32
UefiImageGetImageSize (
IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context
)
{
return UeGetImageSize (Context);
}
UINT32
UefiImageGetImageSizeInplace (
IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context
)
{
return UeGetImageSizeInplace (Context);
}
UINT64
UefiImageGetPreferredAddress (
IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context
)
{
return UeGetPreferredAddress (Context);
}
BOOLEAN
UefiImageGetRelocsStripped (
IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context
)
{
return UeGetRelocsStripped (Context);
}
UINTN
UefiImageLoaderGetImageAddress (
IN CONST UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context
)
{
return UeLoaderGetImageAddress (Context);
}
UEFI_IMAGE_RECORD *
UefiImageLoaderGetImageRecord (
IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context
)
{
return UefiImageLoaderGetImageRecordUe (Context);
}
RETURN_STATUS
UefiImageDebugLocateImage (
OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context,
IN UINTN Address
)
{
return UefiImageDebugLocateImageUe (Context, Address);
}
RETURN_STATUS
UefiImageGetFixedAddress (
IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context,
OUT UINT64 *Address
)
{
return UefiImageGetFixedAddressUe (
Context,
Address
);
}
VOID
UefiImageDebugPrintSegments (
IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context
)
{
UefiImageDebugPrintSegmentsUe (Context);
}

View File

@ -60,8 +60,6 @@
MdePkg/Library/BaseArmTrngLibNull/BaseArmTrngLibNull.inf
MdePkg/Library/BasePeCoffLib2/BasePeCoffLib2.inf
MdePkg/Library/BaseUefiImageLib/BaseUefiImageLibPeCoff.inf
MdePkg/Library/BaseUeImageLib/BaseUeImageLib.inf
MdePkg/Library/BaseUefiImageLib/BaseUefiImageLibUe.inf
MdePkg/Library/BaseUefiImageExtraActionLibNull/BaseUefiImageExtraActionLibNull.inf
MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.inf
MdePkg/Library/BasePostCodeLibDebug/BasePostCodeLibDebug.inf