]> git.proxmox.com Git - mirror_edk2.git/blobdiff - BaseTools/Source/C/GenFw/GenFw.c
Sync tool code to BuildTools project r1739.
[mirror_edk2.git] / BaseTools / Source / C / GenFw / GenFw.c
index 8c648eb4073d8d05a7c8aaf3a381412dc2a0a1bd..e72f05286969297f84d45990160be97621d4707f 100644 (file)
@@ -33,6 +33,7 @@ Abstract:
 \r
 #include <Common/UefiBaseTypes.h>\r
 #include <IndustryStandard/PeImage.h>\r
+#include <Common/UefiInternalFormRepresentation.h>\r
 \r
 //\r
 // Acpi Table definition\r
@@ -60,6 +61,8 @@ Abstract:
 #define UTILITY_MAJOR_VERSION 0\r
 #define UTILITY_MINOR_VERSION 2\r
 \r
+#define HII_RESOURCE_SECTION_INDEX  1\r
+#define HII_RESOURCE_SECTION_NAME   "HII"\r
 //\r
 // Action for this tool.\r
 //\r
@@ -73,6 +76,7 @@ Abstract:
 #define FW_MCI_IMAGE         7\r
 #define FW_MERGE_IMAGE       8\r
 #define FW_RELOC_STRIPEED_IMAGE 9\r
+#define FW_HII_PACKAGE_LIST_RCIMAGE 10\r
 \r
 #define DUMP_TE_HEADER       0x11\r
 \r
@@ -100,6 +104,15 @@ typedef struct {
   UINT32  Reserved[3];\r
 } MICROCODE_IMAGE_HEADER;\r
 \r
+static EFI_GUID mZeroGuid = {0x0, 0x0, 0x0, {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}};\r
+\r
+static const char *gHiiPackageRCFileHeader[] = {\r
+  "//",\r
+  "//  DO NOT EDIT -- auto-generated file",\r
+  "//",\r
+  NULL\r
+};\r
+\r
 STATIC CHAR8 *mInImageName;\r
 \r
 STATIC\r
