Update GenFds tool to support fixup the sub FvImage when the sub FvImage is wrapped...
authorlgao4 <lgao4@7335b38e-4728-0410-8992-fb3ffe349368>
Mon, 28 Dec 2009 14:19:02 +0000 (14:19 +0000)
committerlgao4 <lgao4@7335b38e-4728-0410-8992-fb3ffe349368>
Mon, 28 Dec 2009 14:19:02 +0000 (14:19 +0000)
git-svn-id: https://buildtools.tianocore.org/svn/buildtools/trunk/BaseTools@1784 7335b38e-4728-0410-8992-fb3ffe349368

13 files changed:
Source/C/GenFfs/GenFfs.c
Source/C/GenFv/GenFv.c
Source/C/GenFv/GenFvInternalLib.c
Source/C/GenFv/GenFvInternalLib.h
Source/C/GenSec/GenSec.c
Source/Python/CommonDataClass/FdfClass.py
Source/Python/GenFds/DepexSection.py
Source/Python/GenFds/FfsFileStatement.py
Source/Python/GenFds/FfsInfStatement.py
Source/Python/GenFds/Fv.py
Source/Python/GenFds/FvImageSection.py
Source/Python/GenFds/GenFdsGlobalVariable.py
Source/Python/GenFds/GuidSection.py

index 324490a..e4f291a 100644 (file)
@@ -287,6 +287,8 @@ Returns:
   EFI_COMMON_SECTION_HEADER  TempSectHeader;\r
   EFI_TE_IMAGE_HEADER        TeHeader;\r
   UINT32                     TeOffset;\r
+  EFI_GUID_DEFINED_SECTION   GuidSectHeader;\r
+  UINT32                     HeaderSize;\r
 \r
   Size          = 0;\r
   Offset        = 0;\r
@@ -330,6 +332,7 @@ 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
     if (TempSectHeader.Type == EFI_SECTION_TE) {\r
       (*PESectionNum) ++;\r
@@ -339,8 +342,14 @@ Returns:
       }\r
     } else if (TempSectHeader.Type == EFI_SECTION_PE32) {\r
       (*PESectionNum) ++;\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
+      }\r
+      (*PESectionNum) ++;\r
     } else if (TempSectHeader.Type == EFI_SECTION_COMPRESSION || \r
-               TempSectHeader.Type == EFI_SECTION_GUID_DEFINED ||\r
                TempSectHeader.Type == EFI_SECTION_FIRMWARE_VOLUME_IMAGE) {\r
       //\r
       // for the encapsulated section, assume it contains Pe/Te section \r
@@ -358,17 +367,18 @@ Returns:
       TeOffset = InputFileAlign [Index] - (TeOffset % InputFileAlign [Index]);\r
       TeOffset = TeOffset % InputFileAlign [Index];\r
     }\r
-     \r
+\r
     //\r
     // make sure section data meet its alignment requirement by adding one raw pad section.\r
     // But the different sections have the different section header. Necessary or not?\r
     // Based on section type to adjust offset? Todo\r
     //\r
-    if ((InputFileAlign [Index] != 0) && (((Size + sizeof (EFI_COMMON_SECTION_HEADER) + TeOffset) % InputFileAlign [Index]) != 0)) {\r
-      Offset = (Size + 2 * sizeof (EFI_COMMON_SECTION_HEADER) + TeOffset + InputFileAlign [Index] - 1) & ~(InputFileAlign [Index] - 1);\r
-      Offset = Offset - Size - sizeof (EFI_COMMON_SECTION_HEADER) - TeOffset;\r
+    if ((InputFileAlign [Index] != 0) && (((Size + HeaderSize + TeOffset) % InputFileAlign [Index]) != 0)) {\r
+      Offset = (Size + sizeof (EFI_COMMON_SECTION_HEADER) + HeaderSize + TeOffset + InputFileAlign [Index] - 1) & ~(InputFileAlign [Index] - 1);\r
+      Offset = Offset - Size - HeaderSize - TeOffset;\r
        \r
       if (FileBuffer != NULL && ((Size + Offset) < *BufferLength)) {\r
+        memset (FileBuffer + Size, 0, Offset);\r
         SectHeader          = (EFI_COMMON_SECTION_HEADER *) (FileBuffer + Size);\r
         SectHeader->Type    = EFI_SECTION_RAW;\r
         SectHeader->Size[0] = (UINT8) (Offset & 0xff);\r
index 135c9ed..f3d0aff 100644 (file)
@@ -709,6 +709,17 @@ Returns:
         );\r
       DebugMsg (NULL, 0, 9, "Updated runtime driver base address", "%s = 0x%llx", EFI_FV_RUNTIME_DRIVER_BASE_ADDRESS_STRING, (unsigned long long) mFvDataInfo.RuntimeBaseAddress);\r
     }\r
+    if (mFvBaseAddressNumber > 0) {\r
+      fprintf (FpFile, FV_BASE_ADDRESS_STRING);\r
+      fprintf (FpFile, "\n");\r
+      for (Index = 0; Index < mFvBaseAddressNumber; Index ++) {\r
+        fprintf (\r
+          FpFile,\r
+          "0x%llx\n",\r
+          (unsigned long long)mFvBaseAddress[Index]\r
+          );\r
+      }\r
+    }\r
     fclose (FpFile);\r
   }\r
   \r
