1. Add a new option (--hiibinpackage) of GenFw tool to generate the resource section...
[efi/basetools/.git] / Source / C / GenFw / GenFw.c
index e72f052..4c3add6 100644 (file)
@@ -77,6 +77,7 @@ Abstract:
 #define FW_MERGE_IMAGE       8\r
 #define FW_RELOC_STRIPEED_IMAGE 9\r
 #define FW_HII_PACKAGE_LIST_RCIMAGE 10\r
+#define FW_HII_PACKAGE_LIST_BINIMAGE 11\r
 \r
 #define DUMP_TE_HEADER       0x11\r
 \r
@@ -281,6 +282,12 @@ Returns:
                         except for -o option. It is a action option.\n\\r
                         If it is combined with other action options, the later\n\\r
                         input action option will override the previous one.\n");\r
+  fprintf (stdout, "  --hiibinpackage       Combine all input binary hii pacakges into \n\\r
+                        a single package list as the binary resource section.\n\\r
+                        It can't be combined with other action options\n\\r
+                        except for -o option. It is a action option.\n\\r
+                        If it is combined with other action options, the later\n\\r
+                        input action option will override the previous one.\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
@@ -501,12 +508,6 @@ UINT32 DataOffset;
 UINT32 HiiRsrcOffset;\r
 UINT32 RelocOffset;\r
 \r
-//\r
-// HiiBinData\r
-//\r
-UINT8* HiiBinData = NULL;\r
-UINT32 HiiBinSize = 0;\r
-\r
 EFI_IMAGE_BASE_RELOCATION *CoffBaseRel;\r
 UINT16 *CoffEntryRel;\r
 \r
@@ -628,122 +629,60 @@ CreateSectionHeader(
 }\r
 \r
 VOID\r
-GetBinaryHiiData (\r
-  CHAR8   *RcString,\r
-  UINT32  Size,\r
+SetHiiResourceHeader (\r
+  UINT8   *HiiBinData,\r
   UINT32  OffsetToFile\r
   )\r
 {\r
-  unsigned  Data16;\r
-  UINT32  HiiBinOffset;\r
   UINT32  Index;\r
   EFI_IMAGE_RESOURCE_DIRECTORY        *ResourceDirectory;\r
   EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY  *ResourceDirectoryEntry;\r
   EFI_IMAGE_RESOURCE_DIRECTORY_STRING *ResourceDirectoryString;\r
   EFI_IMAGE_RESOURCE_DATA_ENTRY       *ResourceDataEntry;\r
 \r
-  Index = 0;\r
-  while (Index < Size && *RcString != '\0' && *RcString != '{') {\r
-    RcString ++;\r
-    Index ++;\r
-  }\r
-  \r
-  if (*RcString == '\0' || Index == Size) {\r
-    return;\r
-  }\r
-  \r
-  //\r
-  // Skip '{' character\r
-  // Skip space and ',' character\r
-  //\r
-  RcString ++;\r
-  Index ++;\r
-  while (Index < Size && *RcString != '\0' && (isspace (*RcString) || *RcString == ',')){\r
-    RcString ++;\r
-    Index ++;\r
-  }\r
-\r
-  //\r
-  // '}' end character\r
-  //\r
-  if (*RcString == '}' || Index == Size) {\r
-    return;\r
-  }\r
-\r
-  HiiBinOffset = 0;\r
-  HiiBinSize   = 0x1000;\r
-  HiiBinData   = (UINT8 *) malloc (HiiBinSize);\r
-  if (HiiBinData == NULL) {\r
-    return;\r
-  }\r
-  memset (HiiBinData, 0, HiiBinSize);\r
   //\r
   // Fill Resource section entry\r
   //\r
-  ResourceDirectory = (EFI_IMAGE_RESOURCE_DIRECTORY *) (HiiBinData + HiiBinOffset);\r
-  HiiBinOffset += sizeof (EFI_IMAGE_RESOURCE_DIRECTORY);\r
-  ResourceDirectory->NumberOfNamedEntries = 1;\r
-\r
-  ResourceDirectoryEntry = (EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY *) (HiiBinData + HiiBinOffset);\r
-  HiiBinOffset += sizeof (EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY);\r
-  ResourceDirectoryEntry->u1.s.NameIsString = 1;\r
-  ResourceDirectoryEntry->u1.s.NameOffset   = HiiBinOffset;\r
+  ResourceDirectory      = (EFI_IMAGE_RESOURCE_DIRECTORY *) (HiiBinData);\r
+  ResourceDirectoryEntry = (EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY *) (ResourceDirectory + 1);\r
+  for (Index = 0; Index < ResourceDirectory->NumberOfNamedEntries; Index ++) {\r
+    if (ResourceDirectoryEntry->u1.s.NameIsString) {\r
+      ResourceDirectoryString = (EFI_IMAGE_RESOURCE_DIRECTORY_STRING *) (HiiBinData + ResourceDirectoryEntry->u1.s.NameOffset);\r
 \r
-  ResourceDirectoryString = (EFI_IMAGE_RESOURCE_DIRECTORY_STRING *) (HiiBinData + HiiBinOffset);\r
-  ResourceDirectoryString->Length = 3;\r
-  ResourceDirectoryString->String[0] =L'H';\r
-  ResourceDirectoryString->String[1] =L'I';\r
-  ResourceDirectoryString->String[2] =L'I';\r
-  HiiBinOffset = HiiBinOffset + sizeof (ResourceDirectoryString->Length) + ResourceDirectoryString->Length * sizeof (ResourceDirectoryString->String[0]);\r
+      if (ResourceDirectoryString->Length == 3 &&\r
+          ResourceDirectoryString->String[0] == L'H' &&\r
+          ResourceDirectoryString->String[1] == L'I' &&\r
+          ResourceDirectoryString->String[2] == L'I') {\r
+        //\r
+        // Resource Type "HII" found\r
+        //\r
+        if (ResourceDirectoryEntry->u2.s.DataIsDirectory) {\r
+          //\r
+          // Move to next level - resource Name\r
+          //\r
+          ResourceDirectory = (EFI_IMAGE_RESOURCE_DIRECTORY *) (HiiBinData + ResourceDirectoryEntry->u2.s.OffsetToDirectory);\r
+          ResourceDirectoryEntry = (EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY *) (ResourceDirectory + 1);\r
 \r
-  ResourceDirectoryEntry->u2.OffsetToData = HiiBinOffset;\r
-  ResourceDataEntry = (EFI_IMAGE_RESOURCE_DATA_ENTRY *) (HiiBinData + HiiBinOffset);\r
-  HiiBinOffset += sizeof (EFI_IMAGE_RESOURCE_DATA_ENTRY);\r
-  ResourceDataEntry->OffsetToData = OffsetToFile + HiiBinOffset;\r
+          if (ResourceDirectoryEntry->u2.s.DataIsDirectory) {\r
+            //\r
+            // Move to next level - resource Language\r
+            //\r
+            ResourceDirectory = (EFI_IMAGE_RESOURCE_DIRECTORY *) (HiiBinData + ResourceDirectoryEntry->u2.s.OffsetToDirectory);\r
+            ResourceDirectoryEntry = (EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY *) (ResourceDirectory + 1);\r
+          }\r
+        }\r
 \r
-  while (sscanf (RcString, "0x%X", &Data16) != EOF) {\r
-    //\r
-    // Convert the string data to the binary data.\r
-    //\r
-    *(UINT16 *)(HiiBinData + HiiBinOffset) = (UINT16) Data16;\r
-    HiiBinOffset += 2;\r
-    //\r
-    // Jump to the next data.\r
-    //\r
-    RcString = RcString + 2 + 4;\r
-    Index    = Index + 2 + 4;\r
-    //\r
-    // Skip space and ',' character\r
-    //\r
-    while (Index < Size && *RcString != '\0' && (isspace (*RcString) || *RcString == ',')){\r
-      RcString ++;\r
-      Index ++;\r
-    }\r
-    //\r
-    // '}' end character\r
-    //\r
-    if (*RcString == '}'|| Index == Size) {\r
-      break;\r
-    }\r
-    //\r
-    // Check BinBuffer size\r
-    //\r
-    if (HiiBinOffset >= HiiBinSize) {\r
-      HiiBinSize += 0x1000;\r
-      HiiBinData = (UINT8 *) realloc (HiiBinData, HiiBinSize);\r
-      //\r
-      // Memory allocation is failure.\r
-      //\r
-      if (HiiBinData == NULL) {\r
-        HiiBinSize = 0;\r
-        break;\r
+        //\r
+        // Now it ought to be resource Data and update its OffsetToData value \r
+        //\r
+        if (!ResourceDirectoryEntry->u2.s.DataIsDirectory) {\r
+          ResourceDataEntry = (EFI_IMAGE_RESOURCE_DATA_ENTRY *) (HiiBinData + ResourceDirectoryEntry->u2.OffsetToData);\r
+          ResourceDataEntry->OffsetToData = ResourceDataEntry->OffsetToData + OffsetToFile;\r
+          break;\r
+        }\r
       }\r
     }\r
-  }\r
-\r
-  if (HiiBinData != NULL) {\r
-    HiiBinSize = HiiBinOffset;\r
-    ResourceDataEntry->Size = HiiBinSize + OffsetToFile - ResourceDataEntry->OffsetToData;\r
+    ResourceDirectoryEntry++;\r
   }\r
   \r
   return;\r
@@ -867,10 +806,11 @@ ScanSections(
           Error (NULL, 0, 3000, "Invalid", "Unsupported section alignment.");\r
         }\r
       }\r
-      GetBinaryHiiData ((CHAR8*)Ehdr + shdr->sh_offset, shdr->sh_size, HiiRsrcOffset);\r
-      if (HiiBinSize != 0) {\r
-        CoffOffset += HiiBinSize;\r
+      if (shdr->sh_size != 0) {\r
+        CoffSectionsOffset[i] = CoffOffset;\r
+        CoffOffset += shdr->sh_size;\r
         CoffOffset = CoffAlign(CoffOffset);\r
+        SetHiiResourceHeader ((UINT8*) Ehdr + shdr->sh_offset, HiiRsrcOffset);\r
       }\r
       break;\r
     }\r
@@ -972,13 +912,8 @@ ScanSections(
             EFI_IMAGE_SCN_CNT_INITIALIZED_DATA\r
             | EFI_IMAGE_SCN_MEM_READ);\r
 \r
-    NtHdr->Pe32.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE].Size = HiiBinSize;\r
+    NtHdr->Pe32.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE].Size = RelocOffset - HiiRsrcOffset;\r
     NtHdr->Pe32.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress = HiiRsrcOffset;\r
-\r
-    memcpy(CoffFile + HiiRsrcOffset, HiiBinData, HiiBinSize);\r
-    free (HiiBinData);\r
-    HiiBinData = NULL;\r
-    HiiBinSize = 0;\r
   } else {\r
     // Don't make a section of size 0. \r
     NtHdr->Pe32.FileHeader.NumberOfSections--;\r
@@ -1398,6 +1333,7 @@ ConvertElf (
   //\r
   WriteSections(IsTextShdr);\r
   WriteSections(IsDataShdr);\r
+  WriteSections(IsHiiRsrcShdr);\r
   VerboseMsg ("Write and relocate sections.");\r
 \r
   //\r
@@ -1430,6 +1366,122 @@ ConvertElf (
   }\r
 }\r
 \r
+UINT8 *\r
+CreateHiiResouceSectionHeader (\r
+  UINT32 *pSectionHeaderSize, \r
+  UINT32 HiiDataSize\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Create COFF resource section header\r
+\r
+Arguments:\r
+\r
+  pSectionHeaderSize - Pointer to section header size.\r
+  HiiDataSize        - Size of the total HII data in section.\r
+\r
+Returns:\r
+  The created section header buffer.\r
+\r
+--*/\r
+{\r
+  UINT32  HiiSectionHeaderSize;\r
+  UINT32  HiiSectionOffset;\r
+  UINT8   *HiiSectionHeader;\r
+  EFI_IMAGE_RESOURCE_DIRECTORY        *ResourceDirectory;\r
+  EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY  *TypeResourceDirectoryEntry;\r
+  EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY  *NameResourceDirectoryEntry;\r
+  EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY  *LanguageResourceDirectoryEntry;\r
+  EFI_IMAGE_RESOURCE_DIRECTORY_STRING *ResourceDirectoryString;\r
+  EFI_IMAGE_RESOURCE_DATA_ENTRY       *ResourceDataEntry;\r
+\r
+  //\r
+  // Calculate the total size for the resource header (include Type, Name and Language)\r
+  // then allocate memory for the resource header.\r
+  //\r
+  HiiSectionHeaderSize = 3 * (sizeof (EFI_IMAGE_RESOURCE_DIRECTORY) + sizeof (EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY)) \r
+                          + 3 * (sizeof (UINT16) + 3 * sizeof (CHAR16)) \r
+                          + sizeof (EFI_IMAGE_RESOURCE_DATA_ENTRY);\r
+  HiiSectionHeader = malloc (HiiSectionHeaderSize);\r
+  memset (HiiSectionHeader, 0, HiiSectionHeaderSize);\r
+\r
+  HiiSectionOffset = 0;\r
+  //\r
+  // Create Type entry \r
+  //\r
+  ResourceDirectory = (EFI_IMAGE_RESOURCE_DIRECTORY *) (HiiSectionHeader + HiiSectionOffset);\r
+  HiiSectionOffset += sizeof (EFI_IMAGE_RESOURCE_DIRECTORY);\r
+  ResourceDirectory->NumberOfNamedEntries = 1;\r
+  TypeResourceDirectoryEntry = (EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY *) (HiiSectionHeader + HiiSectionOffset);\r
+  HiiSectionOffset += sizeof (EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY);\r
+  TypeResourceDirectoryEntry->u1.s.NameIsString      = 1;\r
+  TypeResourceDirectoryEntry->u2.s.DataIsDirectory   = 1;\r
+  TypeResourceDirectoryEntry->u2.s.OffsetToDirectory = HiiSectionOffset;\r
+  //\r
+  // Create Name entry\r
+  //\r
+  ResourceDirectory = (EFI_IMAGE_RESOURCE_DIRECTORY *) (HiiSectionHeader + HiiSectionOffset);\r
+  HiiSectionOffset += sizeof (EFI_IMAGE_RESOURCE_DIRECTORY);\r
+  ResourceDirectory->NumberOfNamedEntries = 1;\r
+  NameResourceDirectoryEntry = (EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY *) (HiiSectionHeader + HiiSectionOffset);\r
+  HiiSectionOffset += sizeof (EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY);\r
+  NameResourceDirectoryEntry->u1.s.NameIsString      = 1;\r
+  NameResourceDirectoryEntry->u2.s.DataIsDirectory   = 1;\r
+  NameResourceDirectoryEntry->u2.s.OffsetToDirectory = HiiSectionOffset;\r
+  //\r
+  // Create Language entry\r
+  //\r
+  ResourceDirectory = (EFI_IMAGE_RESOURCE_DIRECTORY *) (HiiSectionHeader + HiiSectionOffset);\r
+  HiiSectionOffset += sizeof (EFI_IMAGE_RESOURCE_DIRECTORY);\r
+  ResourceDirectory->NumberOfNamedEntries = 1;\r
+  LanguageResourceDirectoryEntry = (EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY *) (HiiSectionHeader + HiiSectionOffset);\r
+  HiiSectionOffset += sizeof (EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY);\r
+  LanguageResourceDirectoryEntry->u1.s.NameIsString = 1;\r
+  //\r
+  // Create string entry for Type\r
+  //\r
+  TypeResourceDirectoryEntry->u1.s.NameOffset = HiiSectionOffset;\r
+  ResourceDirectoryString = (EFI_IMAGE_RESOURCE_DIRECTORY_STRING *) (HiiSectionHeader + HiiSectionOffset);\r
+  ResourceDirectoryString->Length = 3;\r
+  ResourceDirectoryString->String[0] = L'H';\r
+  ResourceDirectoryString->String[1] = L'I';\r
+  ResourceDirectoryString->String[2] = L'I';\r
+  HiiSectionOffset = HiiSectionOffset + sizeof (ResourceDirectoryString->Length) + ResourceDirectoryString->Length * sizeof (ResourceDirectoryString->String[0]);\r
+  //\r
+  // Create string entry for Name\r
+  //\r
+  NameResourceDirectoryEntry->u1.s.NameOffset = HiiSectionOffset;\r
+  ResourceDirectoryString = (EFI_IMAGE_RESOURCE_DIRECTORY_STRING *) (HiiSectionHeader + HiiSectionOffset);\r
+  ResourceDirectoryString->Length = 3;\r
+  ResourceDirectoryString->String[0] = L'E';\r
+  ResourceDirectoryString->String[1] = L'F';\r
+  ResourceDirectoryString->String[2] = L'I';\r
+  HiiSectionOffset = HiiSectionOffset + sizeof (ResourceDirectoryString->Length) + ResourceDirectoryString->Length * sizeof (ResourceDirectoryString->String[0]);\r
+  //\r
+  // Create string entry for Language\r
+  //\r
+  LanguageResourceDirectoryEntry->u1.s.NameOffset = HiiSectionOffset;\r
+  ResourceDirectoryString = (EFI_IMAGE_RESOURCE_DIRECTORY_STRING *) (HiiSectionHeader + HiiSectionOffset);\r
+  ResourceDirectoryString->Length = 3;\r
+  ResourceDirectoryString->String[0] = L'B';\r
+  ResourceDirectoryString->String[1] = L'I';\r
+  ResourceDirectoryString->String[2] = L'N';\r
+  HiiSectionOffset = HiiSectionOffset + sizeof (ResourceDirectoryString->Length) + ResourceDirectoryString->Length * sizeof (ResourceDirectoryString->String[0]);\r
+  //\r
+  // Create Leaf data\r
+  //\r
+  LanguageResourceDirectoryEntry->u2.OffsetToData = HiiSectionOffset;\r
+  ResourceDataEntry = (EFI_IMAGE_RESOURCE_DATA_ENTRY *) (HiiSectionHeader + HiiSectionOffset);\r
+  HiiSectionOffset += sizeof (EFI_IMAGE_RESOURCE_DATA_ENTRY);\r
+  ResourceDataEntry->OffsetToData = HiiSectionOffset;\r
+  ResourceDataEntry->Size = HiiDataSize;\r
+\r
+  *pSectionHeaderSize = HiiSectionHeaderSize;\r
+  return HiiSectionHeader;\r
+}\r
+\r
 int\r
 main (\r
   int  argc,\r
@@ -1501,6 +1553,8 @@ Returns:
   EFI_IFR_FORM_SET                 IfrFormSet;\r
   UINT8                            NumberOfFormPacakge;\r
   EFI_HII_PACKAGE_HEADER           EndPackage;\r
+  UINT32                           HiiSectionHeaderSize;\r
+  UINT8                            *HiiSectionHeader;\r
 \r
   SetUtilityName (UTILITY_NAME);\r
 \r
@@ -1539,6 +1593,8 @@ Returns:
   EndPackage.Length      = sizeof (EFI_HII_PACKAGE_HEADER);\r
   EndPackage.Type        = EFI_HII_PACKAGE_END;\r
   memset (&HiiPackageListGuid, 0, sizeof (HiiPackageListGuid));\r
+  HiiSectionHeaderSize   = 0;\r
+  HiiSectionHeader       = NULL;\r
 \r
   if (argc == 1) {\r
     Error (NULL, 0, 1001, "Missing options", "No input options.");\r
@@ -1748,6 +1804,13 @@ Returns:
       continue;\r
     }\r
 \r
+    if (stricmp (argv[0], "--hiibinpackage") == 0) {\r
+      OutImageType = FW_HII_PACKAGE_LIST_BINIMAGE;\r
+      argc --;\r
+      argv ++;\r
+      continue;\r
+    }\r
+\r
     if (argv[0][0] == '-') {\r
       Error (NULL, 0, 1000, "Unknown option", argv[0]);\r
       goto Finish;\r
@@ -1819,6 +1882,11 @@ Returns:
     goto Finish;\r
   }\r
 \r
+  if ((OutImageType == FW_HII_PACKAGE_LIST_BINIMAGE) && ReplaceFlag) {\r
+    Error (NULL, 0, 1002, "Conflicting option", "-r replace option cannot be used with --hiibinpackage merge files option.");\r
+    goto Finish;\r
+  }\r
+\r
   //\r
   // Input image file\r
   //\r
@@ -1862,6 +1930,9 @@ Returns:
   case FW_HII_PACKAGE_LIST_RCIMAGE:\r
     VerboseMsg ("Combine the input multi hii bin packages to one text pacakge list RC file.");\r
     break;\r
+  case FW_HII_PACKAGE_LIST_BINIMAGE:\r
+    VerboseMsg ("Combine the input multi hii bin packages to one binary pacakge list file.");\r
+    break;\r
   default:\r
     break;\r
   }\r
@@ -1903,9 +1974,9 @@ Returns:
   }\r
 \r
   //\r
-  // Combine multi binary HII package files to a single text package list RC file.\r
+  // Combine multi binary HII package files.\r
   //\r
-  if (OutImageType == FW_HII_PACKAGE_LIST_RCIMAGE) {\r
+  if (OutImageType == FW_HII_PACKAGE_LIST_RCIMAGE || OutImageType == FW_HII_PACKAGE_LIST_BINIMAGE) {\r
     //\r
     // Get hii package list lenght\r
     //\r
@@ -1970,37 +2041,64 @@ Returns:
       HiiPackageDataPointer = HiiPackageDataPointer + FileLength;\r
     }\r
     memcpy (HiiPackageDataPointer, &EndPackage, sizeof (EndPackage));\r
+\r
     //\r
-    // write the hii package into the text package list rc file.\r
+    // write the hii package into the binary package list file with the resource section header\r
     //\r
-    for (Index = 0; gHiiPackageRCFileHeader[Index] != NULL; Index++) {\r
-      fprintf (fpOut, "%s\n", gHiiPackageRCFileHeader[Index]);\r
+    if (OutImageType == FW_HII_PACKAGE_LIST_BINIMAGE) {\r
+      //\r
+      // Create the resource section header\r
+      //\r
+      HiiSectionHeader = CreateHiiResouceSectionHeader (&HiiSectionHeaderSize, HiiPackageListHeader.PackageLength);\r
+      //\r
+      // Wrtie section header and HiiData into File.\r
+      //\r
+      fwrite (HiiSectionHeader, 1, HiiSectionHeaderSize, fpOut);\r
+      fwrite (HiiPackageListBuffer, 1, HiiPackageListHeader.PackageLength, fpOut);\r
+      //\r
+      // Free allocated resources.\r
+      //\r
+      free (HiiSectionHeader);\r
+      free (HiiPackageListBuffer);\r
+      //\r
+      // Done successfully\r
+      //\r
+      goto Finish;\r
     }\r
-    fprintf (fpOut, "\n%d %s\n{", HII_RESOURCE_SECTION_INDEX, HII_RESOURCE_SECTION_NAME);\r
 \r
-    HiiPackageDataPointer = HiiPackageListBuffer;\r
-    for (Index = 0; Index + 2 < HiiPackageListHeader.PackageLength; Index += 2) {\r
+    //\r
+    // write the hii package into the text package list rc file.\r
+    //\r
+    if (OutImageType == FW_HII_PACKAGE_LIST_RCIMAGE) {\r
+      for (Index = 0; gHiiPackageRCFileHeader[Index] != NULL; Index++) {\r
+        fprintf (fpOut, "%s\n", gHiiPackageRCFileHeader[Index]);\r
+      }\r
+      fprintf (fpOut, "\n%d %s\n{", HII_RESOURCE_SECTION_INDEX, HII_RESOURCE_SECTION_NAME);\r
+\r
+      HiiPackageDataPointer = HiiPackageListBuffer;\r
+      for (Index = 0; Index + 2 < HiiPackageListHeader.PackageLength; Index += 2) {\r
+        if (Index % 16 == 0) {\r
+          fprintf (fpOut, "\n ");\r
+        }\r
+        fprintf (fpOut, " 0x%04X,", *(UINT16 *) HiiPackageDataPointer);\r
+        HiiPackageDataPointer += 2;\r
+      }\r
+      \r
       if (Index % 16 == 0) {\r
         fprintf (fpOut, "\n ");\r
       }\r
-      fprintf (fpOut, " 0x%04X,", *(UINT16 *) HiiPackageDataPointer);\r
-      HiiPackageDataPointer += 2;\r
-    }\r
-    \r
-    if (Index % 16 == 0) {\r
-      fprintf (fpOut, "\n ");\r
-    }\r
-    if ((Index + 2) == HiiPackageListHeader.PackageLength) {\r
-      fprintf (fpOut, " 0x%04X\n}\n", *(UINT16 *) HiiPackageDataPointer);\r
-    }\r
-    if ((Index + 1) == HiiPackageListHeader.PackageLength) {\r
-      fprintf (fpOut, " 0x%04X\n}\n", *(UINT8 *) HiiPackageDataPointer);\r
+      if ((Index + 2) == HiiPackageListHeader.PackageLength) {\r
+        fprintf (fpOut, " 0x%04X\n}\n", *(UINT16 *) HiiPackageDataPointer);\r
+      }\r
+      if ((Index + 1) == HiiPackageListHeader.PackageLength) {\r
+        fprintf (fpOut, " 0x%04X\n}\n", *(UINT8 *) HiiPackageDataPointer);\r
+      }\r
+      free (HiiPackageListBuffer);\r
+      //\r
+      // Done successfully\r
+      //\r
+      goto Finish;\r
     }\r
-    free (HiiPackageListBuffer);\r
-    //\r
-    // Done successfully\r
-    //\r
-    goto Finish;\r
   }\r
 \r
   //\r
@@ -2771,7 +2869,37 @@ Returns:
       TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress = Optional64->SizeOfImage - sizeof (EFI_IMAGE_BASE_RELOCATION);\r
     }\r
   }\r
-   \r
+\r
+  //\r
+  // Fill HII section data\r
+  //\r
+  SectionHeader = (EFI_IMAGE_SECTION_HEADER *) ((UINT8 *) &(PeHdr->Pe32.OptionalHeader) + PeHdr->Pe32.FileHeader.SizeOfOptionalHeader);\r
+  for (Index = 0; Index < PeHdr->Pe32.FileHeader.NumberOfSections; Index++) {\r
+    if (stricmp ((char *)SectionHeader[Index].Name, ".hii") == 0) {\r
+      //\r
+      // Update resource section header offset\r
+      //\r
+      SetHiiResourceHeader ((UINT8*) FileBuffer + SectionHeader[Index].PointerToRawData, SectionHeader[Index].VirtualAddress);\r
+      //\r
+      // Update resource section name\r
+      //\r
+      strcpy((char *) SectionHeader[Index].Name, ".rsrc");\r
+      //\r
+      // Update resource data directory.\r
+      //\r
+      if (PeHdr->Pe32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
+        Optional32 = (EFI_IMAGE_OPTIONAL_HEADER32 *)&PeHdr->Pe32.OptionalHeader;\r
+        Optional32->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress = SectionHeader[Index].VirtualAddress;\r
+        Optional32->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE].Size = SectionHeader[Index].Misc.VirtualSize;\r
+      } else if (PeHdr->Pe32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) {\r
+        Optional64 = (EFI_IMAGE_OPTIONAL_HEADER64 *)&PeHdr->Pe32.OptionalHeader;\r
+        Optional64->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress = SectionHeader[Index].VirtualAddress;\r
+        Optional64->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE].Size = SectionHeader[Index].Misc.VirtualSize;\r
+      }\r
+      break;\r
+    }\r
+  }\r
+\r
   //\r
   // Zero ExceptionTable Xdata\r
   //\r