GenFw.c revision 4fd606d1f5abe38e1f42c38de1d2e895166bd0f4
/** @file
Copyright (c) 2004 - 2011, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
Module Name:
Abstract:
Converts a pe32+ image to an FW, Te image type, or other specific image.
**/
#include "WinNtInclude.h"
#ifndef __GNUC__
#include <windows.h>
#include <io.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <ctype.h>
#include <Common/UefiBaseTypes.h>
#include <IndustryStandard/PeImage.h>
#include <Common/UefiInternalFormRepresentation.h>
//
// Acpi Table definition
//
#include <IndustryStandard/Acpi.h>
#include <IndustryStandard/Acpi1_0.h>
#include <IndustryStandard/Acpi2_0.h>
#include <IndustryStandard/Acpi3_0.h>
#include "CommonLib.h"
#include "PeCoffLib.h"
#include "ParseInf.h"
#include "EfiUtilityMsgs.h"
#include "GenFw.h"
//
// Version of this utility
//
#define UTILITY_NAME "GenFw"
#define UTILITY_MAJOR_VERSION 0
#define UTILITY_MINOR_VERSION 2
#define HII_RESOURCE_SECTION_INDEX 1
#define HII_RESOURCE_SECTION_NAME "HII"
#define DEFAULT_MC_PAD_BYTE_VALUE 0xFF
#define DEFAULT_MC_ALIGNMENT 16
#ifndef _MAX_PATH
#define _MAX_PATH 500
#endif
#define STATUS_IGNORE 0xA
//
// Structure definition for a microcode header
//
typedef struct {
static const char *gHiiPackageRCFileHeader[] = {
"//",
"// DO NOT EDIT -- auto-generated file",
"//",
};
//
// Module image information
//
UINT32 mImageTimeStamp = 0;
UINT32 mImageSize = 0;
);
SetStamp (
);
);
Version (
)
/*++
Routine Description:
Print out version information for this utility.
Arguments:
None
Returns:
None
--*/
{
fprintf (stdout, "%s Version %d.%d %s \n", UTILITY_NAME, UTILITY_MAJOR_VERSION, UTILITY_MINOR_VERSION, __BUILD_VERSION);
}
Usage (
)
/*++
Routine Description:
Print Help message.
Arguments:
VOID
Returns:
None
--*/
{
//
// Summary usage
//
//
// Copyright declaration
//
//
// Details Option
//
File will be created to store the ouput content.\n");
Create Efi Image. EFI_FILETYPE is one of BASE,SMM_CORE,\n\
PEI_CORE, PEIM, DXE_CORE, DXE_DRIVER, UEFI_APPLICATION,\n\
SEC, DXE_SAL_DRIVER, UEFI_DRIVER, DXE_RUNTIME_DRIVER,\n\
DXE_SMM_DRIVER, SECURITY_CORE, COMBINED_PEIM_DRIVER,\n\
PIC_PEIM, RELOCATABLE_PEIM, BS_DRIVER, RT_DRIVER,\n\
APPLICATION, SAL_RT_DRIVER to support all module types\n\
It can only be used together with --keepexceptiontable,\n\
--keepzeropending, -r, -o option.It is a action option.\n\
If it is combined with other action options, the later\n\
input action option will override the previous one.\n");
It can't be combined with other action options\n\
except for -o, -r option. It is a action option.\n\
If it is combined with other action options, the later\n\
input action option will override the previous one.\n");
It can only be used together with --keepexceptiontable,\n\
--keepzeropending, -r, -o option.It is a action option.\n\
If it is combined with other action options, the later\n\
input action option will override the previous one.\n");
It can't be combined with other action options\n\
except for -o, -r option. It is a action option.\n\
If it is combined with other action options, the later\n\
input action option will override the previous one.\n");
It also zeros the time stamp fields.\n\
This option can be used to compare the binary efi image.\n\
It can't be combined with other action options\n\
except for -o, -r option. It is a action option.\n\
If it is combined with other action options, the later\n\
input action option will override the previous one.\n");
It can't be combined with other action options\n\
except for -o, -r option. It is a action option.\n\
If it is combined with other action options, the later\n\
input action option will override the previous one.\n");;
It can't be combined with other action options\n\
except for -o, -r option. It is a action option.\n\
If it is combined with other action options, the later\n\
input action option will override the previous one.\n");
timedate format is \"yyyy-mm-dd 00:00:00\". if timedata \n\
is set to NOW, current system time is used. The support\n\
date scope is 1970-01-01 00+timezone:00:00\n\
~ 2038-01-19 03+timezone:14:07\n\
The scope is adjusted according to the different zones.\n\
It can't be combined with other action options\n\
except for -o, -r option. It is a action option.\n\
If it is combined with other action options, the later\n\
input action option will override the previous one.\n");
It can't be combined with other action options\n\
except for -o option. It is a action option.\n\
If it is combined with other action options, the later\n\
input action option will override the previous one.\n");
It can be specified with -a, -p, -o option.\n\
No other options can be combined with it.\n\
If it is combined with other action options, the later\n\
input action option will override the previous one.\n");
This option is only used together with -j option.\n");
This option is only used together with -j option.\n");
This option can be used together with -e or -t.\n\
It doesn't work for other options.\n");
This option can be used together with -e or -t.\n\
It doesn't work for other options.\n");
If more input files are specified,\n\
the last input file will be as the output file.\n");
Guid is used to specify hii package list guid.\n\
Its format is xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\n\
If not specified, the first Form FormSet guid is used.\n");
a single package list as the text resource data(RC).\n\
It can't be combined with other action options\n\
except for -o option. It is a action option.\n\
If it is combined with other action options, the later\n\
input action option will override the previous one.\n");
a single package list as the binary resource section.\n\
It can't be combined with other action options\n\
except for -o option. It is a action option.\n\
If it is combined with other action options, the later\n\
input action option will override the previous one.\n");
is also set to the first none code section header.\n\
It can't be combined with other action options\n\
except for -o or -r option. It is a action option.\n\
If it is combined with other action options, the later\n\
input action option will override the previous one.\n");
section header of the input image.\n\
It can't be combined with other action options\n\
except for -o or -r option. It is a action option.\n\
If it is combined with other action options, the later\n\
input action option will override the previous one.\n");
}
)
/*++
Routine Description:
Check Acpi Table
Arguments:
AcpiTable Buffer for AcpiSection
Length AcpiSection Length
Returns:
0 success
non-zero otherwise
--*/
{
//
// Generic check for AcpiTable length.
//
return STATUS_ERROR;
}
//
// Currently, we only check must-have tables: FADT, FACS, DSDT,
// and some important tables: MADT, MCFG.
//
switch (AcpiHeader->Signature) {
//
// "FACP" Fixed ACPI Description Table
//
switch (AcpiHeader->Revision) {
break;
break;
break;
default:
break;
}
return STATUS_ERROR;
}
return STATUS_ERROR;
}
break;
//
// "FACS" Firmware ACPI Control Structure
//
break;
}
return STATUS_ERROR;
}
return STATUS_ERROR;
}
break;
//
// "DSDT" Differentiated System Description Table
//
break;
}
return STATUS_ERROR;
}
break;
//
// "APIC" Multiple APIC Description Table
//
break;
}
return STATUS_ERROR;
}
return STATUS_ERROR;
}
break;
//
// "MCFG" PCI Express Memory Mapped Configuration Space Base Address Description Table
//
case EFI_ACPI_3_0_PCI_EXPRESS_MEMORY_MAPPED_CONFIGURATION_SPACE_BASE_ADDRESS_DESCRIPTION_TABLE_SIGNATURE:
break;
}
return STATUS_ERROR;
}
return STATUS_ERROR;
}
break;
//
// Other table pass check
//
default:
break;
}
return STATUS_SUCCESS;
}
)
{
//
// Fill Resource section entry
//
ResourceDirectoryString = (EFI_IMAGE_RESOURCE_DIRECTORY_STRING *) (HiiBinData + ResourceDirectoryEntry->u1.s.NameOffset);
//
// Resource Type "HII" found
//
//
// Move to next level - resource Name
//
ResourceDirectory = (EFI_IMAGE_RESOURCE_DIRECTORY *) (HiiBinData + ResourceDirectoryEntry->u2.s.OffsetToDirectory);
//
// Move to next level - resource Language
//
ResourceDirectory = (EFI_IMAGE_RESOURCE_DIRECTORY *) (HiiBinData + ResourceDirectoryEntry->u2.s.OffsetToDirectory);
}
}
//
// Now it ought to be resource Data and update its OffsetToData value
//
ResourceDataEntry = (EFI_IMAGE_RESOURCE_DATA_ENTRY *) (HiiBinData + ResourceDirectoryEntry->u2.OffsetToData);
break;
}
}
}
}
return;
}
void *Data
)
{
//
// Read the dos & pe hdrs of the image
//
return NULL;
}
} else {
return NULL;
}
}
return PeHdr;
}
void
UINT8 **FileBuffer,
)
{
return;
}
//
// The only reason to expand zero fill sections is to make them compatible with XIP images.
// If SectionAlignment is not equal to FileAlginment then it is not an XIP type image.
//
return;
}
//
// Calculate size of XIP file, and determine if the conversion is needed.
//
XipLength = 0;
SectionHeader = (EFI_IMAGE_SECTION_HEADER *) ((UINT8 *) &(PeHdr->Pe32.OptionalHeader) + PeHdr->Pe32.FileHeader.SizeOfOptionalHeader);
if (SectionSize > 0) {
}
}
}
}
//
// If one of the sections should be loaded to an offset overlapping with
// the executable header, then it cannot be made into an XIP image.
//
VerboseMsg ("PE/COFF conversion to XIP is impossible due to overlap");
VerboseMsg ("of section data with the executable header.");
return;
}
if (FirstSectionOffset == *FileLength) {
//
// If we never found a section with a non-zero size, then we
// skip the conversion.
//
return;
}
if (!ConversionNeeded) {
return;
}
VerboseMsg ("PE/COFF conversion to XIP appears to be larger than necessary.");
VerboseMsg ("The image linking process may have left unused memory ranges.");
}
//
// This field is obsolete and should be zero
//
}
//
// Allocate the extra space that we need to grow the image
//
//
// Copy the file headers
//
return;
}
//
// Copy the section data over to the appropriate XIP offsets
//
SectionHeader = (EFI_IMAGE_SECTION_HEADER *) ((UINT8 *) &(NewPeHdr->Pe32.OptionalHeader) + NewPeHdr->Pe32.FileHeader.SizeOfOptionalHeader);
if (SectionHeader->SizeOfRawData > 0) {
memcpy (
);
}
//
// Make the size of raw data in section header alignment.
//
SectionHeader->SizeOfRawData = (SectionHeader->Misc.VirtualSize + PeHdr->Pe32.OptionalHeader.FileAlignment - 1) & (~(PeHdr->Pe32.OptionalHeader.FileAlignment - 1));
}
free (*FileBuffer);
*FileLength = XipLength;
*FileBuffer = XipFile;
}
UINT8 *
)
/*++
Routine Description:
Create COFF resource section header
Arguments:
pSectionHeaderSize - Pointer to section header size.
HiiDataSize - Size of the total HII data in section.
Returns:
The created section header buffer.
--*/
{
//
// Calculate the total size for the resource header (include Type, Name and Language)
// then allocate memory for the resource header.
//
HiiSectionHeaderSize = 3 * (sizeof (EFI_IMAGE_RESOURCE_DIRECTORY) + sizeof (EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY))
+ sizeof (EFI_IMAGE_RESOURCE_DATA_ENTRY);
HiiSectionOffset = 0;
//
// Create Type entry
//
HiiSectionOffset += sizeof (EFI_IMAGE_RESOURCE_DIRECTORY);
TypeResourceDirectoryEntry = (EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY *) (HiiSectionHeader + HiiSectionOffset);
HiiSectionOffset += sizeof (EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY);
//
// Create Name entry
//
HiiSectionOffset += sizeof (EFI_IMAGE_RESOURCE_DIRECTORY);
NameResourceDirectoryEntry = (EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY *) (HiiSectionHeader + HiiSectionOffset);
HiiSectionOffset += sizeof (EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY);
//
// Create Language entry
//
HiiSectionOffset += sizeof (EFI_IMAGE_RESOURCE_DIRECTORY);
LanguageResourceDirectoryEntry = (EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY *) (HiiSectionHeader + HiiSectionOffset);
HiiSectionOffset += sizeof (EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY);
//
// Create string entry for Type
//
ResourceDirectoryString = (EFI_IMAGE_RESOURCE_DIRECTORY_STRING *) (HiiSectionHeader + HiiSectionOffset);
HiiSectionOffset = HiiSectionOffset + sizeof (ResourceDirectoryString->Length) + ResourceDirectoryString->Length * sizeof (ResourceDirectoryString->String[0]);
//
// Create string entry for Name
//
ResourceDirectoryString = (EFI_IMAGE_RESOURCE_DIRECTORY_STRING *) (HiiSectionHeader + HiiSectionOffset);
HiiSectionOffset = HiiSectionOffset + sizeof (ResourceDirectoryString->Length) + ResourceDirectoryString->Length * sizeof (ResourceDirectoryString->String[0]);
//
// Create string entry for Language
//
ResourceDirectoryString = (EFI_IMAGE_RESOURCE_DIRECTORY_STRING *) (HiiSectionHeader + HiiSectionOffset);
HiiSectionOffset = HiiSectionOffset + sizeof (ResourceDirectoryString->Length) + ResourceDirectoryString->Length * sizeof (ResourceDirectoryString->String[0]);
//
// Create Leaf data
//
HiiSectionOffset += sizeof (EFI_IMAGE_RESOURCE_DATA_ENTRY);
return HiiSectionHeader;
}
)
/*++
Routine Description:
Arguments:
FileOffset - The offset, in bytes, into the file to read
ReadSize - The number of bytes to read from the file starting at FileOffset
Buffer - A pointer to the buffer to read the data into.
Returns:
EFI_SUCCESS - ReadSize bytes of data were read into Buffer from the PE/COFF file starting at FileOffset
--*/
{
while (Length--) {
*(Destination8++) = *(Source8++);
}
return EFI_SUCCESS;
}
)
/*++
Routine Description:
Set new base address into the section header of PeImage
Arguments:
FileName - Name of file
FileBuffer - Pointer to PeImage.
NewPe32BaseAddress - New Base Address for PE image.
Returns:
EFI_SUCCESS Set new base address into this image successfully.
--*/
{
//
// Initialize context
//
return Status;
}
if (ImageContext.RelocationsStripped) {
Error (NULL, 0, 3000, "Invalid", "The input PeImage %s has no relocation to be fixed up", FileName);
return Status;
}
//
// Get PeHeader pointer
//
//
// Get section header list
//
sizeof (UINT32) +
sizeof (EFI_IMAGE_FILE_HEADER) +
);
//
// Set base address into the first section header that doesn't point to code section.
//
break;
}
}
//
// No available section header is found.
//
return EFI_NOT_FOUND;
}
//
// BaseAddress is set to section header.
//
return EFI_SUCCESS;
}
)
/*++
Routine Description:
Set new base address into PeImage, and fix up PeImage based on new address.
Arguments:
FileName - Name of file
FileBuffer - Pointer to PeImage.
NewPe32BaseAddress - New Base Address for PE image.
Returns:
EFI_INVALID_PARAMETER - BaseAddress is not valid.
EFI_SUCCESS - Update PeImage is correctly.
--*/
{
//
// Initialize context
//
return Status;
}
if (ImageContext.RelocationsStripped) {
Error (NULL, 0, 3000, "Invalid", "The input PeImage %s has no relocation to be fixed up", FileName);
return Status;
}
//
// Get PeHeader pointer
//
//
// Load and Relocate Image Data
//
MemoryImagePointer = (UINT8 *) malloc ((UINTN) ImageContext.ImageSize + ImageContext.SectionAlignment);
if (MemoryImagePointer == NULL) {
return EFI_OUT_OF_RESOURCES;
}
memset ((VOID *) MemoryImagePointer, 0, (UINTN) ImageContext.ImageSize + ImageContext.SectionAlignment);
ImageContext.ImageAddress = ((UINTN) MemoryImagePointer + ImageContext.SectionAlignment - 1) & (~((INT64)ImageContext.SectionAlignment - 1));
return Status;
}
return Status;
}
//
// Copy Relocated data to raw image file.
//
sizeof (UINT32) +
sizeof (EFI_IMAGE_FILE_HEADER) +
);
CopyMem (
);
}
//
// Update Image Base Address
//
if ((ImgHdr->Pe32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) && (ImgHdr->Pe32.FileHeader.Machine != IMAGE_FILE_MACHINE_IA64)) {
} else {
);
return EFI_ABORTED;
}
//
// Set new base address into section header
//
return Status;
}
int
main (
int argc,
char *argv[]
)
/*++
Routine Description:
Main function.
Arguments:
argc - Number of command line parameters.
argv - Array of pointers to command line parameter strings.
Returns:
STATUS_SUCCESS - Utility exits successfully.
STATUS_ERROR - Some error occurred during execution.
--*/
{
char *OutImageName;
char *ModuleType;
//
// Assign to fix compile warning
//
FileLen = 0;
InputFileNum = 0;
mInImageName = NULL;
OutImageName = NULL;
ModuleType = NULL;
Type = 0;
FileBuffer = NULL;
FileLength = 0;
CheckSum = 0;
ReplaceFlag = FALSE;
LogLevel = 0;
OutputFileLength = 0;
InputFileLength = 0;
Optional32 = NULL;
Optional64 = NULL;
NumberOfFormPacakge = 0;
HiiSectionHeaderSize = 0;
NewBaseAddress = 0;
InputFileTime = 0;
OutputFileTime = 0;
if (argc == 1) {
Usage ();
return STATUS_ERROR;
}
argc --;
argv ++;
Version ();
Usage ();
return STATUS_SUCCESS;
}
Version ();
return STATUS_SUCCESS;
}
while (argc > 0) {
goto Finish;
}
argc -= 2;
argv += 2;
continue;
}
goto Finish;
}
if (mOutImageType != FW_TE_IMAGE) {
}
argc -= 2;
argv += 2;
continue;
}
argc --;
argv ++;
continue;
}
argc --;
argv ++;
continue;
}
argc --;
argv ++;
continue;
}
argc --;
argv ++;
continue;
}
argc --;
argv ++;
continue;
}
argc --;
argv ++;
continue;
}
goto Finish;
}
argc -= 2;
argv += 2;
continue;
}
ReplaceFlag = TRUE;
argc --;
argv ++;
continue;
}
argc --;
argv ++;
continue;
}
argc --;
argv ++;
continue;
}
argc --;
argv ++;
continue;
}
argc --;
argv ++;
continue;
}
goto Finish;
}
argc -= 2;
argv += 2;
continue;
}
NegativeAddr = TRUE;
} else {
}
if (Status != EFI_SUCCESS) {
goto Finish;
}
argc -= 2;
argv += 2;
continue;
}
NegativeAddr = TRUE;
} else {
}
if (Status != EFI_SUCCESS) {
goto Finish;
}
argc -= 2;
argv += 2;
continue;
}
goto Finish;
}
argc -= 2;
argv += 2;
continue;
}
VerboseMsg ("Verbose output Mode Set!");
argc --;
argv ++;
continue;
}
KeyMsg ("Quiet output Mode Set!");
argc --;
argv ++;
continue;
}
goto Finish;
}
if (LogLevel > 9) {
Error (NULL, 0, 1003, "Invalid option value", "Debug Level range is 0-9, currnt input level is %d", (int) LogLevel);
goto Finish;
}
argc -= 2;
argv += 2;
continue;
}
goto Finish;
}
argc -= 2;
argv += 2;
continue;
}
argc --;
argv ++;
continue;
}
argc --;
argv ++;
continue;
}
if (argv[0][0] == '-') {
goto Finish;
}
//
// Get Input file name
//
if (InputFileName == NULL) {
goto Finish;
}
} else if (InputFileNum % MAXIMUM_INPUT_FILE_NUM == 0) {
//
// InputFileName buffer too small, need to realloc
//
);
if (InputFileName == NULL) {
goto Finish;
}
}
argc --;
argv ++;
}
if (mOutImageType == FW_DUMMY_IMAGE) {
Error (NULL, 0, 1001, "Missing option", "No create file action specified; pls specify -e, -c or -t option to create efi image, or acpi table or TeImage!");
if (ReplaceFlag) {
Error (NULL, 0, 1001, "Missing option", "-r option is not supported as the independent option. It can be used together with other create file option specified at the above.");
}
goto Finish;
}
//
// check input files
//
if (InputFileNum == 0) {
goto Finish;
}
//
// Combine MciBinary files to one file
//
Error (NULL, 0, 1002, "Conflicting option", "-r replace option cannot be used with -j merge files option.");
goto Finish;
}
//
// Combine HiiBinary packages to a single package list
//
Error (NULL, 0, 1002, "Conflicting option", "-r replace option cannot be used with --hiipackage merge files option.");
goto Finish;
}
Error (NULL, 0, 1002, "Conflicting option", "-r replace option cannot be used with --hiibinpackage merge files option.");
goto Finish;
}
//
// Input image file
//
//
// Action will be taken for the input file.
//
switch (mOutImageType) {
case FW_EFI_IMAGE:
break;
case FW_TE_IMAGE:
VerboseMsg ("Create Te Image based on the input PE image.");
break;
case FW_ACPI_IMAGE:
VerboseMsg ("Get acpi table data from the input PE image.");
break;
case FW_RELOC_STRIPEED_IMAGE:
VerboseMsg ("Remove relocation section from Pe or Te image.");
break;
case FW_BIN_IMAGE:
VerboseMsg ("Convert the input EXE to the output BIN file.");
break;
case FW_ZERO_DEBUG_IMAGE:
VerboseMsg ("Zero the Debug Data Fields and Time Stamp in input PE image.");
break;
case FW_SET_STAMP_IMAGE:
break;
case DUMP_TE_HEADER:
VerboseMsg ("Dump the TE header information of the input TE image.");
break;
case FW_MCI_IMAGE:
VerboseMsg ("Conver input MicroCode.txt file to MicroCode.bin file.");
break;
case FW_MERGE_IMAGE:
VerboseMsg ("Combine the input multi microcode bin files to one bin file.");
break;
VerboseMsg ("Combine the input multi hii bin packages to one text pacakge list RC file.");
break;
VerboseMsg ("Combine the input multi hii bin packages to one binary pacakge list file.");
break;
case FW_REBASE_IMAGE:
VerboseMsg ("Rebase the input image to new base address.");
break;
case FW_SET_ADDRESS_IMAGE:
VerboseMsg ("Set the preferred address into the section header of the input image");
break;
default:
break;
}
if (ReplaceFlag) {
VerboseMsg ("Overwrite the input file with the output content.");
}
//
// Open output file and Write image into the output file.
//
if (OutImageName != NULL) {
//
// Get Output file time stamp
//
//
// Get Output file data
//
if (OutputFileBuffer == NULL) {
goto Finish;
}
}
goto Finish;
}
//
// Open input file and read file data into file buffer.
//
goto Finish;
}
//
// Get Iutput file time stamp
//
//
// Get Input file data
//
if (InputFileBuffer == NULL) {
goto Finish;
}
DebugMsg (NULL, 0, 9, "input file info", "the input file size is %u bytes", (unsigned) InputFileLength);
//
// Combine multi binary HII package files.
//
if (mOutImageType == FW_HII_PACKAGE_LIST_RCIMAGE || mOutImageType == FW_HII_PACKAGE_LIST_BINIMAGE) {
//
// Open output file handle.
//
if (!fpOut) {
goto Finish;
}
//
// Get hii package list lenght
//
goto Finish;
}
Error (NULL, 0, 3000, "Invalid", "The wrong package size is in HII package file %s", InputFileName [Index]);
goto Finish;
}
}
}
}
//
// Check whether hii packages are valid
//
if (NumberOfFormPacakge > 1) {
goto Finish;
}
goto Finish;
}
//
// read hii packages
//
if (HiiPackageListBuffer == NULL) {
goto Finish;
}
goto Finish;
}
}
//
// write the hii package into the binary package list file with the resource section header
//
if (mOutImageType == FW_HII_PACKAGE_LIST_BINIMAGE) {
//
// Create the resource section header
//
HiiSectionHeader = CreateHiiResouceSectionHeader (&HiiSectionHeaderSize, HiiPackageListHeader.PackageLength);
//
// Wrtie section header and HiiData into File.
//
//
// Free allocated resources.
//
//
// Done successfully
//
goto Finish;
}
//
// write the hii package into the text package list rc file.
//
if (mOutImageType == FW_HII_PACKAGE_LIST_RCIMAGE) {
}
if (Index % 16 == 0) {
}
HiiPackageDataPointer += 2;
}
if (Index % 16 == 0) {
}
}
}
//
// Done successfully
//
goto Finish;
}
}
//
// Combine MciBinary files to one file
//
if (mOutImageType == FW_MERGE_IMAGE) {
//
// Open output file handle.
//
if (!fpOut) {
goto Finish;
}
if (!fpIn) {
goto Finish;
}
if (FileBuffer == NULL) {
goto Finish;
}
//
// write input file to out file
//
//
// write pad value to out file.
//
while (FileLength ++ % MciAlignment != 0) {
}
//
// free allocated memory space
//
free (FileBuffer);
FileBuffer = NULL;
}
//
// Done successfully
//
goto Finish;
}
//
// Convert MicroCode.txt file to MicroCode.bin file
//
if (mOutImageType == FW_MCI_IMAGE) {
goto Finish;
}
//
// The first pass is to determine
// how much data is in the file so we can allocate a working buffer.
//
FileLength = 0;
do {
if (Status == STATUS_SUCCESS) {
FileLength += sizeof (Data);
}
if (Status == STATUS_IGNORE) {
}
} while (Status == STATUS_SUCCESS);
//
// Error if no data.
//
if (FileLength == 0) {
goto Finish;
}
if (FileLength < sizeof (MICROCODE_IMAGE_HEADER)) {
Error (NULL, 0, 3000, "Invalid", "amount of parseable data in %s is insufficient to contain a microcode header", mInImageName);
goto Finish;
}
//
// Allocate a buffer for the data
//
if (FileBuffer == NULL) {
goto Finish;
}
//
// Re-read the file, storing the data into our buffer
//
do {
if (Status == STATUS_IGNORE) {
}
} while (Status == STATUS_SUCCESS);
//
// close input file after read data
//
//
// Can't do much checking on the header because, per the spec, the
// DataSize field may be 0, which means DataSize = 2000 and TotalSize = 2K,
// and the TotalSize field is invalid (actually missing). Thus we can't
// even verify the Reserved fields are 0.
//
Index = 2048;
} else {
}
if (Index != FileLength) {
Error (NULL, 0, 3000, "Invalid", "file length of %s (0x%x) does not equal expected TotalSize: 0x%04X.", mInImageName, (unsigned) FileLength, (unsigned) Index);
goto Finish;
}
//
// Checksum the contents
//
CheckSum = 0;
Index = 0;
while (Index < FileLength) {
CheckSum += *DataPointer;
DataPointer ++;
Index += sizeof (*DataPointer);
}
if (CheckSum != 0) {
Error (NULL, 0, 3000, "Invalid", "checksum (0x%x) failed on file %s.", (unsigned) CheckSum, mInImageName);
goto Finish;
}
//
// Open the output file and write the buffer contents
//
goto WriteFile;
}
//
// Open input file and read file data into file buffer.
//
if (FileBuffer == NULL) {
goto Finish;
}
//
// Dump TeImage Header into output file.
//
if (mOutImageType == DUMP_TE_HEADER) {
goto Finish;
}
//
// Open the output file handle.
//
if (ReplaceFlag) {
goto Finish;
}
} else {
if (OutImageName != NULL) {
} else {
}
goto Finish;
}
}
fprintf (fpInOut, "%17X [%8X] RVA [size] of Base Relocation Directory\n", (unsigned) TEImageHeader.DataDirectory[0].VirtualAddress, (unsigned) TEImageHeader.DataDirectory[0].Size);
fprintf (fpInOut, "%17X [%8X] RVA [size] of Debug Directory\n", (unsigned) TEImageHeader.DataDirectory[1].VirtualAddress, (unsigned) TEImageHeader.DataDirectory[1].Size);
}
fprintf (fpOut, "%17X [%8X] RVA [size] of Base Relocation Directory\n", (unsigned) TEImageHeader.DataDirectory[0].VirtualAddress, (unsigned) TEImageHeader.DataDirectory[0].Size);
fprintf (fpOut, "%17X [%8X] RVA [size] of Debug Directory\n", (unsigned) TEImageHeader.DataDirectory[1].VirtualAddress, (unsigned) TEImageHeader.DataDirectory[1].Size);
}
goto Finish;
}
//
// Following code to convert dll to efi image or te image.
// Get new image type
//
if (ModuleType == NULL) {
if (mOutImageType == FW_EFI_IMAGE) {
goto Finish;
} else if (mOutImageType == FW_TE_IMAGE) {
//
// Default TE Image Type is Boot service driver
//
VerboseMsg ("Efi Image subsystem type is efi boot service driver.");
}
} else {
VerboseMsg ("Efi Image subsystem type is efi boot service driver.");
VerboseMsg ("Efi Image subsystem type is efi application.");
VerboseMsg ("Efi Image subsystem type is efi runtime driver.");
VerboseMsg ("Efi Image subsystem type is efi sal runtime driver.");
} else {
goto Finish;
}
}
}
//
// Convert ELF image to PeImage
//
if (IsElfHeader(FileBuffer)) {
goto Finish;
}
}
//
// Make sure File Offsets and Virtual Offsets are the same in the image so it is XIP
// XIP == eXecute In Place
//
//
// Remove reloc section from PE or TE image
//
if (mOutImageType == FW_RELOC_STRIPEED_IMAGE) {
//
// Check TeImage
//
//
// Check the reloc section is in the end of image.
//
//
// Remove .reloc section and update TeImage Header
//
SectionHeader->SizeOfRawData = 0;
break;
}
}
}
} else {
//
// Check PE Image
//
Error (NULL, 0, 3000, "Invalid", "TE and DOS header signatures were not found in %s image.", mInImageName);
goto Finish;
}
} else {
goto Finish;
}
}
SectionHeader = (EFI_IMAGE_SECTION_HEADER *) ((UINT8 *) &(PeHdr->Pe32.OptionalHeader) + PeHdr->Pe32.FileHeader.SizeOfOptionalHeader);
//
// Check the reloc section is in the end of image.
//
//
// Remove .reloc section and update PeImage Header
//
}
}
}
}
SectionHeader->SizeOfRawData = 0;
break;
}
}
}
}
//
// Write file
//
goto WriteFile;
}
//
// Read the dos & pe hdrs of the image
//
goto Finish;
}
} else {
goto Finish;
}
}
// Some tools kick out IMAGE_FILE_MACHINE_ARM (0x1c0) vs IMAGE_FILE_MACHINE_ARMT (0x1c2)
// so patch back to the offical UEFI value.
}
//
// Set new base address into image
//
if ((PeHdr->Pe32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) && (PeHdr->Pe32.FileHeader.Machine != IMAGE_FILE_MACHINE_IA64)) {
if (NewBaseAddress >= 0x100000000ULL) {
goto Finish;
}
}
if (NegativeAddr) {
//
// Set Base Address to a negative value.
//
}
if (mOutImageType == FW_REBASE_IMAGE) {
} else {
}
if (NegativeAddr) {
Error (NULL, 0, 3000, "Invalid", "Rebase/Set Image %s to Base address -0x%llx can't success", mInImageName, 0 - NewBaseAddress);
} else {
Error (NULL, 0, 3000, "Invalid", "Rebase/Set Image %s to Base address 0x%llx can't success", mInImageName, NewBaseAddress);
}
goto Finish;
}
//
// Write file
//
goto WriteFile;
}
//
// Extract bin data from Pe image.
//
if (mOutImageType == FW_BIN_IMAGE) {
goto Finish;
}
//
// Output bin data from exe file
//
goto WriteFile;
}
//
// Zero Debug Information of Pe Image
//
if (mOutImageType == FW_ZERO_DEBUG_IMAGE) {
goto Finish;
}
//
// Write the updated Image
//
goto WriteFile;
}
//
// Set Time Stamp of Pe Image
//
if (mOutImageType == FW_SET_STAMP_IMAGE) {
goto Finish;
}
//
// Write the updated Image
//
goto WriteFile;
}
//
// Extract acpi data from pe image.
//
if (mOutImageType == FW_ACPI_IMAGE) {
SectionHeader = (EFI_IMAGE_SECTION_HEADER *) ((UINT8 *) &(PeHdr->Pe32.OptionalHeader) + PeHdr->Pe32.FileHeader.SizeOfOptionalHeader);
if (strcmp ((char *)SectionHeader->Name, ".data") == 0 || strcmp ((char *)SectionHeader->Name, ".sdata") == 0) {
//
// Check Acpi Table
//
} else {
}
goto Finish;
}
//
// Output Apci data to file
//
goto WriteFile;
}
}
goto Finish;
}
//
// Zero all unused fields of the DOS header
//
}
}
//
// Initialize TeImage Header
//
TEImageHeader.StrippedSize = (UINT16) ((UINTN) ((UINT8 *) &(PeHdr->Pe32.OptionalHeader) + PeHdr->Pe32.FileHeader.SizeOfOptionalHeader) - (UINTN) FileBuffer);
//
// Patch the PE header
//
Optional32->MajorImageVersion = 0;
Optional32->MinorImageVersion = 0;
Optional32->Win32VersionValue = 0;
Optional32->CheckSum = 0;
Optional32->SizeOfStackReserve = 0;
Optional32->SizeOfStackCommit = 0;
Optional32->SizeOfHeapReserve = 0;
Optional32->SizeOfHeapCommit = 0;
TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress = Optional32->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress;
TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size = Optional32->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size;
}
TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress = Optional32->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress;
TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].Size = Optional32->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].Size;
}
//
// Zero .pdata section data.
//
if (!KeepExceptionTableFlag && Optional32->NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_EXCEPTION &&
SectionHeader = (EFI_IMAGE_SECTION_HEADER *) ((UINT8 *) &(PeHdr->Pe32.OptionalHeader) + PeHdr->Pe32.FileHeader.SizeOfOptionalHeader);
if (SectionHeader->VirtualAddress == Optional32->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXCEPTION].VirtualAddress) {
//
// Zero .pdata Section data
//
//
// Zero .pdata Section header name
//
//
// Zero Execption Table
//
break;
}
}
}
//
// Strip zero padding at the end of the .reloc section
//
if (!KeepZeroPendingFlag && Optional32->NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC) {
SectionHeader = (EFI_IMAGE_SECTION_HEADER *) ((UINT8 *) &(PeHdr->Pe32.OptionalHeader) + PeHdr->Pe32.FileHeader.SizeOfOptionalHeader);
//
// Look for the Section Header that starts as the same virtual address as the Base Relocation Data Directory
//
if (SectionHeader->VirtualAddress == Optional32->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress) {
SectionHeader->Misc.VirtualSize = Optional32->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size;
AllignedRelocSize = (Optional32->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size + Optional32->FileAlignment - 1) & (~(Optional32->FileAlignment - 1));
//
// Check to see if there is zero padding at the end of the base relocations
//
//
// Check to see if the base relocations are at the end of the file
//
//
// All the required conditions are met to strip the zero padding of the end of the base relocations section
//
DebugMsg (NULL, 0, 9, "Remove the zero padding bytes at the end of the base relocations", "The size of padding bytes is %u", (unsigned) (SectionHeader->SizeOfRawData - AllignedRelocSize));
}
}
}
}
}
}
Optional64->MajorImageVersion = 0;
Optional64->MinorImageVersion = 0;
Optional64->Win32VersionValue = 0;
Optional64->CheckSum = 0;
Optional64->SizeOfStackReserve = 0;
Optional64->SizeOfStackCommit = 0;
Optional64->SizeOfHeapReserve = 0;
Optional64->SizeOfHeapCommit = 0;
TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress = Optional64->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress;
TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size = Optional64->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size;
}
TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress = Optional64->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress;
TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].Size = Optional64->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].Size;
}
//
// Zero the .pdata section for X64 machine and don't check the Debug Directory is empty
// For Itaninum and X64 Image, remove .pdata section.
//
if ((!KeepExceptionTableFlag && PeHdr->Pe32.FileHeader.Machine == IMAGE_FILE_MACHINE_X64) || PeHdr->Pe32.FileHeader.Machine == IMAGE_FILE_MACHINE_IA64) {
SectionHeader = (EFI_IMAGE_SECTION_HEADER *) ((UINT8 *) &(PeHdr->Pe32.OptionalHeader) + PeHdr->Pe32.FileHeader.SizeOfOptionalHeader);
if (SectionHeader->VirtualAddress == Optional64->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXCEPTION].VirtualAddress) {
//
// Zero .pdata Section header name
//
for (Index1 = 0; Index1 < Optional64->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXCEPTION].Size / sizeof (RUNTIME_FUNCTION); Index1++, RuntimeFunction++) {
SectionHeader = (EFI_IMAGE_SECTION_HEADER *) ((UINT8 *) &(PeHdr->Pe32.OptionalHeader) + PeHdr->Pe32.FileHeader.SizeOfOptionalHeader);
if (RuntimeFunction->UnwindInfoAddress >= SectionHeader->VirtualAddress && RuntimeFunction->UnwindInfoAddress < (SectionHeader->VirtualAddress + SectionHeader->SizeOfRawData)) {
UnwindInfo = (UNWIND_INFO *)(FileBuffer + SectionHeader->PointerToRawData + (RuntimeFunction->UnwindInfoAddress - SectionHeader->VirtualAddress));
}
break;
}
}
}
//
// Zero Execption Table
//
break;
}
}
}
}
//
// Strip zero padding at the end of the .reloc section
//
SectionHeader = (EFI_IMAGE_SECTION_HEADER *) ((UINT8 *) &(PeHdr->Pe32.OptionalHeader) + PeHdr->Pe32.FileHeader.SizeOfOptionalHeader);
//
// Look for the Section Header that starts as the same virtual address as the Base Relocation Data Directory
//
if (SectionHeader->VirtualAddress == Optional64->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress) {
SectionHeader->Misc.VirtualSize = Optional64->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size;
AllignedRelocSize = (Optional64->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size + Optional64->FileAlignment - 1) & (~(Optional64->FileAlignment - 1));
//
// Check to see if there is zero padding at the end of the base relocations
//
//
// Check to see if the base relocations are at the end of the file
//
//
// All the required conditions are met to strip the zero padding of the end of the base relocations section
//
DebugMsg (NULL, 0, 9, "Remove the zero padding bytes at the end of the base relocations", "The size of padding bytes is %u", (unsigned) (SectionHeader->SizeOfRawData - AllignedRelocSize));
}
}
}
}
}
}
} else {
Error (NULL, 0, 3000, "Invalid", "Magic 0x%x of PeImage %s is unknown.", PeHdr->Pe32.OptionalHeader.Magic, mInImageName);
goto Finish;
}
//
// PeImage can be loaded into memory, but it has no relocation section.
// Fix TeImage Header to set VA of relocation data directory to not zero, the size is still zero.
//
if (Optional32 != NULL) {
TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress = Optional32->SizeOfImage - sizeof (EFI_IMAGE_BASE_RELOCATION);
} else if (Optional64 != NULL) {
TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress = Optional64->SizeOfImage - sizeof (EFI_IMAGE_BASE_RELOCATION);
}
}
//
// Fill HII section data
//
SectionHeader = (EFI_IMAGE_SECTION_HEADER *) ((UINT8 *) &(PeHdr->Pe32.OptionalHeader) + PeHdr->Pe32.FileHeader.SizeOfOptionalHeader);
//
// Update resource section header offset
//
SetHiiResourceHeader ((UINT8*) FileBuffer + SectionHeader[Index].PointerToRawData, SectionHeader[Index].VirtualAddress);
//
// Update resource section name
//
//
// Update resource data directory.
//
Optional32->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress = SectionHeader[Index].VirtualAddress;
Optional32->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE].Size = SectionHeader[Index].Misc.VirtualSize;
Optional64->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress = SectionHeader[Index].VirtualAddress;
Optional64->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE].Size = SectionHeader[Index].Misc.VirtualSize;
}
break;
}
}
//
// Zero ExceptionTable Xdata
//
if (!KeepExceptionTableFlag) {
SectionHeader = (EFI_IMAGE_SECTION_HEADER *) ((UINT8 *) &(PeHdr->Pe32.OptionalHeader) + PeHdr->Pe32.FileHeader.SizeOfOptionalHeader);
//
// zero .xdata section
//
DebugMsg (NULL, 0, 9, NULL, "Zero the .xdata section for PE image at Offset 0x%x and Length 0x%x", (unsigned) SectionHeader[Index].PointerToRawData, (unsigned) SectionHeader[Index].SizeOfRawData);
break;
}
}
}
//
//
if (mOutImageType == FW_TE_IMAGE) {
//
// Pack the subsystem and NumberOfSections into 1 byte. Make sure they fit both.
//
Error (NULL, 0, 3000, "Invalid", "Image's subsystem or NumberOfSections of PeImage %s cannot be packed into 1 byte.", mInImageName);
goto Finish;
}
//
// TeImage has the same section alignment and file alignment.
//
Error (NULL, 0, 3000, "Invalid", "Section-Alignment and File-Alignment of PeImage %s do not match, they must be equal for a TeImage.", mInImageName);
goto Finish;
}
DebugMsg (NULL, 0, 9, "TeImage Header Info", "Machine type is %X, Number of sections is %X, Stripped size is %X, EntryPoint is %X, BaseOfCode is %X, ImageBase is %llX",
TEImageHeader.Machine, TEImageHeader.NumberOfSections, TEImageHeader.StrippedSize, (unsigned) TEImageHeader.AddressOfEntryPoint, (unsigned) TEImageHeader.BaseOfCode, (unsigned long long) TEImageHeader.ImageBase);
//
// Update Image to TeImage
//
memmove (FileBuffer + sizeof (EFI_TE_IMAGE_HEADER), FileBuffer + TEImageHeader.StrippedSize, FileLength);
} else {
//
// Following codes are to fix the objcopy's issue:
// objcopy in binutil 2.50.18 will set PE image's charactices to "RELOC_STRIPPED" if image has no ".reloc" section
// It cause issue for EFI image which has no ".reloc" sections.
// Following codes will be removed when objcopy in binutil fix this problem for PE image.
//
if (Optional32->ImageBase == 0) {
}
if (Optional64->ImageBase == 0) {
}
}
}
}
//
// Update Image to EfiImage or TE image
//
if (ReplaceFlag) {
//
// Update File when File is changed.
//
goto Finish;
}
}
} else {
if ((OutputFileTime < InputFileTime) || (FileLength != OutputFileLength) || (memcmp (FileBuffer, OutputFileBuffer, FileLength) != 0)) {
//
// Update File when File is changed or File is old.
//
goto Finish;
}
}
}
if (GetUtilityStatus () != STATUS_SUCCESS) {
//
// when file updates failed, original file is still recovered.
//
}
//
// Write converted data into fpInOut file and close input file.
//
}
if (FileBuffer != NULL) {
free (FileBuffer);
}
if (InputFileName != NULL) {
}
//
// Write converted data into fpOut file and close output file.
//
if (GetUtilityStatus () != STATUS_SUCCESS) {
if (OutputFileBuffer == NULL) {
} else {
}
}
}
if (InputFileBuffer != NULL) {
}
if (OutputFileBuffer != NULL) {
}
//
// Write module size and time stamp to report file.
//
if (OutImageName != NULL) {
}
if (ReportFileName != NULL) {
if (ReportFile != NULL) {
}
}
}
return GetUtilityStatus ();
}
)
/*++
Routine Description:
Zero debug information in PeImage.
Arguments:
FileBuffer - Pointer to PeImage.
Returns:
EFI_ABORTED - PeImage is invalid.
EFI_SUCCESS - Zero debug data successfully.
--*/
{
//
// Init variable.
//
} else {
}
//
// Get Debug, Export and Resource EntryTable RVA address.
// Resource Directory entry need to review.
//
Optional32Hdr = (EFI_IMAGE_OPTIONAL_HEADER32 *) ((UINT8*) FileHdr + sizeof (EFI_IMAGE_FILE_HEADER));
SectionHeader = (EFI_IMAGE_SECTION_HEADER *) ((UINT8 *) Optional32Hdr + FileHdr->SizeOfOptionalHeader);
ExportDirectoryEntryRva = Optional32Hdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
}
ResourceDirectoryEntryRva = Optional32Hdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress;
}
DebugDirectoryEntryRva = Optional32Hdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress;
if (ZeroDebugFlag) {
}
}
} else {
Optional64Hdr = (EFI_IMAGE_OPTIONAL_HEADER64 *) ((UINT8*) FileHdr + sizeof (EFI_IMAGE_FILE_HEADER));
SectionHeader = (EFI_IMAGE_SECTION_HEADER *) ((UINT8 *) Optional64Hdr + FileHdr->SizeOfOptionalHeader);
ExportDirectoryEntryRva = Optional64Hdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
}
ResourceDirectoryEntryRva = Optional64Hdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress;
}
DebugDirectoryEntryRva = Optional64Hdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress;
if (ZeroDebugFlag) {
}
}
}
//
// Get DirectoryEntryTable file offset.
//
}
}
}
}
//
//Zero Debug Data and TimeStamp
//
FileHdr->TimeDateStamp = 0;
mImageTimeStamp = 0;
if (ExportDirectoryEntryFileOffset != 0) {
*NewTimeStamp = 0;
}
if (ResourceDirectoryEntryFileOffset != 0) {
*NewTimeStamp = 0;
}
if (DebugDirectoryEntryFileOffset != 0) {
DebugEntry->TimeDateStamp = 0;
mImageTimeStamp = 0;
if (ZeroDebugFlag) {
}
}
return EFI_SUCCESS;
}
SetStamp (
)
/*++
Routine Description:
Set new time stamp into PeImage FileHdr and Directory table:
Debug, Export and Resource.
Arguments:
FileBuffer - Pointer to PeImage.
TimeStamp - Time stamp string.
Returns:
EFI_INVALID_PARAMETER - TimeStamp format is not recognized.
EFI_SUCCESS - Set new time stamp in this image successfully.
--*/
{
//
// Init variable.
//
//
// Get time and date that will be set.
//
return EFI_INVALID_PARAMETER;
}
//
// compare the value with "NOW", if yes, current system time is set.
//
//
// get system current time and date
//
} else {
//
// Check Time Format strictly yyyy-mm-dd 00:00:00
//
continue;
}
continue;
}
continue;
break;
}
}
Error (NULL, 0, 1003, "Invalid option value", "Incorrect Time \"%s\"\n Correct Format \"yyyy-mm-dd 00:00:00\"", TimeStamp);
return EFI_INVALID_PARAMETER;
}
//
// get the date and time from TimeStamp
//
) != 6) {
Error (NULL, 0, 1003, "Invalid option value", "Incorrect Tiem \"%s\"\n Correct Format \"yyyy-mm-dd 00:00:00\"", TimeStamp);
return EFI_INVALID_PARAMETER;
}
//
// in struct, Month (0 - 11; Jan = 0). So decrease 1 from it
//
return EFI_INVALID_PARAMETER;
}
//
// in struct, Year (current year minus 1900)
// and only the dates can be handled from Jan 1, 1970 to Jan 18, 2038
//
//
// convert 0 -> 100 (2000), 1 -> 101 (2001), ..., 38 -> 138 (2038)
//
//
// convert 1970 -> 70, 2000 -> 100, ...
//
} else {
return EFI_INVALID_PARAMETER;
}
//
// convert the date and time to time_t format
//
return EFI_INVALID_PARAMETER;
}
}
ptime->tm_year + 1900, ptime->tm_mon + 1, ptime->tm_mday, ptime->tm_hour, ptime->tm_min, ptime->tm_sec);
//
// Set new time and data into PeImage.
//
} else {
}
//
// Get Debug, Export and Resource EntryTable RVA address.
// Resource Directory entry need to review.
//
Optional32Hdr = (EFI_IMAGE_OPTIONAL_HEADER32 *) ((UINT8*) FileHdr + sizeof (EFI_IMAGE_FILE_HEADER));
SectionHeader = (EFI_IMAGE_SECTION_HEADER *) ((UINT8 *) Optional32Hdr + FileHdr->SizeOfOptionalHeader);
ExportDirectoryEntryRva = Optional32Hdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
}
ResourceDirectoryEntryRva = Optional32Hdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress;
}
DebugDirectoryEntryRva = Optional32Hdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress;
}
} else {
Optional64Hdr = (EFI_IMAGE_OPTIONAL_HEADER64 *) ((UINT8*) FileHdr + sizeof (EFI_IMAGE_FILE_HEADER));
SectionHeader = (EFI_IMAGE_SECTION_HEADER *) ((UINT8 *) Optional64Hdr + FileHdr->SizeOfOptionalHeader);
ExportDirectoryEntryRva = Optional64Hdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
}
ResourceDirectoryEntryRva = Optional64Hdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress;
}
DebugDirectoryEntryRva = Optional64Hdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress;
}
}
//
// Get DirectoryEntryTable file offset.
//
}
}
}
}
//
// Set new stamp
//
if (ExportDirectoryEntryRva != 0) {
}
if (ResourceDirectoryEntryRva != 0) {
}
if (DebugDirectoryEntryRva != 0) {
}
return EFI_SUCCESS;
}
)
/*++
Routine Description:
Read a 32-bit microcode data value from a text file and convert to raw binary form.
Arguments:
InFptr - file pointer to input text file
Data - pointer to where to return the data parsed
Returns:
STATUS_SUCCESS - no errors or warnings, Data contains valid information
STATUS_ERROR - errors were encountered
--*/
{
unsigned ScannedData = 0;
while (1) {
return STATUS_ERROR;
}
//
// If it was a binary file, then it may have overwritten our null terminator
//
return STATUS_ERROR;
}
//
// strip space
//
}
// Skip Blank Lines and Comment Lines
break;
}
}
// Look for
// dd 000000001h ; comment
// dd XXXXXXXX
// DD XXXXXXXXX
// DD XXXXXXXXX
//
//
// Skip blanks and look for a hex digit
//
cptr += 3;
}
return STATUS_ERROR;
}
}
return STATUS_SUCCESS;
}
return STATUS_ERROR;
}