@@ -258,6 +271,16 @@ Returns:
   fprintf (stdout, "  -r, --replace         Overwrite the input file with the output content.\n\\r
                         If more input files are specified,\n\\r
                         the last input file will be as the output file.\n");\r
+  fprintf (stdout, "  -g HiiPackageListGuid, --hiiguid HiiPackageListGuid\n\\r
+                        HiiListPackageGuidGuid is from the module guid.\n\\r
+                        Its format is xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\n\\r
+                        If not specified, the first Form FormSet guid is used.\n");\r
+  fprintf (stdout, "  --hiipackage          Combine all input binary hii pacakges into \n\\r
+                        a single package list as the text resource data(RC).\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
@@ -440,7 +463,7 @@ typedef Elf32_Dyn Elf_Dyn;
 #define ELFCLASS ELFCLASS32\r
 #define ELF_R_TYPE(r) ELF32_R_TYPE(r)\r
 #define ELF_R_SYM(r) ELF32_R_SYM(r)\r
-\r
+#define ELF_HII_SECTION_NAME ".hii"\r
 //\r
 // Well known ELF structures.\r
 //\r
@@ -452,7 +475,7 @@ Elf_Phdr *gPhdrBase;
 // PE section alignment.\r
 //\r
 const UINT32 CoffAlignment = 0x20;\r
-const UINT16 CoffNbrSections = 4;\r
+const UINT16 CoffNbrSections = 5;\r
 \r
 //\r
 // Current offset in coff file.\r
@@ -475,8 +498,15 @@ UINT32 NtHdrOffset;
 UINT32 TableOffset;\r
 UINT32 TextOffset;\r
 UINT32 DataOffset;\r
+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
@@ -547,11 +577,28 @@ IsTextShdr(
   return (Shdr->sh_flags & (SHF_WRITE | SHF_ALLOC)) == SHF_ALLOC;\r
 }\r
 \r
+int\r
+IsHiiRsrcShdr(\r
+  Elf_Shdr *Shdr\r
+  )\r
+{\r
+  Elf_Shdr *Namedr = GetShdrByIndex(Ehdr->e_shstrndx);\r
+\r
+  if (strcmp((CHAR8*)Ehdr + Namedr->sh_offset + Shdr->sh_name, ELF_HII_SECTION_NAME) == 0) {\r
+    return 1;\r
+  }\r
+\r
+  return 0;\r
+}\r
+\r
 int\r
 IsDataShdr(\r
   Elf_Shdr *Shdr\r
   )\r
 {\r
+  if (IsHiiRsrcShdr(Shdr)) {\r
+    return 0;\r
+  }\r
   return (Shdr->sh_flags & (SHF_WRITE | SHF_ALLOC)) == (SHF_ALLOC | SHF_WRITE);\r
 }\r
 \r
@@ -580,6 +627,128 @@ CreateSectionHeader(
   TableOffset += sizeof (EFI_IMAGE_SECTION_HEADER);\r
 }\r
 \r
+VOID\r
+GetBinaryHiiData (\r
+  CHAR8   *RcString,\r
+  UINT32  Size,\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
+\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
+\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
+\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
+    }\r
+  }\r
+\r
+  if (HiiBinData != NULL) {\r
+    HiiBinSize = HiiBinOffset;\r
+    ResourceDataEntry->Size = HiiBinSize + OffsetToFile - ResourceDataEntry->OffsetToData;\r
+  }\r
+  \r
+  return;\r
+}\r
+\r
 VOID\r
 ScanSections(\r
   VOID\r
@@ -605,11 +774,11 @@ ScanSections(
        break;\r
   case EM_X86_64:\r
   case EM_IA_64:\r
-       CoffOffset += sizeof (EFI_IMAGE_NT_HEADERS64);\r
+    CoffOffset += sizeof (EFI_IMAGE_NT_HEADERS64);\r
        break;\r
   default:\r
     VerboseMsg ("%s unknown e_machine type. Assume IA-32", (UINTN)Ehdr->e_machine);\r
-       CoffOffset += sizeof (EFI_IMAGE_NT_HEADERS32);\r
+    CoffOffset += sizeof (EFI_IMAGE_NT_HEADERS32);\r
        break;\r
   }\r
 \r
@@ -672,13 +841,41 @@ ScanSections(
           Error (NULL, 0, 3000, "Invalid", "Unsupported section alignment.");\r
         }\r
       }\r
-\r
       CoffSectionsOffset[i] = CoffOffset;\r
       CoffOffset += shdr->sh_size;\r
     }\r
   }\r
   CoffOffset = CoffAlign(CoffOffset);\r
 \r
