mirror of
https://github.com/acidanthera/audk.git
synced 2025-09-24 10:17:45 +02:00
Drop premature UE support
This commit is contained in:
parent
cd0e8aa6ad
commit
2f91fddf99
@ -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
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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,
|
||||
|
@ -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)\
|
||||
|
@ -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;
|
||||
}
|
@ -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_
|
@ -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_
|
@ -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_
|
@ -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
@ -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
|
@ -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;
|
||||
}
|
@ -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_
|
@ -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);
|
||||
}
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user