]> git.proxmox.com Git - mirror_edk2.git/blobdiff - BaseTools/Source/C/GenFw/GenFw.c
BaseTools: Replace BSD License with BSD+Patent License
[mirror_edk2.git] / BaseTools / Source / C / GenFw / GenFw.c
index 90ba2511022ba9fd1853fb1a59b35beb9f9afb69..973bae5fe4dbec9c13d36f95e506a9138c8451a1 100644 (file)
@@ -1,21 +1,8 @@
 /** @file\r
+Converts a pe32+ image to an FW, Te image type, or other specific image.\r
 \r
-Copyright (c) 2004 - 2011, 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
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-\r
-Module Name:\r
-\r
-    GenFw.c\r
-\r
-Abstract:\r
-\r
-    Converts a pe32+ image to an FW, Te image type, or other specific image.\r
+Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
 \r
 **/\r
 \r
@@ -66,10 +53,6 @@ Abstract:
 #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
 //\r
 // Structure definition for a microcode header\r
@@ -103,6 +86,7 @@ CHAR8  *mInImageName;
 UINT32 mImageTimeStamp = 0;\r
 UINT32 mImageSize = 0;\r
 UINT32 mOutImageType = FW_DUMMY_IMAGE;\r
+BOOLEAN mIsConvertXip = FALSE;\r
 \r
 \r
 STATIC\r
@@ -147,7 +131,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
@@ -179,25 +163,26 @@ Returns:
   //\r
   // Copyright declaration\r
   //\r