+  //\r
+  //  The HII resource sections.\r
+  //\r
+  HiiRsrcOffset = CoffOffset;\r
+  for (i = 0; i < Ehdr->e_shnum; i++) {\r
+    Elf_Shdr *shdr = GetShdrByIndex(i);\r
+    if (IsHiiRsrcShdr(shdr)) {\r
+      if ((shdr->sh_addralign != 0) && (shdr->sh_addralign != 1)) {\r
+        // the alignment field is valid\r
+        if ((shdr->sh_addr & (shdr->sh_addralign - 1)) == 0) {\r
+          // if the section address is aligned we must align PE/COFF \r
+          CoffOffset = (CoffOffset + shdr->sh_addralign - 1) & ~(shdr->sh_addralign - 1);\r
+        } else if ((shdr->sh_addr % shdr->sh_addralign) != (CoffOffset % shdr->sh_addralign)) {\r
+          // ARM RVCT tools have behavior outside of the ELF specification to try \r
+          // and make images smaller.  If sh_addr is not aligned to sh_addralign \r
+          // then the section needs to preserve sh_addr MOD sh_addralign. \r
+          // Normally doing nothing here works great.\r
+          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
+        CoffOffset = CoffAlign(CoffOffset);\r
+      }\r
+      break;\r
+    }\r
+  }\r
+\r
   RelocOffset = CoffOffset;\r
 \r
   //\r
@@ -760,8 +957,8 @@ ScanSections(
     NtHdr->Pe32.FileHeader.NumberOfSections--;\r
   }\r
 \r
-  if ((RelocOffset - TextOffset) > 0) {\r
-    CreateSectionHeader (".data", DataOffset, RelocOffset - DataOffset,\r
+  if ((HiiRsrcOffset - DataOffset) > 0) {\r
+    CreateSectionHeader (".data", DataOffset, HiiRsrcOffset - DataOffset,\r
             EFI_IMAGE_SCN_CNT_INITIALIZED_DATA\r
             | EFI_IMAGE_SCN_MEM_WRITE\r
             | EFI_IMAGE_SCN_MEM_READ);\r
@@ -769,6 +966,24 @@ ScanSections(
     // Don't make a section of size 0. \r
     NtHdr->Pe32.FileHeader.NumberOfSections--;\r
   }\r
+\r
+  if ((RelocOffset - HiiRsrcOffset) > 0) {\r
+    CreateSectionHeader (".rsrc", HiiRsrcOffset, RelocOffset - HiiRsrcOffset,\r
+            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].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
+  }\r
+\r
 }\r
 \r
 VOID\r
@@ -1215,141 +1430,6 @@ ConvertElf (
   }\r
 }\r
 \r
-void\r
-ZeroXdataSection (\r
- IN     CHAR8                 *ImageName,\r
- IN OUT UINT8                 *FileBuffer,\r
- IN EFI_IMAGE_SECTION_HEADER  *SectionHeader,\r
- IN     UINT32                 SectionTotalNumber\r
-  )\r
-{\r
-  FILE   *fpMapFile;\r
-  CHAR8  MapFileName[_MAX_PATH];\r
-  CHAR8  Line [MAX_LINE_LEN];\r
-  CHAR8  KeyWord [MAX_LINE_LEN];\r
-  CHAR8  SectionName [MAX_LINE_LEN];\r
-  UINT32 FunctionType = 0;\r
-  unsigned SectionOffset = 0;\r
-  unsigned SectionLength = 0;\r
-  unsigned SectionNumber = 0;\r
-  CHAR8  *PdbPointer;\r
-  INT32  Index;\r
-  UINT32 Index2;\r
-\r
-  for (Index2 = 0; Index2 < SectionTotalNumber; Index2++) {\r
-    if (stricmp ((char *)SectionHeader[Index2].Name, ".zdata") == 0) {\r
-      //\r
-      // try to zero the customized .zdata section, which is mapped to .xdata\r
-      //\r
-      memset (FileBuffer + SectionHeader[Index2].PointerToRawData, 0, SectionHeader[Index2].SizeOfRawData);\r
-      DebugMsg (NULL, 0, 9, NULL, "Zero the .xdata section for PE image at Offset 0x%x and Length 0x%x", (unsigned) SectionHeader[Index2].PointerToRawData, (unsigned) SectionHeader[Index2].SizeOfRawData);\r
-      return;\r
-    }\r
-  }\r
-  //\r
-  // Try to get PDB file name\r
-  //\r
-  PdbPointer = (CHAR8  *) PeCoffLoaderGetPdbPointer (FileBuffer);\r
-  if (PdbPointer != NULL) {\r
-    strcpy (MapFileName, PdbPointer);\r
-  } else {\r
-    strcpy (MapFileName, ImageName);\r
-  }\r
-\r
-  //\r
-  // Construct map file name\r
-  //\r
-  Index = strlen (MapFileName) - 1;\r
-  while (Index >= 0 && MapFileName[Index] != '.') {\r
-    Index --;\r
-  }\r
-  if (Index < 0) {\r
-    //\r
-    // don't know how to costruct map file\r
-    //\r
-    return;\r
-  }\r
-\r
-  //\r
-  // fill map file postfix\r
-  //\r
-  MapFileName[Index + 1] = 'm';\r
-  MapFileName[Index + 2] = 'a';\r
-  MapFileName[Index + 3] = 'p';\r
-  MapFileName[Index + 4] = '\0';\r
-\r
-  //\r
-  // try opening Map File\r
-  //\r
-  fpMapFile = fopen (MapFileName, "r");\r
-  if (fpMapFile == NULL) {\r
-    //\r
-    // Can't open Map file. Maybe it doesn't exist.\r
-    //\r
-    return;\r
-  }\r
-\r
-  //\r
-  // Output Functions information into Fv Map file\r
-  //\r
-  while (fgets (Line, MAX_LINE_LEN, fpMapFile) != NULL) {\r
-    //\r
-    // Skip blank line\r
-    //\r
-    if (Line[0] == 0x0a) {\r
-      if (FunctionType != 0) {\r
-        //\r
-        // read all section table data\r
-        //\r
-        FunctionType = 0;\r
-        break;\r
-      }\r
-      FunctionType = 0;\r
-      continue;\r
-    }\r
-\r
-    //\r
-    // By Start keyword\r
-    //\r
-    if (FunctionType == 0) {\r
-      sscanf (Line, "%s", KeyWord);\r
-      if (stricmp (KeyWord, "Start") == 0) {\r
-        //\r
-        // function list\r
-        //\r
-        FunctionType = 1;\r
-      }\r
-      continue;\r
-    }\r
-    //\r
-    // Printf Function Information\r
-    //\r
-    if (FunctionType == 1) {\r
-      sscanf (Line, "%x:%x %xH %s", &SectionNumber, &SectionOffset, &SectionLength, SectionName);\r
-      if (stricmp (SectionName, ".xdata") == 0) {\r
-        FunctionType = 2;\r
-        break;\r
-      }\r
-    }\r
-  }\r
-\r
-  if (FunctionType != 2) {\r
-    //\r
-    // no .xdata section is found\r
-    //\r
-    fclose (fpMapFile);\r
-    return;\r
-  }\r
-\r
-  //\r
-  // Zero .xdata Section data\r
-  //\r
-  memset (FileBuffer + SectionHeader[SectionNumber-1].PointerToRawData + SectionOffset, 0, SectionLength);\r
-  DebugMsg (NULL, 0, 9, NULL, "Zero the .xdata section for PE image at Offset 0x%x and Length 0x%x", (unsigned) SectionHeader[SectionNumber-1].PointerToRawData + SectionOffset, SectionLength);\r
-  fclose (fpMapFile);\r
-  return;\r
-}\r
-\r
 int\r
 main (\r
   int  argc,\r
@@ -1413,6 +1493,14 @@ Returns:
   EFI_IMAGE_OPTIONAL_HEADER64      *Optional64;\r
   EFI_IMAGE_DOS_HEADER             BackupDosHdr;\r
   MICROCODE_IMAGE_HEADER           *MciHeader;\r
+  UINT8                            *HiiPackageListBuffer;\r
+  UINT8                            *HiiPackageDataPointer;\r
+  EFI_GUID                         HiiPackageListGuid;\r
+  EFI_HII_PACKAGE_LIST_HEADER      HiiPackageListHeader;\r
+  EFI_HII_PACKAGE_HEADER           HiiPackageHeader;\r
+  EFI_IFR_FORM_SET                 IfrFormSet;\r
+  UINT8                            NumberOfFormPacakge;\r
+  EFI_HII_PACKAGE_HEADER           EndPackage;\r
 \r
   SetUtilityName (UTILITY_NAME);\r
 \r
@@ -1445,6 +1533,12 @@ Returns:
   Optional64        = NULL;\r
   KeepExceptionTableFlag = FALSE;\r
   KeepZeroPendingFlag    = FALSE;\r
+  NumberOfFormPacakge    = 0;\r
+  HiiPackageListBuffer   = NULL;\r
+  HiiPackageDataPointer  = NULL;\r
+  EndPackage.Length      = sizeof (EFI_HII_PACKAGE_HEADER);\r
+  EndPackage.Type        = EFI_HII_PACKAGE_END;\r
+  memset (&HiiPackageListGuid, 0, sizeof (HiiPackageListGuid));\r
 \r
   if (argc == 1) {\r
     Error (NULL, 0, 1001, "Missing options", "No input options.");\r
@@ -1636,6 +1730,24 @@ Returns:
       continue;\r
     }\r
     \r
+    if ((stricmp (argv[0], "-g") == 0) || (stricmp (argv[0], "--hiiguid") == 0)) {\r
+      Status = StringToGuid (argv[1], &HiiPackageListGuid);\r
+      if (EFI_ERROR (Status)) {\r
+        Error (NULL, 0, 1003, "Invalid option value", "%s = %s", argv[0], argv[1]);\r
+        goto Finish;\r
+      }\r
+      argc -= 2;\r
+      argv += 2;\r
+      continue;\r
+    }\r
+\r
+    if (stricmp (argv[0], "--hiipackage") == 0) {\r
+      OutImageType = FW_HII_PACKAGE_LIST_RCIMAGE;\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
@@ -1699,6 +1811,14 @@ Returns:
     goto Finish;\r
   }\r
 \r
+  //\r
+  // Combine HiiBinary packages to a single package list\r
+  //\r
+  if ((OutImageType == FW_HII_PACKAGE_LIST_RCIMAGE) && ReplaceFlag) {\r
+    Error (NULL, 0, 1002, "Conflicting option", "-r replace option cannot be used with --hiipackage merge files option.");\r
+    goto Finish;\r
+  }\r
+\r
   //\r
   // Input image file\r
   //\r
@@ -1739,6 +1859,9 @@ Returns:
   case FW_MERGE_IMAGE:\r
     VerboseMsg ("Combine the input multi microcode bin files to one bin file.");\r
     break;\r
+  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
   default:\r
     break;\r
   }\r
@@ -1779,6 +1902,107 @@ Returns:
     }\r
   }\r
 \r
