ImageTool: Rework PeEmit with dynamically-growing buffers

This commit is contained in:
Mikhail Krichanov 2023-12-15 16:28:15 +03:00
parent 5a8fe7214e
commit 410e9987f3
31 changed files with 1246 additions and 1270 deletions

View File

@ -134,8 +134,8 @@
<Command.XCODE>
"$(CC)" $(DEPS_FLAGS) $(CC_FLAGS) -o ${dst} $(INC) ${src}
## Early stages on ARM/AArch64 execute with strict alignment enabled and will crash,
# when compiler generates misaligned access.
## Early stages on ARM/AArch64 execute with strict alignment enabled and will crash,
# when compiler generates misaligned access.
#
[C-Code-File.BASE.AARCH64,C-Code-File.SEC.AARCH64,C-Code-File.PEI_CORE.AARCH64,C-Code-File.PEIM.AARCH64,C-Code-File.BASE.ARM,C-Code-File.SEC.ARM,C-Code-File.PEI_CORE.ARM,C-Code-File.PEIM.ARM]
<InputFile>
@ -352,7 +352,7 @@
$(OUTPUT_DIR)(+)$(MODULE_NAME).map
<Command.MSFT, Command.INTEL, Command.CLANGPDB>
ImageTool GenImage -c PE -t $(MODULE_TYPE) -o ${dst} ${src}
ImageTool GenImage -c PE -x -t $(MODULE_TYPE) -o ${dst} ${src}
$(CP) ${dst} $(DEBUG_DIR)
$(CP) ${dst} $(BIN_DIR)(+)$(MODULE_NAME_GUID).efi
-$(CP) $(DEBUG_DIR)(+)*.map $(OUTPUT_DIR)
@ -362,7 +362,7 @@
$(CP) ${src} $(DEBUG_DIR)(+)$(MODULE_NAME).strip
$(OBJCOPY) $(OBJCOPY_STRIPFLAG) $(DEBUG_DIR)(+)$(MODULE_NAME).strip
ImageTool GenImage -c PE -t $(MODULE_TYPE) -o ${dst} $(DEBUG_DIR)(+)$(MODULE_NAME).strip
ImageTool GenImage -c PE -x -t $(MODULE_TYPE) -d ${src} -o ${dst} $(DEBUG_DIR)(+)$(MODULE_NAME).strip
$(CP) ${dst} $(DEBUG_DIR)
$(CP) ${dst} $(BIN_DIR)(+)$(MODULE_NAME_GUID).efi
@ -373,7 +373,7 @@
"$(MTOC)" -subsystem $(MODULE_TYPE) $(MTOC_FLAGS) ${src} $(DEBUG_DIR)(+)$(MODULE_NAME).pecoff
# create symbol file for GDB debug
-$(DSYMUTIL) ${src}
ImageTool GenImage -c PE -t $(MODULE_TYPE) -o ${dst} $(DEBUG_DIR)(+)$(MODULE_NAME).pecoff
ImageTool GenImage -c PE -x -t $(MODULE_TYPE) -o ${dst} $(DEBUG_DIR)(+)$(MODULE_NAME).pecoff
$(CP) ${dst} $(DEBUG_DIR)
$(CP) ${dst} $(BIN_DIR)(+)$(MODULE_NAME_GUID).efi
-$(CP) $(DEBUG_DIR)(+)*.map $(OUTPUT_DIR)

View File

