/** @file\r
+Converts a pe32+ image to an FW, Te image type, or other specific image.\r
\r
-Copyright (c) 2004 - 2009, Intel Corporation\r
-All rights reserved. This program and the accompanying materials\r
-are licensed and made available under the terms and conditions of the BSD License\r
-which accompanies this distribution. The full text of the license may be found at\r
-http://opensource.org/licenses/bsd-license.php\r
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-\r
-Module Name:\r
-\r
- GenFw.c\r
-\r
-Abstract:\r
-\r
- Converts a pe32+ image to an FW, Te image type, or other specific image.\r
+Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
\r
**/\r
\r
#ifndef __GNUC__\r
#include <windows.h>\r
#include <io.h>\r
+#include <sys/types.h>\r
+#include <sys/stat.h>\r
#endif\r
#include <stdio.h>\r
#include <stdlib.h>\r
#include "ParseInf.h"\r
#include "EfiUtilityMsgs.h"\r
\r
-#include "elf_common.h"\r
-#include "elf32.h"\r
-#include "elf64.h"\r
-\r
+#include "GenFw.h"\r
\r
//\r
// Version of this utility\r
\r
#define HII_RESOURCE_SECTION_INDEX 1\r
#define HII_RESOURCE_SECTION_NAME "HII"\r
-//\r
-// Action for this tool.\r
-//\r
-#define FW_DUMMY_IMAGE 0\r
-#define FW_EFI_IMAGE 1\r
-#define FW_TE_IMAGE 2\r
-#define FW_ACPI_IMAGE 3\r
-#define FW_BIN_IMAGE 4\r
-#define FW_ZERO_DEBUG_IMAGE 5\r
-#define FW_SET_STAMP_IMAGE 6\r
-#define FW_MCI_IMAGE 7\r
-#define FW_MERGE_IMAGE 8\r
-#define FW_RELOC_STRIPEED_IMAGE 9\r
-#define FW_HII_PACKAGE_LIST_RCIMAGE 10\r
-\r
-#define DUMP_TE_HEADER 0x11\r
\r
#define DEFAULT_MC_PAD_BYTE_VALUE 0xFF\r
#define DEFAULT_MC_ALIGNMENT 16\r
\r
-#ifndef _MAX_PATH\r
-#define _MAX_PATH 500\r
-#endif\r
-\r
-#define STATUS_IGNORE 0xA\r
+#define STATUS_IGNORE 0xA\r
//\r
// Structure definition for a microcode header\r
//\r
NULL\r
};\r
\r
-STATIC CHAR8 *mInImageName;\r
+//\r
+// Module image information\r
+//\r
+CHAR8 *mInImageName;\r
+UINT32 mImageTimeStamp = 0;\r
+UINT32 mImageSize = 0;\r
+UINT32 mOutImageType = FW_DUMMY_IMAGE;\r
+BOOLEAN mIsConvertXip = FALSE;\r
+\r
\r
STATIC\r
EFI_STATUS\r
\r
--*/\r
{\r
- fprintf (stdout, "%s Version %d.%d\n", UTILITY_NAME, UTILITY_MAJOR_VERSION, UTILITY_MINOR_VERSION);\r
+ fprintf (stdout, "%s Version %d.%d %s \n", UTILITY_NAME, UTILITY_MAJOR_VERSION, UTILITY_MINOR_VERSION, __BUILD_VERSION);\r
}\r
\r
STATIC\r
//\r
// Copyright declaration\r
//\r
- fprintf (stdout, "Copyright (c) 2007, Intel Corporation. All rights reserved.\n\n");\r
+ fprintf (stdout, "Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.\n\n");\r
\r
//\r
// Details Option\r
//\r
fprintf (stdout, "Options:\n");\r
fprintf (stdout, " -o FileName, --outputfile FileName\n\\r
- File will be created to store the ouput content.\n");\r
+ File will be created to store the output content.\n");\r
fprintf (stdout, " -e EFI_FILETYPE, --efiImage EFI_FILETYPE\n\\r
- Create Efi Image. EFI_FILETYPE is one of BASE, SEC,\n\\r
+ Create Efi Image. EFI_FILETYPE is one of BASE,SMM_CORE,\n\\r
PEI_CORE, PEIM, DXE_CORE, DXE_DRIVER, UEFI_APPLICATION,\n\\r
- DXE_SAL_DRIVER, UEFI_DRIVER, DXE_RUNTIME_DRIVER, \n\\r
- DXE_SMM_DRIVER, SECURITY_CORE, COMBINED_PEIM_DRIVER, \n\\r
+ SEC, DXE_SAL_DRIVER, UEFI_DRIVER, DXE_RUNTIME_DRIVER,\n\\r
+ DXE_SMM_DRIVER, SECURITY_CORE, COMBINED_PEIM_DRIVER,\n\\r
+ MM_STANDALONE, MM_CORE_STANDALONE,\n\\r
PIC_PEIM, RELOCATABLE_PEIM, BS_DRIVER, RT_DRIVER,\n\\r
APPLICATION, SAL_RT_DRIVER to support all module types\n\\r
It can only be used together with --keepexceptiontable,\n\\r
- --keepzeropending, -r, -o option.It is a action option.\n\\r
- If it is combined with other action options, the later\n\\r
- input action option will override the previous one.\n");\r
+ --keepzeropending, --keepoptionalheader, -r, -o option.\n\\r
+ It is a action option. If it is combined with other action options,\n\\r
+ the later input action option will override the previous one.\n");\r
fprintf (stdout, " -c, --acpi Create Acpi table.\n\\r
It can't be combined with other action options\n\\r
except for -o, -r option. It is a action option.\n\\r
input action option will override the previous one.\n");\r
fprintf (stdout, " -t, --terse Create Te Image.\n\\r
It can only be used together with --keepexceptiontable,\n\\r
- --keepzeropending, -r, -o option.It is a action option.\n\\r
- If it is combined with other action options, the later\n\\r
- input action option will override the previous one.\n");\r
+ --keepzeropending, --keepoptionalheader, -r, -o option.\n\\r
+ It is a action option. If it is combined with other action options,\n\\r
+ the later input action option will override the previous one.\n");\r
fprintf (stdout, " -u, --dump Dump TeImage Header.\n\\r
It can't be combined with other action options\n\\r
except for -o, -r option. It is a action option.\n\\r
except for -o, -r option. It is a action option.\n\\r
If it is combined with other action options, the later\n\\r
input action option will override the previous one.\n");;\r
- fprintf (stdout, " -l, --stripped Relocation info stripped from the input PE or TE image.\n\\r
+ fprintf (stdout, " -l, --stripped Strip off the relocation info from PE or TE image.\n\\r
It can't be combined with other action options\n\\r
except for -o, -r option. It is a action option.\n\\r
If it is combined with other action options, the later\n\\r
fprintf (stdout, " -s timedate, --stamp timedate\n\\r
timedate format is \"yyyy-mm-dd 00:00:00\". if timedata \n\\r
is set to NOW, current system time is used. The support\n\\r
- date scope is 1970-1-1 8:0:0 ~ 2038-1-19 3:14:07\n\\r
+ date scope is 1970-01-01 00+timezone:00:00\n\\r
+ ~ 2038-01-19 03+timezone:14:07\n\\r
+ The scope is adjusted according to the different zones.\n\\r
It can't be combined with other action options\n\\r
except for -o, -r option. It is a action option.\n\\r
If it is combined with other action options, the later\n\\r
If it is combined with other action options, the later\n\\r
input action option will override the previous one.\n");\r
fprintf (stdout, " -a NUM, --align NUM NUM is one HEX or DEC format alignment value.\n\\r
- This option is only used together with -j option.\n"); \r
+ This option is only used together with -j option.\n");\r
fprintf (stdout, " -p NUM, --pad NUM NUM is one HEX or DEC format padding value.\n\\r
This option is only used together with -j option.\n");\r
fprintf (stdout, " --keepexceptiontable Don't clear exception table.\n\\r
This option can be used together with -e or -t.\n\\r
It doesn't work for other options.\n");\r
+ fprintf (stdout, " --keepoptionalheader Don't zero PE/COFF optional header fields.\n\\r
+ This option can be used together with -e or -t.\n\\r
+ It doesn't work for other options.\n");\r
fprintf (stdout, " --keepzeropending Don't strip zero pending of .reloc.\n\\r
This option can be used together with -e or -t.\n\\r
It doesn't work for other options.\n");\r
If more input files are specified,\n\\r
the last input file will be as the output file.\n");\r
fprintf (stdout, " -g HiiPackageListGuid, --hiiguid HiiPackageListGuid\n\\r
- HiiListPackageGuidGuid is from the module guid.\n\\r
+ Guid is used to specify hii package list guid.\n\\r
Its format is xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\n\\r
If not specified, the first Form FormSet guid is used.\n");\r
- fprintf (stdout, " --hiipackage Combine all input binary hii pacakges into \n\\r
+ fprintf (stdout, " --hiipackage Combine all input binary hii packages into \n\\r
a single package list as the text resource data(RC).\n\\r
It can't be combined with other action options\n\\r
except for -o option. It is a action option.\n\\r
If it is combined with other action options, the later\n\\r
input action option will override the previous one.\n");\r
+ fprintf (stdout, " --hiibinpackage Combine all input binary hii packages into \n\\r
+ a single package list as the binary resource section.\n\\r
+ It can't be combined with other action options\n\\r
+ except for -o option. It is a action option.\n\\r
+ If it is combined with other action options, the later\n\\r
+ input action option will override the previous one.\n");\r
+ fprintf (stdout, " --rebase NewAddress Rebase image to new base address. New address \n\\r
+ is also set to the first none code section header.\n\\r
+ It can't be combined with other action options\n\\r
+ except for -o or -r option. It is a action option.\n\\r
+ If it is combined with other action options, the later\n\\r
+ input action option will override the previous one.\n");\r
+ fprintf (stdout, " --address NewAddress Set new address into the first none code \n\\r
+ section header of the input image.\n\\r
+ It can't be combined with other action options\n\\r
+ except for -o or -r option. It is a action option.\n\\r
+ If it is combined with other action options, the later\n\\r
+ input action option will override the previous one.\n");\r
fprintf (stdout, " -v, --verbose Turn on verbose output with informational messages.\n");\r
fprintf (stdout, " -q, --quiet Disable all messages except key message and fatal error\n");\r
fprintf (stdout, " -d, --debug level Enable debug messages, at input debug level.\n");\r
return STATUS_SUCCESS;\r
}\r
\r
-\r
-INTN\r
-IsElfHeader(\r
- UINT8 *FileBuffer\r
-)\r
-{\r
- return (FileBuffer[EI_MAG0] == ELFMAG0\r
- && FileBuffer[EI_MAG1] == ELFMAG1\r
- && FileBuffer[EI_MAG2] == ELFMAG2\r
- && FileBuffer[EI_MAG3] == ELFMAG3);\r
-}\r
-\r
-typedef Elf32_Shdr Elf_Shdr;\r
-typedef Elf32_Ehdr Elf_Ehdr;\r
-typedef Elf32_Rel Elf_Rel;\r
-typedef Elf32_Sym Elf_Sym;\r
-typedef Elf32_Phdr Elf_Phdr;\r
-typedef Elf32_Dyn Elf_Dyn;\r
-\r
-#define ELFCLASS ELFCLASS32\r
-#define ELF_R_TYPE(r) ELF32_R_TYPE(r)\r
-#define ELF_R_SYM(r) ELF32_R_SYM(r)\r
-#define ELF_HII_SECTION_NAME ".hii"\r
-//\r
-// Well known ELF structures.\r
-//\r
-Elf_Ehdr *Ehdr;\r
-Elf_Shdr *ShdrBase;\r
-Elf_Phdr *gPhdrBase;\r
-\r
-//\r
-// PE section alignment.\r
-//\r
-const UINT32 CoffAlignment = 0x20;\r
-const UINT16 CoffNbrSections = 5;\r
-\r
-//\r
-// Current offset in coff file.\r
-//\r
-UINT32 CoffOffset;\r
-\r
-//\r
-// Result Coff file in memory.\r
-//\r
-UINT8 *CoffFile = NULL;\r
-//\r
-// ELF sections to offset in Coff file.\r
-//\r
-UINT32 *CoffSectionsOffset = NULL;\r
-\r
-//\r
-// Offset in Coff file of headers and sections.\r
-//\r
-UINT32 NtHdrOffset;\r
-UINT32 TableOffset;\r
-UINT32 TextOffset;\r
-UINT32 DataOffset;\r
-UINT32 HiiRsrcOffset;\r
-UINT32 RelocOffset;\r
-\r
-//\r
-// HiiBinData\r
-//\r
-UINT8* HiiBinData = NULL;\r
-UINT32 HiiBinSize = 0;\r
-\r
-EFI_IMAGE_BASE_RELOCATION *CoffBaseRel;\r
-UINT16 *CoffEntryRel;\r
-\r
-UINT32\r
-CoffAlign(\r
- UINT32 Offset\r
- )\r
-{\r
- return (Offset + CoffAlignment - 1) & ~(CoffAlignment - 1);\r
-}\r
-\r
-Elf_Shdr *\r
-GetShdrByIndex(\r
- UINT32 Num\r
+VOID\r
+SetHiiResourceHeader (\r
+ UINT8 *HiiBinData,\r
+ UINT32 OffsetToFile\r
)\r
{\r
- if (Num >= Ehdr->e_shnum)\r
- return NULL;\r
- return (Elf_Shdr*)((UINT8*)ShdrBase + Num * Ehdr->e_shentsize);\r
-}\r
+ UINT32 Index;\r
+ EFI_IMAGE_RESOURCE_DIRECTORY *ResourceDirectory;\r
+ EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY *ResourceDirectoryEntry;\r
+ EFI_IMAGE_RESOURCE_DIRECTORY_STRING *ResourceDirectoryString;\r
+ EFI_IMAGE_RESOURCE_DATA_ENTRY *ResourceDataEntry;\r
\r
-INTN\r
-CheckElfHeader(\r
- VOID\r
- )\r
-{\r
//\r
- // Note: Magic has already been tested.\r
+ // Fill Resource section entry\r
//\r
- if (Ehdr->e_ident[EI_CLASS] != ELFCLASS) {\r
- Error (NULL, 0, 3000, "Unsupported", "%s needs to be ported for 64-bit ELF.", mInImageName);\r
- return 0;\r
- }\r
- if (Ehdr->e_ident[EI_DATA] != ELFDATA2LSB) {\r
- Error (NULL, 0, 3000, "Unsupported", "ELF EI_DATA not ELFDATA2LSB");\r
- return 0;\r
- }\r
- if ((Ehdr->e_type != ET_EXEC) && (Ehdr->e_type != ET_DYN)) {\r
- Error (NULL, 0, 3000, "Unsupported", "ELF e_type not ET_EXEC or ET_DYN");\r
- return 0;\r
- }\r
- if (!((Ehdr->e_machine == EM_386) || (Ehdr->e_machine == EM_ARM))) { \r
- Error (NULL, 0, 3000, "Unsupported", "ELF e_machine not EM_386 or EM_ARM");\r
- return 0;\r
- }\r
- if (Ehdr->e_version != EV_CURRENT) {\r
- Error (NULL, 0, 3000, "Unsupported", "ELF e_version (%u) not EV_CURRENT (%d)", (unsigned) Ehdr->e_version, EV_CURRENT);\r
- return 0;\r
- }\r
+ ResourceDirectory = (EFI_IMAGE_RESOURCE_DIRECTORY *) (HiiBinData);\r
+ ResourceDirectoryEntry = (EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY *) (ResourceDirectory + 1);\r
+ for (Index = 0; Index < ResourceDirectory->NumberOfNamedEntries; Index ++) {\r
+ if (ResourceDirectoryEntry->u1.s.NameIsString) {\r
+ ResourceDirectoryString = (EFI_IMAGE_RESOURCE_DIRECTORY_STRING *) (HiiBinData + ResourceDirectoryEntry->u1.s.NameOffset);\r
\r
- //\r
- // Find the section header table\r
- //\r
- ShdrBase = (Elf_Shdr *)((UINT8 *)Ehdr + Ehdr->e_shoff);\r
- gPhdrBase = (Elf_Phdr *)((UINT8 *)Ehdr + Ehdr->e_phoff);\r
+ if (ResourceDirectoryString->Length == 3 &&\r
+ ResourceDirectoryString->String[0] == L'H' &&\r
+ ResourceDirectoryString->String[1] == L'I' &&\r
+ ResourceDirectoryString->String[2] == L'I') {\r
+ //\r
+ // Resource Type "HII" found\r
+ //\r
+ if (ResourceDirectoryEntry->u2.s.DataIsDirectory) {\r
+ //\r
+ // Move to next level - resource Name\r
+ //\r
+ ResourceDirectory = (EFI_IMAGE_RESOURCE_DIRECTORY *) (HiiBinData + ResourceDirectoryEntry->u2.s.OffsetToDirectory);\r
+ ResourceDirectoryEntry = (EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY *) (ResourceDirectory + 1);\r
\r
- CoffSectionsOffset = (UINT32 *)malloc(Ehdr->e_shnum * sizeof (UINT32));\r
+ if (ResourceDirectoryEntry->u2.s.DataIsDirectory) {\r
+ //\r
+ // Move to next level - resource Language\r
+ //\r
+ ResourceDirectory = (EFI_IMAGE_RESOURCE_DIRECTORY *) (HiiBinData + ResourceDirectoryEntry->u2.s.OffsetToDirectory);\r
+ ResourceDirectoryEntry = (EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY *) (ResourceDirectory + 1);\r
+ }\r
+ }\r
\r
- memset(CoffSectionsOffset, 0, Ehdr->e_shnum * sizeof(UINT32));\r
- return 1;\r
-}\r
+ //\r
+ // Now it ought to be resource Data and update its OffsetToData value\r
+ //\r
+ if (!ResourceDirectoryEntry->u2.s.DataIsDirectory) {\r
+ ResourceDataEntry = (EFI_IMAGE_RESOURCE_DATA_ENTRY *) (HiiBinData + ResourceDirectoryEntry->u2.OffsetToData);\r
+ ResourceDataEntry->OffsetToData = ResourceDataEntry->OffsetToData + OffsetToFile;\r
+ break;\r
+ }\r
+ }\r
+ }\r
+ ResourceDirectoryEntry++;\r
+ }\r
\r
-int\r
-IsTextShdr(\r
- Elf_Shdr *Shdr\r
- )\r
-{\r
- return (Shdr->sh_flags & (SHF_WRITE | SHF_ALLOC)) == SHF_ALLOC;\r
+ return;\r
}\r
\r
-int\r
-IsHiiRsrcShdr(\r
- Elf_Shdr *Shdr\r
+EFI_IMAGE_OPTIONAL_HEADER_UNION *\r
+GetPeCoffHeader (\r
+ void *Data\r
)\r
{\r
- Elf_Shdr *Namedr = GetShdrByIndex(Ehdr->e_shstrndx);\r
-\r
- if (strcmp((CHAR8*)Ehdr + Namedr->sh_offset + Shdr->sh_name, ELF_HII_SECTION_NAME) == 0) {\r
- return 1;\r
- }\r
+ EFI_IMAGE_DOS_HEADER *DosHdr;\r
+ EFI_IMAGE_OPTIONAL_HEADER_UNION *PeHdr;\r
\r
- return 0;\r
-}\r
+ //\r
+ // Read the dos & pe hdrs of the image\r
+ //\r
+ DosHdr = (EFI_IMAGE_DOS_HEADER *)Data;\r
+ if (DosHdr->e_magic != EFI_IMAGE_DOS_SIGNATURE) {\r
+ // NO DOS header, check for PE/COFF header\r
+ PeHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)(Data);\r
+ if (PeHdr->Pe32.Signature != EFI_IMAGE_NT_SIGNATURE) {\r
+ return NULL;\r
+ }\r
+ } else {\r
\r
-int\r
-IsDataShdr(\r
- Elf_Shdr *Shdr\r
- )\r
-{\r
- if (IsHiiRsrcShdr(Shdr)) {\r
- return 0;\r
+ PeHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)(((UINT8 *)Data) + DosHdr->e_lfanew);\r
+ if (PeHdr->Pe32.Signature != EFI_IMAGE_NT_SIGNATURE) {\r
+ return NULL;\r
+ }\r
}\r
- return (Shdr->sh_flags & (SHF_WRITE | SHF_ALLOC)) == (SHF_ALLOC | SHF_WRITE);\r
-}\r
\r
-VOID\r
-CreateSectionHeader(\r
- const CHAR8 *Name,\r
- UINT32 Offset,\r
- UINT32 Size,\r
- UINT32 Flags\r
- )\r
-{\r
- EFI_IMAGE_SECTION_HEADER *Hdr;\r
- Hdr = (EFI_IMAGE_SECTION_HEADER*)(CoffFile + TableOffset);\r
-\r
- strcpy((char *)Hdr->Name, Name);\r
- Hdr->Misc.VirtualSize = Size;\r
- Hdr->VirtualAddress = Offset;\r
- Hdr->SizeOfRawData = Size;\r
- Hdr->PointerToRawData = Offset;\r
- Hdr->PointerToRelocations = 0;\r
- Hdr->PointerToLinenumbers = 0;\r
- Hdr->NumberOfRelocations = 0;\r
- Hdr->NumberOfLinenumbers = 0;\r
- Hdr->Characteristics = Flags;\r
-\r
- TableOffset += sizeof (EFI_IMAGE_SECTION_HEADER);\r
+ return PeHdr;\r
}\r
\r
-VOID\r
-GetBinaryHiiData (\r
- CHAR8 *RcString,\r
- UINT32 Size,\r
- UINT32 OffsetToFile\r
+void\r
+PeCoffConvertImageToXip (\r
+ UINT8 **FileBuffer,\r
+ UINT32 *FileLength\r
)\r
{\r
- unsigned Data16;\r
- UINT32 HiiBinOffset;\r
- UINT32 Index;\r
- EFI_IMAGE_RESOURCE_DIRECTORY *ResourceDirectory;\r
- EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY *ResourceDirectoryEntry;\r
- EFI_IMAGE_RESOURCE_DIRECTORY_STRING *ResourceDirectoryString;\r
- EFI_IMAGE_RESOURCE_DATA_ENTRY *ResourceDataEntry;\r
-\r
- Index = 0;\r
- while (Index < Size && *RcString != '\0' && *RcString != '{') {\r
- RcString ++;\r
- Index ++;\r
- }\r
- \r
- if (*RcString == '\0' || Index == Size) {\r
+ EFI_IMAGE_OPTIONAL_HEADER_UNION *PeHdr;\r
+ EFI_IMAGE_OPTIONAL_HEADER_UNION *NewPeHdr;\r
+ EFI_IMAGE_SECTION_HEADER *SectionHeader;\r
+ UINTN TotalNecessaryFileSize;\r
+ UINTN SectionSize;\r
+ UINT8 *XipFile;\r
+ UINT32 XipLength;\r
+ UINTN Index;\r
+ UINTN FirstSectionOffset;\r
+ BOOLEAN ConversionNeeded;\r
+\r
+ PeHdr = GetPeCoffHeader ((void *) *FileBuffer);\r
+ if (PeHdr == NULL) {\r
return;\r
}\r
- \r
- //\r
- // Skip '{' character\r
- // Skip space and ',' character\r
- //\r
- RcString ++;\r
- Index ++;\r
- while (Index < Size && *RcString != '\0' && (isspace (*RcString) || *RcString == ',')){\r
- RcString ++;\r
- Index ++;\r
- }\r
\r
- //\r
- // '}' end character\r
- //\r
- if (*RcString == '}' || Index == Size) {\r
+ if (PeHdr->Pe32.OptionalHeader.SectionAlignment != PeHdr->Pe32.OptionalHeader.FileAlignment) {\r
+ //\r
+ // The only reason to expand zero fill sections is to make them compatible with XIP images.\r
+ // If SectionAlignment is not equal to FileAlignment then it is not an XIP type image.\r
+ //\r
return;\r
}\r
\r
- HiiBinOffset = 0;\r
- HiiBinSize = 0x1000;\r
- HiiBinData = (UINT8 *) malloc (HiiBinSize);\r
- if (HiiBinData == NULL) {\r
- return;\r
- }\r
- memset (HiiBinData, 0, HiiBinSize);\r
//\r
- // Fill Resource section entry\r
+ // Calculate size of XIP file, and determine if the conversion is needed.\r
//\r
- ResourceDirectory = (EFI_IMAGE_RESOURCE_DIRECTORY *) (HiiBinData + HiiBinOffset);\r
- HiiBinOffset += sizeof (EFI_IMAGE_RESOURCE_DIRECTORY);\r
- ResourceDirectory->NumberOfNamedEntries = 1;\r
-\r
- ResourceDirectoryEntry = (EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY *) (HiiBinData + HiiBinOffset);\r
- HiiBinOffset += sizeof (EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY);\r
- ResourceDirectoryEntry->u1.s.NameIsString = 1;\r
- ResourceDirectoryEntry->u1.s.NameOffset = HiiBinOffset;\r
-\r
- ResourceDirectoryString = (EFI_IMAGE_RESOURCE_DIRECTORY_STRING *) (HiiBinData + HiiBinOffset);\r
- ResourceDirectoryString->Length = 3;\r
- ResourceDirectoryString->String[0] =L'H';\r
- ResourceDirectoryString->String[1] =L'I';\r
- ResourceDirectoryString->String[2] =L'I';\r
- HiiBinOffset = HiiBinOffset + sizeof (ResourceDirectoryString->Length) + ResourceDirectoryString->Length * sizeof (ResourceDirectoryString->String[0]);\r
-\r
- ResourceDirectoryEntry->u2.OffsetToData = HiiBinOffset;\r
- ResourceDataEntry = (EFI_IMAGE_RESOURCE_DATA_ENTRY *) (HiiBinData + HiiBinOffset);\r
- HiiBinOffset += sizeof (EFI_IMAGE_RESOURCE_DATA_ENTRY);\r
- ResourceDataEntry->OffsetToData = OffsetToFile + HiiBinOffset;\r
-\r
- while (sscanf (RcString, "0x%X", &Data16) != EOF) {\r
- //\r
- // Convert the string data to the binary data.\r
- //\r
- *(UINT16 *)(HiiBinData + HiiBinOffset) = (UINT16) Data16;\r
- HiiBinOffset += 2;\r
- //\r
- // Jump to the next data.\r
- //\r
- RcString = RcString + 2 + 4;\r
- Index = Index + 2 + 4;\r
- //\r
- // Skip space and ',' character\r
- //\r
- while (Index < Size && *RcString != '\0' && (isspace (*RcString) || *RcString == ',')){\r
- RcString ++;\r
- Index ++;\r
+ ConversionNeeded = FALSE;\r
+ XipLength = 0;\r
+ FirstSectionOffset = *FileLength;\r
+ TotalNecessaryFileSize = 0;\r
+ SectionHeader = (EFI_IMAGE_SECTION_HEADER *) ((UINT8 *) &(PeHdr->Pe32.OptionalHeader) + PeHdr->Pe32.FileHeader.SizeOfOptionalHeader);\r
+ for (Index = 0; Index < PeHdr->Pe32.FileHeader.NumberOfSections; Index ++, SectionHeader ++) {\r
+ SectionSize = MAX (SectionHeader->Misc.VirtualSize, SectionHeader->SizeOfRawData);\r
+ TotalNecessaryFileSize += SectionSize;\r
+ if (SectionSize > 0) {\r
+ FirstSectionOffset = MIN (FirstSectionOffset, SectionHeader->VirtualAddress);\r
+ XipLength = MAX (XipLength, SectionHeader->VirtualAddress + SectionSize);\r
+ if (SectionHeader->VirtualAddress != SectionHeader->PointerToRawData) {\r
+ ConversionNeeded = TRUE;\r
+ }\r
+ }\r
+ if (SectionHeader->Misc.VirtualSize > SectionHeader->SizeOfRawData) {\r
+ ConversionNeeded = TRUE;\r
}\r
+ }\r
+\r
+ if (FirstSectionOffset < PeHdr->Pe32.OptionalHeader.SizeOfHeaders) {\r
//\r
- // '}' end character\r
+ // If one of the sections should be loaded to an offset overlapping with\r
+ // the executable header, then it cannot be made into an XIP image.\r
//\r
- if (*RcString == '}'|| Index == Size) {\r
- break;\r
- }\r
+ VerboseMsg ("PE/COFF conversion to XIP is impossible due to overlap");\r
+ VerboseMsg ("of section data with the executable header.");\r
+ return;\r
+ }\r
+\r
+ if (FirstSectionOffset == *FileLength) {\r
//\r
- // Check BinBuffer size\r
+ // If we never found a section with a non-zero size, then we\r
+ // skip the conversion.\r
//\r
- if (HiiBinOffset >= HiiBinSize) {\r
- HiiBinSize += 0x1000;\r
- HiiBinData = (UINT8 *) realloc (HiiBinData, HiiBinSize);\r
- //\r
- // Memory allocation is failure.\r
- //\r
- if (HiiBinData == NULL) {\r
- HiiBinSize = 0;\r
- break;\r
- }\r
- }\r
+ return;\r
}\r
\r
- if (HiiBinData != NULL) {\r
- HiiBinSize = HiiBinOffset;\r
- ResourceDataEntry->Size = HiiBinSize + OffsetToFile - ResourceDataEntry->OffsetToData;\r
+ TotalNecessaryFileSize += FirstSectionOffset;\r
+\r
+ if (!ConversionNeeded) {\r
+ return;\r
}\r
- \r
- return;\r
-}\r
\r
-VOID\r
-ScanSections(\r
- VOID\r
- )\r
-{\r
- UINT32 i;\r
- EFI_IMAGE_DOS_HEADER *DosHdr;\r
- EFI_IMAGE_OPTIONAL_HEADER_UNION *NtHdr;\r
- UINT32 CoffEntry;\r
-\r
- CoffEntry = 0;\r
- CoffOffset = 0;\r
-\r
- //\r
- // Coff file start with a DOS header.\r
- //\r
- CoffOffset = sizeof(EFI_IMAGE_DOS_HEADER) + 0x40;\r
- NtHdrOffset = CoffOffset;\r
- switch (Ehdr->e_machine) {\r
- case EM_386:\r
- case EM_ARM:\r
- CoffOffset += sizeof (EFI_IMAGE_NT_HEADERS32);\r
- break;\r
- case EM_X86_64:\r
- case EM_IA_64:\r
- CoffOffset += sizeof (EFI_IMAGE_NT_HEADERS64);\r
- break;\r
- default:\r
- VerboseMsg ("%s unknown e_machine type. Assume IA-32", (UINTN)Ehdr->e_machine);\r
- CoffOffset += sizeof (EFI_IMAGE_NT_HEADERS32);\r
- break;\r
- }\r
-\r
- TableOffset = CoffOffset;\r
- CoffOffset += CoffNbrSections * sizeof(EFI_IMAGE_SECTION_HEADER);\r
-\r
- //\r
- // First text sections.\r
- //\r
- CoffOffset = CoffAlign(CoffOffset);\r
- TextOffset = CoffOffset;\r
- for (i = 0; i < Ehdr->e_shnum; i++) {\r
- Elf_Shdr *shdr = GetShdrByIndex(i);\r
- if (IsTextShdr(shdr)) {\r
- if ((shdr->sh_addralign != 0) && (shdr->sh_addralign != 1)) {\r
- // the alignment field is valid\r
- if ((shdr->sh_addr & (shdr->sh_addralign - 1)) == 0) {\r
- // if the section address is aligned we must align PE/COFF \r
- CoffOffset = (CoffOffset + shdr->sh_addralign - 1) & ~(shdr->sh_addralign - 1);\r
- } else if ((shdr->sh_addr % shdr->sh_addralign) != (CoffOffset % shdr->sh_addralign)) {\r
- // ARM RVCT tools have behavior outside of the ELF specification to try \r
- // and make images smaller. If sh_addr is not aligned to sh_addralign \r
- // then the section needs to preserve sh_addr MOD sh_addralign. \r
- // Normally doing nothing here works great.\r
- Error (NULL, 0, 3000, "Invalid", "Unsupported section alignment.");\r
- }\r
- }\r
- \r
- /* Relocate entry. */\r
- if ((Ehdr->e_entry >= shdr->sh_addr) &&\r
- (Ehdr->e_entry < shdr->sh_addr + shdr->sh_size)) {\r
- CoffEntry = CoffOffset + Ehdr->e_entry - shdr->sh_addr;\r
- }\r
- CoffSectionsOffset[i] = CoffOffset;\r
- CoffOffset += shdr->sh_size;\r
- }\r
+ if (XipLength > (2 * TotalNecessaryFileSize)) {\r
+ VerboseMsg ("PE/COFF conversion to XIP appears to be larger than necessary.");\r
+ VerboseMsg ("The image linking process may have left unused memory ranges.");\r
}\r
\r
- if (Ehdr->e_machine != EM_ARM) {\r
- CoffOffset = CoffAlign(CoffOffset);\r
+ if (PeHdr->Pe32.FileHeader.PointerToSymbolTable != 0) {\r
+ //\r
+ // This field is obsolete and should be zero\r
+ //\r
+ PeHdr->Pe32.FileHeader.PointerToSymbolTable = 0;\r
}\r
\r
//\r
- // Then data sections.\r
+ // Allocate the extra space that we need to grow the image\r
//\r
- DataOffset = CoffOffset;\r
- for (i = 0; i < Ehdr->e_shnum; i++) {\r
- Elf_Shdr *shdr = GetShdrByIndex(i);\r
- if (IsDataShdr(shdr)) {\r
- if ((shdr->sh_addralign != 0) && (shdr->sh_addralign != 1)) {\r
- // the alignment field is valid\r
- if ((shdr->sh_addr & (shdr->sh_addralign - 1)) == 0) {\r
- // if the section address is aligned we must align PE/COFF \r
- CoffOffset = (CoffOffset + shdr->sh_addralign - 1) & ~(shdr->sh_addralign - 1);\r
- } else if ((shdr->sh_addr % shdr->sh_addralign) != (CoffOffset % shdr->sh_addralign)) {\r
- // ARM RVCT tools have behavior outside of the ELF specification to try \r
- // and make images smaller. If sh_addr is not aligned to sh_addralign \r
- // then the section needs to preserve sh_addr MOD sh_addralign. \r
- // Normally doing nothing here works great.\r
- Error (NULL, 0, 3000, "Invalid", "Unsupported section alignment.");\r
- }\r
- }\r
- CoffSectionsOffset[i] = CoffOffset;\r
- CoffOffset += shdr->sh_size;\r
- }\r
- }\r
- CoffOffset = CoffAlign(CoffOffset);\r
-\r
- //\r
- // The HII resource sections.\r
- //\r
- HiiRsrcOffset = CoffOffset;\r
- for (i = 0; i < Ehdr->e_shnum; i++) {\r
- Elf_Shdr *shdr = GetShdrByIndex(i);\r
- if (IsHiiRsrcShdr(shdr)) {\r
- if ((shdr->sh_addralign != 0) && (shdr->sh_addralign != 1)) {\r
- // the alignment field is valid\r
- if ((shdr->sh_addr & (shdr->sh_addralign - 1)) == 0) {\r
- // if the section address is aligned we must align PE/COFF \r
- CoffOffset = (CoffOffset + shdr->sh_addralign - 1) & ~(shdr->sh_addralign - 1);\r
- } else if ((shdr->sh_addr % shdr->sh_addralign) != (CoffOffset % shdr->sh_addralign)) {\r
- // ARM RVCT tools have behavior outside of the ELF specification to try \r
- // and make images smaller. If sh_addr is not aligned to sh_addralign \r
- // then the section needs to preserve sh_addr MOD sh_addralign. \r
- // Normally doing nothing here works great.\r
- Error (NULL, 0, 3000, "Invalid", "Unsupported section alignment.");\r
- }\r
- }\r
- GetBinaryHiiData ((CHAR8*)Ehdr + shdr->sh_offset, shdr->sh_size, HiiRsrcOffset);\r
- if (HiiBinSize != 0) {\r
- CoffOffset += HiiBinSize;\r
- CoffOffset = CoffAlign(CoffOffset);\r
- }\r
- break;\r
- }\r
+ XipFile = malloc (XipLength);\r
+ if (XipFile == NULL) {\r
+ Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");\r
+ return;\r
}\r
-\r
- RelocOffset = CoffOffset;\r
+ memset (XipFile, 0, XipLength);\r
\r
//\r
- // Allocate base Coff file. Will be expanded later for relocations.\r
+ // Copy the file headers\r
//\r
- CoffFile = (UINT8 *)malloc(CoffOffset);\r
- memset(CoffFile, 0, CoffOffset);\r
+ memcpy (XipFile, *FileBuffer, PeHdr->Pe32.OptionalHeader.SizeOfHeaders);\r
+\r
+ NewPeHdr = GetPeCoffHeader ((void *)XipFile);\r
+ if (NewPeHdr == NULL) {\r
+ free (XipFile);\r
+ return;\r
+ }\r
\r
//\r
- // Fill headers.\r
+ // Copy the section data over to the appropriate XIP offsets\r
//\r
- DosHdr = (EFI_IMAGE_DOS_HEADER *)CoffFile;\r
- DosHdr->e_magic = EFI_IMAGE_DOS_SIGNATURE;\r
- DosHdr->e_lfanew = NtHdrOffset;\r
+ SectionHeader = (EFI_IMAGE_SECTION_HEADER *) ((UINT8 *) &(NewPeHdr->Pe32.OptionalHeader) + NewPeHdr->Pe32.FileHeader.SizeOfOptionalHeader);\r
+ for (Index = 0; Index < PeHdr->Pe32.FileHeader.NumberOfSections; Index ++, SectionHeader ++) {\r
+ if (SectionHeader->SizeOfRawData > 0) {\r
+ memcpy (\r
+ XipFile + SectionHeader->VirtualAddress,\r
+ *FileBuffer + SectionHeader->PointerToRawData,\r
+ SectionHeader->SizeOfRawData\r
+ );\r
+ }\r
+ //\r
+ // Make the size of raw data in section header alignment.\r
+ //\r
+ SectionHeader->SizeOfRawData = (SectionHeader->Misc.VirtualSize + PeHdr->Pe32.OptionalHeader.FileAlignment - 1) & (~(PeHdr->Pe32.OptionalHeader.FileAlignment - 1));\r
+ SectionHeader->PointerToRawData = SectionHeader->VirtualAddress;\r
+ }\r
\r
- NtHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION*)(CoffFile + NtHdrOffset);\r
+ free (*FileBuffer);\r
+ *FileLength = XipLength;\r
+ *FileBuffer = XipFile;\r
\r
- NtHdr->Pe32.Signature = EFI_IMAGE_NT_SIGNATURE;\r
+ mIsConvertXip = TRUE;\r
+}\r
\r
- switch (Ehdr->e_machine) {\r
- case EM_386:\r
- NtHdr->Pe32.FileHeader.Machine = EFI_IMAGE_MACHINE_IA32;\r
- NtHdr->Pe32.OptionalHeader.Magic = EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC;\r
- break;\r
- case EM_X86_64:\r
- NtHdr->Pe32.FileHeader.Machine = EFI_IMAGE_MACHINE_X64;\r
- NtHdr->Pe32.OptionalHeader.Magic = EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC;\r
- break;\r
- case EM_IA_64:\r
- NtHdr->Pe32.FileHeader.Machine = EFI_IMAGE_MACHINE_IPF;\r
- NtHdr->Pe32.OptionalHeader.Magic = EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC;\r
- break;\r
- case EM_ARM:\r
- NtHdr->Pe32.FileHeader.Machine = EFI_IMAGE_MACHINE_ARMT;\r
- NtHdr->Pe32.OptionalHeader.Magic = EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC;\r
- break;\r
- default:\r
- VerboseMsg ("%s unknown e_machine type. Assume IA-32", (UINTN)Ehdr->e_machine);\r
- NtHdr->Pe32.FileHeader.Machine = EFI_IMAGE_MACHINE_IA32;\r
- NtHdr->Pe32.OptionalHeader.Magic = EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC;\r
- }\r
+UINT8 *\r
+CreateHiiResouceSectionHeader (\r
+ UINT32 *pSectionHeaderSize,\r
+ UINT32 HiiDataSize\r
+ )\r
+/*++\r
\r
- NtHdr->Pe32.FileHeader.NumberOfSections = CoffNbrSections;\r
- NtHdr->Pe32.FileHeader.TimeDateStamp = (UINT32) time(NULL);\r
- NtHdr->Pe32.FileHeader.PointerToSymbolTable = 0;\r
- NtHdr->Pe32.FileHeader.NumberOfSymbols = 0;\r
- NtHdr->Pe32.FileHeader.SizeOfOptionalHeader = sizeof(NtHdr->Pe32.OptionalHeader);\r
- NtHdr->Pe32.FileHeader.Characteristics = EFI_IMAGE_FILE_EXECUTABLE_IMAGE\r
- | EFI_IMAGE_FILE_LINE_NUMS_STRIPPED\r
- | EFI_IMAGE_FILE_LOCAL_SYMS_STRIPPED\r
- | EFI_IMAGE_FILE_32BIT_MACHINE;\r
+Routine Description:\r
\r
- NtHdr->Pe32.OptionalHeader.SizeOfCode = DataOffset - TextOffset;\r
- NtHdr->Pe32.OptionalHeader.SizeOfInitializedData = RelocOffset - DataOffset;\r
- NtHdr->Pe32.OptionalHeader.SizeOfUninitializedData = 0;\r
- NtHdr->Pe32.OptionalHeader.AddressOfEntryPoint = CoffEntry;\r
+ Create COFF resource section header\r
\r
- NtHdr->Pe32.OptionalHeader.BaseOfCode = TextOffset;\r
+Arguments:\r
\r
- NtHdr->Pe32.OptionalHeader.BaseOfData = DataOffset;\r
- NtHdr->Pe32.OptionalHeader.ImageBase = 0;\r
- NtHdr->Pe32.OptionalHeader.SectionAlignment = CoffAlignment;\r
- NtHdr->Pe32.OptionalHeader.FileAlignment = CoffAlignment;\r
- NtHdr->Pe32.OptionalHeader.SizeOfImage = 0;\r
+ pSectionHeaderSize - Pointer to section header size.\r
+ HiiDataSize - Size of the total HII data in section.\r
\r
- NtHdr->Pe32.OptionalHeader.SizeOfHeaders = TextOffset;\r
- NtHdr->Pe32.OptionalHeader.NumberOfRvaAndSizes = EFI_IMAGE_NUMBER_OF_DIRECTORY_ENTRIES;\r
+Returns:\r
+ The created section header buffer.\r
+\r
+--*/\r
+{\r
+ UINT32 HiiSectionHeaderSize;\r
+ UINT32 HiiSectionOffset;\r
+ UINT8 *HiiSectionHeader;\r
+ EFI_IMAGE_RESOURCE_DIRECTORY *ResourceDirectory;\r
+ EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY *TypeResourceDirectoryEntry;\r
+ EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY *NameResourceDirectoryEntry;\r
+ EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY *LanguageResourceDirectoryEntry;\r
+ EFI_IMAGE_RESOURCE_DIRECTORY_STRING *ResourceDirectoryString;\r
+ EFI_IMAGE_RESOURCE_DATA_ENTRY *ResourceDataEntry;\r
\r
//\r
- // Section headers.\r
+ // Calculate the total size for the resource header (include Type, Name and Language)\r
+ // then allocate memory for the resource header.\r
//\r
- if ((DataOffset - TextOffset) > 0) {\r
- CreateSectionHeader (".text", TextOffset, DataOffset - TextOffset,\r
- EFI_IMAGE_SCN_CNT_CODE\r
- | EFI_IMAGE_SCN_MEM_EXECUTE\r
- | EFI_IMAGE_SCN_MEM_READ);\r
- } else {\r
- // Don't make a section of size 0. \r
- NtHdr->Pe32.FileHeader.NumberOfSections--;\r
- }\r
-\r
- if ((HiiRsrcOffset - DataOffset) > 0) {\r
- CreateSectionHeader (".data", DataOffset, HiiRsrcOffset - DataOffset,\r
- EFI_IMAGE_SCN_CNT_INITIALIZED_DATA\r
- | EFI_IMAGE_SCN_MEM_WRITE\r
- | EFI_IMAGE_SCN_MEM_READ);\r
- } else {\r
- // Don't make a section of size 0. \r
- NtHdr->Pe32.FileHeader.NumberOfSections--;\r
+ HiiSectionHeaderSize = 3 * (sizeof (EFI_IMAGE_RESOURCE_DIRECTORY) + sizeof (EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY))\r
+ + 3 * (sizeof (UINT16) + 3 * sizeof (CHAR16))\r
+ + sizeof (EFI_IMAGE_RESOURCE_DATA_ENTRY);\r
+ HiiSectionHeader = malloc (HiiSectionHeaderSize);\r
+ if (HiiSectionHeader == NULL) {\r
+ Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");\r
+ return NULL;\r
}\r
+ memset (HiiSectionHeader, 0, HiiSectionHeaderSize);\r
\r
- if ((RelocOffset - HiiRsrcOffset) > 0) {\r
- CreateSectionHeader (".rsrc", HiiRsrcOffset, RelocOffset - HiiRsrcOffset,\r
- EFI_IMAGE_SCN_CNT_INITIALIZED_DATA\r
- | EFI_IMAGE_SCN_MEM_READ);\r
-\r
- NtHdr->Pe32.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE].Size = HiiBinSize;\r
- NtHdr->Pe32.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress = HiiRsrcOffset;\r
-\r
- memcpy(CoffFile + HiiRsrcOffset, HiiBinData, HiiBinSize);\r
- free (HiiBinData);\r
- HiiBinData = NULL;\r
- HiiBinSize = 0;\r
- } else {\r
- // Don't make a section of size 0. \r
- NtHdr->Pe32.FileHeader.NumberOfSections--;\r
- }\r
+ HiiSectionOffset = 0;\r
+ //\r
+ // Create Type entry\r
+ //\r
+ ResourceDirectory = (EFI_IMAGE_RESOURCE_DIRECTORY *) (HiiSectionHeader + HiiSectionOffset);\r
+ HiiSectionOffset += sizeof (EFI_IMAGE_RESOURCE_DIRECTORY);\r
+ ResourceDirectory->NumberOfNamedEntries = 1;\r
+ TypeResourceDirectoryEntry = (EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY *) (HiiSectionHeader + HiiSectionOffset);\r
+ HiiSectionOffset += sizeof (EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY);\r
+ TypeResourceDirectoryEntry->u1.s.NameIsString = 1;\r
+ TypeResourceDirectoryEntry->u2.s.DataIsDirectory = 1;\r
+ TypeResourceDirectoryEntry->u2.s.OffsetToDirectory = HiiSectionOffset;\r
+ //\r
+ // Create Name entry\r
+ //\r
+ ResourceDirectory = (EFI_IMAGE_RESOURCE_DIRECTORY *) (HiiSectionHeader + HiiSectionOffset);\r
+ HiiSectionOffset += sizeof (EFI_IMAGE_RESOURCE_DIRECTORY);\r
+ ResourceDirectory->NumberOfNamedEntries = 1;\r
+ NameResourceDirectoryEntry = (EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY *) (HiiSectionHeader + HiiSectionOffset);\r
+ HiiSectionOffset += sizeof (EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY);\r
+ NameResourceDirectoryEntry->u1.s.NameIsString = 1;\r
+ NameResourceDirectoryEntry->u2.s.DataIsDirectory = 1;\r
+ NameResourceDirectoryEntry->u2.s.OffsetToDirectory = HiiSectionOffset;\r
+ //\r
+ // Create Language entry\r
+ //\r
+ ResourceDirectory = (EFI_IMAGE_RESOURCE_DIRECTORY *) (HiiSectionHeader + HiiSectionOffset);\r
+ HiiSectionOffset += sizeof (EFI_IMAGE_RESOURCE_DIRECTORY);\r
+ ResourceDirectory->NumberOfNamedEntries = 1;\r
+ LanguageResourceDirectoryEntry = (EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY *) (HiiSectionHeader + HiiSectionOffset);\r
+ HiiSectionOffset += sizeof (EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY);\r
+ LanguageResourceDirectoryEntry->u1.s.NameIsString = 1;\r
+ //\r
+ // Create string entry for Type\r
+ //\r
+ TypeResourceDirectoryEntry->u1.s.NameOffset = HiiSectionOffset;\r
+ ResourceDirectoryString = (EFI_IMAGE_RESOURCE_DIRECTORY_STRING *) (HiiSectionHeader + HiiSectionOffset);\r
+ ResourceDirectoryString->Length = 3;\r
+ ResourceDirectoryString->String[0] = L'H';\r
+ ResourceDirectoryString->String[1] = L'I';\r
+ ResourceDirectoryString->String[2] = L'I';\r
+ HiiSectionOffset = HiiSectionOffset + sizeof (ResourceDirectoryString->Length) + ResourceDirectoryString->Length * sizeof (ResourceDirectoryString->String[0]);\r
+ //\r
+ // Create string entry for Name\r
+ //\r
+ NameResourceDirectoryEntry->u1.s.NameOffset = HiiSectionOffset;\r
+ ResourceDirectoryString = (EFI_IMAGE_RESOURCE_DIRECTORY_STRING *) (HiiSectionHeader + HiiSectionOffset);\r
+ ResourceDirectoryString->Length = 3;\r
+ ResourceDirectoryString->String[0] = L'E';\r
+ ResourceDirectoryString->String[1] = L'F';\r
+ ResourceDirectoryString->String[2] = L'I';\r
+ HiiSectionOffset = HiiSectionOffset + sizeof (ResourceDirectoryString->Length) + ResourceDirectoryString->Length * sizeof (ResourceDirectoryString->String[0]);\r
+ //\r
+ // Create string entry for Language\r
+ //\r
+ LanguageResourceDirectoryEntry->u1.s.NameOffset = HiiSectionOffset;\r
+ ResourceDirectoryString = (EFI_IMAGE_RESOURCE_DIRECTORY_STRING *) (HiiSectionHeader + HiiSectionOffset);\r
+ ResourceDirectoryString->Length = 3;\r
+ ResourceDirectoryString->String[0] = L'B';\r
+ ResourceDirectoryString->String[1] = L'I';\r
+ ResourceDirectoryString->String[2] = L'N';\r
+ HiiSectionOffset = HiiSectionOffset + sizeof (ResourceDirectoryString->Length) + ResourceDirectoryString->Length * sizeof (ResourceDirectoryString->String[0]);\r
+ //\r
+ // Create Leaf data\r
+ //\r
+ LanguageResourceDirectoryEntry->u2.OffsetToData = HiiSectionOffset;\r
+ ResourceDataEntry = (EFI_IMAGE_RESOURCE_DATA_ENTRY *) (HiiSectionHeader + HiiSectionOffset);\r
+ HiiSectionOffset += sizeof (EFI_IMAGE_RESOURCE_DATA_ENTRY);\r
+ ResourceDataEntry->OffsetToData = HiiSectionOffset;\r
+ ResourceDataEntry->Size = HiiDataSize;\r
\r
+ *pSectionHeaderSize = HiiSectionHeaderSize;\r
+ return HiiSectionHeader;\r
}\r
\r
-VOID\r
-WriteSections(\r
- int (*Filter)(Elf_Shdr *)\r
+EFI_STATUS\r
+RebaseImageRead (\r
+ IN VOID *FileHandle,\r
+ IN UINTN FileOffset,\r
+ IN OUT UINT32 *ReadSize,\r
+ OUT VOID *Buffer\r
)\r
-{\r
- UINT32 Idx;\r
- Elf_Shdr *SecShdr;\r
- UINT32 SecOffset;\r
-\r
- //\r
- // First: copy sections.\r
- //\r
- for (Idx = 0; Idx < Ehdr->e_shnum; Idx++) {\r
- Elf_Shdr *Shdr = GetShdrByIndex(Idx);\r
- if ((*Filter)(Shdr)) {\r
- switch (Shdr->sh_type) {\r
- case SHT_PROGBITS:\r
- /* Copy. */\r
- memcpy(CoffFile + CoffSectionsOffset[Idx],\r
- (UINT8*)Ehdr + Shdr->sh_offset,\r
- Shdr->sh_size);\r
- break;\r
- \r
- case SHT_NOBITS:\r
- memset(CoffFile + CoffSectionsOffset[Idx], 0, Shdr->sh_size);\r
- break;\r
- \r
- default:\r
- //\r
- // Ignore for unkown section type.\r
- //\r
- VerboseMsg ("%s unknown section type %x. We directly copy this section into Coff file", mInImageName, (unsigned)Shdr->sh_type);\r
- break;\r
- }\r
- }\r
- }\r
-\r
- //\r
- // Second: apply relocations.\r
- //\r
- for (Idx = 0; Idx < Ehdr->e_shnum; Idx++) {\r
- Elf_Shdr *RelShdr = GetShdrByIndex(Idx);\r
- if (RelShdr->sh_type != SHT_REL)\r
- continue;\r
- SecShdr = GetShdrByIndex(RelShdr->sh_info);\r
- SecOffset = CoffSectionsOffset[RelShdr->sh_info];\r
- if (RelShdr->sh_type == SHT_REL && (*Filter)(SecShdr)) {\r
- UINT32 RelIdx;\r
- Elf_Shdr *SymtabShdr = GetShdrByIndex(RelShdr->sh_link);\r
- UINT8 *Symtab = (UINT8*)Ehdr + SymtabShdr->sh_offset;\r
-\r
- for (RelIdx = 0; RelIdx < RelShdr->sh_size; RelIdx += RelShdr->sh_entsize) {\r
- Elf_Rel *Rel = (Elf_Rel *)((UINT8*)Ehdr + RelShdr->sh_offset + RelIdx);\r
- Elf_Sym *Sym = (Elf_Sym *)(Symtab + ELF_R_SYM(Rel->r_info) * SymtabShdr->sh_entsize);\r
- Elf_Shdr *SymShdr;\r
- UINT8 *Targ;\r
-\r
- if (Sym->st_shndx == SHN_UNDEF\r
- || Sym->st_shndx == SHN_ABS\r
- || Sym->st_shndx > Ehdr->e_shnum) {\r
- Error (NULL, 0, 3000, "Invalid", "%s bad symbol definition.", mInImageName);\r
- }\r
- SymShdr = GetShdrByIndex(Sym->st_shndx);\r
+/*++\r
\r
- //\r
- // Note: r_offset in a memory address.\r
- // Convert it to a pointer in the coff file.\r
- //\r
- Targ = CoffFile + SecOffset + (Rel->r_offset - SecShdr->sh_addr);\r
+Routine Description:\r
\r
- if (Ehdr->e_machine == EM_386) {\r
- switch (ELF_R_TYPE(Rel->r_info)) {\r
- case R_386_NONE:\r
- break;\r
- case R_386_32:\r
- //\r
- // Absolute relocation.\r
- //\r
- *(UINT32 *)Targ = *(UINT32 *)Targ - SymShdr->sh_addr\r
- + CoffSectionsOffset[Sym->st_shndx];\r
- break;\r
- case R_386_PC32:\r
- //\r
- // Relative relocation: Symbol - Ip + Addend\r
- //\r
- *(UINT32 *)Targ = *(UINT32 *)Targ\r
- + (CoffSectionsOffset[Sym->st_shndx] - SymShdr->sh_addr)\r
- - (SecOffset - SecShdr->sh_addr);\r
- break;\r
- default:\r
- Error (NULL, 0, 3000, "Invalid", "%s unhandled section type %x.", mInImageName, (unsigned) ELF_R_TYPE(Rel->r_info));\r
- }\r
- } else if (Ehdr->e_machine == EM_ARM) {\r
- switch (ELF32_R_TYPE(Rel->r_info)) {\r
- case R_ARM_RBASE: // No relocation - no action required\r
- case R_ARM_PC24: // PC-relative relocations don't require modification\r
- case R_ARM_XPC25: // PC-relative relocations don't require modification\r
- break;\r
- case R_ARM_ABS32:\r
- case R_ARM_RABS32:\r
- //\r
- // Absolute relocation.\r
- //\r
- *(UINT32 *)Targ = *(UINT32 *)Targ - SymShdr->sh_addr + CoffSectionsOffset[Sym->st_shndx];\r
- break;\r
- default:\r
- Error (NULL, 0, 3000, "Invalid", "%s unhandled section type %x.", mInImageName, (unsigned) ELF32_R_TYPE(Rel->r_info));\r
- }\r
- }\r
- }\r
- }\r
- }\r
-}\r
+ Support routine for the PE/COFF Loader that reads a buffer from a PE/COFF file\r
\r
-VOID\r
-CoffAddFixupEntry(\r
- UINT16 Val\r
- )\r
-{\r
- *CoffEntryRel = Val;\r
- CoffEntryRel++;\r
- CoffBaseRel->SizeOfBlock += 2;\r
- CoffOffset += 2;\r
-}\r
+Arguments:\r
\r
-VOID\r
-CoffAddFixup(\r
- UINT32 Offset,\r
- UINT8 Type\r
- )\r
-{\r
- if (CoffBaseRel == NULL\r
- || CoffBaseRel->VirtualAddress != (Offset & ~0xfff)) {\r
- if (CoffBaseRel != NULL) {\r
- //\r
- // Add a null entry (is it required ?)\r
- //\r
- CoffAddFixupEntry (0);\r
- //\r
- // Pad for alignment.\r
- //\r
- if (CoffOffset % 4 != 0)\r
- CoffAddFixupEntry (0);\r
- }\r
+ FileHandle - The handle to the PE/COFF file\r
\r
- CoffFile = realloc\r
- (CoffFile,\r
- CoffOffset + sizeof(EFI_IMAGE_BASE_RELOCATION) + 2*0x1000);\r
- memset(CoffFile + CoffOffset, 0,\r
- sizeof(EFI_IMAGE_BASE_RELOCATION) + 2*0x1000);\r
+ FileOffset - The offset, in bytes, into the file to read\r
\r
- CoffBaseRel = (EFI_IMAGE_BASE_RELOCATION*)(CoffFile + CoffOffset);\r
- CoffBaseRel->VirtualAddress = Offset & ~0xfff;\r
- CoffBaseRel->SizeOfBlock = sizeof(EFI_IMAGE_BASE_RELOCATION);\r
+ ReadSize - The number of bytes to read from the file starting at FileOffset\r
\r
- CoffEntryRel = (UINT16 *)(CoffBaseRel + 1);\r
- CoffOffset += sizeof(EFI_IMAGE_BASE_RELOCATION);\r
- }\r
+ Buffer - A pointer to the buffer to read the data into.\r
\r
- //\r
- // Fill the entry.\r
- //\r
- CoffAddFixupEntry((UINT16) ((Type << 12) | (Offset & 0xfff)));\r
-}\r
+Returns:\r
\r
+ EFI_SUCCESS - ReadSize bytes of data were read into Buffer from the PE/COFF file starting at FileOffset\r
\r
-Elf_Phdr *\r
-GetPhdrByIndex (\r
- UINT32 num\r
- )\r
+--*/\r
{\r
- if (num >= Ehdr->e_phnum) {\r
- return NULL;\r
+ CHAR8 *Destination8;\r
+ CHAR8 *Source8;\r
+ UINT32 Length;\r
+\r
+ Destination8 = Buffer;\r
+ Source8 = (CHAR8 *) ((UINTN) FileHandle + FileOffset);\r
+ Length = *ReadSize;\r
+ while (Length--) {\r
+ *(Destination8++) = *(Source8++);\r
}\r
- \r
- return (Elf32_Phdr *)((UINT8*)gPhdrBase + num * Ehdr->e_phentsize);\r
-}\r
\r
+ return EFI_SUCCESS;\r
+}\r
\r
-VOID\r
-WriteRelocations(\r
- VOID\r
+EFI_STATUS\r
+SetAddressToSectionHeader (\r
+ IN CHAR8 *FileName,\r
+ IN OUT UINT8 *FileBuffer,\r
+ IN UINT64 NewPe32BaseAddress\r
)\r
-{\r
- UINT32 Index;\r
- EFI_IMAGE_OPTIONAL_HEADER_UNION *NtHdr;\r
- EFI_IMAGE_DATA_DIRECTORY *Dir;\r
- BOOLEAN FoundRelocations;\r
- Elf_Dyn *Dyn;\r
- Elf_Rel *Rel;\r
- UINTN RelElementSize;\r
- UINTN RelSize;\r
- UINTN RelOffset;\r
- UINTN K;\r
- UINT8 *Targ;\r
- Elf32_Phdr *DynamicSegment;\r
- Elf32_Phdr *TargetSegment;\r
-\r
- for (Index = 0, FoundRelocations = FALSE; Index < Ehdr->e_shnum; Index++) {\r
- Elf_Shdr *RelShdr = GetShdrByIndex(Index);\r
- if (RelShdr->sh_type == SHT_REL) {\r
- Elf_Shdr *SecShdr = GetShdrByIndex(RelShdr->sh_info);\r
- if (IsTextShdr(SecShdr) || IsDataShdr(SecShdr)) {\r
- UINT32 RelIdx;\r
- FoundRelocations = TRUE;\r
- for (RelIdx = 0; RelIdx < RelShdr->sh_size; RelIdx += RelShdr->sh_entsize) {\r
- Elf_Rel *Rel = (Elf_Rel *)\r
- ((UINT8*)Ehdr + RelShdr->sh_offset + RelIdx);\r
- \r
- if (Ehdr->e_machine == EM_386) { \r
- switch (ELF_R_TYPE(Rel->r_info)) {\r
- case R_386_NONE:\r
- case R_386_PC32:\r
- break;\r
- case R_386_32:\r
- CoffAddFixup(CoffSectionsOffset[RelShdr->sh_info]\r
- + (Rel->r_offset - SecShdr->sh_addr),\r
- EFI_IMAGE_REL_BASED_HIGHLOW);\r
- break;\r
- default:\r
- Error (NULL, 0, 3000, "Invalid", "%s unhandled section type %x.", mInImageName, (unsigned) ELF_R_TYPE(Rel->r_info));\r
- }\r
- } else if (Ehdr->e_machine == EM_ARM) {\r
- switch (ELF32_R_TYPE(Rel->r_info)) {\r
- case R_ARM_RBASE:\r
- case R_ARM_PC24:\r
- case R_ARM_XPC25:\r
- break;\r
- case R_ARM_ABS32:\r
- case R_ARM_RABS32:\r
- CoffAddFixup (\r
- CoffSectionsOffset[RelShdr->sh_info]\r
- + (Rel->r_offset - SecShdr->sh_addr),\r
- EFI_IMAGE_REL_BASED_HIGHLOW\r
- );\r
- break;\r
- default:\r
- Error (NULL, 0, 3000, "Invalid", "%s unhandled section type %x.", mInImageName, (unsigned) ELF32_R_TYPE(Rel->r_info));\r
- }\r
- } else {\r
- Error (NULL, 0, 3000, "Not Supported", "This tool does not support relocations for ELF with e_machine %u (processor type).", (unsigned) Ehdr->e_machine);\r
- }\r
- }\r
- }\r
- }\r
- }\r
+/*++\r
\r
- if (!FoundRelocations && (Ehdr->e_machine == EM_ARM)) {\r
- /* Try again, but look for PT_DYNAMIC instead of SHT_REL */\r
+Routine Description:\r
\r
- for (Index = 0; Index < Ehdr->e_phnum; Index++) {\r
- RelElementSize = 0;\r
- RelSize = 0;\r
- RelOffset = 0;\r
+ Set new base address into the section header of PeImage\r
\r
- DynamicSegment = GetPhdrByIndex (Index);\r
+Arguments:\r
\r
- if (DynamicSegment->p_type == PT_DYNAMIC) {\r
- Dyn = (Elf32_Dyn *) ((UINT8 *)Ehdr + DynamicSegment->p_offset);\r
+ FileName - Name of file\r
+ FileBuffer - Pointer to PeImage.\r
+ NewPe32BaseAddress - New Base Address for PE image.\r
\r
- while (Dyn->d_tag != DT_NULL) {\r
- switch (Dyn->d_tag) {\r
- case DT_REL:\r
- RelOffset = Dyn->d_un.d_val;\r
- break;\r
-\r
- case DT_RELSZ:\r
- RelSize = Dyn->d_un.d_val;\r
- break;\r
+Returns:\r
\r
- case DT_RELENT:\r
- RelElementSize = Dyn->d_un.d_val;\r
- break;\r
- }\r
- Dyn++;\r
- }\r
- if (( RelOffset == 0 ) || ( RelSize == 0 ) || ( RelElementSize == 0 )) {\r
- Error (NULL, 0, 3000, "Invalid", "%s bad ARM dynamic relocations.", mInImageName);\r
- }\r
+ EFI_SUCCESS Set new base address into this image successfully.\r
\r
- for (K = 0; K < RelSize; K += RelElementSize) {\r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;\r
+ UINTN Index;\r
+ EFI_IMAGE_OPTIONAL_HEADER_UNION *ImgHdr;\r
+ EFI_IMAGE_SECTION_HEADER *SectionHeader;\r
\r
- Rel = (Elf32_Rel *) ((UINT8 *) Ehdr + DynamicSegment->p_offset + RelOffset + K);\r
+ //\r
+ // Initialize context\r
+ //\r
+ memset (&ImageContext, 0, sizeof (ImageContext));\r
+ ImageContext.Handle = (VOID *) FileBuffer;\r
+ ImageContext.ImageRead = (PE_COFF_LOADER_READ_FILE) RebaseImageRead;\r
+ Status = PeCoffLoaderGetImageInfo (&ImageContext);\r
+ if (EFI_ERROR (Status)) {\r
+ Error (NULL, 0, 3000, "Invalid", "The input PeImage %s is not valid", FileName);\r
+ return Status;\r
+ }\r
\r
- switch (ELF32_R_TYPE (Rel->r_info)) {\r
- case R_ARM_RBASE:\r
- break;\r
- case R_ARM_RABS32:\r
- TargetSegment = GetPhdrByIndex (ELF32_R_SYM (Rel->r_info) - 1);\r
+ if (ImageContext.RelocationsStripped) {\r
+ Error (NULL, 0, 3000, "Invalid", "The input PeImage %s has no relocation to be fixed up", FileName);\r
+ return Status;\r
+ }\r
\r
- // Note: r_offset in a memory address. Convert it to a pointer in the coff file.\r
- Targ = CoffFile + CoffSectionsOffset[ ELF32_R_SYM( Rel->r_info ) ] + Rel->r_offset - TargetSegment->p_vaddr;\r
+ //\r
+ // Get PeHeader pointer\r
+ //\r
+ ImgHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)(FileBuffer + ImageContext.PeCoffHeaderOffset);\r
\r
- *(UINT32 *)Targ = *(UINT32 *)Targ + CoffSectionsOffset [ELF32_R_SYM( Rel->r_info )];\r
+ //\r
+ // Get section header list\r
+ //\r
+ SectionHeader = (EFI_IMAGE_SECTION_HEADER *) (\r
+ (UINTN) ImgHdr +\r
+ sizeof (UINT32) +\r
+ sizeof (EFI_IMAGE_FILE_HEADER) +\r
+ ImgHdr->Pe32.FileHeader.SizeOfOptionalHeader\r
+ );\r
\r
- CoffAddFixup (CoffSectionsOffset[ELF32_R_SYM (Rel->r_info)] + (Rel->r_offset - TargetSegment->p_vaddr), EFI_IMAGE_REL_BASED_HIGHLOW);\r
- break;\r
- default:\r
- Error (NULL, 0, 3000, "Invalid", "%s bad ARM dynamic relocations, unkown type.", mInImageName);\r
- }\r
- }\r
- break;\r
- }\r
+ //\r
+ // Set base address into the first section header that doesn't point to code section.\r
+ //\r
+ for (Index = 0; Index < ImgHdr->Pe32.FileHeader.NumberOfSections; Index ++, SectionHeader ++) {\r
+ if ((SectionHeader->Characteristics & EFI_IMAGE_SCN_CNT_CODE) == 0) {\r
+ *(UINT64 *) &SectionHeader->PointerToRelocations = NewPe32BaseAddress;\r
+ break;\r
}\r
}\r
\r
//\r
- // Pad by adding empty entries.\r
+ // BaseAddress is set to section header.\r
//\r
- while (CoffOffset & (CoffAlignment - 1)) {\r
- CoffAddFixupEntry(0);\r
- }\r
+ return EFI_SUCCESS;\r
+}\r
\r
+EFI_STATUS\r
+RebaseImage (\r
+ IN CHAR8 *FileName,\r
+ IN OUT UINT8 *FileBuffer,\r
+ IN UINT64 NewPe32BaseAddress\r
+ )\r
+/*++\r
\r
- NtHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)(CoffFile + NtHdrOffset);\r
- Dir = &NtHdr->Pe32.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC];\r
- Dir->Size = CoffOffset - RelocOffset;\r
- if (Dir->Size == 0) {\r
- // If no relocations, null out the directory entry and don't add the .reloc section\r
- Dir->VirtualAddress = 0;\r
- NtHdr->Pe32.FileHeader.NumberOfSections--;\r
- } else {\r
- Dir->VirtualAddress = RelocOffset;\r
- CreateSectionHeader (".reloc", RelocOffset, CoffOffset - RelocOffset,\r
- EFI_IMAGE_SCN_CNT_INITIALIZED_DATA\r
- | EFI_IMAGE_SCN_MEM_DISCARDABLE\r
- | EFI_IMAGE_SCN_MEM_READ);\r
- }\r
+Routine Description:\r
\r
-}\r
+ Set new base address into PeImage, and fix up PeImage based on new address.\r
\r
-VOID\r
-WriteDebug(\r
- VOID\r
- )\r
-{\r
- UINT32 Len;\r
- UINT32 DebugOffset;\r
- EFI_IMAGE_OPTIONAL_HEADER_UNION *NtHdr;\r
- EFI_IMAGE_DATA_DIRECTORY *DataDir;\r
- EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *Dir;\r
- EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY *Nb10;\r
-\r
- Len = strlen(mInImageName) + 1;\r
- DebugOffset = CoffOffset;\r
-\r
- CoffOffset += sizeof(EFI_IMAGE_DEBUG_DIRECTORY_ENTRY)\r
- + sizeof(EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY)\r
- + Len;\r
- CoffOffset = CoffAlign(CoffOffset);\r
-\r
- CoffFile = realloc(CoffFile, CoffOffset);\r
- memset(CoffFile + DebugOffset, 0, CoffOffset - DebugOffset);\r
-\r
- Dir = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY*)(CoffFile + DebugOffset);\r
- Dir->Type = EFI_IMAGE_DEBUG_TYPE_CODEVIEW;\r
- Dir->SizeOfData = sizeof(EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY) + Len;\r
- Dir->RVA = DebugOffset + sizeof(EFI_IMAGE_DEBUG_DIRECTORY_ENTRY);\r
- Dir->FileOffset = DebugOffset + sizeof(EFI_IMAGE_DEBUG_DIRECTORY_ENTRY);\r
-\r
- Nb10 = (EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY*)(Dir + 1);\r
- Nb10->Signature = CODEVIEW_SIGNATURE_NB10;\r
- strcpy ((char *)(Nb10 + 1), mInImageName);\r
-\r
-\r
- NtHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)(CoffFile + NtHdrOffset);\r
- DataDir = &NtHdr->Pe32.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG];\r
- DataDir->VirtualAddress = DebugOffset;\r
- DataDir->Size = CoffOffset - DebugOffset;\r
- if (DataDir->Size == 0) {\r
- // If no debug, null out the directory entry and don't add the .debug section\r
- DataDir->VirtualAddress = 0;\r
- NtHdr->Pe32.FileHeader.NumberOfSections--;\r
- } else {\r
- DataDir->VirtualAddress = DebugOffset;\r
- CreateSectionHeader (".debug", DebugOffset, CoffOffset - DebugOffset,\r
- EFI_IMAGE_SCN_CNT_INITIALIZED_DATA\r
- | EFI_IMAGE_SCN_MEM_DISCARDABLE\r
- | EFI_IMAGE_SCN_MEM_READ);\r
+Arguments:\r
\r
- }\r
-}\r
+ FileName - Name of file\r
+ FileBuffer - Pointer to PeImage.\r
+ NewPe32BaseAddress - New Base Address for PE image.\r
\r
-VOID\r
-ConvertElf (\r
- UINT8 **FileBuffer,\r
- UINT32 *FileLength\r
- )\r
-{\r
- EFI_IMAGE_OPTIONAL_HEADER_UNION *NtHdr;\r
+Returns:\r
\r
- //\r
- // Check header, read section table.\r
- //\r
- Ehdr = (Elf32_Ehdr*)*FileBuffer;\r
- if (!CheckElfHeader())\r
- return;\r
+ EFI_INVALID_PARAMETER - BaseAddress is not valid.\r
+ EFI_SUCCESS - Update PeImage is correctly.\r
+\r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;\r
+ UINTN Index;\r
+ EFI_IMAGE_OPTIONAL_HEADER_UNION *ImgHdr;\r
+ UINT8 *MemoryImagePointer;\r
+ EFI_IMAGE_SECTION_HEADER *SectionHeader;\r
\r
- VerboseMsg ("Check Efl Image Header");\r
//\r
- // Compute sections new address.\r
+ // Initialize context\r
//\r
- \r
- ScanSections();\r
+ memset (&ImageContext, 0, sizeof (ImageContext));\r
+ ImageContext.Handle = (VOID *) FileBuffer;\r
+ ImageContext.ImageRead = (PE_COFF_LOADER_READ_FILE) RebaseImageRead;\r
+ Status = PeCoffLoaderGetImageInfo (&ImageContext);\r
+ if (EFI_ERROR (Status)) {\r
+ Error (NULL, 0, 3000, "Invalid", "The input PeImage %s is not valid", FileName);\r
+ return Status;\r
+ }\r
\r
- VerboseMsg ("Compute sections new address.");\r
+ if (ImageContext.RelocationsStripped) {\r
+ Error (NULL, 0, 3000, "Invalid", "The input PeImage %s has no relocation to be fixed up", FileName);\r
+ return Status;\r
+ }\r
\r
//\r
- // Write and relocate sections.\r
+ // Get PeHeader pointer\r
//\r
- WriteSections(IsTextShdr);\r
- WriteSections(IsDataShdr);\r
- VerboseMsg ("Write and relocate sections.");\r
+ ImgHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)(FileBuffer + ImageContext.PeCoffHeaderOffset);\r
\r
//\r
- // Translate and write relocations.\r
+ // Load and Relocate Image Data\r
//\r
- WriteRelocations();\r
- VerboseMsg ("Translate and write relocations.");\r
+ MemoryImagePointer = (UINT8 *) malloc ((UINTN) ImageContext.ImageSize + ImageContext.SectionAlignment);\r
+ if (MemoryImagePointer == NULL) {\r
+ Error (NULL, 0, 4001, "Resource", "memory cannot be allocated on rebase of %s", FileName);\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+ memset ((VOID *) MemoryImagePointer, 0, (UINTN) ImageContext.ImageSize + ImageContext.SectionAlignment);\r
+ ImageContext.ImageAddress = ((UINTN) MemoryImagePointer + ImageContext.SectionAlignment - 1) & (~((INT64)ImageContext.SectionAlignment - 1));\r
+\r
+ Status = PeCoffLoaderLoadImage (&ImageContext);\r
+ if (EFI_ERROR (Status)) {\r
+ Error (NULL, 0, 3000, "Invalid", "LocateImage() call failed on rebase of %s", FileName);\r
+ free ((VOID *) MemoryImagePointer);\r
+ return Status;\r
+ }\r
+\r
+ ImageContext.DestinationAddress = NewPe32BaseAddress;\r
+ Status = PeCoffLoaderRelocateImage (&ImageContext);\r
+ if (EFI_ERROR (Status)) {\r
+ Error (NULL, 0, 3000, "Invalid", "RelocateImage() call failed on rebase of %s", FileName);\r
+ free ((VOID *) MemoryImagePointer);\r
+ return Status;\r
+ }\r
\r
//\r
- // Write debug info.\r
+ // Copy Relocated data to raw image file.\r
//\r
- WriteDebug();\r
- VerboseMsg ("Write debug info.");\r
+ SectionHeader = (EFI_IMAGE_SECTION_HEADER *) (\r
+ (UINTN) ImgHdr +\r
+ sizeof (UINT32) +\r
+ sizeof (EFI_IMAGE_FILE_HEADER) +\r
+ ImgHdr->Pe32.FileHeader.SizeOfOptionalHeader\r
+ );\r
+\r
+ for (Index = 0; Index < ImgHdr->Pe32.FileHeader.NumberOfSections; Index ++, SectionHeader ++) {\r
+ CopyMem (\r
+ FileBuffer + SectionHeader->PointerToRawData,\r
+ (VOID*) (UINTN) (ImageContext.ImageAddress + SectionHeader->VirtualAddress),\r
+ SectionHeader->SizeOfRawData\r
+ );\r
+ }\r
\r
- NtHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)(CoffFile + NtHdrOffset);\r
- NtHdr->Pe32.OptionalHeader.SizeOfImage = CoffOffset;\r
+ free ((VOID *) MemoryImagePointer);\r
\r
//\r
- // Replace.\r
+ // Update Image Base Address\r
//\r
- free(*FileBuffer);\r
- *FileBuffer = CoffFile;\r
- *FileLength = CoffOffset;\r
+ if (ImgHdr->Pe32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
+ ImgHdr->Pe32.OptionalHeader.ImageBase = (UINT32) NewPe32BaseAddress;\r
+ } else if (ImgHdr->Pe32Plus.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) {\r
+ ImgHdr->Pe32Plus.OptionalHeader.ImageBase = NewPe32BaseAddress;\r
+ } else {\r
+ Error (NULL, 0, 3000, "Invalid", "unknown PE magic signature %X in PE32 image %s",\r
+ ImgHdr->Pe32.OptionalHeader.Magic,\r
+ FileName\r
+ );\r
+ return EFI_ABORTED;\r
+ }\r
\r
//\r
- // Free memory space\r
+ // Set new base address into section header\r
//\r
- if (CoffSectionsOffset != NULL) {\r
- free (CoffSectionsOffset);\r
- }\r
+ Status = SetAddressToSectionHeader (FileName, FileBuffer, NewPe32BaseAddress);\r
+\r
+ return Status;\r
}\r
\r
int\r
char *OutImageName;\r
char *ModuleType;\r
CHAR8 *TimeStamp;\r
- UINT32 OutImageType;\r
FILE *fpIn;\r
FILE *fpOut;\r
FILE *fpInOut;\r
UINT32 FileLength;\r
UINT8 *OutputFileBuffer;\r
UINT32 OutputFileLength;\r
+ UINT8 *InputFileBuffer;\r
+ UINT32 InputFileLength;\r
RUNTIME_FUNCTION *RuntimeFunction;\r
UNWIND_INFO *UnwindInfo;\r
STATUS Status;\r
BOOLEAN ReplaceFlag;\r
BOOLEAN KeepExceptionTableFlag;\r
+ BOOLEAN KeepOptionalHeaderFlag;\r
BOOLEAN KeepZeroPendingFlag;\r
UINT64 LogLevel;\r
EFI_TE_IMAGE_HEADER TEImageHeader;\r
EFI_HII_PACKAGE_LIST_HEADER HiiPackageListHeader;\r
EFI_HII_PACKAGE_HEADER HiiPackageHeader;\r
EFI_IFR_FORM_SET IfrFormSet;\r
- UINT8 NumberOfFormPacakge;\r
+ UINT8 NumberOfFormPackage;\r
EFI_HII_PACKAGE_HEADER EndPackage;\r
+ UINT32 HiiSectionHeaderSize;\r
+ UINT8 *HiiSectionHeader;\r
+ UINT64 NewBaseAddress;\r
+ BOOLEAN NegativeAddr;\r
+ FILE *ReportFile;\r
+ CHAR8 *ReportFileName;\r
+ UINTN FileLen;\r
+ time_t InputFileTime;\r
+ time_t OutputFileTime;\r
+ struct stat Stat_Buf;\r
\r
SetUtilityName (UTILITY_NAME);\r
\r
//\r
// Assign to fix compile warning\r
//\r
+ FileLen = 0;\r
InputFileNum = 0;\r
InputFileName = NULL;\r
mInImageName = NULL;\r
OutImageName = NULL;\r
ModuleType = NULL;\r
- OutImageType = FW_DUMMY_IMAGE;\r
Type = 0;\r
Status = STATUS_SUCCESS;\r
FileBuffer = NULL;\r
LogLevel = 0;\r
OutputFileBuffer = NULL;\r
OutputFileLength = 0;\r
+ InputFileBuffer = NULL;\r
+ InputFileLength = 0;\r
Optional32 = NULL;\r
Optional64 = NULL;\r
KeepExceptionTableFlag = FALSE;\r
+ KeepOptionalHeaderFlag = FALSE;\r
KeepZeroPendingFlag = FALSE;\r
- NumberOfFormPacakge = 0;\r
+ NumberOfFormPackage = 0;\r
HiiPackageListBuffer = NULL;\r
HiiPackageDataPointer = NULL;\r
EndPackage.Length = sizeof (EFI_HII_PACKAGE_HEADER);\r
EndPackage.Type = EFI_HII_PACKAGE_END;\r
memset (&HiiPackageListGuid, 0, sizeof (HiiPackageListGuid));\r
+ HiiSectionHeaderSize = 0;\r
+ HiiSectionHeader = NULL;\r
+ NewBaseAddress = 0;\r
+ NegativeAddr = FALSE;\r
+ InputFileTime = 0;\r
+ OutputFileTime = 0;\r
\r
if (argc == 1) {\r
Error (NULL, 0, 1001, "Missing options", "No input options.");\r
goto Finish;\r
}\r
ModuleType = argv[1];\r
- if (OutImageType != FW_TE_IMAGE) {\r
- OutImageType = FW_EFI_IMAGE;\r
+ if (mOutImageType != FW_TE_IMAGE) {\r
+ mOutImageType = FW_EFI_IMAGE;\r
}\r
argc -= 2;\r
argv += 2;\r
}\r
\r
if ((stricmp (argv[0], "-l") == 0) || (stricmp (argv[0], "--stripped") == 0)) {\r
- OutImageType = FW_RELOC_STRIPEED_IMAGE;\r
+ mOutImageType = FW_RELOC_STRIPEED_IMAGE;\r
argc --;\r
argv ++;\r
continue;\r
}\r
\r
if ((stricmp (argv[0], "-c") == 0) || (stricmp (argv[0], "--acpi") == 0)) {\r
- OutImageType = FW_ACPI_IMAGE;\r
+ mOutImageType = FW_ACPI_IMAGE;\r
argc --;\r
argv ++;\r
continue;\r
}\r
\r
if ((stricmp (argv[0], "-t") == 0) || (stricmp (argv[0], "--terse") == 0)) {\r
- OutImageType = FW_TE_IMAGE;\r
+ mOutImageType = FW_TE_IMAGE;\r
argc --;\r
argv ++;\r
continue;\r
}\r
\r
if ((stricmp (argv[0], "-u") == 0) || (stricmp (argv[0], "--dump") == 0)) {\r
- OutImageType = DUMP_TE_HEADER;\r
+ mOutImageType = DUMP_TE_HEADER;\r
argc --;\r
argv ++;\r
continue;\r
}\r
\r
if ((stricmp (argv[0], "-b") == 0) || (stricmp (argv[0], "--exe2bin") == 0)) {\r
- OutImageType = FW_BIN_IMAGE;\r
+ mOutImageType = FW_BIN_IMAGE;\r
argc --;\r
argv ++;\r
continue;\r
}\r
\r
if ((stricmp (argv[0], "-z") == 0) || (stricmp (argv[0], "--zero") == 0)) {\r
- OutImageType = FW_ZERO_DEBUG_IMAGE;\r
+ mOutImageType = FW_ZERO_DEBUG_IMAGE;\r
argc --;\r
argv ++;\r
continue;\r
}\r
\r
if ((stricmp (argv[0], "-s") == 0) || (stricmp (argv[0], "--stamp") == 0)) {\r
- OutImageType = FW_SET_STAMP_IMAGE;\r
+ mOutImageType = FW_SET_STAMP_IMAGE;\r
if (argv[1] == NULL || argv[1][0] == '-') {\r
Error (NULL, 0, 1003, "Invalid option value", "time stamp is missing for -s option");\r
goto Finish;\r
continue;\r
}\r
\r
+ if (stricmp(argv[0], "--keepoptionalheader") == 0) {\r
+ KeepOptionalHeaderFlag = TRUE;\r
+ argc--;\r
+ argv++;\r
+ continue;\r
+ }\r
+\r
if (stricmp (argv[0], "--keepzeropending") == 0) {\r
KeepZeroPendingFlag = TRUE;\r
argc --;\r
}\r
\r
if ((stricmp (argv[0], "-m") == 0) || (stricmp (argv[0], "--mcifile") == 0)) {\r
- OutImageType = FW_MCI_IMAGE;\r
+ mOutImageType = FW_MCI_IMAGE;\r
argc --;\r
argv ++;\r
continue;\r
}\r
\r
if ((stricmp (argv[0], "-j") == 0) || (stricmp (argv[0], "--join") == 0)) {\r
- OutImageType = FW_MERGE_IMAGE;\r
+ mOutImageType = FW_MERGE_IMAGE;\r
argc --;\r
argv ++;\r
continue;\r
continue;\r
}\r
\r
+ if ((stricmp (argv[0], "--rebase") == 0)) {\r
+ if (argv[1][0] == '-') {\r
+ NegativeAddr = TRUE;\r
+ Status = AsciiStringToUint64 (argv[1] + 1, FALSE, &Temp64);\r
+ } else {\r
+ NegativeAddr = FALSE;\r
+ Status = AsciiStringToUint64 (argv[1], FALSE, &Temp64);\r
+ }\r
+ if (Status != EFI_SUCCESS) {\r
+ Error (NULL, 0, 1003, "Invalid option value", "%s = %s", argv[0], argv[1]);\r
+ goto Finish;\r
+ }\r
+ mOutImageType = FW_REBASE_IMAGE;\r
+ NewBaseAddress = (UINT64) Temp64;\r
+ argc -= 2;\r
+ argv += 2;\r
+ continue;\r
+ }\r
+\r
+ if ((stricmp (argv[0], "--address") == 0)) {\r
+ if (argv[1][0] == '-') {\r
+ NegativeAddr = TRUE;\r
+ Status = AsciiStringToUint64 (argv[1] + 1, FALSE, &Temp64);\r
+ } else {\r
+ NegativeAddr = FALSE;\r
+ Status = AsciiStringToUint64 (argv[1], FALSE, &Temp64);\r
+ }\r
+ if (Status != EFI_SUCCESS) {\r
+ Error (NULL, 0, 1003, "Invalid option value", "%s = %s", argv[0], argv[1]);\r
+ goto Finish;\r
+ }\r
+ mOutImageType = FW_SET_ADDRESS_IMAGE;\r
+ NewBaseAddress = (UINT64) Temp64;\r
+ argc -= 2;\r
+ argv += 2;\r
+ continue;\r
+ }\r
+\r
if ((stricmp (argv[0], "-p") == 0) || (stricmp (argv[0], "--pad") == 0)) {\r
if (AsciiStringToUint64 (argv[1], FALSE, &Temp64) != EFI_SUCCESS) {\r
Error (NULL, 0, 1003, "Invalid option value", "%s = %s", argv[0], argv[1]);\r
goto Finish;\r
}\r
if (LogLevel > 9) {\r
- Error (NULL, 0, 1003, "Invalid option value", "Debug Level range is 0-9, currnt input level is %d", (int) LogLevel);\r
+ Error (NULL, 0, 1003, "Invalid option value", "Debug Level range is 0-9, current input level is %d", (int) LogLevel);\r
goto Finish;\r
}\r
SetPrintLevel (LogLevel);\r
argv += 2;\r
continue;\r
}\r
- \r
+\r
if ((stricmp (argv[0], "-g") == 0) || (stricmp (argv[0], "--hiiguid") == 0)) {\r
Status = StringToGuid (argv[1], &HiiPackageListGuid);\r
if (EFI_ERROR (Status)) {\r
}\r
\r
if (stricmp (argv[0], "--hiipackage") == 0) {\r
- OutImageType = FW_HII_PACKAGE_LIST_RCIMAGE;\r
+ mOutImageType = FW_HII_PACKAGE_LIST_RCIMAGE;\r
+ argc --;\r
+ argv ++;\r
+ continue;\r
+ }\r
+\r
+ if (stricmp (argv[0], "--hiibinpackage") == 0) {\r
+ mOutImageType = FW_HII_PACKAGE_LIST_BINIMAGE;\r
argc --;\r
argv ++;\r
continue;\r
// InputFileName buffer too small, need to realloc\r
//\r
InputFileName = (CHAR8 **) realloc (\r
- InputFileName,\r
- (InputFileNum + MAXIMUM_INPUT_FILE_NUM) * sizeof (CHAR8 *)\r
- );\r
+ InputFileName,\r
+ (InputFileNum + MAXIMUM_INPUT_FILE_NUM) * sizeof (CHAR8 *)\r
+ );\r
\r
if (InputFileName == NULL) {\r
Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");\r
\r
VerboseMsg ("%s tool start.", UTILITY_NAME);\r
\r
- if (OutImageType == FW_DUMMY_IMAGE) {\r
+ if (mOutImageType == FW_DUMMY_IMAGE) {\r
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!");\r
if (ReplaceFlag) {\r
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.");\r
//\r
// Combine MciBinary files to one file\r
//\r
- if ((OutImageType == FW_MERGE_IMAGE) && ReplaceFlag) {\r
+ if ((mOutImageType == FW_MERGE_IMAGE) && ReplaceFlag) {\r
Error (NULL, 0, 1002, "Conflicting option", "-r replace option cannot be used with -j merge files option.");\r
goto Finish;\r
}\r
//\r
// Combine HiiBinary packages to a single package list\r
//\r
- if ((OutImageType == FW_HII_PACKAGE_LIST_RCIMAGE) && ReplaceFlag) {\r
+ if ((mOutImageType == FW_HII_PACKAGE_LIST_RCIMAGE) && ReplaceFlag) {\r
Error (NULL, 0, 1002, "Conflicting option", "-r replace option cannot be used with --hiipackage merge files option.");\r
goto Finish;\r
}\r
\r
+ if ((mOutImageType == FW_HII_PACKAGE_LIST_BINIMAGE) && ReplaceFlag) {\r
+ Error (NULL, 0, 1002, "Conflicting option", "-r replace option cannot be used with --hiibinpackage merge files option.");\r
+ goto Finish;\r
+ }\r
+\r
//\r
// Input image file\r
//\r
//\r
// Action will be taken for the input file.\r
//\r
- switch (OutImageType) {\r
+ switch (mOutImageType) {\r
case FW_EFI_IMAGE:\r
VerboseMsg ("Create efi image on module type %s based on the input PE image.", ModuleType);\r
break;\r
VerboseMsg ("Dump the TE header information of the input TE image.");\r
break;\r
case FW_MCI_IMAGE:\r
- VerboseMsg ("Conver input MicroCode.txt file to MicroCode.bin file.");\r
+ VerboseMsg ("Convert input MicroCode.txt file to MicroCode.bin file.");\r
break;\r
case FW_MERGE_IMAGE:\r
VerboseMsg ("Combine the input multi microcode bin files to one bin file.");\r
break;\r
case FW_HII_PACKAGE_LIST_RCIMAGE:\r
- VerboseMsg ("Combine the input multi hii bin packages to one text pacakge list RC file.");\r
+ VerboseMsg ("Combine the input multi hii bin packages to one text package list RC file.");\r
+ break;\r
+ case FW_HII_PACKAGE_LIST_BINIMAGE:\r
+ VerboseMsg ("Combine the input multi hii bin packages to one binary package list file.");\r
+ break;\r
+ case FW_REBASE_IMAGE:\r
+ VerboseMsg ("Rebase the input image to new base address.");\r
+ break;\r
+ case FW_SET_ADDRESS_IMAGE:\r
+ VerboseMsg ("Set the preferred address into the section header of the input image");\r
break;\r
default:\r
break;\r
// Open output file and Write image into the output file.\r
//\r
if (OutImageName != NULL) {\r
- fpOut = fopen (OutImageName, "rb");\r
+ fpOut = fopen (LongFilePath (OutImageName), "rb");\r
if (fpOut != NULL) {\r
+ //\r
+ // Get Output file time stamp\r
+ //\r
+ fstat(fileno (fpOut), &Stat_Buf);\r
+ OutputFileTime = Stat_Buf.st_mtime;\r
+ //\r
+ // Get Output file data\r
+ //\r
OutputFileLength = _filelength (fileno (fpOut));\r
OutputFileBuffer = malloc (OutputFileLength);\r
if (OutputFileBuffer == NULL) {\r
}\r
fread (OutputFileBuffer, 1, OutputFileLength, fpOut);\r
fclose (fpOut);\r
- }\r
- fpOut = fopen (OutImageName, "wb");\r
- if (!fpOut) {\r
- Error (NULL, 0, 0001, "Error opening output file", OutImageName);\r
- goto Finish;\r
+ fpOut = NULL;\r
}\r
VerboseMsg ("Output file name is %s", OutImageName);\r
- } else if (!ReplaceFlag) {\r
- if (OutImageType == DUMP_TE_HEADER) {\r
- fpOut = stdout;\r
- } else {\r
- Error (NULL, 0, 1001, "Missing option", "output file");\r
- goto Finish;\r
- }\r
+ } else if (!ReplaceFlag && mOutImageType != DUMP_TE_HEADER) {\r
+ Error (NULL, 0, 1001, "Missing option", "output file");\r
+ goto Finish;\r
}\r
\r
//\r
- // Combine multi binary HII package files to a single text package list RC file.\r
+ // Open input file and read file data into file buffer.\r
//\r
- if (OutImageType == FW_HII_PACKAGE_LIST_RCIMAGE) {\r
+ fpIn = fopen (LongFilePath (mInImageName), "rb");\r
+ if (fpIn == NULL) {\r
+ Error (NULL, 0, 0001, "Error opening file", mInImageName);\r
+ goto Finish;\r
+ }\r
+ //\r
+ // Get Iutput file time stamp\r
+ //\r
+ fstat(fileno (fpIn), &Stat_Buf);\r
+ InputFileTime = Stat_Buf.st_mtime;\r
+ //\r
+ // Get Input file data\r
+ //\r
+ InputFileLength = _filelength (fileno (fpIn));\r
+ InputFileBuffer = malloc (InputFileLength);\r
+ if (InputFileBuffer == NULL) {\r
+ Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");\r
+ fclose (fpIn);\r
+ goto Finish;\r
+ }\r
+ fread (InputFileBuffer, 1, InputFileLength, fpIn);\r
+ fclose (fpIn);\r
+ DebugMsg (NULL, 0, 9, "input file info", "the input file size is %u bytes", (unsigned) InputFileLength);\r
+\r
+ //\r
+ // Combine multi binary HII package files.\r
+ //\r
+ if (mOutImageType == FW_HII_PACKAGE_LIST_RCIMAGE || mOutImageType == FW_HII_PACKAGE_LIST_BINIMAGE) {\r
//\r
- // Get hii package list lenght\r
+ // Open output file handle.\r
+ //\r
+ fpOut = fopen (LongFilePath (OutImageName), "wb");\r
+ if (!fpOut) {\r
+ Error (NULL, 0, 0001, "Error opening output file", OutImageName);\r
+ goto Finish;\r
+ }\r
+ //\r
+ // Get hii package list length\r
//\r
HiiPackageListHeader.PackageLength = sizeof (EFI_HII_PACKAGE_LIST_HEADER);\r
for (Index = 0; Index < InputFileNum; Index ++) {\r
- fpIn = fopen (InputFileName [Index], "rb");\r
- if (!fpIn) {\r
+ fpIn = fopen (LongFilePath (InputFileName [Index]), "rb");\r
+ if (fpIn == NULL) {\r
Error (NULL, 0, 0001, "Error opening file", InputFileName [Index]);\r
goto Finish;\r
}\r
fread (&IfrFormSet, 1, sizeof (IfrFormSet), fpIn);\r
memcpy (&HiiPackageListGuid, &IfrFormSet.Guid, sizeof (EFI_GUID));\r
}\r
- NumberOfFormPacakge ++;\r
+ NumberOfFormPackage ++;\r
}\r
HiiPackageListHeader.PackageLength += FileLength;\r
fclose (fpIn);\r
//\r
// Check whether hii packages are valid\r
//\r
- if (NumberOfFormPacakge > 1) {\r
+ if (NumberOfFormPackage > 1) {\r
Error (NULL, 0, 3000, "Invalid", "The input hii packages contains more than one hii form package");\r
goto Finish;\r
}\r
if (memcmp (&HiiPackageListGuid, &mZeroGuid, sizeof (EFI_GUID)) == 0) {\r
- Error (NULL, 0, 3000, "Invalid", "HII pacakge list guid is not specified!");\r
+ Error (NULL, 0, 3000, "Invalid", "HII package list guid is not specified!");\r
goto Finish;\r
}\r
memcpy (&HiiPackageListHeader.PackageListGuid, &HiiPackageListGuid, sizeof (EFI_GUID));\r
memcpy (HiiPackageListBuffer, &HiiPackageListHeader, sizeof (HiiPackageListHeader));\r
HiiPackageDataPointer = HiiPackageListBuffer + sizeof (HiiPackageListHeader);\r
for (Index = 0; Index < InputFileNum; Index ++) {\r
- fpIn = fopen (InputFileName [Index], "rb");\r
- if (!fpIn) {\r
+ fpIn = fopen (LongFilePath (InputFileName [Index]), "rb");\r
+ if (fpIn == NULL) {\r
Error (NULL, 0, 0001, "Error opening file", InputFileName [Index]);\r
free (HiiPackageListBuffer);\r
goto Finish;\r
HiiPackageDataPointer = HiiPackageDataPointer + FileLength;\r
}\r
memcpy (HiiPackageDataPointer, &EndPackage, sizeof (EndPackage));\r
+\r
+ //\r
+ // write the hii package into the binary package list file with the resource section header\r
+ //\r
+ if (mOutImageType == FW_HII_PACKAGE_LIST_BINIMAGE) {\r
+ //\r
+ // Create the resource section header\r
+ //\r
+ HiiSectionHeader = CreateHiiResouceSectionHeader (&HiiSectionHeaderSize, HiiPackageListHeader.PackageLength);\r
+ if (HiiSectionHeader == NULL) {\r
+ free (HiiPackageListBuffer);\r
+ goto Finish;\r
+ }\r
+ //\r
+ // Wrtie section header and HiiData into File.\r
+ //\r
+ fwrite (HiiSectionHeader, 1, HiiSectionHeaderSize, fpOut);\r
+ fwrite (HiiPackageListBuffer, 1, HiiPackageListHeader.PackageLength, fpOut);\r
+ //\r
+ // Free allocated resources.\r
+ //\r
+ free (HiiSectionHeader);\r
+ free (HiiPackageListBuffer);\r
+ //\r
+ // Done successfully\r
+ //\r
+ goto Finish;\r
+ }\r
+\r
//\r
// write the hii package into the text package list rc file.\r
//\r
- for (Index = 0; gHiiPackageRCFileHeader[Index] != NULL; Index++) {\r
- fprintf (fpOut, "%s\n", gHiiPackageRCFileHeader[Index]);\r
- }\r
- fprintf (fpOut, "\n%d %s\n{", HII_RESOURCE_SECTION_INDEX, HII_RESOURCE_SECTION_NAME);\r
+ if (mOutImageType == FW_HII_PACKAGE_LIST_RCIMAGE) {\r
+ for (Index = 0; gHiiPackageRCFileHeader[Index] != NULL; Index++) {\r
+ fprintf (fpOut, "%s\n", gHiiPackageRCFileHeader[Index]);\r
+ }\r
+ fprintf (fpOut, "\n%d %s\n{", HII_RESOURCE_SECTION_INDEX, HII_RESOURCE_SECTION_NAME);\r
+\r
+ HiiPackageDataPointer = HiiPackageListBuffer;\r
+ for (Index = 0; Index + 2 < HiiPackageListHeader.PackageLength; Index += 2) {\r
+ if (Index % 16 == 0) {\r
+ fprintf (fpOut, "\n ");\r
+ }\r
+ fprintf (fpOut, " 0x%04X,", *(UINT16 *) HiiPackageDataPointer);\r
+ HiiPackageDataPointer += 2;\r
+ }\r
\r
- HiiPackageDataPointer = HiiPackageListBuffer;\r
- for (Index = 0; Index + 2 < HiiPackageListHeader.PackageLength; Index += 2) {\r
if (Index % 16 == 0) {\r
fprintf (fpOut, "\n ");\r
}\r
- fprintf (fpOut, " 0x%04X,", *(UINT16 *) HiiPackageDataPointer);\r
- HiiPackageDataPointer += 2;\r
- }\r
- \r
- if (Index % 16 == 0) {\r
- fprintf (fpOut, "\n ");\r
- }\r
- if ((Index + 2) == HiiPackageListHeader.PackageLength) {\r
- fprintf (fpOut, " 0x%04X\n}\n", *(UINT16 *) HiiPackageDataPointer);\r
- }\r
- if ((Index + 1) == HiiPackageListHeader.PackageLength) {\r
- fprintf (fpOut, " 0x%04X\n}\n", *(UINT8 *) HiiPackageDataPointer);\r
+ if ((Index + 2) == HiiPackageListHeader.PackageLength) {\r
+ fprintf (fpOut, " 0x%04X\n}\n", *(UINT16 *) HiiPackageDataPointer);\r
+ }\r
+ if ((Index + 1) == HiiPackageListHeader.PackageLength) {\r
+ fprintf (fpOut, " 0x%04X\n}\n", *(UINT8 *) HiiPackageDataPointer);\r
+ }\r
+ free (HiiPackageListBuffer);\r
+ //\r
+ // Done successfully\r
+ //\r
+ goto Finish;\r
}\r
- free (HiiPackageListBuffer);\r
- //\r
- // Done successfully\r
- //\r
- goto Finish;\r
}\r
\r
//\r
// Combine MciBinary files to one file\r
//\r
- if (OutImageType == FW_MERGE_IMAGE) {\r
+ if (mOutImageType == FW_MERGE_IMAGE) {\r
+ //\r
+ // Open output file handle.\r
+ //\r
+ fpOut = fopen (LongFilePath (OutImageName), "wb");\r
+ if (!fpOut) {\r
+ Error (NULL, 0, 0001, "Error opening output file", OutImageName);\r
+ goto Finish;\r
+ }\r
for (Index = 0; Index < InputFileNum; Index ++) {\r
- fpIn = fopen (InputFileName [Index], "rb");\r
+ fpIn = fopen (LongFilePath (InputFileName [Index]), "rb");\r
if (!fpIn) {\r
Error (NULL, 0, 0001, "Error opening file", InputFileName [Index]);\r
goto Finish;\r
//\r
// Convert MicroCode.txt file to MicroCode.bin file\r
//\r
- if (OutImageType == FW_MCI_IMAGE) {\r
- fpIn = fopen (mInImageName, "r");\r
- if (!fpIn) {\r
+ if (mOutImageType == FW_MCI_IMAGE) {\r
+ fpIn = fopen (LongFilePath (mInImageName), "r");\r
+ if (fpIn == NULL) {\r
Error (NULL, 0, 0001, "Error opening file", mInImageName);\r
goto Finish;\r
}\r
//\r
// Open the output file and write the buffer contents\r
//\r
- if (fpOut != NULL) {\r
- if (fwrite (FileBuffer, FileLength, 1, fpOut) != 1) {\r
- Error (NULL, 0, 0002, "Error writing file", OutImageName);\r
- goto Finish;\r
- }\r
- }\r
-\r
- if (ReplaceFlag) {\r
- fpInOut = fopen (mInImageName, "wb");\r
- if (fpInOut != NULL) {\r
- Error (NULL, 0, 0001, "Error opening file", mInImageName);\r
- goto Finish;\r
- }\r
- if (fwrite (FileBuffer, FileLength, 1, fpInOut) != 1) {\r
- Error (NULL, 0, 0002, "Error writing file", mInImageName);\r
- goto Finish;\r
- }\r
- }\r
VerboseMsg ("the size of output file is %u bytes", (unsigned) FileLength);\r
- //\r
- // Convert Mci.TXT to Mci.bin file successfully\r
- //\r
- goto Finish;\r
+ goto WriteFile;\r
}\r
\r
//\r
// Open input file and read file data into file buffer.\r
//\r
- fpIn = fopen (mInImageName, "rb");\r
- if (!fpIn) {\r
- Error (NULL, 0, 0001, "Error opening file", mInImageName);\r
- goto Finish;\r
- }\r
-\r
- FileLength = _filelength (fileno (fpIn));\r
+ FileLength = InputFileLength;\r
FileBuffer = malloc (FileLength);\r
if (FileBuffer == NULL) {\r
Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");\r
- fclose (fpIn);\r
goto Finish;\r
}\r
-\r
- fread (FileBuffer, 1, FileLength, fpIn);\r
- fclose (fpIn);\r
-\r
- DebugMsg (NULL, 0, 9, "input file info", "the input file size is %u bytes", (unsigned) FileLength);\r
+ memcpy (FileBuffer, InputFileBuffer, InputFileLength);\r
\r
- //\r
- // Replace file\r
- //\r
- if (ReplaceFlag) {\r
- fpInOut = fopen (mInImageName, "wb");\r
- if (!fpInOut) {\r
- Error (NULL, 0, 0001, "Error opening file", mInImageName);\r
- goto Finish;\r
- }\r
- }\r
//\r
// Dump TeImage Header into output file.\r
//\r
- if (OutImageType == DUMP_TE_HEADER) {\r
+ if (mOutImageType == DUMP_TE_HEADER) {\r
memcpy (&TEImageHeader, FileBuffer, sizeof (TEImageHeader));\r
if (TEImageHeader.Signature != EFI_TE_IMAGE_HEADER_SIGNATURE) {\r
Error (NULL, 0, 3000, "Invalid", "TE header signature of file %s is not correct.", mInImageName);\r
goto Finish;\r
}\r
+ //\r
+ // Open the output file handle.\r
+ //\r
+ if (ReplaceFlag) {\r
+ fpInOut = fopen (LongFilePath (mInImageName), "wb");\r
+ if (fpInOut == NULL) {\r
+ Error (NULL, 0, 0001, "Error opening file", mInImageName);\r
+ goto Finish;\r
+ }\r
+ } else {\r
+ if (OutImageName != NULL) {\r
+ fpOut = fopen (LongFilePath (OutImageName), "wb");\r
+ } else {\r
+ fpOut = stdout;\r
+ }\r
+ if (fpOut == NULL) {\r
+ Error (NULL, 0, 0001, "Error opening output file", OutImageName);\r
+ goto Finish;\r
+ }\r
+ }\r
if (fpInOut != NULL) {\r
fprintf (fpInOut, "Dump of file %s\n\n", mInImageName);\r
fprintf (fpInOut, "TE IMAGE HEADER VALUES\n");\r
fprintf (fpInOut, "%17X [%8X] RVA [size] of Base Relocation Directory\n", (unsigned) TEImageHeader.DataDirectory[0].VirtualAddress, (unsigned) TEImageHeader.DataDirectory[0].Size);\r
fprintf (fpInOut, "%17X [%8X] RVA [size] of Debug Directory\n", (unsigned) TEImageHeader.DataDirectory[1].VirtualAddress, (unsigned) TEImageHeader.DataDirectory[1].Size);\r
}\r
-\r
if (fpOut != NULL) {\r
fprintf (fpOut, "Dump of file %s\n\n", mInImageName);\r
fprintf (fpOut, "TE IMAGE HEADER VALUES\n");\r
// Following code to convert dll to efi image or te image.\r
// Get new image type\r
//\r
- if ((OutImageType == FW_EFI_IMAGE) || (OutImageType == FW_TE_IMAGE)) {\r
+ if ((mOutImageType == FW_EFI_IMAGE) || (mOutImageType == FW_TE_IMAGE)) {\r
if (ModuleType == NULL) {\r
- if (OutImageType == FW_EFI_IMAGE) {\r
+ if (mOutImageType == FW_EFI_IMAGE) {\r
Error (NULL, 0, 1001, "Missing option", "EFI_FILETYPE");\r
goto Finish;\r
- } else if (OutImageType == FW_TE_IMAGE) {\r
+ } else if (mOutImageType == FW_TE_IMAGE) {\r
//\r
// Default TE Image Type is Boot service driver\r
//\r
}\r
} else {\r
if (stricmp (ModuleType, "BASE") == 0 ||\r
- stricmp (ModuleType, "SEC") == 0 ||\r
- stricmp (ModuleType, "SECURITY_CORE") == 0 ||\r
- stricmp (ModuleType, "PEI_CORE") == 0 ||\r
- stricmp (ModuleType, "PEIM") == 0 ||\r
- stricmp (ModuleType, "COMBINED_PEIM_DRIVER") == 0 ||\r
- stricmp (ModuleType, "PIC_PEIM") == 0 ||\r
- stricmp (ModuleType, "RELOCATABLE_PEIM") == 0 ||\r
- stricmp (ModuleType, "DXE_CORE") == 0 ||\r
- stricmp (ModuleType, "BS_DRIVER") == 0 ||\r
- stricmp (ModuleType, "DXE_DRIVER") == 0 ||\r
- stricmp (ModuleType, "DXE_SMM_DRIVER") == 0 ||\r
- stricmp (ModuleType, "UEFI_DRIVER") == 0 ||\r
- stricmp (ModuleType, "SMM_DRIVER") == 0 ||\r
- stricmp (ModuleType, "SMM_CORE") == 0) {\r
- Type = EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER;\r
- VerboseMsg ("Efi Image subsystem type is efi boot service driver.");\r
+ stricmp (ModuleType, "SEC") == 0 ||\r
+ stricmp (ModuleType, "SECURITY_CORE") == 0 ||\r
+ stricmp (ModuleType, "PEI_CORE") == 0 ||\r
+ stricmp (ModuleType, "PEIM") == 0 ||\r
+ stricmp (ModuleType, "COMBINED_PEIM_DRIVER") == 0 ||\r
+ stricmp (ModuleType, "PIC_PEIM") == 0 ||\r
+ stricmp (ModuleType, "RELOCATABLE_PEIM") == 0 ||\r
+ stricmp (ModuleType, "DXE_CORE") == 0 ||\r
+ stricmp (ModuleType, "BS_DRIVER") == 0 ||\r
+ stricmp (ModuleType, "DXE_DRIVER") == 0 ||\r
+ stricmp (ModuleType, "DXE_SMM_DRIVER") == 0 ||\r
+ stricmp (ModuleType, "UEFI_DRIVER") == 0 ||\r
+ stricmp (ModuleType, "SMM_CORE") == 0 ||\r
+ stricmp (ModuleType, "MM_STANDALONE") == 0 ||\r
+ stricmp (ModuleType, "MM_CORE_STANDALONE") == 0) {\r
+ Type = EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER;\r
+ VerboseMsg ("Efi Image subsystem type is efi boot service driver.");\r
\r
} else if (stricmp (ModuleType, "UEFI_APPLICATION") == 0 ||\r
- stricmp (ModuleType, "APPLICATION") == 0) {\r
- Type = EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION;\r
- VerboseMsg ("Efi Image subsystem type is efi application.");\r
+ stricmp (ModuleType, "APPLICATION") == 0) {\r
+ Type = EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION;\r
+ VerboseMsg ("Efi Image subsystem type is efi application.");\r
\r
} else if (stricmp (ModuleType, "DXE_RUNTIME_DRIVER") == 0 ||\r
- stricmp (ModuleType, "RT_DRIVER") == 0) {\r
- Type = EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER;\r
- VerboseMsg ("Efi Image subsystem type is efi runtime driver.");\r
+ stricmp (ModuleType, "RT_DRIVER") == 0) {\r
+ Type = EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER;\r
+ VerboseMsg ("Efi Image subsystem type is efi runtime driver.");\r
\r
} else if (stricmp (ModuleType, "DXE_SAL_DRIVER") == 0 ||\r
- stricmp (ModuleType, "SAL_RT_DRIVER") == 0) {\r
- Type = EFI_IMAGE_SUBSYSTEM_SAL_RUNTIME_DRIVER;\r
- VerboseMsg ("Efi Image subsystem type is efi sal runtime driver.");\r
+ stricmp (ModuleType, "SAL_RT_DRIVER") == 0) {\r
+ Type = EFI_IMAGE_SUBSYSTEM_SAL_RUNTIME_DRIVER;\r
+ VerboseMsg ("Efi Image subsystem type is efi sal runtime driver.");\r
\r
} else {\r
Error (NULL, 0, 1003, "Invalid option value", "EFI_FILETYPE = %s", ModuleType);\r
}\r
\r
//\r
- // Convert EFL image to PeImage\r
+ // Convert ELF image to PeImage\r
//\r
if (IsElfHeader(FileBuffer)) {\r
- VerboseMsg ("Convert the input ELF Image to Pe Image");\r
- ConvertElf(&FileBuffer, &FileLength);\r
+ VerboseMsg ("Convert %s from ELF to PE/COFF.", mInImageName);\r
+ if (!ConvertElf(&FileBuffer, &FileLength)) {\r
+ Error (NULL, 0, 3000, "Invalid", "Unable to convert %s from ELF to PE/COFF.", mInImageName);\r
+ goto Finish;\r
+ }\r
}\r
\r
+ //\r
+ // Make sure File Offsets and Virtual Offsets are the same in the image so it is XIP\r
+ // XIP == eXecute In Place\r
+ //\r
+ PeCoffConvertImageToXip (&FileBuffer, &FileLength);\r
+\r
//\r
// Remove reloc section from PE or TE image\r
//\r
- if (OutImageType == FW_RELOC_STRIPEED_IMAGE) {\r
+ if (mOutImageType == FW_RELOC_STRIPEED_IMAGE) {\r
//\r
// Check TeImage\r
//\r
//\r
if ((SectionHeader->PointerToRawData + SectionHeader->SizeOfRawData) ==\r
(FileLength + TeHdr->StrippedSize - sizeof (EFI_TE_IMAGE_HEADER))) {\r
- //\r
- // Remove .reloc section and update TeImage Header\r
- //\r
- FileLength = FileLength - SectionHeader->SizeOfRawData;\r
- SectionHeader->SizeOfRawData = 0;\r
- SectionHeader->Misc.VirtualSize = 0;\r
- TeHdr->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress = 0;\r
- TeHdr->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size = 0;\r
- break;\r
+ //\r
+ // Remove .reloc section and update TeImage Header\r
+ //\r
+ FileLength = FileLength - SectionHeader->SizeOfRawData;\r
+ SectionHeader->SizeOfRawData = 0;\r
+ SectionHeader->Misc.VirtualSize = 0;\r
+ TeHdr->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress = 0;\r
+ TeHdr->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size = 0;\r
+ break;\r
}\r
}\r
}\r
goto Finish;\r
}\r
}\r
- \r
+\r
if (PeHdr->Pe32.FileHeader.Machine == IMAGE_FILE_MACHINE_ARM) {\r
// Some tools kick out IMAGE_FILE_MACHINE_ARM (0x1c0) vs IMAGE_FILE_MACHINE_ARMT (0x1c2)\r
- // so patch back to the offical UEFI value.\r
+ // so patch back to the official UEFI value.\r
PeHdr->Pe32.FileHeader.Machine = IMAGE_FILE_MACHINE_ARMT;\r
}\r
\r
+ //\r
+ // Set new base address into image\r
+ //\r
+ if (mOutImageType == FW_REBASE_IMAGE || mOutImageType == FW_SET_ADDRESS_IMAGE) {\r
+ if (PeHdr->Pe32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
+ if (NewBaseAddress >= 0x100000000ULL) {\r
+ Error (NULL, 0, 3000, "Invalid", "New base address is larger than 4G for 32bit PE image");\r
+ goto Finish;\r
+ }\r
+ }\r
+\r
+ if (NegativeAddr) {\r
+ //\r
+ // Set Base Address to a negative value.\r
+ //\r
+ NewBaseAddress = (UINT64) (0 - NewBaseAddress);\r
+ }\r
+ if (mOutImageType == FW_REBASE_IMAGE) {\r
+ Status = RebaseImage (mInImageName, FileBuffer, NewBaseAddress);\r
+ } else {\r
+ Status = SetAddressToSectionHeader (mInImageName, FileBuffer, NewBaseAddress);\r
+ }\r
+ if (EFI_ERROR (Status)) {\r
+ if (NegativeAddr) {\r
+ Error (NULL, 0, 3000, "Invalid", "Rebase/Set Image %s to Base address -0x%llx can't success", mInImageName, 0 - NewBaseAddress);\r
+ } else {\r
+ Error (NULL, 0, 3000, "Invalid", "Rebase/Set Image %s to Base address 0x%llx can't success", mInImageName, NewBaseAddress);\r
+ }\r
+ goto Finish;\r
+ }\r
+\r
+ //\r
+ // Write file\r
+ //\r
+ goto WriteFile;\r
+ }\r
+\r
//\r
// Extract bin data from Pe image.\r
//\r
- if (OutImageType == FW_BIN_IMAGE) {\r
+ if (mOutImageType == FW_BIN_IMAGE) {\r
if (FileLength < PeHdr->Pe32.OptionalHeader.SizeOfHeaders) {\r
Error (NULL, 0, 3000, "Invalid", "FileSize of %s is not a legal size.", mInImageName);\r
goto Finish;\r
//\r
// Output bin data from exe file\r
//\r
- if (fpOut != NULL) {\r
- fwrite (FileBuffer + PeHdr->Pe32.OptionalHeader.SizeOfHeaders, 1, FileLength - PeHdr->Pe32.OptionalHeader.SizeOfHeaders, fpOut);\r
- }\r
- if (fpInOut != NULL) {\r
- fwrite (FileBuffer + PeHdr->Pe32.OptionalHeader.SizeOfHeaders, 1, FileLength - PeHdr->Pe32.OptionalHeader.SizeOfHeaders, fpInOut);\r
- }\r
- VerboseMsg ("the size of output file is %u bytes", (unsigned) (FileLength - PeHdr->Pe32.OptionalHeader.SizeOfHeaders));\r
- goto Finish;\r
+ FileLength = FileLength - PeHdr->Pe32.OptionalHeader.SizeOfHeaders;\r
+ memmove (FileBuffer, FileBuffer + PeHdr->Pe32.OptionalHeader.SizeOfHeaders, FileLength);\r
+ VerboseMsg ("the size of output file is %u bytes", (unsigned) FileLength);\r
+ goto WriteFile;\r
}\r
\r
//\r
// Zero Debug Information of Pe Image\r
//\r
- if (OutImageType == FW_ZERO_DEBUG_IMAGE) {\r
+ if (mOutImageType == FW_ZERO_DEBUG_IMAGE) {\r
Status = ZeroDebugData (FileBuffer, TRUE);\r
if (EFI_ERROR (Status)) {\r
Error (NULL, 0, 3000, "Invalid", "Zero DebugData Error status is 0x%x", (int) Status);\r
goto Finish;\r
}\r
\r
- if (fpOut != NULL) {\r
- fwrite (FileBuffer, 1, FileLength, fpOut);\r
- }\r
- if (fpInOut != NULL) {\r
- fwrite (FileBuffer, 1, FileLength, fpInOut);\r
- }\r
+ //\r
+ // Write the updated Image\r
+ //\r
VerboseMsg ("the size of output file is %u bytes", (unsigned) FileLength);\r
- goto Finish;\r
+ goto WriteFile;\r
}\r
\r
//\r
// Set Time Stamp of Pe Image\r
//\r
- if (OutImageType == FW_SET_STAMP_IMAGE) {\r
+ if (mOutImageType == FW_SET_STAMP_IMAGE) {\r
Status = SetStamp (FileBuffer, TimeStamp);\r
if (EFI_ERROR (Status)) {\r
goto Finish;\r
}\r
\r
- if (fpOut != NULL) {\r
- fwrite (FileBuffer, 1, FileLength, fpOut);\r
- }\r
- if (fpInOut != NULL) {\r
- fwrite (FileBuffer, 1, FileLength, fpInOut);\r
- }\r
+ //\r
+ // Write the updated Image\r
+ //\r
VerboseMsg ("the size of output file is %u bytes", (unsigned) FileLength);\r
- goto Finish;\r
+ goto WriteFile;\r
}\r
\r
//\r
// Extract acpi data from pe image.\r
//\r
- if (OutImageType == FW_ACPI_IMAGE) {\r
+ if (mOutImageType == FW_ACPI_IMAGE) {\r
SectionHeader = (EFI_IMAGE_SECTION_HEADER *) ((UINT8 *) &(PeHdr->Pe32.OptionalHeader) + PeHdr->Pe32.FileHeader.SizeOfOptionalHeader);\r
for (Index = 0; Index < PeHdr->Pe32.FileHeader.NumberOfSections; Index ++, SectionHeader ++) {\r
if (strcmp ((char *)SectionHeader->Name, ".data") == 0 || strcmp ((char *)SectionHeader->Name, ".sdata") == 0) {\r
//\r
// Output Apci data to file\r
//\r
- if (fpOut != NULL) {\r
- fwrite (FileBuffer + SectionHeader->PointerToRawData, 1, FileLength, fpOut);\r
- }\r
- if (fpInOut != NULL) {\r
- fwrite (FileBuffer + SectionHeader->PointerToRawData, 1, FileLength, fpInOut);\r
- }\r
+ memmove (FileBuffer, FileBuffer + SectionHeader->PointerToRawData, FileLength);\r
VerboseMsg ("the size of output file is %u bytes", (unsigned) FileLength);\r
- goto Finish;\r
+ goto WriteFile;\r
}\r
}\r
Error (NULL, 0, 3000, "Invalid", "failed to get ACPI table from %s.", mInImageName);\r
memset (DosHdr, 0, sizeof (EFI_IMAGE_DOS_HEADER));\r
DosHdr->e_magic = BackupDosHdr.e_magic;\r
DosHdr->e_lfanew = BackupDosHdr.e_lfanew;\r
- \r
+\r
for (Index = sizeof (EFI_IMAGE_DOS_HEADER); Index < (UINT32 ) DosHdr->e_lfanew; Index++) {\r
FileBuffer[Index] = (UINT8) DosHdr->e_cp;\r
}\r
TEImageHeader.NumberOfSections = (UINT8) PeHdr->Pe32.FileHeader.NumberOfSections;\r
TEImageHeader.StrippedSize = (UINT16) ((UINTN) ((UINT8 *) &(PeHdr->Pe32.OptionalHeader) + PeHdr->Pe32.FileHeader.SizeOfOptionalHeader) - (UINTN) FileBuffer);\r
TEImageHeader.Subsystem = (UINT8) Type;\r
- \r
+\r
//\r
// Patch the PE header\r
//\r
\r
if (PeHdr->Pe32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
Optional32 = (EFI_IMAGE_OPTIONAL_HEADER32 *)&PeHdr->Pe32.OptionalHeader;\r
- Optional32->MajorLinkerVersion = 0;\r
- Optional32->MinorLinkerVersion = 0;\r
- Optional32->MajorOperatingSystemVersion = 0;\r
- Optional32->MinorOperatingSystemVersion = 0;\r
- Optional32->MajorImageVersion = 0;\r
- Optional32->MinorImageVersion = 0;\r
- Optional32->MajorSubsystemVersion = 0;\r
- Optional32->MinorSubsystemVersion = 0;\r
- Optional32->Win32VersionValue = 0;\r
- Optional32->CheckSum = 0;\r
- Optional32->SizeOfStackReserve = 0;\r
- Optional32->SizeOfStackCommit = 0;\r
- Optional32->SizeOfHeapReserve = 0;\r
- Optional32->SizeOfHeapCommit = 0;\r
-\r
+ if (!KeepOptionalHeaderFlag) {\r
+ Optional32->MajorOperatingSystemVersion = 0;\r
+ Optional32->MinorOperatingSystemVersion = 0;\r
+ Optional32->MajorImageVersion = 0;\r
+ Optional32->MinorImageVersion = 0;\r
+ Optional32->MajorSubsystemVersion = 0;\r
+ Optional32->MinorSubsystemVersion = 0;\r
+ Optional32->Win32VersionValue = 0;\r
+ Optional32->CheckSum = 0;\r
+ Optional32->SizeOfStackReserve = 0;\r
+ Optional32->SizeOfStackCommit = 0;\r
+ Optional32->SizeOfHeapReserve = 0;\r
+ Optional32->SizeOfHeapCommit = 0;\r
+ }\r
TEImageHeader.AddressOfEntryPoint = Optional32->AddressOfEntryPoint;\r
TEImageHeader.BaseOfCode = Optional32->BaseOfCode;\r
TEImageHeader.ImageBase = (UINT64) (Optional32->ImageBase);\r
// Zero .pdata section data.\r
//\r
if (!KeepExceptionTableFlag && Optional32->NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_EXCEPTION &&\r
- Optional32->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXCEPTION].VirtualAddress != 0 &&\r
- Optional32->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXCEPTION].Size != 0) {\r
- SectionHeader = (EFI_IMAGE_SECTION_HEADER *) ((UINT8 *) &(PeHdr->Pe32.OptionalHeader) + PeHdr->Pe32.FileHeader.SizeOfOptionalHeader);\r
- for (Index = 0; Index < PeHdr->Pe32.FileHeader.NumberOfSections; Index++, SectionHeader++) {\r
- if (SectionHeader->VirtualAddress == Optional32->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXCEPTION].VirtualAddress) {\r
- //\r
- // Zero .pdata Section data\r
- //\r
- memset (FileBuffer + SectionHeader->PointerToRawData, 0, SectionHeader->SizeOfRawData);\r
- //\r
- // Zero .pdata Section header name\r
- //\r
- memset (SectionHeader->Name, 0, sizeof (SectionHeader->Name));\r
- //\r
- // Zero Execption Table\r
- //\r
- Optional32->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXCEPTION].VirtualAddress = 0;\r
- Optional32->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXCEPTION].Size = 0;\r
- DebugMsg (NULL, 0, 9, "Zero the .pdata section for PE image", NULL);\r
- break;\r
+ Optional32->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXCEPTION].VirtualAddress != 0 &&\r
+ Optional32->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXCEPTION].Size != 0) {\r
+ SectionHeader = (EFI_IMAGE_SECTION_HEADER *) ((UINT8 *) &(PeHdr->Pe32.OptionalHeader) + PeHdr->Pe32.FileHeader.SizeOfOptionalHeader);\r
+ for (Index = 0; Index < PeHdr->Pe32.FileHeader.NumberOfSections; Index++, SectionHeader++) {\r
+ if (SectionHeader->VirtualAddress == Optional32->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXCEPTION].VirtualAddress) {\r
+ //\r
+ // Zero .pdata Section data\r
+ //\r
+ memset (FileBuffer + SectionHeader->PointerToRawData, 0, SectionHeader->SizeOfRawData);\r
+ //\r
+ // Zero .pdata Section header name\r
+ //\r
+ memset (SectionHeader->Name, 0, sizeof (SectionHeader->Name));\r
+ //\r
+ // Zero Exception Table\r
+ //\r
+ Optional32->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXCEPTION].VirtualAddress = 0;\r
+ Optional32->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXCEPTION].Size = 0;\r
+ DebugMsg (NULL, 0, 9, "Zero the .pdata section for PE image", NULL);\r
+ break;\r
+ }\r
}\r
- }\r
}\r
\r
//\r
}\r
} else if (PeHdr->Pe32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) {\r
Optional64 = (EFI_IMAGE_OPTIONAL_HEADER64 *)&PeHdr->Pe32.OptionalHeader;\r
- Optional64->MajorLinkerVersion = 0;\r
- Optional64->MinorLinkerVersion = 0;\r
- Optional64->MajorOperatingSystemVersion = 0;\r
- Optional64->MinorOperatingSystemVersion = 0;\r
- Optional64->MajorImageVersion = 0;\r
- Optional64->MinorImageVersion = 0;\r
- Optional64->MajorSubsystemVersion = 0;\r
- Optional64->MinorSubsystemVersion = 0;\r
- Optional64->Win32VersionValue = 0;\r
- Optional64->CheckSum = 0;\r
- Optional64->SizeOfStackReserve = 0;\r
- Optional64->SizeOfStackCommit = 0;\r
- Optional64->SizeOfHeapReserve = 0;\r
- Optional64->SizeOfHeapCommit = 0;\r
-\r
+ if (!KeepOptionalHeaderFlag) {\r
+ Optional64->MajorOperatingSystemVersion = 0;\r
+ Optional64->MinorOperatingSystemVersion = 0;\r
+ Optional64->MajorImageVersion = 0;\r
+ Optional64->MinorImageVersion = 0;\r
+ Optional64->MajorSubsystemVersion = 0;\r
+ Optional64->MinorSubsystemVersion = 0;\r
+ Optional64->Win32VersionValue = 0;\r
+ Optional64->CheckSum = 0;\r
+ Optional64->SizeOfStackReserve = 0;\r
+ Optional64->SizeOfStackCommit = 0;\r
+ Optional64->SizeOfHeapReserve = 0;\r
+ Optional64->SizeOfHeapCommit = 0;\r
+ }\r
TEImageHeader.AddressOfEntryPoint = Optional64->AddressOfEntryPoint;\r
TEImageHeader.BaseOfCode = Optional64->BaseOfCode;\r
TEImageHeader.ImageBase = (UINT64) (Optional64->ImageBase);\r
// Zero the .pdata section for X64 machine and don't check the Debug Directory is empty\r
// For Itaninum and X64 Image, remove .pdata section.\r
//\r
- if ((!KeepExceptionTableFlag && PeHdr->Pe32.FileHeader.Machine == IMAGE_FILE_MACHINE_X64) || PeHdr->Pe32.FileHeader.Machine == IMAGE_FILE_MACHINE_IA64) {\r
+ if ((!KeepExceptionTableFlag && PeHdr->Pe32.FileHeader.Machine == IMAGE_FILE_MACHINE_X64)) {\r
if (Optional64->NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_EXCEPTION &&\r
- Optional64->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXCEPTION].VirtualAddress != 0 &&\r
- Optional64->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXCEPTION].Size != 0) {\r
- SectionHeader = (EFI_IMAGE_SECTION_HEADER *) ((UINT8 *) &(PeHdr->Pe32.OptionalHeader) + PeHdr->Pe32.FileHeader.SizeOfOptionalHeader);\r
- for (Index = 0; Index < PeHdr->Pe32.FileHeader.NumberOfSections; Index++, SectionHeader++) {\r
- if (SectionHeader->VirtualAddress == Optional64->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXCEPTION].VirtualAddress) {\r
- //\r
- // Zero .pdata Section header name\r
- //\r
- memset (SectionHeader->Name, 0, sizeof (SectionHeader->Name));\r
-\r
- RuntimeFunction = (RUNTIME_FUNCTION *)(FileBuffer + SectionHeader->PointerToRawData);\r
- for (Index1 = 0; Index1 < Optional64->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXCEPTION].Size / sizeof (RUNTIME_FUNCTION); Index1++, RuntimeFunction++) {\r
- SectionHeader = (EFI_IMAGE_SECTION_HEADER *) ((UINT8 *) &(PeHdr->Pe32.OptionalHeader) + PeHdr->Pe32.FileHeader.SizeOfOptionalHeader);\r
- for (Index2 = 0; Index2 < PeHdr->Pe32.FileHeader.NumberOfSections; Index2++, SectionHeader++) {\r
- if (RuntimeFunction->UnwindInfoAddress >= SectionHeader->VirtualAddress && RuntimeFunction->UnwindInfoAddress < (SectionHeader->VirtualAddress + SectionHeader->SizeOfRawData)) {\r
- UnwindInfo = (UNWIND_INFO *)(FileBuffer + SectionHeader->PointerToRawData + (RuntimeFunction->UnwindInfoAddress - SectionHeader->VirtualAddress));\r
- if (UnwindInfo->Version == 1) {\r
- memset (UnwindInfo + 1, 0, UnwindInfo->CountOfUnwindCodes * sizeof (UINT16));\r
- memset (UnwindInfo, 0, sizeof (UNWIND_INFO));\r
+ Optional64->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXCEPTION].VirtualAddress != 0 &&\r
+ Optional64->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXCEPTION].Size != 0) {\r
+ SectionHeader = (EFI_IMAGE_SECTION_HEADER *) ((UINT8 *) &(PeHdr->Pe32.OptionalHeader) + PeHdr->Pe32.FileHeader.SizeOfOptionalHeader);\r
+ for (Index = 0; Index < PeHdr->Pe32.FileHeader.NumberOfSections; Index++, SectionHeader++) {\r
+ if (SectionHeader->VirtualAddress == Optional64->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXCEPTION].VirtualAddress) {\r
+ //\r
+ // Zero .pdata Section header name\r
+ //\r
+ memset (SectionHeader->Name, 0, sizeof (SectionHeader->Name));\r
+\r
+ RuntimeFunction = (RUNTIME_FUNCTION *)(FileBuffer + SectionHeader->PointerToRawData);\r
+ for (Index1 = 0; Index1 < Optional64->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXCEPTION].Size / sizeof (RUNTIME_FUNCTION); Index1++, RuntimeFunction++) {\r
+ SectionHeader = (EFI_IMAGE_SECTION_HEADER *) ((UINT8 *) &(PeHdr->Pe32.OptionalHeader) + PeHdr->Pe32.FileHeader.SizeOfOptionalHeader);\r
+ for (Index2 = 0; Index2 < PeHdr->Pe32.FileHeader.NumberOfSections; Index2++, SectionHeader++) {\r
+ if (RuntimeFunction->UnwindInfoAddress >= SectionHeader->VirtualAddress && RuntimeFunction->UnwindInfoAddress < (SectionHeader->VirtualAddress + SectionHeader->SizeOfRawData)) {\r
+ UnwindInfo = (UNWIND_INFO *)(FileBuffer + SectionHeader->PointerToRawData + (RuntimeFunction->UnwindInfoAddress - SectionHeader->VirtualAddress));\r
+ if (UnwindInfo->Version == 1) {\r
+ memset (UnwindInfo + 1, 0, UnwindInfo->CountOfUnwindCodes * sizeof (UINT16));\r
+ memset (UnwindInfo, 0, sizeof (UNWIND_INFO));\r
+ }\r
+ break;\r
}\r
- break;\r
}\r
+ memset (RuntimeFunction, 0, sizeof (RUNTIME_FUNCTION));\r
}\r
- memset (RuntimeFunction, 0, sizeof (RUNTIME_FUNCTION));\r
+ //\r
+ // Zero Exception Table\r
+ //\r
+ Optional64->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXCEPTION].Size = 0;\r
+ Optional64->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXCEPTION].VirtualAddress = 0;\r
+ DebugMsg (NULL, 0, 9, "Zero the .pdata section if the machine type is X64 for PE32+ image", NULL);\r
+ break;\r
}\r
- //\r
- // Zero Execption Table\r
- //\r
- Optional64->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXCEPTION].Size = 0;\r
- Optional64->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXCEPTION].VirtualAddress = 0;\r
- DebugMsg (NULL, 0, 9, "Zero the .pdata section if the machine type is X64 for PE32+ image", NULL);\r
- break;\r
}\r
- }\r
}\r
}\r
\r
Error (NULL, 0, 3000, "Invalid", "Magic 0x%x of PeImage %s is unknown.", PeHdr->Pe32.OptionalHeader.Magic, mInImageName);\r
goto Finish;\r
}\r
- \r
+\r
if (((PeHdr->Pe32.FileHeader.Characteristics & EFI_IMAGE_FILE_RELOCS_STRIPPED) == 0) && \\r
(TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress == 0) && \\r
(TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size == 0)) {\r
- //\r
- // PeImage can be loaded into memory, but it has no relocation section. \r
- // Fix TeImage Header to set VA of relocation data directory to not zero, the size is still zero.\r
- //\r
- if (Optional32 != NULL) {\r
- TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress = Optional32->SizeOfImage - sizeof (EFI_IMAGE_BASE_RELOCATION);\r
- } else if (Optional64 != NULL) {\r
- TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress = Optional64->SizeOfImage - sizeof (EFI_IMAGE_BASE_RELOCATION);\r
+ //\r
+ // PeImage can be loaded into memory, but it has no relocation section.\r
+ // Fix TeImage Header to set VA of relocation data directory to not zero, the size is still zero.\r
+ //\r
+ if (Optional32 != NULL) {\r
+ TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress = Optional32->SizeOfImage - sizeof (EFI_IMAGE_BASE_RELOCATION);\r
+ } else if (Optional64 != NULL) {\r
+ TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress = Optional64->SizeOfImage - sizeof (EFI_IMAGE_BASE_RELOCATION);\r
+ }\r
+ }\r
+\r
+ //\r
+ // Fill HII section data\r
+ //\r
+ SectionHeader = (EFI_IMAGE_SECTION_HEADER *) ((UINT8 *) &(PeHdr->Pe32.OptionalHeader) + PeHdr->Pe32.FileHeader.SizeOfOptionalHeader);\r
+ for (Index = 0; Index < PeHdr->Pe32.FileHeader.NumberOfSections; Index++) {\r
+ if (stricmp ((char *)SectionHeader[Index].Name, ".hii") == 0) {\r
+ //\r
+ // Update resource section header offset\r
+ //\r
+ SetHiiResourceHeader ((UINT8*) FileBuffer + SectionHeader[Index].PointerToRawData, SectionHeader[Index].VirtualAddress);\r
+ //\r
+ // Update resource section name\r
+ //\r
+ strcpy((char *) SectionHeader[Index].Name, ".rsrc");\r
+ //\r
+ // Update resource data directory.\r
+ //\r
+ if (PeHdr->Pe32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
+ Optional32 = (EFI_IMAGE_OPTIONAL_HEADER32 *)&PeHdr->Pe32.OptionalHeader;\r
+ Optional32->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress = SectionHeader[Index].VirtualAddress;\r
+ Optional32->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE].Size = SectionHeader[Index].Misc.VirtualSize;\r
+ } else if (PeHdr->Pe32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) {\r
+ Optional64 = (EFI_IMAGE_OPTIONAL_HEADER64 *)&PeHdr->Pe32.OptionalHeader;\r
+ Optional64->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress = SectionHeader[Index].VirtualAddress;\r
+ Optional64->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE].Size = SectionHeader[Index].Misc.VirtualSize;\r
+ }\r
+ break;\r
}\r
}\r
- \r
+\r
//\r
// Zero ExceptionTable Xdata\r
//\r
//\r
ZeroDebugData (FileBuffer, FALSE);\r
\r
- if (OutImageType == FW_TE_IMAGE) {\r
+ if (mOutImageType == FW_TE_IMAGE) {\r
if ((PeHdr->Pe32.FileHeader.NumberOfSections &~0xFF) || (Type &~0xFF)) {\r
//\r
// Pack the subsystem and NumberOfSections into 1 byte. Make sure they fit both.\r
}\r
\r
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",\r
- TEImageHeader.Machine, TEImageHeader.NumberOfSections, TEImageHeader.StrippedSize, (unsigned) TEImageHeader.AddressOfEntryPoint, (unsigned) TEImageHeader.BaseOfCode, (unsigned long long) TEImageHeader.ImageBase);\r
+ TEImageHeader.Machine, TEImageHeader.NumberOfSections, TEImageHeader.StrippedSize, (unsigned) TEImageHeader.AddressOfEntryPoint, (unsigned) TEImageHeader.BaseOfCode, (unsigned long long) TEImageHeader.ImageBase);\r
//\r
// Update Image to TeImage\r
//\r
- if (fpOut != NULL) {\r
- fwrite (&TEImageHeader, 1, sizeof (EFI_TE_IMAGE_HEADER), fpOut);\r
- fwrite (FileBuffer + TEImageHeader.StrippedSize, 1, FileLength - TEImageHeader.StrippedSize, fpOut);\r
- }\r
- if (fpInOut != NULL) {\r
- fwrite (&TEImageHeader, 1, sizeof (EFI_TE_IMAGE_HEADER), fpInOut);\r
- fwrite (FileBuffer + TEImageHeader.StrippedSize, 1, FileLength - TEImageHeader.StrippedSize, fpInOut);\r
+ FileLength = FileLength - TEImageHeader.StrippedSize;\r
+ memmove (FileBuffer + sizeof (EFI_TE_IMAGE_HEADER), FileBuffer + TEImageHeader.StrippedSize, FileLength);\r
+ FileLength = FileLength + sizeof (EFI_TE_IMAGE_HEADER);\r
+ memcpy (FileBuffer, &TEImageHeader, sizeof (EFI_TE_IMAGE_HEADER));\r
+ VerboseMsg ("the size of output file is %u bytes", (unsigned) (FileLength));\r
+ } else {\r
+\r
+ //\r
+ // Following codes are to fix the objcopy's issue:\r
+ // objcopy in binutil 2.50.18 will set PE image's charactices to "RELOC_STRIPPED" if image has no ".reloc" section\r
+ // It cause issue for EFI image which has no ".reloc" sections.\r
+ // Following codes will be removed when objcopy in binutil fix this problem for PE image.\r
+ //\r
+ if ((PeHdr->Pe32.FileHeader.Characteristics & EFI_IMAGE_FILE_RELOCS_STRIPPED) != 0) {\r
+ if (PeHdr->Pe32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
+ Optional32 = (EFI_IMAGE_OPTIONAL_HEADER32 *)&PeHdr->Pe32.OptionalHeader;\r
+ if (Optional32->ImageBase == 0) {\r
+ PeHdr->Pe32.FileHeader.Characteristics &= ~EFI_IMAGE_FILE_RELOCS_STRIPPED;\r
+ }\r
+ } else if (PeHdr->Pe32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) {\r
+ Optional64 = (EFI_IMAGE_OPTIONAL_HEADER64 *)&PeHdr->Pe32.OptionalHeader;\r
+ if (Optional64->ImageBase == 0) {\r
+ PeHdr->Pe32.FileHeader.Characteristics &= ~EFI_IMAGE_FILE_RELOCS_STRIPPED;\r
+ }\r
+ }\r
}\r
- VerboseMsg ("the size of output file is %u bytes", (unsigned) (FileLength - TEImageHeader.StrippedSize));\r
- goto Finish;\r
}\r
+\r
WriteFile:\r
//\r
- // Update Image to EfiImage\r
+ // Update Image to EfiImage or TE image\r
//\r
- if (fpOut != NULL) {\r
- fwrite (FileBuffer, 1, FileLength, fpOut);\r
- }\r
- if (fpInOut != NULL) {\r
- fwrite (FileBuffer, 1, FileLength, fpInOut);\r
+ if (ReplaceFlag) {\r
+ if ((FileLength != InputFileLength) || (memcmp (FileBuffer, InputFileBuffer, FileLength) != 0)) {\r
+ //\r
+ // Update File when File is changed.\r
+ //\r
+ fpInOut = fopen (LongFilePath (mInImageName), "wb");\r
+ if (fpInOut == NULL) {\r
+ Error (NULL, 0, 0001, "Error opening file", mInImageName);\r
+ goto Finish;\r
+ }\r
+ fwrite (FileBuffer, 1, FileLength, fpInOut);\r
+ VerboseMsg ("the size of output file is %u bytes", (unsigned) FileLength);\r
+ }\r
+ } else {\r
+ if ((OutputFileTime < InputFileTime) || (FileLength != OutputFileLength) || (memcmp (FileBuffer, OutputFileBuffer, FileLength) != 0)) {\r
+ //\r
+ // Update File when File is changed or File is old.\r
+ //\r
+ fpOut = fopen (LongFilePath (OutImageName), "wb");\r
+ if (fpOut == NULL) {\r
+ Error (NULL, 0, 0001, "Error opening output file", OutImageName);\r
+ goto Finish;\r
+ }\r
+ fwrite (FileBuffer, 1, FileLength, fpOut);\r
+ VerboseMsg ("the size of output file is %u bytes", (unsigned) FileLength);\r
+ }\r
}\r
- VerboseMsg ("the size of output file is %u bytes", (unsigned) FileLength);\r
+ mImageSize = FileLength;\r
\r
Finish:\r
if (fpInOut != NULL) {\r
if (GetUtilityStatus () != STATUS_SUCCESS) {\r
//\r
- // when file updates failed, original file is still recoveried.\r
+ // when file updates failed, original file is still recovered.\r
//\r
- fwrite (FileBuffer, 1, FileLength, fpInOut);\r
+ fwrite (InputFileBuffer, 1, InputFileLength, fpInOut);\r
}\r
//\r
// Write converted data into fpInOut file and close input file.\r
if (OutputFileBuffer == NULL) {\r
remove (OutImageName);\r
} else {\r
- fpOut = fopen (OutImageName, "wb");\r
+ fpOut = fopen (LongFilePath (OutImageName), "wb");\r
fwrite (OutputFileBuffer, 1, OutputFileLength, fpOut);\r
fclose (fpOut);\r
- free (OutputFileBuffer);\r
}\r
}\r
}\r
\r
+ if (InputFileBuffer != NULL) {\r
+ free (InputFileBuffer);\r
+ }\r
+\r
+ if (OutputFileBuffer != NULL) {\r
+ free (OutputFileBuffer);\r
+ }\r
+\r
+ //\r
+ // Write module size and time stamp to report file.\r
+ //\r
+ if (OutImageName != NULL) {\r
+ FileLen = strlen (OutImageName);\r
+ }\r
+ if (FileLen >= 4 && strcmp (OutImageName + (FileLen - 4), ".efi") == 0) {\r
+ ReportFileName = (CHAR8 *) malloc (FileLen + 1);\r
+ if (ReportFileName != NULL) {\r
+ strcpy (ReportFileName, OutImageName);\r
+ strcpy (ReportFileName + (FileLen - 4), ".txt");\r
+ ReportFile = fopen (LongFilePath (ReportFileName), "w+");\r
+ if (ReportFile != NULL) {\r
+ fprintf (ReportFile, "MODULE_SIZE = %u\n", (unsigned) mImageSize);\r
+ fprintf (ReportFile, "TIME_STAMP = %u\n", (unsigned) mImageTimeStamp);\r
+ fclose(ReportFile);\r
+ }\r
+ free (ReportFileName);\r
+ }\r
+ }\r
VerboseMsg ("%s tool done with return code is 0x%x.", UTILITY_NAME, GetUtilityStatus ());\r
\r
return GetUtilityStatus ();\r
{\r
UINT32 Index;\r
UINT32 DebugDirectoryEntryRva;\r
+ UINT32 DebugDirectoryEntrySize;\r
UINT32 DebugDirectoryEntryFileOffset;\r
UINT32 ExportDirectoryEntryRva;\r
UINT32 ExportDirectoryEntryFileOffset;\r
EFI_IMAGE_OPTIONAL_HEADER64 *Optional64Hdr;\r
EFI_IMAGE_SECTION_HEADER *SectionHeader;\r
EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *DebugEntry;\r
- UINT32 *NewTimeStamp; \r
+ EFI_IMAGE_DEBUG_CODEVIEW_RSDS_ENTRY *RsdsEntry;\r
+ UINT32 *NewTimeStamp;\r
\r
//\r
// Init variable.\r
//\r
DebugDirectoryEntryRva = 0;\r
+ DebugDirectoryEntrySize = 0;\r
ExportDirectoryEntryRva = 0;\r
ResourceDirectoryEntryRva = 0;\r
DebugDirectoryEntryFileOffset = 0;\r
// Get Debug, Export and Resource EntryTable RVA address.\r
// Resource Directory entry need to review.\r
//\r
- if (FileHdr->Machine == EFI_IMAGE_MACHINE_IA32) {\r
- Optional32Hdr = (EFI_IMAGE_OPTIONAL_HEADER32 *) ((UINT8*) FileHdr + sizeof (EFI_IMAGE_FILE_HEADER));\r
+ Optional32Hdr = (EFI_IMAGE_OPTIONAL_HEADER32 *) ((UINT8*) FileHdr + sizeof (EFI_IMAGE_FILE_HEADER));\r
+ Optional64Hdr = (EFI_IMAGE_OPTIONAL_HEADER64 *) ((UINT8*) FileHdr + sizeof (EFI_IMAGE_FILE_HEADER));\r
+ if (Optional32Hdr->Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
SectionHeader = (EFI_IMAGE_SECTION_HEADER *) ((UINT8 *) Optional32Hdr + FileHdr->SizeOfOptionalHeader);\r
if (Optional32Hdr->NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_EXPORT && \\r
Optional32Hdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXPORT].Size != 0) {\r
if (Optional32Hdr->NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_DEBUG && \\r
Optional32Hdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].Size != 0) {\r
DebugDirectoryEntryRva = Optional32Hdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress;\r
+ DebugDirectoryEntrySize = Optional32Hdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].Size;\r
if (ZeroDebugFlag) {\r
Optional32Hdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].Size = 0;\r
Optional32Hdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress = 0;\r
}\r
}\r
} else {\r
- Optional64Hdr = (EFI_IMAGE_OPTIONAL_HEADER64 *) ((UINT8*) FileHdr + sizeof (EFI_IMAGE_FILE_HEADER));\r
SectionHeader = (EFI_IMAGE_SECTION_HEADER *) ((UINT8 *) Optional64Hdr + FileHdr->SizeOfOptionalHeader);\r
if (Optional64Hdr->NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_EXPORT && \\r
Optional64Hdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXPORT].Size != 0) {\r
if (Optional64Hdr->NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_DEBUG && \\r
Optional64Hdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].Size != 0) {\r
DebugDirectoryEntryRva = Optional64Hdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress;\r
+ DebugDirectoryEntrySize = Optional64Hdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].Size;\r
if (ZeroDebugFlag) {\r
Optional64Hdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].Size = 0;\r
Optional64Hdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress = 0;\r
//Zero Debug Data and TimeStamp\r
//\r
FileHdr->TimeDateStamp = 0;\r
-\r
+ mImageTimeStamp = 0;\r
if (ExportDirectoryEntryFileOffset != 0) {\r
NewTimeStamp = (UINT32 *) (FileBuffer + ExportDirectoryEntryFileOffset + sizeof (UINT32));\r
*NewTimeStamp = 0;\r
\r
if (DebugDirectoryEntryFileOffset != 0) {\r
DebugEntry = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *) (FileBuffer + DebugDirectoryEntryFileOffset);\r
- DebugEntry->TimeDateStamp = 0;\r
- if (ZeroDebugFlag) {\r
- memset (FileBuffer + DebugEntry->FileOffset, 0, DebugEntry->SizeOfData);\r
- memset (DebugEntry, 0, sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY));\r
+ Index = 0;\r
+ for (Index=0; Index < DebugDirectoryEntrySize / sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY); Index ++, DebugEntry ++) {\r
+ DebugEntry->TimeDateStamp = 0;\r
+ if (mIsConvertXip) {\r
+ DebugEntry->FileOffset = DebugEntry->RVA;\r
+ }\r
+ if (ZeroDebugFlag || DebugEntry->Type != EFI_IMAGE_DEBUG_TYPE_CODEVIEW) {\r
+ memset (FileBuffer + DebugEntry->FileOffset, 0, DebugEntry->SizeOfData);\r
+ memset (DebugEntry, 0, sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY));\r
+ }\r
+ if (DebugEntry->Type == EFI_IMAGE_DEBUG_TYPE_CODEVIEW) {\r
+ RsdsEntry = (EFI_IMAGE_DEBUG_CODEVIEW_RSDS_ENTRY *) (FileBuffer + DebugEntry->FileOffset);\r
+ if (RsdsEntry->Signature == CODEVIEW_SIGNATURE_MTOC) {\r
+ // MTOC sets DebugDirectoryEntrySize to size of the .debug section, so fix it.\r
+ if (!ZeroDebugFlag) {\r
+ if (Optional32Hdr->Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
+ Optional32Hdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].Size = sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY);\r
+ } else {\r
+ Optional64Hdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].Size = sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY);\r
+ }\r
+ }\r
+ break;\r
+ }\r
+ }\r
}\r
}\r
\r
EFI_IMAGE_OPTIONAL_HEADER64 *Optional64Hdr;\r
EFI_IMAGE_SECTION_HEADER *SectionHeader;\r
UINT32 *NewTimeStamp;\r
- \r
+\r
//\r
// Init variable.\r
//\r
}\r
\r
ptime = localtime (&newtime);\r
- DebugMsg (NULL, 0, 9, "New Image Time Stamp", "%04d-%02d-%02d %02d:%02d:%02d",\r
- ptime->tm_year + 1900, ptime->tm_mon + 1, ptime->tm_mday, ptime->tm_hour, ptime->tm_min, ptime->tm_sec);\r
+ if (ptime != NULL) {\r
+ DebugMsg (NULL, 0, 9, "New Image Time Stamp", "%04d-%02d-%02d %02d:%02d:%02d",\r
+ ptime->tm_year + 1900, ptime->tm_mon + 1, ptime->tm_mday, ptime->tm_hour, ptime->tm_min, ptime->tm_sec);\r
+ }\r
//\r
// Set new time and data into PeImage.\r
//\r
// Set new stamp\r
//\r
FileHdr->TimeDateStamp = (UINT32) newtime;\r
-\r
+ mImageTimeStamp = (UINT32) newtime;\r
if (ExportDirectoryEntryRva != 0) {\r
NewTimeStamp = (UINT32 *) (FileBuffer + ExportDirectoryEntryFileOffset + sizeof (UINT32));\r
*NewTimeStamp = (UINT32) newtime;\r
{\r
CHAR8 Line[MAX_LINE_LEN];\r
CHAR8 *cptr;\r
- unsigned ScannedData = 0;\r
+ int ScannedData = 0;\r
\r
Line[MAX_LINE_LEN - 1] = 0;\r
while (1) {\r
//\r
// strip space\r
//\r
- for (cptr = Line; *cptr && isspace(*cptr); cptr++) {\r
+ for (cptr = Line; *cptr && isspace((int)*cptr); cptr++) {\r
}\r
\r
// Skip Blank Lines and Comment Lines\r
// DD XXXXXXXXX\r
// DD XXXXXXXXX\r
//\r
- if ((tolower(cptr[0]) == 'd') && (tolower(cptr[1]) == 'd') && isspace (cptr[2])) {\r
+ if ((tolower((int)cptr[0]) == 'd') && (tolower((int)cptr[1]) == 'd') && isspace ((int)cptr[2])) {\r
//\r
// Skip blanks and look for a hex digit\r
//\r
cptr += 3;\r
- for (; *cptr && isspace(*cptr); cptr++) {\r
+ for (; *cptr && isspace((int)*cptr); cptr++) {\r
}\r
- if (isxdigit (*cptr)) {\r
+ if (isxdigit ((int)*cptr)) {\r
if (sscanf (cptr, "%X", &ScannedData) != 1) {\r
return STATUS_ERROR;\r
}\r