]> git.proxmox.com Git - mirror_edk2.git/blobdiff - BaseTools/Source/C/GenFw/GenFw.c
BaseTools: Fix Segmentation fault: 11 when build AppPkg with XCODE5
[mirror_edk2.git] / BaseTools / Source / C / GenFw / GenFw.c
index e72f05286969297f84d45990160be97621d4707f..af60c92763c4c8020559d46972e5f8321c460f00 100644 (file)
@@ -1,7 +1,8 @@
 /** @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
+Copyright (c) 2004 - 2016, Intel Corporation. All rights reserved.<BR>\r
+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
@@ -9,14 +10,6 @@ http://opensource.org/licenses/bsd-license.php
 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
-\r
 **/\r
 \r
 #include "WinNtInclude.h"\r
@@ -24,6 +17,8 @@ Abstract:
 #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
@@ -49,10 +44,7 @@ Abstract:
 #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
@@ -63,31 +55,11 @@ Abstract:
 \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
@@ -113,7 +85,14 @@ static const char *gHiiPackageRCFileHeader[] = {
   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
+\r
 \r
 STATIC\r
 EFI_STATUS\r
@@ -157,7 +136,7 @@ Returns:
 \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
@@ -189,7 +168,7 @@ Returns:
   //\r
   // Copyright declaration\r
   //\r
-  fprintf (stdout, "Copyright (c) 2007, Intel Corporation. All rights reserved.\n\n");\r
+  fprintf (stdout, "Copyright (c) 2007 - 2015, Intel Corporation. All rights reserved.\n\n");\r
 \r
   //\r
   // Details Option\r
@@ -198,16 +177,17 @@ Returns:
   fprintf (stdout, "  -o FileName, --outputfile FileName\n\\r
                         File will be created to store the ouput 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
@@ -215,9 +195,9 @@ Returns:
                         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
@@ -235,7 +215,7 @@ Returns:
                         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
@@ -243,7 +223,9 @@ Returns:
   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
@@ -265,6 +247,9 @@ Returns:
   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
@@ -272,7 +257,7 @@ Returns:
                         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
@@ -281,6 +266,24 @@ Returns:
                         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 pacakges 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
@@ -441,993 +444,591 @@ Returns:
   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
-  )\r
-{\r
-  if (Num >= Ehdr->e_shnum)\r
-    return NULL;\r
-  return (Elf_Shdr*)((UINT8*)ShdrBase + Num * Ehdr->e_shentsize);\r
-}\r
-\r
-INTN\r
-CheckElfHeader(\r
-  VOID\r
+VOID\r
+SetHiiResourceHeader (\r
+  UINT8   *HiiBinData,\r
+  UINT32  OffsetToFile\r
   )\r
 {\r
-  //\r
-  // Note: Magic has already been tested.\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
+  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
   //\r
-  // Find the section header table\r
+  // Fill Resource section entry\r
   //\r
-  ShdrBase  = (Elf_Shdr *)((UINT8 *)Ehdr + Ehdr->e_shoff);\r
-  gPhdrBase = (Elf_Phdr *)((UINT8 *)Ehdr + Ehdr->e_phoff);\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
-  CoffSectionsOffset = (UINT32 *)malloc(Ehdr->e_shnum * sizeof (UINT32));\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
-  memset(CoffSectionsOffset, 0, Ehdr->e_shnum * sizeof(UINT32));\r
-  return 1;\r
-}\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
-int\r
-IsTextShdr(\r
-  Elf_Shdr *Shdr\r
-  )\r
-{\r
-  return (Shdr->sh_flags & (SHF_WRITE | SHF_ALLOC)) == SHF_ALLOC;\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
+  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
+  \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
+  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 FileAlginment then it is not an XIP type image.\r
+    //\r
+    return;\r
   }\r
 \r
   //\r
-  // '}' end character\r
+  // Calculate size of XIP file, and determine if the conversion is needed.\r
   //\r
-  if (*RcString == '}' || Index == Size) {\r
-    return;\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
-  HiiBinOffset = 0;\r
-  HiiBinSize   = 0x1000;\r
-  HiiBinData   = (UINT8 *) malloc (HiiBinSize);\r
-  if (HiiBinData == NULL) {\r
+  if (FirstSectionOffset < PeHdr->Pe32.OptionalHeader.SizeOfHeaders) {\r
+    //\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
+    VerboseMsg ("PE/COFF conversion to XIP is impossible due to overlap");\r
+    VerboseMsg ("of section data with the executable header.");\r
     return;\r
   }\r
-  memset (HiiBinData, 0, HiiBinSize);\r
-  //\r
-  // Fill Resource section entry\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
+  if (FirstSectionOffset == *FileLength) {\r
     //\r
-    *(UINT16 *)(HiiBinData + HiiBinOffset) = (UINT16) Data16;\r
-    HiiBinOffset += 2;\r
+    // If we never found a section with a non-zero size, then we\r
+    // skip the conversion.\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
-    }\r
-    //\r
-    // '}' end character\r
-    //\r
-    if (*RcString == '}'|| Index == Size) {\r
-      break;\r
-    }\r
-    //\r
-    // Check BinBuffer size\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
 \r
-  NtHdr->Pe32.Signature = EFI_IMAGE_NT_SIGNATURE;\r
+UINT8 *\r
+CreateHiiResouceSectionHeader (\r
+  UINT32 *pSectionHeaderSize, \r
+  UINT32 HiiDataSize\r
+  )\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
+Routine Description:\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
+  Create COFF resource section header\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
+Arguments:\r
 \r
-  NtHdr->Pe32.OptionalHeader.BaseOfCode = TextOffset;\r
+  pSectionHeaderSize - Pointer to section header size.\r
+  HiiDataSize        - Size of the total HII data in section.\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
+Returns:\r
+  The created section header buffer.\r
 \r
-  NtHdr->Pe32.OptionalHeader.SizeOfHeaders = TextOffset;\r
-  NtHdr->Pe32.OptionalHeader.NumberOfRvaAndSizes = EFI_IMAGE_NUMBER_OF_DIRECTORY_ENTRIES;\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
-  //\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
+Routine Description:\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
+  Support routine for the PE/COFF Loader that reads a buffer from a PE/COFF file\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
+Arguments:\r
 \r
-VOID\r
-CoffAddFixupEntry(\r
-  UINT16 Val\r
-  )\r
-{\r
-  *CoffEntryRel = Val;\r
-  CoffEntryRel++;\r
-  CoffBaseRel->SizeOfBlock += 2;\r
-  CoffOffset += 2;\r
-}\r
+  FileHandle - The handle to the PE/COFF file\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
-\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
-  if (!FoundRelocations && (Ehdr->e_machine == EM_ARM)) {\r
-    /* Try again, but look for PT_DYNAMIC instead of SHT_REL */\r
+/*++\r
 \r
-    for (Index = 0; Index < Ehdr->e_phnum; Index++) {\r
-      RelElementSize = 0;\r
-      RelSize = 0;\r
-      RelOffset = 0;\r
+Routine Description:\r
 \r
-      DynamicSegment = GetPhdrByIndex (Index);\r
+  Set new base address into the section header of PeImage\r
 \r
-      if (DynamicSegment->p_type == PT_DYNAMIC) {\r
-        Dyn = (Elf32_Dyn *) ((UINT8 *)Ehdr + DynamicSegment->p_offset);\r
+Arguments:\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
+  FileName           - Name of file\r
+  FileBuffer         - Pointer to PeImage.\r
+  NewPe32BaseAddress - New Base Address for PE image.\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) && (ImgHdr->Pe32.FileHeader.Machine != IMAGE_FILE_MACHINE_IA64)) {\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
@@ -1458,7 +1059,6 @@ Returns:
   char                             *OutImageName;\r
   char                             *ModuleType;\r
   CHAR8                            *TimeStamp;\r
-  UINT32                           OutImageType;\r
   FILE                             *fpIn;\r
   FILE                             *fpOut;\r
   FILE                             *fpInOut;\r
@@ -1477,11 +1077,14 @@ Returns:
   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
@@ -1499,20 +1102,30 @@ Returns:
   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
@@ -1529,16 +1142,25 @@ Returns:
   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
@@ -1578,8 +1200,8 @@ Returns:
         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
@@ -1587,49 +1209,49 @@ Returns:
     }\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
@@ -1654,6 +1276,13 @@ Returns:
       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
@@ -1662,14 +1291,14 @@ Returns:
     }\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
@@ -1686,6 +1315,44 @@ Returns:
       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
@@ -1729,7 +1396,7 @@ Returns:
       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
@@ -1742,7 +1409,14 @@ Returns:
     }\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
@@ -1768,9 +1442,9 @@ Returns:
       // 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
@@ -1787,7 +1461,7 @@ Returns:
 \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
@@ -1806,7 +1480,7 @@ Returns:
   //\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
@@ -1814,11 +1488,16 @@ Returns:
   //\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
@@ -1828,7 +1507,7 @@ Returns:
   //\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
@@ -1862,6 +1541,15 @@ Returns:
   case FW_HII_PACKAGE_LIST_RCIMAGE:\r
     VerboseMsg ("Combine the input multi hii bin packages to one text pacakge list RC file.");\r
     break;\r
+  case FW_HII_PACKAGE_LIST_BINIMAGE:\r
+    VerboseMsg ("Combine the input multi hii bin packages to one binary pacakge 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
   }\r
@@ -1874,8 +1562,16 @@ Returns:
   // 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
@@ -1886,33 +1582,60 @@ Returns:
       }\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
+  // Open input file and read file data into file buffer.\r
+  //\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 to a single text package list RC file.\r
+  // Combine multi binary HII package files.\r
   //\r
-  if (OutImageType == FW_HII_PACKAGE_LIST_RCIMAGE) {\r
+  if (mOutImageType == FW_HII_PACKAGE_LIST_RCIMAGE || mOutImageType == FW_HII_PACKAGE_LIST_BINIMAGE) {\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
     //\r
     // Get hii package list lenght\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
@@ -1928,7 +1651,7 @@ Returns:
           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
@@ -1937,7 +1660,7 @@ Returns:
     //\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
@@ -1957,8 +1680,8 @@ Returns:
     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
@@ -1970,45 +1693,84 @@ Returns:
       HiiPackageDataPointer = HiiPackageDataPointer + FileLength;\r
     }\r
     memcpy (HiiPackageDataPointer, &EndPackage, sizeof (EndPackage));\r
+\r
     //\r
-    // write the hii package into the text package list rc file.\r
+    // write the hii package into the binary package list file with the resource section header\r
     //\r
-    for (Index = 0; gHiiPackageRCFileHeader[Index] != NULL; Index++) {\r
-      fprintf (fpOut, "%s\n", gHiiPackageRCFileHeader[Index]);\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
-    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
+    //\r
+    // write the hii package into the text package list rc file.\r
+    //\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
       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
@@ -2049,9 +1811,9 @@ Returns:
   //\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
@@ -2145,72 +1907,50 @@ Returns:
     //\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
+  memcpy (FileBuffer, InputFileBuffer, InputFileLength);\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
-\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
@@ -2224,7 +1964,6 @@ Returns:
       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
@@ -2245,12 +1984,12 @@ Returns:
   // 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
@@ -2259,37 +1998,38 @@ Returns:
       }\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
@@ -2299,17 +2039,26 @@ Returns:
   }\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
@@ -2323,15 +2072,15 @@ Returns:
           //\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
@@ -2417,17 +2166,54 @@ Returns:
       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
     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) && (PeHdr->Pe32.FileHeader.Machine != IMAGE_FILE_MACHINE_IA64)) {\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
@@ -2435,59 +2221,49 @@ Returns:
     //\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
@@ -2508,14 +2284,9 @@ Returns:
         //\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
@@ -2529,7 +2300,7 @@ Returns:
     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
@@ -2544,7 +2315,7 @@ Returns:
   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
@@ -2552,21 +2323,20 @@ Returns:
 \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
@@ -2585,28 +2355,28 @@ Returns:
     // 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 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
+          }\r
         }\r
-      }\r
     }\r
 \r
     //\r
@@ -2646,21 +2416,20 @@ Returns:
     }\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
@@ -2681,40 +2450,40 @@ Returns:
     //\r
     if ((!KeepExceptionTableFlag && PeHdr->Pe32.FileHeader.Machine == IMAGE_FILE_MACHINE_X64) || PeHdr->Pe32.FileHeader.Machine == IMAGE_FILE_MACHINE_IA64) {\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 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
-            // 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
@@ -2757,21 +2526,51 @@ Returns:
     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
@@ -2794,7 +2593,7 @@ Returns:
   //\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
@@ -2812,40 +2611,78 @@ Returns:
     }\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
@@ -2870,14 +2707,41 @@ Finish:
       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
@@ -2909,6 +2773,7 @@ Returns:
 {\r
   UINT32                           Index;\r
   UINT32                           DebugDirectoryEntryRva;\r
+  UINT32                           DebugDirectoryEntrySize;\r
   UINT32                           DebugDirectoryEntryFileOffset;\r
   UINT32                           ExportDirectoryEntryRva;\r
   UINT32                           ExportDirectoryEntryFileOffset;\r
@@ -2920,12 +2785,14 @@ Returns:
   EFI_IMAGE_OPTIONAL_HEADER64     *Optional64Hdr;\r
   EFI_IMAGE_SECTION_HEADER        *SectionHeader;\r
   EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *DebugEntry;\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
@@ -2947,8 +2814,9 @@ Returns:
   // 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
@@ -2961,13 +2829,13 @@ Returns:
     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
@@ -2980,6 +2848,7 @@ Returns:
     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
@@ -3012,7 +2881,7 @@ Returns:
   //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
@@ -3025,10 +2894,33 @@ Returns:
 \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 (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_RSDS) {\r
+          RsdsEntry->Unknown  = 0;\r
+          RsdsEntry->Unknown2 = 0;\r
+          RsdsEntry->Unknown3 = 0;\r
+          RsdsEntry->Unknown4 = 0;\r
+          RsdsEntry->Unknown5 = 0;\r
+        } else 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
@@ -3178,8 +3070,10 @@ Returns:
   }\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
@@ -3252,7 +3146,7 @@ Returns:
   // 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
@@ -3294,7 +3188,7 @@ Returns:
 {\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
@@ -3311,7 +3205,7 @@ Returns:
     //\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
@@ -3326,14 +3220,14 @@ Returns:
   // 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