-  fprintf (stdout, "Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.\n\n");\r
+  fprintf (stdout, "Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.\n\n");\r
 \r
   //\r
   // Details Option\r
   //\r
   fprintf (stdout, "Options:\n");\r
   fprintf (stdout, "  -o FileName, --outputfile FileName\n\\r
-                        File will be created to store the ouput content.\n");\r
+                        File will be created to store the output content.\n");\r
   fprintf (stdout, "  -e EFI_FILETYPE, --efiImage EFI_FILETYPE\n\\r
                         Create Efi Image. EFI_FILETYPE is one of BASE,SMM_CORE,\n\\r
                         PEI_CORE, PEIM, DXE_CORE, DXE_DRIVER, UEFI_APPLICATION,\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
@@ -205,9 +190,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
@@ -251,12 +236,15 @@ Returns:
                         If it is combined with other action options, the later\n\\r
                         input action option will override the previous one.\n");\r
   fprintf (stdout, "  -a NUM, --align NUM   NUM is one HEX or DEC format alignment value.\n\\r
-                        This option is only used together with -j option.\n");  \r
+                        This option is only used together with -j option.\n");\r
   fprintf (stdout, "  -p NUM, --pad NUM     NUM is one HEX or DEC format padding value.\n\\r
                         This option is only used together with -j option.\n");\r
   fprintf (stdout, "  --keepexceptiontable  Don't clear exception table.\n\\r
                         This option can be used together with -e or -t.\n\\r
                         It doesn't work for other options.\n");\r
+  fprintf (stdout, "  --keepoptionalheader  Don't zero PE/COFF optional header fields.\n\\r
+                        This option can be used together with -e or -t.\n\\r
+                        It doesn't work for other options.\n");\r
   fprintf (stdout, "  --keepzeropending     Don't strip zero pending of .reloc.\n\\r
                         This option can be used together with -e or -t.\n\\r
                         It doesn't work for other options.\n");\r
@@ -267,13 +255,13 @@ Returns:
                         Guid is used to specify hii package list guid.\n\\r
                         Its format is xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\n\\r
                         If not specified, the first Form FormSet guid is used.\n");\r
-  fprintf (stdout, "  --hiipackage          Combine all input binary hii pacakges into \n\\r
+  fprintf (stdout, "  --hiipackage          Combine all input binary hii packages into \n\\r
                         a single package list as the text resource data(RC).\n\\r
                         It can't be combined with other action options\n\\r
                         except for -o option. It is a action option.\n\\r
                         If it is combined with other action options, the later\n\\r
                         input action option will override the previous one.\n");\r
-  fprintf (stdout, "  --hiibinpackage       Combine all input binary hii pacakges into \n\\r
+  fprintf (stdout, "  --hiibinpackage       Combine all input binary hii packages into \n\\r
                         a single package list as the binary resource section.\n\\r
                         It can't be combined with other action options\n\\r
                         except for -o option. It is a action option.\n\\r
@@ -496,7 +484,7 @@ SetHiiResourceHeader (
         }\r
 \r
         //\r
-        // Now it ought to be resource Data and update its OffsetToData value \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
@@ -507,7 +495,7 @@ SetHiiResourceHeader (
     }\r
     ResourceDirectoryEntry++;\r
   }\r
-  \r
+\r
   return;\r
 }\r
 \r
@@ -536,7 +524,7 @@ GetPeCoffHeader (
       return NULL;\r
     }\r
   }\r
-  \r
+\r
   return PeHdr;\r
 }\r
 \r
@@ -561,11 +549,11 @@ PeCoffConvertImageToXip (
   if (PeHdr == NULL) {\r
     return;\r
   }\r
-  \r
+\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
+    // If SectionAlignment is not equal to FileAlignment then it is not an XIP type image.\r
     //\r
     return;\r
   }\r
@@ -633,6 +621,10 @@ PeCoffConvertImageToXip (
   // Allocate the extra space that we need to grow the image\r
   //\r
   XipFile = malloc (XipLength);\r
+  if (XipFile == NULL) {\r
+    Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");\r
+    return;\r
+  }\r
   memset (XipFile, 0, XipLength);\r
 \r
   //\r
@@ -658,18 +650,23 @@ PeCoffConvertImageToXip (
         SectionHeader->SizeOfRawData\r
         );\r
     }\r
-    SectionHeader->SizeOfRawData = SectionHeader->Misc.VirtualSize;\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
   free (*FileBuffer);\r
   *FileLength = XipLength;\r
   *FileBuffer = XipFile;\r
+\r
+  mIsConvertXip = TRUE;\r
 }\r
 \r
 UINT8 *\r
 CreateHiiResouceSectionHeader (\r
-  UINT32 *pSectionHeaderSize, \r
+  UINT32 *pSectionHeaderSize,\r
   UINT32 HiiDataSize\r
   )\r
 /*++\r
@@ -702,15 +699,19 @@ Returns:
   // Calculate the total size for the resource header (include Type, Name and Language)\r
   // then allocate memory for the resource header.\r
   //\r
-  HiiSectionHeaderSize = 3 * (sizeof (EFI_IMAGE_RESOURCE_DIRECTORY) + sizeof (EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY)) \r
-                          + 3 * (sizeof (UINT16) + 3 * sizeof (CHAR16)) \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
   HiiSectionOffset = 0;\r
   //\r
-  // Create Type entry \r
+  // Create Type entry\r
   //\r
   ResourceDirectory = (EFI_IMAGE_RESOURCE_DIRECTORY *) (HiiSectionHeader + HiiSectionOffset);\r
   HiiSectionOffset += sizeof (EFI_IMAGE_RESOURCE_DIRECTORY);\r
@@ -870,7 +871,7 @@ Returns:
 \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
+    return Status;\r
   }\r
 \r
   //\r
@@ -883,8 +884,8 @@ Returns:
   //\r
   SectionHeader = (EFI_IMAGE_SECTION_HEADER *) (\r
     (UINTN) ImgHdr +\r
-    sizeof (UINT32) + \r
-    sizeof (EFI_IMAGE_FILE_HEADER) +  \r
+    sizeof (UINT32) +\r
+    sizeof (EFI_IMAGE_FILE_HEADER) +\r
     ImgHdr->Pe32.FileHeader.SizeOfOptionalHeader\r
     );\r
 \r
@@ -898,13 +899,6 @@ Returns:
     }\r
   }\r
 \r
-  //\r
-  // No available section header is found.\r
-  //\r
-  if (Index == ImgHdr->Pe32.FileHeader.NumberOfSections) {\r
-    return EFI_NOT_FOUND;\r
-  }\r
-  \r
   //\r
   // BaseAddress is set to section header.\r
   //\r
@@ -957,7 +951,7 @@ Returns:
 \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
+    return Status;\r
   }\r
 \r
   //\r
@@ -996,15 +990,15 @@ Returns:
   //\r
   SectionHeader = (EFI_IMAGE_SECTION_HEADER *) (\r
     (UINTN) ImgHdr +\r
-    sizeof (UINT32) + \r
-    sizeof (EFI_IMAGE_FILE_HEADER) +  \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
+      FileBuffer + SectionHeader->PointerToRawData,\r
+      (VOID*) (UINTN) (ImageContext.ImageAddress + SectionHeader->VirtualAddress),\r
       SectionHeader->SizeOfRawData\r
       );\r
   }\r
@@ -1014,7 +1008,7 @@ Returns:
   //\r
   // Update Image Base Address\r
   //\r
-  if ((ImgHdr->Pe32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) && (ImgHdr->Pe32.FileHeader.Machine != IMAGE_FILE_MACHINE_IA64)) {\r
+  if (ImgHdr->Pe32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
     ImgHdr->Pe32.OptionalHeader.ImageBase = (UINT32) NewPe32BaseAddress;\r
   } else if (ImgHdr->Pe32Plus.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) {\r
     ImgHdr->Pe32Plus.OptionalHeader.ImageBase = NewPe32BaseAddress;\r
@@ -1087,6 +1081,7 @@ Returns:
   STATUS                           Status;\r
   BOOLEAN                          ReplaceFlag;\r
   BOOLEAN                          KeepExceptionTableFlag;\r
+  BOOLEAN                          KeepOptionalHeaderFlag;\r
   BOOLEAN                          KeepZeroPendingFlag;\r
   UINT64                           LogLevel;\r
   EFI_TE_IMAGE_HEADER              TEImageHeader;\r
@@ -1104,7 +1099,7 @@ 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
@@ -1149,8 +1144,9 @@ Returns:
   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
@@ -1277,6 +1273,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
@@ -1381,7 +1384,7 @@ Returns:
         goto Finish;\r
       }\r
       if (LogLevel > 9) {\r
-        Error (NULL, 0, 1003, "Invalid option value", "Debug Level range is 0-9, currnt input level is %d", (int) LogLevel);\r
+        Error (NULL, 0, 1003, "Invalid option value", "Debug Level range is 0-9, current input level is %d", (int) LogLevel);\r
         goto Finish;\r
       }\r
       SetPrintLevel (LogLevel);\r
@@ -1527,16 +1530,16 @@ Returns:
     VerboseMsg ("Dump the TE header information of the input TE image.");\r
     break;\r
   case FW_MCI_IMAGE:\r
-    VerboseMsg ("Conver input MicroCode.txt file to MicroCode.bin file.");\r
+    VerboseMsg ("Convert input MicroCode.txt file to MicroCode.bin file.");\r
     break;\r
   case FW_MERGE_IMAGE:\r
     VerboseMsg ("Combine the input multi microcode bin files to one bin file.");\r
     break;\r
   case FW_HII_PACKAGE_LIST_RCIMAGE:\r
-    VerboseMsg ("Combine the input multi hii bin packages to one text pacakge list RC file.");\r
+    VerboseMsg ("Combine the input multi hii bin packages to one text package list RC file.");\r
     break;\r
   case FW_HII_PACKAGE_LIST_BINIMAGE:\r
-    VerboseMsg ("Combine the input multi hii bin packages to one binary pacakge list file.");\r
+    VerboseMsg ("Combine the input multi hii bin packages to one binary package list file.");\r
     break;\r
   case FW_REBASE_IMAGE:\r
     VerboseMsg ("Rebase the input image to new base address.");\r
@@ -1556,7 +1559,7 @@ 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
@@ -1587,7 +1590,7 @@ Returns:
   //\r
   // Open input file and read file data into file buffer.\r
   //\r
-  fpIn = fopen (mInImageName, "rb");\r
+  fpIn = fopen (LongFilePath (mInImageName), "rb");\r
   if (fpIn == NULL) {\r
     Error (NULL, 0, 0001, "Error opening file", mInImageName);\r
     goto Finish;\r
@@ -1618,17 +1621,17 @@ Returns:
     //\r
     // Open output file handle.\r
     //\r
-    fpOut = fopen (OutImageName, "wb");\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
+    // Get hii package list length\r
     //\r
     HiiPackageListHeader.PackageLength = sizeof (EFI_HII_PACKAGE_LIST_HEADER);\r
     for (Index = 0; Index < InputFileNum; Index ++) {\r
-      fpIn = fopen (InputFileName [Index], "rb");\r
+      fpIn = fopen (LongFilePath (InputFileName [Index]), "rb");\r
       if (fpIn == NULL) {\r
         Error (NULL, 0, 0001, "Error opening file", InputFileName [Index]);\r
         goto Finish;\r
@@ -1645,7 +1648,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
@@ -1654,12 +1657,12 @@ 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
     if (memcmp (&HiiPackageListGuid, &mZeroGuid, sizeof (EFI_GUID)) == 0) {\r
-      Error (NULL, 0, 3000, "Invalid", "HII pacakge list guid is not specified!");\r
+      Error (NULL, 0, 3000, "Invalid", "HII package list guid is not specified!");\r
       goto Finish;\r
     }\r
     memcpy (&HiiPackageListHeader.PackageListGuid, &HiiPackageListGuid, sizeof (EFI_GUID));\r
@@ -1674,7 +1677,7 @@ 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
+      fpIn = fopen (LongFilePath (InputFileName [Index]), "rb");\r
       if (fpIn == NULL) {\r
         Error (NULL, 0, 0001, "Error opening file", InputFileName [Index]);\r
         free (HiiPackageListBuffer);\r
@@ -1696,6 +1699,10 @@ Returns:
       // 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
@@ -1754,13 +1761,13 @@ Returns:
     //\r
     // Open output file handle.\r
     //\r
-    fpOut = fopen (OutImageName, "wb");\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
@@ -1802,7 +1809,7 @@ Returns:
   // Convert MicroCode.txt file to MicroCode.bin file\r
   //\r
   if (mOutImageType == FW_MCI_IMAGE) {\r
-    fpIn = fopen (mInImageName, "r");\r
+    fpIn = fopen (LongFilePath (mInImageName), "r");\r
     if (fpIn == NULL) {\r
       Error (NULL, 0, 0001, "Error opening file", mInImageName);\r
       goto Finish;\r
@@ -1925,14 +1932,14 @@ Returns:
     // Open the output file handle.\r
     //\r
     if (ReplaceFlag) {\r
-      fpInOut = fopen (mInImageName, "wb");\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 (OutImageName, "wb");\r
+        fpOut = fopen (LongFilePath (OutImageName), "wb");\r
       } else {\r
         fpOut = stdout;\r
       }\r
@@ -2000,7 +2007,9 @@ Returns:
         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, "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
@@ -2157,7 +2166,7 @@ Returns:
 \r
   if (PeHdr->Pe32.FileHeader.Machine == IMAGE_FILE_MACHINE_ARM) {\r
     // Some tools kick out IMAGE_FILE_MACHINE_ARM (0x1c0) vs IMAGE_FILE_MACHINE_ARMT (0x1c2)\r
-    // so patch back to the offical UEFI value.\r
+    // so patch back to the official UEFI value.\r
     PeHdr->Pe32.FileHeader.Machine = IMAGE_FILE_MACHINE_ARMT;\r
   }\r
 \r
@@ -2165,13 +2174,13 @@ Returns:
   // 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 (PeHdr->Pe32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
       if (NewBaseAddress >= 0x100000000ULL) {\r
         Error (NULL, 0, 3000, "Invalid", "New base address is larger than 4G for 32bit PE image");\r
         goto Finish;\r
       }\r
     }\r
-    \r
+\r
     if (NegativeAddr) {\r
       //\r
       // Set Base Address to a negative value.\r
@@ -2311,19 +2320,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->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
@@ -2356,7 +2366,7 @@ Returns:
             //\r
             memset (SectionHeader->Name, 0, sizeof (SectionHeader->Name));\r
             //\r
-            // Zero Execption Table\r
+            // Zero Exception Table\r
             //\r
             Optional32->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXCEPTION].VirtualAddress = 0;\r
             Optional32->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXCEPTION].Size           = 0;\r
@@ -2403,19 +2413,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->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
@@ -2434,7 +2445,7 @@ Returns:
     // Zero the .pdata section for X64 machine and don't check the Debug Directory is empty\r
     // For Itaninum and X64 Image, remove .pdata section.\r
     //\r
-    if ((!KeepExceptionTableFlag && PeHdr->Pe32.FileHeader.Machine == IMAGE_FILE_MACHINE_X64) || PeHdr->Pe32.FileHeader.Machine == IMAGE_FILE_MACHINE_IA64) {\r
+    if ((!KeepExceptionTableFlag && PeHdr->Pe32.FileHeader.Machine == IMAGE_FILE_MACHINE_X64)) {\r
       if (Optional64->NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_EXCEPTION &&\r
         Optional64->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXCEPTION].VirtualAddress != 0 &&\r
         Optional64->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXCEPTION].Size != 0) {\r
@@ -2462,7 +2473,7 @@ Returns:
                 memset (RuntimeFunction, 0, sizeof (RUNTIME_FUNCTION));\r
               }\r
               //\r
-              // Zero Execption Table\r
+              // Zero Exception Table\r
               //\r
               Optional64->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXCEPTION].Size = 0;\r
               Optional64->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXCEPTION].VirtualAddress = 0;\r
@@ -2517,7 +2528,7 @@ Returns:
     (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
+      // 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
@@ -2638,7 +2649,7 @@ WriteFile:
       //\r
       // Update File when File is changed.\r
       //\r
-      fpInOut = fopen (mInImageName, "wb");\r
+      fpInOut = fopen (LongFilePath (mInImageName), "wb");\r
       if (fpInOut == NULL) {\r
         Error (NULL, 0, 0001, "Error opening file", mInImageName);\r
         goto Finish;\r
@@ -2651,7 +2662,7 @@ WriteFile:
       //\r
       // Update File when File is changed or File is old.\r
       //\r
-      fpOut = fopen (OutImageName, "wb");\r
+      fpOut = fopen (LongFilePath (OutImageName), "wb");\r
       if (fpOut == NULL) {\r
         Error (NULL, 0, 0001, "Error opening output file", OutImageName);\r
         goto Finish;\r
@@ -2693,13 +2704,13 @@ 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
       }\r
     }\r
   }\r
-  \r
+\r
   if (InputFileBuffer != NULL) {\r
     free (InputFileBuffer);\r
   }\r
@@ -2718,8 +2729,8 @@ Finish:
     ReportFileName = (CHAR8 *) malloc (FileLen + 1);\r
     if (ReportFileName != NULL) {\r
       strcpy (ReportFileName, OutImageName);\r
-      strcpy (ReportFileName + (FileLen - 4), ".txt"); \r
-      ReportFile = fopen (ReportFileName, "w+");\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
@@ -2759,6 +2770,7 @@ Returns:
 {\r
   UINT32                           Index;\r
   UINT32                           DebugDirectoryEntryRva;\r
+  UINT32                           DebugDirectoryEntrySize;\r
   UINT32                           DebugDirectoryEntryFileOffset;\r
   UINT32                           ExportDirectoryEntryRva;\r
   UINT32                           ExportDirectoryEntryFileOffset;\r
@@ -2770,12 +2782,14 @@ Returns:
   EFI_IMAGE_OPTIONAL_HEADER64     *Optional64Hdr;\r
   EFI_IMAGE_SECTION_HEADER        *SectionHeader;\r
   EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *DebugEntry;\r
-  UINT32                          *NewTimeStamp;  \r
+  EFI_IMAGE_DEBUG_CODEVIEW_RSDS_ENTRY *RsdsEntry;\r
+  UINT32                          *NewTimeStamp;\r
 \r
   //\r
   // Init variable.\r
   //\r
   DebugDirectoryEntryRva           = 0;\r
+  DebugDirectoryEntrySize          = 0;\r
   ExportDirectoryEntryRva          = 0;\r
   ResourceDirectoryEntryRva        = 0;\r
   DebugDirectoryEntryFileOffset    = 0;\r
@@ -2797,8 +2811,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
@@ -2811,13 +2826,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
@@ -2830,6 +2845,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
@@ -2875,11 +2891,30 @@ Returns:
 \r
   if (DebugDirectoryEntryFileOffset != 0) {\r
     DebugEntry = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *) (FileBuffer + DebugDirectoryEntryFileOffset);\r
-    DebugEntry->TimeDateStamp = 0;\r
-    mImageTimeStamp = 0;\r
-    if (ZeroDebugFlag) {\r
-      memset (FileBuffer + DebugEntry->FileOffset, 0, DebugEntry->SizeOfData);\r
-      memset (DebugEntry, 0, sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY));\r
+    Index = 0;\r
+    for (Index=0; Index < DebugDirectoryEntrySize / sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY); Index ++, DebugEntry ++) {\r
+      DebugEntry->TimeDateStamp = 0;\r
+      if (mIsConvertXip) {\r
+        DebugEntry->FileOffset = DebugEntry->RVA;\r
+      }\r
+      if (ZeroDebugFlag || DebugEntry->Type != EFI_IMAGE_DEBUG_TYPE_CODEVIEW) {\r
+        memset (FileBuffer + DebugEntry->FileOffset, 0, DebugEntry->SizeOfData);\r
+        memset (DebugEntry, 0, sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY));\r
+      }\r
+      if (DebugEntry->Type == EFI_IMAGE_DEBUG_TYPE_CODEVIEW) {\r
+        RsdsEntry = (EFI_IMAGE_DEBUG_CODEVIEW_RSDS_ENTRY *) (FileBuffer + DebugEntry->FileOffset);\r
+        if (RsdsEntry->Signature == CODEVIEW_SIGNATURE_MTOC) {\r
+          // MTOC sets DebugDirectoryEntrySize to size of the .debug section, so fix it.\r
+          if (!ZeroDebugFlag) {\r
+            if (Optional32Hdr->Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
+              Optional32Hdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].Size = sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY);\r
+            } else {\r
+              Optional64Hdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].Size = sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY);\r
+            }\r
+          }\r
+          break;\r
+        }\r
+      }\r
     }\r
   }\r
 \r
@@ -2927,7 +2962,7 @@ Returns:
   EFI_IMAGE_OPTIONAL_HEADER64     *Optional64Hdr;\r
   EFI_IMAGE_SECTION_HEADER        *SectionHeader;\r
   UINT32                          *NewTimeStamp;\r
-  \r
+\r
   //\r
   // Init variable.\r
   //\r
@@ -3029,8 +3064,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
@@ -3145,7 +3182,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