]> git.proxmox.com Git - mirror_edk2.git/blobdiff - BaseTools/Source/C/GenSec/GenSec.c
BaseTools: Clean up source files
[mirror_edk2.git] / BaseTools / Source / C / GenSec / GenSec.c
index 0129e4eb3fb35590e96b0796108c8c42de84edf2..f3dfaf63bae3f1b75fc3c419efd89385707c7397 100644 (file)
@@ -1,16 +1,22 @@
 /** @file\r
 Creates output file that is a properly formed section per the PI spec.\r
 \r
-Copyright (c) 2004 - 2016, Intel Corporation. All rights reserved.<BR>\r
-This program and the accompanying materials                          \r
-are licensed and made available under the terms and conditions of the BSD License         \r
-which accompanies this distribution.  The full text of the license may be found at        \r
-http://opensource.org/licenses/bsd-license.php                                            \r
-                                                                                          \r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
+Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
 \r
 **/\r
+#ifndef __GNUC__\r
+#include <windows.h>\r
+#include <io.h>\r
+#include <sys/types.h>\r
+#include <sys/stat.h>\r
+#endif\r
 \r
 #include <stdio.h>\r
 #include <stdlib.h>\r
@@ -27,6 +33,8 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 #include "Crc32.h"\r
 #include "EfiUtilityMsgs.h"\r
 #include "ParseInf.h"\r
+#include "FvLib.h"\r
+#include "PeCoffLib.h"\r
 \r
 //\r
 // GenSec Tool Information\r
