]> git.proxmox.com Git - mirror_edk2.git/blobdiff - BaseTools/Source/C/GenSec/GenSec.c
BaseTools: argument genfds-multi-thread create GenSec command issue
[mirror_edk2.git] / BaseTools / Source / C / GenSec / GenSec.c
index 79e8e1bebb0314b877735d0bbe515dab5cb0b3d1..46149762586ef0d7b849b3fa7333f462d5d40a3f 100644 (file)
@@ -1,6 +1,7 @@
 /** @file\r
+Creates output file that is a properly formed section per the PI spec.\r
 \r
-Copyright (c) 2004 - 2011, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2004 - 2018, 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
@@ -9,15 +10,13 @@ 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
-  GenSection.c\r
-\r
-Abstract:\r
-\r
-  Creates output file that is a properly formed section per the PI spec.\r
-\r
 **/\r
+#ifndef __GNUC__\r
+#include <windows.h>\r
+#include <io.h>\r
+#include <sys/types.h>\r
+#include <sys/stat.h>\r
+#endif\r
 \r
 #include <stdio.h>\r
 #include <stdlib.h>\r
@@ -34,6 +33,8 @@ Abstract:
 #include "Crc32.h"\r
 #include "EfiUtilityMsgs.h"\r
 #include "ParseInf.h"\r
+#include "FvLib.h"\r
+#include "PeCoffLib.h"\r
 \r
 //\r
 // GenSec Tool Information\r
@@ -42,8 +43,6 @@ Abstract:
 #define UTILITY_MAJOR_VERSION   0\r
 #define UTILITY_MINOR_VERSION   1\r
 \r
