mirror of
https://github.com/acidanthera/audk.git
synced 2025-09-23 17:57:45 +02:00
ImageTool: Separate image generation from file I/O logic
This commit is contained in:
parent
5976987671
commit
efb6eea39e
@ -7,7 +7,7 @@
|
||||
PROJECT = ImageTool
|
||||
PRODUCT = $(PROJECT)$(INFIX)$(SUFFIX)
|
||||
OBJS = $(PROJECT).o
|
||||
OBJS += Image.o PeEmit32.o PeEmit64.o PeEmitCommon.o PeScan.o ElfScan32.o ElfScan64.o ElfScanCommon.o BinEmit.o
|
||||
OBJS += Image.o PeEmit32.o PeEmit64.o PeEmitCommon.o PeScan.o ElfScan32.o ElfScan64.o ElfScanCommon.o BinEmit.o ImageToolEmit.o
|
||||
OBJS += UefiImageExtraActionLib.o
|
||||
OBJS += PeCoffInit.o PeCoffInfo.o PeCoffLoad.o PeCoffRelocate.o PeCoffHii.o PeCoffDebug.o
|
||||
|
||||
|
@ -9,6 +9,8 @@
|
||||
#include <IndustryStandard/Acpi30.h>
|
||||
#include <IndustryStandard/MemoryMappedConfigurationSpaceAccessTable.h>
|
||||
|
||||
#include "ImageToolEmit.h"
|
||||
|
||||
#define EFI_ACPI_1_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_VERSION 0x0
|
||||
|
||||
|
||||
@ -224,16 +226,11 @@ GetAcpi (
|
||||
}
|
||||
|
||||
static
|
||||
bool
|
||||
ImageSetModuleType (
|
||||
OUT image_tool_image_info_t *Image,
|
||||
IN const char *TypeName
|
||||
int32_t
|
||||
NameToType (
|
||||
IN const char *TypeName
|
||||
)
|
||||
{
|
||||
uint16_t ModuleType;
|
||||
|
||||
assert (Image != NULL);
|
||||
|
||||
if ((strcmp (TypeName, "BASE") == 0)
|
||||
|| (strcmp (TypeName, "SEC") == 0)
|
||||
|| (strcmp (TypeName, "SECURITY_CORE") == 0)
|
||||
@ -250,61 +247,38 @@ ImageSetModuleType (
|
||||
|| (strcmp (TypeName, "SMM_CORE") == 0)
|
||||
|| (strcmp (TypeName, "MM_STANDALONE") == 0)
|
||||
|| (strcmp (TypeName, "MM_CORE_STANDALONE") == 0)) {
|
||||
ModuleType = EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER;
|
||||
} else if ((strcmp (TypeName, "UEFI_APPLICATION") == 0)
|
||||
return EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER;
|
||||
}
|
||||
|
||||
if ((strcmp (TypeName, "UEFI_APPLICATION") == 0)
|
||||
|| (strcmp (TypeName, "APPLICATION") == 0)) {
|
||||
ModuleType = EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION;
|
||||
} else if ((strcmp (TypeName, "DXE_RUNTIME_DRIVER") == 0)
|
||||
return EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION;
|
||||
}
|
||||
|
||||
if ((strcmp (TypeName, "DXE_RUNTIME_DRIVER") == 0)
|
||||
|| (strcmp (TypeName, "RT_DRIVER") == 0)) {
|
||||
ModuleType = EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER;
|
||||
} else if ((strcmp (TypeName, "DXE_SAL_DRIVER") == 0)
|
||||
return EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER;
|
||||
}
|
||||
|
||||
if ((strcmp (TypeName, "DXE_SAL_DRIVER") == 0)
|
||||
|| (strcmp (TypeName, "SAL_RT_DRIVER") == 0)) {
|
||||
ModuleType = EFI_IMAGE_SUBSYSTEM_SAL_RUNTIME_DRIVER;
|
||||
} else {
|
||||
fprintf (stderr, "ImageTool: Unknown EFI_FILETYPE = %s\n", TypeName);
|
||||
return false;
|
||||
return EFI_IMAGE_SUBSYSTEM_SAL_RUNTIME_DRIVER;
|
||||
}
|
||||
|
||||
Image->HeaderInfo.Subsystem = ModuleType;
|
||||
|
||||
return true;
|
||||
return -1;
|
||||
}
|
||||
|
||||
static
|
||||
RETURN_STATUS
|
||||
ValidateOutputFile (
|
||||
void *OutputFile,
|
||||
uint32_t OutputFileSize,
|
||||
const image_tool_image_info_t *ImageInfo
|
||||
int8_t
|
||||
NameToFormat (
|
||||
IN const char *FormatName
|
||||
)
|
||||
{
|
||||
RETURN_STATUS Status;
|
||||
bool Result;
|
||||
image_tool_image_info_t OutputImageInfo;
|
||||
|
||||
Status = ToolContextConstructPe (&OutputImageInfo, OutputFile, OutputFileSize);
|
||||
if (EFI_ERROR (Status)) {
|
||||
assert (false);
|
||||
return Status;
|
||||
if (strcmp (FormatName, "PE") == 0) {
|
||||
return UefiImageFormatPe;
|
||||
}
|
||||
|
||||
Result = CheckToolImage (&OutputImageInfo);
|
||||
if (!Result) {
|
||||
raise ();
|
||||
ToolImageDestruct (&OutputImageInfo);
|
||||
return RETURN_UNSUPPORTED;
|
||||
}
|
||||
|
||||
Result = ToolImageCompare (&OutputImageInfo, ImageInfo);
|
||||
|
||||
ToolImageDestruct (&OutputImageInfo);
|
||||
|
||||
if (!Result) {
|
||||
assert (false);
|
||||
return RETURN_VOLUME_CORRUPTED;
|
||||
}
|
||||
|
||||
return RETURN_SUCCESS;
|
||||
return -1;
|
||||
}
|
||||
|
||||
static
|
||||
@ -318,16 +292,43 @@ GenExecutable (
|
||||
IN const char *BaseAddress
|
||||
)
|
||||
{
|
||||
UINT32 InputFileSize;
|
||||
VOID *InputFile;
|
||||
UINT32 HiiFileSize;
|
||||
VOID *HiiFile;
|
||||
RETURN_STATUS Status;
|
||||
bool Result;
|
||||
image_tool_image_info_t ImageInfo;
|
||||
UINT64 NewBaseAddress;
|
||||
void *OutputFile;
|
||||
uint32_t OutputFileSize;
|
||||
UINT32 InputFileSize;
|
||||
VOID *InputFile;
|
||||
int8_t Format;
|
||||
int32_t Type;
|
||||
UINT32 HiiFileSize;
|
||||
VOID *HiiFile;
|
||||
RETURN_STATUS Status;
|
||||
UINT64 NewBaseAddress;
|
||||
void *OutputFile;
|
||||
uint32_t OutputFileSize;
|
||||
|
||||
Format = -1;
|
||||
if (FormatName != NULL) {
|
||||
Format = NameToFormat (FormatName);
|
||||
if (Format == -1) {
|
||||
fprintf (stderr, "ImageTool: Unknown output format %s\n", FormatName);
|
||||
return RETURN_UNSUPPORTED;
|
||||
}
|
||||
}
|
||||
|
||||
Type = -1;
|
||||
if (TypeName != NULL) {
|
||||
Type = NameToType (TypeName);
|
||||
if (Type == -1) {
|
||||
fprintf (stderr, "ImageTool: Unknown EFI_FILETYPE = %s\n", TypeName);
|
||||
return RETURN_UNSUPPORTED;
|
||||
}
|
||||
}
|
||||
|
||||
NewBaseAddress = 0;
|
||||
if (BaseAddress != NULL) {
|
||||
Status = AsciiStrHexToUint64S (BaseAddress, NULL, &NewBaseAddress);
|
||||
if (RETURN_ERROR (Status)) {
|
||||
fprintf (stderr, "ImageTool: Could not convert ASCII string to UINT64\n");
|
||||
return Status;
|
||||
}
|
||||
}
|
||||
|
||||
InputFile = UserReadFile (InputFileName, &InputFileSize);
|
||||
if (InputFile == NULL) {
|
||||
@ -335,83 +336,34 @@ GenExecutable (
|
||||
return RETURN_ABORTED;
|
||||
}
|
||||
|
||||
Status = ToolContextConstructPe (&ImageInfo, InputFile, InputFileSize);
|
||||
if (Status == RETURN_UNSUPPORTED) {
|
||||
Status = ScanElf (&ImageInfo, InputFile, InputFileSize, InputFileName);
|
||||
}
|
||||
|
||||
free (InputFile);
|
||||
|
||||
if (RETURN_ERROR (Status)) {
|
||||
fprintf (stderr, "ImageTool: Could not parse input file %s - %llx\n", InputFileName, (unsigned long long)Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
if (TypeName != NULL) {
|
||||
Result = ImageSetModuleType (&ImageInfo, TypeName);
|
||||
if (!Result) {
|
||||
ToolImageDestruct (&ImageInfo);
|
||||
return RETURN_UNSUPPORTED;
|
||||
}
|
||||
}
|
||||
|
||||
HiiFile = NULL;
|
||||
HiiFileSize = 0;
|
||||
if (HiiFileName != NULL) {
|
||||
HiiFile = UserReadFile (HiiFileName, &HiiFileSize);
|
||||
if (HiiFile == NULL) {
|
||||
fprintf (stderr, "ImageTool: Could not open %s: %s\n", HiiFileName, strerror (errno));
|
||||
return RETURN_ABORTED;
|
||||
}
|
||||
|
||||
free (ImageInfo.HiiInfo.Data);
|
||||
|
||||
ImageInfo.HiiInfo.Data = HiiFile;
|
||||
ImageInfo.HiiInfo.DataSize = HiiFileSize;
|
||||
}
|
||||
|
||||
ToolImageSortRelocs (&ImageInfo);
|
||||
|
||||
Result = CheckToolImage (&ImageInfo);
|
||||
if (!Result) {
|
||||
ToolImageDestruct (&ImageInfo);
|
||||
return RETURN_UNSUPPORTED;
|
||||
}
|
||||
|
||||
if (BaseAddress != NULL) {
|
||||
Status = AsciiStrHexToUint64S (BaseAddress, NULL, &NewBaseAddress);
|
||||
if (RETURN_ERROR (Status)) {
|
||||
fprintf (stderr, "ImageTool: Could not convert ASCII string to UINT64\n");
|
||||
ToolImageDestruct (&ImageInfo);
|
||||
return Status;
|
||||
}
|
||||
|
||||
Result = ToolImageRelocate (&ImageInfo, NewBaseAddress);
|
||||
if (!Result) {
|
||||
fprintf (stderr, "ImageTool: Failed to relocate input file %s\n", InputFileName);
|
||||
ToolImageDestruct (&ImageInfo);
|
||||
return RETURN_UNSUPPORTED;
|
||||
}
|
||||
}
|
||||
|
||||
if (strcmp (FormatName, "PE") == 0) {
|
||||
OutputFile = ToolImageEmitPe (&ImageInfo, &OutputFileSize);
|
||||
} else {
|
||||
assert (false);
|
||||
}
|
||||
OutputFile = ToolImageEmit (
|
||||
&OutputFileSize,
|
||||
InputFile,
|
||||
InputFileSize,
|
||||
Format,
|
||||
Type,
|
||||
HiiFile,
|
||||
HiiFileSize,
|
||||
BaseAddress != NULL,
|
||||
NewBaseAddress,
|
||||
InputFileName
|
||||
);
|
||||
|
||||
if (OutputFile == NULL) {
|
||||
ToolImageDestruct (&ImageInfo);
|
||||
free (HiiFile);
|
||||
return RETURN_ABORTED;
|
||||
}
|
||||
|
||||
Status = ValidateOutputFile (OutputFile, OutputFileSize, &ImageInfo);
|
||||
|
||||
ToolImageDestruct (&ImageInfo);
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
assert (false);
|
||||
return Status;
|
||||
}
|
||||
|
||||
UserWriteFile (OutputFileName, OutputFile, OutputFileSize);
|
||||
|
||||
free (OutputFile);
|
||||
|
179
BaseTools/ImageTool/ImageToolEmit.c
Normal file
179
BaseTools/ImageTool/ImageToolEmit.c
Normal file
@ -0,0 +1,179 @@
|
||||
/** @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 <stdlib.h>
|
||||
|
||||
#include "ImageToolEmit.h"
|
||||
|
||||
static
|
||||
RETURN_STATUS
|
||||
ToolContextConstruct (
|
||||
OUT image_tool_image_info_t *ImageInfo,
|
||||
OUT int8_t *Format,
|
||||
IN const void *File,
|
||||
IN size_t FileSize,
|
||||
IN const char *SymbolsPath OPTIONAL
|
||||
)
|
||||
{
|
||||
RETURN_STATUS Status;
|
||||
|
||||
*Format = -1;
|
||||
|
||||
Status = ToolContextConstructPe (
|
||||
ImageInfo,
|
||||
File,
|
||||
FileSize
|
||||
);
|
||||
if (!RETURN_ERROR (Status)) {
|
||||
*Format = UefiImageFormatPe;
|
||||
} else if (Status == RETURN_UNSUPPORTED) {
|
||||
Status = ScanElf (ImageInfo, File, FileSize, SymbolsPath);
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
static
|
||||
RETURN_STATUS
|
||||
ValidateOutputFile (
|
||||
void *OutputFile,
|
||||
uint32_t OutputFileSize,
|
||||
const image_tool_image_info_t *ImageInfo
|
||||
)
|
||||
{
|
||||
RETURN_STATUS Status;
|
||||
bool Result;
|
||||
image_tool_image_info_t OutputImageInfo;
|
||||
int8_t Format;
|
||||
|
||||
Status = ToolContextConstruct (
|
||||
&OutputImageInfo,
|
||||
&Format,
|
||||
OutputFile,
|
||||
OutputFileSize,
|
||||
NULL
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
assert (false);
|
||||
return Status;
|
||||
}
|
||||
|
||||
Result = CheckToolImage (&OutputImageInfo);
|
||||
if (!Result) {
|
||||
raise ();
|
||||
ToolImageDestruct (&OutputImageInfo);
|
||||
return RETURN_UNSUPPORTED;
|
||||
}
|
||||
|
||||
Result = ToolImageCompare (&OutputImageInfo, ImageInfo);
|
||||
|
||||
ToolImageDestruct (&OutputImageInfo);
|
||||
|
||||
if (!Result) {
|
||||
assert (false);
|
||||
return RETURN_VOLUME_CORRUPTED;
|
||||
}
|
||||
|
||||
return RETURN_SUCCESS;
|
||||
}
|
||||
|
||||
void *
|
||||
ToolImageEmit (
|
||||
OUT uint32_t *OutputFileSize,
|
||||
IN const void *Buffer,
|
||||
IN uint64_t BufferSize,
|
||||
IN int8_t Format,
|
||||
IN int32_t Type,
|
||||
IN void *HiiFile,
|
||||
IN uint32_t HiiFileSize,
|
||||
IN bool Relocate,
|
||||
IN uint64_t BaseAddress,
|
||||
IN const char *SymbolsPath OPTIONAL
|
||||
)
|
||||
{
|
||||
RETURN_STATUS Status;
|
||||
bool Success;
|
||||
image_tool_image_info_t ImageInfo;
|
||||
int8_t SourceFormat;
|
||||
void *OutputFile;
|
||||
|
||||
Status = ToolContextConstruct (
|
||||
&ImageInfo,
|
||||
&SourceFormat,
|
||||
Buffer,
|
||||
BufferSize,
|
||||
SymbolsPath
|
||||
);
|
||||
|
||||
if (SymbolsPath == NULL) {
|
||||
SymbolsPath = "<unknown>";
|
||||
}
|
||||
|
||||
if (RETURN_ERROR (Status)) {
|
||||
fprintf (stderr, "ImageTool: Could not parse input file %s - %llx\n", SymbolsPath, (unsigned long long)Status);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (Format == -1) {
|
||||
Format = SourceFormat;
|
||||
if (Format == -1) {
|
||||
fprintf (stderr, "ImageTool: Unknown output format of file %s\n", SymbolsPath);
|
||||
ToolImageDestruct (&ImageInfo);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (Type != -1) {
|
||||
ImageInfo.HeaderInfo.Subsystem = (uint16_t)Type;
|
||||
}
|
||||
|
||||
if (HiiFile != NULL) {
|
||||
free (ImageInfo.HiiInfo.Data);
|
||||
|
||||
ImageInfo.HiiInfo.Data = HiiFile;
|
||||
ImageInfo.HiiInfo.DataSize = HiiFileSize;
|
||||
}
|
||||
|
||||
ToolImageSortRelocs (&ImageInfo);
|
||||
|
||||
Success = CheckToolImage (&ImageInfo);
|
||||
if (!Success) {
|
||||
ToolImageDestruct (&ImageInfo);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (Relocate) {
|
||||
Success = ToolImageRelocate (&ImageInfo, BaseAddress);
|
||||
if (!Success) {
|
||||
fprintf (stderr, "ImageTool: Failed to relocate input file %s\n", SymbolsPath);
|
||||
ToolImageDestruct (&ImageInfo);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
OutputFile = NULL;
|
||||
if (Format == UefiImageFormatPe) {
|
||||
OutputFile = ToolImageEmitPe (&ImageInfo, OutputFileSize);
|
||||
} else {
|
||||
assert (false);
|
||||
}
|
||||
|
||||
Status = ValidateOutputFile (OutputFile, *OutputFileSize, &ImageInfo);
|
||||
|
||||
ToolImageDestruct (&ImageInfo);
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
assert (false);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return OutputFile;
|
||||
}
|
27
BaseTools/ImageTool/ImageToolEmit.h
Normal file
27
BaseTools/ImageTool/ImageToolEmit.h
Normal file
@ -0,0 +1,27 @@
|
||||
/** @file
|
||||
Copyright (c) 2023, Marvin Häuser. All rights reserved.
|
||||
SPDX-License-Identifier: BSD-3-Clause
|
||||
**/
|
||||
|
||||
#ifndef IMAGE_TOOL_EMIT_H
|
||||
#define IMAGE_TOOL_EMIT_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <Base.h>
|
||||
|
||||
void *
|
||||
ToolImageEmit (
|
||||
OUT uint32_t *OutputFileSize,
|
||||
IN const void *Buffer,
|
||||
IN uint64_t BufferSize,
|
||||
IN int8_t Format,
|
||||
IN int32_t Type,
|
||||
IN void *HiiFile,
|
||||
IN uint32_t HiiFileSize,
|
||||
IN bool Relocate,
|
||||
IN uint64_t BaseAddress,
|
||||
IN const char *SymbolsPath OPTIONAL
|
||||
);
|
||||
|
||||
#endif // IMAGE_TOOL_EMIT_H
|
@ -19,7 +19,7 @@ OV = $(UDK_PATH)\MdePkg\Library\BaseOverflowLib
|
||||
PE = $(UDK_PATH)\MdePkg\Library\BasePeCoffLib2
|
||||
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
|
||||
OBJECTS = ImageTool.obj Image.obj PeEmit32.obj PeEmit64.obj PeEmitCommon.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) {$(PE)}PeCoffInit.obj PeCoffInfo.obj PeCoffRelocate.obj PeCoffLoad.obj PeCoffHii.obj PeCoffDebug.obj
|
||||
|
||||
|
@ -2,6 +2,11 @@
|
||||
#ifndef UEFI_IMAGE_LIB_H_
|
||||
#define UEFI_IMAGE_LIB_H_
|
||||
|
||||
typedef enum {
|
||||
UefiImageFormatPe = 0,
|
||||
UefiImageFormatMax
|
||||
} UEFI_IMAGE_FORMAT;
|
||||
|
||||
// FIXME: Work on reasonable abstraction
|
||||
#ifndef UEFI_IMAGE_LOADER_IMAGE_CONTEXT
|
||||
#include <Library/PeCoffLib2.h>
|
||||
|
Loading…
x
Reference in New Issue
Block a user