@ -19,9 +19,6 @@ CreateEntry (
EFI_IMAGE_RESOURCE_DIRECTORY *RDir;
EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY *Entry;
assert (HiiSectionHeader != NULL);
assert (HiiSectionOffset != NULL);
RDir = (EFI_IMAGE_RESOURCE_DIRECTORY *)(HiiSectionHeader + *HiiSectionOffset);
*HiiSectionOffset += sizeof (EFI_IMAGE_RESOURCE_DIRECTORY);
RDir->NumberOfNamedEntries = 1;
@ -49,11 +46,6 @@ CreateStringEntry (
{
EFI_IMAGE_RESOURCE_DIRECTORY_STRING *RDStr;
assert (Entry != NULL);
assert (HiiSectionHeader != NULL);
assert (HiiSectionOffset != NULL);
assert (String != NULL);
Entry->u1.s.NameOffset = *HiiSectionOffset;
RDStr = (EFI_IMAGE_RESOURCE_DIRECTORY_STRING *)(HiiSectionHeader + *HiiSectionOffset);
RDStr->Length = (UINT16)StrLen (String);
@ -78,8 +70,6 @@ InitializeHiiResouceSectionHeader (
EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY *LangRDirEntry;
EFI_IMAGE_RESOURCE_DATA_ENTRY *ResourceDataEntry;
assert (HiiSectionHeader != NULL);
HiiSectionOffset = 0;
//
// Create Type, Name, Language entries
@ -123,10 +113,6 @@ ConstructHii (
UINT32 FileSize;
UINT8 NumberOfFormPackages;
assert (Hii != NULL);
assert (HiiGuid != NULL);
assert (FileNames != NULL);
NumberOfFormPackages = 0;
EndPackage.Length = sizeof (EFI_HII_PACKAGE_HEADER);
@ -173,7 +159,7 @@ ConstructHii (
CopyGuid (&HiiPackageListHeader.PackageListGuid, HiiGuid);
HiiPackageData = calloc (1, HiiPackageListHeader.PackageLength);
HiiPackageData = AllocateZeroPool (HiiPackageListHeader.PackageLength);
if (HiiPackageData == NULL) {
return RETURN_OUT_OF_RESOURCES;
}
@ -185,6 +171,7 @@ ConstructHii (
File = UserReadFile (FileNames[Index], &FileSize);
if (File == NULL) {
fprintf (stderr, "ImageTool: Could not open %s: %s\n", FileNames[Index], strerror (errno));
free (HiiPackageData);
return RETURN_ABORTED;
}

View File

@ -0,0 +1,215 @@
#include <assert.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include <Base.h>
#include <Library/BaseOverflowLib.h>
#include "ImageTool.h"
#include "DynamicBuffer.h"
#define IMAGE_TOOL_DYNAMIC_BUFFER_GROWTH 0x1000
void
ImageToolBufferInit (
image_tool_dynamic_buffer *Buffer
)
{
memset (Buffer, 0, sizeof (*Buffer));
}
static
uint32_t
ImageToolBufferExpand (
image_tool_dynamic_buffer *Buffer,
uint32_t Size
)
{
bool Overflow;
uint32_t NewAllocatedSize;
uint8_t *NewMemory;
uint32_t Offset;
assert (Buffer->DataSize <= Buffer->AllocatedSize);
assert (IS_ALIGNED (Buffer->AllocatedSize, IMAGE_TOOL_DYNAMIC_BUFFER_GROWTH));
if (Buffer->AllocatedSize - Buffer->DataSize < Size) {
Overflow = BaseOverflowAlignUpU32 (
Size,
IMAGE_TOOL_DYNAMIC_BUFFER_GROWTH,
&NewAllocatedSize
);
if (Overflow) {
DEBUG_RAISE ();
return MAX_UINT32;
}
Overflow = BaseOverflowAddU32 (
NewAllocatedSize,
Buffer->AllocatedSize,
&NewAllocatedSize
);
if (Overflow) {
DEBUG_RAISE ();
return MAX_UINT32;
}
NewMemory = AllocatePool (NewAllocatedSize);
if (NewMemory == NULL) {
DEBUG_RAISE ();
return MAX_UINT32;
}
if (Buffer->Memory != NULL) {
memmove (NewMemory, Buffer->Memory, Buffer->DataSize);
FreePool (Buffer->Memory);
}
memset (
NewMemory + Buffer->DataSize,
0,
NewAllocatedSize - Buffer->DataSize
);
Buffer->Memory = NewMemory;
Buffer->AllocatedSize = NewAllocatedSize;
}
Offset = Buffer->DataSize;
Buffer->DataSize += Size;
return Offset;
}
void
ImageToolBufferRead (
void *Data,
uint32_t Size,
const image_tool_dynamic_buffer *Buffer,
uint32_t Offset
)
{
assert (Offset + Size > Offset);
assert (Offset + Size <= Buffer->DataSize);
memmove (Data, &Buffer->Memory[Offset], Size);
}
void
ImageToolBufferWrite (
image_tool_dynamic_buffer *Buffer,
uint32_t Offset,
const void *Data,
uint32_t Size
)
{
assert (Offset + Size > Offset);
assert (Offset + Size <= Buffer->DataSize);
memmove (&Buffer->Memory[Offset], Data, Size);
}
uint32_t
ImageToolBufferAppend (
image_tool_dynamic_buffer *Buffer,
const void *Data,
uint32_t Size
)
{
uint32_t Offset;
Offset = ImageToolBufferExpand (Buffer, Size);
if (Offset != MAX_UINT32) {
memmove (&Buffer->Memory[Offset], Data, Size);
}
return Offset;
}
uint32_t
ImageToolBufferAppendReserve (
image_tool_dynamic_buffer *Buffer,
uint32_t Size
)
{
uint32_t Offset;
Offset = ImageToolBufferExpand (Buffer, Size);
if (Offset != MAX_UINT32) {
memset (&Buffer->Memory[Offset], 0, Size);
}
return Offset;
}
uint32_t
ImageToolBufferAppendReserveAlign (
image_tool_dynamic_buffer *Buffer,
uint32_t Alignment
)
{
assert (IS_POW2 (Alignment));
return ImageToolBufferAppendReserve (
Buffer,
ALIGN_VALUE_ADDEND (ImageToolBufferGetSize (Buffer), Alignment)
);
}
void *
ImageToolBufferGetPointer (
const image_tool_dynamic_buffer *Buffer,
uint32_t Offset
)
{
assert (Offset < Buffer->DataSize);
return &Buffer->Memory[Offset];
}
uint32_t
ImageToolBufferGetSize (
const image_tool_dynamic_buffer *Buffer
)
{
return Buffer->DataSize;
}
void *
ImageToolBufferDump (
uint32_t *Size,
image_tool_dynamic_buffer *Buffer
)
{
void *Data;
uint32_t DataSize;
if (Buffer->Memory == NULL) {
return NULL;
}
DataSize = ImageToolBufferGetSize (Buffer);
Data = AllocateCopyPool (DataSize, Buffer->Memory);
if (Data == NULL) {
return NULL;
}
*Size = DataSize;
return Data;
}
void
ImageToolBufferFree (
image_tool_dynamic_buffer *Buffer
)
{
if (Buffer->Memory != NULL) {
FreePool (Buffer->Memory);
}
ImageToolBufferInit (Buffer);
}

View File

@ -0,0 +1,74 @@
#ifndef DYNAMIC_BUFFER_H
#define DYNAMIC_BUFFER_H
#include <stdint.h>
typedef struct {
uint32_t AllocatedSize;
uint32_t DataSize;
uint8_t *Memory;
} image_tool_dynamic_buffer;
void
ImageToolBufferInit (
image_tool_dynamic_buffer *Buffer
);
uint32_t
ImageToolBufferAppend (
image_tool_dynamic_buffer *Buffer,
const void *Data,
uint32_t Size
);
uint32_t
ImageToolBufferAppendReserve (
image_tool_dynamic_buffer *Buffer,
uint32_t Size
);
uint32_t
ImageToolBufferAppendReserveAlign (
image_tool_dynamic_buffer *Buffer,
uint32_t Alignment
);
void
ImageToolBufferRead (
void *Data,
uint32_t Size,
const image_tool_dynamic_buffer *Buffer,
uint32_t Offset
);
void
ImageToolBufferWrite (
image_tool_dynamic_buffer *Buffer,
uint32_t Offset,
const void *Data,
uint32_t Size
);
void *
ImageToolBufferGetPointer (
const image_tool_dynamic_buffer *Buffer,
uint32_t Offset
);
uint32_t
ImageToolBufferGetSize (
const image_tool_dynamic_buffer *Buffer
);
void *
ImageToolBufferDump (
uint32_t *Size,
image_tool_dynamic_buffer *Buffer
);
void
ImageToolBufferFree (
image_tool_dynamic_buffer *Buffer
);
#endif // DYNAMIC_BUFFER_H

View File

@ -103,8 +103,6 @@ IsShdrLoadable (
IN const Elf_Shdr *Shdr
)
{
assert (Shdr != NULL);
return (Shdr->sh_flags & SHF_ALLOC) != 0;
}
@ -360,7 +358,12 @@ SetRelocs (
//
break;
default:
fprintf (stderr, "ImageTool: Unsupported ELF EM_X86_64 relocation 0x%llx in %s\n", ELF_R_TYPE(Rel->r_info), ImageInfo->DebugInfo.SymbolsPath);
fprintf (
stderr,
"ImageTool: Unsupported ELF EM_X86_64 relocation 0x%llx in %s\n",
(unsigned long long)ELF_R_TYPE(Rel->r_info),
ImageInfo->DebugInfo.SymbolsPath
);
return RETURN_INCOMPATIBLE_VERSION;
}
} else if (Ehdr->e_machine == EM_AARCH64) {
@ -402,7 +405,12 @@ SetRelocs (
break;
default:
fprintf (stderr, "ImageTool: Unsupported ELF EM_AARCH64 relocation 0x%llx in %s\n", ELF_R_TYPE(Rel->r_info), ImageInfo->DebugInfo.SymbolsPath);
fprintf (
stderr,
"ImageTool: Unsupported ELF EM_AARCH64 relocation 0x%llx in %s\n",
(unsigned long long)ELF_R_TYPE(Rel->r_info),
ImageInfo->DebugInfo.SymbolsPath
);
return RETURN_INCOMPATIBLE_VERSION;
}
}
@ -571,7 +579,7 @@ CreateIntermediate (
return RETURN_VOLUME_CORRUPTED;
}
Segments = calloc (1, sizeof (*Segments) * ImageInfo->SegmentInfo.NumSegments);
Segments = AllocateZeroPool (sizeof (*Segments) * ImageInfo->SegmentInfo.NumSegments);
if (Segments == NULL) {
fprintf (stderr, "ImageTool: Could not allocate memory for Segments\n");
return RETURN_OUT_OF_RESOURCES;
@ -580,7 +588,7 @@ CreateIntermediate (
ImageInfo->SegmentInfo.Segments = Segments;
if (NumRelocs != 0) {
Relocs = calloc (1, sizeof (*Relocs) * NumRelocs);
Relocs = AllocateZeroPool (sizeof (*Relocs) * NumRelocs);
if (Relocs == NULL) {
fprintf (stderr, "ImageTool: Could not allocate memory for Relocs\n");
return RETURN_OUT_OF_RESOURCES;
@ -606,7 +614,7 @@ CreateIntermediate (
return RETURN_VOLUME_CORRUPTED;
}
Segments[SIndex].Name = calloc (1, strlen (Name) + 1);
Segments[SIndex].Name = AllocateZeroPool (strlen (Name) + 1);
if (Segments[SIndex].Name == NULL) {
fprintf (stderr, "ImageTool: Could not allocate memory for Segment #%d Name\n", Index);
return RETURN_OUT_OF_RESOURCES;
@ -620,7 +628,7 @@ CreateIntermediate (
Segments[SIndex].Write = (Shdr->sh_flags & SHF_WRITE) != 0;
Segments[SIndex].Execute = (Shdr->sh_flags & SHF_EXECINSTR) != 0;
Segments[SIndex].Data = calloc (1, Segments[SIndex].ImageSize);
Segments[SIndex].Data = AllocateZeroPool (Segments[SIndex].ImageSize);
if (Segments[SIndex].Data == NULL) {
fprintf (stderr, "ImageTool: Could not allocate memory for Segment #%d Data\n", Index);
return RETURN_OUT_OF_RESOURCES;
@ -652,7 +660,6 @@ ScanElf (
const Elf_Ehdr *Ehdr;
Elf_Addr BaseAddress;
assert (ImageInfo != NULL);
assert (File != NULL || FileSize == 0);
Status = ParseElfFile (&Context, File, FileSize);
@ -667,7 +674,6 @@ ScanElf (
ImageInfo->HeaderInfo.BaseAddress = BaseAddress;
ImageInfo->HeaderInfo.EntryPointAddress = (uint32_t)(Ehdr->e_entry - BaseAddress);
ImageInfo->HeaderInfo.IsXip = true;
ImageInfo->SegmentInfo.SegmentAlignment = (uint32_t)Context.Alignment;
ImageInfo->RelocInfo.RelocsStripped = false;
@ -698,11 +704,11 @@ ScanElf (
return RETURN_INCOMPATIBLE_VERSION;
}
ImageInfo->DebugInfo.SymbolsPath = malloc (ImageInfo->DebugInfo.SymbolsPathLen + 1);
ImageInfo->DebugInfo.SymbolsPath = AllocatePool (ImageInfo->DebugInfo.SymbolsPathLen + 1);
if (ImageInfo->DebugInfo.SymbolsPath == NULL) {
fprintf (stderr, "ImageTool: Could not allocate memory for Debug Data\n");
return RETURN_OUT_OF_RESOURCES;
};
}
if (SymbolsPath != NULL) {
memmove (ImageInfo->DebugInfo.SymbolsPath, SymbolsPath, ImageInfo->DebugInfo.SymbolsPathLen + 1);

View File

@ -10,7 +10,7 @@ OBJS = $(PROJECT).o
OBJS += Image.o UefiImageScan.o PeEmit32.o PeEmit64.o PeEmitCommon.o PeScan.o ElfScan32.o ElfScan64.o ElfScanCommon.o BinEmit.o ImageToolEmit.o
OBJS += UefiImageExtraActionLib.o
OBJS += PeCoffInit.o PeCoffInfo.o PeCoffLoad.o PeCoffRelocate.o PeCoffHii.o PeCoffDebug.o PeCoffHash.o
OBJS += PeSupport.o UefiImageLib.o CommonSupport.o
OBJS += PeSupport.o UefiImageLib.o CommonSupport.o DynamicBuffer.o
WERROR = 1
DEBUG = 1

View File

@ -16,22 +16,18 @@ CheckToolImageSegment (
{
bool Overflow;
assert (Segment != NULL);
assert (PreviousEndAddress != NULL);
if (!IS_ALIGNED (Segment->ImageSize, SegmentInfo->SegmentAlignment)) {
raise ();
DEBUG_RAISE ();
return false;
}
if (Segment->Write && Segment->Execute) {
raise ();
DEBUG_RAISE ();
return false;
}
// FIXME: Expand prior segment
if (Segment->ImageAddress != *PreviousEndAddress) {
raise ();
DEBUG_RAISE ();
return false;
}
@ -41,7 +37,7 @@ CheckToolImageSegment (
PreviousEndAddress
);
if (Overflow) {
raise ();
DEBUG_RAISE ();
return false;
}
@ -58,21 +54,18 @@ CheckToolImageSegmentInfo (
uint32_t Index;
bool Result;
assert (SegmentInfo != NULL);
assert (ImageSize != NULL);
if (!IS_POW2 (SegmentInfo->SegmentAlignment)) {
raise ();
DEBUG_RAISE ();
return false;
}
if (SegmentInfo->NumSegments == 0) {
raise ();
DEBUG_RAISE ();
return false;
}
if (!IS_ALIGNED (SegmentInfo->Segments[0].ImageAddress, SegmentInfo->SegmentAlignment)) {
raise ();
DEBUG_RAISE ();
return false;
}
@ -84,7 +77,7 @@ CheckToolImageSegmentInfo (
ImageSize
);
if (!Result) {
raise ();
DEBUG_RAISE ();
return false;
}
}
@ -93,6 +86,32 @@ CheckToolImageSegmentInfo (
}
static
bool
CheckToolImageHeaderInfo (
const image_tool_header_info_t *HeaderInfo,
const image_tool_segment_info_t *SegmentInfo,
uint32_t ImageSize
)
{
if (SegmentInfo->Segments[0].ImageAddress > HeaderInfo->EntryPointAddress ||
HeaderInfo->EntryPointAddress > ImageSize) {
DEBUG_RAISE ();
return false;
}
if (!IS_ALIGNED (HeaderInfo->BaseAddress, SegmentInfo->SegmentAlignment)) {
DEBUG_RAISE ();
return false;
}
if (HeaderInfo->BaseAddress + ImageSize < HeaderInfo->BaseAddress) {
DEBUG_RAISE ();
return false;
}
return true;
}
const image_tool_segment_t *
ImageGetSegmentByAddress (
uint32_t *Address,
@ -102,9 +121,6 @@ ImageGetSegmentByAddress (
{
uint32_t Index;
assert (Address != NULL);
assert (SegmentInfo != NULL);
for (Index = 0; Index < SegmentInfo->NumSegments; ++Index) {
if ((SegmentInfo->Segments[Index].ImageAddress <= *Address)
&& (*Address < SegmentInfo->Segments[Index].ImageAddress + SegmentInfo->Segments[Index].ImageSize)) {
@ -117,22 +133,52 @@ ImageGetSegmentByAddress (
return NULL;
}
uint8_t
ToolImageGetRelocSize (
uint8_t Type
)
{
switch (Type) {
case EFI_IMAGE_REL_BASED_HIGHLOW:
{
return sizeof (UINT32);
}
case EFI_IMAGE_REL_BASED_DIR64:
{
return sizeof (UINT64);
}
#if 0
case EFI_IMAGE_REL_BASED_ARM_MOV32T:
{
return sizeof (UINT32);
}
#endif
default:
{
return 0;
}
}
}
static
bool
CheckToolImageReloc (
const image_tool_image_info_t *Image,
uint32_t ImageSize,
const image_tool_reloc_t *Reloc
const image_tool_reloc_t *Reloc,
uint8_t RelocSize
)
{
uint32_t RelocOffset;
uint32_t RemainingSize;
const image_tool_segment_t *Segment;
#if 0
uint16_t MovHigh;
uint16_t MovLow;
assert (Image != NULL);
assert (Reloc != NULL);
#endif
RelocOffset = Reloc->Target;
Segment = ImageGetSegmentByAddress (
@ -141,64 +187,40 @@ CheckToolImageReloc (
&Image->SegmentInfo
);
if (Segment == NULL) {
raise ();
DEBUG_RAISE ();
return false;
}
switch (Reloc->Type) {
case EFI_IMAGE_REL_BASED_HIGHLOW:
{
if (RemainingSize < sizeof (UINT32)) {
raise ();
return false;
}
if (RelocSize > RemainingSize) {
DEBUG_RAISE ();
return false;
}
break;
#if 0
if (Reloc->Type == EFI_IMAGE_REL_BASED_ARM_MOV32T) {
if (!IS_ALIGNED (Reloc->Target, ALIGNOF (UINT16))) {
DEBUG_RAISE ();
return false;
}
case EFI_IMAGE_REL_BASED_DIR64:
{
if (RemainingSize < sizeof (UINT64)) {
raise ();
return false;
}
break;
}
case EFI_IMAGE_REL_BASED_ARM_MOV32T:
{
if (RemainingSize < sizeof (UINT32)) {
raise ();
return false;
}
if (!IS_ALIGNED (Reloc->Target, ALIGNOF (UINT16))) {
raise ();
return false;
}
MovHigh = *(const uint16_t *)&Segment->Data[RelocOffset];
MovLow = *(const uint16_t *)&Segment->Data[RelocOffset + 2];
if (((MovHigh & 0xFBF0U) != 0xF200U && (MovHigh & 0xFBF0U) != 0xF2C0U) ||
(MovLow & 0x8000U) != 0) {
raise ();
return false;
}
break;
}
default:
{
raise ();
MovHigh = *(const uint16_t *)&Segment->Data[RelocOffset];
MovLow = *(const uint16_t *)&Segment->Data[RelocOffset + 2];
if (((MovHigh & 0xFBF0U) != 0xF200U && (MovHigh & 0xFBF0U) != 0xF2C0U) ||
(MovLow & 0x8000U) != 0) {
DEBUG_RAISE ();
return false;
}
}
#endif
/*if (Segment->Write) {
// FIXME: Update drivers?
if ((Image->HeaderInfo.Subsystem == EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER ||
Image->HeaderInfo.Subsystem == EFI_IMAGE_SUBSYSTEM_SAL_RUNTIME_DRIVER) &&
Segment->Write) {
printf("!!! writable reloc at %x !!!\n", Reloc->Target);
}*/
//DEBUG_RAISE ();
//return false;
}
return true;
}
@ -206,49 +228,52 @@ CheckToolImageReloc (
static
bool
CheckToolImageRelocInfo (
const image_tool_image_info_t *Image,
uint32_t ImageSize
const image_tool_image_info_t *Image
)
{
const image_tool_reloc_info_t *RelocInfo;
uint8_t RelocSize;
uint32_t MinRelocTarget;
uint32_t Index;
bool Result;
assert (Image != NULL);
RelocInfo = &Image->RelocInfo;
if (RelocInfo->NumRelocs == 0) {
return true;
}
if (RelocInfo->RelocsStripped && (RelocInfo->NumRelocs > 0)) {
raise ();
if (RelocInfo->RelocsStripped) {
DEBUG_RAISE ();
return false;
}
if (RelocInfo->NumRelocs > (MAX_UINT32 / sizeof (UINT16))) {
raise ();
DEBUG_RAISE ();
return false;
}
Result = CheckToolImageReloc (Image, ImageSize, &RelocInfo->Relocs[0]);
if (!Result) {
raise ();
return false;
}
MinRelocTarget = 0;
for (Index = 1; Index < RelocInfo->NumRelocs; ++Index) {
if (RelocInfo->Relocs[Index].Target < RelocInfo->Relocs[Index - 1].Target) {
assert (false);
for (Index = 0; Index < RelocInfo->NumRelocs; ++Index) {
if (RelocInfo->Relocs[Index].Target < MinRelocTarget) {
DEBUG_RAISE ();
return false;
}
Result = CheckToolImageReloc (Image, ImageSize, &RelocInfo->Relocs[Index]);
RelocSize = ToolImageGetRelocSize (RelocInfo->Relocs[Index].Type);
if (RelocSize == 0) {
DEBUG_RAISE ();
return false;
}
Result = CheckToolImageReloc (Image, &RelocInfo->Relocs[Index], RelocSize);
if (!Result) {
raise ();
DEBUG_RAISE ();
return false;
}
MinRelocTarget = RelocInfo->Relocs[Index].Target + RelocSize;
}
return true;
@ -260,14 +285,9 @@ CheckToolImageDebugInfo (
const image_tool_debug_info_t *DebugInfo
)
{
assert (DebugInfo != NULL);
if (DebugInfo->SymbolsPath != NULL) {
// FIXME: UE-only?
if (DebugInfo->SymbolsPathLen > MAX_UINT8) {
raise ();
return false;
}
if (DebugInfo->SymbolsPathLen > MAX_UINT8) {
DEBUG_RAISE ();
return false;
}
return true;
@ -281,23 +301,31 @@ CheckToolImage (
bool Result;
uint32_t ImageSize;
assert (Image != NULL);
Result = CheckToolImageSegmentInfo (&Image->SegmentInfo, &ImageSize);
if (!Result) {
raise ();
DEBUG_RAISE ();
return false;
}
Result = CheckToolImageRelocInfo (Image, ImageSize);
Result = CheckToolImageHeaderInfo (
&Image->HeaderInfo,
&Image->SegmentInfo,
ImageSize
);
if (!Result) {
raise ();
DEBUG_RAISE ();
return false;
}
Result = CheckToolImageRelocInfo (Image);
if (!Result) {
DEBUG_RAISE ();
return false;
}
Result = CheckToolImageDebugInfo (&Image->DebugInfo);
if (!Result) {
raise ();
DEBUG_RAISE ();
return false;
}
@ -316,10 +344,6 @@ ImageInitUnpaddedSize (
Segment = &Image->SegmentInfo.Segments[Index];
Segment->UnpaddedSize = Segment->ImageSize;
if (Image->HeaderInfo.IsXip) {
continue;
}
for (; Segment->UnpaddedSize > 0; --Segment->UnpaddedSize) {
if (Segment->Data[Segment->UnpaddedSize - 1] != 0) {
break;
@ -335,20 +359,33 @@ ToolImageDestruct (
{
uint8_t Index;
assert (Image != NULL);
if (Image->SegmentInfo.Segments != NULL) {
for (Index = 0; Index < Image->SegmentInfo.NumSegments; ++Index) {
free (Image->SegmentInfo.Segments[Index].Name);
free (Image->SegmentInfo.Segments[Index].Data);
if (Image->SegmentInfo.Segments[Index].Name != NULL) {
FreePool (Image->SegmentInfo.Segments[Index].Name);
}
if (Image->SegmentInfo.Segments[Index].Data != NULL) {
FreePool (Image->SegmentInfo.Segments[Index].Data);
}
}
free (Image->SegmentInfo.Segments);
if (Image->SegmentInfo.Segments != NULL) {
FreePool (Image->SegmentInfo.Segments);
}
}
free (Image->HiiInfo.Data);
free (Image->RelocInfo.Relocs);
free (Image->DebugInfo.SymbolsPath);
if (Image->HiiInfo.Data != NULL) {
FreePool (Image->HiiInfo.Data);
}
if (Image->RelocInfo.Relocs != NULL) {
FreePool (Image->RelocInfo.Relocs);
}
if (Image->DebugInfo.SymbolsPath != NULL) {
FreePool (Image->DebugInfo.SymbolsPath);
}
memset (Image, 0, sizeof (*Image));
}
@ -356,9 +393,12 @@ ToolImageDestruct (
bool
ToolImageRelocate (
image_tool_image_info_t *Image,
uint64_t BaseAddress
uint64_t BaseAddress,
uint32_t IgnorePrefix
)
{
const image_tool_segment_t *LastSegment;
uint32_t ImageSize;
uint64_t Adjust;
const image_tool_reloc_t *Reloc;
uint32_t RelocOffset;
@ -368,10 +408,28 @@ ToolImageRelocate (
uint32_t RelocTarget32;
uint64_t RelocTarget64;
if (!IS_ALIGNED (BaseAddress, Image->SegmentInfo.SegmentAlignment)) {
DEBUG_RAISE ();
return false;
}
Adjust = BaseAddress - Image->HeaderInfo.BaseAddress;
if (Adjust == 0) {
return TRUE;
return true;
}
LastSegment = &Image->SegmentInfo.Segments[Image->SegmentInfo.NumSegments - 1];
ImageSize = LastSegment->ImageAddress + LastSegment->ImageSize;
//
// When removing the image header prefix, BaseAddress + ImageSize may indeed
// overflow. The important part is that the address starting from the first
// image segment does not.
//
if (BaseAddress + ImageSize < BaseAddress + IgnorePrefix) {
DEBUG_RAISE ();
return false;
}
for (Index = 0; Index < Image->RelocInfo.NumRelocs; ++Index) {
@ -383,10 +441,7 @@ ToolImageRelocate (
&RemainingSize,
&Image->SegmentInfo
);
if (Segment == NULL) {
raise ();
return false;
}
assert (Segment != NULL);
switch (Reloc->Type) {
case EFI_IMAGE_REL_BASED_HIGHLOW:
@ -409,6 +464,7 @@ ToolImageRelocate (
break;
}
#if 0
case EFI_IMAGE_REL_BASED_ARM_MOV32T:
{
assert (RemainingSize >= sizeof (UINT32));
@ -417,10 +473,11 @@ ToolImageRelocate (
PeCoffThumbMovwMovtImmediateFixup (&Segment->Data[RelocOffset], Adjust);
break;
}
#endif
default:
{
raise ();
assert (false);
return false;
}
}
@ -494,7 +551,7 @@ ToolImageCompare (
sizeof (Image1->HeaderInfo)
);
if (CmpResult != 0) {
raise ();
DEBUG_RAISE ();
return false;
}
@ -510,7 +567,7 @@ ToolImageCompare (
OFFSET_OF (image_tool_segment_info_t, Segments)
);
if (CmpResult != 0) {
raise ();
DEBUG_RAISE ();
return false;
}
@ -521,7 +578,7 @@ ToolImageCompare (
OFFSET_OF (image_tool_segment_t, Name)
);
if (CmpResult != 0) {
raise ();
DEBUG_RAISE ();
return false;
}
@ -538,20 +595,22 @@ ToolImageCompare (
++NameIndex
) {
if (Name1[NameIndex] != Name2[NameIndex]) {
raise ();
DEBUG_RAISE ();
return false;
}
}
}
CmpResult = memcmp (
Image1->SegmentInfo.Segments[SegIndex].Data,
Image2->SegmentInfo.Segments[SegIndex].Data,
Image1->SegmentInfo.Segments[SegIndex].ImageSize
);
if (CmpResult != 0) {
raise ();
return false;
if (Image1->SegmentInfo.Segments[SegIndex].ImageSize != 0) {
CmpResult = memcmp (
Image1->SegmentInfo.Segments[SegIndex].Data,
Image2->SegmentInfo.Segments[SegIndex].Data,
Image1->SegmentInfo.Segments[SegIndex].ImageSize
);
if (CmpResult != 0) {
DEBUG_RAISE ();
return false;
}
}
}
@ -565,18 +624,20 @@ ToolImageCompare (
OFFSET_OF (image_tool_reloc_info_t, Relocs)
);
if (CmpResult != 0) {
raise ();
DEBUG_RAISE ();
return false;
}
CmpResult = memcmp (
Image1->RelocInfo.Relocs,
Image2->RelocInfo.Relocs,
Image1->RelocInfo.NumRelocs * sizeof (*Image1->RelocInfo.Relocs)
);
if (CmpResult != 0) {
raise ();
return false;
if (Image1->RelocInfo.NumRelocs != 0) {
CmpResult = memcmp (
Image1->RelocInfo.Relocs,
Image2->RelocInfo.Relocs,
Image1->RelocInfo.NumRelocs * sizeof (*Image1->RelocInfo.Relocs)
);
if (CmpResult != 0) {
DEBUG_RAISE ();
return false;
}
}
//
@ -589,18 +650,20 @@ ToolImageCompare (
OFFSET_OF (image_tool_hii_info_t, Data)
);
if (CmpResult != 0) {
raise ();
DEBUG_RAISE ();
return false;
}
CmpResult = memcmp (
Image1->HiiInfo.Data,
Image2->HiiInfo.Data,
Image1->HiiInfo.DataSize
);
if (CmpResult != 0) {
raise ();
return false;
if (Image1->HiiInfo.DataSize != 0) {
CmpResult = memcmp (
Image1->HiiInfo.Data,
Image2->HiiInfo.Data,
Image1->HiiInfo.DataSize
);
if (CmpResult != 0) {
DEBUG_RAISE ();
return false;
}
}
//
@ -613,12 +676,12 @@ ToolImageCompare (
OFFSET_OF (image_tool_debug_info_t, SymbolsPath)
);
if (CmpResult != 0) {
raise ();
DEBUG_RAISE ();
return false;
}
if ((Image1->DebugInfo.SymbolsPath != NULL) != (Image2->DebugInfo.SymbolsPath != NULL)) {
raise ();
DEBUG_RAISE ();
return false;
}
@ -628,7 +691,7 @@ ToolImageCompare (
Image2->DebugInfo.SymbolsPath
);
if (CmpResult != 0) {
raise ();
DEBUG_RAISE ();
return false;
}
}
@ -642,7 +705,11 @@ ToolImageStripRelocs (
)
{
Image->RelocInfo.NumRelocs = 0;
free (Image->RelocInfo.Relocs);
if (Image->RelocInfo.Relocs != NULL) {
FreePool (Image->RelocInfo.Relocs);
}
Image->RelocInfo.Relocs = NULL;
Image->RelocInfo.RelocsStripped = TRUE;

View File

@ -37,10 +37,6 @@ HiiSrc (
FILE *FilePtr;
UINT32 Index;
assert (FileNames != NULL);
assert (HiiName != NULL);
assert (Guid != NULL);
Status = AsciiStrToGuid (Guid, &HiiGuid);
if (RETURN_ERROR (Status)) {
fprintf (stderr, "ImageTool: Invalid GUID - %s\n", Guid);
@ -55,7 +51,7 @@ HiiSrc (
FilePtr = fopen (HiiName, "w");
if (FilePtr == NULL) {
free (Hii);
FreePool (Hii);
return RETURN_NO_MEDIA;
}
@ -113,7 +109,8 @@ HiiSrc (
" (CONST MODULE_HII_PACKAGE_LIST *)&mModuleHiiPackageList;\n"
);
free (Hii);
fclose (FilePtr);
FreePool (Hii);
return RETURN_SUCCESS;
}
@ -247,9 +244,6 @@ GetAcpi (
UINT16 Index;
UINT32 FileLength;
assert (PeName != NULL);
assert (AcpiName != NULL);
Pe = UserReadFile (PeName, &PeSize);
if (Pe == NULL) {
fprintf (stderr, "ImageTool: Could not open %s: %s\n", PeName, strerror (errno));
@ -353,9 +347,11 @@ RETURN_STATUS
GenExecutable (
IN const char *OutputFileName,
IN const char *InputFileName,
IN const char *SymbolsPath OPTIONAL,
IN const char *FormatName,
IN const char *TypeName,
IN const char *BaseAddress,
IN bool Xip,
IN bool Strip,
IN bool FixedAddress
)
@ -402,6 +398,10 @@ GenExecutable (
return RETURN_ABORTED;
}
if (SymbolsPath == NULL) {
SymbolsPath = InputFileName;
}
OutputFile = ToolImageEmit (
&OutputFileSize,
InputFile,
@ -410,18 +410,20 @@ GenExecutable (
Type,
BaseAddress != NULL,
NewBaseAddress,
InputFileName,
SymbolsPath,
Xip,
Strip,
FixedAddress
);
if (OutputFile == NULL) {
DEBUG_RAISE ();
return RETURN_ABORTED;
}
UserWriteFile (OutputFileName, OutputFile, OutputFileSize);
free (OutputFile);
FreePool (OutputFile);
return RETURN_SUCCESS;
}
@ -432,16 +434,18 @@ int main (int argc, const char *argv[])
UINT32 NumOfFiles;
const char *OutputName;
const char *InputName;
const char *SymbolsPath;
const char *FormatName;
const char *TypeName;
const char *BaseAddress;
bool Xip;
bool Strip;
bool FixedAddress;
int ArgIndex;
if (argc < 2) {
fprintf (stderr, "ImageTool: No command is specified\n");
raise ();
DEBUG_RAISE ();
return -1;
}
//
@ -452,16 +456,18 @@ int main (int argc, const char *argv[])
if (strcmp (argv[1], "GenImage") == 0) {
if (argc < 5) {
fprintf (stderr, "ImageTool: Command arguments are missing\n");
fprintf (stderr, " Usage: ImageTool GenImage [-c Format] [-t ModuleType] [-b BaseAddress] [-s] [-f] -o OutputFile InputFile\n");
raise ();
fprintf (stderr, " Usage: ImageTool GenImage [-c Format] [-t ModuleType] [-b BaseAddress] [-d SymbolsPath] [-x] [-s] [-f] -o OutputFile InputFile\n");
DEBUG_RAISE ();
return -1;
}
OutputName = NULL;
InputName = NULL;
SymbolsPath = NULL;
FormatName = NULL;
TypeName = NULL;
BaseAddress = NULL;
Xip = false;
Strip = false;
FixedAddress = false;
for (ArgIndex = 2; ArgIndex < argc; ++ArgIndex) {
@ -497,6 +503,16 @@ int main (int argc, const char *argv[])
}
BaseAddress = argv[ArgIndex];
} else if (strcmp (argv[ArgIndex], "-d") == 0) {
++ArgIndex;
if (ArgIndex == argc) {
fprintf (stderr, "Must specify an argument to -d\n");
return -1;
}
SymbolsPath = argv[ArgIndex];
} else if (strcmp (argv[ArgIndex], "-x") == 0) {
Xip = true;
} else if (strcmp (argv[ArgIndex], "-s") == 0) {
Strip = true;
} else if (strcmp (argv[ArgIndex], "-f") == 0) {
@ -524,21 +540,23 @@ int main (int argc, const char *argv[])
Status = GenExecutable (
OutputName,
InputName,
SymbolsPath,
FormatName,
TypeName,
BaseAddress,
Xip,
Strip,
FixedAddress
);
if (RETURN_ERROR (Status)) {
raise ();
DEBUG_RAISE ();
return -1;
}
} else if (strcmp (argv[1], "HiiSrc") == 0) {
if (argc < 5 || strcmp (argv[3], "-o") != 0) {
fprintf (stderr, "ImageTool: Command arguments are missing\n");
fprintf (stderr, " Usage: ImageTool HiiBin GUID -o OutputFile InputFile1 InputFile2 ...\n");
raise ();
DEBUG_RAISE ();
return -1;
}
@ -546,20 +564,20 @@ int main (int argc, const char *argv[])
Status = HiiSrc (argv[4], argv[2], &argv[5], NumOfFiles);
if (RETURN_ERROR (Status)) {
raise ();
DEBUG_RAISE ();
return -1;
}
} else if (strcmp (argv[1], "GetAcpi") == 0) {
if (argc != 5 || strcmp (argv[2], "-o") != 0) {
fprintf (stderr, "ImageTool: Command arguments are missing\n");
fprintf (stderr, " Usage: ImageTool GetAcpi -o OutputFile InputFile\n");
raise ();
DEBUG_RAISE ();
return -1;
}
Status = GetAcpi (argv[4], argv[3]);
if (RETURN_ERROR (Status)) {
raise ();
DEBUG_RAISE ();
return -1;
}
}

View File

@ -18,19 +18,12 @@
#include <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/BaseOverflowLib.h>
#include <Library/DebugLib.h>
#include <Library/MemoryAllocationLib.h>
#include <UserFile.h>
#define MAX_PE_ALIGNMENT 0x10000
#define raise() assert(false)
typedef struct {
EFI_IMAGE_DEBUG_DIRECTORY_ENTRY Dir;
EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY Nb10;
char Name[];
} DebugData;
#define PAGE(x) ((x) & ~4095U)
#define PAGE_OFF(x) ((x) & 4095U)
@ -39,9 +32,8 @@ typedef struct {
uint32_t EntryPointAddress;
uint16_t Machine;
uint16_t Subsystem;
uint8_t IsXip;
uint8_t FixedAddress;
uint8_t Reserved[6];
uint8_t Reserved[7];
} image_tool_header_info_t;
typedef struct {
@ -60,7 +52,8 @@ typedef struct {
typedef struct {
uint32_t SegmentAlignment;
uint32_t NumSegments;
uint16_t NumSegments;
uint8_t Reserved[2];
image_tool_segment_t *Segments;
} image_tool_segment_info_t;
@ -117,7 +110,8 @@ ImageInitUnpaddedSize (
bool
ToolImageRelocate (
image_tool_image_info_t *Image,
uint64_t BaseAddress
uint64_t BaseAddress,
uint32_t IgnorePrefix
);
void
@ -136,6 +130,11 @@ ToolImageStripRelocs (
image_tool_image_info_t *Image
);
uint8_t
ToolImageGetRelocSize (
uint8_t Type
);
RETURN_STATUS
ToolContextConstructUefiImage (
OUT image_tool_image_info_t *Image,
@ -153,6 +152,7 @@ void *
ToolImageEmitPe (
image_tool_image_info_t *Image,
uint32_t *FileSize,
bool Xip,
bool Strip
);
@ -182,4 +182,11 @@ ConstructHii (
OUT UINT32 *HiiSize
);
const image_tool_segment_t *
ImageGetSegmentByAddress (
uint32_t *Address,
uint32_t *RemainingSize,
const image_tool_segment_info_t *SegmentInfo
);
#endif // IMAGE_TOOL_H

View File

@ -33,9 +33,11 @@ ToolContextConstruct (
File,
FileSize
);
#ifndef IMAGE_TOOL_DISABLE_ELF
if (Status == RETURN_UNSUPPORTED) {
Status = ScanElf (ImageInfo, File, FileSize, SymbolsPath);
}
#endif
return Status;
}
@ -61,13 +63,13 @@ ValidateOutputFile (
NULL
);
if (EFI_ERROR (Status)) {
assert (false);
assert (Status == RETURN_OUT_OF_RESOURCES);
return Status;
}
Result = CheckToolImage (&OutputImageInfo);
if (!Result) {
raise ();
assert (false);
ToolImageDestruct (&OutputImageInfo);
return RETURN_UNSUPPORTED;
}
@ -94,6 +96,7 @@ ToolImageEmit (
IN bool Relocate,
IN uint64_t BaseAddress,
IN const char *SymbolsPath OPTIONAL,
IN bool Xip,
IN bool Strip,
IN bool FixedAddress
)
@ -138,12 +141,13 @@ ToolImageEmit (
Success = CheckToolImage (&ImageInfo);
if (!Success) {
DEBUG_RAISE ();
ToolImageDestruct (&ImageInfo);
return NULL;
}
if (Relocate) {
Success = ToolImageRelocate (&ImageInfo, BaseAddress);
Success = ToolImageRelocate (&ImageInfo, BaseAddress, 0);
if (!Success) {
fprintf (stderr, "ImageTool: Failed to relocate input file %s\n", SymbolsPath);
ToolImageDestruct (&ImageInfo);
@ -157,17 +161,24 @@ ToolImageEmit (
OutputFile = NULL;
if (Format == UefiImageFormatPe) {
OutputFile = ToolImageEmitPe (&ImageInfo, OutputFileSize, Strip);
OutputFile = ToolImageEmitPe (&ImageInfo, OutputFileSize, Xip, Strip);
} else {
assert (false);
}
if (OutputFile == NULL) {
DEBUG_RAISE ();
ToolImageDestruct (&ImageInfo);
return NULL;
}
Status = ValidateOutputFile (OutputFile, *OutputFileSize, &ImageInfo);
ToolImageDestruct (&ImageInfo);
if (EFI_ERROR (Status)) {
assert (false);
assert (Status == RETURN_OUT_OF_RESOURCES);
FreePool (OutputFile);
return NULL;
}

View File

@ -20,6 +20,7 @@ ToolImageEmit (
IN bool Relocate,
IN uint64_t BaseAddress,
IN const char *SymbolsPath OPTIONAL,
IN bool Xip,
IN bool Strip,
IN bool FixedAddress
);

View File

@ -20,7 +20,7 @@ PE = $(UDK_PATH)\MdePkg\Library\BasePeCoffLib2
UA = $(UDK_PATH)\MdePkg\Library\BaseUefiImageExtraActionLibNull
OBJECTS = ImageTool.obj Image.obj PeEmit32.obj PeEmit64.obj PeEmitCommon.obj UefiImageScan.obj PeScan.obj ElfScan32.obj ElfScan64.obj ElfScanCommon.obj BinEmit.obj ImageToolEmit.obj
OBJECTS = $(OBJECTS) {$(OV)}BaseAlignment.obj BaseBitOverflow.obj {$(UA)}UefiImageExtraActionLib.obj
OBJECTS = $(OBJECTS) {$(OV)}BaseAlignment.obj BaseBitOverflow.obj {$(UA)}UefiImageExtraActionLib.obj DynamicBuffer.obj
OBJECTS = $(OBJECTS) {$(PE)}PeCoffInit.obj PeCoffInfo.obj PeCoffRelocate.obj PeCoffLoad.obj PeCoffHii.obj PeCoffDebug.obj PeCoffHash.obj
BASE = $(UDK_PATH)\MdePkg\Library\BaseLib

File diff suppressed because it is too large Load Diff

View File

@ -9,6 +9,7 @@ void *
ToolImageEmitPe (
image_tool_image_info_t *Image,
uint32_t *FileSize,
bool Xip,
bool Strip
)
{
@ -20,13 +21,13 @@ ToolImageEmitPe (
case IMAGE_FILE_MACHINE_I386:
case IMAGE_FILE_MACHINE_ARMTHUMB_MIXED:
{
return ToolImageEmitPe32 (Image, FileSize);
return ToolImageEmitPe32 (Image, FileSize, Xip);
}
case IMAGE_FILE_MACHINE_X64:
case IMAGE_FILE_MACHINE_ARM64:
{
return ToolImageEmitPe64 (Image, FileSize);
return ToolImageEmitPe64 (Image, FileSize, Xip);
}
default:

View File

@ -13,13 +13,15 @@
void *
ToolImageEmitPe32 (
const image_tool_image_info_t *Image,
uint32_t *FileSize
uint32_t *FileSize,
bool Xip
);
void *
ToolImageEmitPe64 (
const image_tool_image_info_t *Image,
uint32_t *FileSize
uint32_t *FileSize,
bool Xip
);
#endif // PE_EMIT_COMMON_H

View File

@ -6,11 +6,13 @@
#include "ImageTool.h"
#include "PeScan.h"
#define PE_COFF_SECT_NAME_RELOC ".reloc\0"
#define PE_COFF_SECT_NAME_RESRC ".rsrc\0\0"
#define PE_COFF_SECT_NAME_DEBUG ".debug\0"
bool
RETURN_STATUS
ScanPeGetRelocInfo (
OUT image_tool_reloc_info_t *RelocInfo,
IN PE_COFF_LOADER_IMAGE_CONTEXT *Context
@ -29,9 +31,7 @@ ScanPeGetRelocInfo (
const char *ImageBuffer;
UINT16 RelocType;
UINT16 RelocOffset;
assert (RelocInfo != NULL);
assert (Context != NULL);
uint32_t ToolRelocsSize;
// FIXME: PE/COFF context access
RelocBlockRva = Context->RelocDirRva;
@ -40,13 +40,28 @@ ScanPeGetRelocInfo (
// Verify the Relocation Directory is not empty.
//
if (RelocDirSize == 0) {
return true;
return RETURN_SUCCESS;
}
RelocInfo->Relocs = calloc (RelocDirSize / sizeof (UINT16), sizeof (*RelocInfo->Relocs));
STATIC_ASSERT (
sizeof (*RelocInfo->Relocs) % sizeof (UINT16) == 0,
"The division below is inaccurate."
);
Overflow = BaseOverflowMulU32 (
RelocDirSize,
sizeof (*RelocInfo->Relocs) / sizeof (UINT16),
&ToolRelocsSize
);
if (Overflow) {
DEBUG_RAISE ();
return RETURN_OUT_OF_RESOURCES;
}
RelocInfo->Relocs = AllocateZeroPool (ToolRelocsSize);
if (RelocInfo->Relocs == NULL) {
fprintf (stderr, "ImageTool: Could not allocate memory for Relocs[]\n");
return false;
return RETURN_OUT_OF_RESOURCES;
}
TopOfRelocDir = RelocBlockRva + RelocDirSize;
@ -65,7 +80,7 @@ ScanPeGetRelocInfo (
);
if (Overflow) {
fprintf (stderr, "ImageTool: Overflow during TopOfRelocDir calculation\n");
return false;
return RETURN_VOLUME_CORRUPTED;
}
//
// Apply all Base Relocations of the Image.
@ -83,7 +98,7 @@ ScanPeGetRelocInfo (
);
if (Overflow) {
fprintf (stderr, "ImageTool: Overflow during SizeOfRelocs calculation\n");
return false;
return RETURN_VOLUME_CORRUPTED;
}
//
// Verify the Base Relocation Block is in bounds of the Relocation
@ -91,7 +106,7 @@ ScanPeGetRelocInfo (
//
if (SizeOfRelocs > RelocBlockRvaMax - RelocBlockRva) {
fprintf (stderr, "ImageTool: Base Relocation Block is out of bounds of the Relocation Directory\n");
return false;
return RETURN_VOLUME_CORRUPTED;
}
//
// This arithmetic cannot overflow because we know
@ -113,7 +128,6 @@ ScanPeGetRelocInfo (
RelocType = IMAGE_RELOC_TYPE (RelocBlock->Relocations[RelocIndex]);
RelocOffset = IMAGE_RELOC_OFFSET (RelocBlock->Relocations[RelocIndex]);
// FIXME: Make separate functions for UE
switch (RelocType) {
case EFI_IMAGE_REL_BASED_ABSOLUTE:
continue;
@ -123,7 +137,7 @@ ScanPeGetRelocInfo (
break;
default:
fprintf (stderr, "ImageTool: Unknown RelocType = 0x%x\n", RelocType);
return false;
return RETURN_UNSUPPORTED;
}
RelocInfo->Relocs[RelocInfo->NumRelocs].Target = RelocBlock->VirtualAddress + RelocOffset;
@ -140,13 +154,13 @@ ScanPeGetRelocInfo (
//
if (RelocBlockRva != TopOfRelocDir) {
fprintf (stderr, "ImageTool: Relocation Directory size does not match the contained data\n");
return false;
return RETURN_VOLUME_CORRUPTED;
}
return true;
return RETURN_SUCCESS;
}
bool
RETURN_STATUS
ScanPeGetSegmentInfo (
OUT image_tool_segment_info_t *SegmentInfo,
IN PE_COFF_LOADER_IMAGE_CONTEXT *Context
@ -158,15 +172,19 @@ ScanPeGetSegmentInfo (
const char *ImageBuffer;
uint32_t Index;
assert (SegmentInfo != NULL);
assert (Context != NULL);
NumSections = PeCoffGetSectionTable (Context, &Section);
SegmentInfo->Segments = calloc (NumSections, sizeof (*SegmentInfo->Segments));
STATIC_ASSERT (
sizeof (*SegmentInfo->Segments) <= sizeof (*Section),
"The multiplication below may overflow."
);
SegmentInfo->Segments = AllocateZeroPool (
NumSections * sizeof (*SegmentInfo->Segments)
);
if (SegmentInfo->Segments == NULL) {
fprintf (stderr, "ImageTool: Could not allocate memory for Segments[]\n");
return false;
return RETURN_OUT_OF_RESOURCES;
}
ImageBuffer = (char *)PeCoffLoaderGetImageAddress (Context);
@ -184,112 +202,35 @@ ScanPeGetSegmentInfo (
&& memcmp (Section->Name, PE_COFF_SECT_NAME_RELOC, sizeof (Section->Name)) != 0
&& memcmp (Section->Name, PE_COFF_SECT_NAME_RESRC, sizeof (Section->Name)) != 0
&& memcmp (Section->Name, PE_COFF_SECT_NAME_DEBUG, sizeof (Section->Name)) != 0) {
ImageSegment->Name = calloc (1, sizeof (Section->Name));
ImageSegment->Name = AllocateCopyPool (
sizeof (Section->Name),
Section->Name
);
if (ImageSegment->Name == NULL) {
fprintf (stderr, "ImageTool: Could not allocate memory for Segment Name\n");
return false;
return RETURN_OUT_OF_RESOURCES;
}
memmove (ImageSegment->Name, Section->Name, sizeof (Section->Name));
ImageSegment->ImageAddress = Section->VirtualAddress;
ImageSegment->ImageSize = ALIGN_VALUE (Section->VirtualSize, SegmentInfo->SegmentAlignment);
ImageSegment->Read = (Section->Characteristics & EFI_IMAGE_SCN_MEM_READ) != 0;
ImageSegment->Write = (Section->Characteristics & EFI_IMAGE_SCN_MEM_WRITE) != 0;
ImageSegment->Execute = (Section->Characteristics & EFI_IMAGE_SCN_MEM_EXECUTE) != 0;
ImageSegment->Data = malloc (ImageSegment->ImageSize);
ImageSegment->Data = AllocateCopyPool (
ImageSegment->ImageSize,
ImageBuffer + Section->VirtualAddress
);
if (ImageSegment->Data == NULL) {
fprintf (stderr, "ImageTool: Could not allocate memory for Segment Data\n");
free (ImageSegment->Name);
return false;
FreePool (ImageSegment->Name);
return RETURN_OUT_OF_RESOURCES;
}
memmove (
ImageSegment->Data,
ImageBuffer + Section->VirtualAddress,
ImageSegment->ImageSize
);
++SegmentInfo->NumSegments;
++ImageSegment;
}
}
return true;
}
bool
ScanPeGetDebugInfo (
OUT image_tool_debug_info_t *DebugInfo,
IN PE_COFF_LOADER_IMAGE_CONTEXT *Context
)
{
const CHAR8 *PdbPath;
UINT32 PdbPathSize;
RETURN_STATUS Status;
assert (DebugInfo != NULL);
assert (Context != NULL);
Status = PeCoffGetPdbPath (Context, &PdbPath, &PdbPathSize);
if (Status == RETURN_NOT_FOUND) {
return true;
}
if (RETURN_ERROR (Status)) {
fprintf (stderr, "ImageTool: Could not get PdbPath\n");
return false;
}
DebugInfo->SymbolsPath = malloc (PdbPathSize);
if (DebugInfo->SymbolsPath == NULL) {
fprintf (stderr, "ImageTool: Could not allocate memory for SymbolsPath\n");
return false;
}
memmove (DebugInfo->SymbolsPath, PdbPath, PdbPathSize);
assert (PdbPathSize >= 1);
assert (DebugInfo->SymbolsPath[PdbPathSize - 1] == '\0');
DebugInfo->SymbolsPathLen = PdbPathSize - 1;
return true;
}
bool
ScanPeGetHiiInfo (
OUT image_tool_hii_info_t *HiiInfo,
IN PE_COFF_LOADER_IMAGE_CONTEXT *Context
)
{
UINT32 HiiRva;
UINT32 HiiSize;
RETURN_STATUS Status;
const char *ImageBuffer;
assert (HiiInfo != NULL);
assert (Context != NULL);
Status = PeCoffGetHiiDataRva (Context, &HiiRva, &HiiSize);
if (Status == RETURN_NOT_FOUND) {
return true;
}
if (RETURN_ERROR (Status)) {
fprintf (stderr, "ImageTool: Could not get HiiRva\n");
return false;
}
HiiInfo->Data = calloc (1, HiiSize);
if (HiiInfo->Data == NULL) {
fprintf (stderr, "ImageTool: Could not allocate memory for HiiInfo Data\n");
return false;
}
ImageBuffer = (char *)PeCoffLoaderGetImageAddress (Context);
memmove (HiiInfo->Data, ImageBuffer + HiiRva, HiiSize);
HiiInfo->DataSize = HiiSize;
return true;
return RETURN_SUCCESS;
}

View File

@ -8,13 +8,13 @@
#include "ImageTool.h"
bool
RETURN_STATUS
ScanPeGetRelocInfo (
OUT image_tool_reloc_info_t *RelocInfo,
IN PE_COFF_LOADER_IMAGE_CONTEXT *Context
);
bool
RETURN_STATUS
ScanPeGetSegmentInfo (
OUT image_tool_segment_info_t *SegmentInfo,
IN PE_COFF_LOADER_IMAGE_CONTEXT *Context

View File

@ -25,8 +25,6 @@ ScanUefiImageGetHeaderInfo (
HeaderInfo->EntryPointAddress = UefiImageGetEntryPointAddress (Context);
HeaderInfo->Machine = UefiImageGetMachine (Context);
HeaderInfo->Subsystem = UefiImageGetSubsystem (Context);
// FIXME:
HeaderInfo->IsXip = true;
Status = UefiImageGetFixedAddress (Context, &Address);
if (!RETURN_ERROR (Status)) {
@ -47,7 +45,7 @@ ScanUefiImageGetHeaderInfo (
}
static
bool
RETURN_STATUS
ScanUefiImageGetRelocInfo (
OUT image_tool_reloc_info_t *RelocInfo,
IN UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context
@ -55,9 +53,6 @@ ScanUefiImageGetRelocInfo (
{
UINT8 FormatIndex;
assert (RelocInfo != NULL);
assert (Context != NULL);
FormatIndex = UefiImageGetFormat (Context);
RelocInfo->RelocsStripped = UefiImageGetRelocsStripped (Context);
@ -71,11 +66,11 @@ ScanUefiImageGetRelocInfo (
"ImageTool: Unsupported UefiImage format %u\n",
FormatIndex
);
return false;
return RETURN_UNSUPPORTED;
}
static
bool
RETURN_STATUS
ScanUefiImageGetSegmentInfo (
OUT image_tool_segment_info_t *SegmentInfo,
IN UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context
@ -83,9 +78,6 @@ ScanUefiImageGetSegmentInfo (
{
UINT8 FormatIndex;
assert (SegmentInfo != NULL);
assert (Context != NULL);
FormatIndex = UefiImageGetFormat (Context);
SegmentInfo->SegmentAlignment = UefiImageGetSegmentAlignment (Context);
@ -99,10 +91,10 @@ ScanUefiImageGetSegmentInfo (
"ImageTool: Unsupported UefiImage format %u\n",
FormatIndex
);
return false;
return RETURN_UNSUPPORTED;
}
bool
RETURN_STATUS
ScanUefiImageGetDebugInfo (
OUT image_tool_debug_info_t *DebugInfo,
IN UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context
@ -112,35 +104,31 @@ ScanUefiImageGetDebugInfo (
const CHAR8 *SymbolsPath;
UINT32 SymbolsPathSize;
assert (DebugInfo != NULL);
assert (Context != NULL);
Status = UefiImageGetSymbolsPath (Context, &SymbolsPath, &SymbolsPathSize);
if (Status == RETURN_NOT_FOUND) {
return true;
if (Status == RETURN_NOT_FOUND || Status == RETURN_UNSUPPORTED) {
return RETURN_SUCCESS;
}
if (RETURN_ERROR (Status)) {
fprintf (stderr, "ImageTool: Could not get SymbolsPath\n");
return false;
return Status;
}
assert (SymbolsPathSize >= 1);
DebugInfo->SymbolsPath = malloc (SymbolsPathSize + 1);
DebugInfo->SymbolsPath = AllocateCopyPool (SymbolsPathSize, SymbolsPath);
if (DebugInfo->SymbolsPath == NULL) {
fprintf (stderr, "ImageTool: Could not allocate memory for SymbolsPath\n");
return false;
return RETURN_OUT_OF_RESOURCES;
}
memmove (DebugInfo->SymbolsPath, SymbolsPath, SymbolsPathSize);
assert (DebugInfo->SymbolsPath[SymbolsPathSize - 1] == '\0');
DebugInfo->SymbolsPathLen = SymbolsPathSize - 1;
return true;
return RETURN_SUCCESS;
}
bool
RETURN_STATUS
ScanUefiImageGetHiiInfo (
OUT image_tool_hii_info_t *HiiInfo,
IN UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context
@ -151,30 +139,26 @@ ScanUefiImageGetHiiInfo (
UINT32 HiiSize;
const char *ImageBuffer;
assert (HiiInfo != NULL);
assert (Context != NULL);
Status = UefiImageGetHiiDataRva (Context, &HiiRva, &HiiSize);
if (Status == RETURN_NOT_FOUND) {
return true;
return RETURN_SUCCESS;
}
if (RETURN_ERROR (Status)) {
fprintf (stderr, "ImageTool: Malformed HII data\n");
return false;
}
HiiInfo->Data = malloc (HiiSize);
if (HiiInfo->Data == NULL) {
fprintf (stderr, "ImageTool: Could not allocate memory for HiiInfo Data\n");
return false;
return Status;
}
ImageBuffer = (char *)UefiImageLoaderGetImageAddress (Context);
memmove (HiiInfo->Data, ImageBuffer + HiiRva, HiiSize);
HiiInfo->Data = AllocateCopyPool (HiiSize, ImageBuffer + HiiRva);
if (HiiInfo->Data == NULL) {
fprintf (stderr, "ImageTool: Could not allocate memory for HiiInfo Data\n");
return RETURN_OUT_OF_RESOURCES;
}
HiiInfo->DataSize = HiiSize;
return true;
return RETURN_SUCCESS;
}
RETURN_STATUS
@ -194,7 +178,6 @@ ToolContextConstructUefiImage (
void *Destination;
bool Success;
assert (Image != NULL);
assert (File != NULL || FileSize == 0);
if (FileSize > MAX_UINT32) {
@ -229,7 +212,7 @@ ToolContextConstructUefiImage (
if (RETURN_ERROR (Status)) {
fprintf (stderr, "ImageTool: Could not Load Image\n");
FreeAlignedPages (Destination, DestinationPages);
return RETURN_VOLUME_CORRUPTED;
return Status;
}
memset (Image, 0, sizeof (*Image));
@ -237,36 +220,41 @@ ToolContextConstructUefiImage (
Success = ScanUefiImageGetHeaderInfo (&Image->HeaderInfo, &Context);
if (!Success) {
fprintf (stderr, "ImageTool: Could not retrieve header info\n");
ToolImageDestruct (Image);
FreeAlignedPages (Destination, DestinationPages);
return RETURN_VOLUME_CORRUPTED;
}
Success = ScanUefiImageGetSegmentInfo (&Image->SegmentInfo, &Context);
if (!Success) {
Status = ScanUefiImageGetSegmentInfo (&Image->SegmentInfo, &Context);
if (RETURN_ERROR (Status)) {
fprintf (stderr, "ImageTool: Could not retrieve segment info\n");
ToolImageDestruct (Image);
FreeAlignedPages (Destination, DestinationPages);
return RETURN_VOLUME_CORRUPTED;
return Status;
}
Success = ScanUefiImageGetRelocInfo (&Image->RelocInfo, &Context);
if (!Success) {
Status = ScanUefiImageGetRelocInfo (&Image->RelocInfo, &Context);
if (RETURN_ERROR (Status)) {
fprintf (stderr, "ImageTool: Could not retrieve reloc info\n");
ToolImageDestruct (Image);
FreeAlignedPages (Destination, DestinationPages);
return RETURN_VOLUME_CORRUPTED;
return Status;
}
Success = ScanUefiImageGetHiiInfo (&Image->HiiInfo, &Context);
if (!Success) {
Status = ScanUefiImageGetHiiInfo (&Image->HiiInfo, &Context);
if (RETURN_ERROR (Status)) {
fprintf (stderr, "ImageTool: Could not retrieve HII info\n");
ToolImageDestruct (Image);
FreeAlignedPages (Destination, DestinationPages);
return RETURN_VOLUME_CORRUPTED;
return Status;
}
Success = ScanUefiImageGetDebugInfo (&Image->DebugInfo, &Context);
if (!Success) {
Status = ScanUefiImageGetDebugInfo (&Image->DebugInfo, &Context);
if (RETURN_ERROR (Status)) {
fprintf (stderr, "ImageTool: Could not retrieve debug info\n");
ToolImageDestruct (Image);
FreeAlignedPages (Destination, DestinationPages);
return RETURN_VOLUME_CORRUPTED;
return Status;
}
FreeAlignedPages (Destination, DestinationPages);

View File

@ -42,6 +42,7 @@ OBJECTS += \
$(EDK2_OBJPATH)/BaseTools/ImageTool/PeEmit64.o \
$(EDK2_OBJPATH)/BaseTools/ImageTool/PeEmitCommon.o \
$(EDK2_OBJPATH)/BaseTools/ImageTool/BinEmit.o \
$(EDK2_OBJPATH)/BaseTools/ImageTool/DynamicBuffer.o \
$(EDK2_OBJPATH)/OpenCorePkg/User/Library/UserFile.o
OBJECTS += \

View File

@ -42,6 +42,7 @@ OBJECTS = $(OBJECTS) \
$(EDK2_OBJPATH)\BaseTools\ImageTool\PeEmit64.obj \
$(EDK2_OBJPATH)\BaseTools\ImageTool\PeEmitCommon.obj \
$(EDK2_OBJPATH)\BaseTools\ImageTool\BinEmit.obj \
$(EDK2_OBJPATH)\BaseTools\ImageTool\DynamicBuffer.obj \
$(EDK2_OBJPATH)\OpenCorePkg\User\Library\UserFile.obj
OBJECTS = $(OBJECTS) \

View File

@ -3732,6 +3732,7 @@ Returns:
true,
NewBaseAddress,
NULL,
TRUE,
Strip,
FALSE
);

View File

@ -1456,6 +1456,7 @@ Returns:
true,
NewBaseAddress,
NULL,
TRUE,
FALSE,
TRUE
);

View File

@ -95,6 +95,7 @@ class DataSection (DataSectionClassObject):
GenFdsGlobalVariable.GenerateFirmwareImage(
StrippedFile,
GenFdsGlobalVariable.MacroExtend(self.SectFileName, Dict),
Xip=True,
Strip=True,
IsMakefile = IsMakefile
)

View File

@ -290,6 +290,7 @@ class EfiSection (EfiSectionClassObject):
GenFdsGlobalVariable.GenerateFirmwareImage(
StrippedFile,
File,
Xip=True,
Strip=True,
IsMakefile = IsMakefile
)

View File

@ -793,6 +793,7 @@ class FfsInfStatement(FfsInfStatementClassObject):
GenFdsGlobalVariable.GenerateFirmwareImage(
StrippedFile,
File,
Xip=True,
Strip=True,
IsMakefile=IsMakefile
)
@ -827,6 +828,7 @@ class FfsInfStatement(FfsInfStatementClassObject):
GenFdsGlobalVariable.GenerateFirmwareImage(
StrippedFile,
GenSecInputFile,
Xip=True,
Strip=True,
IsMakefile=IsMakefile
)

View File

@ -607,7 +607,7 @@ class GenFdsGlobalVariable:
GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate FV")
@staticmethod
def GenerateFirmwareImage(Output, Input, Format="Auto", Strip=False, IsMakefile=False):
def GenerateFirmwareImage(Output, Input, Format="Auto", Xip=False, Strip=False, IsMakefile=False):
if not GenFdsGlobalVariable.NeedsUpdate(Output, Input) and not IsMakefile:
return
GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, Input))
@ -615,6 +615,8 @@ class GenFdsGlobalVariable:
Cmd = ["ImageTool GenImage"]
if Format != "Auto":
Cmd += ("-c", Format)
if Xip:
Cmd.append("-x")
if Strip:
Cmd.append("-s")
Cmd += ("-o", Output, Input)

View File

@ -642,7 +642,7 @@ class ModuleReport(object):
if os.path.isfile(DefaultEFIfile):
Tempfile = os.path.join(OutputDir, self.ModuleName + "_hash.tmp")
# rebase the efi image since its base address may not zero
cmd = ["ImageTool GenImage -b 0 -o", Tempfile, DefaultEFIfile]
cmd = ["ImageTool GenImage -x -b 0 -o", Tempfile, DefaultEFIfile]
try:
PopenObject = subprocess.Popen(' '.join(cmd), stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
except Exception as X:

View File

@ -1524,16 +1524,16 @@ class Build():
#
# Update Image to new BaseAddress by ImageTool tool
#
LaunchCommand(["ImageTool", "GenImage", "-b", str(BaseAddress), "-o", ModuleOutputImage, ModuleOutputImage], ModuleInfo.OutputDir)
LaunchCommand(["ImageTool", "GenImage", "-b", str(BaseAddress), "-o", ModuleOutputImage, ModuleOutputImage], ModuleInfo.DebugDir)
LaunchCommand(["ImageTool", "GenImage", "-x", "-b", str(BaseAddress), "-o", ModuleOutputImage, ModuleOutputImage], ModuleInfo.OutputDir)
LaunchCommand(["ImageTool", "GenImage", "-x", "-b", str(BaseAddress), "-o", ModuleOutputImage, ModuleOutputImage], ModuleInfo.DebugDir)
## for SMM module in SMRAM, the SMRAM will be allocated from base to top.
else:
BaseAddress = AlignUp(BaseAddress, ModuleInfo.Image.SectionAlignment)
#
# Set new address to the section header only for SMM driver.
#
LaunchCommand(["ImageTool", "GenImage", "-f -b", str(BaseAddress), "-o", ModuleOutputImage, ModuleOutputImage], ModuleInfo.OutputDir)
LaunchCommand(["ImageTool", "GenImage", "-f -b", str(BaseAddress), "-o", ModuleOutputImage, ModuleOutputImage], ModuleInfo.DebugDir)
LaunchCommand(["ImageTool", "GenImage", "-x", "-f -b", str(BaseAddress), "-o", ModuleOutputImage, ModuleOutputImage], ModuleInfo.OutputDir)
LaunchCommand(["ImageTool", "GenImage", "-x", "-f -b", str(BaseAddress), "-o", ModuleOutputImage, ModuleOutputImage], ModuleInfo.DebugDir)
#
# Collect function address from Map file
#

View File

@ -96,10 +96,10 @@ UefiImageLoaderGetRuntimeContextSizePe (
RETURN_STATUS
UefiImageRelocateImagePe (
IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context,
IN UINT64 BaseAddress,
OUT UEFI_IMAGE_LOADER_RUNTIME_CONTEXT *RuntimeContext OPTIONAL,
IN UINT32 RuntimeContextSize
IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context,
IN UINT64 BaseAddress,
OUT VOID *RuntimeContext OPTIONAL,
IN UINT32 RuntimeContextSize
)
{
return PeCoffRelocateImage (

View File

@ -71,10 +71,10 @@ RETURN_STATUS
typedef
RETURN_STATUS
(*UEFI_IMAGE_RELOCARE_IMAGE) (
IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context,
IN UINT64 BaseAddress,
OUT UEFI_IMAGE_LOADER_RUNTIME_CONTEXT *RuntimeContext OPTIONAL,
IN UINT32 RuntimeContextSize
IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context,
IN UINT64 BaseAddress,
OUT VOID *RuntimeContext OPTIONAL,
IN UINT32 RuntimeContextSize
);
typedef

View File

@ -285,12 +285,16 @@ UefiImageRelocateImage (
)
{
RETURN_STATUS Status;
VOID *FormatContext;
UINT32 FormatContextSize;
FormatContext = RuntimeContext;
FormatContextSize = RuntimeContextSize;
if (RuntimeContext != NULL) {
*(UINT64 *)RuntimeContext = Context->FormatIndex;
RuntimeContext = (UEFI_IMAGE_LOADER_RUNTIME_CONTEXT *)((UINT64 *)RuntimeContext + 1);
ASSERT (RuntimeContextSize >= 8);
RuntimeContextSize -= 8;
FormatContext = (VOID *)((UINT64 *)RuntimeContext + 1);
ASSERT (FormatContextSize >= 8);
FormatContextSize -= 8;
}
UEFI_IMAGE_EXEC (
@ -299,8 +303,8 @@ UefiImageRelocateImage (
RelocateImage,
Context,
BaseAddress,
RuntimeContext,
RuntimeContextSize
FormatContext,
FormatContextSize
);
if (!RETURN_ERROR (Status)) {