]> git.proxmox.com Git - mirror_edk2.git/blobdiff - BaseTools/Source/C/GenSec/GenSec.c
Sync BaseTool trunk (version r2610) into EDKII BaseTools.
[mirror_edk2.git] / BaseTools / Source / C / GenSec / GenSec.c
index d6b22aee86b7ca9604232b83f985f1df3b8129bf..63e8e13e8fc53da1e2146ff842859e6cc2e6d226 100644 (file)
@@ -1,6 +1,6 @@
 /** @file\r
 \r
-Copyright (c) 2004 - 2011, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2004 - 2013, 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
@@ -42,8 +42,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
@@ -94,6 +92,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 +153,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 - 2013, Intel Corporation. All rights reserved.\n\n");\r
 \r
   //\r
   // Details Option\r
@@ -184,7 +187,7 @@ 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
@@ -266,6 +269,7 @@ Returns:
   FILE                      *InFile;\r
   UINT8                     *Buffer;\r
   UINT32                    TotalLength;\r
+  UINT32                    HeaderLength;\r
   EFI_COMMON_SECTION_HEADER *CommonSect;\r
   STATUS                    Status;\r
 \r
@@ -298,9 +302,14 @@ Returns:
   //\r
   // Size must fit in 3 bytes\r
   //\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
+  //}\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 +322,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
@@ -421,10 +435,11 @@ 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
@@ -476,8 +491,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 +508,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 +540,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 +624,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
@@ -646,15 +682,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
@@ -672,13 +714,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
@@ -695,30 +742,40 @@ Returns:
 \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 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
   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 +836,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, &mZeroGuid) == 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 +858,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
@@ -843,42 +910,54 @@ Returns:
     //\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
@@ -935,6 +1014,7 @@ Returns:
   UINT64                    LogLevel;\r
   UINT32                    *InputFileAlign;\r
   UINT32                    InputFileAlignNum;\r
+  EFI_COMMON_SECTION_HEADER *SectionHeader;\r
 \r
   InputFileAlign        = NULL;\r
   InputFileAlignNum     = 0;\r
@@ -1262,8 +1342,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
@@ -1463,7 +1543,11 @@ 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