mirror of
https://github.com/acidanthera/audk.git
synced 2025-09-23 17:57:45 +02:00
ImageTool: Abstract executable generation
This commit is contained in:
parent
75fcd420f6
commit
08778e2a3d
@ -180,8 +180,9 @@ SetHiiResourceHeader (
|
||||
|
||||
static
|
||||
RETURN_STATUS
|
||||
ReadElfFile (
|
||||
IN const char *Name
|
||||
ParseElfFile (
|
||||
IN const void *File,
|
||||
IN uint32_t FileSize
|
||||
)
|
||||
{
|
||||
static const unsigned char Ident[] = {
|
||||
@ -190,23 +191,18 @@ ReadElfFile (
|
||||
const Elf_Shdr *Shdr;
|
||||
UINTN Offset;
|
||||
UINT32 Index;
|
||||
UINT32 FileSize;
|
||||
char *Last;
|
||||
|
||||
assert (Name != NULL);
|
||||
assert (File != NULL || FileSize == 0);
|
||||
|
||||
mEhdr = (Elf_Ehdr *)UserReadFile (Name, &FileSize);
|
||||
if (mEhdr == NULL) {
|
||||
fprintf (stderr, "ImageTool: Could not open %s: %s\n", Name, strerror (errno));
|
||||
return RETURN_VOLUME_CORRUPTED;
|
||||
}
|
||||
mEhdr = (Elf_Ehdr *)File;
|
||||
|
||||
//
|
||||
// Check header
|
||||
//
|
||||
if ((FileSize < sizeof (*mEhdr))
|
||||
|| (memcmp (Ident, mEhdr->e_ident, sizeof (Ident)) != 0)) {
|
||||
fprintf (stderr, "ImageTool: Invalid ELF header in file %s\n", Name);
|
||||
fprintf (stderr, "ImageTool: Invalid ELF header\n");
|
||||
fprintf (stderr, "ImageTool: mEhdr->e_ident[0] = 0x%x expected 0x%x\n", mEhdr->e_ident[0], Ident[0]);
|
||||
fprintf (stderr, "ImageTool: mEhdr->e_ident[1] = 0x%x expected 0x%x\n", mEhdr->e_ident[1], Ident[1]);
|
||||
fprintf (stderr, "ImageTool: mEhdr->e_ident[2] = 0x%x expected 0x%x\n", mEhdr->e_ident[2], Ident[2]);
|
||||
@ -241,7 +237,7 @@ ReadElfFile (
|
||||
Offset = (UINTN)mEhdr->e_shoff + Index * mEhdr->e_shentsize;
|
||||
|
||||
if (FileSize < (Offset + sizeof (*Shdr))) {
|
||||
fprintf (stderr, "ImageTool: ELF section header is outside file %s\n", Name);
|
||||
fprintf (stderr, "ImageTool: ELF section header is outside file\n");
|
||||
return RETURN_VOLUME_CORRUPTED;
|
||||
}
|
||||
|
||||
@ -249,7 +245,7 @@ ReadElfFile (
|
||||
|
||||
if ((Shdr->sh_type != SHT_NOBITS)
|
||||
&& ((FileSize < Shdr->sh_offset) || ((FileSize - Shdr->sh_offset) < Shdr->sh_size))) {
|
||||
fprintf (stderr, "ImageTool: ELF section %d points outside file %s\n", Index, Name);
|
||||
fprintf (stderr, "ImageTool: ELF section %d points outside file\n", Index);
|
||||
return RETURN_VOLUME_CORRUPTED;
|
||||
}
|
||||
|
||||
@ -764,20 +760,17 @@ CreateIntermediate (
|
||||
|
||||
RETURN_STATUS
|
||||
ScanElf (
|
||||
IN const char *ElfName,
|
||||
IN const char *ModuleType
|
||||
IN const void *File,
|
||||
IN uint32_t FileSize,
|
||||
IN const char *SymbolsPath
|
||||
)
|
||||
{
|
||||
RETURN_STATUS Status;
|
||||
|
||||
assert (ElfName != NULL);
|
||||
assert (ModuleType != NULL);
|
||||
assert (File != NULL || FileSize == 0);
|
||||
|
||||
Status = ReadElfFile (ElfName);
|
||||
Status = ParseElfFile (File, FileSize);
|
||||
if (RETURN_ERROR (Status)) {
|
||||
if (mEhdr != NULL) {
|
||||
free (mEhdr);
|
||||
}
|
||||
return Status;
|
||||
}
|
||||
|
||||
@ -788,7 +781,7 @@ ScanElf (
|
||||
mImageInfo.HeaderInfo.IsXip = true;
|
||||
mImageInfo.SegmentInfo.SegmentAlignment = (uint32_t)mPeAlignment;
|
||||
mImageInfo.RelocInfo.RelocsStripped = false;
|
||||
mImageInfo.DebugInfo.SymbolsPathLen = strlen (ElfName);
|
||||
mImageInfo.DebugInfo.SymbolsPathLen = strlen (SymbolsPath);
|
||||
|
||||
switch (mEhdr->e_machine) {
|
||||
#if defined(EFI_TARGET64)
|
||||
@ -808,58 +801,26 @@ ScanElf (
|
||||
#endif
|
||||
default:
|
||||
fprintf (stderr, "ImageTool: Unknown ELF architecture %d\n", mEhdr->e_machine);
|
||||
free (mEhdr);
|
||||
return RETURN_INCOMPATIBLE_VERSION;
|
||||
}
|
||||
|
||||
mImageInfo.DebugInfo.SymbolsPath = malloc (mImageInfo.DebugInfo.SymbolsPathLen + 1);
|
||||
if (mImageInfo.DebugInfo.SymbolsPath == NULL) {
|
||||
fprintf (stderr, "ImageTool: Could not allocate memory for Debug Data\n");
|
||||
free (mEhdr);
|
||||
return RETURN_OUT_OF_RESOURCES;
|
||||
};
|
||||
|
||||
memmove (mImageInfo.DebugInfo.SymbolsPath, ElfName, mImageInfo.DebugInfo.SymbolsPathLen + 1);
|
||||
memmove (mImageInfo.DebugInfo.SymbolsPath, SymbolsPath, mImageInfo.DebugInfo.SymbolsPathLen + 1);
|
||||
|
||||
if ((strcmp (ModuleType, "BASE") == 0)
|
||||
|| (strcmp (ModuleType, "SEC") == 0)
|
||||
|| (strcmp (ModuleType, "SECURITY_CORE") == 0)
|
||||
|| (strcmp (ModuleType, "PEI_CORE") == 0)
|
||||
|| (strcmp (ModuleType, "PEIM") == 0)
|
||||
|| (strcmp (ModuleType, "COMBINED_PEIM_DRIVER") == 0)
|
||||
|| (strcmp (ModuleType, "PIC_PEIM") == 0)
|
||||
|| (strcmp (ModuleType, "RELOCATABLE_PEIM") == 0)
|
||||
|| (strcmp (ModuleType, "DXE_CORE") == 0)
|
||||
|| (strcmp (ModuleType, "BS_DRIVER") == 0)
|
||||
|| (strcmp (ModuleType, "DXE_DRIVER") == 0)
|
||||
|| (strcmp (ModuleType, "DXE_SMM_DRIVER") == 0)
|
||||
|| (strcmp (ModuleType, "UEFI_DRIVER") == 0)
|
||||
|| (strcmp (ModuleType, "SMM_CORE") == 0)
|
||||
|| (strcmp (ModuleType, "MM_STANDALONE") == 0)
|
||||
|| (strcmp (ModuleType, "MM_CORE_STANDALONE") == 0)) {
|
||||
mImageInfo.HeaderInfo.Subsystem = EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER;
|
||||
} else if ((strcmp (ModuleType, "UEFI_APPLICATION") == 0)
|
||||
|| (strcmp (ModuleType, "APPLICATION") == 0)) {
|
||||
mImageInfo.HeaderInfo.Subsystem = EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION;
|
||||
} else if ((strcmp (ModuleType, "DXE_RUNTIME_DRIVER") == 0)
|
||||
|| (strcmp (ModuleType, "RT_DRIVER") == 0)) {
|
||||
mImageInfo.HeaderInfo.Subsystem = EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER;
|
||||
} else if ((strcmp (ModuleType, "DXE_SAL_DRIVER") == 0)
|
||||
|| (strcmp (ModuleType, "SAL_RT_DRIVER") == 0)) {
|
||||
mImageInfo.HeaderInfo.Subsystem = EFI_IMAGE_SUBSYSTEM_SAL_RUNTIME_DRIVER;
|
||||
} else {
|
||||
fprintf (stderr, "ImageTool: Unknown EFI_FILETYPE = %s\n", ModuleType);
|
||||
free (mImageInfo.DebugInfo.SymbolsPath);
|
||||
free (mEhdr);
|
||||
return RETURN_UNSUPPORTED;
|
||||
}
|
||||
//
|
||||
// There is no corresponding ELF property.
|
||||
//
|
||||
mImageInfo.HeaderInfo.Subsystem = 0;
|
||||
|
||||
Status = CreateIntermediate ();
|
||||
if (RETURN_ERROR (Status)) {
|
||||
ToolImageDestruct (&mImageInfo);
|
||||
}
|
||||
|
||||
free (mEhdr);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
@ -14,53 +14,6 @@
|
||||
image_tool_image_info_t mImageInfo;
|
||||
|
||||
|
||||
static
|
||||
RETURN_STATUS
|
||||
PeXip (
|
||||
IN const char *OldName,
|
||||
IN const char *NewName,
|
||||
IN const char *ModuleType
|
||||
)
|
||||
{
|
||||
void *Pe;
|
||||
uint32_t PeSize;
|
||||
RETURN_STATUS Status;
|
||||
image_tool_image_info_t Image;
|
||||
|
||||
assert (OldName != NULL);
|
||||
assert (NewName != NULL);
|
||||
assert (ModuleType != NULL);
|
||||
|
||||
Pe = UserReadFile (OldName, &PeSize);
|
||||
if (Pe == NULL) {
|
||||
fprintf (stderr, "ImageTool: Could not open %s: %s\n", OldName, strerror (errno));
|
||||
return RETURN_ABORTED;
|
||||
}
|
||||
|
||||
Status = ToolContextConstructPe (&Image, Pe, PeSize, ModuleType);
|
||||
|
||||
free (Pe);
|
||||
Pe = NULL;
|
||||
|
||||
if (RETURN_ERROR (Status)) {
|
||||
return RETURN_ABORTED;
|
||||
}
|
||||
|
||||
Pe = ToolImageEmitPe (&Image, &PeSize);
|
||||
if (Pe == NULL) {
|
||||
ToolImageDestruct (&Image);
|
||||
return RETURN_ABORTED;
|
||||
}
|
||||
|
||||
ToolImageDestruct (&Image);
|
||||
|
||||
UserWriteFile (NewName, Pe, PeSize);
|
||||
|
||||
free (Pe);
|
||||
|
||||
return RETURN_SUCCESS;
|
||||
}
|
||||
|
||||
static
|
||||
RETURN_STATUS
|
||||
HiiBin (
|
||||
@ -341,37 +294,115 @@ GetAcpi (
|
||||
}
|
||||
|
||||
static
|
||||
RETURN_STATUS
|
||||
ElfToPe (
|
||||
IN const char *ElfName,
|
||||
IN const char *PeName,
|
||||
IN const char *ModuleType
|
||||
bool
|
||||
ImageSetModuleType (
|
||||
OUT image_tool_image_info_t *Image,
|
||||
IN const char *TypeName
|
||||
)
|
||||
{
|
||||
RETURN_STATUS Status;
|
||||
void *Pe;
|
||||
uint32_t PeSize;
|
||||
uint16_t ModuleType;
|
||||
|
||||
assert (ElfName != NULL);
|
||||
assert (PeName != NULL);
|
||||
assert (ModuleType != NULL);
|
||||
assert (Image != NULL);
|
||||
|
||||
if ((strcmp (TypeName, "BASE") == 0)
|
||||
|| (strcmp (TypeName, "SEC") == 0)
|
||||
|| (strcmp (TypeName, "SECURITY_CORE") == 0)
|
||||
|| (strcmp (TypeName, "PEI_CORE") == 0)
|
||||
|| (strcmp (TypeName, "PEIM") == 0)
|
||||
|| (strcmp (TypeName, "COMBINED_PEIM_DRIVER") == 0)
|
||||
|| (strcmp (TypeName, "PIC_PEIM") == 0)
|
||||
|| (strcmp (TypeName, "RELOCATABLE_PEIM") == 0)
|
||||
|| (strcmp (TypeName, "DXE_CORE") == 0)
|
||||
|| (strcmp (TypeName, "BS_DRIVER") == 0)
|
||||
|| (strcmp (TypeName, "DXE_DRIVER") == 0)
|
||||
|| (strcmp (TypeName, "DXE_SMM_DRIVER") == 0)
|
||||
|| (strcmp (TypeName, "UEFI_DRIVER") == 0)
|
||||
|| (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)
|
||||
|| (strcmp (TypeName, "APPLICATION") == 0)) {
|
||||
ModuleType = EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION;
|
||||
} else 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)
|
||||
|| (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;
|
||||
}
|
||||
|
||||
Image->HeaderInfo.Subsystem = ModuleType;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static
|
||||
RETURN_STATUS
|
||||
GenExecutable (
|
||||
IN const char *OutputFileName,
|
||||
IN const char *InputFileName,
|
||||
IN const char *FormatName,
|
||||
IN const char *TypeName
|
||||
)
|
||||
{
|
||||
UINT32 InputFileSize;
|
||||
VOID *InputFile;
|
||||
RETURN_STATUS Status;
|
||||
bool Result;
|
||||
void *OutputFile;
|
||||
uint32_t OutputFileSize;
|
||||
|
||||
InputFile = UserReadFile (InputFileName, &InputFileSize);
|
||||
if (InputFile == NULL) {
|
||||
fprintf (stderr, "ImageTool: Could not open %s: %s\n", InputFileName, strerror (errno));
|
||||
return RETURN_ABORTED;
|
||||
}
|
||||
|
||||
Status = ToolContextConstructPe (&mImageInfo, InputFile, InputFileSize);
|
||||
if (Status == RETURN_UNSUPPORTED) {
|
||||
Status = ScanElf (InputFile, InputFileSize, InputFileName);
|
||||
}
|
||||
|
||||
free (InputFile);
|
||||
|
||||
Status = ScanElf (ElfName, ModuleType);
|
||||
if (RETURN_ERROR (Status)) {
|
||||
fprintf (stderr, "ImageTool: Could not parse input file %s - %llx\n", InputFileName, (unsigned long long)Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
Pe = ToolImageEmitPe (&mImageInfo, &PeSize);
|
||||
if (Pe == NULL) {
|
||||
if (TypeName != NULL) {
|
||||
Result = ImageSetModuleType (&mImageInfo, TypeName);
|
||||
if (!Result) {
|
||||
ToolImageDestruct (&mImageInfo);
|
||||
return RETURN_UNSUPPORTED;
|
||||
}
|
||||
}
|
||||
|
||||
Result = CheckToolImage (&mImageInfo);
|
||||
if (!Result) {
|
||||
ToolImageDestruct (&mImageInfo);
|
||||
return RETURN_ABORTED;
|
||||
return RETURN_UNSUPPORTED;
|
||||
}
|
||||
|
||||
if (strcmp (FormatName, "PE") == 0) {
|
||||
OutputFile = ToolImageEmitPe (&mImageInfo, &OutputFileSize);
|
||||
} else {
|
||||
assert (false);
|
||||
}
|
||||
|
||||
ToolImageDestruct (&mImageInfo);
|
||||
|
||||
UserWriteFile (PeName, Pe, PeSize);
|
||||
if (OutputFile == NULL) {
|
||||
return RETURN_ABORTED;
|
||||
}
|
||||
|
||||
free (Pe);
|
||||
UserWriteFile (OutputFileName, OutputFile, OutputFileSize);
|
||||
|
||||
free (OutputFile);
|
||||
|
||||
return RETURN_SUCCESS;
|
||||
}
|
||||
@ -387,28 +418,15 @@ int main (int argc, const char *argv[])
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (strcmp (argv[1], "ElfToPe") == 0) {
|
||||
if (strcmp (argv[1], "ElfToPe") == 0 || strcmp (argv[1], "PeXip") == 0) {
|
||||
if (argc < 5) {
|
||||
fprintf (stderr, "ImageTool: Command arguments are missing\n");
|
||||
fprintf (stderr, " Usage: ImageTool ElfToPe InputFile OutputFile ModuleType\n");
|
||||
fprintf (stderr, " Usage: ImageTool %s InputFile OutputFile ModuleType\n", argv[1]);
|
||||
raise ();
|
||||
return -1;
|
||||
}
|
||||
|
||||
Status = ElfToPe (argv[2], argv [3], argv[4]);
|
||||
if (RETURN_ERROR (Status)) {
|
||||
raise ();
|
||||
return -1;
|
||||
}
|
||||
} else if (strcmp (argv[1], "PeXip") == 0) {
|
||||
if (argc < 5) {
|
||||
fprintf (stderr, "ImageTool: Command arguments are missing\n");
|
||||
fprintf (stderr, " Usage: ImageTool PeXip InputFile OutputFile ModuleType\n");
|
||||
raise ();
|
||||
return -1;
|
||||
}
|
||||
|
||||
Status = PeXip (argv[2], argv[3], argv[4]);
|
||||
Status = GenExecutable (argv[3], argv[2], "PE", argv[4]);
|
||||
if (RETURN_ERROR (Status)) {
|
||||
raise ();
|
||||
return -1;
|
||||
|
@ -7,6 +7,8 @@
|
||||
#ifndef IMAGE_TOOL_H
|
||||
#define IMAGE_TOOL_H
|
||||
|
||||
#include <Base.h>
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
@ -152,8 +154,7 @@ RETURN_STATUS
|
||||
ToolContextConstructPe (
|
||||
OUT image_tool_image_info_t *Image,
|
||||
IN const void *File,
|
||||
IN size_t FileSize,
|
||||
IN const char *ModuleType OPTIONAL
|
||||
IN size_t FileSize
|
||||
);
|
||||
|
||||
bool
|
||||
@ -169,8 +170,9 @@ ToolImageEmitPe (
|
||||
|
||||
RETURN_STATUS
|
||||
ScanElf (
|
||||
IN const char *ElfName,
|
||||
IN const char *ModuleType
|
||||
IN const void *File,
|
||||
IN uint32_t FileSize,
|
||||
IN const char *SymbolsPath
|
||||
);
|
||||
|
||||
RETURN_STATUS
|
||||
|
@ -14,8 +14,7 @@ static
|
||||
bool
|
||||
ScanPeGetHeaderInfo (
|
||||
OUT image_tool_header_info_t *HeaderInfo,
|
||||
IN PE_COFF_LOADER_IMAGE_CONTEXT *Context,
|
||||
IN const char *ModuleType OPTIONAL
|
||||
IN PE_COFF_LOADER_IMAGE_CONTEXT *Context
|
||||
)
|
||||
{
|
||||
assert (HeaderInfo != NULL);
|
||||
@ -26,42 +25,7 @@ ScanPeGetHeaderInfo (
|
||||
// FIXME:
|
||||
HeaderInfo->Machine = PeCoffGetMachine (Context);
|
||||
HeaderInfo->IsXip = true;
|
||||
|
||||
if (ModuleType == NULL) {
|
||||
HeaderInfo->Subsystem = PeCoffGetSubsystem (Context);
|
||||
return true;
|
||||
}
|
||||
|
||||
if ((strcmp (ModuleType, "BASE") == 0)
|
||||
|| (strcmp (ModuleType, "SEC") == 0)
|
||||
|| (strcmp (ModuleType, "SECURITY_CORE") == 0)
|
||||
|| (strcmp (ModuleType, "PEI_CORE") == 0)
|
||||
|| (strcmp (ModuleType, "PEIM") == 0)
|
||||
|| (strcmp (ModuleType, "COMBINED_PEIM_DRIVER") == 0)
|
||||
|| (strcmp (ModuleType, "PIC_PEIM") == 0)
|
||||
|| (strcmp (ModuleType, "RELOCATABLE_PEIM") == 0)
|
||||
|| (strcmp (ModuleType, "DXE_CORE") == 0)
|
||||
|| (strcmp (ModuleType, "BS_DRIVER") == 0)
|
||||
|| (strcmp (ModuleType, "DXE_DRIVER") == 0)
|
||||
|| (strcmp (ModuleType, "DXE_SMM_DRIVER") == 0)
|
||||
|| (strcmp (ModuleType, "UEFI_DRIVER") == 0)
|
||||
|| (strcmp (ModuleType, "SMM_CORE") == 0)
|
||||
|| (strcmp (ModuleType, "MM_STANDALONE") == 0)
|
||||
|| (strcmp (ModuleType, "MM_CORE_STANDALONE") == 0)) {
|
||||
HeaderInfo->Subsystem = EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER;
|
||||
} else if ((strcmp (ModuleType, "UEFI_APPLICATION") == 0)
|
||||
|| (strcmp (ModuleType, "APPLICATION") == 0)) {
|
||||
HeaderInfo->Subsystem = EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION;
|
||||
} else if ((strcmp (ModuleType, "DXE_RUNTIME_DRIVER") == 0)
|
||||
|| (strcmp (ModuleType, "RT_DRIVER") == 0)) {
|
||||
HeaderInfo->Subsystem = EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER;
|
||||
} else if ((strcmp (ModuleType, "DXE_SAL_DRIVER") == 0)
|
||||
|| (strcmp (ModuleType, "SAL_RT_DRIVER") == 0)) {
|
||||
HeaderInfo->Subsystem = EFI_IMAGE_SUBSYSTEM_SAL_RUNTIME_DRIVER;
|
||||
} else {
|
||||
fprintf (stderr, "ImageTool: Unknown EFI_FILETYPE = %s\n", ModuleType);
|
||||
return false;
|
||||
}
|
||||
HeaderInfo->Subsystem = PeCoffGetSubsystem (Context);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -397,8 +361,7 @@ RETURN_STATUS
|
||||
ToolContextConstructPe (
|
||||
OUT image_tool_image_info_t *Image,
|
||||
IN const void *File,
|
||||
IN size_t FileSize,
|
||||
IN const char *ModuleType OPTIONAL
|
||||
IN size_t FileSize
|
||||
)
|
||||
{
|
||||
PE_COFF_LOADER_IMAGE_CONTEXT Context;
|
||||
@ -446,7 +409,7 @@ ToolContextConstructPe (
|
||||
|
||||
memset (Image, 0, sizeof (*Image));
|
||||
|
||||
Result = ScanPeGetHeaderInfo (&Image->HeaderInfo, &Context, ModuleType);
|
||||
Result = ScanPeGetHeaderInfo (&Image->HeaderInfo, &Context);
|
||||
if (!Result) {
|
||||
fprintf (stderr, "ImageTool: Could not retrieve header info\n");
|
||||
ToolImageDestruct (Image);
|
||||
|
Loading…
x
Reference in New Issue
Block a user