mirror of
https://github.com/acidanthera/audk.git
synced 2025-09-24 18:27:49 +02:00
ImageTool: Utilize UefiImageLib
This commit is contained in:
parent
dcdb8d3425
commit
5ed47e7c71
@ -7,9 +7,10 @@
|
|||||||
PROJECT = ImageTool
|
PROJECT = ImageTool
|
||||||
PRODUCT = $(PROJECT)$(INFIX)$(SUFFIX)
|
PRODUCT = $(PROJECT)$(INFIX)$(SUFFIX)
|
||||||
OBJS = $(PROJECT).o
|
OBJS = $(PROJECT).o
|
||||||
OBJS += Image.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
|
OBJS += PeCoffInit.o PeCoffInfo.o PeCoffLoad.o PeCoffRelocate.o PeCoffHii.o PeCoffDebug.o PeCoffHash.o
|
||||||
|
OBJS += UefiImageLibPeCoff.o PeCoffSupport.o CommonSupport.o
|
||||||
|
|
||||||
WERROR = 1
|
WERROR = 1
|
||||||
DEBUG = 1
|
DEBUG = 1
|
||||||
@ -18,6 +19,7 @@ OC_USER = ../../OpenCorePkg
|
|||||||
UDK_PATH = ../..
|
UDK_PATH = ../..
|
||||||
|
|
||||||
VPATH += ../../MdePkg/Library/BasePeCoffLib2:$\
|
VPATH += ../../MdePkg/Library/BasePeCoffLib2:$\
|
||||||
../../MdePkg/Library/BaseUefiImageExtraActionLibNull
|
../../MdePkg/Library/BaseUefiImageExtraActionLibNull:$\
|
||||||
|
../../MdePkg/Library/BaseUefiImageLib
|
||||||
|
|
||||||
include $(OC_USER)/User/Makefile
|
include $(OC_USER)/User/Makefile
|
||||||
|
@ -136,8 +136,9 @@ ToolImageStripRelocs (
|
|||||||
);
|
);
|
||||||
|
|
||||||
RETURN_STATUS
|
RETURN_STATUS
|
||||||
ToolContextConstructPe (
|
ToolContextConstructUefiImage (
|
||||||
OUT image_tool_image_info_t *Image,
|
OUT image_tool_image_info_t *Image,
|
||||||
|
OUT INT8 *Format,
|
||||||
IN const void *File,
|
IN const void *File,
|
||||||
IN size_t FileSize
|
IN size_t FileSize
|
||||||
);
|
);
|
||||||
|
@ -19,7 +19,7 @@ ToolContextConstruct (
|
|||||||
OUT image_tool_image_info_t *ImageInfo,
|
OUT image_tool_image_info_t *ImageInfo,
|
||||||
OUT int8_t *Format,
|
OUT int8_t *Format,
|
||||||
IN const void *File,
|
IN const void *File,
|
||||||
IN size_t FileSize,
|
IN uint32_t FileSize,
|
||||||
IN const char *SymbolsPath OPTIONAL
|
IN const char *SymbolsPath OPTIONAL
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
@ -27,14 +27,13 @@ ToolContextConstruct (
|
|||||||
|
|
||||||
*Format = -1;
|
*Format = -1;
|
||||||
|
|
||||||
Status = ToolContextConstructPe (
|
Status = ToolContextConstructUefiImage (
|
||||||
ImageInfo,
|
ImageInfo,
|
||||||
|
Format,
|
||||||
File,
|
File,
|
||||||
FileSize
|
FileSize
|
||||||
);
|
);
|
||||||
if (!RETURN_ERROR (Status)) {
|
if (Status == RETURN_UNSUPPORTED) {
|
||||||
*Format = UefiImageFormatPe;
|
|
||||||
} else if (Status == RETURN_UNSUPPORTED) {
|
|
||||||
Status = ScanElf (ImageInfo, File, FileSize, SymbolsPath);
|
Status = ScanElf (ImageInfo, File, FileSize, SymbolsPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -89,7 +88,7 @@ void *
|
|||||||
ToolImageEmit (
|
ToolImageEmit (
|
||||||
OUT uint32_t *OutputFileSize,
|
OUT uint32_t *OutputFileSize,
|
||||||
IN const void *Buffer,
|
IN const void *Buffer,
|
||||||
IN uint64_t BufferSize,
|
IN uint32_t BufferSize,
|
||||||
IN int8_t Format,
|
IN int8_t Format,
|
||||||
IN int32_t Type,
|
IN int32_t Type,
|
||||||
IN void *HiiFile,
|
IN void *HiiFile,
|
||||||
|
@ -14,7 +14,7 @@ void *
|
|||||||
ToolImageEmit (
|
ToolImageEmit (
|
||||||
OUT uint32_t *OutputFileSize,
|
OUT uint32_t *OutputFileSize,
|
||||||
IN const void *Buffer,
|
IN const void *Buffer,
|
||||||
IN uint64_t BufferSize,
|
IN uint32_t BufferSize,
|
||||||
IN int8_t Format,
|
IN int8_t Format,
|
||||||
IN int32_t Type,
|
IN int32_t Type,
|
||||||
IN void *HiiFile,
|
IN void *HiiFile,
|
||||||
|
@ -19,19 +19,21 @@ OV = $(UDK_PATH)\MdePkg\Library\BaseOverflowLib
|
|||||||
PE = $(UDK_PATH)\MdePkg\Library\BasePeCoffLib2
|
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 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
|
||||||
OBJECTS = $(OBJECTS) {$(PE)}PeCoffInit.obj PeCoffInfo.obj PeCoffRelocate.obj PeCoffLoad.obj PeCoffHii.obj PeCoffDebug.obj
|
OBJECTS = $(OBJECTS) {$(PE)}PeCoffInit.obj PeCoffInfo.obj PeCoffRelocate.obj PeCoffLoad.obj PeCoffHii.obj PeCoffDebug.obj PeCoffHash.obj
|
||||||
|
|
||||||
BASE = $(UDK_PATH)\MdePkg\Library\BaseLib
|
BASE = $(UDK_PATH)\MdePkg\Library\BaseLib
|
||||||
OUT = $(UDK_PATH)\MdePkg\Library\UefiDebugLibConOut
|
OUT = $(UDK_PATH)\MdePkg\Library\UefiDebugLibConOut
|
||||||
PRIN = $(UDK_PATH)\MdePkg\Library\BasePrintLib
|
PRIN = $(UDK_PATH)\MdePkg\Library\BasePrintLib
|
||||||
ERRO = $(UDK_PATH)\MdePkg\Library\BaseDebugPrintErrorLevelLib
|
ERRO = $(UDK_PATH)\MdePkg\Library\BaseDebugPrintErrorLevelLib
|
||||||
|
UIMG = $(UDK_PATH)\MdePkg\Library\BaseUefiImageLib
|
||||||
BMPN = $(UDK_PATH)\MdeModulePkg\Library\BaseMemoryProfileLibNull
|
BMPN = $(UDK_PATH)\MdeModulePkg\Library\BaseMemoryProfileLibNull
|
||||||
CMEM = $(UDK_PATH)\MdeModulePkg\Library\CommonMemoryAllocationLib
|
CMEM = $(UDK_PATH)\MdeModulePkg\Library\CommonMemoryAllocationLib
|
||||||
USER = $(OC_USER)\User\Library
|
USER = $(OC_USER)\User\Library
|
||||||
OBJECTS = $(OBJECTS) {$(BASE)}SafeString.obj String.obj SwapBytes16.obj SwapBytes32.obj CpuDeadLoop.obj CheckSum.obj QuickSort.obj
|
OBJECTS = $(OBJECTS) {$(BASE)}SafeString.obj String.obj SwapBytes16.obj SwapBytes32.obj CpuDeadLoop.obj CheckSum.obj QuickSort.obj LinkedList.obj
|
||||||
OBJECTS = $(OBJECTS) {$(OUT)}DebugLib.obj {$(PRIN)}PrintLib.obj PrintLibInternal.obj {$(ERRO)}BaseDebugPrintErrorLevelLib.obj
|
OBJECTS = $(OBJECTS) {$(OUT)}DebugLib.obj {$(PRIN)}PrintLib.obj PrintLibInternal.obj {$(ERRO)}BaseDebugPrintErrorLevelLib.obj
|
||||||
|
OBJECTS = $(OBJECTS) {$(UIMG)}UefiImageLibPeCoff.obj PeCoffSupport.obj CommonSupport.obj
|
||||||
OBJECTS = $(OBJECTS) {$(USER)}UserFile.obj UserBaseMemoryLib.obj UserMath.obj UserPcd.obj UserMisc.obj UserGlobalVar.obj UserBootServices.obj
|
OBJECTS = $(OBJECTS) {$(USER)}UserFile.obj UserBaseMemoryLib.obj UserMath.obj UserPcd.obj UserMisc.obj UserGlobalVar.obj UserBootServices.obj
|
||||||
OBJECTS = $(OBJECTS) {$(BMPN)}BaseMemoryProfileLibNull.obj {$(CMEM)}CommonMemoryAllocationLib.obj {$(CMEM)}CommonMemoryAllocationLibEx.obj
|
OBJECTS = $(OBJECTS) {$(BMPN)}BaseMemoryProfileLibNull.obj {$(CMEM)}CommonMemoryAllocationLib.obj {$(CMEM)}CommonMemoryAllocationLibEx.obj
|
||||||
|
|
||||||
@ -99,6 +101,10 @@ cleanall:
|
|||||||
$(CC) -c $(CFLAGS) $(INC) $< -Fo$@
|
$(CC) -c $(CFLAGS) $(INC) $< -Fo$@
|
||||||
@move $@ $(OUT_DIR)\
|
@move $@ $(OUT_DIR)\
|
||||||
|
|
||||||
|
{$(UIMG)}.c.obj :
|
||||||
|
$(CC) -c $(CFLAGS) $(INC) $< -Fo$@
|
||||||
|
@move $@ $(OUT_DIR)\
|
||||||
|
|
||||||
{$(USER)}.c.obj :
|
{$(USER)}.c.obj :
|
||||||
$(CC) -c $(CFLAGS) $(INC) /D WIN32 /wd 4754 $< -Fo$@
|
$(CC) -c $(CFLAGS) $(INC) /D WIN32 /wd 4754 $< -Fo$@
|
||||||
@move $@ $(OUT_DIR)\
|
@move $@ $(OUT_DIR)\
|
||||||
|
@ -10,27 +10,6 @@
|
|||||||
#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"
|
||||||
|
|
||||||
static
|
|
||||||
bool
|
|
||||||
ScanPeGetHeaderInfo (
|
|
||||||
OUT image_tool_header_info_t *HeaderInfo,
|
|
||||||
IN PE_COFF_LOADER_IMAGE_CONTEXT *Context
|
|
||||||
)
|
|
||||||
{
|
|
||||||
assert (HeaderInfo != NULL);
|
|
||||||
assert (Context != NULL);
|
|
||||||
|
|
||||||
HeaderInfo->BaseAddress = (uint64_t)PeCoffGetImageBase (Context);
|
|
||||||
HeaderInfo->EntryPointAddress = PeCoffGetAddressOfEntryPoint (Context);
|
|
||||||
// FIXME:
|
|
||||||
HeaderInfo->Machine = PeCoffGetMachine (Context);
|
|
||||||
HeaderInfo->IsXip = true;
|
|
||||||
HeaderInfo->Subsystem = PeCoffGetSubsystem (Context);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static
|
|
||||||
bool
|
bool
|
||||||
ScanPeGetRelocInfo (
|
ScanPeGetRelocInfo (
|
||||||
OUT image_tool_reloc_info_t *RelocInfo,
|
OUT image_tool_reloc_info_t *RelocInfo,
|
||||||
@ -54,8 +33,6 @@ ScanPeGetRelocInfo (
|
|||||||
assert (RelocInfo != NULL);
|
assert (RelocInfo != NULL);
|
||||||
assert (Context != NULL);
|
assert (Context != NULL);
|
||||||
|
|
||||||
RelocInfo->RelocsStripped = false;
|
|
||||||
|
|
||||||
// FIXME: PE/COFF context access
|
// FIXME: PE/COFF context access
|
||||||
RelocBlockRva = Context->RelocDirRva;
|
RelocBlockRva = Context->RelocDirRva;
|
||||||
RelocDirSize = Context->RelocDirSize;
|
RelocDirSize = Context->RelocDirSize;
|
||||||
@ -169,7 +146,6 @@ ScanPeGetRelocInfo (
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
|
||||||
bool
|
bool
|
||||||
ScanPeGetSegmentInfo (
|
ScanPeGetSegmentInfo (
|
||||||
OUT image_tool_segment_info_t *SegmentInfo,
|
OUT image_tool_segment_info_t *SegmentInfo,
|
||||||
@ -185,8 +161,6 @@ ScanPeGetSegmentInfo (
|
|||||||
assert (SegmentInfo != NULL);
|
assert (SegmentInfo != NULL);
|
||||||
assert (Context != NULL);
|
assert (Context != NULL);
|
||||||
|
|
||||||
SegmentInfo->SegmentAlignment = PeCoffGetSectionAlignment (Context);
|
|
||||||
|
|
||||||
NumSections = PeCoffGetSectionTable (Context, &Section);
|
NumSections = PeCoffGetSectionTable (Context, &Section);
|
||||||
|
|
||||||
SegmentInfo->Segments = calloc (NumSections, sizeof (*SegmentInfo->Segments));
|
SegmentInfo->Segments = calloc (NumSections, sizeof (*SegmentInfo->Segments));
|
||||||
@ -319,100 +293,3 @@ ScanPeGetHiiInfo (
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
RETURN_STATUS
|
|
||||||
ToolContextConstructPe (
|
|
||||||
OUT image_tool_image_info_t *Image,
|
|
||||||
IN const void *File,
|
|
||||||
IN size_t FileSize
|
|
||||||
)
|
|
||||||
{
|
|
||||||
PE_COFF_LOADER_IMAGE_CONTEXT Context;
|
|
||||||
RETURN_STATUS Status;
|
|
||||||
UINT32 ImageSize;
|
|
||||||
UINT32 ImageAlignment;
|
|
||||||
UINT32 DestinationSize;
|
|
||||||
UINT32 DestinationPages;
|
|
||||||
void *Destination;
|
|
||||||
bool Result;
|
|
||||||
|
|
||||||
assert (Image != NULL);
|
|
||||||
assert (File != NULL || FileSize == 0);
|
|
||||||
|
|
||||||
if (FileSize > MAX_UINT32) {
|
|
||||||
fprintf (stderr, "ImageTool: FileSize is too huge\n");
|
|
||||||
return RETURN_UNSUPPORTED;
|
|
||||||
}
|
|
||||||
|
|
||||||
Status = PeCoffInitializeContext (&Context, File, (UINT32)FileSize);
|
|
||||||
if (RETURN_ERROR (Status)) {
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
ImageSize = PeCoffGetSizeOfImage (&Context);
|
|
||||||
DestinationPages = EFI_SIZE_TO_PAGES (ImageSize);
|
|
||||||
DestinationSize = EFI_PAGES_TO_SIZE (DestinationPages);
|
|
||||||
ImageAlignment = PeCoffGetSectionAlignment (&Context);
|
|
||||||
|
|
||||||
Destination = AllocateAlignedCodePages (
|
|
||||||
DestinationPages,
|
|
||||||
ImageAlignment
|
|
||||||
);
|
|
||||||
if (Destination == NULL) {
|
|
||||||
fprintf (stderr, "ImageTool: Could not allocate Destination buffer\n");
|
|
||||||
return RETURN_OUT_OF_RESOURCES;
|
|
||||||
}
|
|
||||||
|
|
||||||
Status = PeCoffLoadImage (&Context, Destination, DestinationSize);
|
|
||||||
if (RETURN_ERROR (Status)) {
|
|
||||||
fprintf (stderr, "ImageTool: Could not Load Image\n");
|
|
||||||
FreeAlignedPages (Destination, DestinationPages);
|
|
||||||
return RETURN_VOLUME_CORRUPTED;
|
|
||||||
}
|
|
||||||
|
|
||||||
memset (Image, 0, sizeof (*Image));
|
|
||||||
|
|
||||||
Result = ScanPeGetHeaderInfo (&Image->HeaderInfo, &Context);
|
|
||||||
if (!Result) {
|
|
||||||
fprintf (stderr, "ImageTool: Could not retrieve header info\n");
|
|
||||||
ToolImageDestruct (Image);
|
|
||||||
FreeAlignedPages (Destination, DestinationPages);
|
|
||||||
return RETURN_VOLUME_CORRUPTED;
|
|
||||||
}
|
|
||||||
|
|
||||||
Result = ScanPeGetDebugInfo (&Image->DebugInfo, &Context);
|
|
||||||
if (!Result) {
|
|
||||||
fprintf (stderr, "ImageTool: Could not retrieve debug info\n");
|
|
||||||
ToolImageDestruct (Image);
|
|
||||||
FreeAlignedPages (Destination, DestinationPages);
|
|
||||||
return RETURN_VOLUME_CORRUPTED;
|
|
||||||
}
|
|
||||||
|
|
||||||
Result = ScanPeGetSegmentInfo (&Image->SegmentInfo, &Context);
|
|
||||||
if (!Result) {
|
|
||||||
fprintf (stderr, "ImageTool: Could not retrieve segment info\n");
|
|
||||||
ToolImageDestruct (Image);
|
|
||||||
FreeAlignedPages (Destination, DestinationPages);
|
|
||||||
return RETURN_VOLUME_CORRUPTED;
|
|
||||||
}
|
|
||||||
|
|
||||||
Result = ScanPeGetRelocInfo (&Image->RelocInfo, &Context);
|
|
||||||
if (!Result) {
|
|
||||||
fprintf (stderr, "ImageTool: Could not retrieve reloc info\n");
|
|
||||||
ToolImageDestruct (Image);
|
|
||||||
FreeAlignedPages (Destination, DestinationPages);
|
|
||||||
return RETURN_VOLUME_CORRUPTED;
|
|
||||||
}
|
|
||||||
|
|
||||||
Result = ScanPeGetHiiInfo (&Image->HiiInfo, &Context);
|
|
||||||
if (!Result) {
|
|
||||||
fprintf (stderr, "ImageTool: Could not retrieve HII info\n");
|
|
||||||
ToolImageDestruct (Image);
|
|
||||||
FreeAlignedPages (Destination, DestinationPages);
|
|
||||||
return RETURN_VOLUME_CORRUPTED;
|
|
||||||
}
|
|
||||||
|
|
||||||
FreeAlignedPages (Destination, DestinationPages);
|
|
||||||
|
|
||||||
return RETURN_SUCCESS;
|
|
||||||
}
|
|
||||||
|
23
BaseTools/ImageTool/PeScan.h
Normal file
23
BaseTools/ImageTool/PeScan.h
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
/** @file
|
||||||
|
Copyright (c) 2023, Marvin Häuser. All rights reserved.
|
||||||
|
SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
**/
|
||||||
|
|
||||||
|
#ifndef PE_SCAN_H
|
||||||
|
#define PE_SCAN_H
|
||||||
|
|
||||||
|
#include "ImageTool.h"
|
||||||
|
|
||||||
|
bool
|
||||||
|
ScanPeGetRelocInfo (
|
||||||
|
OUT image_tool_reloc_info_t *RelocInfo,
|
||||||
|
IN PE_COFF_LOADER_IMAGE_CONTEXT *Context
|
||||||
|
);
|
||||||
|
|
||||||
|
bool
|
||||||
|
ScanPeGetSegmentInfo (
|
||||||
|
OUT image_tool_segment_info_t *SegmentInfo,
|
||||||
|
IN PE_COFF_LOADER_IMAGE_CONTEXT *Context
|
||||||
|
);
|
||||||
|
|
||||||
|
#endif // PE_SCAN_H
|
261
BaseTools/ImageTool/UefiImageScan.c
Normal file
261
BaseTools/ImageTool/UefiImageScan.c
Normal file
@ -0,0 +1,261 @@
|
|||||||
|
/** @file
|
||||||
|
Copyright (c) 2023, Marvin Häuser. All rights reserved.
|
||||||
|
SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
**/
|
||||||
|
|
||||||
|
#include "ImageTool.h"
|
||||||
|
|
||||||
|
#include <Uefi/UefiBaseType.h>
|
||||||
|
|
||||||
|
#include <Library/UefiImageLib.h>
|
||||||
|
|
||||||
|
#include "PeScan.h"
|
||||||
|
|
||||||
|
static
|
||||||
|
bool
|
||||||
|
ScanUefiImageGetHeaderInfo (
|
||||||
|
OUT image_tool_header_info_t *HeaderInfo,
|
||||||
|
IN UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context
|
||||||
|
)
|
||||||
|
{
|
||||||
|
assert (HeaderInfo != NULL);
|
||||||
|
assert (Context != NULL);
|
||||||
|
|
||||||
|
HeaderInfo->BaseAddress = (uint64_t)UefiImageGetPreferredAddress (Context);
|
||||||
|
HeaderInfo->EntryPointAddress = UefiImageGetEntryPointAddress (Context);
|
||||||
|
HeaderInfo->Machine = UefiImageGetMachine (Context);
|
||||||
|
HeaderInfo->Subsystem = UefiImageGetSubsystem (Context);
|
||||||
|
// FIXME:
|
||||||
|
HeaderInfo->IsXip = true;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
bool
|
||||||
|
ScanUefiImageGetRelocInfo (
|
||||||
|
OUT image_tool_reloc_info_t *RelocInfo,
|
||||||
|
IN UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context
|
||||||
|
)
|
||||||
|
{
|
||||||
|
UINT8 FormatIndex;
|
||||||
|
|
||||||
|
assert (RelocInfo != NULL);
|
||||||
|
assert (Context != NULL);
|
||||||
|
|
||||||
|
FormatIndex = UefiImageGetFormat (Context);
|
||||||
|
|
||||||
|
RelocInfo->RelocsStripped = UefiImageGetRelocsStripped (Context);
|
||||||
|
|
||||||
|
if (FormatIndex == UefiImageFormatPe) {
|
||||||
|
return ScanPeGetRelocInfo (
|
||||||
|
RelocInfo,
|
||||||
|
(PE_COFF_LOADER_IMAGE_CONTEXT *)Context
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf (
|
||||||
|
stderr,
|
||||||
|
"ImageTool: Unsupported UefiImage format %u\n",
|
||||||
|
FormatIndex
|
||||||
|
);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
bool
|
||||||
|
ScanUefiImageGetSegmentInfo (
|
||||||
|
OUT image_tool_segment_info_t *SegmentInfo,
|
||||||
|
IN UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context
|
||||||
|
)
|
||||||
|
{
|
||||||
|
UINT8 FormatIndex;
|
||||||
|
|
||||||
|
assert (SegmentInfo != NULL);
|
||||||
|
assert (Context != NULL);
|
||||||
|
|
||||||
|
FormatIndex = UefiImageGetFormat (Context);
|
||||||
|
|
||||||
|
SegmentInfo->SegmentAlignment = UefiImageGetSegmentAlignment (Context);
|
||||||
|
|
||||||
|
if (FormatIndex == UefiImageFormatPe) {
|
||||||
|
return ScanPeGetSegmentInfo (
|
||||||
|
SegmentInfo,
|
||||||
|
(PE_COFF_LOADER_IMAGE_CONTEXT *)Context
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf (
|
||||||
|
stderr,
|
||||||
|
"ImageTool: Unsupported UefiImage format %u\n",
|
||||||
|
FormatIndex
|
||||||
|
);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
ScanUefiImageGetDebugInfo (
|
||||||
|
OUT image_tool_debug_info_t *DebugInfo,
|
||||||
|
IN UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context
|
||||||
|
)
|
||||||
|
{
|
||||||
|
RETURN_STATUS Status;
|
||||||
|
const CHAR8 *SymbolsPath;
|
||||||
|
UINT32 SymbolsPathSize;
|
||||||
|
|
||||||
|
assert (DebugInfo != NULL);
|
||||||
|
assert (Context != NULL);
|
||||||
|
|
||||||
|
Status = UefiImageGetSymbolsPath (Context, &SymbolsPath, &SymbolsPathSize);
|
||||||
|
if (Status == RETURN_NOT_FOUND) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (RETURN_ERROR (Status)) {
|
||||||
|
fprintf (stderr, "ImageTool: Could not get SymbolsPath\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert (SymbolsPathSize >= 1);
|
||||||
|
|
||||||
|
DebugInfo->SymbolsPath = malloc (SymbolsPathSize + 1);
|
||||||
|
if (DebugInfo->SymbolsPath == NULL) {
|
||||||
|
fprintf (stderr, "ImageTool: Could not allocate memory for SymbolsPath\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
memmove (DebugInfo->SymbolsPath, SymbolsPath, SymbolsPathSize);
|
||||||
|
assert (DebugInfo->SymbolsPath[SymbolsPathSize - 1] == '\0');
|
||||||
|
|
||||||
|
DebugInfo->SymbolsPathLen = SymbolsPathSize - 1;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
ScanUefiImageGetHiiInfo (
|
||||||
|
OUT image_tool_hii_info_t *HiiInfo,
|
||||||
|
IN UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context
|
||||||
|
)
|
||||||
|
{
|
||||||
|
RETURN_STATUS Status;
|
||||||
|
UINT32 HiiRva;
|
||||||
|
UINT32 HiiSize;
|
||||||
|
const char *ImageBuffer;
|
||||||
|
|
||||||
|
assert (HiiInfo != NULL);
|
||||||
|
assert (Context != NULL);
|
||||||
|
|
||||||
|
Status = UefiImageGetHiiDataRva (Context, &HiiRva, &HiiSize);
|
||||||
|
if (Status == RETURN_NOT_FOUND) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
ImageBuffer = (char *)UefiImageLoaderGetImageAddress (Context);
|
||||||
|
|
||||||
|
memmove (HiiInfo->Data, ImageBuffer + HiiRva, HiiSize);
|
||||||
|
HiiInfo->DataSize = HiiSize;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
RETURN_STATUS
|
||||||
|
ToolContextConstructUefiImage (
|
||||||
|
OUT image_tool_image_info_t *Image,
|
||||||
|
OUT int8_t *Format,
|
||||||
|
IN const void *File,
|
||||||
|
IN size_t FileSize
|
||||||
|
)
|
||||||
|
{
|
||||||
|
RETURN_STATUS Status;
|
||||||
|
UEFI_IMAGE_LOADER_IMAGE_CONTEXT Context;
|
||||||
|
UINT32 ImageSize;
|
||||||
|
UINT32 ImageAlignment;
|
||||||
|
UINT32 DestinationPages;
|
||||||
|
UINT32 DestinationSize;
|
||||||
|
void *Destination;
|
||||||
|
bool Success;
|
||||||
|
|
||||||
|
assert (Image != NULL);
|
||||||
|
assert (File != NULL || FileSize == 0);
|
||||||
|
|
||||||
|
if (FileSize > MAX_UINT32) {
|
||||||
|
fprintf (stderr, "ImageTool: FileSize is too huge\n");
|
||||||
|
return RETURN_UNSUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = UefiImageInitializeContext (&Context, File, (UINT32)FileSize);
|
||||||
|
if (RETURN_ERROR (Status)) {
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
*Format = (int8_t)UefiImageGetFormat (&Context);
|
||||||
|
|
||||||
|
ImageSize = UefiImageGetImageSize (&Context);
|
||||||
|
DestinationPages = EFI_SIZE_TO_PAGES (ImageSize);
|
||||||
|
DestinationSize = EFI_PAGES_TO_SIZE (DestinationPages);
|
||||||
|
ImageAlignment = UefiImageGetSegmentAlignment (&Context);
|
||||||
|
|
||||||
|
Destination = AllocateAlignedCodePages (DestinationPages, ImageAlignment);
|
||||||
|
if (Destination == NULL) {
|
||||||
|
fprintf (stderr, "ImageTool: Could not allocate Destination buffer\n");
|
||||||
|
return RETURN_OUT_OF_RESOURCES;
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = UefiImageLoadImage (&Context, Destination, DestinationSize);
|
||||||
|
if (RETURN_ERROR (Status)) {
|
||||||
|
fprintf (stderr, "ImageTool: Could not Load Image\n");
|
||||||
|
FreeAlignedPages (Destination, DestinationPages);
|
||||||
|
return RETURN_VOLUME_CORRUPTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset (Image, 0, sizeof (*Image));
|
||||||
|
|
||||||
|
Success = ScanUefiImageGetHeaderInfo (&Image->HeaderInfo, &Context);
|
||||||
|
if (!Success) {
|
||||||
|
fprintf (stderr, "ImageTool: Could not retrieve header info\n");
|
||||||
|
FreeAlignedPages (Destination, DestinationPages);
|
||||||
|
return RETURN_VOLUME_CORRUPTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
Success = ScanUefiImageGetSegmentInfo (&Image->SegmentInfo, &Context);
|
||||||
|
if (!Success) {
|
||||||
|
fprintf (stderr, "ImageTool: Could not retrieve segment info\n");
|
||||||
|
FreeAlignedPages (Destination, DestinationPages);
|
||||||
|
return RETURN_VOLUME_CORRUPTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
Success = ScanUefiImageGetRelocInfo (&Image->RelocInfo, &Context);
|
||||||
|
if (!Success) {
|
||||||
|
fprintf (stderr, "ImageTool: Could not retrieve reloc info\n");
|
||||||
|
FreeAlignedPages (Destination, DestinationPages);
|
||||||
|
return RETURN_VOLUME_CORRUPTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
Success = ScanUefiImageGetHiiInfo (&Image->HiiInfo, &Context);
|
||||||
|
if (!Success) {
|
||||||
|
fprintf (stderr, "ImageTool: Could not retrieve HII info\n");
|
||||||
|
FreeAlignedPages (Destination, DestinationPages);
|
||||||
|
return RETURN_VOLUME_CORRUPTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
Success = ScanUefiImageGetDebugInfo (&Image->DebugInfo, &Context);
|
||||||
|
if (!Success) {
|
||||||
|
fprintf (stderr, "ImageTool: Could not retrieve debug info\n");
|
||||||
|
FreeAlignedPages (Destination, DestinationPages);
|
||||||
|
return RETURN_VOLUME_CORRUPTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
FreeAlignedPages (Destination, DestinationPages);
|
||||||
|
|
||||||
|
return RETURN_SUCCESS;
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user