summaryrefslogtreecommitdiff
path: root/BaseTools/Source/C/GenFw/GenFw.c
diff options
context:
space:
mode:
Diffstat (limited to 'BaseTools/Source/C/GenFw/GenFw.c')
-rw-r--r--BaseTools/Source/C/GenFw/GenFw.c834
1 files changed, 616 insertions, 218 deletions
diff --git a/BaseTools/Source/C/GenFw/GenFw.c b/BaseTools/Source/C/GenFw/GenFw.c
index aabd143b6a..d42c88e23d 100644
--- a/BaseTools/Source/C/GenFw/GenFw.c
+++ b/BaseTools/Source/C/GenFw/GenFw.c
@@ -1,6 +1,6 @@
/** @file
-Copyright (c) 2004 - 2009, Intel Corporation
+Copyright (c) 2004 - 2010, Intel Corporation
All rights reserved. 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
@@ -78,6 +78,8 @@ Abstract:
#define FW_RELOC_STRIPEED_IMAGE 9
#define FW_HII_PACKAGE_LIST_RCIMAGE 10
#define FW_HII_PACKAGE_LIST_BINIMAGE 11
+#define FW_REBASE_IMAGE 12
+#define FW_SET_ADDRESS_IMAGE 13
#define DUMP_TE_HEADER 0x11
@@ -116,6 +118,12 @@ static const char *gHiiPackageRCFileHeader[] = {
STATIC CHAR8 *mInImageName;
+//
+// Module image information
+//
+STATIC UINT32 mImageTimeStamp = 0;
+STATIC UINT32 mImageSize = 0;
+
STATIC
EFI_STATUS
ZeroDebugData (
@@ -190,7 +198,7 @@ Returns:
//
// Copyright declaration
//
- fprintf (stdout, "Copyright (c) 2007, Intel Corporation. All rights reserved.\n\n");
+ fprintf (stdout, "Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.\n\n");
//
// Details Option
@@ -244,7 +252,9 @@ Returns:
fprintf (stdout, " -s timedate, --stamp timedate\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-1-1 8:0:0 ~ 2038-1-19 3:14:07\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\
@@ -288,6 +298,18 @@ Returns:
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");
+ fprintf (stdout, " --rebase NewAddress Rebase image to new base address. New address \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");
+ fprintf (stdout, " --address NewAddress Set new address into the first none code \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");
fprintf (stdout, " -v, --verbose Turn on verbose output with informational messages.\n");
fprintf (stdout, " -q, --quiet Disable all messages except key message and fatal error\n");
fprintf (stdout, " -d, --debug level Enable debug messages, at input debug level.\n");
@@ -860,6 +882,7 @@ ScanSections(
NtHdr->Pe32.FileHeader.NumberOfSections = CoffNbrSections;
NtHdr->Pe32.FileHeader.TimeDateStamp = (UINT32) time(NULL);
+ mImageTimeStamp = NtHdr->Pe32.FileHeader.TimeDateStamp;
NtHdr->Pe32.FileHeader.PointerToSymbolTable = 0;
NtHdr->Pe32.FileHeader.NumberOfSymbols = 0;
NtHdr->Pe32.FileHeader.SizeOfOptionalHeader = sizeof(NtHdr->Pe32.OptionalHeader);
@@ -1639,6 +1662,257 @@ Returns:
return HiiSectionHeader;
}
+EFI_STATUS
+RebaseImageRead (
+ IN VOID *FileHandle,
+ IN UINTN FileOffset,
+ IN OUT UINT32 *ReadSize,
+ OUT VOID *Buffer
+ )
+/*++
+
+Routine Description:
+
+ Support routine for the PE/COFF Loader that reads a buffer from a PE/COFF file
+
+Arguments:
+
+ FileHandle - The handle to the PE/COFF file
+
+ 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
+
+--*/
+{
+ CHAR8 *Destination8;
+ CHAR8 *Source8;
+ UINT32 Length;
+
+ Destination8 = Buffer;
+ Source8 = (CHAR8 *) ((UINTN) FileHandle + FileOffset);
+ Length = *ReadSize;
+ while (Length--) {
+ *(Destination8++) = *(Source8++);
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+SetAddressToSectionHeader (
+ IN CHAR8 *FileName,
+ IN OUT UINT8 *FileBuffer,
+ IN UINT64 NewPe32BaseAddress
+ )
+/*++
+
+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.
+
+--*/
+{
+ EFI_STATUS Status;
+ PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;
+ UINTN Index;
+ EFI_IMAGE_OPTIONAL_HEADER_UNION *ImgHdr;
+ EFI_IMAGE_SECTION_HEADER *SectionHeader;
+
+ //
+ // Initialize context
+ //
+ memset (&ImageContext, 0, sizeof (ImageContext));
+ ImageContext.Handle = (VOID *) FileBuffer;
+ ImageContext.ImageRead = (PE_COFF_LOADER_READ_FILE) RebaseImageRead;
+ Status = PeCoffLoaderGetImageInfo (&ImageContext);
+ if (EFI_ERROR (Status)) {
+ Error (NULL, 0, 3000, "Invalid", "The input PeImage %s is not valid", FileName);
+ 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
+ //
+ ImgHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)(FileBuffer + ImageContext.PeCoffHeaderOffset);
+
+ //
+ // Get section header list
+ //
+ SectionHeader = (EFI_IMAGE_SECTION_HEADER *) (
+ (UINTN) ImgHdr +
+ sizeof (UINT32) +
+ sizeof (EFI_IMAGE_FILE_HEADER) +
+ ImgHdr->Pe32.FileHeader.SizeOfOptionalHeader
+ );
+
+ //
+ // Set base address into the first section header that doesn't point to code section.
+ //
+ for (Index = 0; Index < ImgHdr->Pe32.FileHeader.NumberOfSections; Index ++, SectionHeader ++) {
+ if ((SectionHeader->Characteristics & EFI_IMAGE_SCN_CNT_CODE) == 0) {
+ *(UINT64 *) &SectionHeader->PointerToRelocations = NewPe32BaseAddress;
+ break;
+ }
+ }
+
+ //
+ // No available section header is found.
+ //
+ if (Index == ImgHdr->Pe32.FileHeader.NumberOfSections) {
+ return EFI_NOT_FOUND;
+ }
+
+ //
+ // BaseAddress is set to section header.
+ //
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+RebaseImage (
+ IN CHAR8 *FileName,
+ IN OUT UINT8 *FileBuffer,
+ IN UINT64 NewPe32BaseAddress
+ )
+/*++
+
+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.
+
+--*/
+{
+ EFI_STATUS Status;
+ PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;
+ UINTN Index;
+ EFI_IMAGE_OPTIONAL_HEADER_UNION *ImgHdr;
+ UINT8 *MemoryImagePointer;
+ EFI_IMAGE_SECTION_HEADER *SectionHeader;
+
+ //
+ // Initialize context
+ //
+ memset (&ImageContext, 0, sizeof (ImageContext));
+ ImageContext.Handle = (VOID *) FileBuffer;
+ ImageContext.ImageRead = (PE_COFF_LOADER_READ_FILE) RebaseImageRead;
+ Status = PeCoffLoaderGetImageInfo (&ImageContext);
+ if (EFI_ERROR (Status)) {
+ Error (NULL, 0, 3000, "Invalid", "The input PeImage %s is not valid", FileName);
+ 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
+ //
+ ImgHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)(FileBuffer + ImageContext.PeCoffHeaderOffset);
+
+ //
+ // Load and Relocate Image Data
+ //
+ MemoryImagePointer = (UINT8 *) malloc ((UINTN) ImageContext.ImageSize + ImageContext.SectionAlignment);
+ if (MemoryImagePointer == NULL) {
+ Error (NULL, 0, 4001, "Resource", "memory cannot be allocated on rebase of %s", FileName);
+ 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));
+
+ Status = PeCoffLoaderLoadImage (&ImageContext);
+ if (EFI_ERROR (Status)) {
+ Error (NULL, 0, 3000, "Invalid", "LocateImage() call failed on rebase of %s", FileName);
+ free ((VOID *) MemoryImagePointer);
+ return Status;
+ }
+
+ ImageContext.DestinationAddress = NewPe32BaseAddress;
+ Status = PeCoffLoaderRelocateImage (&ImageContext);
+ if (EFI_ERROR (Status)) {
+ Error (NULL, 0, 3000, "Invalid", "RelocateImage() call failed on rebase of %s", FileName);
+ free ((VOID *) MemoryImagePointer);
+ return Status;
+ }
+
+ //
+ // Copy Relocated data to raw image file.
+ //
+ SectionHeader = (EFI_IMAGE_SECTION_HEADER *) (
+ (UINTN) ImgHdr +
+ sizeof (UINT32) +
+ sizeof (EFI_IMAGE_FILE_HEADER) +
+ ImgHdr->Pe32.FileHeader.SizeOfOptionalHeader
+ );
+
+ for (Index = 0; Index < ImgHdr->Pe32.FileHeader.NumberOfSections; Index ++, SectionHeader ++) {
+ CopyMem (
+ FileBuffer + SectionHeader->PointerToRawData,
+ (VOID*) (UINTN) (ImageContext.ImageAddress + SectionHeader->VirtualAddress),
+ SectionHeader->SizeOfRawData
+ );
+ }
+
+ free ((VOID *) MemoryImagePointer);
+
+ //
+ // Update Image Base Address
+ //
+ if ((ImgHdr->Pe32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) && (ImgHdr->Pe32.FileHeader.Machine != IMAGE_FILE_MACHINE_IA64)) {
+ ImgHdr->Pe32.OptionalHeader.ImageBase = (UINT32) NewPe32BaseAddress;
+ } else if (ImgHdr->Pe32Plus.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) {
+ ImgHdr->Pe32Plus.OptionalHeader.ImageBase = NewPe32BaseAddress;
+ } else {
+ Error (NULL, 0, 3000, "Invalid", "unknown PE magic signature %X in PE32 image %s",
+ ImgHdr->Pe32.OptionalHeader.Magic,
+ FileName
+ );
+ return EFI_ABORTED;
+ }
+
+ //
+ // Set new base address into section header
+ //
+ Status = SetAddressToSectionHeader (FileName, FileBuffer, NewPe32BaseAddress);
+
+ return Status;
+}
+
int
main (
int argc,
@@ -1686,6 +1960,8 @@ Returns:
UINT32 FileLength;
UINT8 *OutputFileBuffer;
UINT32 OutputFileLength;
+ UINT8 *InputFileBuffer;
+ UINT32 InputFileLength;
RUNTIME_FUNCTION *RuntimeFunction;
UNWIND_INFO *UnwindInfo;
STATUS Status;
@@ -1712,12 +1988,18 @@ Returns:
EFI_HII_PACKAGE_HEADER EndPackage;
UINT32 HiiSectionHeaderSize;
UINT8 *HiiSectionHeader;
+ UINT64 NewBaseAddress;
+ BOOLEAN NegativeAddr;
+ FILE *ReportFile;
+ CHAR8 *ReportFileName;
+ UINTN FileLen;
SetUtilityName (UTILITY_NAME);
//
// Assign to fix compile warning
//
+ FileLen = 0;
InputFileNum = 0;
InputFileName = NULL;
mInImageName = NULL;
@@ -1740,6 +2022,8 @@ Returns:
LogLevel = 0;
OutputFileBuffer = NULL;
OutputFileLength = 0;
+ InputFileBuffer = NULL;
+ InputFileLength = 0;
Optional32 = NULL;
Optional64 = NULL;
KeepExceptionTableFlag = FALSE;
@@ -1752,6 +2036,8 @@ Returns:
memset (&HiiPackageListGuid, 0, sizeof (HiiPackageListGuid));
HiiSectionHeaderSize = 0;
HiiSectionHeader = NULL;
+ NewBaseAddress = 0;
+ NegativeAddr = FALSE;
if (argc == 1) {
Error (NULL, 0, 1001, "Missing options", "No input options.");
@@ -1899,6 +2185,44 @@ Returns:
continue;
}
+ if ((stricmp (argv[0], "--rebase") == 0)) {
+ if (argv[1][0] == '-') {
+ NegativeAddr = TRUE;
+ Status = AsciiStringToUint64 (argv[1] + 1, FALSE, &Temp64);
+ } else {
+ NegativeAddr = FALSE;
+ Status = AsciiStringToUint64 (argv[1], FALSE, &Temp64);
+ }
+ if (Status != EFI_SUCCESS) {
+ Error (NULL, 0, 1003, "Invalid option value", "%s = %s", argv[0], argv[1]);
+ goto Finish;
+ }
+ OutImageType = FW_REBASE_IMAGE;
+ NewBaseAddress = (UINT64) Temp64;
+ argc -= 2;
+ argv += 2;
+ continue;
+ }
+
+ if ((stricmp (argv[0], "--address") == 0)) {
+ if (argv[1][0] == '-') {
+ NegativeAddr = TRUE;
+ Status = AsciiStringToUint64 (argv[1] + 1, FALSE, &Temp64);
+ } else {
+ NegativeAddr = FALSE;
+ Status = AsciiStringToUint64 (argv[1], FALSE, &Temp64);
+ }
+ if (Status != EFI_SUCCESS) {
+ Error (NULL, 0, 1003, "Invalid option value", "%s = %s", argv[0], argv[1]);
+ goto Finish;
+ }
+ OutImageType = FW_SET_ADDRESS_IMAGE;
+ NewBaseAddress = (UINT64) Temp64;
+ argc -= 2;
+ argv += 2;
+ continue;
+ }
+
if ((stricmp (argv[0], "-p") == 0) || (stricmp (argv[0], "--pad") == 0)) {
if (AsciiStringToUint64 (argv[1], FALSE, &Temp64) != EFI_SUCCESS) {
Error (NULL, 0, 1003, "Invalid option value", "%s = %s", argv[0], argv[1]);
@@ -1942,7 +2266,7 @@ Returns:
argv += 2;
continue;
}
-
+
if ((stricmp (argv[0], "-g") == 0) || (stricmp (argv[0], "--hiiguid") == 0)) {
Status = StringToGuid (argv[1], &HiiPackageListGuid);
if (EFI_ERROR (Status)) {
@@ -1988,9 +2312,9 @@ Returns:
// InputFileName buffer too small, need to realloc
//
InputFileName = (CHAR8 **) realloc (
- InputFileName,
- (InputFileNum + MAXIMUM_INPUT_FILE_NUM) * sizeof (CHAR8 *)
- );
+ InputFileName,
+ (InputFileNum + MAXIMUM_INPUT_FILE_NUM) * sizeof (CHAR8 *)
+ );
if (InputFileName == NULL) {
Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");
@@ -2090,6 +2414,12 @@ Returns:
case FW_HII_PACKAGE_LIST_BINIMAGE:
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;
}
@@ -2114,33 +2444,52 @@ Returns:
}
fread (OutputFileBuffer, 1, OutputFileLength, fpOut);
fclose (fpOut);
- }
- fpOut = fopen (OutImageName, "wb");
- if (!fpOut) {
- Error (NULL, 0, 0001, "Error opening output file", OutImageName);
- goto Finish;
+ fpOut = NULL;
}
VerboseMsg ("Output file name is %s", OutImageName);
- } else if (!ReplaceFlag) {
- if (OutImageType == DUMP_TE_HEADER) {
- fpOut = stdout;
- } else {
- Error (NULL, 0, 1001, "Missing option", "output file");
- goto Finish;
- }
+ } else if (!ReplaceFlag && OutImageType != DUMP_TE_HEADER) {
+ Error (NULL, 0, 1001, "Missing option", "output file");
+ goto Finish;
}
//
+ // Open input file and read file data into file buffer.
+ //
+ fpIn = fopen (mInImageName, "rb");
+ if (fpIn == NULL) {
+ Error (NULL, 0, 0001, "Error opening file", mInImageName);
+ goto Finish;
+ }
+ InputFileLength = _filelength (fileno (fpIn));
+ InputFileBuffer = malloc (InputFileLength);
+ if (InputFileBuffer == NULL) {
+ Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");
+ fclose (fpIn);
+ goto Finish;
+ }
+ fread (InputFileBuffer, 1, InputFileLength, fpIn);
+ fclose (fpIn);
+ DebugMsg (NULL, 0, 9, "input file info", "the input file size is %u bytes", (unsigned) InputFileLength);
+
+ //
// Combine multi binary HII package files.
//
if (OutImageType == FW_HII_PACKAGE_LIST_RCIMAGE || OutImageType == FW_HII_PACKAGE_LIST_BINIMAGE) {
//
+ // Open output file handle.
+ //
+ fpOut = fopen (OutImageName, "wb");
+ if (!fpOut) {
+ Error (NULL, 0, 0001, "Error opening output file", OutImageName);
+ goto Finish;
+ }
+ //
// Get hii package list lenght
//
HiiPackageListHeader.PackageLength = sizeof (EFI_HII_PACKAGE_LIST_HEADER);
for (Index = 0; Index < InputFileNum; Index ++) {
fpIn = fopen (InputFileName [Index], "rb");
- if (!fpIn) {
+ if (fpIn == NULL) {
Error (NULL, 0, 0001, "Error opening file", InputFileName [Index]);
goto Finish;
}
@@ -2186,7 +2535,7 @@ Returns:
HiiPackageDataPointer = HiiPackageListBuffer + sizeof (HiiPackageListHeader);
for (Index = 0; Index < InputFileNum; Index ++) {
fpIn = fopen (InputFileName [Index], "rb");
- if (!fpIn) {
+ if (fpIn == NULL) {
Error (NULL, 0, 0001, "Error opening file", InputFileName [Index]);
free (HiiPackageListBuffer);
goto Finish;
@@ -2240,7 +2589,7 @@ Returns:
fprintf (fpOut, " 0x%04X,", *(UINT16 *) HiiPackageDataPointer);
HiiPackageDataPointer += 2;
}
-
+
if (Index % 16 == 0) {
fprintf (fpOut, "\n ");
}
@@ -2262,6 +2611,14 @@ Returns:
// Combine MciBinary files to one file
//
if (OutImageType == FW_MERGE_IMAGE) {
+ //
+ // Open output file handle.
+ //
+ fpOut = fopen (OutImageName, "wb");
+ if (!fpOut) {
+ Error (NULL, 0, 0001, "Error opening output file", OutImageName);
+ goto Finish;
+ }
for (Index = 0; Index < InputFileNum; Index ++) {
fpIn = fopen (InputFileName [Index], "rb");
if (!fpIn) {
@@ -2306,7 +2663,7 @@ Returns:
//
if (OutImageType == FW_MCI_IMAGE) {
fpIn = fopen (mInImageName, "r");
- if (!fpIn) {
+ if (fpIn == NULL) {
Error (NULL, 0, 0001, "Error opening file", mInImageName);
goto Finish;
}
@@ -2400,63 +2757,21 @@ Returns:
//
// Open the output file and write the buffer contents
//
- if (fpOut != NULL) {
- if (fwrite (FileBuffer, FileLength, 1, fpOut) != 1) {
- Error (NULL, 0, 0002, "Error writing file", OutImageName);
- goto Finish;
- }
- }
-
- if (ReplaceFlag) {
- fpInOut = fopen (mInImageName, "wb");
- if (fpInOut != NULL) {
- Error (NULL, 0, 0001, "Error opening file", mInImageName);
- goto Finish;
- }
- if (fwrite (FileBuffer, FileLength, 1, fpInOut) != 1) {
- Error (NULL, 0, 0002, "Error writing file", mInImageName);
- goto Finish;
- }
- }
VerboseMsg ("the size of output file is %u bytes", (unsigned) FileLength);
- //
- // Convert Mci.TXT to Mci.bin file successfully
- //
- goto Finish;
+ goto WriteFile;
}
//
// Open input file and read file data into file buffer.
//
- fpIn = fopen (mInImageName, "rb");
- if (!fpIn) {
- Error (NULL, 0, 0001, "Error opening file", mInImageName);
- goto Finish;
- }
-
- FileLength = _filelength (fileno (fpIn));
+ FileLength = InputFileLength;
FileBuffer = malloc (FileLength);
if (FileBuffer == NULL) {
Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");
- fclose (fpIn);
goto Finish;
}
+ memcpy (FileBuffer, InputFileBuffer, InputFileLength);
- fread (FileBuffer, 1, FileLength, fpIn);
- fclose (fpIn);
-
- DebugMsg (NULL, 0, 9, "input file info", "the input file size is %u bytes", (unsigned) FileLength);
-
- //
- // Replace file
- //
- if (ReplaceFlag) {
- fpInOut = fopen (mInImageName, "wb");
- if (!fpInOut) {
- Error (NULL, 0, 0001, "Error opening file", mInImageName);
- goto Finish;
- }
- }
//
// Dump TeImage Header into output file.
//
@@ -2466,6 +2781,26 @@ Returns:
Error (NULL, 0, 3000, "Invalid", "TE header signature of file %s is not correct.", mInImageName);
goto Finish;
}
+ //
+ // Open the output file handle.
+ //
+ if (ReplaceFlag) {
+ fpInOut = fopen (mInImageName, "wb");
+ if (fpInOut == NULL) {
+ Error (NULL, 0, 0001, "Error opening file", mInImageName);
+ goto Finish;
+ }
+ } else {
+ if (OutImageName != NULL) {
+ fpOut = fopen (OutImageName, "wb");
+ } else {
+ fpOut = stdout;
+ }
+ if (fpOut == NULL) {
+ Error (NULL, 0, 0001, "Error opening output file", OutImageName);
+ goto Finish;
+ }
+ }
if (fpInOut != NULL) {
fprintf (fpInOut, "Dump of file %s\n\n", mInImageName);
fprintf (fpInOut, "TE IMAGE HEADER VALUES\n");
@@ -2479,7 +2814,6 @@ Returns:
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);
}
-
if (fpOut != NULL) {
fprintf (fpOut, "Dump of file %s\n\n", mInImageName);
fprintf (fpOut, "TE IMAGE HEADER VALUES\n");
@@ -2514,36 +2848,36 @@ Returns:
}
} else {
if (stricmp (ModuleType, "BASE") == 0 ||
- stricmp (ModuleType, "SEC") == 0 ||
- stricmp (ModuleType, "SECURITY_CORE") == 0 ||
- stricmp (ModuleType, "PEI_CORE") == 0 ||
- stricmp (ModuleType, "PEIM") == 0 ||
- stricmp (ModuleType, "COMBINED_PEIM_DRIVER") == 0 ||
- stricmp (ModuleType, "PIC_PEIM") == 0 ||
- stricmp (ModuleType, "RELOCATABLE_PEIM") == 0 ||
- stricmp (ModuleType, "DXE_CORE") == 0 ||
- stricmp (ModuleType, "BS_DRIVER") == 0 ||
- stricmp (ModuleType, "DXE_DRIVER") == 0 ||
- stricmp (ModuleType, "DXE_SMM_DRIVER") == 0 ||
- stricmp (ModuleType, "UEFI_DRIVER") == 0 ||
- stricmp (ModuleType, "SMM_CORE") == 0) {
- Type = EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER;
- VerboseMsg ("Efi Image subsystem type is efi boot service driver.");
+ stricmp (ModuleType, "SEC") == 0 ||
+ stricmp (ModuleType, "SECURITY_CORE") == 0 ||
+ stricmp (ModuleType, "PEI_CORE") == 0 ||
+ stricmp (ModuleType, "PEIM") == 0 ||
+ stricmp (ModuleType, "COMBINED_PEIM_DRIVER") == 0 ||
+ stricmp (ModuleType, "PIC_PEIM") == 0 ||
+ stricmp (ModuleType, "RELOCATABLE_PEIM") == 0 ||
+ stricmp (ModuleType, "DXE_CORE") == 0 ||
+ stricmp (ModuleType, "BS_DRIVER") == 0 ||
+ stricmp (ModuleType, "DXE_DRIVER") == 0 ||
+ stricmp (ModuleType, "DXE_SMM_DRIVER") == 0 ||
+ stricmp (ModuleType, "UEFI_DRIVER") == 0 ||
+ stricmp (ModuleType, "SMM_CORE") == 0) {
+ Type = EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER;
+ VerboseMsg ("Efi Image subsystem type is efi boot service driver.");
} else if (stricmp (ModuleType, "UEFI_APPLICATION") == 0 ||
- stricmp (ModuleType, "APPLICATION") == 0) {
- Type = EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION;
- VerboseMsg ("Efi Image subsystem type is efi application.");
+ stricmp (ModuleType, "APPLICATION") == 0) {
+ Type = EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION;
+ VerboseMsg ("Efi Image subsystem type is efi application.");
} else if (stricmp (ModuleType, "DXE_RUNTIME_DRIVER") == 0 ||
- stricmp (ModuleType, "RT_DRIVER") == 0) {
- Type = EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER;
- VerboseMsg ("Efi Image subsystem type is efi runtime driver.");
+ stricmp (ModuleType, "RT_DRIVER") == 0) {
+ Type = EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER;
+ VerboseMsg ("Efi Image subsystem type is efi runtime driver.");
} else if (stricmp (ModuleType, "DXE_SAL_DRIVER") == 0 ||
- stricmp (ModuleType, "SAL_RT_DRIVER") == 0) {
- Type = EFI_IMAGE_SUBSYSTEM_SAL_RUNTIME_DRIVER;
- VerboseMsg ("Efi Image subsystem type is efi sal runtime driver.");
+ stricmp (ModuleType, "SAL_RT_DRIVER") == 0) {
+ Type = EFI_IMAGE_SUBSYSTEM_SAL_RUNTIME_DRIVER;
+ VerboseMsg ("Efi Image subsystem type is efi sal runtime driver.");
} else {
Error (NULL, 0, 1003, "Invalid option value", "EFI_FILETYPE = %s", ModuleType);
@@ -2559,7 +2893,7 @@ Returns:
VerboseMsg ("Convert the input ELF Image to Pe Image");
ConvertElf(&FileBuffer, &FileLength);
}
-
+
//
// Make sure File Offsets and Virtual Offsets are the same in the image so it is XIP
// XIP == eXecute In Place
@@ -2583,15 +2917,15 @@ Returns:
//
if ((SectionHeader->PointerToRawData + SectionHeader->SizeOfRawData) ==
(FileLength + TeHdr->StrippedSize - sizeof (EFI_TE_IMAGE_HEADER))) {
- //
- // Remove .reloc section and update TeImage Header
- //
- FileLength = FileLength - SectionHeader->SizeOfRawData;
- SectionHeader->SizeOfRawData = 0;
- SectionHeader->Misc.VirtualSize = 0;
- TeHdr->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress = 0;
- TeHdr->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size = 0;
- break;
+ //
+ // Remove .reloc section and update TeImage Header
+ //
+ FileLength = FileLength - SectionHeader->SizeOfRawData;
+ SectionHeader->SizeOfRawData = 0;
+ SectionHeader->Misc.VirtualSize = 0;
+ TeHdr->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress = 0;
+ TeHdr->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size = 0;
+ break;
}
}
}
@@ -2677,7 +3011,7 @@ Returns:
goto Finish;
}
}
-
+
if (PeHdr->Pe32.FileHeader.Machine == IMAGE_FILE_MACHINE_ARM) {
// Some tools kick out IMAGE_FILE_MACHINE_ARM (0x1c0) vs IMAGE_FILE_MACHINE_ARMT (0x1c2)
// so patch back to the offical UEFI value.
@@ -2685,6 +3019,43 @@ Returns:
}
//
+ // Set new base address into image
+ //
+ if (OutImageType == FW_REBASE_IMAGE || OutImageType == FW_SET_ADDRESS_IMAGE) {
+ if ((PeHdr->Pe32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) && (PeHdr->Pe32.FileHeader.Machine != IMAGE_FILE_MACHINE_IA64)) {
+ if (NewBaseAddress >= 0x100000000ULL) {
+ Error (NULL, 0, 3000, "Invalid", "New base address is larger than 4G for 32bit PE image");
+ goto Finish;
+ }
+ }
+
+ if (NegativeAddr) {
+ //
+ // Set Base Address to a negative value.
+ //
+ NewBaseAddress = (UINT64) (0 - NewBaseAddress);
+ }
+ if (OutImageType == FW_REBASE_IMAGE) {
+ Status = RebaseImage (mInImageName, FileBuffer, NewBaseAddress);
+ } else {
+ Status = SetAddressToSectionHeader (mInImageName, FileBuffer, NewBaseAddress);
+ }
+ if (EFI_ERROR (Status)) {
+ 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 (OutImageType == FW_BIN_IMAGE) {
@@ -2695,14 +3066,10 @@ Returns:
//
// Output bin data from exe file
//
- if (fpOut != NULL) {
- fwrite (FileBuffer + PeHdr->Pe32.OptionalHeader.SizeOfHeaders, 1, FileLength - PeHdr->Pe32.OptionalHeader.SizeOfHeaders, fpOut);
- }
- if (fpInOut != NULL) {
- fwrite (FileBuffer + PeHdr->Pe32.OptionalHeader.SizeOfHeaders, 1, FileLength - PeHdr->Pe32.OptionalHeader.SizeOfHeaders, fpInOut);
- }
- VerboseMsg ("the size of output file is %u bytes", (unsigned) (FileLength - PeHdr->Pe32.OptionalHeader.SizeOfHeaders));
- goto Finish;
+ FileLength = FileLength - PeHdr->Pe32.OptionalHeader.SizeOfHeaders;
+ memcpy (FileBuffer, FileBuffer + PeHdr->Pe32.OptionalHeader.SizeOfHeaders, FileLength);
+ VerboseMsg ("the size of output file is %u bytes", (unsigned) FileLength);
+ goto WriteFile;
}
//
@@ -2715,14 +3082,11 @@ Returns:
goto Finish;
}
- if (fpOut != NULL) {
- fwrite (FileBuffer, 1, FileLength, fpOut);
- }
- if (fpInOut != NULL) {
- fwrite (FileBuffer, 1, FileLength, fpInOut);
- }
+ //
+ // Write the updated Image
+ //
VerboseMsg ("the size of output file is %u bytes", (unsigned) FileLength);
- goto Finish;
+ goto WriteFile;
}
//
@@ -2734,14 +3098,11 @@ Returns:
goto Finish;
}
- if (fpOut != NULL) {
- fwrite (FileBuffer, 1, FileLength, fpOut);
- }
- if (fpInOut != NULL) {
- fwrite (FileBuffer, 1, FileLength, fpInOut);
- }
+ //
+ // Write the updated Image
+ //
VerboseMsg ("the size of output file is %u bytes", (unsigned) FileLength);
- goto Finish;
+ goto WriteFile;
}
//
@@ -2768,14 +3129,9 @@ Returns:
//
// Output Apci data to file
//
- if (fpOut != NULL) {
- fwrite (FileBuffer + SectionHeader->PointerToRawData, 1, FileLength, fpOut);
- }
- if (fpInOut != NULL) {
- fwrite (FileBuffer + SectionHeader->PointerToRawData, 1, FileLength, fpInOut);
- }
+ memcpy (FileBuffer, FileBuffer + SectionHeader->PointerToRawData, FileLength);
VerboseMsg ("the size of output file is %u bytes", (unsigned) FileLength);
- goto Finish;
+ goto WriteFile;
}
}
Error (NULL, 0, 3000, "Invalid", "failed to get ACPI table from %s.", mInImageName);
@@ -2789,7 +3145,7 @@ Returns:
memset (DosHdr, 0, sizeof (EFI_IMAGE_DOS_HEADER));
DosHdr->e_magic = BackupDosHdr.e_magic;
DosHdr->e_lfanew = BackupDosHdr.e_lfanew;
-
+
for (Index = sizeof (EFI_IMAGE_DOS_HEADER); Index < (UINT32 ) DosHdr->e_lfanew; Index++) {
FileBuffer[Index] = (UINT8) DosHdr->e_cp;
}
@@ -2804,7 +3160,7 @@ Returns:
TEImageHeader.NumberOfSections = (UINT8) PeHdr->Pe32.FileHeader.NumberOfSections;
TEImageHeader.StrippedSize = (UINT16) ((UINTN) ((UINT8 *) &(PeHdr->Pe32.OptionalHeader) + PeHdr->Pe32.FileHeader.SizeOfOptionalHeader) - (UINTN) FileBuffer);
TEImageHeader.Subsystem = (UINT8) Type;
-
+
//
// Patch the PE header
//
@@ -2845,28 +3201,28 @@ Returns:
// Zero .pdata section data.
//
if (!KeepExceptionTableFlag && Optional32->NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_EXCEPTION &&
- Optional32->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXCEPTION].VirtualAddress != 0 &&
- Optional32->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXCEPTION].Size != 0) {
- SectionHeader = (EFI_IMAGE_SECTION_HEADER *) ((UINT8 *) &(PeHdr->Pe32.OptionalHeader) + PeHdr->Pe32.FileHeader.SizeOfOptionalHeader);
- for (Index = 0; Index < PeHdr->Pe32.FileHeader.NumberOfSections; Index++, SectionHeader++) {
- if (SectionHeader->VirtualAddress == Optional32->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXCEPTION].VirtualAddress) {
- //
- // Zero .pdata Section data
- //
- memset (FileBuffer + SectionHeader->PointerToRawData, 0, SectionHeader->SizeOfRawData);
- //
- // Zero .pdata Section header name
- //
- memset (SectionHeader->Name, 0, sizeof (SectionHeader->Name));
- //
- // Zero Execption Table
- //
- Optional32->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXCEPTION].VirtualAddress = 0;
- Optional32->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXCEPTION].Size = 0;
- DebugMsg (NULL, 0, 9, "Zero the .pdata section for PE image", NULL);
- break;
+ Optional32->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXCEPTION].VirtualAddress != 0 &&
+ Optional32->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXCEPTION].Size != 0) {
+ SectionHeader = (EFI_IMAGE_SECTION_HEADER *) ((UINT8 *) &(PeHdr->Pe32.OptionalHeader) + PeHdr->Pe32.FileHeader.SizeOfOptionalHeader);
+ for (Index = 0; Index < PeHdr->Pe32.FileHeader.NumberOfSections; Index++, SectionHeader++) {
+ if (SectionHeader->VirtualAddress == Optional32->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXCEPTION].VirtualAddress) {
+ //
+ // Zero .pdata Section data
+ //
+ memset (FileBuffer + SectionHeader->PointerToRawData, 0, SectionHeader->SizeOfRawData);
+ //
+ // Zero .pdata Section header name
+ //
+ memset (SectionHeader->Name, 0, sizeof (SectionHeader->Name));
+ //
+ // Zero Execption Table
+ //
+ Optional32->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXCEPTION].VirtualAddress = 0;
+ Optional32->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXCEPTION].Size = 0;
+ DebugMsg (NULL, 0, 9, "Zero the .pdata section for PE image", NULL);
+ break;
+ }
}
- }
}
//
@@ -2941,40 +3297,40 @@ Returns:
//
if ((!KeepExceptionTableFlag && PeHdr->Pe32.FileHeader.Machine == IMAGE_FILE_MACHINE_X64) || PeHdr->Pe32.FileHeader.Machine == IMAGE_FILE_MACHINE_IA64) {
if (Optional64->NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_EXCEPTION &&
- Optional64->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXCEPTION].VirtualAddress != 0 &&
- Optional64->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXCEPTION].Size != 0) {
- SectionHeader = (EFI_IMAGE_SECTION_HEADER *) ((UINT8 *) &(PeHdr->Pe32.OptionalHeader) + PeHdr->Pe32.FileHeader.SizeOfOptionalHeader);
- for (Index = 0; Index < PeHdr->Pe32.FileHeader.NumberOfSections; Index++, SectionHeader++) {
- if (SectionHeader->VirtualAddress == Optional64->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXCEPTION].VirtualAddress) {
- //
- // Zero .pdata Section header name
- //
- memset (SectionHeader->Name, 0, sizeof (SectionHeader->Name));
-
- RuntimeFunction = (RUNTIME_FUNCTION *)(FileBuffer + SectionHeader->PointerToRawData);
- 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);
- for (Index2 = 0; Index2 < PeHdr->Pe32.FileHeader.NumberOfSections; Index2++, SectionHeader++) {
- if (RuntimeFunction->UnwindInfoAddress >= SectionHeader->VirtualAddress && RuntimeFunction->UnwindInfoAddress < (SectionHeader->VirtualAddress + SectionHeader->SizeOfRawData)) {
- UnwindInfo = (UNWIND_INFO *)(FileBuffer + SectionHeader->PointerToRawData + (RuntimeFunction->UnwindInfoAddress - SectionHeader->VirtualAddress));
- if (UnwindInfo->Version == 1) {
- memset (UnwindInfo + 1, 0, UnwindInfo->CountOfUnwindCodes * sizeof (UINT16));
- memset (UnwindInfo, 0, sizeof (UNWIND_INFO));
+ Optional64->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXCEPTION].VirtualAddress != 0 &&
+ Optional64->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXCEPTION].Size != 0) {
+ SectionHeader = (EFI_IMAGE_SECTION_HEADER *) ((UINT8 *) &(PeHdr->Pe32.OptionalHeader) + PeHdr->Pe32.FileHeader.SizeOfOptionalHeader);
+ for (Index = 0; Index < PeHdr->Pe32.FileHeader.NumberOfSections; Index++, SectionHeader++) {
+ if (SectionHeader->VirtualAddress == Optional64->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXCEPTION].VirtualAddress) {
+ //
+ // Zero .pdata Section header name
+ //
+ memset (SectionHeader->Name, 0, sizeof (SectionHeader->Name));
+
+ RuntimeFunction = (RUNTIME_FUNCTION *)(FileBuffer + SectionHeader->PointerToRawData);
+ 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);
+ for (Index2 = 0; Index2 < PeHdr->Pe32.FileHeader.NumberOfSections; Index2++, SectionHeader++) {
+ if (RuntimeFunction->UnwindInfoAddress >= SectionHeader->VirtualAddress && RuntimeFunction->UnwindInfoAddress < (SectionHeader->VirtualAddress + SectionHeader->SizeOfRawData)) {
+ UnwindInfo = (UNWIND_INFO *)(FileBuffer + SectionHeader->PointerToRawData + (RuntimeFunction->UnwindInfoAddress - SectionHeader->VirtualAddress));
+ if (UnwindInfo->Version == 1) {
+ memset (UnwindInfo + 1, 0, UnwindInfo->CountOfUnwindCodes * sizeof (UINT16));
+ memset (UnwindInfo, 0, sizeof (UNWIND_INFO));
+ }
+ break;
}
- break;
}
+ memset (RuntimeFunction, 0, sizeof (RUNTIME_FUNCTION));
}
- memset (RuntimeFunction, 0, sizeof (RUNTIME_FUNCTION));
+ //
+ // Zero Execption Table
+ //
+ Optional64->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXCEPTION].Size = 0;
+ Optional64->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXCEPTION].VirtualAddress = 0;
+ DebugMsg (NULL, 0, 9, "Zero the .pdata section if the machine type is X64 for PE32+ image", NULL);
+ break;
}
- //
- // Zero Execption Table
- //
- Optional64->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXCEPTION].Size = 0;
- Optional64->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXCEPTION].VirtualAddress = 0;
- DebugMsg (NULL, 0, 9, "Zero the .pdata section if the machine type is X64 for PE32+ image", NULL);
- break;
}
- }
}
}
@@ -3017,19 +3373,19 @@ Returns:
Error (NULL, 0, 3000, "Invalid", "Magic 0x%x of PeImage %s is unknown.", PeHdr->Pe32.OptionalHeader.Magic, mInImageName);
goto Finish;
}
-
+
if (((PeHdr->Pe32.FileHeader.Characteristics & EFI_IMAGE_FILE_RELOCS_STRIPPED) == 0) && \
(TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress == 0) && \
(TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size == 0)) {
- //
- // 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);
- }
+ //
+ // 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);
+ }
}
//
@@ -3102,40 +3458,54 @@ Returns:
}
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);
+ TEImageHeader.Machine, TEImageHeader.NumberOfSections, TEImageHeader.StrippedSize, (unsigned) TEImageHeader.AddressOfEntryPoint, (unsigned) TEImageHeader.BaseOfCode, (unsigned long long) TEImageHeader.ImageBase);
//
// Update Image to TeImage
//
- if (fpOut != NULL) {
- fwrite (&TEImageHeader, 1, sizeof (EFI_TE_IMAGE_HEADER), fpOut);
- fwrite (FileBuffer + TEImageHeader.StrippedSize, 1, FileLength - TEImageHeader.StrippedSize, fpOut);
- }
- if (fpInOut != NULL) {
- fwrite (&TEImageHeader, 1, sizeof (EFI_TE_IMAGE_HEADER), fpInOut);
- fwrite (FileBuffer + TEImageHeader.StrippedSize, 1, FileLength - TEImageHeader.StrippedSize, fpInOut);
- }
- VerboseMsg ("the size of output file is %u bytes", (unsigned) (FileLength - TEImageHeader.StrippedSize));
- goto Finish;
+ FileLength = FileLength - TEImageHeader.StrippedSize;
+ memcpy (FileBuffer + sizeof (EFI_TE_IMAGE_HEADER), FileBuffer + TEImageHeader.StrippedSize, FileLength);
+ FileLength = FileLength + sizeof (EFI_TE_IMAGE_HEADER);
+ memcpy (FileBuffer, &TEImageHeader, sizeof (EFI_TE_IMAGE_HEADER));
+ VerboseMsg ("the size of output file is %u bytes", (unsigned) (FileLength));
}
+
WriteFile:
//
- // Update Image to EfiImage
+ // Update Image to EfiImage or TE image
//
- if (fpOut != NULL) {
- fwrite (FileBuffer, 1, FileLength, fpOut);
- }
- if (fpInOut != NULL) {
- fwrite (FileBuffer, 1, FileLength, fpInOut);
+ if (ReplaceFlag) {
+ if ((FileLength != InputFileLength) || (memcmp (FileBuffer, InputFileBuffer, FileLength) != 0)) {
+ //
+ // Update File when File is changed.
+ //
+ fpInOut = fopen (mInImageName, "wb");
+ if (fpInOut == NULL) {
+ Error (NULL, 0, 0001, "Error opening file", mInImageName);
+ goto Finish;
+ }
+ fwrite (FileBuffer, 1, FileLength, fpInOut);
+ VerboseMsg ("the size of output file is %u bytes", (unsigned) FileLength);
+ }
+ } else {
+ if ((FileLength != OutputFileLength) || (memcmp (FileBuffer, OutputFileBuffer, FileLength) != 0)) {
+ fpOut = fopen (OutImageName, "wb");
+ if (fpOut == NULL) {
+ Error (NULL, 0, 0001, "Error opening output file", OutImageName);
+ goto Finish;
+ }
+ fwrite (FileBuffer, 1, FileLength, fpOut);
+ VerboseMsg ("the size of output file is %u bytes", (unsigned) FileLength);
+ }
}
- VerboseMsg ("the size of output file is %u bytes", (unsigned) FileLength);
+ mImageSize = FileLength;
Finish:
if (fpInOut != NULL) {
if (GetUtilityStatus () != STATUS_SUCCESS) {
//
- // when file updates failed, original file is still recoveried.
+ // when file updates failed, original file is still recovered.
//
- fwrite (FileBuffer, 1, FileLength, fpInOut);
+ fwrite (InputFileBuffer, 1, InputFileLength, fpInOut);
}
//
// Write converted data into fpInOut file and close input file.
@@ -3163,11 +3533,38 @@ Finish:
fpOut = fopen (OutImageName, "wb");
fwrite (OutputFileBuffer, 1, OutputFileLength, fpOut);
fclose (fpOut);
- free (OutputFileBuffer);
}
}
}
+
+ if (InputFileBuffer != NULL) {
+ free (InputFileBuffer);
+ }
+
+ if (OutputFileBuffer != NULL) {
+ free (OutputFileBuffer);
+ }
+ //
+ // Write module size and time stamp to report file.
+ //
+ if (OutImageName != NULL) {
+ FileLen = strlen (OutImageName);
+ }
+ if (FileLen >= 4 && strcmp (OutImageName + (FileLen - 4), ".efi") == 0) {
+ ReportFileName = (CHAR8 *) malloc (FileLen + 1);
+ if (ReportFileName != NULL) {
+ strcpy (ReportFileName, OutImageName);
+ strcpy (ReportFileName + (FileLen - 4), ".txt");
+ ReportFile = fopen (ReportFileName, "w+");
+ if (ReportFile != NULL) {
+ fprintf (ReportFile, "MODULE_SIZE = %u\n", (unsigned) mImageSize);
+ fprintf (ReportFile, "TIME_STAMP = %u\n", (unsigned) mImageTimeStamp);
+ fclose(ReportFile);
+ }
+ free (ReportFileName);
+ }
+ }
VerboseMsg ("%s tool done with return code is 0x%x.", UTILITY_NAME, GetUtilityStatus ());
return GetUtilityStatus ();
@@ -3302,7 +3699,7 @@ Returns:
//Zero Debug Data and TimeStamp
//
FileHdr->TimeDateStamp = 0;
-
+ mImageTimeStamp = 0;
if (ExportDirectoryEntryFileOffset != 0) {
NewTimeStamp = (UINT32 *) (FileBuffer + ExportDirectoryEntryFileOffset + sizeof (UINT32));
*NewTimeStamp = 0;
@@ -3316,6 +3713,7 @@ Returns:
if (DebugDirectoryEntryFileOffset != 0) {
DebugEntry = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *) (FileBuffer + DebugDirectoryEntryFileOffset);
DebugEntry->TimeDateStamp = 0;
+ mImageTimeStamp = 0;
if (ZeroDebugFlag) {
memset (FileBuffer + DebugEntry->FileOffset, 0, DebugEntry->SizeOfData);
memset (DebugEntry, 0, sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY));
@@ -3542,7 +3940,7 @@ Returns:
// Set new stamp
//
FileHdr->TimeDateStamp = (UINT32) newtime;
-
+ mImageTimeStamp = (UINT32) newtime;
if (ExportDirectoryEntryRva != 0) {
NewTimeStamp = (UINT32 *) (FileBuffer + ExportDirectoryEntryFileOffset + sizeof (UINT32));
*NewTimeStamp = (UINT32) newtime;