-#define MAX_SECTION_SIZE        0x1000000\r
-\r
 STATIC CHAR8      *mSectionTypeName[] = {\r
   NULL,                                 // 0x00 - reserved\r
   "EFI_SECTION_COMPRESSION",            // 0x01\r
@@ -83,7 +82,8 @@ STATIC CHAR8      *mGUIDedSectionAttribue[]  = { "NONE", "PROCESSING_REQUIRED",
 \r
 STATIC CHAR8 *mAlignName[] = {\r
   "1", "2", "4", "8", "16", "32", "64", "128", "256", "512",\r
-  "1K", "2K", "4K", "8K", "16K", "32K", "64K"\r
+  "1K", "2K", "4K", "8K", "16K", "32K", "64K", "128K", "256K",\r
+  "512K", "1M", "2M", "4M", "8M", "16M"\r
 };\r
 \r
 //\r
@@ -94,6 +94,11 @@ typedef struct {
   UINT32                    CRC32Checksum;\r
 } CRC32_SECTION_HEADER;\r
 \r
+typedef struct {\r
+  EFI_GUID_DEFINED_SECTION2 GuidSectionHeader;\r
+  UINT32                    CRC32Checksum;\r
+} CRC32_SECTION_HEADER2;\r
+\r
 STATIC EFI_GUID  mZeroGuid                 = {0x0, 0x0, 0x0, {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}};\r
 STATIC EFI_GUID  mEfiCrc32SectionGuid      = EFI_CRC32_GUIDED_SECTION_EXTRACTION_PROTOCOL_GUID;\r
 \r
@@ -150,7 +155,7 @@ 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 - 2017, Intel Corporation. All rights reserved.\n\n");\r
 \r
   //\r
   // Details Option\r
@@ -184,12 +189,16 @@ Returns:
   fprintf (stdout, "  -n String, --name String\n\\r
                         String is a NULL terminated string used in Ui section.\n");\r
   fprintf (stdout, "  -j Number, --buildnumber Number\n\\r
-                        Number is an integer value between 0000 and 9999\n\\r
+                        Number is an integer value between 0 and 65535\n\\r
                         used in Ver section.\n");\r
   fprintf (stdout, "  --sectionalign SectionAlign\n\\r
                         SectionAlign points to section alignment, which support\n\\r
-                        the alignment scope 1~64K. It is specified in same\n\\r
-                        order that the section file is input.\n");\r
+                        the alignment scope 0~16M. If SectionAlign is specified\n\\r
+                        as 0, tool get alignment value from SectionFile. It is\n\\r
+                        specified in same order that the section file is input.\n");\r
+  fprintf (stdout, "  --dummy dummyfile\n\\r
+                        compare dummpyfile with input_file to decide whether\n\\r
+                        need to set PROCESSING_REQUIRED attribute.\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
@@ -266,20 +275,21 @@ Returns:
   FILE                      *InFile;\r
   UINT8                     *Buffer;\r
   UINT32                    TotalLength;\r
+  UINT32                    HeaderLength;\r
   EFI_COMMON_SECTION_HEADER *CommonSect;\r
   STATUS                    Status;\r
 \r
   if (InputFileNum > 1) {\r
-    Error (NULL, 0, 2000, "Invalid paramter", "more than one input file specified");\r
+    Error (NULL, 0, 2000, "Invalid parameter", "more than one input file specified");\r
     return STATUS_ERROR;\r
   } else if (InputFileNum < 1) {\r
-    Error (NULL, 0, 2000, "Invalid paramter", "no input file specified");\r
+    Error (NULL, 0, 2000, "Invalid parameter", "no input file specified");\r
     return STATUS_ERROR;\r
   }\r
   //\r
   // Open the input file\r
   //\r
-  InFile = fopen (InputFileName[0], "rb");\r
+  InFile = fopen (LongFilePath (InputFileName[0]), "rb");\r
   if (InFile == NULL) {\r
     Error (NULL, 0, 0001, "Error opening file", InputFileName[0]);\r
     return STATUS_ERROR;\r
@@ -298,9 +308,14 @@ Returns:
   //\r
   // Size must fit in 3 bytes\r
   //\r
+  //if (TotalLength >= MAX_SECTION_SIZE) {\r
+  //  Error (NULL, 0, 2000, "Invalid parameter", "%s file size (0x%X) exceeds section size limit(%uM).", InputFileName[0], (unsigned) TotalLength, MAX_SECTION_SIZE>>20);\r
+  //  goto Done;\r
+  //}\r
+  HeaderLength = sizeof (EFI_COMMON_SECTION_HEADER);\r
   if (TotalLength >= MAX_SECTION_SIZE) {\r
-    Error (NULL, 0, 2000, "Invalid paramter", "%s file size (0x%X) exceeds section size limit(%uM).", InputFileName[0], (unsigned) TotalLength, MAX_SECTION_SIZE>>20);\r
-    goto Done;\r
+    TotalLength = sizeof (EFI_COMMON_SECTION_HEADER2) + InputFileLength;\r
+    HeaderLength = sizeof (EFI_COMMON_SECTION_HEADER2);\r
   }\r
   VerboseMsg ("the size of the created section file is %u bytes", (unsigned) TotalLength);\r
   //\r
@@ -313,15 +328,20 @@ Returns:
   }\r
   CommonSect = (EFI_COMMON_SECTION_HEADER *) Buffer;\r
   CommonSect->Type     = SectionType;\r
-  CommonSect->Size[0]  = (UINT8) (TotalLength & 0xff);\r
-  CommonSect->Size[1]  = (UINT8) ((TotalLength & 0xff00) >> 8);\r
-  CommonSect->Size[2]  = (UINT8) ((TotalLength & 0xff0000) >> 16);\r
+  if (TotalLength < MAX_SECTION_SIZE) {\r
+    CommonSect->Size[0]  = (UINT8) (TotalLength & 0xff);\r
+    CommonSect->Size[1]  = (UINT8) ((TotalLength & 0xff00) >> 8);\r
+    CommonSect->Size[2]  = (UINT8) ((TotalLength & 0xff0000) >> 16);\r
+  } else {\r
+    memset(CommonSect->Size, 0xff, sizeof(UINT8) * 3);\r
+    ((EFI_COMMON_SECTION_HEADER2 *)CommonSect)->ExtendedSize = TotalLength;\r
+  }\r
   \r
   //\r
   // read data from the input file.\r
   //\r
   if (InputFileLength != 0) {\r
-    if (fread (Buffer + sizeof (EFI_COMMON_SECTION_HEADER), (size_t) InputFileLength, 1, InFile) != 1) {\r
+    if (fread (Buffer + HeaderLength, (size_t) InputFileLength, 1, InFile) != 1) {\r
       Error (NULL, 0, 0004, "Error reading file", InputFileName[0]);\r
       goto Done;\r
     }\r
@@ -349,7 +369,7 @@ StringtoAlignment (
 \r
 Routine Description:\r
 \r
-  Converts Align String to align value (1~64K). \r
+  Converts Align String to align value (1~16M).\r
 \r
 Arguments:\r
 \r
@@ -421,19 +441,20 @@ Returns:
   UINT32                     Index;\r
   FILE                       *InFile;\r
   EFI_COMMON_SECTION_HEADER  *SectHeader;\r
-  EFI_COMMON_SECTION_HEADER  TempSectHeader;\r
+  EFI_COMMON_SECTION_HEADER2 TempSectHeader;\r
   EFI_TE_IMAGE_HEADER        TeHeader;\r
   UINT32                     TeOffset;\r
   EFI_GUID_DEFINED_SECTION   GuidSectHeader;\r
+  EFI_GUID_DEFINED_SECTION2  GuidSectHeader2;\r
   UINT32                     HeaderSize;\r
 \r
   if (InputFileNum < 1) {\r
-    Error (NULL, 0, 2000, "Invalid paramter", "must specify at least one input file");\r
+    Error (NULL, 0, 2000, "Invalid parameter", "must specify at least one input file");\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
   if (BufferLength == NULL) {\r
-    Error (NULL, 0, 2000, "Invalid paramter", "BufferLength can't be NULL");\r
+    Error (NULL, 0, 2000, "Invalid parameter", "BufferLength can't be NULL");\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
@@ -458,7 +479,7 @@ Returns:
     // \r
     // Open file and read contents\r
     //\r
-    InFile = fopen (InputFileName[Index], "rb");\r
+    InFile = fopen (LongFilePath (InputFileName[Index]), "rb");\r
     if (InFile == NULL) {\r
       Error (NULL, 0, 0001, "Error opening file", InputFileName[Index]);\r
       return EFI_ABORTED;\r
@@ -476,8 +497,16 @@ Returns:
       // Check this section is Te/Pe section, and Calculate the numbers of Te/Pe section.\r
       //\r
       TeOffset = 0;\r
-      HeaderSize = sizeof (EFI_COMMON_SECTION_HEADER);\r
-      fread (&TempSectHeader, 1, sizeof (TempSectHeader), InFile);\r
+      //\r
+      // The section might be EFI_COMMON_SECTION_HEADER2\r
+      // But only Type needs to be checked\r
+      //\r
+      if (FileSize >= MAX_SECTION_SIZE) {\r
+        HeaderSize = sizeof (EFI_COMMON_SECTION_HEADER2);\r
+      } else {\r
+        HeaderSize = sizeof (EFI_COMMON_SECTION_HEADER);\r
+      }\r
+      fread (&TempSectHeader, 1, HeaderSize, InFile);\r
       if (TempSectHeader.Type == EFI_SECTION_TE) {\r
         fread (&TeHeader, 1, sizeof (TeHeader), InFile);\r
         if (TeHeader.Signature == EFI_TE_IMAGE_HEADER_SIGNATURE) {\r
@@ -485,9 +514,16 @@ Returns:
         }\r
       } else if (TempSectHeader.Type == EFI_SECTION_GUID_DEFINED) {\r
         fseek (InFile, 0, SEEK_SET);\r
-        fread (&GuidSectHeader, 1, sizeof (GuidSectHeader), InFile);\r
-        if ((GuidSectHeader.Attributes & EFI_GUIDED_SECTION_PROCESSING_REQUIRED) == 0) {\r
-          HeaderSize = GuidSectHeader.DataOffset;\r
+        if (FileSize >= MAX_SECTION_SIZE) {\r
+          fread (&GuidSectHeader2, 1, sizeof (GuidSectHeader2), InFile);\r
+          if ((GuidSectHeader2.Attributes & EFI_GUIDED_SECTION_PROCESSING_REQUIRED) == 0) {\r
+            HeaderSize = GuidSectHeader2.DataOffset;\r
+          }\r
+        } else {\r
+          fread (&GuidSectHeader, 1, sizeof (GuidSectHeader), InFile);\r
+          if ((GuidSectHeader.Attributes & EFI_GUIDED_SECTION_PROCESSING_REQUIRED) == 0) {\r
+            HeaderSize = GuidSectHeader.DataOffset;\r
+          }\r
         }\r
       } \r
 \r
@@ -510,6 +546,9 @@ Returns:
         Offset = Offset - Size - HeaderSize - TeOffset;\r
          \r
         if (FileBuffer != NULL && ((Size + Offset) < *BufferLength)) {\r
+          //\r
+          // The maximal alignment is 64K, the raw section size must be less than 0xffffff\r
+          //\r
           memset (FileBuffer + Size, 0, Offset);\r
           SectHeader          = (EFI_COMMON_SECTION_HEADER *) (FileBuffer + Size);\r
           SectHeader->Type    = EFI_SECTION_RAW;\r
@@ -591,16 +630,19 @@ Returns:
   UINT32                  TotalLength;\r
   UINT32                  InputLength;\r
   UINT32                  CompressedLength;\r
+  UINT32                  HeaderLength;\r
   UINT8                   *FileBuffer;\r
   UINT8                   *OutputBuffer;\r
   EFI_STATUS              Status;\r
   EFI_COMPRESSION_SECTION *CompressionSect;\r
+  EFI_COMPRESSION_SECTION2 *CompressionSect2;\r
   COMPRESS_FUNCTION       CompressFunction;\r
 \r
   InputLength       = 0;\r
   FileBuffer        = NULL;\r
   OutputBuffer      = NULL;\r
   CompressedLength  = 0;\r
+  TotalLength       = 0;\r
   //\r
   // read all input file contents into a buffer\r
   // first get the size of all file contents\r
@@ -638,6 +680,10 @@ Returns:
     return Status;\r
   }\r
 \r
+  if (FileBuffer == NULL) {\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+\r
   CompressFunction = NULL;\r
 \r
   //\r
@@ -646,15 +692,21 @@ Returns:
   switch (SectCompSubType) {\r
   case EFI_NOT_COMPRESSED:\r
     CompressedLength = InputLength;\r
+    HeaderLength = sizeof (EFI_COMPRESSION_SECTION);\r
+    if (CompressedLength + HeaderLength >= MAX_SECTION_SIZE) {\r
+      HeaderLength = sizeof (EFI_COMPRESSION_SECTION2);\r
+    }\r
+    TotalLength = CompressedLength + HeaderLength;\r
     //\r
     // Copy file buffer to the none compressed data.\r
     //\r
-    OutputBuffer = malloc (CompressedLength + sizeof (EFI_COMPRESSION_SECTION));\r
+    OutputBuffer = malloc (TotalLength);\r
     if (OutputBuffer == NULL) {\r
       free (FileBuffer);\r
       return EFI_OUT_OF_RESOURCES;\r
     }\r
-    memcpy (OutputBuffer + sizeof (EFI_COMPRESSION_SECTION), FileBuffer, CompressedLength);\r
+    memcpy (OutputBuffer + HeaderLength, FileBuffer, CompressedLength);\r
+    free (FileBuffer);\r
     FileBuffer = OutputBuffer;\r
     break;\r
 \r
@@ -663,7 +715,7 @@ Returns:
     break;\r
 \r
   default:\r
-    Error (NULL, 0, 2000, "Invalid paramter", "unknown compression type");\r
+    Error (NULL, 0, 2000, "Invalid parameter", "unknown compression type");\r
     free (FileBuffer);\r
     return EFI_ABORTED;\r
   }\r
@@ -672,13 +724,18 @@ Returns:
 \r
     Status = CompressFunction (FileBuffer, InputLength, OutputBuffer, &CompressedLength);\r
     if (Status == EFI_BUFFER_TOO_SMALL) {\r
-      OutputBuffer = malloc (CompressedLength + sizeof (EFI_COMPRESSION_SECTION));\r
+      HeaderLength = sizeof (EFI_COMPRESSION_SECTION);\r
+      if (CompressedLength + HeaderLength >= MAX_SECTION_SIZE) {\r
+        HeaderLength = sizeof (EFI_COMPRESSION_SECTION2);\r
+      }\r
+      TotalLength = CompressedLength + HeaderLength;\r
+      OutputBuffer = malloc (TotalLength);\r
       if (!OutputBuffer) {\r
         free (FileBuffer);\r
         return EFI_OUT_OF_RESOURCES;\r
       }\r
 \r
-      Status = CompressFunction (FileBuffer, InputLength, OutputBuffer + sizeof (EFI_COMPRESSION_SECTION), &CompressedLength);\r
+      Status = CompressFunction (FileBuffer, InputLength, OutputBuffer + HeaderLength, &CompressedLength);\r
     }\r
 \r
     free (FileBuffer);\r
@@ -691,34 +748,48 @@ Returns:
 \r
       return Status;\r
     }\r
+\r
+    if (FileBuffer == NULL) {\r
+      return EFI_OUT_OF_RESOURCES;\r
+    }\r
   }\r
 \r
   DebugMsg (NULL, 0, 9, "comprss file size", \r
             "the original section size is %d bytes and the compressed section size is %u bytes", (unsigned) InputLength, (unsigned) CompressedLength);\r
-  TotalLength = CompressedLength + sizeof (EFI_COMPRESSION_SECTION);\r
-  if (TotalLength >= MAX_SECTION_SIZE) {\r
-    Error (NULL, 0, 2000, "Invalid paramter", "The size of all files exceeds section size limit(%uM).", MAX_SECTION_SIZE>>20);\r
-    if (FileBuffer != NULL) {\r
-      free (FileBuffer);\r
-    }\r
-    if (OutputBuffer != NULL) {\r
-      free (OutputBuffer);\r
-    }\r
-    return STATUS_ERROR;\r
-  }\r
+\r
+  //if (TotalLength >= MAX_SECTION_SIZE) {\r
+  //  Error (NULL, 0, 2000, "Invalid parameter", "The size of all files exceeds section size limit(%uM).", MAX_SECTION_SIZE>>20);\r
+  //  if (FileBuffer != NULL) {\r
+  //    free (FileBuffer);\r
+  //  }\r
+  //  if (OutputBuffer != NULL) {\r
+  //    free (OutputBuffer);\r
+  //  }\r
+  //  return STATUS_ERROR;\r
+  //}\r
   VerboseMsg ("the size of the created section file is %u bytes", (unsigned) TotalLength);\r
 \r
   //\r
   // Add the section header for the compressed data\r
   //\r
-  CompressionSect = (EFI_COMPRESSION_SECTION *) FileBuffer;\r
-  \r
-  CompressionSect->CommonHeader.Type     = EFI_SECTION_COMPRESSION;\r
-  CompressionSect->CommonHeader.Size[0]  = (UINT8) (TotalLength & 0xff);\r
-  CompressionSect->CommonHeader.Size[1]  = (UINT8) ((TotalLength & 0xff00) >> 8);\r
-  CompressionSect->CommonHeader.Size[2]  = (UINT8) ((TotalLength & 0xff0000) >> 16);\r
-  CompressionSect->CompressionType       = SectCompSubType;\r
-  CompressionSect->UncompressedLength    = InputLength;\r
+  if (TotalLength >= MAX_SECTION_SIZE) {\r
+    CompressionSect2 = (EFI_COMPRESSION_SECTION2 *)FileBuffer;\r
+\r
+    memset(CompressionSect2->CommonHeader.Size, 0xff, sizeof(UINT8) * 3);\r
+    CompressionSect2->CommonHeader.Type         = EFI_SECTION_COMPRESSION;\r
+    CompressionSect2->CommonHeader.ExtendedSize = TotalLength;\r
+    CompressionSect2->CompressionType           = SectCompSubType;\r
+    CompressionSect2->UncompressedLength        = InputLength;\r
+  } else {\r
+    CompressionSect = (EFI_COMPRESSION_SECTION *) FileBuffer;\r
+    \r
+    CompressionSect->CommonHeader.Type     = EFI_SECTION_COMPRESSION;\r
+    CompressionSect->CommonHeader.Size[0]  = (UINT8) (TotalLength & 0xff);\r
+    CompressionSect->CommonHeader.Size[1]  = (UINT8) ((TotalLength & 0xff00) >> 8);\r
+    CompressionSect->CommonHeader.Size[2]  = (UINT8) ((TotalLength & 0xff0000) >> 16);\r
+    CompressionSect->CompressionType       = SectCompSubType;\r
+    CompressionSect->UncompressedLength    = InputLength;\r
+  }\r
 \r
   //\r
   // Set OutFileBuffer \r
@@ -779,17 +850,14 @@ Returns:
   UINT32                Crc32Checksum;\r
   EFI_STATUS            Status;\r
   CRC32_SECTION_HEADER  *Crc32GuidSect;\r
+  CRC32_SECTION_HEADER2  *Crc32GuidSect2;\r
   EFI_GUID_DEFINED_SECTION  *VendorGuidSect;\r
+  EFI_GUID_DEFINED_SECTION2  *VendorGuidSect2;\r
 \r
   InputLength = 0;\r
   Offset      = 0;\r
   FileBuffer  = NULL;\r
-\r
-  if (CompareGuid (VendorGuid, &mEfiCrc32SectionGuid) == 0) {\r
-    Offset = sizeof (CRC32_SECTION_HEADER);\r
-  } else {\r
-    Offset = sizeof (EFI_GUID_DEFINED_SECTION);\r
-  }\r
+  TotalLength = 0;\r
 \r
   //\r
   // read all input file contents into a buffer\r
@@ -804,6 +872,19 @@ Returns:
             );\r
 \r
   if (Status == EFI_BUFFER_TOO_SMALL) {\r
+    if (CompareGuid (VendorGuid, &mZeroGuid) == 0) {\r
+      Offset = sizeof (CRC32_SECTION_HEADER);\r
+      if (InputLength + Offset >= MAX_SECTION_SIZE) {\r
+        Offset = sizeof (CRC32_SECTION_HEADER2);\r
+      }\r
+    } else {\r
+      Offset = sizeof (EFI_GUID_DEFINED_SECTION);\r
+      if (InputLength + Offset >= MAX_SECTION_SIZE) {\r
+        Offset = sizeof (EFI_GUID_DEFINED_SECTION2);\r
+      }\r
+    }\r
+    TotalLength = InputLength + Offset;\r
+\r
     FileBuffer = (UINT8 *) malloc (InputLength + Offset);\r
     if (FileBuffer == NULL) {\r
       Error (NULL, 0, 4001, "Resource", "memory cannot be allcoated");\r
@@ -830,55 +911,78 @@ Returns:
   }\r
 \r
   if (InputLength == 0) {\r
+    if (FileBuffer != NULL) {\r
+      free (FileBuffer);\r
+    }\r
     Error (NULL, 0, 2000, "Invalid parameter", "the size of input file %s can't be zero", InputFileName);\r
     return EFI_NOT_FOUND;\r
   }\r
 \r
+  //\r
+  // InputLength != 0, but FileBuffer == NULL means out of resources.\r
+  //\r
+  if (FileBuffer == NULL) {\r
+    Error (NULL, 0, 4001, "Resource", "memory cannot be allcoated");\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+\r
   //\r
   // Now data is in FileBuffer + Offset\r
   //\r
-  if (CompareGuid (VendorGuid, &mEfiCrc32SectionGuid) == 0) {\r
+  if (CompareGuid (VendorGuid, &mZeroGuid) == 0) {\r
     //\r
     // Default Guid section is CRC32.\r
     //\r
     Crc32Checksum = 0;\r
     CalculateCrc32 (FileBuffer + Offset, InputLength, &Crc32Checksum);\r
-\r
-    TotalLength = InputLength + sizeof (CRC32_SECTION_HEADER);\r
+    \r
     if (TotalLength >= MAX_SECTION_SIZE) {\r
-      Error (NULL, 0, 2000, "Invalid paramter", "The size of all files exceeds section size limit(%uM).", MAX_SECTION_SIZE>>20);\r
-      free (FileBuffer);\r
-      return STATUS_ERROR;\r
+      Crc32GuidSect2 = (CRC32_SECTION_HEADER2 *) FileBuffer;\r
+      Crc32GuidSect2->GuidSectionHeader.CommonHeader.Type     = EFI_SECTION_GUID_DEFINED;\r
+      Crc32GuidSect2->GuidSectionHeader.CommonHeader.Size[0]  = (UINT8) 0xff;\r
+      Crc32GuidSect2->GuidSectionHeader.CommonHeader.Size[1]  = (UINT8) 0xff;\r
+      Crc32GuidSect2->GuidSectionHeader.CommonHeader.Size[2]  = (UINT8) 0xff;\r
+      Crc32GuidSect2->GuidSectionHeader.CommonHeader.ExtendedSize = TotalLength;\r
+      memcpy (&(Crc32GuidSect2->GuidSectionHeader.SectionDefinitionGuid), &mEfiCrc32SectionGuid, sizeof (EFI_GUID));\r
+      Crc32GuidSect2->GuidSectionHeader.Attributes  = EFI_GUIDED_SECTION_AUTH_STATUS_VALID;\r
+      Crc32GuidSect2->GuidSectionHeader.DataOffset  = sizeof (CRC32_SECTION_HEADER2);\r
+      Crc32GuidSect2->CRC32Checksum                 = Crc32Checksum;\r
+      DebugMsg (NULL, 0, 9, "Guided section", "Data offset is %u", Crc32GuidSect2->GuidSectionHeader.DataOffset);\r
+    } else {\r
+      Crc32GuidSect = (CRC32_SECTION_HEADER *) FileBuffer;\r
+      Crc32GuidSect->GuidSectionHeader.CommonHeader.Type     = EFI_SECTION_GUID_DEFINED;\r
+      Crc32GuidSect->GuidSectionHeader.CommonHeader.Size[0]  = (UINT8) (TotalLength & 0xff);\r
+      Crc32GuidSect->GuidSectionHeader.CommonHeader.Size[1]  = (UINT8) ((TotalLength & 0xff00) >> 8);\r
+      Crc32GuidSect->GuidSectionHeader.CommonHeader.Size[2]  = (UINT8) ((TotalLength & 0xff0000) >> 16);\r
+      memcpy (&(Crc32GuidSect->GuidSectionHeader.SectionDefinitionGuid), &mEfiCrc32SectionGuid, sizeof (EFI_GUID));\r
+      Crc32GuidSect->GuidSectionHeader.Attributes  = EFI_GUIDED_SECTION_AUTH_STATUS_VALID;\r
+      Crc32GuidSect->GuidSectionHeader.DataOffset  = sizeof (CRC32_SECTION_HEADER);\r
+      Crc32GuidSect->CRC32Checksum                 = Crc32Checksum;\r
+      DebugMsg (NULL, 0, 9, "Guided section", "Data offset is %u", Crc32GuidSect->GuidSectionHeader.DataOffset);\r
     }\r
-    \r
-    Crc32GuidSect = (CRC32_SECTION_HEADER *) FileBuffer;\r
-    Crc32GuidSect->GuidSectionHeader.CommonHeader.Type     = EFI_SECTION_GUID_DEFINED;\r
-    Crc32GuidSect->GuidSectionHeader.CommonHeader.Size[0]  = (UINT8) (TotalLength & 0xff);\r
-    Crc32GuidSect->GuidSectionHeader.CommonHeader.Size[1]  = (UINT8) ((TotalLength & 0xff00) >> 8);\r
-    Crc32GuidSect->GuidSectionHeader.CommonHeader.Size[2]  = (UINT8) ((TotalLength & 0xff0000) >> 16);\r
-    memcpy (&(Crc32GuidSect->GuidSectionHeader.SectionDefinitionGuid), &mEfiCrc32SectionGuid, sizeof (EFI_GUID));\r
-    Crc32GuidSect->GuidSectionHeader.Attributes  = EFI_GUIDED_SECTION_AUTH_STATUS_VALID;\r
-    Crc32GuidSect->GuidSectionHeader.DataOffset  = sizeof (CRC32_SECTION_HEADER);\r
-    Crc32GuidSect->CRC32Checksum                 = Crc32Checksum;\r
-    DebugMsg (NULL, 0, 9, "Guided section", "Data offset is %u", Crc32GuidSect->GuidSectionHeader.DataOffset);\r
-\r
   } else {\r
-    TotalLength = InputLength + sizeof (EFI_GUID_DEFINED_SECTION);\r
     if (TotalLength >= MAX_SECTION_SIZE) {\r
-      Error (NULL, 0, 2000, "Invalid paramter", "The size of all files exceeds section size limit(%uM).", MAX_SECTION_SIZE>>20);\r
-      free (FileBuffer);\r
-      return STATUS_ERROR;\r
+      VendorGuidSect2 = (EFI_GUID_DEFINED_SECTION2 *) FileBuffer;\r
+      VendorGuidSect2->CommonHeader.Type     = EFI_SECTION_GUID_DEFINED;\r
+      VendorGuidSect2->CommonHeader.Size[0]  = (UINT8) 0xff;\r
+      VendorGuidSect2->CommonHeader.Size[1]  = (UINT8) 0xff;\r
+      VendorGuidSect2->CommonHeader.Size[2]  = (UINT8) 0xff;\r
+      VendorGuidSect2->CommonHeader.ExtendedSize = InputLength + sizeof (EFI_GUID_DEFINED_SECTION2);\r
+      memcpy (&(VendorGuidSect2->SectionDefinitionGuid), VendorGuid, sizeof (EFI_GUID));\r
+      VendorGuidSect2->Attributes  = DataAttribute;\r
+      VendorGuidSect2->DataOffset  = (UINT16) (sizeof (EFI_GUID_DEFINED_SECTION2) + DataHeaderSize);\r
+      DebugMsg (NULL, 0, 9, "Guided section", "Data offset is %u", VendorGuidSect2->DataOffset);\r
+    } else {\r
+      VendorGuidSect = (EFI_GUID_DEFINED_SECTION *) FileBuffer;\r
+      VendorGuidSect->CommonHeader.Type     = EFI_SECTION_GUID_DEFINED;\r
+      VendorGuidSect->CommonHeader.Size[0]  = (UINT8) (TotalLength & 0xff);\r
+      VendorGuidSect->CommonHeader.Size[1]  = (UINT8) ((TotalLength & 0xff00) >> 8);\r
+      VendorGuidSect->CommonHeader.Size[2]  = (UINT8) ((TotalLength & 0xff0000) >> 16);\r
+      memcpy (&(VendorGuidSect->SectionDefinitionGuid), VendorGuid, sizeof (EFI_GUID));\r
+      VendorGuidSect->Attributes  = DataAttribute;\r
+      VendorGuidSect->DataOffset  = (UINT16) (sizeof (EFI_GUID_DEFINED_SECTION) + DataHeaderSize);\r
+      DebugMsg (NULL, 0, 9, "Guided section", "Data offset is %u", VendorGuidSect->DataOffset);\r
     }\r
-\r
-    VendorGuidSect = (EFI_GUID_DEFINED_SECTION *) FileBuffer;\r
-    VendorGuidSect->CommonHeader.Type     = EFI_SECTION_GUID_DEFINED;\r
-    VendorGuidSect->CommonHeader.Size[0]  = (UINT8) (TotalLength & 0xff);\r
-    VendorGuidSect->CommonHeader.Size[1]  = (UINT8) ((TotalLength & 0xff00) >> 8);\r
-    VendorGuidSect->CommonHeader.Size[2]  = (UINT8) ((TotalLength & 0xff0000) >> 16);\r
-    memcpy (&(VendorGuidSect->SectionDefinitionGuid), VendorGuid, sizeof (EFI_GUID));\r
-    VendorGuidSect->Attributes  = DataAttribute;\r
-    VendorGuidSect->DataOffset  = (UINT16) (sizeof (EFI_GUID_DEFINED_SECTION) + DataHeaderSize);\r
-    DebugMsg (NULL, 0, 9, "Guided section", "Data offset is %u", VendorGuidSect->DataOffset);\r
   }\r
   VerboseMsg ("the size of the created section file is %u bytes", (unsigned) TotalLength);\r
   \r
@@ -890,6 +994,103 @@ Returns:
   return EFI_SUCCESS;\r
 }\r
 \r
+EFI_STATUS\r
+FfsRebaseImageRead (\r
+    IN      VOID    *FileHandle,\r
+    IN      UINTN   FileOffset,\r
+    IN OUT  UINT32  *ReadSize,\r
+    OUT     VOID    *Buffer\r
+    )\r
+  /*++\r
+\r
+    Routine Description:\r
+\r
+    Support routine for the PE/COFF Loader that reads a buffer from a PE/COFF file\r
+\r
+    Arguments:\r
+\r
+   FileHandle - The handle to the PE/COFF file\r
+\r
+   FileOffset - The offset, in bytes, into the file to read\r
+\r
+   ReadSize   - The number of bytes to read from the file starting at FileOffset\r
+\r
+   Buffer     - A pointer to the buffer to read the data into.\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
+   --*/\r
+{\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 EFI_SUCCESS;\r
+}\r
+\r
+STATIC\r
+EFI_STATUS\r
+GetAlignmentFromFile(char *InFile, UINT32 *Alignment)\r
+  /*\r
+    InFile is input file for getting alignment\r
+    return the alignment\r
+    */\r
+{\r
+  FILE                           *InFileHandle;\r
+  UINT8                          *PeFileBuffer;\r
+  UINTN                          PeFileSize;\r
+  UINT32                         CurSecHdrSize;\r
+  PE_COFF_LOADER_IMAGE_CONTEXT   ImageContext;\r
+  EFI_COMMON_SECTION_HEADER      *CommonHeader;\r
+  EFI_STATUS                     Status;\r
+\r
+  InFileHandle        = NULL;\r
+  PeFileBuffer        = NULL;\r
+  *Alignment          = 0;\r
+\r
+  memset (&ImageContext, 0, sizeof (ImageContext));\r
+\r
+  InFileHandle = fopen(LongFilePath(InFile), "rb");\r
+  if (InFileHandle == NULL){\r
+    Error (NULL, 0, 0001, "Error opening file", InFile);\r
+    return EFI_ABORTED;\r
+  }\r
+  PeFileSize = _filelength (fileno(InFileHandle));\r
+  PeFileBuffer = (UINT8 *) malloc (PeFileSize);\r
+  if (PeFileBuffer == NULL) {\r
+    fclose (InFileHandle);\r
+    Error(NULL, 0, 4001, "Resource", "memory cannot be allocated  of %s", InFileHandle);\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+  fread (PeFileBuffer, sizeof (UINT8), PeFileSize, InFileHandle);\r
+  fclose (InFileHandle);\r
+  CommonHeader = (EFI_COMMON_SECTION_HEADER *) PeFileBuffer;\r
+  CurSecHdrSize = GetSectionHeaderLength(CommonHeader);\r
+  ImageContext.Handle = (VOID *) ((UINTN)PeFileBuffer + CurSecHdrSize);\r
+  ImageContext.ImageRead = (PE_COFF_LOADER_READ_FILE)FfsRebaseImageRead;\r
+  Status               = PeCoffLoaderGetImageInfo(&ImageContext);\r
+  if (EFI_ERROR (Status)) {\r
+    Error (NULL, 0, 3000, "Invalid PeImage", "The input file is %s and return status is %x", InFile, (int) Status);\r
+    return Status;\r
+   }\r
+  *Alignment = ImageContext.SectionAlignment;\r
+  // Free the allocated memory resource\r
+  if (PeFileBuffer != NULL) {\r
+    free (PeFileBuffer);\r
+    PeFileBuffer = NULL;\r
+  }\r
+  return EFI_SUCCESS;\r
+}\r
+\r
 int\r
 main (\r
   int  argc,\r
@@ -935,6 +1136,14 @@ Returns:
   UINT64                    LogLevel;\r
   UINT32                    *InputFileAlign;\r
   UINT32                    InputFileAlignNum;\r
+  EFI_COMMON_SECTION_HEADER *SectionHeader;\r
+  CHAR8                     *DummyFileName;\r
+  FILE                      *DummyFile;\r
+  UINTN                     DummyFileSize;\r
+  UINT8                     *DummyFileBuffer;\r
+  FILE                      *InFile;\r
+  UINT8                     *InFileBuffer;\r
+  UINTN                     InFileSize;\r
 \r
   InputFileAlign        = NULL;\r
   InputFileAlignNum     = 0;\r
@@ -956,6 +1165,13 @@ Returns:
   SectGuidHeaderLength  = 0;\r
   VersionSect           = NULL;\r
   UiSect                = NULL;\r
+  DummyFileSize         = 0;\r
+  DummyFileName         = NULL;\r
+  DummyFile             = NULL;\r
+  DummyFileBuffer       = NULL;\r
+  InFile                = NULL;\r
+  InFileSize            = 0;\r
+  InFileBuffer          = NULL;\r
   \r
   SetUtilityName (UTILITY_NAME);\r
   \r
@@ -1026,8 +1242,22 @@ Returns:
       argv += 2;\r
       continue;\r
     }\r
+    if (stricmp (argv[0], "--dummy") == 0) {\r
+      DummyFileName = argv[1];\r
+      if (DummyFileName == NULL) {\r
+        Error (NULL, 0, 1003, "Invalid option value", "Dummy file can't be NULL");\r
+        goto Finish;\r
+      }\r
+      argc -= 2;\r
+      argv += 2;\r
+      continue;\r
+    }\r
 \r
     if ((stricmp (argv[0], "-r") == 0) || (stricmp (argv[0], "--attributes") == 0)) {\r
+      if (argv[1] == NULL) {\r
+        Error (NULL, 0, 1003, "Invalid option value", "Guid section attributes can't be NULL");\r
+        goto Finish;\r
+      }\r
       if (stricmp (argv[1], mGUIDedSectionAttribue[EFI_GUIDED_SECTION_PROCESSING_REQUIRED]) == 0) {\r
         SectGuidAttribute |= EFI_GUIDED_SECTION_PROCESSING_REQUIRED;\r
       } else if (stricmp (argv[1], mGUIDedSectionAttribue[EFI_GUIDED_SECTION_AUTH_STATUS_VALID]) == 0) {\r
@@ -1130,7 +1360,7 @@ Returns:
         InputFileAlign = (UINT32 *) malloc (MAXIMUM_INPUT_FILE_NUM * sizeof (UINT32));\r
         if (InputFileAlign == NULL) {\r
           Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");\r
-          return 1;\r
+          goto Finish;\r
         }\r
         memset (InputFileAlign, 1, MAXIMUM_INPUT_FILE_NUM * sizeof (UINT32));\r
       } else if (InputFileAlignNum % MAXIMUM_INPUT_FILE_NUM == 0) {\r
@@ -1141,15 +1371,18 @@ Returns:
 \r
         if (InputFileAlign == NULL) {\r
           Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");\r
-          return 1;\r
+          goto Finish;\r
         }\r
         memset (&(InputFileAlign[InputFileNum]), 1, (MAXIMUM_INPUT_FILE_NUM * sizeof (UINT32)));\r
       }\r
-      \r
-      Status = StringtoAlignment (argv[1], &(InputFileAlign[InputFileAlignNum]));\r
-      if (EFI_ERROR (Status)) {\r
-        Error (NULL, 0, 1003, "Invalid option value", "%s = %s", argv[0], argv[1]);\r
-        goto Finish;\r
+      if (stricmp(argv[1], "0") == 0) {\r
+        InputFileAlign[InputFileAlignNum] = 0;\r
+      } else {\r
+        Status = StringtoAlignment (argv[1], &(InputFileAlign[InputFileAlignNum]));\r
+        if (EFI_ERROR (Status)) {\r
+          Error (NULL, 0, 1003, "Invalid option value", "%s = %s", argv[0], argv[1]);\r
+          goto Finish;\r
+        }\r
       }\r
       argc -= 2;\r
       argv += 2;\r
@@ -1164,7 +1397,7 @@ Returns:
       InputFileName = (CHAR8 **) malloc (MAXIMUM_INPUT_FILE_NUM * sizeof (CHAR8 *));\r
       if (InputFileName == NULL) {\r
         Error (NULL, 0, 4001, "Resource", "memory cannot be allcoated");\r
-        return 1;\r
+        goto Finish;\r
       }\r
       memset (InputFileName, 0, (MAXIMUM_INPUT_FILE_NUM * sizeof (CHAR8 *)));\r
     } else if (InputFileNum % MAXIMUM_INPUT_FILE_NUM == 0) {\r
@@ -1178,7 +1411,7 @@ Returns:
 \r
       if (InputFileName == NULL) {\r
         Error (NULL, 0, 4001, "Resource", "memory cannot be allcoated");\r
-        return 1;\r
+        goto Finish;\r
       }\r
       memset (&(InputFileName[InputFileNum]), 0, (MAXIMUM_INPUT_FILE_NUM * sizeof (CHAR8 *)));\r
     }\r
@@ -1192,9 +1425,83 @@ Returns:
     Error (NULL, 0, 1003, "Invalid option", "section alignment must be set for each section");\r
     goto Finish;\r
   }\r
+  for (Index = 0; Index < InputFileAlignNum; Index++)\r
+  {\r
+    if (InputFileAlign[Index] == 0) {\r
+      Status = GetAlignmentFromFile(InputFileName[Index], &(InputFileAlign[Index]));\r
+      if (EFI_ERROR(Status)) {\r
+        Error (NULL, 0, 1003, "Fail to get Alignment from %s", InputFileName[InputFileNum]);\r
+        goto Finish;\r
+      }\r
+    }\r
+  }\r
 \r
   VerboseMsg ("%s tool start.", UTILITY_NAME);\r
 \r
+  if (DummyFileName != NULL) {\r
+      //\r
+      // Open file and read contents\r
+      //\r
+      DummyFile = fopen (LongFilePath (DummyFileName), "rb");\r
+      if (DummyFile == NULL) {\r
+        Error (NULL, 0, 0001, "Error opening file", DummyFileName);\r
+        goto Finish;\r
+      }\r
+\r
+      fseek (DummyFile, 0, SEEK_END);\r
+      DummyFileSize = ftell (DummyFile);\r
+      fseek (DummyFile, 0, SEEK_SET);\r
+      DummyFileBuffer = (UINT8 *) malloc (DummyFileSize);\r
+      if (DummyFileBuffer == NULL) {\r
+        fclose(DummyFile);\r
+        Error (NULL, 0, 4001, "Resource", "memory cannot be allcoated");\r
+        goto Finish;\r
+      }\r
+\r
+      fread(DummyFileBuffer, 1, DummyFileSize, DummyFile);\r
+      fclose(DummyFile);\r
+      DebugMsg (NULL, 0, 9, "Dummy files", "the dummy file name is %s and the size is %u bytes", DummyFileName, (unsigned) DummyFileSize);\r
+\r
+      if (InputFileName == NULL) {\r
+        Error (NULL, 0, 4001, "Resource", "memory cannot be allcoated");\r
+        goto Finish;\r
+      }\r
+      InFile = fopen(LongFilePath(InputFileName[0]), "rb");\r
+      if (InFile == NULL) {\r
+        Error (NULL, 0, 0001, "Error opening file", InputFileName[0]);\r
+        goto Finish;\r
+      }\r
+\r
+      fseek (InFile, 0, SEEK_END);\r
+      InFileSize = ftell (InFile);\r
+      fseek (InFile, 0, SEEK_SET);\r
+      InFileBuffer = (UINT8 *) malloc (InFileSize);\r
+      if (InFileBuffer == NULL) {\r
+        fclose(InFile);\r
+        Error (NULL, 0, 4001, "Resource", "memory cannot be allcoated");\r
+        goto Finish;\r
+      }\r
+\r
+      fread(InFileBuffer, 1, InFileSize, InFile);\r
+      fclose(InFile);\r
+      DebugMsg (NULL, 0, 9, "Input files", "the input file name is %s and the size is %u bytes", InputFileName[0], (unsigned) InFileSize);\r
+      if (InFileSize > DummyFileSize){\r
+        if (stricmp((CHAR8 *)DummyFileBuffer, (CHAR8 *)(InFileBuffer + (InFileSize - DummyFileSize))) == 0){\r
+          SectGuidHeaderLength = InFileSize - DummyFileSize;\r
+        }\r
+      }\r
+      if (SectGuidHeaderLength == 0) {\r
+        SectGuidAttribute |= EFI_GUIDED_SECTION_PROCESSING_REQUIRED;\r
+      }\r
+      if (DummyFileBuffer != NULL) {\r
+        free (DummyFileBuffer);\r
+        DummyFileBuffer = NULL;\r
+      }\r
+      if (InFileBuffer != NULL) {\r
+        free (InFileBuffer);\r
+      }\r
+    }\r
+\r
   //\r
   // Parse all command line parameters to get the corresponding section type.\r
   //\r
@@ -1222,10 +1529,6 @@ Returns:
     VerboseMsg ("Compress method is %s", mCompressionTypeName [SectCompSubType]);\r
   } else if (stricmp (SectionName, mSectionTypeName[EFI_SECTION_GUID_DEFINED]) == 0) {\r
     SectType     = EFI_SECTION_GUID_DEFINED;\r
-\r
-    if (CompareGuid (&VendorGuid, &mZeroGuid) == 0) {\r
-      memcpy (&VendorGuid, &mEfiCrc32SectionGuid, sizeof (EFI_GUID));\r
-    }\r
     \r
     if ((SectGuidAttribute & EFI_GUIDED_SECTION_NONE) != 0) {\r
       //\r
@@ -1266,8 +1569,8 @@ Returns:
     SectType = EFI_SECTION_SMM_DEPEX;\r
   } else if (stricmp (SectionName, mSectionTypeName[EFI_SECTION_VERSION]) == 0) {\r
     SectType = EFI_SECTION_VERSION;\r
-    if (VersionNumber < 0 || VersionNumber > 9999) {\r
-      Error (NULL, 0, 1003, "Invalid option value", "%d is not in 0~9999", VersionNumber);\r
+    if (VersionNumber < 0 || VersionNumber > 65535) {\r
+      Error (NULL, 0, 1003, "Invalid option value", "%d is not in 0~65535", VersionNumber);\r
       goto Finish;\r
     }\r
     VerboseMsg ("Version section number is %d", VersionNumber);\r
@@ -1296,7 +1599,9 @@ Returns:
   //\r
   // GuidValue is only required by Guided section.\r
   //\r
-  if ((SectType != EFI_SECTION_GUID_DEFINED) && (CompareGuid (&VendorGuid, &mZeroGuid) != 0)) {\r
+  if ((SectType != EFI_SECTION_GUID_DEFINED) &&\r
+    (SectionName != NULL) &&\r
+    (CompareGuid (&VendorGuid, &mZeroGuid) != 0)) {\r
     fprintf (stdout, "Warning: the input guid value is not required for this section type %s\n", SectionName);\r
   }\r
   \r
@@ -1349,7 +1654,7 @@ Returns:
     break;\r
 \r
   case EFI_SECTION_GUID_DEFINED:\r
-    if (InputFileAlign != NULL && (CompareGuid (&VendorGuid, &mEfiCrc32SectionGuid) != 0)) {\r
+    if (InputFileAlign != NULL && (CompareGuid (&VendorGuid, &mZeroGuid) != 0)) {\r
       //\r
       // Only process alignment for the default known CRC32 guided section.\r
       // For the unknown guided section, the alignment is processed when the dummy all section (EFI_SECTION_ALL) is generated.\r
@@ -1467,13 +1772,17 @@ Returns:
   // Get output file length\r
   //\r
   if (SectType != EFI_SECTION_ALL) {\r
-    InputLength = SECTION_SIZE (OutFileBuffer);\r
+    SectionHeader = (EFI_COMMON_SECTION_HEADER *)OutFileBuffer;\r
+    InputLength = *(UINT32 *)SectionHeader->Size & 0x00ffffff;\r
+    if (InputLength == 0xffffff) {\r
+      InputLength = ((EFI_COMMON_SECTION_HEADER2 *)SectionHeader)->ExtendedSize;\r
+    }\r
   }\r
   \r
   //\r
   // Write the output file\r
   //\r
-  OutFile = fopen (OutputFileName, "wb");\r
+  OutFile = fopen (LongFilePath (OutputFileName), "wb");\r
   if (OutFile == NULL) {\r
     Error (NULL, 0, 0001, "Error opening file for writing", OutputFileName);\r
     goto Finish;\r
@@ -1497,7 +1806,11 @@ Finish:
   if (OutFile != NULL) {\r
     fclose (OutFile);\r
   }\r
-  \r
+\r
+  if (DummyFileBuffer != NULL) {\r
+    free (DummyFileBuffer);\r
+  }\r
+\r
   VerboseMsg ("%s tool done with return code is 0x%x.", UTILITY_NAME, GetUtilityStatus ());\r
 \r
   return GetUtilityStatus ();\r