Enhance GenFv tool to print Fv Size and Length, and Get module map by module pdb...
authorlgao4 <lgao4@7335b38e-4728-0410-8992-fb3ffe349368>
Tue, 12 Aug 2008 03:32:55 +0000 (03:32 +0000)
committerlgao4 <lgao4@7335b38e-4728-0410-8992-fb3ffe349368>
Tue, 12 Aug 2008 03:32:55 +0000 (03:32 +0000)
git-svn-id: https://buildtools.tianocore.org/svn/buildtools/trunk/BaseTools@1298 7335b38e-4728-0410-8992-fb3ffe349368

Source/C/Common/BasePeCoff.c
Source/C/Common/PeCoffLib.h
Source/C/GenFv/GenFv.c
Source/C/GenFv/GenFvInternalLib.c
Source/C/GenFv/GenFvInternalLib.h
Source/C/Include/Common/MdeModuleHii.h
Source/C/VfrCompile/Makefile

index 6633b67..523837f 100644 (file)
@@ -1163,3 +1163,145 @@ Returns:
 \r
   return Status;\r
 }\r
+\r
+/**\r
+  Returns a pointer to the PDB file name for a PE/COFF image that has been\r
+  loaded into system memory with the PE/COFF Loader Library functions.\r
+\r
+  Returns the PDB file name for the PE/COFF image specified by Pe32Data.  If\r
+  the PE/COFF image specified by Pe32Data is not a valid, then NULL is\r
+  returned.  If the PE/COFF image specified by Pe32Data does not contain a\r
+  debug directory entry, then NULL is returned.  If the debug directory entry\r
+  in the PE/COFF image specified by Pe32Data does not contain a PDB file name,\r
+  then NULL is returned.\r
+  If Pe32Data is NULL, then return NULL.\r
+\r
+  @param  Pe32Data   Pointer to the PE/COFF image that is loaded in system\r
+                     memory.\r
+\r
+  @return The PDB file name for the PE/COFF image specified by Pe32Data or NULL\r
+          if it cannot be retrieved.\r
+\r
+**/\r
+VOID *\r
+EFIAPI\r
+PeCoffLoaderGetPdbPointer (\r
+  IN VOID  *Pe32Data\r
+  )\r
+{\r
+  EFI_IMAGE_DOS_HEADER                  *DosHdr;\r
+  EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION   Hdr;\r
+  EFI_IMAGE_DATA_DIRECTORY              *DirectoryEntry;\r
+  EFI_IMAGE_DEBUG_DIRECTORY_ENTRY       *DebugEntry;\r
+  UINTN                                 DirCount;\r
+  VOID                                  *CodeViewEntryPointer;\r
+  INTN                                  TEImageAdjust;\r
+  UINT32                                NumberOfRvaAndSizes;\r
+  UINT16                                Magic;\r
+\r
+  if (Pe32Data == NULL) {\r
+    return NULL;\r
+  }\r
+\r
+  TEImageAdjust       = 0;\r
+  DirectoryEntry      = NULL;\r
+  DebugEntry          = NULL;\r
+  NumberOfRvaAndSizes = 0;\r
+\r
+  DosHdr = (EFI_IMAGE_DOS_HEADER *)Pe32Data;\r
+  if (EFI_IMAGE_DOS_SIGNATURE == DosHdr->e_magic) {\r
+    //\r
+    // DOS image header is present, so read the PE header after the DOS image header.\r
+    //\r
+    Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)((UINTN) Pe32Data + (UINTN) ((DosHdr->e_lfanew) & 0x0ffff));\r
+  } else {\r
+    //\r
+    // DOS image header is not present, so PE header is at the image base.\r
+    //\r
+    Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)Pe32Data;\r
+  }\r
+\r
+  if (EFI_TE_IMAGE_HEADER_SIGNATURE == Hdr.Te->Signature) {\r
+    if (Hdr.Te->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress != 0) {\r
+      DirectoryEntry  = &Hdr.Te->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG];\r
+      TEImageAdjust   = sizeof (EFI_TE_IMAGE_HEADER) - Hdr.Te->StrippedSize;\r
+      DebugEntry = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *)((UINTN) Hdr.Te +\r
+                    Hdr.Te->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress +\r
+                    TEImageAdjust);\r
+    }\r
+  } else if (EFI_IMAGE_NT_SIGNATURE == Hdr.Pe32->Signature) {\r
+    //\r
+    // NOTE: We use Machine field to identify PE32/PE32+, instead of Magic.\r
+    //       It is due to backward-compatibility, for some system might\r
+    //       generate PE32+ image with PE32 Magic.\r
+    //\r
+    switch (Hdr.Pe32->FileHeader.Machine) {\r
+    case EFI_IMAGE_MACHINE_IA32:\r
+      //\r
+      // Assume PE32 image with IA32 Machine field.\r
+      //\r
+      Magic = EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC;\r
+      break;\r
+    case EFI_IMAGE_MACHINE_X64:\r
+    case EFI_IMAGE_MACHINE_IPF:\r
+      //\r
+      // Assume PE32+ image with X64 or IPF Machine field\r
+      //\r
+      Magic = EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC;\r
+      break;\r
+    default:\r
+      //\r
+      // For unknow Machine field, use Magic in optional Header\r
+      //\r
+      Magic = Hdr.Pe32->OptionalHeader.Magic;\r
+    }\r
+\r
+    if (EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC == Magic) {\r
+      //\r
+      // Use PE32 offset get Debug Directory Entry\r
+      //\r
+      NumberOfRvaAndSizes = Hdr.Pe32->OptionalHeader.NumberOfRvaAndSizes;\r
+      DirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *)&(Hdr.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG]);\r
+      DebugEntry     = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *) ((UINTN) Pe32Data + DirectoryEntry->VirtualAddress);\r
+    } else if (Hdr.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) {\r
+      //\r
+      // Use PE32+ offset get Debug Directory Entry\r
+      //\r
+      NumberOfRvaAndSizes = Hdr.Pe32Plus->OptionalHeader.NumberOfRvaAndSizes;\r
+      DirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *)&(Hdr.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG]);\r
+      DebugEntry     = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *) ((UINTN) Pe32Data + DirectoryEntry->VirtualAddress);\r
+    }\r
+\r
+    if (NumberOfRvaAndSizes <= EFI_IMAGE_DIRECTORY_ENTRY_DEBUG) {\r
+      DirectoryEntry = NULL;\r
+      DebugEntry = NULL;\r
+    }\r
+  } else {\r
+    return NULL;\r
+  }\r
+\r
+  if (NULL == DebugEntry || NULL == DirectoryEntry) {\r
+    return NULL;\r
+  }\r
+\r
+  //\r
+  // Scan the directory to find the debug entry.\r
+  // \r
+  for (DirCount = 0; DirCount < DirectoryEntry->Size; DirCount += sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY), DebugEntry++) {\r
+    if (EFI_IMAGE_DEBUG_TYPE_CODEVIEW == DebugEntry->Type) {\r
+      if (DebugEntry->SizeOfData > 0) {\r
+        CodeViewEntryPointer = (VOID *) ((UINTN) DebugEntry->RVA + ((UINTN)Pe32Data) + (UINTN)TEImageAdjust);\r
+        switch (* (UINT32 *) CodeViewEntryPointer) {\r
+        case CODEVIEW_SIGNATURE_NB10:\r
+          return (VOID *) ((CHAR8 *)CodeViewEntryPointer + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY));\r
+        case CODEVIEW_SIGNATURE_RSDS:\r
+          return (VOID *) ((CHAR8 *)CodeViewEntryPointer + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_RSDS_ENTRY));\r
+        default:\r
+          break;\r
+        }\r
+      }\r
+    }\r
+  }\r
+\r
+  return NULL;\r
+}\r
index 9eb7573..fc2e4ca 100644 (file)
@@ -128,4 +128,10 @@ PeCoffLoaderLoadImage (
   )\r
 ;\r
 \r
+VOID *\r
+EFIAPI\r
+PeCoffLoaderGetPdbPointer (\r
+  IN VOID  *Pe32Data\r
+  )\r
+;\r
 #endif\r
