1. GenSec tool only updates output file when the contents of the output file are...
authorlgao4 <lgao4@7335b38e-4728-0410-8992-fb3ffe349368>
Thu, 24 Apr 2008 04:11:15 +0000 (04:11 +0000)
committerlgao4 <lgao4@7335b38e-4728-0410-8992-fb3ffe349368>
Thu, 24 Apr 2008 04:11:15 +0000 (04:11 +0000)
2. GenFfs tool checks the Pe/Te section for PEI and DXE file type. If Pe section doesn't exist, GenFfs tool will report error.
3. GenFv tool also output the relative address of function to fv map file for developer reference.

git-svn-id: https://buildtools.tianocore.org/svn/buildtools/trunk/BaseTools@1175 7335b38e-4728-0410-8992-fb3ffe349368

Source/C/GenFfs/GenFfs.c
Source/C/GenFv/GenFvInternalLib.c
Source/C/GenSec/GenSec.c

index 87d64aa..602bb38 100644 (file)
@@ -238,7 +238,8 @@ GetSectionContents (
   IN  UINT32  InputFileNum,\r
   OUT UINT8   *FileBuffer,\r
   OUT UINT32  *BufferLength,\r
-  OUT UINT32  *MaxAlignment\r
+  OUT UINT32  *MaxAlignment,\r
+  OUT UINT8   *PESectionNum\r
   )\r
 /*++\r
         \r
@@ -261,6 +262,8 @@ Arguments:
                    On output, this is the actual length of the data.\r
 \r
   MaxAlignment   - The max alignment required by all the input file datas.\r
+  \r
+  PeSectionNum   - Calculate the number of Pe/Te Section in this FFS file.\r
 \r
 Returns:\r
                        \r
@@ -319,15 +322,18 @@ Returns:
               "the input section name is %s and the size is %d bytes", InputFileName[Index], FileSize); \r
 \r
     //\r
-    // Check this section is Te section\r
+    // Check this section is Te/Pe section, and Calculate the numbers of Te/Pe section.\r
     //\r
     TeOffset = 0;\r
     fread (&TempSectHeader, 1, sizeof (TempSectHeader), InFile);\r
     if (TempSectHeader.Type == EFI_SECTION_TE) {\r
+      (*PESectionNum) ++;\r
       fread (&TeHeader, 1, sizeof (TeHeader), InFile);\r
       if (TeHeader.Signature == EFI_TE_IMAGE_HEADER_SIGNATURE) {\r
         TeOffset = TeHeader.StrippedSize - sizeof (TeHeader);\r
       }\r
+    } else if (TempSectHeader.Type == EFI_SECTION_PE32) {\r
+      (*PESectionNum) ++;\r
     }\r
     fseek (InFile, 0, SEEK_SET);\r
 \r
@@ -428,6 +434,7 @@ Returns:
   FILE                    *FfsFile;\r
   UINT32                  Index;\r
   UINT64                  LogLevel;\r
+  UINT8                   PeSectionNum;\r
   \r
   //\r
   // Init local variables\r
@@ -446,6 +453,7 @@ Returns:
   MaxAlignment   = 1;\r
   FfsFile        = NULL;\r
   Status         = EFI_SUCCESS;\r
+  PeSectionNum   = 0;\r
 \r
   SetUtilityName (UTILITY_NAME);\r
 \r
@@ -729,7 +737,7 @@ Returns:
     }\r
     VerboseMsg ("the %dth input section name is %s and section alignment is %d", Index, InputFileName[Index], InputFileAlign[Index]);\r
   }\r
-\r
+  \r
   //\r
   // Calculate the size of all input section files.\r
   //  \r
@@ -739,8 +747,24 @@ Returns:
              InputFileNum,\r
              FileBuffer,\r
              &FileSize,\r
-             &MaxAlignment\r
+             &MaxAlignment,\r
+             &PeSectionNum\r
              );\r
+  \r
+  if ((FfsFiletype == EFI_FV_FILETYPE_SECURITY_CORE || \r
+      FfsFiletype == EFI_FV_FILETYPE_PEI_CORE ||\r
+      FfsFiletype == EFI_FV_FILETYPE_DXE_CORE) && (PeSectionNum != 1)) {\r
+    Error (NULL, 0, 2000, "Invalid parameter", "Fv File type %s must have one and only one Pe or Te section, but %d Pe/Te section are input", mFfsFileType [FfsFiletype], PeSectionNum);\r
+    goto Finish;\r
+  }\r
+  \r
+  if ((FfsFiletype == EFI_FV_FILETYPE_PEIM ||\r
+      FfsFiletype == EFI_FV_FILETYPE_DRIVER ||\r
+      FfsFiletype == EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER ||\r
+      FfsFiletype == EFI_FV_FILETYPE_APPLICATION) && (PeSectionNum < 1)) {\r
+    Error (NULL, 0, 2000, "Invalid parameter", "Fv File type %s must have at least one Pe or Te section, but no Pe/Te section is input", mFfsFileType [FfsFiletype]);\r
+    goto Finish;   \r
+  }\r
 \r
   if (Status == EFI_BUFFER_TOO_SMALL) {\r
     FileBuffer = (UINT8 *) malloc (FileSize);\r
@@ -759,7 +783,8 @@ Returns:
                InputFileNum,\r
                FileBuffer,\r
                &FileSize,\r
-               &MaxAlignment\r
+               &MaxAlignment,\r
+               &PeSectionNum\r
                );\r
   }\r
 \r
index 7a84183..60db4e9 100644 (file)
@@ -2690,19 +2690,23 @@ Returns:
     if (FunctionType == 1) {\r
       sscanf (Line, "%s %s %lx %s", KeyWord, FunctionName, &FunctionAddress, FunctionTypeName);\r
       if (FunctionTypeName [1] == '\0' && (FunctionTypeName [0] == 'f' || FunctionTypeName [0] == 'F')) {\r
-        fprintf (FvMapFile, "  %016lx F  ", ImageBaseAddress + FunctionAddress);\r
+        fprintf (FvMapFile, "  %016lx ", ImageBaseAddress + FunctionAddress);\r
+        fprintf (FvMapFile, "(%08lx) F  ", FunctionAddress - Offset);\r
         fprintf (FvMapFile, "%s\n", FunctionName);\r
     } else {\r
-        fprintf (FvMapFile, "  %016lx    ", ImageBaseAddress + FunctionAddress);\r
+        fprintf (FvMapFile, "  %016lx ", ImageBaseAddress + FunctionAddress);\r
+        fprintf (FvMapFile, "(%08lx)    ", FunctionAddress - Offset);\r
         fprintf (FvMapFile, "%s\n", FunctionName);\r
       }\r
     } else if (FunctionType == 2) {\r
       sscanf (Line, "%s %s %lx %s", KeyWord, FunctionName, &FunctionAddress, FunctionTypeName);\r
       if (FunctionTypeName [1] == '\0' && (FunctionTypeName [0] == 'f' || FunctionTypeName [0] == 'F')) {\r
-        fprintf (FvMapFile, "  %016lx FS ", ImageBaseAddress + FunctionAddress);\r
+        fprintf (FvMapFile, "  %016lx ", ImageBaseAddress + FunctionAddress);\r
+        fprintf (FvMapFile, "(%08lx) FS ", FunctionAddress - Offset);\r
         fprintf (FvMapFile, "%s\n", FunctionName);\r
       } else {\r
-        fprintf (FvMapFile, "  %016lx    ", ImageBaseAddress + FunctionAddress);\r
+        fprintf (FvMapFile, "  %016lx ", ImageBaseAddress + FunctionAddress);\r
+        fprintf (FvMapFile, "(%08lx)    ", FunctionAddress - Offset);\r
         fprintf (FvMapFile, "%s\n", FunctionName);\r
       }\r
     }\r
index 0196f3a..285cc32 100644 (file)
@@ -184,9 +184,9 @@ Returns:
 }\r
 \r
 VOID\r
-Ascii2UnicodeWriteString (\r
+Ascii2UnicodeString (\r
   CHAR8    *String,\r
-  FILE     *OutFile\r
+  CHAR16   *UniString\r
   )\r
 /*++\r
 \r
@@ -196,8 +196,8 @@ Routine Description:
 \r
 Arguments:\r
 \r
-  String    - Pointer to string that is written to FILE.\r
-  OutFile   - Pointer to FILE\r
+  String      - Pointer to string that is written to FILE.\r
+  UniString   - Pointer to unicode string\r
 \r
 Returns:\r
 \r
@@ -205,19 +205,13 @@ Returns:
 \r
 --*/\r
 {\r
-  UINT32 Index;\r
-  UINT8  AsciiNull;\r
-\r
-  AsciiNull = 0;\r
-\r
+  while (*String != '\0') {\r
+    *(UniString++) = (CHAR16) *(String++);\r
+  }\r
   //\r
-  // Next, write out the string... Convert ASCII to Unicode in the process.\r
+  // End the UniString with a NULL.\r
   //\r
-  Index = 0;\r
-  do {\r
-    fwrite (&String[Index], 1, 1, OutFile);\r
-    fwrite (&AsciiNull, 1, 1, OutFile);\r
-  } while (String[Index++] != 0);\r
+  *UniString = '\0';\r
 } \r
 \r
 STATUS\r