@@ -74,7 +82,8 @@ STATIC CHAR8      *mGUIDedSectionAttribue[]  = { "NONE", "PROCESSING_REQUIRED",
 \r
 STATIC CHAR8 *mAlignName[] = {\r
   "1", "2", "4", "8", "16", "32", "64", "128", "256", "512",\r
-  "1K", "2K", "4K", "8K", "16K", "32K", "64K"\r
+  "1K", "2K", "4K", "8K", "16K", "32K", "64K", "128K", "256K",\r
+  "512K", "1M", "2M", "4M", "8M", "16M"\r
 };\r
 \r
 //\r
@@ -94,7 +103,7 @@ STATIC EFI_GUID  mZeroGuid                 = {0x0, 0x0, 0x0, {0x0, 0x0, 0x0, 0x0
 STATIC EFI_GUID  mEfiCrc32SectionGuid      = EFI_CRC32_GUIDED_SECTION_EXTRACTION_PROTOCOL_GUID;\r
 \r
 STATIC\r
-VOID \r
+VOID\r
 Version (\r
   VOID\r
   )\r
@@ -107,12 +116,12 @@ Routine Description:
 Arguments:\r
 \r
   None\r
-  \r
+\r
 Returns:\r
 \r
   None\r
-  \r
---*/ \r
+\r
+--*/\r
 {\r
   fprintf (stdout, "%s Version %d.%d %s \n", UTILITY_NAME, UTILITY_MAJOR_VERSION, UTILITY_MINOR_VERSION, __BUILD_VERSION);\r
 }\r
@@ -142,11 +151,11 @@ Returns:
   // Summary usage\r
   //\r
   fprintf (stdout, "\nUsage: %s [options] [input_file]\n\n", UTILITY_NAME);\r
-  \r
+\r
   //\r
   // Copyright declaration\r
-  // \r
-  fprintf (stdout, "Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.\n\n");\r
+  //\r
+  fprintf (stdout, "Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.\n\n");\r
 \r
   //\r
   // Details Option\r
@@ -167,7 +176,7 @@ Returns:
                         EFI_SECTION_ALL is default section type.\n");\r
   fprintf (stdout, "  -c [Type], --compress [Type]\n\\r
                         Compress method type can be PI_NONE or PI_STD.\n\\r
-                        if -c option is not given, PI_STD is default type.\n"); \r
+                        if -c option is not given, PI_STD is default type.\n");\r
   fprintf (stdout, "  -g GuidValue, --vendor GuidValue\n\\r
                         GuidValue is one specific vendor guid value.\n\\r
                         Its format is xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\n");\r
@@ -184,8 +193,12 @@ Returns:
                         used in Ver section.\n");\r
   fprintf (stdout, "  --sectionalign SectionAlign\n\\r
                         SectionAlign points to section alignment, which support\n\\r
-                        the alignment scope 1~64K. It is specified in same\n\\r
-                        order that the section file is input.\n");\r
+                        the alignment scope 0~16M. If SectionAlign is specified\n\\r
+                        as 0, tool get alignment value from SectionFile. It is\n\\r
+                        specified in same order that the section file is input.\n");\r
+  fprintf (stdout, "  --dummy dummyfile\n\\r
+                        compare dummpyfile with input_file to decide whether\n\\r
+                        need to set PROCESSING_REQUIRED attribute.\n");\r
   fprintf (stdout, "  -v, --verbose         Turn on verbose output with informational messages.\n");\r
   fprintf (stdout, "  -q, --quiet           Disable all messages except key message and fatal error\n");\r
   fprintf (stdout, "  -d, --debug level     Enable debug messages, at input debug level.\n");\r
@@ -202,7 +215,7 @@ Ascii2UnicodeString (
 \r
 Routine Description:\r
 \r
-  Write ascii string as unicode string format to FILE \r
+  Write ascii string as unicode string format to FILE\r
 \r
 Arguments:\r
 \r
@@ -222,7 +235,7 @@ Returns:
   // End the UniString with a NULL.\r
   //\r
   *UniString = '\0';\r
-} \r
+}\r
 \r
 STATUS\r
 GenSectionCommonLeafSection (\r
@@ -232,19 +245,19 @@ GenSectionCommonLeafSection (
   UINT8   **OutFileBuffer\r
   )\r
 /*++\r
-        \r
+\r
 Routine Description:\r
-           \r
+\r
   Generate a leaf section of type other than EFI_SECTION_VERSION\r
   and EFI_SECTION_USER_INTERFACE. Input file must be well formed.\r
   The function won't validate the input file's contents. For\r
   common leaf sections, the input file may be a binary file.\r
   The utility will add section header to the file.\r
-            \r
+\r
 Arguments:\r
-               \r
+\r
   InputFileName  - Name of the input file.\r
-                \r
+\r
   InputFileNum   - Number of input files. Should be 1 for leaf section.\r
 \r
   SectionType    - A valid section type string\r
@@ -252,7 +265,7 @@ Arguments:
   OutFileBuffer  - Buffer pointer to Output file contents\r
 \r
 Returns:\r
-                       \r
+\r
   STATUS_ERROR            - can't continue\r
   STATUS_SUCCESS          - successful return\r
 \r
@@ -310,7 +323,7 @@ Returns:
   //\r
   Buffer = (UINT8 *) malloc ((size_t) TotalLength);\r
   if (Buffer == NULL) {\r
-    Error (NULL, 0, 4001, "Resource", "memory cannot be allcoated"); \r
+    Error (NULL, 0, 4001, "Resource", "memory cannot be allcoated");\r
     goto Done;\r
   }\r
   CommonSect = (EFI_COMMON_SECTION_HEADER *) Buffer;\r
@@ -323,7 +336,7 @@ Returns:
     memset(CommonSect->Size, 0xff, sizeof(UINT8) * 3);\r
     ((EFI_COMMON_SECTION_HEADER2 *)CommonSect)->ExtendedSize = TotalLength;\r
   }\r
-  \r
+\r
   //\r
   // read data from the input file.\r
   //\r
@@ -335,7 +348,7 @@ Returns:
   }\r
 \r
   //\r
-  // Set OutFileBuffer \r
+  // Set OutFileBuffer\r
   //\r
   *OutFileBuffer = Buffer;\r
   Status = STATUS_SUCCESS;\r
@@ -356,7 +369,7 @@ StringtoAlignment (
 \r
 Routine Description:\r
 \r
-  Converts Align String to align value (1~64K). \r
+  Converts Align String to align value (1~16M).\r
 \r
 Arguments:\r
 \r
@@ -395,14 +408,14 @@ GetSectionContents (
   UINT32  *BufferLength\r
   )\r
 /*++\r
-        \r
+\r
 Routine Description:\r
-           \r
+\r
   Get the contents of all section files specified in InputFileName\r
   into FileBuffer.\r
-            \r
+\r
 Arguments:\r
-               \r
+\r
   InputFileName  - Name of the input file.\r
 \r
   InputFileAlign - Alignment required by the input file data.\r
@@ -411,11 +424,11 @@ Arguments:
 \r
   FileBuffer     - Output buffer to contain data\r
 \r
-  BufferLength   - On input, this is size of the FileBuffer. \r
+  BufferLength   - On input, this is size of the FileBuffer.\r
                    On output, this is the actual length of the data.\r
 \r
 Returns:\r
-                       \r
+\r
   EFI_SUCCESS on successful return\r
   EFI_INVALID_PARAMETER if InputFileNum is less than 1 or BufferLength point is NULL.\r
   EFI_ABORTED if unable to open input file.\r
@@ -462,8 +475,8 @@ Returns:
       }\r
       Size++;\r
     }\r
-    \r
-    // \r
+\r
+    //\r
     // Open file and read contents\r
     //\r
     InFile = fopen (LongFilePath (InputFileName[Index]), "rb");\r
@@ -475,7 +488,7 @@ Returns:
     fseek (InFile, 0, SEEK_END);\r
     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
+    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
@@ -512,7 +525,7 @@ Returns:
             HeaderSize = GuidSectHeader.DataOffset;\r
           }\r
         }\r
-      } \r
+      }\r
 \r
       fseek (InFile, 0, SEEK_SET);\r
 \r
@@ -531,7 +544,7 @@ Returns:
       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
+\r
         if (FileBuffer != NULL && ((Size + Offset) < *BufferLength)) {\r
           //\r
           // The maximal alignment is 64K, the raw section size must be less than 0xffffff\r
@@ -564,7 +577,7 @@ Returns:
     fclose (InFile);\r
     Size += FileSize;\r
   }\r
-  \r
+\r
   //\r
   // Set the real required buffer size.\r
   //\r
@@ -586,28 +599,28 @@ GenSectionCompressionSection (
   UINT8   **OutFileBuffer\r
   )\r
 /*++\r
-        \r
+\r
 Routine Description:\r
-           \r
+\r
   Generate an encapsulating section of type EFI_SECTION_COMPRESSION\r
   Input file must be already sectioned. The function won't validate\r
-  the input files' contents. Caller should hand in files already \r
+  the input files' contents. Caller should hand in files already\r
   with section header.\r
-            \r
+\r
 Arguments:\r
-               \r
+\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
-  SectCompSubType - Specify the compression algorithm requested. \r
-  \r
+  SectCompSubType - Specify the compression algorithm requested.\r
+\r
   OutFileBuffer   - Buffer pointer to Output file contents\r
 \r
 Returns:\r
-                       \r
+\r
   EFI_SUCCESS           on successful return\r
   EFI_INVALID_PARAMETER if InputFileNum is less than 1\r
   EFI_ABORTED           if unable to open input file.\r
@@ -741,7 +754,7 @@ Returns:
     }\r
   }\r
 \r
-  DebugMsg (NULL, 0, 9, "comprss file size", \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
 \r
   //if (TotalLength >= MAX_SECTION_SIZE) {\r
@@ -769,7 +782,7 @@ Returns:
     CompressionSect2->UncompressedLength        = InputLength;\r
   } else {\r
     CompressionSect = (EFI_COMPRESSION_SECTION *) FileBuffer;\r
-    \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
@@ -779,7 +792,7 @@ Returns:
   }\r
 \r
   //\r
-  // Set OutFileBuffer \r
+  // Set OutFileBuffer\r
   //\r
   *OutFileBuffer = FileBuffer;\r
 \r
@@ -797,32 +810,32 @@ GenSectionGuidDefinedSection (
   UINT8    **OutFileBuffer\r
   )\r
 /*++\r
-        \r
+\r
 Routine Description:\r
-           \r
+\r
   Generate an encapsulating section of type EFI_SECTION_GUID_DEFINED\r
   Input file must be already sectioned. The function won't validate\r
-  the input files' contents. Caller should hand in files already \r
+  the input files' contents. Caller should hand in files already\r
   with section header.\r
-            \r
+\r
 Arguments:\r
-               \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
   VendorGuid    - Specify vendor guid value.\r
 \r
-  DataAttribute - Specify attribute for the vendor guid data. \r
-  \r
+  DataAttribute - Specify attribute for the vendor guid data.\r
+\r
   DataHeaderSize- Guided Data Header Size\r
-  \r
+\r
   OutFileBuffer   - Buffer pointer to Output file contents\r
 \r
 Returns:\r
-                       \r
+\r
   EFI_SUCCESS on successful return\r
   EFI_INVALID_PARAMETER if InputFileNum is less than 1\r
   EFI_ABORTED if unable to open input file.\r
@@ -897,15 +910,22 @@ Returns:
     return Status;\r
   }\r
 \r
-  if (FileBuffer == NULL) {\r
-    return EFI_OUT_OF_RESOURCES;\r
-  }\r
-\r
   if (InputLength == 0) {\r
+    if (FileBuffer != NULL) {\r
+      free (FileBuffer);\r
+    }\r
     Error (NULL, 0, 2000, "Invalid parameter", "the size of input file %s can't be zero", InputFileName);\r
     return EFI_NOT_FOUND;\r
   }\r
 \r
+  //\r
+  // InputLength != 0, but FileBuffer == NULL means out of resources.\r
+  //\r
+  if (FileBuffer == NULL) {\r
+    Error (NULL, 0, 4001, "Resource", "memory cannot be allcoated");\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+\r
   //\r
   // Now data is in FileBuffer + Offset\r
   //\r
@@ -915,7 +935,7 @@ Returns:
     //\r
     Crc32Checksum = 0;\r
     CalculateCrc32 (FileBuffer + Offset, InputLength, &Crc32Checksum);\r
-    \r
+\r
     if (TotalLength >= MAX_SECTION_SIZE) {\r
       Crc32GuidSect2 = (CRC32_SECTION_HEADER2 *) FileBuffer;\r
       Crc32GuidSect2->GuidSectionHeader.CommonHeader.Type     = EFI_SECTION_GUID_DEFINED;\r
@@ -965,15 +985,112 @@ Returns:
     }\r
   }\r
   VerboseMsg ("the size of the created section file is %u bytes", (unsigned) TotalLength);\r
-  \r
+\r
   //\r
-  // Set OutFileBuffer \r
+  // Set OutFileBuffer\r
   //\r
   *OutFileBuffer = FileBuffer;\r
 \r
   return EFI_SUCCESS;\r
 }\r
 \r
+EFI_STATUS\r
+FfsRebaseImageRead (\r
+    IN      VOID    *FileHandle,\r
+    IN      UINTN   FileOffset,\r
+    IN OUT  UINT32  *ReadSize,\r
+    OUT     VOID    *Buffer\r
+    )\r
+  /*++\r
+\r
+    Routine Description:\r
+\r
+    Support routine for the PE/COFF Loader that reads a buffer from a PE/COFF file\r
+\r
+    Arguments:\r
+\r
+   FileHandle - The handle to the PE/COFF file\r
+\r
+   FileOffset - The offset, in bytes, into the file to read\r
+\r
+   ReadSize   - The number of bytes to read from the file starting at FileOffset\r
+\r
+   Buffer     - A pointer to the buffer to read the data into.\r
+\r
+   Returns:\r
+\r
+   EFI_SUCCESS - ReadSize bytes of data were read into Buffer from the PE/COFF file starting at FileOffset\r
+\r
+   --*/\r
+{\r
+  CHAR8   *Destination8;\r
+  CHAR8   *Source8;\r
+  UINT32  Length;\r
+\r
+  Destination8  = Buffer;\r
+  Source8       = (CHAR8 *) ((UINTN) FileHandle + FileOffset);\r
+  Length        = *ReadSize;\r
+  while (Length--) {\r
+    *(Destination8++) = *(Source8++);\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+STATIC\r
+EFI_STATUS\r
+GetAlignmentFromFile(char *InFile, UINT32 *Alignment)\r
+  /*\r
+    InFile is input file for getting alignment\r
+    return the alignment\r
+    */\r
+{\r
+  FILE                           *InFileHandle;\r
+  UINT8                          *PeFileBuffer;\r
+  UINTN                          PeFileSize;\r
+  UINT32                         CurSecHdrSize;\r
+  PE_COFF_LOADER_IMAGE_CONTEXT   ImageContext;\r
+  EFI_COMMON_SECTION_HEADER      *CommonHeader;\r
+  EFI_STATUS                     Status;\r
+\r
+  InFileHandle        = NULL;\r
+  PeFileBuffer        = NULL;\r
+  *Alignment          = 0;\r
+\r
+  memset (&ImageContext, 0, sizeof (ImageContext));\r
+\r
+  InFileHandle = fopen(LongFilePath(InFile), "rb");\r
+  if (InFileHandle == NULL){\r
+    Error (NULL, 0, 0001, "Error opening file", InFile);\r
+    return EFI_ABORTED;\r
+  }\r
+  PeFileSize = _filelength (fileno(InFileHandle));\r
+  PeFileBuffer = (UINT8 *) malloc (PeFileSize);\r
+  if (PeFileBuffer == NULL) {\r
+    fclose (InFileHandle);\r
+    Error(NULL, 0, 4001, "Resource", "memory cannot be allocated  of %s", InFileHandle);\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+  fread (PeFileBuffer, sizeof (UINT8), PeFileSize, InFileHandle);\r
+  fclose (InFileHandle);\r
+  CommonHeader = (EFI_COMMON_SECTION_HEADER *) PeFileBuffer;\r
+  CurSecHdrSize = GetSectionHeaderLength(CommonHeader);\r
+  ImageContext.Handle = (VOID *) ((UINTN)PeFileBuffer + CurSecHdrSize);\r
+  ImageContext.ImageRead = (PE_COFF_LOADER_READ_FILE)FfsRebaseImageRead;\r
+  Status               = PeCoffLoaderGetImageInfo(&ImageContext);\r
+  if (EFI_ERROR (Status)) {\r
+    Error (NULL, 0, 3000, "Invalid PeImage", "The input file is %s and return status is %x", InFile, (int) Status);\r
+    return Status;\r
+   }\r
+  *Alignment = ImageContext.SectionAlignment;\r
+  // Free the allocated memory resource\r
+  if (PeFileBuffer != NULL) {\r
+    free (PeFileBuffer);\r
+    PeFileBuffer = NULL;\r
+  }\r
+  return EFI_SUCCESS;\r
+}\r
+\r
 int\r
 main (\r
   int  argc,\r
@@ -1009,7 +1126,7 @@ Returns:
   int                       VersionNumber;\r
   UINT8                     SectType;\r
   UINT8                     SectCompSubType;\r
-  UINT16                    SectGuidAttribute; \r
+  UINT16                    SectGuidAttribute;\r
   UINT64                    SectGuidHeaderLength;\r
   EFI_VERSION_SECTION       *VersionSect;\r
   EFI_USER_INTERFACE_SECTION *UiSect;\r
@@ -1020,6 +1137,13 @@ Returns:
   UINT32                    *InputFileAlign;\r
   UINT32                    InputFileAlignNum;\r
   EFI_COMMON_SECTION_HEADER *SectionHeader;\r
+  CHAR8                     *DummyFileName;\r
+  FILE                      *DummyFile;\r
+  UINTN                     DummyFileSize;\r
+  UINT8                     *DummyFileBuffer;\r
+  FILE                      *InFile;\r
+  UINT8                     *InFileBuffer;\r
+  UINTN                     InFileSize;\r
 \r
   InputFileAlign        = NULL;\r
   InputFileAlignNum     = 0;\r
@@ -1041,9 +1165,16 @@ Returns:
   SectGuidHeaderLength  = 0;\r
   VersionSect           = NULL;\r
   UiSect                = NULL;\r
-  \r
+  DummyFileSize         = 0;\r
+  DummyFileName         = NULL;\r
+  DummyFile             = NULL;\r
+  DummyFileBuffer       = NULL;\r
+  InFile                = NULL;\r
+  InFileSize            = 0;\r
+  InFileBuffer          = NULL;\r
+\r
   SetUtilityName (UTILITY_NAME);\r
-  \r
+\r
   if (argc == 1) {\r
     Error (NULL, 0, 1001, "Missing options", "No options input");\r
     Usage ();\r
@@ -1059,12 +1190,12 @@ Returns:
   if ((stricmp (argv[0], "-h") == 0) || (stricmp (argv[0], "--help") == 0)) {\r
     Version ();\r
     Usage ();\r
-    return STATUS_SUCCESS;    \r
+    return STATUS_SUCCESS;\r
   }\r
 \r
   if (stricmp (argv[0], "--version") == 0) {\r
     Version ();\r
-    return STATUS_SUCCESS;    \r
+    return STATUS_SUCCESS;\r
   }\r
 \r
   while (argc > 0) {\r
@@ -1076,7 +1207,7 @@ Returns:
       }\r
       argc -= 2;\r
       argv += 2;\r
-      continue; \r
+      continue;\r
     }\r
 \r
     if ((stricmp (argv[0], "-o") == 0) || (stricmp (argv[0], "--outputfile") == 0)) {\r
@@ -1087,7 +1218,7 @@ Returns:
       }\r
       argc -= 2;\r
       argv += 2;\r
-      continue; \r
+      continue;\r
     }\r
 \r
     if ((stricmp (argv[0], "-c") == 0) || (stricmp (argv[0], "--compress") == 0)) {\r
@@ -1111,8 +1242,22 @@ Returns:
       argv += 2;\r
       continue;\r
     }\r
+    if (stricmp (argv[0], "--dummy") == 0) {\r
+      DummyFileName = argv[1];\r
+      if (DummyFileName == NULL) {\r
+        Error (NULL, 0, 1003, "Invalid option value", "Dummy file can't be NULL");\r
+        goto Finish;\r
+      }\r
+      argc -= 2;\r
+      argv += 2;\r
+      continue;\r
+    }\r
 \r
     if ((stricmp (argv[0], "-r") == 0) || (stricmp (argv[0], "--attributes") == 0)) {\r
+      if (argv[1] == NULL) {\r
+        Error (NULL, 0, 1003, "Invalid option value", "Guid section attributes can't be NULL");\r
+        goto Finish;\r
+      }\r
       if (stricmp (argv[1], mGUIDedSectionAttribue[EFI_GUIDED_SECTION_PROCESSING_REQUIRED]) == 0) {\r
         SectGuidAttribute |= EFI_GUIDED_SECTION_PROCESSING_REQUIRED;\r
       } else if (stricmp (argv[1], mGUIDedSectionAttribue[EFI_GUIDED_SECTION_AUTH_STATUS_VALID]) == 0) {\r
@@ -1215,7 +1360,7 @@ Returns:
         InputFileAlign = (UINT32 *) malloc (MAXIMUM_INPUT_FILE_NUM * sizeof (UINT32));\r
         if (InputFileAlign == NULL) {\r
           Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");\r
-          return 1;\r
+          goto Finish;\r
         }\r
         memset (InputFileAlign, 1, MAXIMUM_INPUT_FILE_NUM * sizeof (UINT32));\r
       } else if (InputFileAlignNum % MAXIMUM_INPUT_FILE_NUM == 0) {\r
@@ -1226,20 +1371,23 @@ Returns:
 \r
         if (InputFileAlign == NULL) {\r
           Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");\r
-          return 1;\r
+          goto Finish;\r
         }\r
         memset (&(InputFileAlign[InputFileNum]), 1, (MAXIMUM_INPUT_FILE_NUM * sizeof (UINT32)));\r
       }\r
-      \r
-      Status = StringtoAlignment (argv[1], &(InputFileAlign[InputFileAlignNum]));\r
-      if (EFI_ERROR (Status)) {\r
-        Error (NULL, 0, 1003, "Invalid option value", "%s = %s", argv[0], argv[1]);\r
-        goto Finish;\r
+      if (stricmp(argv[1], "0") == 0) {\r
+        InputFileAlign[InputFileAlignNum] = 0;\r
+      } else {\r
+        Status = StringtoAlignment (argv[1], &(InputFileAlign[InputFileAlignNum]));\r
+        if (EFI_ERROR (Status)) {\r
+          Error (NULL, 0, 1003, "Invalid option value", "%s = %s", argv[0], argv[1]);\r
+          goto Finish;\r
+        }\r
       }\r
       argc -= 2;\r
       argv += 2;\r
       InputFileAlignNum ++;\r
-      continue; \r
+      continue;\r
     }\r
 \r
     //\r
@@ -1249,7 +1397,7 @@ Returns:
       InputFileName = (CHAR8 **) malloc (MAXIMUM_INPUT_FILE_NUM * sizeof (CHAR8 *));\r
       if (InputFileName == NULL) {\r
         Error (NULL, 0, 4001, "Resource", "memory cannot be allcoated");\r
-        return 1;\r
+        goto Finish;\r
       }\r
       memset (InputFileName, 0, (MAXIMUM_INPUT_FILE_NUM * sizeof (CHAR8 *)));\r
     } else if (InputFileNum % MAXIMUM_INPUT_FILE_NUM == 0) {\r
@@ -1263,7 +1411,7 @@ Returns:
 \r
       if (InputFileName == NULL) {\r
         Error (NULL, 0, 4001, "Resource", "memory cannot be allcoated");\r
-        return 1;\r
+        goto Finish;\r
       }\r
       memset (&(InputFileName[InputFileNum]), 0, (MAXIMUM_INPUT_FILE_NUM * sizeof (CHAR8 *)));\r
     }\r
@@ -1277,9 +1425,83 @@ Returns:
     Error (NULL, 0, 1003, "Invalid option", "section alignment must be set for each section");\r
     goto Finish;\r
   }\r
+  for (Index = 0; Index < InputFileAlignNum; Index++)\r
+  {\r
+    if (InputFileAlign[Index] == 0) {\r
+      Status = GetAlignmentFromFile(InputFileName[Index], &(InputFileAlign[Index]));\r
+      if (EFI_ERROR(Status)) {\r
+        Error (NULL, 0, 1003, "Fail to get Alignment from %s", InputFileName[InputFileNum]);\r
+        goto Finish;\r
+      }\r
+    }\r
+  }\r
 \r
   VerboseMsg ("%s tool start.", UTILITY_NAME);\r
 \r
+  if (DummyFileName != NULL) {\r
+      //\r
+      // Open file and read contents\r
+      //\r
+      DummyFile = fopen (LongFilePath (DummyFileName), "rb");\r
+      if (DummyFile == NULL) {\r
+        Error (NULL, 0, 0001, "Error opening file", DummyFileName);\r
+        goto Finish;\r
+      }\r
+\r
+      fseek (DummyFile, 0, SEEK_END);\r
+      DummyFileSize = ftell (DummyFile);\r
+      fseek (DummyFile, 0, SEEK_SET);\r
+      DummyFileBuffer = (UINT8 *) malloc (DummyFileSize);\r
+      if (DummyFileBuffer == NULL) {\r
+        fclose(DummyFile);\r
+        Error (NULL, 0, 4001, "Resource", "memory cannot be allcoated");\r
+        goto Finish;\r
+      }\r
+\r
+      fread(DummyFileBuffer, 1, DummyFileSize, DummyFile);\r
+      fclose(DummyFile);\r
+      DebugMsg (NULL, 0, 9, "Dummy files", "the dummy file name is %s and the size is %u bytes", DummyFileName, (unsigned) DummyFileSize);\r
+\r
+      if (InputFileName == NULL) {\r
+        Error (NULL, 0, 4001, "Resource", "memory cannot be allcoated");\r
+        goto Finish;\r
+      }\r
+      InFile = fopen(LongFilePath(InputFileName[0]), "rb");\r
+      if (InFile == NULL) {\r
+        Error (NULL, 0, 0001, "Error opening file", InputFileName[0]);\r
+        goto Finish;\r
+      }\r
+\r
+      fseek (InFile, 0, SEEK_END);\r
+      InFileSize = ftell (InFile);\r
+      fseek (InFile, 0, SEEK_SET);\r
+      InFileBuffer = (UINT8 *) malloc (InFileSize);\r
+      if (InFileBuffer == NULL) {\r
+        fclose(InFile);\r
+        Error (NULL, 0, 4001, "Resource", "memory cannot be allcoated");\r
+        goto Finish;\r
+      }\r
+\r
+      fread(InFileBuffer, 1, InFileSize, InFile);\r
+      fclose(InFile);\r
+      DebugMsg (NULL, 0, 9, "Input files", "the input file name is %s and the size is %u bytes", InputFileName[0], (unsigned) InFileSize);\r
+      if (InFileSize > DummyFileSize){\r
+        if (stricmp((CHAR8 *)DummyFileBuffer, (CHAR8 *)(InFileBuffer + (InFileSize - DummyFileSize))) == 0){\r
+          SectGuidHeaderLength = InFileSize - DummyFileSize;\r
+        }\r
+      }\r
+      if (SectGuidHeaderLength == 0) {\r
+        SectGuidAttribute |= EFI_GUIDED_SECTION_PROCESSING_REQUIRED;\r
+      }\r
+      if (DummyFileBuffer != NULL) {\r
+        free (DummyFileBuffer);\r
+        DummyFileBuffer = NULL;\r
+      }\r
+      if (InFileBuffer != NULL) {\r
+        free (InFileBuffer);\r
+      }\r
+    }\r
+\r
   //\r
   // Parse all command line parameters to get the corresponding section type.\r
   //\r
@@ -1307,14 +1529,14 @@ Returns:
     VerboseMsg ("Compress method is %s", mCompressionTypeName [SectCompSubType]);\r
   } else if (stricmp (SectionName, mSectionTypeName[EFI_SECTION_GUID_DEFINED]) == 0) {\r
     SectType     = EFI_SECTION_GUID_DEFINED;\r
-    \r
+\r
     if ((SectGuidAttribute & EFI_GUIDED_SECTION_NONE) != 0) {\r
       //\r
       // NONE attribute, clear attribute value.\r
       //\r
       SectGuidAttribute = SectGuidAttribute & ~EFI_GUIDED_SECTION_NONE;\r
     }\r
-    VerboseMsg ("Vendor Guid is %08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X", \r
+    VerboseMsg ("Vendor Guid is %08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X",\r
                 (unsigned) VendorGuid.Data1,\r
                 VendorGuid.Data2,\r
                 VendorGuid.Data3,\r
@@ -1373,7 +1595,7 @@ Returns:
     Error (NULL, 0, 1003, "Invalid option value", "SectionType = %s", SectionName);\r
     goto Finish;\r
   }\r
-  \r
+\r
   //\r
   // GuidValue is only required by Guided section.\r
   //\r
@@ -1382,10 +1604,10 @@ Returns:
     (CompareGuid (&VendorGuid, &mZeroGuid) != 0)) {\r
     fprintf (stdout, "Warning: the input guid value is not required for this section type %s\n", SectionName);\r
   }\r
-  \r
+\r
   //\r
   // Check whether there is input file\r
-  //  \r
+  //\r
   if ((SectType != EFI_SECTION_VERSION) && (SectType != EFI_SECTION_USER_INTERFACE)) {\r
     //\r
     // The input file are required for other section type.\r
@@ -1508,7 +1730,7 @@ Returns:
               OutFileBuffer,\r
               &InputLength\r
               );\r
-  \r
+\r
     if (Status == EFI_BUFFER_TOO_SMALL) {\r
       OutFileBuffer = (UINT8 *) malloc (InputLength);\r
       if (OutFileBuffer == NULL) {\r
@@ -1540,10 +1762,10 @@ Returns:
               );\r
     break;\r
   }\r
-  \r
+\r
   if (Status != EFI_SUCCESS || OutFileBuffer == NULL) {\r
     Error (NULL, 0, 2000, "Status is not successful", "Status value is 0x%X", (int) Status);\r
-         goto Finish;\r
+    goto Finish;\r
   }\r
 \r
   //\r
@@ -1556,7 +1778,7 @@ Returns:
       InputLength = ((EFI_COMMON_SECTION_HEADER2 *)SectionHeader)->ExtendedSize;\r
     }\r
   }\r
-  \r
+\r
   //\r
   // Write the output file\r
   //\r
@@ -1584,7 +1806,11 @@ Finish:
   if (OutFile != NULL) {\r
     fclose (OutFile);\r
   }\r
-  \r
+\r
+  if (DummyFileBuffer != NULL) {\r
+    free (DummyFileBuffer);\r
+  }\r
+\r
   VerboseMsg ("%s tool done with return code is 0x%x.", UTILITY_NAME, GetUtilityStatus ());\r
 \r
   return GetUtilityStatus ();\r