+  //\r
+  // Combine multi binary HII package files to a single text package list RC file.\r
+  //\r
+  if (OutImageType == FW_HII_PACKAGE_LIST_RCIMAGE) {\r
+    //\r
+    // Get hii package list lenght\r
+    //\r
+    HiiPackageListHeader.PackageLength = sizeof (EFI_HII_PACKAGE_LIST_HEADER);\r
+    for (Index = 0; Index < InputFileNum; Index ++) {\r
+      fpIn = fopen (InputFileName [Index], "rb");\r
+      if (!fpIn) {\r
+        Error (NULL, 0, 0001, "Error opening file", InputFileName [Index]);\r
+        goto Finish;\r
+      }\r
+      FileLength = _filelength (fileno (fpIn));\r
+      fread (&HiiPackageHeader, 1, sizeof (HiiPackageHeader), fpIn);\r
+      if (HiiPackageHeader.Type == EFI_HII_PACKAGE_FORM) {\r
+        if (HiiPackageHeader.Length != FileLength) {\r
+          Error (NULL, 0, 3000, "Invalid", "The wrong package size is in HII package file %s", InputFileName [Index]);\r
+          fclose (fpIn);\r
+          goto Finish;\r
+        }\r
+        if (memcmp (&HiiPackageListGuid, &mZeroGuid, sizeof (EFI_GUID)) == 0) {\r
+          fread (&IfrFormSet, 1, sizeof (IfrFormSet), fpIn);\r
+          memcpy (&HiiPackageListGuid, &IfrFormSet.Guid, sizeof (EFI_GUID));\r
+        }\r
+        NumberOfFormPacakge ++;\r
+      }\r
+      HiiPackageListHeader.PackageLength += FileLength;\r
+      fclose (fpIn);\r
+    }\r
+    HiiPackageListHeader.PackageLength += sizeof (EndPackage);\r
+    //\r
+    // Check whether hii packages are valid\r
+    //\r
+    if (NumberOfFormPacakge > 1) {\r
+      Error (NULL, 0, 3000, "Invalid", "The input hii packages contains more than one hii form package");\r
+      goto Finish;\r
+    }\r
+    if (memcmp (&HiiPackageListGuid, &mZeroGuid, sizeof (EFI_GUID)) == 0) {\r
+      Error (NULL, 0, 3000, "Invalid", "HII pacakge list guid is not specified!");\r
+      goto Finish;\r
+    }\r
+    memcpy (&HiiPackageListHeader.PackageListGuid, &HiiPackageListGuid, sizeof (EFI_GUID));\r
+    //\r
+    // read hii packages\r
+    //\r
+    HiiPackageListBuffer = malloc (HiiPackageListHeader.PackageLength);\r
+    if (HiiPackageListBuffer == NULL) {\r
+      Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");\r
+      goto Finish;\r
+    }\r
+    memcpy (HiiPackageListBuffer, &HiiPackageListHeader, sizeof (HiiPackageListHeader));\r
+    HiiPackageDataPointer = HiiPackageListBuffer + sizeof (HiiPackageListHeader);\r
+    for (Index = 0; Index < InputFileNum; Index ++) {\r
+      fpIn = fopen (InputFileName [Index], "rb");\r
+      if (!fpIn) {\r
+        Error (NULL, 0, 0001, "Error opening file", InputFileName [Index]);\r
+        free (HiiPackageListBuffer);\r
+        goto Finish;\r
+      }\r
+\r
+      FileLength = _filelength (fileno (fpIn));\r
+      fread (HiiPackageDataPointer, 1, FileLength, fpIn);\r
+      fclose (fpIn);\r
+      HiiPackageDataPointer = HiiPackageDataPointer + FileLength;\r
+    }\r
+    memcpy (HiiPackageDataPointer, &EndPackage, sizeof (EndPackage));\r
+    //\r
+    // write the hii package into the text package list rc file.\r
+    //\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
+    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
+\r
   //\r
   // Combine MciBinary files to one file\r
   //\r
@@ -2471,12 +2695,13 @@ Returns:
             for (Index1 = 0; Index1 < Optional64->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXCEPTION].Size / sizeof (RUNTIME_FUNCTION); Index1++, RuntimeFunction++) {\r
               SectionHeader = (EFI_IMAGE_SECTION_HEADER *) ((UINT8 *) &(PeHdr->Pe32.OptionalHeader) + PeHdr->Pe32.FileHeader.SizeOfOptionalHeader);\r
               for (Index2 = 0; Index2 < PeHdr->Pe32.FileHeader.NumberOfSections; Index2++, SectionHeader++) {\r
-                if (RuntimeFunction->UnwindInfoAddress > SectionHeader->VirtualAddress && RuntimeFunction->UnwindInfoAddress < (SectionHeader->VirtualAddress + SectionHeader->SizeOfRawData)) {\r
+                if (RuntimeFunction->UnwindInfoAddress >= SectionHeader->VirtualAddress && RuntimeFunction->UnwindInfoAddress < (SectionHeader->VirtualAddress + SectionHeader->SizeOfRawData)) {\r
                   UnwindInfo = (UNWIND_INFO *)(FileBuffer + SectionHeader->PointerToRawData + (RuntimeFunction->UnwindInfoAddress - SectionHeader->VirtualAddress));\r
                   if (UnwindInfo->Version == 1) {\r
                     memset (UnwindInfo + 1, 0, UnwindInfo->CountOfUnwindCodes * sizeof (UINT16));\r
                     memset (UnwindInfo, 0, sizeof (UNWIND_INFO));\r
                   }\r
+                  break;\r
                 }\r
               }\r
               memset (RuntimeFunction, 0, sizeof (RUNTIME_FUNCTION));\r
@@ -2552,7 +2777,16 @@ Returns:
   //\r
   if (!KeepExceptionTableFlag) {\r
     SectionHeader = (EFI_IMAGE_SECTION_HEADER *) ((UINT8 *) &(PeHdr->Pe32.OptionalHeader) + PeHdr->Pe32.FileHeader.SizeOfOptionalHeader);\r
-    ZeroXdataSection(mInImageName, FileBuffer, SectionHeader, PeHdr->Pe32.FileHeader.NumberOfSections);\r
+    for (Index = 0; Index < PeHdr->Pe32.FileHeader.NumberOfSections; Index++) {\r
+      if (stricmp ((char *)SectionHeader[Index].Name, ".xdata") == 0) {\r
+        //\r
+        // zero .xdata section\r
+        //\r
+        memset (FileBuffer + SectionHeader[Index].PointerToRawData, 0, SectionHeader[Index].SizeOfRawData);\r
+        DebugMsg (NULL, 0, 9, NULL, "Zero the .xdata section for PE image at Offset 0x%x and Length 0x%x", (unsigned) SectionHeader[Index].PointerToRawData, (unsigned) SectionHeader[Index].SizeOfRawData);\r
+        break;\r
+      }\r
+    }\r
   }\r
 \r
   //\r