@@ -225,7 +219,7 @@ GenSectionCommonLeafSection (
   CHAR8   **InputFileName,\r
   UINT32  InputFileNum,\r
   UINT8   SectionType,\r
-  FILE    *OutFile\r
+  UINT8   **OutFileBuffer\r
   )\r
 /*++\r
         \r
@@ -245,7 +239,7 @@ Arguments:
 \r
   SectionType    - A valid section type string\r
 \r
-  OutFile        - Output file handle\r
+  OutFileBuffer  - Buffer pointer to Output file contents\r
 \r
 Returns:\r
                        \r
@@ -258,7 +252,7 @@ Returns:
   FILE                      *InFile;\r
   UINT8                     *Buffer;\r
   UINT32                    TotalLength;\r
-  EFI_COMMON_SECTION_HEADER CommonSect;\r
+  EFI_COMMON_SECTION_HEADER *CommonSect;\r
   STATUS                    Status;\r
 \r
   if (InputFileNum > 1) {\r
@@ -286,11 +280,7 @@ Returns:
   InputFileLength = ftell (InFile);\r
   fseek (InFile, 0, SEEK_SET);\r
   DebugMsg (NULL, 0, 9, "Input file", "File name is %s and File size is %d bytes", InputFileName[0], InputFileLength);\r
-  //\r
-  // Fill in the fields in the local section header structure\r
-  //\r
-  CommonSect.Type = (EFI_SECTION_TYPE) SectionType;\r
-  TotalLength     = sizeof (CommonSect) + InputFileLength;\r
+  TotalLength     = sizeof (EFI_COMMON_SECTION_HEADER) + InputFileLength;\r
   //\r
   // Size must fit in 3 bytes\r
   //\r
@@ -300,39 +290,37 @@ Returns:
   }\r
   VerboseMsg ("the size of the created section file is %d bytes", TotalLength);\r
   //\r
-  // Now copy the size into the section header and write out the section header\r
+  // Fill in the fields in the local section header structure\r
   //\r
-  memcpy (&CommonSect.Size, &TotalLength, 3);\r
-  fwrite (&CommonSect, sizeof (CommonSect), 1, OutFile);\r
+  Buffer = (UINT8 *) malloc ((size_t) TotalLength);\r
+  if (Buffer == NULL) {\r
+    Error (NULL, 0, 4001, "Resource", "memory cannot be allcoated"); \r
+    goto Done;\r
+  }\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
+  \r
   //\r
-  // Allocate a buffer to read in the contents of the input file. Then\r
-  // read it in as one block and write it to the output file.\r
+  // read data from the input file.\r
   //\r
   if (InputFileLength != 0) {\r
-    Buffer = (UINT8 *) malloc ((size_t) InputFileLength);\r
-    if (Buffer == NULL) {\r
-      Error (NULL, 0, 4001, "Resource", "memory cannot be allcoated"); \r
-      goto Done;\r
-    }\r
-\r
-    if (fread (Buffer, (size_t) InputFileLength, 1, InFile) != 1) {\r
+    if (fread (Buffer + sizeof (EFI_COMMON_SECTION_HEADER), (size_t) InputFileLength, 1, InFile) != 1) {\r
       Error (NULL, 0, 0004, "Error reading file", InputFileName[0]);\r
       goto Done;\r
     }\r
-\r
-    if (fwrite (Buffer, (size_t) InputFileLength, 1, OutFile) != 1) {\r
-      Error (NULL, 0, 0002, "Error writing file", NULL);\r
-      goto Done;\r
-    }\r
   }\r
 \r
+  //\r
+  // Set OutFileBuffer \r
+  //\r
+  *OutFileBuffer = Buffer;\r
   Status = STATUS_SUCCESS;\r
 \r
 Done:\r
   fclose (InFile);\r
-  if (Buffer != NULL) {\r
-    free (Buffer);\r
-  }\r
 \r
   return Status;\r
 }\r
@@ -444,10 +432,10 @@ Returns:
 \r
 EFI_STATUS\r
 GenSectionCompressionSection (\r
-  CHAR8    **InputFileName,\r
+  CHAR8   **InputFileName,\r
   UINT32  InputFileNum,\r
   UINT8   SectCompSubType,\r
-  FILE    *OutFile\r
+  UINT8   **OutFileBuffer\r
   )\r
 /*++\r
         \r
@@ -466,7 +454,7 @@ Arguments:
 \r
   SectCompSubType - Specify the compression algorithm requested. \r
   \r
-  OutFile        - Output file handle\r
+  OutFileBuffer   - Buffer pointer to Output file contents\r
 \r
 Returns:\r
                        \r
@@ -482,7 +470,7 @@ Returns:
   UINT8                   *FileBuffer;\r
   UINT8                   *OutputBuffer;\r
   EFI_STATUS              Status;\r
-  EFI_COMPRESSION_SECTION CompressionSect;\r
+  EFI_COMPRESSION_SECTION *CompressionSect;\r
   COMPRESS_FUNCTION       CompressFunction;\r
 \r
   InputLength       = 0;\r
@@ -548,13 +536,13 @@ Returns:
 \r
     Status = CompressFunction (FileBuffer, InputLength, OutputBuffer, &CompressedLength);\r
     if (Status == EFI_BUFFER_TOO_SMALL) {\r
-      OutputBuffer = malloc (CompressedLength);\r
+      OutputBuffer = malloc (CompressedLength + sizeof (EFI_COMPRESSION_SECTION));\r
       if (!OutputBuffer) {\r
         free (FileBuffer);\r
         return EFI_OUT_OF_RESOURCES;\r
       }\r
 \r
-      Status = CompressFunction (FileBuffer, InputLength, OutputBuffer, &CompressedLength);\r
+      Status = CompressFunction (FileBuffer, InputLength, OutputBuffer + sizeof (EFI_COMPRESSION_SECTION), &CompressedLength);\r
     }\r
 \r
     free (FileBuffer);\r
@@ -587,16 +575,20 @@ Returns:
   //\r
   // Add the section header for the compressed data\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
-  fwrite (&CompressionSect, sizeof (CompressionSect), 1, OutFile);\r
-  fwrite (FileBuffer, CompressedLength, 1, OutFile);\r
-  free (FileBuffer);\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
+  // Set OutFileBuffer \r
+  //\r
+  *OutFileBuffer = FileBuffer;\r
+\r
   return EFI_SUCCESS;\r
 }\r
 \r
@@ -607,7 +599,7 @@ GenSectionGuidDefinedSection (
   EFI_GUID *VendorGuid,\r
   UINT16   DataAttribute,\r
   UINT32   DataHeaderSize,\r
-  FILE     *OutFile\r
+  UINT8    **OutFileBuffer\r
   )\r
 /*++\r
         \r
@@ -630,7 +622,7 @@ Arguments:
   \r
   DataHeaderSize- Guided Data Header Size\r
   \r
-  OutFile       - Output file handle\r
+  OutFileBuffer   - Buffer pointer to Output file contents\r
 \r
 Returns:\r
                        \r
@@ -643,14 +635,23 @@ Returns:
 {\r
   UINT32                TotalLength;\r
   UINT32                InputLength;\r
+  UINT32                Offset;\r
   UINT8                 *FileBuffer;\r
   UINT32                Crc32Checksum;\r
   EFI_STATUS            Status;\r
-  CRC32_SECTION_HEADER  Crc32GuidSect;\r
-  EFI_GUID_DEFINED_SECTION  VendorGuidSect;\r
+  CRC32_SECTION_HEADER  *Crc32GuidSect;\r
+  EFI_GUID_DEFINED_SECTION  *VendorGuidSect;\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
+\r
   //\r
   // read all input file contents into a buffer\r
   // first get the size of all file contents\r
@@ -663,7 +664,7 @@ Returns:
             );\r
 \r
   if (Status == EFI_BUFFER_TOO_SMALL) {\r
-    FileBuffer = (UINT8 *) malloc (InputLength);\r
+    FileBuffer = (UINT8 *) malloc (InputLength + Offset);\r
     if (FileBuffer == NULL) {\r
       Error (NULL, 0, 4001, "Resource", "memory cannot be allcoated");\r
       return EFI_OUT_OF_RESOURCES;\r
@@ -674,7 +675,7 @@ Returns:
     Status = GetSectionContents (\r
               InputFileName,\r
               InputFileNum,\r
-              FileBuffer,\r
+              FileBuffer + Offset,\r
               &InputLength\r
               );\r
   }\r
@@ -687,14 +688,14 @@ Returns:
   }\r
 \r
   //\r
-  // Now data is in FileBuffer\r
+  // Now data is in FileBuffer + Offset\r
   //\r
   if (CompareGuid (VendorGuid, &mEfiCrc32SectionGuid) == 0) {\r
     //\r
     // Default Guid section is CRC32.\r
     //\r
     Crc32Checksum = 0;\r
-    CalculateCrc32 (FileBuffer, InputLength, &Crc32Checksum);\r
+    CalculateCrc32 (FileBuffer + Offset, InputLength, &Crc32Checksum);\r
 \r
     TotalLength = InputLength + sizeof (CRC32_SECTION_HEADER);\r
     if (TotalLength >= MAX_SECTION_SIZE) {\r
@@ -702,16 +703,17 @@ Returns:
       free (FileBuffer);\r
       return STATUS_ERROR;\r
     }\r
-\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
-    fwrite (&Crc32GuidSect, sizeof (Crc32GuidSect), 1, OutFile);  \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 %d", Crc32GuidSect->GuidSectionHeader.DataOffset);\r
 \r
   } else {\r
     TotalLength = InputLength + sizeof (EFI_GUID_DEFINED_SECTION);\r
@@ -721,21 +723,23 @@ Returns:
       return STATUS_ERROR;\r
     }\r
 \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  = sizeof (EFI_GUID_DEFINED_SECTION) + DataHeaderSize;\r
-    fwrite (&VendorGuidSect, sizeof (EFI_GUID_DEFINED_SECTION), 1, OutFile);  \r
-    DebugMsg (NULL, 0, 9, "Guided section", "Data offset is %d", VendorGuidSect.DataOffset);\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  = sizeof (EFI_GUID_DEFINED_SECTION) + DataHeaderSize;\r
+    DebugMsg (NULL, 0, 9, "Guided section", "Data offset is %d", VendorGuidSect->DataOffset);\r
   }\r
   VerboseMsg ("the size of the created section file is %d bytes", TotalLength);\r
-\r
-  fwrite (FileBuffer, InputLength, 1, OutFile);\r
-  free (FileBuffer);\r
   \r
+  //\r
+  // Set OutFileBuffer \r
+  //\r
+  *OutFileBuffer = FileBuffer;\r
+\r
   return EFI_SUCCESS;\r
 }\r
 \r
@@ -777,9 +781,12 @@ Returns:
   UINT8                     SectCompSubType;\r
   UINT16                    SectGuidAttribute; \r
   UINT64                    SectGuidHeaderLength;\r
-  EFI_COMMON_SECTION_HEADER CommonSect;\r
+  EFI_VERSION_SECTION       *VersionSect;\r
+  EFI_USER_INTERFACE_SECTION *UiSect;\r
   UINT32                    InputLength;\r
-  UINT8                     *FileBuffer;\r
+  UINT8                     *OutFileBuffer;\r
+  UINT8                     *TempBuffer;\r
+  UINT32                    TempLength;\r
   EFI_STATUS                Status;\r
   UINT64                    LogLevel;\r
   \r
@@ -795,11 +802,14 @@ Returns:
   SectType              = EFI_SECTION_ALL;\r
   SectCompSubType       = 0;\r
   SectGuidAttribute     = 0;\r
-  FileBuffer            = NULL;\r
+  OutFileBuffer         = NULL;\r
   InputLength           = 0;\r
   Status                = STATUS_SUCCESS;\r
   LogLevel              = 0;\r
   SectGuidHeaderLength  = 0;\r
+  VersionSect           = NULL;\r
+  UiSect                = NULL;\r
+  TempBuffer            = NULL;\r
   \r
   SetUtilityName (UTILITY_NAME);\r
   \r
@@ -1132,15 +1142,6 @@ Returns:
   }\r
   VerboseMsg ("Output file name is %s", OutputFileName);\r
 \r
-  //\r
-  // Open output file\r
-  //\r
-  OutFile = fopen (OutputFileName, "wb");\r
-  if (OutFile == NULL) {\r
-    Error (NULL, 0, 0001, "Error opening file", OutputFileName);\r
-    goto Finish;\r
-  }\r
-  \r
   //\r
   // At this point, we've fully validated the command line, and opened appropriate\r
   // files, so let's go and do what we've been asked to do...\r
@@ -1155,7 +1156,7 @@ Returns:
               InputFileName,\r
               InputFileNum,\r
               SectCompSubType,\r
-              OutFile\r
+              &OutFileBuffer\r
               );\r
     break;\r
 \r
@@ -1166,14 +1167,12 @@ Returns:
               &VendorGuid,\r
               SectGuidAttribute,\r
               (UINT32) SectGuidHeaderLength,\r
-              OutFile\r
+              &OutFileBuffer\r
               );\r
     break;\r
 \r
   case EFI_SECTION_VERSION:\r
-    CommonSect.Type = (EFI_SECTION_TYPE) SectType;\r
-\r
-    Index           = sizeof (CommonSect);\r
+    Index           = sizeof (EFI_COMMON_SECTION_HEADER);\r
     //\r
     // 2 bytes for the build number UINT16\r
     //\r
@@ -1182,25 +1181,40 @@ Returns:
     // StringBuffer is ascii.. unicode is 2X + 2 bytes for terminating unicode null.\r
     //\r
     Index += (strlen (StringBuffer) * 2) + 2;\r
-    memcpy (&CommonSect.Size, &Index, 3);\r
-    fwrite (&CommonSect, sizeof (CommonSect), 1, OutFile);\r
-    fwrite (&VersionNumber, sizeof (UINT16), 1, OutFile);\r
-    Ascii2UnicodeWriteString (StringBuffer, OutFile);\r
+    OutFileBuffer = (UINT8 *) malloc (Index);\r
+    if (OutFileBuffer == NULL) {\r
+      Error (NULL, 0, 4001, "Resource", "memory cannot be allcoated");\r
+      goto Finish;\r
+    }\r
+    VersionSect = (EFI_VERSION_SECTION *) OutFileBuffer;\r
+    VersionSect->CommonHeader.Type     = SectType;\r
+    VersionSect->CommonHeader.Size[0]  = (UINT8) (Index & 0xff);\r
+    VersionSect->CommonHeader.Size[1]  = (UINT8) ((Index & 0xff00) >> 8);\r
+    VersionSect->CommonHeader.Size[2]  = (UINT8) ((Index & 0xff0000) >> 16);\r
+    VersionSect->BuildNumber           = (UINT16) VersionNumber;\r
+    Ascii2UnicodeString (StringBuffer, VersionSect->VersionString);\r
     VerboseMsg ("the size of the created section file is %d bytes", Index);\r
     break;\r
 \r
   case EFI_SECTION_USER_INTERFACE:\r
-    CommonSect.Type = (EFI_SECTION_TYPE) SectType;\r
-    Index           = sizeof (CommonSect);\r
+    Index           = sizeof (EFI_COMMON_SECTION_HEADER);\r
     //\r
     // StringBuffer is ascii.. unicode is 2X + 2 bytes for terminating unicode null.\r
     //\r
     Index += (strlen (StringBuffer) * 2) + 2;\r
-    memcpy (&CommonSect.Size, &Index, 3);\r
-    fwrite (&CommonSect, sizeof (CommonSect), 1, OutFile);\r
-    Ascii2UnicodeWriteString (StringBuffer, OutFile);\r
+    OutFileBuffer = (UINT8 *) malloc (Index);\r
+    if (OutFileBuffer == NULL) {\r
+      Error (NULL, 0, 4001, "Resource", "memory cannot be allcoated");\r
+      goto Finish;\r
+    }\r
+    UiSect = (EFI_USER_INTERFACE_SECTION *) OutFileBuffer;\r
+    UiSect->CommonHeader.Type     = SectType;\r
+    UiSect->CommonHeader.Size[0]  = (UINT8) (Index & 0xff);\r
+    UiSect->CommonHeader.Size[1]  = (UINT8) ((Index & 0xff00) >> 8);\r
+    UiSect->CommonHeader.Size[2]  = (UINT8) ((Index & 0xff0000) >> 16);\r
+    Ascii2UnicodeString (StringBuffer, UiSect->FileNameString);\r
     VerboseMsg ("the size of the created section file is %d bytes", Index);\r
-    break;\r
+   break;\r
 \r
   case EFI_SECTION_ALL:\r
     //\r
@@ -1210,13 +1224,13 @@ Returns:
     Status = GetSectionContents (\r
               InputFileName,\r
               InputFileNum,\r
-              FileBuffer,\r
+              OutFileBuffer,\r
               &InputLength\r
               );\r
   \r
     if (Status == EFI_BUFFER_TOO_SMALL) {\r
-      FileBuffer = (UINT8 *) malloc (InputLength);\r
-      if (FileBuffer == NULL) {\r
+      OutFileBuffer = (UINT8 *) malloc (InputLength);\r
+      if (OutFileBuffer == NULL) {\r
         Error (NULL, 0, 4001, "Resource", "memory cannot be allcoated");\r
         goto Finish;\r
       }\r
@@ -1226,18 +1240,10 @@ Returns:
       Status = GetSectionContents (\r
                 InputFileName,\r
                 InputFileNum,\r
-                FileBuffer,\r
+                OutFileBuffer,\r
                 &InputLength\r
                 );\r
     }\r
-  \r
-    if (Status == EFI_SUCCESS) {\r
-      fwrite (FileBuffer, InputLength, 1, OutFile);\r
-    }\r
-\r
-    if (FileBuffer != NULL) {\r
-      free (FileBuffer);\r
-    }\r
     VerboseMsg ("the size of the created section file is %d bytes", InputLength);\r
     break;\r
   default:\r
@@ -1248,15 +1254,87 @@ Returns:
               InputFileName,\r
               InputFileNum,\r
               SectType,\r
-              OutFile\r
+              &OutFileBuffer\r
               );\r
     break;\r
   }\r
+  \r
+  //\r
+  // Get output file length\r
+  //\r
+  if (SectType != EFI_SECTION_ALL) {\r
+    InputLength = SECTION_SIZE (OutFileBuffer);\r
+  }\r
+  //\r
+  // Write the Buffer to the Output file.\r
+  //\r
+  OutFile = fopen (OutputFileName, "rb");\r
+  if (OutFile != NULL) {\r
+    //\r
+    // the output file exists\r
+    // first compare the output buffer and the exist output file \r
+    // if same, not to update output file\r
+    //\r
+    fseek (OutFile, 0, SEEK_END);\r
+    TempLength = ftell (OutFile);\r
+    fseek (OutFile, 0, SEEK_SET);\r
+\r
+    if (InputLength != TempLength) {\r
+      //\r
+      //  they can't be same because their size are different\r
+      //\r
+      goto WriteFile;\r
+    }\r
+    //\r
+    // read file data from output file\r
+    //\r
+    TempBuffer = (UINT8 *) malloc (TempLength);\r
+    if (TempBuffer == NULL) {\r
+      Error (NULL, 0, 4001, "Resource", "memory cannot be allcoated");\r
+      goto Finish;\r
+    }\r
+    fread (TempBuffer, TempLength, 1, OutFile);\r
+    //\r
+    // Compare Data byte by byte\r
+    //\r
+    for (Index = 0; Index < InputLength; Index ++) {\r
+      if (OutFileBuffer [Index] != TempBuffer [Index]) {\r
+        break;\r
+      }\r
+    }\r
+    //\r
+    // Data is same, output file doesn't need to be updated.\r
+    //\r
+    if (Index >= InputLength) {\r
+      goto Finish;\r
+    }\r
+  }\r
+\r
+WriteFile:\r
+  if (OutFile != NULL) {\r
+    fclose (OutFile);\r
+  }\r
+\r
+  OutFile = fopen (OutputFileName, "wb");\r
+  if (OutFile == NULL) {\r
+    Error (NULL, 0, 0001, "Error opening file for writing", OutputFileName);\r
+    goto Finish;\r
+  }\r
+\r
+  fwrite (OutFileBuffer, InputLength, 1, OutFile);\r
 \r
 Finish:\r
   if (InputFileName != NULL) {\r
     free (InputFileName);\r
   }\r
+  \r
+  if (TempBuffer != NULL) {\r
+    free (TempBuffer);\r
+  }\r
+\r
+  if (OutFileBuffer != NULL) {\r
+    free (OutFileBuffer);\r
+  }\r
 \r
   if (OutFile != NULL) {\r
     fclose (OutFile);\r