ImageTool: Rework PeEmit with dynamically-growing buffers

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

View File

@ -382,7 +382,7 @@
$(OUTPUT_DIR)(+)$(MODULE_NAME).map $(OUTPUT_DIR)(+)$(MODULE_NAME).map
<Command.MSFT, Command.INTEL, Command.CLANGPDB> <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} $(DEBUG_DIR)
$(CP) ${dst} $(BIN_DIR)(+)$(MODULE_NAME_GUID).efi $(CP) ${dst} $(BIN_DIR)(+)$(MODULE_NAME_GUID).efi
-$(CP) $(DEBUG_DIR)(+)*.map $(OUTPUT_DIR) -$(CP) $(DEBUG_DIR)(+)*.map $(OUTPUT_DIR)
@ -392,7 +392,7 @@
$(CP) ${src} $(DEBUG_DIR)(+)$(MODULE_NAME).strip $(CP) ${src} $(DEBUG_DIR)(+)$(MODULE_NAME).strip
$(OBJCOPY) $(OBJCOPY_STRIPFLAG) $(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} $(DEBUG_DIR)
$(CP) ${dst} $(BIN_DIR)(+)$(MODULE_NAME_GUID).efi $(CP) ${dst} $(BIN_DIR)(+)$(MODULE_NAME_GUID).efi
@ -403,7 +403,7 @@
"$(MTOC)" -subsystem $(MODULE_TYPE) $(MTOC_FLAGS) ${src} $(DEBUG_DIR)(+)$(MODULE_NAME).pecoff "$(MTOC)" -subsystem $(MODULE_TYPE) $(MTOC_FLAGS) ${src} $(DEBUG_DIR)(+)$(MODULE_NAME).pecoff
# create symbol file for GDB debug # create symbol file for GDB debug
-$(DSYMUTIL) ${src} -$(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} $(DEBUG_DIR)
$(CP) ${dst} $(BIN_DIR)(+)$(MODULE_NAME_GUID).efi $(CP) ${dst} $(BIN_DIR)(+)$(MODULE_NAME_GUID).efi
-$(CP) $(DEBUG_DIR)(+)*.map $(OUTPUT_DIR) -$(CP) $(DEBUG_DIR)(+)*.map $(OUTPUT_DIR)

View File

