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
|
PROJECT = ImageTool
|
||||||
OBJS = $(PROJECT).o
|
OBJS = $(PROJECT).o
|
||||||
OBJS += Image.o PeEmit.o PeScan.o UeEmit.o ElfScan.o BinEmit.o
|
OBJS += Image.o PeEmit.o PeScan.o ElfScan.o BinEmit.o
|
||||||
OBJS += BaseAlignment.o BaseBitOverflow.o UeImageLib.o UefiImageExtraActionLib.o
|
OBJS += BaseAlignment.o BaseBitOverflow.o UefiImageExtraActionLib.o
|
||||||
OBJS += PeCoffInit.o PeCoffInfo.o PeCoffLoad.o PeCoffRelocate.o PeCoffHii.o PeCoffDebug.o
|
OBJS += PeCoffInit.o PeCoffInfo.o PeCoffLoad.o PeCoffRelocate.o PeCoffHii.o PeCoffDebug.o
|
||||||
|
|
||||||
DEBUG = 1
|
DEBUG = 1
|
||||||
@ -23,8 +23,7 @@ CFLAGS += -include Pcds.h -Werror
|
|||||||
|
|
||||||
VPATH += ../../MdePkg/Library/BaseOverflowLib:$\
|
VPATH += ../../MdePkg/Library/BaseOverflowLib:$\
|
||||||
../../MdePkg/Library/BasePeCoffLib2:$\
|
../../MdePkg/Library/BasePeCoffLib2:$\
|
||||||
../../MdePkg/Library/BaseUefiImageExtraActionLibNull:$\
|
../../MdePkg/Library/BaseUefiImageExtraActionLibNull
|
||||||
../../MdePkg/Library/BaseUeImageLib
|
|
||||||
|
|
||||||
Tools: Tool32 Tool64
|
Tools: Tool32 Tool64
|
||||||
|
|
||||||
|
@ -13,70 +13,6 @@
|
|||||||
|
|
||||||
image_tool_image_info_t mImageInfo;
|
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
|
static
|
||||||
RETURN_STATUS
|
RETURN_STATUS
|
||||||
@ -533,19 +469,6 @@ int main (int argc, const char *argv[])
|
|||||||
raise ();
|
raise ();
|
||||||
return -1;
|
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;
|
return 0;
|
||||||
|
@ -12,9 +12,7 @@
|
|||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
#include <IndustryStandard/PeImage2.h>
|
#include <IndustryStandard/PeImage2.h>
|
||||||
#include <IndustryStandard/UeImage.h>
|
|
||||||
#include <Library/PeCoffLib2.h>
|
#include <Library/PeCoffLib2.h>
|
||||||
#include <Library/UeImageLib.h>
|
|
||||||
#include <Library/BaseLib.h>
|
#include <Library/BaseLib.h>
|
||||||
#include <Library/BaseMemoryLib.h>
|
#include <Library/BaseMemoryLib.h>
|
||||||
#include <Library/BaseOverflowLib.h>
|
#include <Library/BaseOverflowLib.h>
|
||||||
@ -150,12 +148,6 @@ ImageConvertToXip (
|
|||||||
image_tool_image_info_t *Image
|
image_tool_image_info_t *Image
|
||||||
);
|
);
|
||||||
|
|
||||||
void *
|
|
||||||
ToolImageEmitUe (
|
|
||||||
const image_tool_image_info_t *Image,
|
|
||||||
uint32_t *FileSize
|
|
||||||
);
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
ToolContextConstructPe (
|
ToolContextConstructPe (
|
||||||
OUT image_tool_image_info_t *Image,
|
OUT image_tool_image_info_t *Image,
|
||||||
|
@ -17,11 +17,10 @@ OUT_DIR = .\Windows_$(INFIX)
|
|||||||
|
|
||||||
OV = $(UDK_PATH)\MdePkg\Library\BaseOverflowLib
|
OV = $(UDK_PATH)\MdePkg\Library\BaseOverflowLib
|
||||||
PE = $(UDK_PATH)\MdePkg\Library\BasePeCoffLib2
|
PE = $(UDK_PATH)\MdePkg\Library\BasePeCoffLib2
|
||||||
UE = $(UDK_PATH)\MdePkg\Library\BaseUeImageLib
|
|
||||||
UA = $(UDK_PATH)\MdePkg\Library\BaseUefiImageExtraActionLibNull
|
UA = $(UDK_PATH)\MdePkg\Library\BaseUefiImageExtraActionLibNull
|
||||||
|
|
||||||
OBJECTS = ImageTool.obj Image.obj PeEmit.obj PeScan.obj UeEmit.obj ElfScan.obj BinEmit.obj
|
OBJECTS = ImageTool.obj Image.obj PeEmit.obj PeScan.obj ElfScan.obj BinEmit.obj
|
||||||
OBJECTS = $(OBJECTS) {$(OV)}BaseAlignment.obj BaseBitOverflow.obj {$(UE)}UeImageLib.obj {$(UA)}UefiImageExtraActionLib.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
|
OBJECTS = $(OBJECTS) {$(PE)}PeCoffInit.obj PeCoffInfo.obj PeCoffRelocate.obj PeCoffLoad.obj PeCoffHii.obj PeCoffDebug.obj
|
||||||
|
|
||||||
BASE = $(UDK_PATH)\MdePkg\Library\BaseLib
|
BASE = $(UDK_PATH)\MdePkg\Library\BaseLib
|
||||||
@ -74,10 +73,6 @@ cleanall:
|
|||||||
$(CC) -c $(CFLAGS) $(INC) /FI Pcds.h $< -Fo$@
|
$(CC) -c $(CFLAGS) $(INC) /FI Pcds.h $< -Fo$@
|
||||||
@move $@ $(OUT_DIR)\
|
@move $@ $(OUT_DIR)\
|
||||||
|
|
||||||
{$(UE)}.c.obj :
|
|
||||||
$(CC) -c $(CFLAGS) $(INC) /FI Pcds.h $< -Fo$@
|
|
||||||
@move $@ $(OUT_DIR)\
|
|
||||||
|
|
||||||
{$(UA)}.c.obj :
|
{$(UA)}.c.obj :
|
||||||
$(CC) -c $(CFLAGS) $(INC) $< -Fo$@
|
$(CC) -c $(CFLAGS) $(INC) $< -Fo$@
|
||||||
@move $@ $(OUT_DIR)\
|
@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/BaseArmTrngLibNull/BaseArmTrngLibNull.inf
|
||||||
MdePkg/Library/BasePeCoffLib2/BasePeCoffLib2.inf
|
MdePkg/Library/BasePeCoffLib2/BasePeCoffLib2.inf
|
||||||
MdePkg/Library/BaseUefiImageLib/BaseUefiImageLibPeCoff.inf
|
MdePkg/Library/BaseUefiImageLib/BaseUefiImageLibPeCoff.inf
|
||||||
MdePkg/Library/BaseUeImageLib/BaseUeImageLib.inf
|
|
||||||
MdePkg/Library/BaseUefiImageLib/BaseUefiImageLibUe.inf
|
|
||||||
MdePkg/Library/BaseUefiImageExtraActionLibNull/BaseUefiImageExtraActionLibNull.inf
|
MdePkg/Library/BaseUefiImageExtraActionLibNull/BaseUefiImageExtraActionLibNull.inf
|
||||||
MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.inf
|
MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.inf
|
||||||
MdePkg/Library/BasePostCodeLibDebug/BasePostCodeLibDebug.inf
|
MdePkg/Library/BasePostCodeLibDebug/BasePostCodeLibDebug.inf
|
||||||
|
Loading…
x
Reference in New Issue
Block a user