index 7288995..e0656c3 100644 (file)
@@ -105,6 +105,15 @@ Returns:
   fprintf (stdout, "  -i FileName, --inputfile FileName\n\\r
                         File is the input FV.inf or Cap.inf to specify\n\\r
                         how to construct FvImage or CapImage.\n");\r
+  fprintf (stdout, "  -b BlockSize, --blocksize BlockSize\n\\r
+                        BlockSize is one HEX or DEC format value\n\\r
+                        BlockSize is required by Fv Image.\n");\r
+  fprintf (stdout, "  -n NumberBlock, --numberblock NumberBlock\n\\r
+                        NumberBlock is one HEX or DEC format value\n\\r
+                        NumberBlock is one optional parameter.\n");\r
+  fprintf (stdout, "  -f FfsFile, --ffsfile FfsFile\n\\r
+                        FfsFile is placed into Fv Image\n\\r
+                        multi files can input one by one\n");\r
   fprintf (stdout, "  -r Address, --baseaddr Address\n\\r
                         Address is the rebase start address for drivers that\n\\r
                         run in Flash. It supports DEC or HEX digital format.\n");\r
@@ -117,6 +126,15 @@ Returns:
   fprintf (stdout, "  -m logfile, --map logfile\n\\r
                         Logfile is the output fv map file name. if it is not\n\\r
                         given, the FvName.map will be the default map file name\n"); \r
+  fprintf (stdout, "  --capguid GuidValue\n\\r
+                        GuidValue is one specific capsule vendor guid value.\n\\r
+                        Its format is xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\n");\r
+  fprintf (stdout, "  --capflag CapFlag\n\\r
+                        Capsule Reset Flag can be PersistAcrossReset,\n\\r
+                        or PopulateSystemTable or not set.\n");\r
+  fprintf (stdout, "  --capheadsize HeadSize\n\\r
+                        HeadSize is one HEX or DEC format value\n\\r
+                        HeadSize is required by Capsule Image.\n");                        \r
   fprintf (stdout, "  -c, --capsule         Create Capsule Image.\n");\r
   fprintf (stdout, "  -p, --dump            Dump Capsule Image header.\n");\r
   fprintf (stdout, "  -v, --verbose         Turn on verbose output with informational messages.\n");\r
@@ -126,6 +144,9 @@ Returns:
   fprintf (stdout, "  -h, --help            Show this help message and exit.\n");\r
 }\r
 \r
+UINT32 mFvTotalSize;\r
+UINT32 mFvTakenSize;\r
+\r
 int\r
 main (\r
   IN INTN   argc,\r
@@ -172,7 +193,8 @@ Returns:
   MEMORY_FILE           AddrMemoryFile;\r
   FILE                  *FpFile;\r
   EFI_CAPSULE_HEADER    *CapsuleHeader;\r
-  UINT64                LogLevel;\r
+  UINT64                LogLevel, TempNumber;\r
+  UINT32                Index;\r
 \r
   InfFileName   = NULL;\r
   AddrFileName  = NULL;\r
@@ -188,6 +210,10 @@ Returns:
   FpFile        = NULL;\r
   CapsuleHeader = NULL;\r
   LogLevel      = 0;\r
+  TempNumber    = 0;\r
+  Index         = 0;\r
+  mFvTotalSize  = 0;\r
+  mFvTakenSize  = 0;\r
 \r
   SetUtilityName (UTILITY_NAME);\r
 \r
@@ -197,6 +223,12 @@ Returns:
     return STATUS_ERROR;\r
   }\r
 \r
+  //\r
+  // Init global data to Zero\r
+  //\r
+  memset (&gFvDataInfo, 0, sizeof (FV_INFO));\r
+  memset (&gCapDataInfo, 0, sizeof (CAP_INFO)); \r
+   \r
   //\r
   // Parse command line\r
   //\r
@@ -259,6 +291,44 @@ Returns:
       continue; \r
     }\r
 \r
+    if ((stricmp (argv[0], "-b") == 0) || (stricmp (argv[0], "--blocksize") == 0)) {\r
+      Status = AsciiStringToUint64 (argv[1], FALSE, &TempNumber);\r
+      if (EFI_ERROR (Status)) {\r
+        Error (NULL, 0, 1003, "Invalid option value", "%s = %s", argv[0], argv[1]);\r
+        return STATUS_ERROR;        \r
+      }\r
+      gFvDataInfo.FvBlocks[0].Length = (UINT32) TempNumber;\r
+      DebugMsg (NULL, 0, 9, "FV Block Size", "%s = 0x%x", EFI_BLOCK_SIZE_STRING, TempNumber);\r
+      argc -= 2;\r
+      argv += 2;\r
+      continue; \r
+    }\r
+\r
+    if ((stricmp (argv[0], "-n") == 0) || (stricmp (argv[0], "--numberblock") == 0)) {\r
+      Status = AsciiStringToUint64 (argv[1], FALSE, &TempNumber);\r
+      if (EFI_ERROR (Status)) {\r
+        Error (NULL, 0, 1003, "Invalid option value", "%s = %s", argv[0], argv[1]);\r
+        return STATUS_ERROR;        \r
+      }\r
+      gFvDataInfo.FvBlocks[0].NumBlocks = (UINT32) TempNumber;\r
+      DebugMsg (NULL, 0, 9, "FV Number Block", "%s = 0x%x", EFI_NUM_BLOCKS_STRING, TempNumber);\r
+      argc -= 2;\r
+      argv += 2;\r
+      continue; \r
+    }\r
+\r
+    if ((stricmp (argv[0], "-f") == 0) || (stricmp (argv[0], "--ffsfile") == 0)) {\r
+      if (argv[1] == NULL) {\r
+        Error (NULL, 0, 1003, "Invalid option value", "Input Ffsfile can't be null");\r
+        return STATUS_ERROR;\r
+      }\r
+      strcpy (gFvDataInfo.FvFiles[Index++], argv[1]);\r
+      DebugMsg (NULL, 0, 9, "FV component file", "the %dth name is %s", Index - 1, argv[1]);\r
+      argc -= 2;\r
+      argv += 2;\r
+      continue; \r
+    }\r
+\r
     if ((stricmp (argv[0], "-c") == 0) || (stricmp (argv[0], "--capsule") == 0)) {\r
       CapsuleFlag = TRUE;\r
       argc --;\r
@@ -266,6 +336,59 @@ Returns:
       continue; \r
     }\r
 \r
+    if (stricmp (argv[0], "--capheadsize") == 0) {\r
+      //\r
+      // Get Capsule Image Header Size\r
+      //\r
+      Status = AsciiStringToUint64 (argv[1], FALSE, &TempNumber);\r
+      if (EFI_ERROR (Status)) {\r
+        Error (NULL, 0, 1003, "Invalid option value", "%s = %s", argv[0], argv[1]);\r
+        return STATUS_ERROR;        \r
+      }\r
+      gCapDataInfo.HeaderSize = (UINT32) TempNumber;\r
+      DebugMsg (NULL, 0, 9, "Capsule Header size", "%s = 0x%x", EFI_CAPSULE_HEADER_SIZE_STRING, TempNumber);\r
+      argc -= 2;\r
+      argv += 2;\r
+      continue; \r
+    }\r
+\r
+    if (stricmp (argv[0], "--capflag") == 0) {\r
+      //\r
+      // Get Capsule Header\r
+      //\r
+      if (argv[1] == NULL) {\r
+        Error (NULL, 0, 1003, "Option value is not set", "%s = %s", argv[0], argv[1]);\r
+        return STATUS_ERROR;\r
+      }\r
+      if (strcmp (argv[1], "PopulateSystemTable") == 0) {\r
+        gCapDataInfo.Flags |= CAPSULE_FLAGS_PERSIST_ACROSS_RESET | CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE;\r
+      } else if (strcmp (argv[1], "PersistAcrossReset") == 0) {\r
+        gCapDataInfo.Flags |= CAPSULE_FLAGS_PERSIST_ACROSS_RESET;\r
+      } else {\r
+        Error (NULL, 0, 1003, "Invalid option value", "%s = %s", argv[0], argv[1]);\r
+        return STATUS_ERROR;\r
+      }\r
+      DebugMsg (NULL, 0, 9, "Capsule Flag", argv[1]);\r
+      argc -= 2;\r
+      argv += 2;\r
+      continue; \r
+    }\r
+\r
+    if (stricmp (argv[0], "--capguid") == 0) {\r
+      //\r
+      // Get the Capsule Guid\r
+      //\r
+      Status = StringToGuid (argv[1], &gCapDataInfo.CapGuid);\r
+      if (EFI_ERROR (Status)) {\r
+        Error (NULL, 0, 1003, "Invalid option value", "%s = %s", EFI_CAPSULE_GUID_STRING, argv[1]);\r
+        return EFI_ABORTED;\r
+      }\r
+      DebugMsg (NULL, 0, 9, "Capsule Guid", "%s = %s", EFI_CAPSULE_GUID_STRING, argv[1]);\r
+      argc -= 2;\r
+      argv += 2;\r
+      continue; \r
+    }\r
+\r
     if ((stricmp (argv[0], "-p") == 0) || (stricmp (argv[0], "--dump") == 0)) {\r
       DumpCapsule = TRUE;\r
       argc --;\r
@@ -327,10 +450,10 @@ Returns:
   VerboseMsg ("%s tool start.", UTILITY_NAME);\r
   \r
   //\r
-  // check input parameter\r
+  // check input parameter, InfFileName can be NULL\r
   //\r
-  if (InfFileName == NULL) {\r
-    Error (NULL, 0, 1001, "Missing option", "Input File");\r
+  if (InfFileName == NULL && DumpCapsule) {\r
+    Error (NULL, 0, 1001, "Missing option", "Input Capsule Image");\r
     return STATUS_ERROR;\r
   }\r
   VerboseMsg ("the input file name is %s", InfFileName);\r
@@ -393,14 +516,18 @@ Returns:
     // free the allocated memory space for addr file.\r
     //\r
     free (InfFileImage);\r
+    InfFileImage = NULL;\r
+    InfFileSize  = 0;\r
   }\r
 \r
   //\r
   // Read the INF file image\r
   //\r
-  Status = GetFileImage (InfFileName, &InfFileImage, &InfFileSize);\r
-  if (EFI_ERROR (Status)) {\r
-    return STATUS_ERROR;\r
+  if (InfFileName != NULL) {\r
+    Status = GetFileImage (InfFileName, &InfFileImage, &InfFileSize);\r
+    if (EFI_ERROR (Status)) {\r
+      return STATUS_ERROR;\r
+    }\r
   }\r
   \r
   if (DumpCapsule) {\r
@@ -440,11 +567,15 @@ Returns:
     //\r
     // Call the GenerateCapImage to generate Capsule Image\r
     //\r
-    GenerateCapImage (\r
-      InfFileImage, \r
-      InfFileSize,\r
-      OutFileName\r
-      );\r
+    for (Index = 0; gFvDataInfo.FvFiles[Index][0] != '\0'; Index ++) {\r
+      strcpy (gCapDataInfo.CapFiles[Index], gFvDataInfo.FvFiles[Index]);\r
+    }\r
+\r
+    Status = GenerateCapImage (\r
+              InfFileImage, \r
+              InfFileSize,\r
+              OutFileName\r
+              );\r
   } else {\r
     VerboseMsg ("Create Fv image and its map file");\r
     if (XipBase != 0) {\r
@@ -453,15 +584,15 @@ Returns:
     //\r
     // Call the GenerateFvImage to generate Fv Image\r
     //\r
-    GenerateFvImage (\r
-      InfFileImage,\r
-      InfFileSize,\r
-      OutFileName,\r
-      MapFileName,\r
-      XipBase,\r
-      &BtBase,\r
-      &RtBase\r
-      );\r
+    Status = GenerateFvImage (\r
+              InfFileImage,\r
+              InfFileSize,\r
+              OutFileName,\r
+              MapFileName,\r
+              XipBase,\r
+              &BtBase,\r
+              &RtBase\r
+              );\r
   }\r
 \r
   //\r
@@ -474,7 +605,7 @@ Returns:
   //\r
   //  update boot driver address and runtime driver address in address file\r
   //\r
-  if (AddrFileName != NULL) {\r
+  if (Status == EFI_SUCCESS && AddrFileName != NULL) {\r
     FpFile = fopen (AddrFileName, "w");\r
     if (FpFile == NULL) {\r
       Error (NULL, 0, 0001, "Error opening file", AddrFileName);\r
@@ -492,6 +623,21 @@ Returns:
       fprintf (FpFile, " = 0x%x\n", RtBase);\r
       DebugMsg (NULL, 0, 9, "Updated runtime driver base address", "%s = 0x%x", EFI_FV_RUNTIME_DRIVER_BASE_ADDRESS_STRING, RtBase);\r
     }\r
+    if (mFvTotalSize != 0) {\r
+      fprintf (FpFile, EFI_FV_TOTAL_SIZE_STRING);\r
+      fprintf (FpFile, " = 0x%x\n", mFvTotalSize);\r
+      DebugMsg (NULL, 0, 9, "The Total Fv Size", "%s = 0x%x", EFI_FV_TOTAL_SIZE_STRING, mFvTotalSize);\r
+    }\r
+    if (mFvTakenSize != 0) {\r
+      fprintf (FpFile, EFI_FV_TAKEN_SIZE_STRING);\r
+      fprintf (FpFile, " = 0x%x\n", mFvTakenSize);\r
+      DebugMsg (NULL, 0, 9, "The used Fv Size", "%s = 0x%x", EFI_FV_TAKEN_SIZE_STRING, mFvTakenSize);\r
+    }\r
+    if (mFvTotalSize != 0 && mFvTakenSize != 0) {\r
+      fprintf (FpFile, EFI_FV_SPACE_SIZE_STRING);\r
+      fprintf (FpFile, " = 0x%x\n", mFvTotalSize - mFvTakenSize);\r
+      DebugMsg (NULL, 0, 9, "The space Fv size", "%s = 0x%x", EFI_FV_SPACE_SIZE_STRING, mFvTotalSize - mFvTakenSize);\r
+    }\r
     fclose (FpFile);\r
   }\r
 \r
index 90aa1e8..2fefec6 100644 (file)
@@ -41,6 +41,8 @@ STATIC UINT32   MaxFfsAlignment = 0;
 EFI_GUID  mEfiFirmwareFileSystem2Guid = EFI_FIRMWARE_FILE_SYSTEM2_GUID;\r
 EFI_GUID  mEfiFirmwareVolumeTopFileGuid = EFI_FFS_VOLUME_TOP_FILE_GUID;\r
 EFI_GUID  mFileGuidArray [MAX_NUMBER_OF_FILES_IN_FV] = {0};\r
+EFI_GUID  mZeroGuid                 = {0x0, 0x0, 0x0, {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}};\r
+EFI_GUID  mDefaultCapsuleGuid       = {0x3B6686BD, 0x0D76, 0x4030, { 0xB7, 0x0E, 0xB5, 0x51, 0x9E, 0x2F, 0xC5, 0xA0 }};\r
 \r
 CHAR8      *mFvbAttributeName[] = {\r
   EFI_FVB2_READ_DISABLED_CAP_STRING, \r
@@ -153,6 +155,9 @@ UINT8                                   m64kRecoveryStartupApDataArray[SIZEOF_ST
   0x00\r
 };\r
 \r
+FV_INFO                     gFvDataInfo;\r
+CAP_INFO                    gCapDataInfo;\r
+\r
 EFI_STATUS\r
 ParseFvInf (\r
   IN  MEMORY_FILE  *InfFile,\r
@@ -178,13 +183,14 @@ Returns:
 {\r
   CHAR8       Value[_MAX_PATH];\r
   UINT64      Value64;\r
-  UINTN       Index;\r
+  UINTN       Index, Number;\r
   EFI_STATUS  Status;\r
 \r
   //\r
   // Initialize FV info\r
   //\r
-  memset (FvInfo, 0, sizeof (FV_INFO));\r
+  // memset (FvInfo, 0, sizeof (FV_INFO));\r
+  //\r
 \r
   //\r
   // Read the FV base address\r
@@ -274,11 +280,15 @@ Returns:
   //\r
   // Read block maps\r
   //\r
+  Number = 0;\r
   for (Index = 0; Index < MAX_NUMBER_OF_FV_BLOCKS; Index++) {\r
+    if (FvInfo->FvBlocks[Index].Length != 0) {\r
+      continue;\r
+    }\r
     //\r
     // Read block size\r
     //\r
-    Status = FindToken (InfFile, OPTIONS_SECTION_STRING, EFI_BLOCK_SIZE_STRING, Index, Value);\r
+    Status = FindToken (InfFile, OPTIONS_SECTION_STRING, EFI_BLOCK_SIZE_STRING, Number, Value);\r
 \r
     if (Status == EFI_SUCCESS) {\r
       //\r
@@ -297,7 +307,7 @@ Returns:
       // If there is no blocks size, but there is the number of block, then we have a mismatched pair\r
       // and should return an error.\r
       //\r
-      Status = FindToken (InfFile, OPTIONS_SECTION_STRING, EFI_NUM_BLOCKS_STRING, Index, Value);\r
+      Status = FindToken (InfFile, OPTIONS_SECTION_STRING, EFI_NUM_BLOCKS_STRING, Number, Value);\r
       if (!EFI_ERROR (Status)) {\r
         Error (NULL, 0, 2000, "Invalid parameter", "both %s and %s must be specified.", EFI_NUM_BLOCKS_STRING, EFI_BLOCK_SIZE_STRING);\r
         return EFI_ABORTED;\r
@@ -312,7 +322,7 @@ Returns:
     //\r
     // Read blocks number\r
     //\r
-    Status = FindToken (InfFile, OPTIONS_SECTION_STRING, EFI_NUM_BLOCKS_STRING, Index, Value);\r
+    Status = FindToken (InfFile, OPTIONS_SECTION_STRING, EFI_NUM_BLOCKS_STRING, Number++, Value);\r
 \r
     if (Status == EFI_SUCCESS) {\r
       //\r
@@ -337,11 +347,15 @@ Returns:
   //\r
   // Read files\r
   //\r
+  Number = 0;\r
   for (Index = 0; Index < MAX_NUMBER_OF_FILES_IN_FV; Index++) {\r
+    if (FvInfo->FvFiles[Index][0] != '\0') {\r
+      continue;\r
+    }\r
     //\r
     // Read the number of blocks\r
     //\r
-    Status = FindToken (InfFile, FILES_SECTION_STRING, EFI_FILE_NAME_STRING, Index, Value);\r
+    Status = FindToken (InfFile, FILES_SECTION_STRING, EFI_FILE_NAME_STRING, Number++, Value);\r
 \r
     if (Status == EFI_SUCCESS) {\r
       //\r
@@ -357,13 +371,6 @@ Returns:
   if (Index == 0) {\r
     Warning (NULL, 0, 0, "FV components are not specified.", NULL);\r
   }\r
-  //\r
-  // Compute size for easy access later\r
-  //\r
-  FvInfo->Size = 0;\r
-  for (Index = 0; FvInfo->FvBlocks[Index].NumBlocks; Index++) {\r
-    FvInfo->Size += FvInfo->FvBlocks[Index].NumBlocks * FvInfo->FvBlocks[Index].Length;\r
-  }\r
 \r
   return EFI_SUCCESS;\r
 }\r
@@ -1410,7 +1417,6 @@ Returns:
   EFI_STATUS                  Status;\r
   MEMORY_FILE                 InfMemoryFile;\r
   MEMORY_FILE                 FvImageMemoryFile;\r
-  FV_INFO                     FvInfo;\r
   UINTN                       Index;\r
   EFI_FIRMWARE_VOLUME_HEADER  *FvHeader;\r
   EFI_FFS_FILE_HEADER         *VtfFileImage;\r
@@ -1424,34 +1430,30 @@ Returns:
   FvBufferHeader = NULL;\r
   FvFile         = NULL;\r
   FvMapFile      = NULL;\r
-  //\r
-  // Check for invalid parameter\r
-  //\r
-  if (InfFileImage == NULL) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  //\r
-  // Initialize file structures\r
-  //\r
-  InfMemoryFile.FileImage           = InfFileImage;\r
-  InfMemoryFile.CurrentFilePointer  = InfFileImage;\r
-  InfMemoryFile.Eof                 = InfFileImage + InfFileSize;\r
 \r
-  //\r
-  // Parse the FV inf file for header information\r
-  //\r
-  Status = ParseFvInf (&InfMemoryFile, &FvInfo);\r
-  if (EFI_ERROR (Status)) {\r
-    Error (NULL, 0, 0003, "Error parsing file", "the input INF file.");\r
-    return Status;\r
+  if (InfFileImage != NULL) {\r
+    //\r
+    // Initialize file structures\r
+    //\r
+    InfMemoryFile.FileImage           = InfFileImage;\r
+    InfMemoryFile.CurrentFilePointer  = InfFileImage;\r
+    InfMemoryFile.Eof                 = InfFileImage + InfFileSize;\r
+  \r
+    //\r
+    // Parse the FV inf file for header information\r
+    //\r
+    Status = ParseFvInf (&InfMemoryFile, &gFvDataInfo);\r
+    if (EFI_ERROR (Status)) {\r
+      Error (NULL, 0, 0003, "Error parsing file", "the input INF file.");\r
+      return Status;\r
+    }\r
   }\r
 \r
   //\r
   // Update the file name return values\r
   //\r
-  if (FvFileName == NULL && FvInfo.FvName[0] != '\0') {\r
-    FvFileName = FvInfo.FvName;\r
+  if (FvFileName == NULL && gFvDataInfo.FvName[0] != '\0') {\r
+    FvFileName = gFvDataInfo.FvName;\r
   }\r
 \r
   if (FvFileName == NULL) {\r
@@ -1459,6 +1461,11 @@ Returns:
     return EFI_ABORTED;\r
   }\r
   \r
+  if (gFvDataInfo.FvBlocks[0].Length == 0) {\r
+    Error (NULL, 0, 1001, "Missing required argument", "Block Size");\r
+    return EFI_ABORTED;\r
+  }\r
+  \r
   //\r
   // FvMap file to log the function address of all modules in one Fvimage\r
   //\r
@@ -1469,40 +1476,34 @@ Returns:
     strcat (FvMapName, ".map");\r
   }\r
   VerboseMsg ("FV Map file name is %s", FvMapName);\r
-\r
-  FvMapFile = fopen (FvMapName, "w");\r
-  if (FvMapFile == NULL) {\r
-    Error (NULL, 0, 0001, "Error opening file", FvMapName);\r
-    return EFI_ABORTED;\r
-  }\r
   \r
   //\r
   // Update FvImage Base Address, XipBase not same to BtBase, RtBase address.\r
   //\r
   if (XipBaseAddress != 0) {\r
-    FvInfo.BaseAddress = XipBaseAddress;\r
+    gFvDataInfo.BaseAddress = XipBaseAddress;\r
   }\r
   if (*BtBaseAddress != 0) {\r
-    FvInfo.BootBaseAddress = *BtBaseAddress;\r
+    gFvDataInfo.BootBaseAddress = *BtBaseAddress;\r
   }\r
   if (*RtBaseAddress != 0) {\r
-    FvInfo.RuntimeBaseAddress = *RtBaseAddress;\r
+    gFvDataInfo.RuntimeBaseAddress = *RtBaseAddress;\r
   }\r
 \r
   //\r
   // Calculate the FV size and Update Fv Size based on the actual FFS files.\r
-  // And Update FvInfo data.\r
+  // And Update gFvDataInfo data.\r
   //\r
-  Status = CalculateFvSize (&FvInfo);\r
+  Status = CalculateFvSize (&gFvDataInfo);\r
   if (EFI_ERROR (Status)) {\r
     return Status;    \r
   }\r
-  VerboseMsg ("the generated FV image size is %d bytes", FvInfo.Size);\r
+  VerboseMsg ("the generated FV image size is %d bytes", gFvDataInfo.Size);\r
   \r
   //\r
   // support fv image and empty fv image\r
   //\r
-  FvImageSize = FvInfo.Size;\r
+  FvImageSize = gFvDataInfo.Size;\r
 \r
   //\r
   // Allocate the FV, assure FvImage Header 8 byte alignment\r
@@ -1516,7 +1517,13 @@ Returns:
   //\r
   // Initialize the FV to the erase polarity\r
   //\r
-  if (FvInfo.FvAttributes & EFI_FVB2_ERASE_POLARITY) {\r
+  if (gFvDataInfo.FvAttributes == 0) {\r
+    //\r
+    // Set Default Fv Attribute \r
+    //\r
+    gFvDataInfo.FvAttributes = FV_DEFAULT_ATTRIBUTE;\r
+  }\r
+  if (gFvDataInfo.FvAttributes & EFI_FVB2_ERASE_POLARITY) {\r
     memset (FvImage, -1, FvImageSize);\r
   } else {\r
     memset (FvImage, 0, FvImageSize);\r
@@ -1535,11 +1542,11 @@ Returns:
   //\r
   // Copy the FFS GUID\r
   //\r
-  memcpy (&FvHeader->FileSystemGuid, &FvInfo.FvGuid, sizeof (EFI_GUID));\r
+  memcpy (&FvHeader->FileSystemGuid, &gFvDataInfo.FvGuid, sizeof (EFI_GUID));\r
 \r
   FvHeader->FvLength        = FvImageSize;\r
   FvHeader->Signature       = EFI_FVH_SIGNATURE;\r
-  FvHeader->Attributes      = FvInfo.FvAttributes;\r
+  FvHeader->Attributes      = gFvDataInfo.FvAttributes;\r
   FvHeader->Revision        = EFI_FVH_REVISION;\r
   FvHeader->ExtHeaderOffset = 0;\r
   FvHeader->Reserved[0]     = 0;\r
@@ -1547,9 +1554,9 @@ Returns:
   //\r
   // Copy firmware block map\r
   //\r
-  for (Index = 0; FvInfo.FvBlocks[Index].Length != 0; Index++) {\r
-    FvHeader->BlockMap[Index].NumBlocks   = FvInfo.FvBlocks[Index].NumBlocks;\r
-    FvHeader->BlockMap[Index].Length      = FvInfo.FvBlocks[Index].Length;\r
+  for (Index = 0; gFvDataInfo.FvBlocks[Index].Length != 0; Index++) {\r
+    FvHeader->BlockMap[Index].NumBlocks   = gFvDataInfo.FvBlocks[Index].NumBlocks;\r
+    FvHeader->BlockMap[Index].Length      = gFvDataInfo.FvBlocks[Index].Length;\r
   }\r
 \r
   //\r
@@ -1568,7 +1575,7 @@ Returns:
   //\r
   // If there is no FFS file, generate one empty FV\r
   //\r
-  if (FvInfo.FvFiles[0][0] == 0) {\r
+  if (gFvDataInfo.FvFiles[0][0] == 0) {\r
     goto WriteFile;\r
   }\r
 \r
@@ -1589,14 +1596,23 @@ Returns:
   //\r
   VtfFileImage = (EFI_FFS_FILE_HEADER *) FvImageMemoryFile.Eof;\r
 \r
+  //\r
+  // Open FvMap file\r
+  //\r
+  FvMapFile = fopen (FvMapName, "w");\r
+  if (FvMapFile == NULL) {\r
+    Error (NULL, 0, 0001, "Error opening file", FvMapName);\r
+    return EFI_ABORTED;\r
+  }\r
+\r
   //\r
   // Add files to FV\r
   //\r
-  for (Index = 0; FvInfo.FvFiles[Index][0] != 0; Index++) {\r
+  for (Index = 0; gFvDataInfo.FvFiles[Index][0] != 0; Index++) {\r
     //\r
     // Add the file\r
     //\r
-    Status = AddFile (&FvImageMemoryFile, &FvInfo, Index, &VtfFileImage, FvMapFile);\r
+    Status = AddFile (&FvImageMemoryFile, &gFvDataInfo, Index, &VtfFileImage, FvMapFile);\r
 \r
     //\r
     // Exit if error detected while adding the file\r
@@ -1626,8 +1642,8 @@ Returns:
     // reset vector. If the PEI Core is found, the VTF file will probably get  \r
     // corrupted by updating the entry point.                                  \r
     //\r
-    if ((FvInfo.BaseAddress + FvInfo.Size) == FV_IMAGES_TOP_ADDRESS) {       \r
-      Status = UpdateResetVector (&FvImageMemoryFile, &FvInfo, VtfFileImage);\r
+    if ((gFvDataInfo.BaseAddress + gFvDataInfo.Size) == FV_IMAGES_TOP_ADDRESS) {       \r
+      Status = UpdateResetVector (&FvImageMemoryFile, &gFvDataInfo, VtfFileImage);\r
       if (EFI_ERROR(Status)) {                                               \r
         Error (NULL, 0, 3000, "Invalid", "Could not update the reset vector.");\r
         goto Finish;                                              \r
@@ -1681,8 +1697,8 @@ Finish:
   //\r
   // Update BootAddress and RuntimeAddress\r
   //\r
-  *BtBaseAddress = FvInfo.BootBaseAddress;\r
-  *RtBaseAddress = FvInfo.RuntimeBaseAddress;\r
+  *BtBaseAddress = gFvDataInfo.BootBaseAddress;\r
+  *RtBaseAddress = gFvDataInfo.RuntimeBaseAddress;\r
 \r
   return Status;\r
 }\r
@@ -1786,11 +1802,23 @@ Returns:
   VtfFileFlag = FALSE;\r
   fpin  = NULL;\r
   Index = 0;\r
+\r
+  //\r
+  // Compute size for easy access later\r
+  //\r
+  FvInfoPtr->Size = 0;\r
+  for (Index = 0; FvInfoPtr->FvBlocks[Index].NumBlocks > 0 && FvInfoPtr->FvBlocks[Index].Length > 0; Index++) {\r
+    FvInfoPtr->Size += FvInfoPtr->FvBlocks[Index].NumBlocks * FvInfoPtr->FvBlocks[Index].Length;\r
+  }\r
+  \r
+  //\r
+  // Caculate the required sizes for all FFS files.\r
+  //\r
   CurrentOffset = sizeof (EFI_FIRMWARE_VOLUME_HEADER);\r
   \r
   for (Index = 1;; Index ++) {\r
     CurrentOffset += sizeof (EFI_FV_BLOCK_MAP_ENTRY);\r
-    if (FvInfoPtr->FvBlocks[Index].NumBlocks == 0 && FvInfoPtr->FvBlocks[Index].Length == 0) {\r
+    if (FvInfoPtr->FvBlocks[Index].NumBlocks == 0 || FvInfoPtr->FvBlocks[Index].Length == 0) {\r
       break;\r
     }\r
   }\r
@@ -1861,7 +1889,7 @@ Returns:
   \r
   DebugMsg (NULL, 0, 9, "FvImage size", "The caculated fv image size is 0x%x and the current set fv image size is 0x%x", CurrentOffset, FvInfoPtr->Size);\r
   \r
-  if (FvInfoPtr->Size < CurrentOffset) { \r
+  if (FvInfoPtr->Size == 0) { \r
     //\r
     // Update FvInfo data\r
     //\r
@@ -1869,7 +1897,19 @@ Returns:
     FvInfoPtr->Size = FvInfoPtr->FvBlocks[0].NumBlocks * FvInfoPtr->FvBlocks[0].Length;\r
     FvInfoPtr->FvBlocks[1].NumBlocks = 0;\r
     FvInfoPtr->FvBlocks[1].Length = 0;\r
+  } else if (FvInfoPtr->Size < CurrentOffset) {\r
+    //\r
+    // Not invalid\r
+    //\r
+    Error (NULL, 0, 3000, "Invalid", "the required fv image size 0x%x exceeds the set fv image size 0x%x", CurrentOffset, FvInfoPtr->Size);\r
+    return EFI_INVALID_PARAMETER;\r
   }\r
+  \r
+  //\r
+  // Set Fv Size Information\r
+  //\r
+  mFvTotalSize = FvInfoPtr->Size;\r
+  mFvTakenSize = CurrentOffset;\r
 \r
   return EFI_SUCCESS;\r
 }\r
@@ -1970,6 +2010,7 @@ Returns:
   FILE                                  *PeFile;\r
   UINT8                                 *PeFileBuffer;\r
   UINT32                                PeFileSize;\r
+  CHAR8                                 *PdbPointer;\r
 \r
   Index              = 0;  \r
   MemoryImagePointer = NULL;\r
@@ -1982,6 +2023,7 @@ Returns:
   Cptr               = NULL;\r
   PeFile             = NULL;\r
   PeFileBuffer       = NULL;\r
+\r
   //\r
   // Check XipAddress, BootAddress and RuntimeAddress\r
   //\r
@@ -2018,12 +2060,19 @@ Returns:
     default:\r
       return EFI_SUCCESS;\r
   }\r
-\r
   //\r
   // Rebase each PE32 section\r
   //\r
   Status      = EFI_SUCCESS;\r
   for (Index = 1;; Index++) {\r
+    //\r
+    // Init Value\r
+    //\r
+    NewPe32BaseAddress = 0;\r
+    \r
+    //\r
+    // Find Pe Image\r
+    //\r
     Status = GetSectionByType (FfsFile, EFI_SECTION_PE32, Index, &CurrentPe32Section);\r
     if (EFI_ERROR (Status)) {\r
       break;\r
@@ -2040,6 +2089,11 @@ Returns:
       Error (NULL, 0, 3000, "Invalid", "GetImageInfo() call failed on rebase %s.", FileName);\r
       return Status;\r
     }\r
+    \r
+    //\r
+    // Get File PdbPointer\r
+    //\r
+    PdbPointer = PeCoffLoaderGetPdbPointer (ImageContext.Handle);\r
 \r
     //\r
     // Get PeHeader pointer\r
@@ -2094,8 +2148,10 @@ Returns:
           }\r
           PeFile = fopen (PeFileName, "rb");\r
           if (PeFile == NULL) {\r
-            Error (NULL, 0, 3000, "Invalid", "The file %s has no .reloc section.", FileName);\r
-            return EFI_ABORTED;\r
+            Warning (NULL, 0, 0, "Invalid", "The file %s has no .reloc section.", FileName);\r
+            //Error (NULL, 0, 3000, "Invalid", "The file %s has no .reloc section.", FileName);\r
+            //return EFI_ABORTED;\r
+            break;\r
           }\r
           //\r
           // Get the file size\r
@@ -2172,7 +2228,7 @@ Returns:
       case EFI_FV_FILETYPE_DXE_CORE:\r
         if ((Flags & REBASE_BOOTTIME_FILE) == 0) {\r
           //\r
-          // Skip DXE core, DxeCore only contain one PE image.\r
+          // Skip DxeCore Driver\r
           //\r
           goto WritePeMap;\r
         }\r
@@ -2191,35 +2247,65 @@ Returns:
         //\r
         return EFI_SUCCESS;\r
     }\r
-\r
+    \r
     //\r
-    // Load and Relocate Image Data\r
+    // Relocation exist and rebase\r
     //\r
-    MemoryImagePointer = (UINT8 *) malloc ((UINTN) ImageContext.ImageSize + ImageContext.SectionAlignment);\r
-    if (MemoryImagePointer == NULL) {\r
-      Error (NULL, 0, 4001, "Resource", "memory cannot be allocated on rebase of %s", FileName);\r
-      return EFI_OUT_OF_RESOURCES;\r
-    }\r
-    memset ((VOID *) MemoryImagePointer, 0, (UINTN) ImageContext.ImageSize + ImageContext.SectionAlignment);\r
-    ImageContext.ImageAddress = ((UINTN) MemoryImagePointer + ImageContext.SectionAlignment - 1) & (~(ImageContext.SectionAlignment - 1));\r
-    \r
-    Status =  PeCoffLoaderLoadImage (&ImageContext);\r
-    if (EFI_ERROR (Status)) {\r
-      Error (NULL, 0, 3000, "Invalid", "LocateImage() call failed on rebase of %s", FileName);\r
-      free ((VOID *) MemoryImagePointer);\r
-      return Status;\r
-    }\r
-         \r
-    ImageContext.DestinationAddress = NewPe32BaseAddress;\r
-    Status                          = PeCoffLoaderRelocateImage (&ImageContext);\r
-    if (EFI_ERROR (Status)) {\r
-      Error (NULL, 0, 3000, "Invalid", "RelocateImage() call failed on rebase of %s", FileName);\r
+    if (!ImageContext.RelocationsStripped) {  \r
+      //\r
+      // Load and Relocate Image Data\r
+      //\r
+      MemoryImagePointer = (UINT8 *) malloc ((UINTN) ImageContext.ImageSize + ImageContext.SectionAlignment);\r
+      if (MemoryImagePointer == NULL) {\r
+        Error (NULL, 0, 4001, "Resource", "memory cannot be allocated on rebase of %s", FileName);\r
+        return EFI_OUT_OF_RESOURCES;\r
+      }\r
+      memset ((VOID *) MemoryImagePointer, 0, (UINTN) ImageContext.ImageSize + ImageContext.SectionAlignment);\r
+      ImageContext.ImageAddress = ((UINTN) MemoryImagePointer + ImageContext.SectionAlignment - 1) & (~(ImageContext.SectionAlignment - 1));\r
+      \r
+      Status =  PeCoffLoaderLoadImage (&ImageContext);\r
+      if (EFI_ERROR (Status)) {\r
+        Error (NULL, 0, 3000, "Invalid", "LocateImage() call failed on rebase of %s", FileName);\r
+        free ((VOID *) MemoryImagePointer);\r
+        return Status;\r
+      }\r
+           \r
+      ImageContext.DestinationAddress = NewPe32BaseAddress;\r
+      Status                          = PeCoffLoaderRelocateImage (&ImageContext);\r
+      if (EFI_ERROR (Status)) {\r
+        Error (NULL, 0, 3000, "Invalid", "RelocateImage() call failed on rebase of %s", FileName);\r
+        free ((VOID *) MemoryImagePointer);\r
+        return Status;\r
+      }\r
+\r
+      //\r
+      // Copy Relocated data to raw image file.\r
+      //\r
+      SectionHeader = (EFI_IMAGE_SECTION_HEADER *) (\r
+                         (UINTN) PeHdr +\r
+                         sizeof (UINT32) + \r
+                         sizeof (EFI_IMAGE_FILE_HEADER) +  \r
+                         PeHdr->FileHeader.SizeOfOptionalHeader\r
+                         );\r
+      \r
+      for (Index = 0; Index < PeHdr->FileHeader.NumberOfSections; Index ++, SectionHeader ++) {\r
+        CopyMem (\r
+          (UINT8 *) CurrentPe32Section.Pe32Section + sizeof (EFI_COMMON_SECTION_HEADER) + SectionHeader->PointerToRawData, \r
+          (VOID*) (UINTN) (ImageContext.ImageAddress + SectionHeader->VirtualAddress), \r
+          SectionHeader->SizeOfRawData\r
+          );\r
+      }\r
+  \r
       free ((VOID *) MemoryImagePointer);\r
-      return Status;\r
+      MemoryImagePointer = NULL;\r
+      if (PeFileBuffer != NULL) {\r
+        free (PeFileBuffer);\r
+        PeFileBuffer = NULL;\r
+      }\r
     }\r
-\r
+    \r
     //\r
-    // Copy Relocated data to raw image file.\r
+    // Update Image Base Address\r
     //\r
     if (PeHdr->FileHeader.Machine == EFI_IMAGE_MACHINE_IA32) {\r
       Optional32 = (EFI_IMAGE_OPTIONAL_HEADER32 *) &(PeHdr->OptionalHeader);\r
@@ -2233,32 +2319,9 @@ Returns:
         (UINT32) PeHdr->FileHeader.Machine,\r
         FileName\r
         );\r
-      free ((VOID *) MemoryImagePointer);\r
       return EFI_ABORTED;\r
     }\r
 \r
-    SectionHeader = (EFI_IMAGE_SECTION_HEADER *) (\r
-                       (UINTN) PeHdr +\r
-                       sizeof (UINT32) + \r
-                       sizeof (EFI_IMAGE_FILE_HEADER) +  \r
-                       PeHdr->FileHeader.SizeOfOptionalHeader\r
-                       );\r
-    \r
-    for (Index = 0; Index < PeHdr->FileHeader.NumberOfSections; Index ++, SectionHeader ++) {\r
-      CopyMem (\r
-        (UINT8 *) CurrentPe32Section.Pe32Section + sizeof (EFI_COMMON_SECTION_HEADER) + SectionHeader->PointerToRawData, \r
-        (VOID*) (UINTN) (ImageContext.ImageAddress + SectionHeader->VirtualAddress), \r
-        SectionHeader->SizeOfRawData\r
-        );\r
-    }\r
-\r
-    free ((VOID *) MemoryImagePointer);\r
-    MemoryImagePointer = NULL;\r
-    if (PeFileBuffer != NULL) {\r
-      free (PeFileBuffer);\r
-      PeFileBuffer = NULL;\r
-    }\r
-\r
     //\r
     // Update BASE address by add one page size.\r
     //\r
@@ -2287,7 +2350,13 @@ Returns:
     // Get this module function address from ModulePeMapFile and add them into FvMap file\r
     //\r
 WritePeMap:\r
-    WriteMapFile (FvMapFile, FileName, ImageContext.DestinationAddress, PeHdr->OptionalHeader.AddressOfEntryPoint, 0);\r
+    //\r
+    // Default use FileName as map file path\r
+    //\r
+    if (PdbPointer == NULL) {\r
+      PdbPointer = FileName;\r
+    }\r
+    WriteMapFile (FvMapFile, PdbPointer, (EFI_GUID *) FfsFile, NewPe32BaseAddress, PeHdr->OptionalHeader.AddressOfEntryPoint, 0);\r
   }\r
 \r
   if (FfsFile->Type != EFI_FV_FILETYPE_SECURITY_CORE &&\r
@@ -2305,11 +2374,16 @@ WritePeMap:
   // Now process TE sections\r
   //\r
   for (Index = 1;; Index++) {\r
+    NewPe32BaseAddress = 0;\r
+    \r
+    //\r
+    // Find Te Image\r
+    //\r
     Status = GetSectionByType (FfsFile, EFI_SECTION_TE, Index, &CurrentPe32Section);\r
     if (EFI_ERROR (Status)) {\r
       break;\r
     }\r
-\r
+    \r
     //\r
     // Calculate the TE base address, the FFS file base plus the offset of the TE section less the size stripped off\r
     // by GenTEImage\r
@@ -2322,13 +2396,16 @@ WritePeMap:
     memset (&ImageContext, 0, sizeof (ImageContext));\r
     ImageContext.Handle     = (VOID *) TEImageHeader;\r
     ImageContext.ImageRead  = (PE_COFF_LOADER_READ_FILE) FfsRebaseImageRead;\r
-\r
     Status                  = PeCoffLoaderGetImageInfo (&ImageContext);\r
-\r
     if (EFI_ERROR (Status)) {\r
       Error (NULL, 0, 3000, "Invalid", "GetImageInfo() call failed on rebase of TE image %s", FileName);\r
       return Status;\r
     }\r
+\r
+    //\r
+    // Get File PdbPointer\r
+    //\r
+    PdbPointer = PeCoffLoaderGetPdbPointer (ImageContext.Handle);\r
     \r
     if ((Flags & REBASE_XIP_FILE) == 0) {\r
       //\r
@@ -2336,6 +2413,13 @@ WritePeMap:
       //\r
       goto WriteTeMap;\r
     }\r
+\r
+    //\r
+    // Set new rebased address.\r
+    //\r
+    NewPe32BaseAddress = XipBase + (UINTN) TEImageHeader + sizeof (EFI_TE_IMAGE_HEADER) \\r
+                         - TEImageHeader->StrippedSize - (UINTN) FfsFile;\r
+\r
     //\r
     // if reloc is stripped, try to get the original efi image to get reloc info.\r
     //\r
@@ -2348,6 +2432,7 @@ WritePeMap:
       while (*Cptr != '.') {\r
         Cptr --;\r
       }\r
+\r
       if (*Cptr != '.') {\r
         Error (NULL, 0, 3000, "Invalid", "The file %s has no .reloc section.", FileName);\r
         return EFI_ABORTED;\r
@@ -2357,99 +2442,110 @@ WritePeMap:
         *(Cptr + 3) = 'i';\r
         *(Cptr + 4) = '\0';\r
       }\r
+\r
       PeFile = fopen (PeFileName, "rb");\r
       if (PeFile == NULL) {\r
-        Error (NULL, 0, 3000, "Invalid", "The file %s has no .reloc section.", FileName);\r
-        return EFI_ABORTED;\r
+        Warning (NULL, 0, 0, "Invalid", "The file %s has no .reloc section.", FileName);\r
+        //Error (NULL, 0, 3000, "Invalid", "The file %s has no .reloc section.", FileName);\r
+        //return EFI_ABORTED;\r
+      } else {\r
+        //\r
+        // Get the file size\r
+        //\r
+        PeFileSize = _filelength (fileno (PeFile));\r
+        PeFileBuffer = (UINT8 *) malloc (PeFileSize);\r
+        if (PeFileBuffer == NULL) {\r
+          Error (NULL, 0, 4001, "Resource", "memory cannot be allocated on rebase of %s", FileName);\r
+          return EFI_OUT_OF_RESOURCES;\r
+        }\r
+        //\r
+        // Read Pe File\r
+        //\r
+        fread (PeFileBuffer, sizeof (UINT8), PeFileSize, PeFile);\r
+        //\r
+        // close file\r
+        //\r
+        fclose (PeFile);\r
+        //\r
+        // Append reloc section into TeImage\r
+        //\r
+        ImageContext.Handle = PeFileBuffer;\r
+        Status              = PeCoffLoaderGetImageInfo (&ImageContext);\r
+        if (EFI_ERROR (Status)) {\r
+          Error (NULL, 0, 3000, "Invalid", "GetImageInfo() call failed on rebase of TE image %s", FileName);\r
+          return Status;\r
+        }\r
+        ImageContext.RelocationsStripped = FALSE;\r
       }\r
+    }\r
+\r
+    //\r
+    // Relocation exist and rebase\r
+    //\r
+    if (!ImageContext.RelocationsStripped) {\r
       //\r
-      // Get the file size\r
+      // Load and Relocate Image Data\r
       //\r
-      PeFileSize = _filelength (fileno (PeFile));\r
-      PeFileBuffer = (UINT8 *) malloc (PeFileSize);\r
-      if (PeFileBuffer == NULL) {\r
+      MemoryImagePointer = (UINT8 *) malloc ((UINTN) ImageContext.ImageSize + ImageContext.SectionAlignment);\r
+      if (MemoryImagePointer == NULL) {\r
         Error (NULL, 0, 4001, "Resource", "memory cannot be allocated on rebase of %s", FileName);\r
         return EFI_OUT_OF_RESOURCES;\r
       }\r
+      memset ((VOID *) MemoryImagePointer, 0, (UINTN) ImageContext.ImageSize + ImageContext.SectionAlignment);\r
+      ImageContext.ImageAddress = ((UINTN) MemoryImagePointer + ImageContext.SectionAlignment - 1) & (~(ImageContext.SectionAlignment - 1));\r
+  \r
+      Status =  PeCoffLoaderLoadImage (&ImageContext);\r
+      if (EFI_ERROR (Status)) {\r
+        Error (NULL, 0, 3000, "Invalid", "LocateImage() call failed on rebase of %s", FileName);\r
+        free ((VOID *) MemoryImagePointer);\r
+        return Status;\r
+      }\r
       //\r
-      // Read Pe File\r
-      //\r
-      fread (PeFileBuffer, sizeof (UINT8), PeFileSize, PeFile);\r
+      // Reloacate TeImage\r
+      // \r
+      ImageContext.DestinationAddress = NewPe32BaseAddress;\r
+      Status                          = PeCoffLoaderRelocateImage (&ImageContext);\r
+      if (EFI_ERROR (Status)) {\r
+        Error (NULL, 0, 3000, "Invalid", "RelocateImage() call failed on rebase of TE image %s", FileName);\r
+        free ((VOID *) MemoryImagePointer);\r
+        return Status;\r
+      }\r
+      \r
       //\r
-      // close file\r
+      // Copy the relocated image into raw image file.\r
       //\r
-      fclose (PeFile);\r
+      SectionHeader = (EFI_IMAGE_SECTION_HEADER *) (TEImageHeader + 1);\r
+      for (Index = 0; Index < TEImageHeader->NumberOfSections; Index ++, SectionHeader ++) {\r
+        if (!ImageContext.IsTeImage) {\r
+          CopyMem (\r
+            (UINT8 *) TEImageHeader + sizeof (EFI_TE_IMAGE_HEADER) - TEImageHeader->StrippedSize + SectionHeader->PointerToRawData, \r
+            (VOID*) (UINTN) (ImageContext.ImageAddress + SectionHeader->VirtualAddress), \r
+            SectionHeader->SizeOfRawData\r
+            );\r
+        } else {\r
+          CopyMem (\r
+            (UINT8 *) TEImageHeader + sizeof (EFI_TE_IMAGE_HEADER) - TEImageHeader->StrippedSize + SectionHeader->PointerToRawData, \r
+            (VOID*) (UINTN) (ImageContext.ImageAddress + sizeof (EFI_TE_IMAGE_HEADER) - TEImageHeader->StrippedSize + SectionHeader->VirtualAddress), \r
+            SectionHeader->SizeOfRawData\r
+            );\r
+        }\r
+      }\r
+      \r
       //\r
-      // Append reloc section into TeImage\r
+      // Free the allocated memory resource\r
       //\r
-      ImageContext.Handle = PeFileBuffer;\r
-      Status              = PeCoffLoaderGetImageInfo (&ImageContext);\r
-      if (EFI_ERROR (Status)) {\r
-        Error (NULL, 0, 3000, "Invalid", "GetImageInfo() call failed on rebase of TE image %s", FileName);\r
-        return Status;\r
-      }\r
-      ImageContext.RelocationsStripped = FALSE;\r
-    }\r
-\r
-    //\r
-    // Load and Relocate Image Data\r
-    //\r
-    MemoryImagePointer = (UINT8 *) malloc ((UINTN) ImageContext.ImageSize + ImageContext.SectionAlignment);\r
-    if (MemoryImagePointer == NULL) {\r
-      Error (NULL, 0, 4001, "Resource", "memory cannot be allocated on rebase of %s", FileName);\r
-      return EFI_OUT_OF_RESOURCES;\r
-    }\r
-    memset ((VOID *) MemoryImagePointer, 0, (UINTN) ImageContext.ImageSize + ImageContext.SectionAlignment);\r
-    ImageContext.ImageAddress = ((UINTN) MemoryImagePointer + ImageContext.SectionAlignment - 1) & (~(ImageContext.SectionAlignment - 1));\r
-\r
-    Status =  PeCoffLoaderLoadImage (&ImageContext);\r
-    if (EFI_ERROR (Status)) {\r
-      Error (NULL, 0, 3000, "Invalid", "LocateImage() call failed on rebase of %s", FileName);\r
       free ((VOID *) MemoryImagePointer);\r
-      return Status;\r
-    }\r
-    //\r
-    // Reloacate TeImage\r
-    // \r
-    ImageContext.DestinationAddress = XipBase + (UINTN) TEImageHeader + sizeof (EFI_TE_IMAGE_HEADER) \\r
-                                      - TEImageHeader->StrippedSize - (UINTN) FfsFile;\r
-    Status                          = PeCoffLoaderRelocateImage (&ImageContext);\r
-    if (EFI_ERROR (Status)) {\r
-      Error (NULL, 0, 3000, "Invalid", "RelocateImage() call failed on rebase of TE image %s", FileName);\r
-      free ((VOID *) MemoryImagePointer);\r
-      return Status;\r
-    }\r
-    \r
-    //\r
-    // Copy the relocated image into raw image file.\r
-    //\r
-    TEImageHeader->ImageBase = ImageContext.DestinationAddress;\r
-    SectionHeader = (EFI_IMAGE_SECTION_HEADER *) (TEImageHeader + 1);\r
-    for (Index = 0; Index < TEImageHeader->NumberOfSections; Index ++, SectionHeader ++) {\r
-      if (!ImageContext.IsTeImage) {\r
-        CopyMem (\r
-          (UINT8 *) TEImageHeader + sizeof (EFI_TE_IMAGE_HEADER) - TEImageHeader->StrippedSize + SectionHeader->PointerToRawData, \r
-          (VOID*) (UINTN) (ImageContext.ImageAddress + SectionHeader->VirtualAddress), \r
-          SectionHeader->SizeOfRawData\r
-          );\r
-      } else {\r
-        CopyMem (\r
-          (UINT8 *) TEImageHeader + sizeof (EFI_TE_IMAGE_HEADER) - TEImageHeader->StrippedSize + SectionHeader->PointerToRawData, \r
-          (VOID*) (UINTN) (ImageContext.ImageAddress + sizeof (EFI_TE_IMAGE_HEADER) - TEImageHeader->StrippedSize + SectionHeader->VirtualAddress), \r
-          SectionHeader->SizeOfRawData\r
-          );\r
+      MemoryImagePointer = NULL;\r
+      if (PeFileBuffer != NULL) {\r
+        free (PeFileBuffer);\r
+        PeFileBuffer = NULL;\r
       }\r
     }\r
     \r
     //\r
-    // Free the allocated memory resource\r
+    // Update Image Base Address\r
     //\r
-    free ((VOID *) MemoryImagePointer);\r
-    MemoryImagePointer = NULL;\r
-    if (PeFileBuffer != NULL) {\r
-      free (PeFileBuffer);\r
-      PeFileBuffer = NULL;\r
-    }\r
+    TEImageHeader->ImageBase = NewPe32BaseAddress;\r
 \r
     //\r
     // Now update file checksum\r
@@ -2473,13 +2569,20 @@ WritePeMap:
     // Get this module function address from ModulePeMapFile and add them into FvMap file\r
     //\r
 WriteTeMap:\r
+    //\r
+    // Default use FileName as map file path\r
+    //\r
+    if (PdbPointer == NULL) {\r
+      PdbPointer = FileName;\r
+    }\r
     WriteMapFile (\r
       FvMapFile, \r
-      FileName, \r
-      ImageContext.DestinationAddress, \r
+      PdbPointer, \r
+      (EFI_GUID *) FfsFile,\r
+      NewPe32BaseAddress, \r
       TEImageHeader->AddressOfEntryPoint, \r
       TEImageHeader->StrippedSize - sizeof (EFI_TE_IMAGE_HEADER)\r
-      );  \r
+      );\r
   }\r
  \r
   return EFI_SUCCESS;\r
@@ -2565,7 +2668,8 @@ Returns:
 EFI_STATUS\r
 WriteMapFile (\r
   IN OUT FILE                  *FvMapFile,\r
-  IN     CHAR8                 *FileName, \r
+  IN     CHAR8                 *FileName,\r
+  IN     EFI_GUID              *FileGuidPtr, \r
   IN     EFI_PHYSICAL_ADDRESS  ImageBaseAddress,\r
   IN     UINT32                AddressOfEntryPoint,\r
   IN     UINT32                Offset\r
@@ -2592,8 +2696,7 @@ Returns:
 {\r
   CHAR8           PeMapFileName [_MAX_PATH];\r
   CHAR8           *Cptr;\r
-  CHAR8           *FileGuidName;\r
-  EFI_GUID        FileGuidValue;\r
+  CHAR8           FileGuidName [MAX_LINE_LEN];\r
   FILE            *PeMapFile;\r
   CHAR8           Line [MAX_LINE_LEN];\r
   CHAR8           KeyWord [MAX_LINE_LEN];\r
@@ -2606,11 +2709,30 @@ Returns:
   // Init local variable\r
   //\r
   FunctionType = 0;\r
+  //\r
+  // Print FileGuid to string buffer. \r
+  //\r
+  PrintGuidToBuffer (FileGuidPtr, FileGuidName, MAX_LINE_LEN, TRUE);\r
   \r
   //\r
   // Construct Map file Name \r
   //\r
   strcpy (PeMapFileName, FileName);\r
+  \r
+  //\r
+  // Change '\\' to '/', unified path format.\r
+  //\r
+  Cptr = PeMapFileName;\r
+  while (*Cptr != '\0') {\r
+    if (*Cptr == '\\') {\r
+      *Cptr = FILE_SEP_CHAR;\r
+    }\r
+    Cptr ++;\r
+  }\r
+  \r
+  //\r
+  // Get Map file\r
+  // \r
   Cptr = PeMapFileName + strlen (PeMapFileName);\r
   while (*Cptr != '.') {\r
     Cptr --;\r
@@ -2631,19 +2753,8 @@ Returns:
     // fprintf (stdout, "can't open %s file to reading\n", PeMapFileName);\r
     return EFI_ABORTED;\r
   }\r
-  //\r
-  // Get Module Guid from FileName\r
-  //\r
-  *Cptr = '\0';\r
-  while ((*Cptr != FILE_SEP_CHAR) && (Cptr >= PeMapFileName)) {\r
-    Cptr --;\r
-  }\r
-  if (*Cptr == FILE_SEP_CHAR) {\r
-    FileGuidName = Cptr + 1;\r
-    if (StringToGuid (FileGuidName, &FileGuidValue) != EFI_SUCCESS) {\r
-      FileGuidName = NULL;\r
-    }\r
-  }\r
+  VerboseMsg ("The map file is %s", PeMapFileName);\r
+  \r
   //\r
   // Output Functions information into Fv Map file\r
   //\r
@@ -2660,9 +2771,7 @@ Returns:
     fprintf (FvMapFile, "BaseAddress=%08lx, ", ImageBaseAddress + Offset);\r
   }\r
   fprintf (FvMapFile, "EntryPoint=%08lx, ", ImageBaseAddress + AddressOfEntryPoint);\r
-  if (FileGuidName != NULL) {\r
-    fprintf (FvMapFile, "GUID=%s", FileGuidName);\r
-  }\r
+  fprintf (FvMapFile, "GUID=%s", FileGuidName);\r
   fprintf (FvMapFile, ")\n\n");\r
 \r
   while (fgets (Line, MAX_LINE_LEN, PeMapFile) != NULL) {\r
@@ -2754,13 +2863,14 @@ Returns:
 {\r
   CHAR8       Value[_MAX_PATH];\r
   UINT64      Value64;\r
-  UINTN       Index;\r
+  UINTN       Index, Number;\r
   EFI_STATUS  Status;\r
 \r
   //\r
   // Initialize Cap info\r
   //\r
-  memset (CapInfo, 0, sizeof (CAP_INFO));\r
+  // memset (CapInfo, 0, sizeof (CAP_INFO));\r
+  //\r
 \r
   //\r
   // Read the Capsule Guid\r
@@ -2776,9 +2886,6 @@ Returns:
       return EFI_ABORTED;\r
     }\r
     DebugMsg (NULL, 0, 9, "Capsule Guid", "%s = %s", EFI_CAPSULE_GUID_STRING, Value);\r
-  } else {\r
-    Error (NULL, 0, 2001, "Missing required argument", EFI_CAPSULE_GUID_STRING);\r
-    return EFI_ABORTED;\r
   }\r
 \r
   //\r
@@ -2825,11 +2932,15 @@ Returns:
   //\r
   // Read the Capsule FileImage\r
   //\r
+  Number = 0;\r
   for (Index = 0; Index < MAX_NUMBER_OF_FILES_IN_CAP; Index++) {\r
+    if (CapInfo->CapFiles[Index][0] != '\0') {\r
+      continue;\r
+    }\r
     //\r
     // Read the capsule file name\r
     //\r
-    Status = FindToken (InfFile, FILES_SECTION_STRING, EFI_FILE_NAME_STRING, Index, Value);\r
+    Status = FindToken (InfFile, FILES_SECTION_STRING, EFI_FILE_NAME_STRING, Number++, Value);\r
 \r
     if (Status == EFI_SUCCESS) {\r
       //\r
@@ -2884,51 +2995,62 @@ Returns:
   UINT32                Index;\r
   FILE                  *fpin, *fpout;\r
   EFI_STATUS            Status;\r
-  CAP_INFO              CapInfo;\r
-\r
-  //\r
-  // Initialize file structures\r
-  //\r
-  InfMemoryFile.FileImage           = InfFileImage;\r
-  InfMemoryFile.CurrentFilePointer  = InfFileImage;\r
-  InfMemoryFile.Eof                 = InfFileImage + InfFileSize;\r
-\r
-  //\r
-  // Parse the Cap inf file for header information\r
-  //\r
-  Status = ParseCapInf (&InfMemoryFile, &CapInfo);\r
-  if (Status != EFI_SUCCESS) {\r
-    return Status;\r
+  \r
+  if (InfFileImage != NULL) {\r
+    //\r
+    // Initialize file structures\r
+    //\r
+    InfMemoryFile.FileImage           = InfFileImage;\r
+    InfMemoryFile.CurrentFilePointer  = InfFileImage;\r
+    InfMemoryFile.Eof                 = InfFileImage + InfFileSize;\r
+  \r
+    //\r
+    // Parse the Cap inf file for header information\r
+    //\r
+    Status = ParseCapInf (&InfMemoryFile, &gCapDataInfo);\r
+    if (Status != EFI_SUCCESS) {\r
+      return Status;\r
+    }\r
   }\r
   \r
-  if (CapInfo.HeaderSize == 0) {\r
-    CapInfo.HeaderSize = sizeof (EFI_CAPSULE_HEADER);\r
+  if (gCapDataInfo.HeaderSize == 0) {\r
+    //\r
+    // make header size align 16 bytes.\r
+    //\r
+    gCapDataInfo.HeaderSize = sizeof (EFI_CAPSULE_HEADER);\r
+    gCapDataInfo.HeaderSize = (gCapDataInfo.HeaderSize + 0xF) & ~0xF;\r
   }\r
 \r
-  if (CapInfo.HeaderSize < sizeof (EFI_CAPSULE_HEADER)) {\r
+  if (gCapDataInfo.HeaderSize < sizeof (EFI_CAPSULE_HEADER)) {\r
     Error (NULL, 0, 2000, "Invalid parameter", "The specified HeaderSize cannot be less than the size of EFI_CAPSULE_HEADER.");\r
     return EFI_INVALID_PARAMETER;\r
   }\r
   \r
-  if (CapFileName == NULL && CapInfo.CapName[0] != '\0') {\r
-    CapFileName = CapInfo.CapName;\r
+  if (CapFileName == NULL && gCapDataInfo.CapName[0] != '\0') {\r
+    CapFileName = gCapDataInfo.CapName;\r
   }\r
   \r
   if (CapFileName == NULL) {\r
     Error (NULL, 0, 2001, "Missing required argument", "Output Capsule file name");\r
     return EFI_INVALID_PARAMETER;\r
   }\r
-\r
+  \r
+  //\r
+  // Set Default Capsule Guid value\r
+  //\r
+  if (CompareGuid (&gCapDataInfo.CapGuid, &mZeroGuid) == 0) {\r
+    memcpy (&gCapDataInfo.CapGuid, &mDefaultCapsuleGuid, sizeof (EFI_GUID));\r
+  }\r
   //\r
   // Calculate the size of capsule image.\r
   //\r
   Index    = 0;\r
   FileSize = 0;\r
-  CapSize  = CapInfo.HeaderSize;\r
-  while (CapInfo.CapFiles [Index][0] != '\0') {\r
-    fpin = fopen (CapInfo.CapFiles[Index], "rb");\r
+  CapSize  = gCapDataInfo.HeaderSize;\r
+  while (gCapDataInfo.CapFiles [Index][0] != '\0') {\r
+    fpin = fopen (gCapDataInfo.CapFiles[Index], "rb");\r
     if (fpin == NULL) {\r
-      Error (NULL, 0, 0001, "Error opening file", CapInfo.CapFiles[Index]);\r
+      Error (NULL, 0, 0001, "Error opening file", gCapDataInfo.CapFiles[Index]);\r
       return EFI_ABORTED;\r
     }\r
     FileSize  = _filelength (fileno (fpin));\r
@@ -2949,24 +3071,24 @@ Returns:
   //\r
   // Initialize the capsule header to zero\r
   //\r
-  memset (CapBuffer, 0, CapInfo.HeaderSize);\r
+  memset (CapBuffer, 0, gCapDataInfo.HeaderSize);\r
   \r
   //\r
   // create capsule header and get capsule body\r
   //\r
   CapsuleHeader = (EFI_CAPSULE_HEADER *) CapBuffer;\r
-  memcpy (&CapsuleHeader->CapsuleGuid, &CapInfo.CapGuid, sizeof (EFI_GUID));\r
-  CapsuleHeader->HeaderSize       = CapInfo.HeaderSize;\r
-  CapsuleHeader->Flags            = CapInfo.Flags;\r
+  memcpy (&CapsuleHeader->CapsuleGuid, &gCapDataInfo.CapGuid, sizeof (EFI_GUID));\r
+  CapsuleHeader->HeaderSize       = gCapDataInfo.HeaderSize;\r
+  CapsuleHeader->Flags            = gCapDataInfo.Flags;\r
   CapsuleHeader->CapsuleImageSize = CapSize;\r
 \r
   Index    = 0;\r
   FileSize = 0;\r
   CapSize  = CapsuleHeader->HeaderSize;\r
-  while (CapInfo.CapFiles [Index][0] != '\0') {\r
-    fpin = fopen (CapInfo.CapFiles[Index], "rb");\r
+  while (gCapDataInfo.CapFiles [Index][0] != '\0') {\r
+    fpin = fopen (gCapDataInfo.CapFiles[Index], "rb");\r
     if (fpin == NULL) {\r
-      Error (NULL, 0, 0001, "Error opening file", CapInfo.CapFiles[Index]);\r
+      Error (NULL, 0, 0001, "Error opening file", gCapDataInfo.CapFiles[Index]);\r
       free (CapBuffer);\r
       return EFI_ABORTED;\r
     }\r
index 767cae9..9f89af0 100644 (file)
@@ -40,16 +40,12 @@ Abstract:
 #include "ParseInf.h"\r
 #include "EfiUtilityMsgs.h"\r
 \r
+extern UINT32 mFvTotalSize;\r
+extern UINT32 mFvTakenSize;\r
 //\r
 // Different file separater for Linux and Windows\r
 //\r
-#ifdef __GNUC__\r
 #define FILE_SEP_CHAR '/'\r
-#define FILE_SEP_STRING "/"\r
-#else\r
-#define FILE_SEP_CHAR '\\'\r
-#define FILE_SEP_STRING "\\"\r
-#endif\r
 \r
 //\r
 // The maximum number of Pad file guid entries.\r
@@ -90,6 +86,10 @@ Abstract:
 #define EFI_FV_BOOT_DRIVER_BASE_ADDRESS_STRING    "EFI_BOOT_DRIVER_BASE_ADDRESS"\r
 #define EFI_FV_RUNTIME_DRIVER_BASE_ADDRESS_STRING "EFI_RUNTIME_DRIVER_BASE_ADDRESS"\r
 \r
+#define EFI_FV_TOTAL_SIZE_STRING    "EFI_FV_TOTAL_SIZE"\r
+#define EFI_FV_TAKEN_SIZE_STRING    "EFI_FV_TAKEN_SIZE"\r
+#define EFI_FV_SPACE_SIZE_STRING    "EFI_FV_SPACE_SIZE"\r
+\r
 //\r
 // Attributes section\r
 //\r
@@ -246,6 +246,9 @@ typedef struct {
 \r
 #pragma pack()\r
 \r
+#define FV_DEFAULT_ATTRIBUTE  0x0004FEFF\r
+extern FV_INFO    gFvDataInfo;\r
+extern CAP_INFO   gCapDataInfo;\r
 //\r
 // Local function prototypes\r
 //\r
@@ -406,4 +409,13 @@ Returns:
 --*/\r
 ;\r
 \r
+EFI_STATUS\r
+WriteMapFile (\r
+  IN OUT FILE                  *FvMapFile,\r
+  IN     CHAR8                 *FileName,\r
+  IN     EFI_GUID              *FileGuidPtr, \r
+  IN     EFI_PHYSICAL_ADDRESS  ImageBaseAddress,\r
+  IN     UINT32                AddressOfEntryPoint,\r
+  IN     UINT32                Offset\r
+  );\r
 #endif\r
index c5b8bd5..022a749 100644 (file)
 //\r
 // Tiano Implementation specific Device Path definition.\r
 //\r
+#pragma pack(1)\r
 typedef struct {\r
   VENDOR_DEVICE_PATH             VendorDevicePath;\r
-  UINT32                         MonotonicCount;\r
+  UINT32                         Reserved;\r
+  UINT64                         UniqueId;\r
 } HII_VENDOR_DEVICE_PATH_NODE;\r
+#pragma pack()\r
 \r
 typedef struct {\r
   HII_VENDOR_DEVICE_PATH_NODE    Node;\r
@@ -52,7 +55,6 @@ typedef struct {
 #define EFI_IFR_TIANO_GUID \\r
   { 0xf0b1735, 0x87a0, 0x4193, {0xb2, 0x66, 0x53, 0x8c, 0x38, 0xaf, 0x48, 0xce} }\r
 \r
-\r
 #pragma pack(1)\r
 \r
 #define EFI_IFR_EXTEND_OP_LABEL       0x0\r
@@ -115,6 +117,37 @@ typedef struct _EFI_IFR_GUID_SUBCLASS {
   UINT16              SubClass;\r
 } EFI_IFR_GUID_SUBCLASS;\r
 \r
+//\r
+// GUIDed opcodes defined for Tiano\r
+//\r
+#define EFI_IFR_FRAMEWORK_GUID \\r
+  { 0x31ca5d1a, 0xd511, 0x4931, { 0xb7, 0x82, 0xae, 0x6b, 0x2b, 0x17, 0x8c, 0xd7 } }\r
+\r
+#define EFI_IFR_EXTEND_OP_OPTIONKEY   0x0\r
+#define EFI_IFR_EXTEND_OP_VAREQNAME   0x1\r
+//\r
+// Store the framework vfr option key value\r
+//\r
+typedef struct _EFI_IFR_GUID_OPTIONKEY {\r
+  EFI_IFR_OP_HEADER   Header;\r
+  EFI_GUID            Guid;\r
+  UINT8               ExtendOpCode;\r
+  EFI_QUESTION_ID     QuestionId;\r
+  EFI_IFR_TYPE_VALUE  OptionValue;\r
+  EFI_QUESTION_ID     KeyValue;\r
+} EFI_IFR_GUID_OPTIONKEY;\r
+\r
+//\r
+// Store the framework vfr vareqval name number\r
+//\r
+typedef struct _EFI_IFR_GUID_VAREQNAME {\r
+  EFI_IFR_OP_HEADER   Header;\r
+  EFI_GUID            Guid;\r
+  UINT8               ExtendOpCode;\r
+  EFI_QUESTION_ID     QuestionId;\r
+  EFI_STRING_ID       NameId;\r
+} EFI_IFR_GUID_VAREQNAME;\r
+\r
 #pragma pack()\r
 \r
 #endif\r
index 672e7ee..e847b76 100644 (file)
@@ -1,13 +1,13 @@
 !INCLUDE ..\Makefiles\ms.common
 
-CPPFLAGS = $(CPPFLAGS) /WX /D PCCTS_USE_NAMESPACE_STD
+CPPFLAGS = $(CPPFLAGS) /WX /D PCCTS_USE_NAMESPACE_STD /D VFREXP_DEBUG
 APPNAME = VfrCompile
 
 LIBS = $(LIB_PATH)\Common.lib
 
-OBJECTS = AParser.obj DLexerBase.obj ATokenBuffer.obj EfiVfrParser.obj \
-          VfrLexer.obj VfrSyntax.obj VfrFormPkg.obj VfrError.obj \
-         VfrUtilityLib.obj VfrCompiler.obj
+OBJECTS = AParser.obj DLexerBase.obj ATokenBuffer.obj \
+          EfiVfrParser.obj VfrLexer.obj VfrSyntax.obj \
+          VfrFormPkg.obj VfrError.obj VfrUtilityLib.obj VfrCompiler.obj
 
 INC = $(INC) -I $(BASE_TOOLS_PATH)\Source\C\VfrCompile\Pccts\h