@ -19,9 +19,6 @@ CreateEntry (
EFI_IMAGE_RESOURCE_DIRECTORY *RDir; EFI_IMAGE_RESOURCE_DIRECTORY *RDir;
EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY *Entry; EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY *Entry;
assert (HiiSectionHeader != NULL);
assert (HiiSectionOffset != NULL);
RDir = (EFI_IMAGE_RESOURCE_DIRECTORY *)(HiiSectionHeader + *HiiSectionOffset); RDir = (EFI_IMAGE_RESOURCE_DIRECTORY *)(HiiSectionHeader + *HiiSectionOffset);
*HiiSectionOffset += sizeof (EFI_IMAGE_RESOURCE_DIRECTORY); *HiiSectionOffset += sizeof (EFI_IMAGE_RESOURCE_DIRECTORY);
RDir->NumberOfNamedEntries = 1; RDir->NumberOfNamedEntries = 1;
@ -49,11 +46,6 @@ CreateStringEntry (
{ {
EFI_IMAGE_RESOURCE_DIRECTORY_STRING *RDStr; EFI_IMAGE_RESOURCE_DIRECTORY_STRING *RDStr;
assert (Entry != NULL);
assert (HiiSectionHeader != NULL);
assert (HiiSectionOffset != NULL);
assert (String != NULL);
Entry->u1.s.NameOffset = *HiiSectionOffset; Entry->u1.s.NameOffset = *HiiSectionOffset;
RDStr = (EFI_IMAGE_RESOURCE_DIRECTORY_STRING *)(HiiSectionHeader + *HiiSectionOffset); RDStr = (EFI_IMAGE_RESOURCE_DIRECTORY_STRING *)(HiiSectionHeader + *HiiSectionOffset);
RDStr->Length = (UINT16)StrLen (String); RDStr->Length = (UINT16)StrLen (String);
@ -78,8 +70,6 @@ InitializeHiiResouceSectionHeader (
EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY *LangRDirEntry; EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY *LangRDirEntry;
EFI_IMAGE_RESOURCE_DATA_ENTRY *ResourceDataEntry; EFI_IMAGE_RESOURCE_DATA_ENTRY *ResourceDataEntry;
assert (HiiSectionHeader != NULL);
HiiSectionOffset = 0; HiiSectionOffset = 0;
// //
// Create Type, Name, Language entries // Create Type, Name, Language entries
@ -123,10 +113,6 @@ ConstructHii (
UINT32 FileSize; UINT32 FileSize;
UINT8 NumberOfFormPackages; UINT8 NumberOfFormPackages;
assert (Hii != NULL);
assert (HiiGuid != NULL);
assert (FileNames != NULL);
NumberOfFormPackages = 0; NumberOfFormPackages = 0;
EndPackage.Length = sizeof (EFI_HII_PACKAGE_HEADER); EndPackage.Length = sizeof (EFI_HII_PACKAGE_HEADER);
@ -173,7 +159,7 @@ ConstructHii (
CopyGuid (&HiiPackageListHeader.PackageListGuid, HiiGuid); CopyGuid (&HiiPackageListHeader.PackageListGuid, HiiGuid);
HiiPackageData = calloc (1, HiiPackageListHeader.PackageLength); HiiPackageData = AllocateZeroPool (HiiPackageListHeader.PackageLength);
if (HiiPackageData == NULL) { if (HiiPackageData == NULL) {
return RETURN_OUT_OF_RESOURCES; return RETURN_OUT_OF_RESOURCES;
} }
@ -185,6 +171,7 @@ ConstructHii (
File = UserReadFile (FileNames[Index], &FileSize); File = UserReadFile (FileNames[Index], &FileSize);
if (File == NULL) { if (File == NULL) {
fprintf (stderr, "ImageTool: Could not open %s: %s\n", FileNames[Index], strerror (errno)); fprintf (stderr, "ImageTool: Could not open %s: %s\n", FileNames[Index], strerror (errno));
free (HiiPackageData);
return RETURN_ABORTED; 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 IN const Elf_Shdr *Shdr
) )
{ {
assert (Shdr != NULL);
return (Shdr->sh_flags & SHF_ALLOC) != 0; return (Shdr->sh_flags & SHF_ALLOC) != 0;
} }
@ -360,7 +358,12 @@ SetRelocs (
// //
break; break;
default: 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; return RETURN_INCOMPATIBLE_VERSION;
} }
} else if (Ehdr->e_machine == EM_AARCH64) { } else if (Ehdr->e_machine == EM_AARCH64) {
@ -402,7 +405,12 @@ SetRelocs (
break; break;
default: 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; return RETURN_INCOMPATIBLE_VERSION;
} }
} }
@ -571,7 +579,7 @@ CreateIntermediate (
return RETURN_VOLUME_CORRUPTED; return RETURN_VOLUME_CORRUPTED;
} }
Segments = calloc (1, sizeof (*Segments) * ImageInfo->SegmentInfo.NumSegments); Segments = AllocateZeroPool (sizeof (*Segments) * ImageInfo->SegmentInfo.NumSegments);
if (Segments == NULL) { if (Segments == NULL) {
fprintf (stderr, "ImageTool: Could not allocate memory for Segments\n"); fprintf (stderr, "ImageTool: Could not allocate memory for Segments\n");
return RETURN_OUT_OF_RESOURCES; return RETURN_OUT_OF_RESOURCES;
@ -580,7 +588,7 @@ CreateIntermediate (
ImageInfo->SegmentInfo.Segments = Segments; ImageInfo->SegmentInfo.Segments = Segments;
if (NumRelocs != 0) { if (NumRelocs != 0) {
Relocs = calloc (1, sizeof (*Relocs) * NumRelocs); Relocs = AllocateZeroPool (sizeof (*Relocs) * NumRelocs);
if (Relocs == NULL) { if (Relocs == NULL) {
fprintf (stderr, "ImageTool: Could not allocate memory for Relocs\n"); fprintf (stderr, "ImageTool: Could not allocate memory for Relocs\n");
return RETURN_OUT_OF_RESOURCES; return RETURN_OUT_OF_RESOURCES;
@ -606,7 +614,7 @@ CreateIntermediate (
return RETURN_VOLUME_CORRUPTED; return RETURN_VOLUME_CORRUPTED;
} }
Segments[SIndex].Name = calloc (1, strlen (Name) + 1); Segments[SIndex].Name = AllocateZeroPool (strlen (Name) + 1);
if (Segments[SIndex].Name == NULL) { if (Segments[SIndex].Name == NULL) {
fprintf (stderr, "ImageTool: Could not allocate memory for Segment #%d Name\n", Index); fprintf (stderr, "ImageTool: Could not allocate memory for Segment #%d Name\n", Index);
return RETURN_OUT_OF_RESOURCES; return RETURN_OUT_OF_RESOURCES;
@ -620,7 +628,7 @@ CreateIntermediate (
Segments[SIndex].Write = (Shdr->sh_flags & SHF_WRITE) != 0; Segments[SIndex].Write = (Shdr->sh_flags & SHF_WRITE) != 0;
Segments[SIndex].Execute = (Shdr->sh_flags & SHF_EXECINSTR) != 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) { if (Segments[SIndex].Data == NULL) {
fprintf (stderr, "ImageTool: Could not allocate memory for Segment #%d Data\n", Index); fprintf (stderr, "ImageTool: Could not allocate memory for Segment #%d Data\n", Index);
return RETURN_OUT_OF_RESOURCES; return RETURN_OUT_OF_RESOURCES;
@ -652,7 +660,6 @@ ScanElf (
const Elf_Ehdr *Ehdr; const Elf_Ehdr *Ehdr;
Elf_Addr BaseAddress; Elf_Addr BaseAddress;
assert (ImageInfo != NULL);
assert (File != NULL || FileSize == 0); assert (File != NULL || FileSize == 0);
Status = ParseElfFile (&Context, File, FileSize); Status = ParseElfFile (&Context, File, FileSize);
@ -667,7 +674,6 @@ ScanElf (
ImageInfo->HeaderInfo.BaseAddress = BaseAddress; ImageInfo->HeaderInfo.BaseAddress = BaseAddress;
ImageInfo->HeaderInfo.EntryPointAddress = (uint32_t)(Ehdr->e_entry - BaseAddress); ImageInfo->HeaderInfo.EntryPointAddress = (uint32_t)(Ehdr->e_entry - BaseAddress);
ImageInfo->HeaderInfo.IsXip = true;
ImageInfo->SegmentInfo.SegmentAlignment = (uint32_t)Context.Alignment; ImageInfo->SegmentInfo.SegmentAlignment = (uint32_t)Context.Alignment;
ImageInfo->RelocInfo.RelocsStripped = false; ImageInfo->RelocInfo.RelocsStripped = false;
@ -698,11 +704,11 @@ ScanElf (
return RETURN_INCOMPATIBLE_VERSION; 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) { if (ImageInfo->DebugInfo.SymbolsPath == NULL) {
fprintf (stderr, "ImageTool: Could not allocate memory for Debug Data\n"); fprintf (stderr, "ImageTool: Could not allocate memory for Debug Data\n");
return RETURN_OUT_OF_RESOURCES; return RETURN_OUT_OF_RESOURCES;
}; }
if (SymbolsPath != NULL) { if (SymbolsPath != NULL) {
memmove (ImageInfo->DebugInfo.SymbolsPath, SymbolsPath, ImageInfo->DebugInfo.SymbolsPathLen + 1); 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 += 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 += UefiImageExtraActionLib.o
OBJS += PeCoffInit.o PeCoffInfo.o PeCoffLoad.o PeCoffRelocate.o PeCoffHii.o PeCoffDebug.o PeCoffHash.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 WERROR = 1
DEBUG = 1 DEBUG = 1

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -20,7 +20,7 @@ PE = $(UDK_PATH)\MdePkg\Library\BasePeCoffLib2
UA = $(UDK_PATH)\MdePkg\Library\BaseUefiImageExtraActionLibNull 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 = 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 OBJECTS = $(OBJECTS) {$(PE)}PeCoffInit.obj PeCoffInfo.obj PeCoffRelocate.obj PeCoffLoad.obj PeCoffHii.obj PeCoffDebug.obj PeCoffHash.obj
BASE = $(UDK_PATH)\MdePkg\Library\BaseLib BASE = $(UDK_PATH)\MdePkg\Library\BaseLib

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -642,7 +642,7 @@ class ModuleReport(object):
if os.path.isfile(DefaultEFIfile): if os.path.isfile(DefaultEFIfile):
Tempfile = os.path.join(OutputDir, self.ModuleName + "_hash.tmp") Tempfile = os.path.join(OutputDir, self.ModuleName + "_hash.tmp")
# rebase the efi image since its base address may not zero # 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: try:
PopenObject = subprocess.Popen(' '.join(cmd), stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True) PopenObject = subprocess.Popen(' '.join(cmd), stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
except Exception as X: except Exception as X:

View File

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

View File

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

View File

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

View File

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