index d17a2ff..7bec90d 100644 (file)
@@ -159,6 +159,9 @@ UINT8                                   m64kRecoveryStartupApDataArray[SIZEOF_ST
 FV_INFO                     mFvDataInfo;\r
 CAP_INFO                    mCapDataInfo;\r
 \r
+EFI_PHYSICAL_ADDRESS mFvBaseAddress[0x10];\r
+UINT32               mFvBaseAddressNumber = 0;\r
+\r
 EFI_STATUS\r
 ParseFvInf (\r
   IN  MEMORY_FILE  *InfFile,\r
@@ -2652,6 +2655,104 @@ Returns:
   return EFI_SUCCESS;\r
 }\r
 \r
+EFI_STATUS\r
+GetChildFvFromFfs (\r
+  IN      UINT8                 FixupFlags,\r
+  IN      FV_INFO               *FvInfo, \r
+  IN      EFI_FFS_FILE_HEADER   *FfsFile,\r
+  IN      UINTN                 XipOffset,\r
+  IN      FILE                  *FvMapFile\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  This function gets all child FvImages in the input FfsFile, and records\r
+  their base address to the parent image.\r
+\r
+Arguments:\r
+  FvInfo            A pointer to FV_INFO struture.\r
+  FfsFile           A pointer to Ffs file image that may contain FvImage.\r
+  XipOffset         The offset address to the parent FvImage base.\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS        Base address of child Fv image is recorded.\r
+--*/\r
+{\r
+  EFI_STATUS                          Status;\r
+  UINTN                               Index;\r
+  EFI_FILE_SECTION_POINTER            SubFvSection;\r
+  EFI_FFS_FILE_STATE                  SavedState;\r
+  EFI_FFS_FILE_HEADER                 *SubFfsFile;\r
+  EFI_FFS_FILE_HEADER                 *NextFfsFile;\r
+  EFI_FIRMWARE_VOLUME_HEADER          *SavedFvHeader;\r
+  UINT32                              SavedFvSize;\r
+  EFI_FIRMWARE_VOLUME_HEADER          *SubFvImageHeader;\r
+  CHAR8                               SubFfsName[PRINTED_GUID_BUFFER_SIZE];\r
+  EFI_PHYSICAL_ADDRESS                SubFvBaseAddress;\r
+\r
+  ZeroMem (SubFfsName, PRINTED_GUID_BUFFER_SIZE);\r
+  GetFvHeader (&SavedFvHeader, &SavedFvSize);\r
+\r
+  for (Index = 1;; Index++) {\r
+    //\r
+    // Find FV section \r
+    //\r
+    Status = GetSectionByType (FfsFile, EFI_SECTION_FIRMWARE_VOLUME_IMAGE, Index, &SubFvSection);\r
+    if (EFI_ERROR (Status)) {\r
+      break;\r
+    }\r
+    SubFvImageHeader = (EFI_FIRMWARE_VOLUME_HEADER *) ((UINT8 *) SubFvSection.FVImageSection + sizeof (EFI_FIRMWARE_VOLUME_IMAGE_SECTION));\r
+    if ((FixupFlags & REBASE_XIP_FILE) == REBASE_XIP_FILE) {\r
+      //\r
+      // Rebase on Flash\r
+      //\r
+      SubFvBaseAddress = FvInfo->BaseAddress + (UINTN) SubFvImageHeader - (UINTN) FfsFile + XipOffset;\r
+      mFvBaseAddress[mFvBaseAddressNumber ++ ] = SubFvBaseAddress;\r
+    } else {\r
+      //\r
+      // Rebase on Memory\r
+      //\r
+      InitializeFvLib (SubFvImageHeader, (UINT32) SubFvImageHeader->FvLength);\r
+      //\r
+      // Go through FFS in this insided FvImage one by one.\r
+      //\r
+      SubFfsFile = NULL;\r
+      while (TRUE) {\r
+        GetNextFile (SubFfsFile, &NextFfsFile);\r
+        if (NextFfsFile == NULL) {\r
+          break;\r
+        }\r
+        SubFfsFile = NextFfsFile;\r
+        //\r
+        // Use FFS GUID as its File Name.\r
+        //\r
+        PrintGuidToBuffer (&SubFfsFile->Name, SubFfsName, PRINTED_GUID_BUFFER_SIZE, TRUE);\r
+        FfsRebase (FvInfo, SubFfsName, SubFfsFile, (UINTN) SubFfsFile - (UINTN) FfsFile + XipOffset, FvMapFile);\r
+      }\r
+    }\r
+  }\r
+\r
+  //\r
+  // Now update file checksum\r
+  //\r
+  if (((FixupFlags & REBASE_XIP_FILE) == 0) && (FfsFile->Attributes & FFS_ATTRIB_CHECKSUM)) {\r
+    SavedState  = FfsFile->State;\r
+    FfsFile->IntegrityCheck.Checksum.File = 0;\r
+    FfsFile->State                        = 0;\r
+    FfsFile->IntegrityCheck.Checksum.File = CalculateChecksum8 (\r
+      (UINT8 *)(FfsFile + 1),\r
+      GetLength (FfsFile->Size) - sizeof (EFI_FFS_FILE_HEADER)\r
+      );\r
+    FfsFile->State = SavedState;\r
+  }\r
+\r
+  InitializeFvLib (SavedFvHeader, SavedFvSize);\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
 EFI_STATUS\r
 FfsRebase ( \r
   IN OUT  FV_INFO               *FvInfo, \r
@@ -2749,6 +2850,17 @@ Returns:
     case EFI_FV_FILETYPE_DRIVER:\r
     case EFI_FV_FILETYPE_DXE_CORE:\r
       break;\r
+    case EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE:\r
+      //\r
+      // Rebase the inside FvImage.\r
+      //\r
+      if (Flags != 0) {\r
+        GetChildFvFromFfs (Flags, FvInfo, FfsFile, XipOffset, FvMapFile);\r
+      }\r
+      //\r
+      // Search PE/TE section in FV sectin.\r
+      //\r
+      break;\r
     default:\r
       return EFI_SUCCESS;\r
   }\r
@@ -3069,7 +3181,8 @@ WritePeMap:
   if (FfsFile->Type != EFI_FV_FILETYPE_SECURITY_CORE &&\r
       FfsFile->Type != EFI_FV_FILETYPE_PEI_CORE &&\r
       FfsFile->Type != EFI_FV_FILETYPE_PEIM &&\r
-      FfsFile->Type != EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER\r
+      FfsFile->Type != EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER &&\r
+      FfsFile->Type != EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE\r
       ) {\r
     //\r
     // Only Peim code may have a TE section\r
index 3c0e933..ea79478 100644 (file)
@@ -67,6 +67,7 @@ Abstract:
 #define OPTIONS_SECTION_STRING                "[options]"\r
 #define ATTRIBUTES_SECTION_STRING             "[attributes]"\r
 #define FILES_SECTION_STRING                  "[files]"\r
+#define FV_BASE_ADDRESS_STRING                "[FV_BASE_ADDRESS]"\r
 \r
 //\r
 // Options section\r
@@ -270,6 +271,9 @@ extern CAP_INFO   mCapDataInfo;
 extern EFI_GUID   mEfiFirmwareFileSystem2Guid;\r
 extern UINT32     mFvTotalSize;\r
 extern UINT32     mFvTakenSize;\r
+\r
+extern EFI_PHYSICAL_ADDRESS mFvBaseAddress[];\r
+extern UINT32               mFvBaseAddressNumber;\r
 //\r
 // Local function prototypes\r
 //\r
index 9a1d0ca..9210246 100644 (file)
@@ -27,6 +27,7 @@ Abstract:
 #include <Common/UefiBaseTypes.h>\r
 #include <Common/PiFirmwareFile.h>\r
 #include <Protocol/GuidedSectionExtraction.h>\r
+#include <IndustryStandard/PeImage.h>\r
 \r
 #include "CommonLib.h"\r
 #include "Compress.h"\r
@@ -80,6 +81,11 @@ STATIC CHAR8      *mCompressionTypeName[]    = { "PI_NONE", "PI_STD" };
 #define EFI_GUIDED_SECTION_NONE 0x80\r
 STATIC CHAR8      *mGUIDedSectionAttribue[]  = { "NONE", "PROCESSING_REQUIRED", "AUTH_STATUS_VALID"};\r
 \r
+STATIC CHAR8 *mAlignName[] = {\r
+  "1", "2", "4", "8", "16", "32", "64", "128", "256", "512",\r
+  "1K", "2K", "4K", "8K", "16K", "32K", "64K"\r
+};\r
+\r
 //\r
 // Crc32 GUID section related definitions.\r
 //\r
@@ -180,6 +186,10 @@ Returns:
   fprintf (stdout, "  -j Number, --buildnumber Number\n\\r
                         Number is an integer value between 0000 and 9999\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
   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
@@ -329,9 +339,50 @@ Done:
   return Status;\r
 }\r
 \r
+STATIC\r
+EFI_STATUS\r
+StringtoAlignment (\r
+  IN  CHAR8  *AlignBuffer,\r
+  OUT UINT32 *AlignNumber\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Converts Align String to align value (1~64K). \r
+\r
+Arguments:\r
+\r
+  AlignBuffer    - Pointer to Align string.\r
+  AlignNumber    - Pointer to Align value.\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS             Successfully convert align string to align value.\r
+  EFI_INVALID_PARAMETER   Align string is invalid or align value is not in scope.\r
+\r
+--*/\r
+{\r
+  UINT32 Index = 0;\r
+  //\r
+  // Check AlignBuffer\r
+  //\r
+  if (AlignBuffer == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+  for (Index = 0; Index < sizeof (mAlignName) / sizeof (CHAR8 *); Index ++) {\r
+    if (stricmp (AlignBuffer, mAlignName [Index]) == 0) {\r
+      *AlignNumber = 1 << Index;\r
+      return EFI_SUCCESS;\r
+    }\r
+  }\r
+  return EFI_INVALID_PARAMETER;\r
+}\r
+\r
 EFI_STATUS\r
 GetSectionContents (\r
   CHAR8   **InputFileName,\r
+  UINT32  *InputFileAlign,\r
   UINT32  InputFileNum,\r
   UINT8   *FileBuffer,\r
   UINT32  *BufferLength\r
@@ -346,7 +397,9 @@ Routine Description:
 Arguments:\r
                \r
   InputFileName  - Name of the input file.\r
-                \r
+\r
+  InputFileAlign - Alignment required by the input file data.\r
+\r
   InputFileNum   - Number of input files. Should be at least 1.\r
 \r
   FileBuffer     - Output buffer to contain data\r
@@ -362,10 +415,17 @@ Returns:
   EFI_BUFFER_TOO_SMALL FileBuffer is not enough to contain all file data.\r
 --*/\r
 {\r
-  UINT32   Size;\r
-  UINT32   FileSize;\r
-  UINT32   Index;\r
-  FILE    *InFile;\r
+  UINT32                     Size;\r
+  UINT32                     Offset;\r
+  UINT32                     FileSize;\r
+  UINT32                     Index;\r
+  FILE                       *InFile;\r
+  EFI_COMMON_SECTION_HEADER  *SectHeader;\r
+  EFI_COMMON_SECTION_HEADER  TempSectHeader;\r
+  EFI_TE_IMAGE_HEADER        TeHeader;\r
+  UINT32                     TeOffset;\r
+  EFI_GUID_DEFINED_SECTION   GuidSectHeader;\r
+  UINT32                     HeaderSize;\r
 \r
   if (InputFileNum < 1) {\r
     Error (NULL, 0, 2000, "Invalid paramter", "must specify at least one input file");\r
@@ -377,7 +437,9 @@ Returns:
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
-  Size = 0;\r
+  Size          = 0;\r
+  Offset        = 0;\r
+  TeOffset      = 0;\r
   //\r
   // Go through our array of file names and copy their contents\r
   // to the output buffer.\r
@@ -406,11 +468,66 @@ Returns:
     FileSize = ftell (InFile);\r
     fseek (InFile, 0, SEEK_SET);\r
     DebugMsg (NULL, 0, 9, "Input files", "the input file name is %s and the size is %u bytes", InputFileName[Index], (unsigned) FileSize); \r
+    //\r
+    // Adjust section buffer when section alignment is required.\r
+    //\r
+    if (InputFileAlign != NULL) {\r
+      //\r
+      // 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
+      if (TempSectHeader.Type == EFI_SECTION_TE) {\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_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
+        }\r
+      } \r
+\r
+      fseek (InFile, 0, SEEK_SET);\r
+\r
+      //\r
+      // Revert TeOffset to the converse value relative to Alignment\r
+      // This is to assure the original PeImage Header at Alignment.\r
+      //\r
+      if (TeOffset != 0) {\r
+        TeOffset = InputFileAlign [Index] - (TeOffset % InputFileAlign [Index]);\r
+        TeOffset = TeOffset % InputFileAlign [Index];\r
+      }\r
+\r
+      //\r
+      // make sure section data meet its alignment requirement by adding one raw pad section.\r
+      //\r
+      if ((InputFileAlign [Index] != 0) && (((Size + HeaderSize + TeOffset) % InputFileAlign [Index]) != 0)) {\r
+        Offset = (Size + sizeof (EFI_COMMON_SECTION_HEADER) + HeaderSize + TeOffset + InputFileAlign [Index] - 1) & ~(InputFileAlign [Index] - 1);\r
+        Offset = Offset - Size - HeaderSize - TeOffset;\r
+         \r
+        if (FileBuffer != NULL && ((Size + Offset) < *BufferLength)) {\r
+          memset (FileBuffer + Size, 0, Offset);\r
+          SectHeader          = (EFI_COMMON_SECTION_HEADER *) (FileBuffer + Size);\r
+          SectHeader->Type    = EFI_SECTION_RAW;\r
+          SectHeader->Size[0] = (UINT8) (Offset & 0xff);\r
+          SectHeader->Size[1] = (UINT8) ((Offset & 0xff00) >> 8);\r
+          SectHeader->Size[2] = (UINT8) ((Offset & 0xff0000) >> 16);\r
+        }\r
+        DebugMsg (NULL, 0, 9, "Pad raw section for section data alignment", "Pad Raw section size is %u", (unsigned) Offset);\r
+\r
+        Size = Size + Offset;\r
+      }\r
+    }\r
+\r
     //\r
     // Now read the contents of the file into the buffer\r
     // Buffer must be enough to contain the file content.\r
     //\r
-    if (FileSize > 0 && FileBuffer != NULL && (Size + FileSize) <= *BufferLength) {\r
+    if ((FileSize > 0) && (FileBuffer != NULL) && ((Size + FileSize) <= *BufferLength)) {\r
       if (fread (FileBuffer + Size, (size_t) FileSize, 1, InFile) != 1) {\r
         Error (NULL, 0, 0004, "Error reading file", InputFileName[Index]);\r
         fclose (InFile);\r
@@ -437,6 +554,7 @@ Returns:
 EFI_STATUS\r
 GenSectionCompressionSection (\r
   CHAR8   **InputFileName,\r
+  UINT32  *InputFileAlign,\r
   UINT32  InputFileNum,\r
   UINT8   SectCompSubType,\r
   UINT8   **OutFileBuffer\r
@@ -453,7 +571,9 @@ Routine Description:
 Arguments:\r
                \r
   InputFileName  - Name of the input file.\r
-                \r
+\r
+  InputFileAlign - Alignment required by the input file data.\r
+\r
   InputFileNum   - Number of input files. Should be at least 1.\r
 \r
   SectCompSubType - Specify the compression algorithm requested. \r
@@ -487,6 +607,7 @@ Returns:
   //\r
   Status = GetSectionContents (\r
             InputFileName,\r
+            InputFileAlign,\r
             InputFileNum,\r
             FileBuffer,\r
             &InputLength\r
@@ -503,6 +624,7 @@ Returns:
     //\r
     Status = GetSectionContents (\r
               InputFileName,\r
+              InputFileAlign,\r
               InputFileNum,\r
               FileBuffer,\r
               &InputLength\r
@@ -599,6 +721,7 @@ Returns:
 EFI_STATUS\r
 GenSectionGuidDefinedSection (\r
   CHAR8    **InputFileName,\r
+  UINT32   *InputFileAlign,\r
   UINT32   InputFileNum,\r
   EFI_GUID *VendorGuid,\r
   UINT16   DataAttribute,\r
@@ -618,6 +741,8 @@ Arguments:
                \r
   InputFileName - Name of the input file.\r
                 \r
+  InputFileAlign - Alignment required by the input file data.\r
+\r
   InputFileNum  - Number of input files. Should be at least 1.\r
 \r
   VendorGuid    - Specify vendor guid value.\r
@@ -662,6 +787,7 @@ Returns:
   //\r
   Status = GetSectionContents (\r
             InputFileName,\r
+            InputFileAlign,\r
             InputFileNum,\r
             FileBuffer,\r
             &InputLength\r
@@ -678,6 +804,7 @@ Returns:
     //\r
     Status = GetSectionContents (\r
               InputFileName,\r
+              InputFileAlign,\r
               InputFileNum,\r
               FileBuffer + Offset,\r
               &InputLength\r
@@ -797,7 +924,11 @@ Returns:
   UINT8                     *OutFileBuffer;\r
   EFI_STATUS                Status;\r
   UINT64                    LogLevel;\r
-  \r
+  UINT32                    *InputFileAlign;\r
+  UINT32                    InputFileAlignNum;\r
+\r
+  InputFileAlign        = NULL;\r
+  InputFileAlignNum     = 0;\r
   InputFileName         = NULL;\r
   OutputFileName        = NULL;\r
   SectionName           = NULL;\r
@@ -809,7 +940,7 @@ Returns:
   InputFileNum          = 0;\r
   SectType              = EFI_SECTION_ALL;\r
   SectCompSubType       = 0;\r
-  SectGuidAttribute     = 0;\r
+  SectGuidAttribute     = EFI_GUIDED_SECTION_NONE;\r
   OutFileBuffer         = NULL;\r
   InputLength           = 0;\r
   Status                = STATUS_SUCCESS;\r
@@ -983,6 +1114,41 @@ Returns:
       continue;\r
     }\r
 \r
+    //\r
+    // Section File alignment requirement\r
+    //\r
+    if (stricmp (argv[0], "--sectionalign") == 0) {\r
+      if (InputFileAlignNum == 0) {\r
+        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
+        }\r
+        memset (InputFileAlign, 1, MAXIMUM_INPUT_FILE_NUM * sizeof (UINT32));\r
+      } else if (InputFileAlignNum % MAXIMUM_INPUT_FILE_NUM == 0) {\r
+        InputFileAlign = (UINT32 *) realloc (\r
+          InputFileAlign,\r
+          (InputFileNum + MAXIMUM_INPUT_FILE_NUM) * sizeof (UINT32)\r
+          );\r
+\r
+        if (InputFileAlign == NULL) {\r
+          Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");\r
+          return 1;\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
+      }\r
+      argc -= 2;\r
+      argv += 2;\r
+      InputFileAlignNum ++;\r
+      continue; \r
+    }\r
+\r
     //\r
     // Get Input file name\r
     //\r
@@ -992,7 +1158,6 @@ Returns:
         Error (NULL, 0, 4001, "Resource", "memory cannot be allcoated");\r
         return 1;\r
       }\r
-\r
       memset (InputFileName, 0, (MAXIMUM_INPUT_FILE_NUM * sizeof (CHAR8 *)));\r
     } else if (InputFileNum % MAXIMUM_INPUT_FILE_NUM == 0) {\r
       //\r
@@ -1007,7 +1172,6 @@ Returns:
         Error (NULL, 0, 4001, "Resource", "memory cannot be allcoated");\r
         return 1;\r
       }\r
-\r
       memset (&(InputFileName[InputFileNum]), 0, (MAXIMUM_INPUT_FILE_NUM * sizeof (CHAR8 *)));\r
     }\r
 \r
@@ -1016,6 +1180,11 @@ Returns:
     argv ++;\r
   }\r
 \r
+  if (InputFileAlignNum > 0 && InputFileAlignNum != InputFileNum) {\r
+    Error (NULL, 0, 1003, "Invalid option", "section alignment must be set for each section");\r
+    goto Finish;\r
+  }\r
+\r
   VerboseMsg ("%s tool start.", UTILITY_NAME);\r
 \r
   //\r
@@ -1050,9 +1219,6 @@ Returns:
       memcpy (&VendorGuid, &mEfiCrc32SectionGuid, sizeof (EFI_GUID));\r
     }\r
     \r
-    if (SectGuidAttribute == 0) {\r
-      SectGuidAttribute = EFI_GUIDED_SECTION_PROCESSING_REQUIRED;\r
-    }\r
     if ((SectGuidAttribute & EFI_GUIDED_SECTION_NONE) != 0) {\r
       //\r
       // NONE attribute, clear attribute value.\r
@@ -1161,8 +1327,13 @@ Returns:
   //\r
   switch (SectType) {\r
   case EFI_SECTION_COMPRESSION:\r
+    if (InputFileAlign != NULL) {\r
+      free (InputFileAlign);\r
+      InputFileAlign = NULL;\r
+    }\r
     Status = GenSectionCompressionSection (\r
               InputFileName,\r
+              InputFileAlign,\r
               InputFileNum,\r
               SectCompSubType,\r
               &OutFileBuffer\r
@@ -1170,8 +1341,17 @@ Returns:
     break;\r
 \r
   case EFI_SECTION_GUID_DEFINED:\r
+    if (InputFileAlign != NULL && (CompareGuid (&VendorGuid, &mEfiCrc32SectionGuid) != 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
+      //\r
+      free (InputFileAlign);\r
+      InputFileAlign = NULL;\r
+    }\r
     Status = GenSectionGuidDefinedSection (\r
               InputFileName,\r
+              InputFileAlign,\r
               InputFileNum,\r
               &VendorGuid,\r
               SectGuidAttribute,\r
@@ -1232,6 +1412,7 @@ Returns:
     //\r
     Status = GetSectionContents (\r
               InputFileName,\r
+              InputFileAlign,\r
               InputFileNum,\r
               OutFileBuffer,\r
               &InputLength\r
@@ -1248,6 +1429,7 @@ Returns:
       //\r
       Status = GetSectionContents (\r
                 InputFileName,\r
+                InputFileAlign,\r
                 InputFileNum,\r
                 OutFileBuffer,\r
                 &InputLength\r
@@ -1296,6 +1478,10 @@ Finish:
     free (InputFileName);\r
   }\r
 \r
+  if (InputFileAlign != NULL) {\r
+    free (InputFileAlign);\r
+  }\r
+\r
   if (OutFileBuffer != NULL) {\r
     free (OutFileBuffer);\r
   }\r
index a9e12ed..4a659b7 100644 (file)
@@ -168,6 +168,7 @@ class DepexSectionClassObject (SectionClassObject):
     def __init__(self):\r
         self.DepexType = None\r
         self.Expression = None\r
+        self.ExpressionProcessed = False\r
 \r
 ## Compress section data in FDF\r
 #\r
@@ -231,6 +232,7 @@ class FvImageSectionClassObject (SectionClassObject):
         self.FvFileType = None\r
         self.FvFileName = None\r
         self.FvFileExtension = None\r
+        self.FvAddr = None\r
 \r
 ## GUIDed section data in FDF\r
 #\r
@@ -247,6 +249,7 @@ class GuidSectionClassObject (SectionClassObject) :
         self.SectionType = None\r
         self.ProcessRequired = False\r
         self.AuthStatusValid = False\r
+        self.FvAddr = None\r
 \r
 ## UI section data in FDF\r
 #\r
@@ -399,4 +402,4 @@ class OptionRomClassObject:
     def __init__(self):\r
         self.DriverName = None\r
         self.FfsList = []\r
-        
\ No newline at end of file
+       \r
index a0a1905..8650a73 100644 (file)
@@ -62,24 +62,27 @@ class DepexSection (DepexSectionClassObject):
     #   @retval tuple       (Generated file name list, section alignment)\r
     #\r
     def GenSection(self, OutputPath, ModuleName, SecNum, keyStringList, FfsFile = None, Dict = {}):\r
+        \r
+        if self.ExpressionProcessed == False:\r
+            self.Expression = self.Expression.replace("\n", " ").replace("\r", " ")\r
+            ExpList = self.Expression.split()\r
+            ExpGuidDict = {}\r
 \r
-        self.Expression = self.Expression.replace("\n", " ").replace("\r", " ")\r
-        ExpList = self.Expression.split()\r
-        ExpGuidDict = {}\r
+            for Exp in ExpList:\r
+                if Exp.upper() not in ('AND', 'OR', 'NOT', 'TRUE', 'FALSE', 'SOR', 'BEFORE', 'AFTER', 'END'):\r
+                    GuidStr = self.__FindGuidValue(Exp)\r
+                    if GuidStr == None:\r
+                        EdkLogger.error("GenFds", RESOURCE_NOT_AVAILABLE,\r
+                                        "Depex GUID %s could not be found in build DB! (ModuleName: %s)" % (Exp, ModuleName))\r
 \r
-        for Exp in ExpList:\r
-            if Exp.upper() not in ('AND', 'OR', 'NOT', 'TRUE', 'FALSE', 'SOR', 'BEFORE', 'AFTER', 'END'):\r
-                GuidStr = self.__FindGuidValue(Exp)\r
-                if GuidStr == None:\r
-                    EdkLogger.error("GenFds", RESOURCE_NOT_AVAILABLE,\r
-                                    "Depex GUID %s could not be found in build DB! (ModuleName: %s)" % (Exp, ModuleName))\r
+                    ExpGuidDict[Exp] = GuidStr\r
 \r
-                ExpGuidDict[Exp] = GuidStr\r
+            for Item in ExpGuidDict:\r
+                self.Expression = self.Expression.replace(Item, ExpGuidDict[Item])\r
 \r
-        for Item in ExpGuidDict:\r
-            self.Expression = self.Expression.replace(Item, ExpGuidDict[Item])\r
+            self.Expression = self.Expression.strip()\r
+            self.ExpressionProcessed = True\r
 \r
-        self.Expression = self.Expression.strip()\r
         if self.DepexType == 'PEI_DEPEX_EXP':\r
             ModuleType = 'PEIM'\r
             SecType    = 'PEI_DEPEX'\r
index e3f2e68..56297a8 100755 (executable)
 #\r
 import Ffs\r
 import Rule\r
-from GenFdsGlobalVariable import GenFdsGlobalVariable\r
 import os\r
 import StringIO\r
 import subprocess\r
+\r
+from GenFdsGlobalVariable import GenFdsGlobalVariable\r
 from CommonDataClass.FdfClass import FileStatementClassObject\r
 from Common import EdkLogger\r
 from Common.BuildToolError import *\r
 from Common.Misc import GuidStructureByteArrayToGuidString\r
+from GuidSection import GuidSection\r
+from FvImageSection import FvImageSection\r
 \r
 ## generate FFS from FILE\r
 #\r
@@ -45,7 +48,7 @@ class FileStatement (FileStatementClassObject) :
     #   @param  Dict        dictionary contains macro and value pair\r
     #   @retval string      Generated FFS file name\r
     #\r
-    def GenFfs(self, Dict = {}):\r
+    def GenFfs(self, Dict = {}, FvAddr=[]):\r
         \r
         if self.NameGuid != None and self.NameGuid.startswith('PCD('):\r
             PcdValue = GenFdsGlobalVariable.GetPcdValue(self.NameGuid)\r
@@ -92,6 +95,13 @@ class FileStatement (FileStatementClassObject) :
             for section in self.SectionList :\r
                 Index = Index + 1\r
                 SecIndex = '%d' %Index\r
+                # process the inside FvImage from FvSection or GuidSection\r
+                if FvAddr != []:\r
+                    if isinstance(section, FvImageSection):\r
+                        section.FvAddr = FvAddr.pop(0)\r
+                    elif isinstance(section, GuidSection):\r
+                        if section.ProcessRequired == False:\r
+                            section.FvAddr = FvAddr.pop(0)\r
                 sectList, align = section.GenSection(OutputDir, self.NameGuid, SecIndex, self.KeyStringList, None, Dict)\r
                 if sectList != []:\r
                     for sect in sectList:\r
index ac13e4d..70d4bd5 100644 (file)
@@ -90,7 +90,7 @@ class FfsInfStatement(FfsInfStatementClassObject):
             self.BaseName = Inf.BaseName\r
             self.ModuleGuid = Inf.Guid\r
             self.ModuleType = Inf.ModuleType\r
-            if Inf.Specification != None and 'PI_SPECIFICATION_VERSION' in Inf.Specification:
+            if Inf.Specification != None and 'PI_SPECIFICATION_VERSION' in Inf.Specification:\r
                 self.PiSpecVersion = Inf.Specification['PI_SPECIFICATION_VERSION']\r
             if Inf.AutoGenVersion < 0x00010005:\r
                 self.ModuleType = Inf.ComponentType\r
@@ -105,7 +105,7 @@ class FfsInfStatement(FfsInfStatementClassObject):
             self.BaseName = Inf.BaseName\r
             self.ModuleGuid = Inf.Guid\r
             self.ModuleType = Inf.ModuleType\r
-            if Inf.Specification != None and 'PI_SPECIFICATION_VERSION' in Inf.Specification:
+            if Inf.Specification != None and 'PI_SPECIFICATION_VERSION' in Inf.Specification:\r
                 self.PiSpecVersion = Inf.Specification['PI_SPECIFICATION_VERSION']\r
             self.VersionString = Inf.Version\r
             self.BinFileList = Inf.Binaries\r
@@ -118,7 +118,7 @@ class FfsInfStatement(FfsInfStatementClassObject):
         if len(self.SourceFileList) != 0 and not self.InDsc:\r
             EdkLogger.warn("GenFds", GENFDS_ERROR, "Module %s NOT found in DSC file; Is it really a binary module?" % (self.InfFileName))\r
 \r
-        if self.ModuleType == 'SMM_CORE' and self.PiSpecVersion < 0x0001000A:
+        if self.ModuleType == 'SMM_CORE' and self.PiSpecVersion < 0x0001000A:\r
             EdkLogger.error("GenFds", FORMAT_NOT_SUPPORTED, "SMM_CORE module type can't be used in the module with PI_SPECIFICATION_VERSION less than 0x0001000A", File=self.InfFileName)      \r
 \r
         if Inf._Defs != None and len(Inf._Defs) > 0:\r
@@ -150,7 +150,7 @@ class FfsInfStatement(FfsInfStatementClassObject):
     #   @param  Dict        dictionary contains macro and value pair\r
     #   @retval string      Generated FFS file name\r
     #\r
-    def GenFfs(self, Dict = {}):\r
+    def GenFfs(self, Dict = {}, FvAddr = []):\r
         #\r
         # Parse Inf file get Module related information\r
         #\r
index 6190bce..8605ac7 100644 (file)
@@ -63,7 +63,7 @@ class FV (FvClassObject):
     #\r
     def AddToBuffer (self, Buffer, BaseAddress=None, BlockSize= None, BlockNum=None, ErasePloarity='1', VtfDict=None, MacroDict = {}) :\r
 \r
-        if self.UiFvName.upper() + 'fv' in GenFds.ImageBinDict.keys():\r
+        if BaseAddress == None and self.UiFvName.upper() + 'fv' in GenFds.ImageBinDict.keys():\r
             return GenFds.ImageBinDict[self.UiFvName.upper() + 'fv']\r
         \r
         #\r
@@ -122,6 +122,7 @@ class FV (FvClassObject):
 \r
         FvInfoFileName = os.path.join(GenFdsGlobalVariable.FfsDir, self.UiFvName + '.inf')\r
         shutil.copy(GenFdsGlobalVariable.FvAddressFileName, FvInfoFileName)\r
+        oldtime = os.path.getmtime(FvInfoFileName)\r
         GenFdsGlobalVariable.GenerateFirmwareVolume(\r
                                 FvOutputFile,\r
                                 [self.InfFileName],\r
@@ -129,6 +130,32 @@ class FV (FvClassObject):
                                 FfsList=FfsFileList\r
                                 )\r
 \r
+        if os.path.getmtime(FvInfoFileName) > oldtime:\r
+            FvAddrString = []\r
+            AddFileObj = open(FvInfoFileName, 'r')\r
+            AddrStrings = AddFileObj.readlines()\r
+            AddrKeyFound = False\r
+            for AddrString in AddrStrings:\r
+                if AddrKeyFound:\r
+                    #get base address for the inside FvImage\r
+                    FvAddrString.append (AddrString)\r
+                elif AddrString.find ("[FV_BASE_ADDRESS]") != -1:\r
+                    AddrKeyFound = True\r
+            AddFileObj.close()\r
+\r
+            if FvAddrString != []:\r
+                # Update Ffs again\r
+                for FfsFile in self.FfsList :\r
+                    FileName = FfsFile.GenFfs(MacroDict, FvAddr=FvAddrString)\r
+                \r
+                #Update GenFv again\r
+                GenFdsGlobalVariable.GenerateFirmwareVolume(\r
+                                        FvOutputFile,\r
+                                        [self.InfFileName],\r
+                                        AddressFile=FvInfoFileName,\r
+                                        FfsList=FfsFileList\r
+                                        )\r
+\r
         #\r
         # Write the Fv contents to Buffer\r
         #\r
@@ -138,6 +165,21 @@ class FV (FvClassObject):
         GenFdsGlobalVariable.SharpCounter = 0\r
 \r
         Buffer.write(FvFileObj.read())\r
+        FvFileObj.seek(0)\r
+        # PI FvHeader is 0x48 byte\r
+        FvHeaderBuffer = FvFileObj.read(0x48)\r
+        # FV alignment position.\r
+        FvAlignmentValue = 1 << (ord (FvHeaderBuffer[0x2E]) & 0x1F)\r
+        # FvAlignmentValue is larger than or equal to 1K\r
+        if FvAlignmentValue >= 0x400:\r
+            if FvAlignmentValue >= 0x10000:\r
+                #The max alignment supported by FFS is 64K.\r
+                self.FvAlignment = "64K"\r
+            else:\r
+                self.FvAlignment = str (FvAlignmentValue / 0x400) + "K"\r
+        else:\r
+            # FvAlignmentValue is less than 1K\r
+            self.FvAlignment = str (FvAlignmentValue)\r
         FvFileObj.close()\r
         GenFds.ImageBinDict[self.UiFvName.upper() + 'fv'] = FvOutputFile\r
         return FvOutputFile\r
index 3a3e714..c945ce9 100755 (executable)
@@ -73,7 +73,13 @@ class FvImageSection(FvImageSectionClassObject):
             Fv = GenFdsGlobalVariable.FdfParser.Profile.FvDict.get(self.FvName)\r
             if Fv != None:\r
                 self.Fv = Fv\r
-                FvFileName = self.Fv.AddToBuffer(Buffer, MacroDict = Dict)\r
+                FvFileName = Fv.AddToBuffer(Buffer, self.FvAddr, MacroDict = Dict)\r
+                if Fv.FvAlignment != None:\r
+                    if self.Alignment == None:\r
+                        self.Alignment = Fv.FvAlignment\r
+                    else:\r
+                        if GenFdsGlobalVariable.GetAlignment (Fv.FvAlignment) > GenFdsGlobalVariable.GetAlignment (self.Alignment):\r
+                            self.Alignment = Fv.FvAlignment\r
             else:\r
                 if self.FvFileName != None:\r
                     FvFileName = GenFdsGlobalVariable.ReplaceWorkspaceMacro(self.FvFileName)\r
index b54e8c8..5eb5bef 100644 (file)
@@ -154,7 +154,7 @@ class GenFdsGlobalVariable:
 
     @staticmethod
     def GenerateSection(Output, Input, Type=None, CompressionType=None, Guid=None,
-                        GuidHdrLen=None, GuidAttr=None, Ui=None, Ver=None):
+                        GuidHdrLen=None, GuidAttr=None, Ui=None, Ver=None, InputAlign=None):
         if not GenFdsGlobalVariable.NeedsUpdate(Output, Input):
             return
         GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, Input))
@@ -170,6 +170,10 @@ class GenFdsGlobalVariable:
             Cmd += ["-l", GuidHdrLen]
         if GuidAttr not in [None, '']:
             Cmd += ["-r", GuidAttr]
+        if InputAlign != None:
+            #Section Align is only for dummy section without section type
+            for SecAlign in InputAlign:
+                Cmd += ["--sectionalign", SecAlign]
 
         if Ui not in [None, '']:
             #Cmd += ["-n", '"' + Ui + '"']
@@ -194,6 +198,15 @@ class GenFdsGlobalVariable:
             Cmd += Input
             GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate section")
 
+    @staticmethod
+    def GetAlignment (AlignString):
+        if AlignString == None:
+            return 0
+        if AlignString in ("1K", "2K", "4K", "8K", "16K", "32K", "64K"):\r
+            return int (AlignString.rstrip('K')) * 1024\r
+        else:\r
+            return int (AlignString)\r
+
     @staticmethod
     def GenerateFfs(Output, Input, Type, Guid, Fixed=False, CheckSum=False, Align=None,
                     SectionAlign=None):
index e111e0f..a1c2ba2 100755 (executable)
@@ -25,6 +25,7 @@ from Common import ToolDefClassObject
 import sys\r
 from Common import EdkLogger\r
 from Common.BuildToolError import *\r
+from FvImageSection import FvImageSection\r
 \r
 ## generate GUIDed section\r
 #\r
@@ -63,16 +64,35 @@ class GuidSection(GuidSectionClassObject) :
             self.SectionType = FfsInf.__ExtendMacro__(self.SectionType)\r
             self.CurrentArchList = [FfsInf.CurrentArch]\r
 \r
-        SectFile = tuple()\r
+        SectFile  = tuple()\r
+        SectAlign = []\r
         Index = 0\r
+        MaxAlign = None\r
         for Sect in self.SectionList:\r
             Index = Index + 1\r
             SecIndex = '%s.%d' %(SecNum,Index)\r
+            # set base address for inside FvImage\r
+            if isinstance(Sect, FvImageSection):\r
+                Sect.FvAddr = self.FvAddr\r
             ReturnSectList, align = Sect.GenSection(OutputPath, ModuleName, SecIndex, KeyStringList,FfsInf, Dict)\r
+            if align != None:\r
+                if MaxAlign == None:\r
+                    MaxAlign = align\r
+                if GenFdsGlobalVariable.GetAlignment (align) > GenFdsGlobalVariable.GetAlignment (MaxAlign):\r
+                    MaxAlign = align\r
             if ReturnSectList != []:\r
+                if align == None:\r
+                    align = "1"\r
                 for file in ReturnSectList:\r
                     SectFile += (file,)\r
+                    SectAlign.append(align)\r
 \r
+        if MaxAlign != None:\r
+            if self.Alignment == None:\r
+                self.Alignment = MaxAlign\r
+            else:\r
+                if GenFdsGlobalVariable.GetAlignment (MaxAlign) > GenFdsGlobalVariable.GetAlignment (self.Alignment):\r
+                    self.Alignment = MaxAlign\r
 \r
         OutputFile = OutputPath + \\r
                      os.sep     + \\r
@@ -91,7 +111,7 @@ class GuidSection(GuidSectionClassObject) :
         #\r
         if self.NameGuid == None :\r
             GenFdsGlobalVariable.VerboseLogger( "Use GenSection function Generate CRC32 Section")\r
-            GenFdsGlobalVariable.GenerateSection(OutputFile, SectFile, Section.Section.SectionType[self.SectionType])\r
+            GenFdsGlobalVariable.GenerateSection(OutputFile, SectFile, Section.Section.SectionType[self.SectionType], InputAlign=SectAlign)\r
             OutputFileList = []\r
             OutputFileList.append(OutputFile)\r
             return OutputFileList, self.Alignment\r
@@ -102,7 +122,7 @@ class GuidSection(GuidSectionClassObject) :
             #\r
             # Call GenSection with DUMMY section type.\r
             #\r
-            GenFdsGlobalVariable.GenerateSection(OutputFile+".dummy", SectFile)\r
+            GenFdsGlobalVariable.GenerateSection(OutputFile+".dummy", SectFile, InputAlign=SectAlign)\r
             #\r
             # Use external tool process the Output\r
             #\r
@@ -115,28 +135,45 @@ class GuidSection(GuidSectionClassObject) :
                        '.tmp'\r
             TempFile = os.path.normpath(TempFile)\r
 \r
-            ExternalToolCmd = (\r
-                ExternalTool,\r
-                '-e',\r
-                '-o', TempFile,\r
-                InputFile,\r
-                )\r
-\r
             #\r
             # Call external tool\r
             #\r
             GenFdsGlobalVariable.GuidTool(TempFile, [InputFile], ExternalTool, '-e')\r
 \r
+            FileHandleIn = open(InputFile,'rb')\r
+            FileHandleIn.seek(0,2)\r
+            InputFileSize = FileHandleIn.tell()\r
+            \r
+            FileHandleOut = open(TempFile,'rb')\r
+            FileHandleOut.seek(0,2)\r
+            TempFileSize = FileHandleOut.tell()\r
+\r
+            HeaderLength = None\r
+            if TempFileSize > InputFileSize and TempFileSize % 4 == 0:\r
+                FileHandleIn.seek(0)\r
+                BufferIn  = FileHandleIn.read()\r
+                FileHandleOut.seek(0)\r
+                BufferOut = FileHandleOut.read()\r
+                if BufferIn in BufferOut[TempFileSize - InputFileSize:]:\r
+                    HeaderLength = str(TempFileSize - InputFileSize)\r
+            #auto sec guided attribute with process required\r
+            if HeaderLength == None:\r
+                Attribute = 'PROCESSING_REQUIRED'\r
+\r
+            FileHandleIn.close()\r
+            FileHandleOut.close()\r
+            \r
             #\r
-            # Call Gensection Add Secntion Header\r
+            # Call Gensection Add Section Header\r
             #\r
-            Attribute = None\r
-            if self.ProcessRequired == True:\r
-                Attribute = 'PROCSSING_REQUIRED'\r
-            if self.AuthStatusValid == True:\r
+            Attribute = 'NONE'\r
+            if self.ProcessRequired in ("TRUE", "1"):\r
+                Attribute = 'PROCESSING_REQUIRED'\r
+                HeaderLength = None\r
+            if self.AuthStatusValid in ("TRUE", "1"):\r
                 Attribute = 'AUTH_STATUS_VALID'\r
             GenFdsGlobalVariable.GenerateSection(OutputFile, [TempFile], Section.Section.SectionType['GUIDED'],\r
-                                                 Guid=self.NameGuid, GuidAttr=Attribute)\r
+                                                 Guid=self.NameGuid, GuidAttr=Attribute, GuidHdrLen=HeaderLength)\r
             OutputFileList = []\r
             OutputFileList.append(OutputFile)\r
             return OutputFileList, self.Alignment\r