]> git.proxmox.com Git - mirror_edk2.git/blobdiff - BaseTools/Source/C/GenFw/GenFw.c
Sync tool code to BuildTools project r1783.
[mirror_edk2.git] / BaseTools / Source / C / GenFw / GenFw.c
index 8c648eb4073d8d05a7c8aaf3a381412dc2a0a1bd..aabd143b6a1f6891866c18c1bdf264a6b5326435 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,8 @@ 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
+#define FW_HII_PACKAGE_LIST_BINIMAGE 11\r
 \r
 #define DUMP_TE_HEADER       0x11\r
 \r
@@ -100,6 +105,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
@@ -185,10 +199,10 @@ Returns:
   fprintf (stdout, "  -o FileName, --outputfile FileName\n\\r
                         File will be created to store the ouput content.\n");\r
   fprintf (stdout, "  -e EFI_FILETYPE, --efiImage EFI_FILETYPE\n\\r
-                        Create Efi Image. EFI_FILETYPE is one of BASE, SEC,\n\\r
+                        Create Efi Image. EFI_FILETYPE is one of BASE,SMM_CORE,\n\\r
                         PEI_CORE, PEIM, DXE_CORE, DXE_DRIVER, UEFI_APPLICATION,\n\\r
-                        DXE_SAL_DRIVER, UEFI_DRIVER, DXE_RUNTIME_DRIVER, \n\\r
-                        DXE_SMM_DRIVER, SECURITY_CORE, COMBINED_PEIM_DRIVER, \n\\r
+                        SEC, DXE_SAL_DRIVER, UEFI_DRIVER, DXE_RUNTIME_DRIVER,\n\\r
+                        DXE_SMM_DRIVER, SECURITY_CORE, COMBINED_PEIM_DRIVER,\n\\r
                         PIC_PEIM, RELOCATABLE_PEIM, BS_DRIVER, RT_DRIVER,\n\\r
                         APPLICATION, SAL_RT_DRIVER to support all module types\n\\r
                         It can only be used together with --keepexceptiontable,\n\\r
@@ -222,7 +236,7 @@ Returns:
                         except for -o, -r 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, "  -l, --stripped        Relocation info stripped from the input PE or TE image.\n\\r
+  fprintf (stdout, "  -l, --stripped        Strip off the relocation info from PE or TE image.\n\\r
                         It can't be combined with other action options\n\\r
                         except for -o, -r option. It is a action option.\n\\r
                         If it is combined with other action options, the later\n\\r
@@ -258,6 +272,22 @@ 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
+                        Guid is used to specify hii package list 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, "  --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
@@ -440,7 +470,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 +482,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,6 +505,7 @@ UINT32 NtHdrOffset;
 UINT32 TableOffset;\r
 UINT32 TextOffset;\r
 UINT32 DataOffset;\r
+UINT32 HiiRsrcOffset;\r
 UINT32 RelocOffset;\r
 \r
 EFI_IMAGE_BASE_RELOCATION *CoffBaseRel;\r
@@ -547,11 +578,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 +628,66 @@ CreateSectionHeader(
   TableOffset += sizeof (EFI_IMAGE_SECTION_HEADER);\r
 }\r
 \r
+VOID\r
+SetHiiResourceHeader (\r
+  UINT8   *HiiBinData,\r
+  UINT32  OffsetToFile\r
+  )\r
+{\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
+  //\r
+  // Fill Resource section entry\r
+  //\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
+      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
+          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
+        //\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
+    ResourceDirectoryEntry++;\r
+  }\r
+  \r
+  return;\r
+}\r
+\r
 VOID\r
 ScanSections(\r
   VOID\r
@@ -605,11 +713,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 +780,42 @@ 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
+      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
+  }\r
+\r
   RelocOffset = CoffOffset;\r
 \r
   //\r
@@ -760,8 +897,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 +906,19 @@ 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 = RelocOffset - HiiRsrcOffset;\r
+    NtHdr->Pe32.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress = HiiRsrcOffset;\r
+  } else {\r
+    // Don't make a section of size 0. \r
+    NtHdr->Pe32.FileHeader.NumberOfSections--;\r
+  }\r
+\r
 }\r
 \r
 VOID\r
@@ -1183,6 +1333,7 @@ ConvertElf (
   //\r
   WriteSections(IsTextShdr);\r
   WriteSections(IsDataShdr);\r
+  WriteSections(IsHiiRsrcShdr);\r
   VerboseMsg ("Write and relocate sections.");\r
 \r
   //\r
@@ -1215,139 +1366,277 @@ 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
+EFI_IMAGE_OPTIONAL_HEADER_UNION *\r
+GetPeCoffHeader (\r
+  void *Data\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
+  EFI_IMAGE_DOS_HEADER             *DosHdr;\r
+  EFI_IMAGE_OPTIONAL_HEADER_UNION  *PeHdr;\r
+\r
   //\r
-  // Try to get PDB file name\r
+  // Read the dos & pe hdrs of the image\r
   //\r
-  PdbPointer = (CHAR8  *) PeCoffLoaderGetPdbPointer (FileBuffer);\r
-  if (PdbPointer != NULL) {\r
-    strcpy (MapFileName, PdbPointer);\r
+  DosHdr = (EFI_IMAGE_DOS_HEADER *)Data;\r
+  if (DosHdr->e_magic != EFI_IMAGE_DOS_SIGNATURE) {\r
+    // NO DOS header, check for PE/COFF header\r
+    PeHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)(Data);\r
+    if (PeHdr->Pe32.Signature != EFI_IMAGE_NT_SIGNATURE) {\r
+      return NULL;\r
+    }\r
   } else {\r
-    strcpy (MapFileName, ImageName);\r
+\r
+    PeHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)(((UINT8 *)Data) + DosHdr->e_lfanew);\r
+    if (PeHdr->Pe32.Signature != EFI_IMAGE_NT_SIGNATURE) {\r
+      return NULL;\r
+    }\r
   }\r
+  \r
+  return PeHdr;\r
+}\r
 \r
-  //\r
-  // Construct map file name\r
-  //\r
-  Index = strlen (MapFileName) - 1;\r
-  while (Index >= 0 && MapFileName[Index] != '.') {\r
-    Index --;\r
+void\r
+PeCoffConvertImageToXip (\r
+  UINT8  **FileBuffer,\r
+  UINT32 *FileLength\r
+  )\r
+{\r
+  EFI_IMAGE_OPTIONAL_HEADER_UNION  *PeHdr;\r
+  EFI_IMAGE_OPTIONAL_HEADER_UNION  *NewPeHdr;\r
+  EFI_IMAGE_SECTION_HEADER         *SectionHeader;\r
+  UINTN                            TotalNecessaryFileSize;\r
+  UINTN                            SectionSize;\r
+  UINT8                            *XipFile;\r
+  UINT32                           XipLength;\r
+  UINTN                            Index;\r
+  UINTN                            FirstSectionOffset;\r
+  BOOLEAN                          ConversionNeeded;\r
+\r
+  PeHdr = GetPeCoffHeader ((void *) *FileBuffer);\r
+  if (PeHdr == NULL) {\r
+    return;\r
   }\r
-  if (Index < 0) {\r
+  \r
+  if (PeHdr->Pe32.OptionalHeader.SectionAlignment != PeHdr->Pe32.OptionalHeader.FileAlignment) {\r
     //\r
-    // don't know how to costruct map file\r
+    // The only reason to expand zero fill sections is to make them compatible with XIP images.\r
+    // If SectionAlignment is not equal to FileAlginment then it is not an XIP type image.\r
     //\r
     return;\r
   }\r
 \r
   //\r
-  // fill map file postfix\r
+  // Calculate size of XIP file, and determine if the conversion is needed.\r
   //\r
-  MapFileName[Index + 1] = 'm';\r
-  MapFileName[Index + 2] = 'a';\r
-  MapFileName[Index + 3] = 'p';\r
-  MapFileName[Index + 4] = '\0';\r
+  ConversionNeeded = FALSE;\r
+  XipLength = 0;\r
+  FirstSectionOffset = *FileLength;\r
+  TotalNecessaryFileSize = 0;\r
+  SectionHeader = (EFI_IMAGE_SECTION_HEADER *) ((UINT8 *) &(PeHdr->Pe32.OptionalHeader) + PeHdr->Pe32.FileHeader.SizeOfOptionalHeader);\r
+  for (Index = 0; Index < PeHdr->Pe32.FileHeader.NumberOfSections; Index ++, SectionHeader ++) {\r
+    SectionSize = MAX (SectionHeader->Misc.VirtualSize, SectionHeader->SizeOfRawData);\r
+    TotalNecessaryFileSize += SectionSize;\r
+    if (SectionSize > 0) {\r
+      FirstSectionOffset = MIN (FirstSectionOffset, SectionHeader->VirtualAddress);\r
+      XipLength = MAX (XipLength, SectionHeader->VirtualAddress + SectionSize);\r
+      if (SectionHeader->VirtualAddress != SectionHeader->PointerToRawData) {\r
+        ConversionNeeded = TRUE;\r
+      }\r
+    }\r
+    if (SectionHeader->Misc.VirtualSize > SectionHeader->SizeOfRawData) {\r
+      ConversionNeeded = TRUE;\r
+    }\r
+  }\r
 \r
-  //\r
-  // try opening Map File\r
-  //\r
-  fpMapFile = fopen (MapFileName, "r");\r
-  if (fpMapFile == NULL) {\r
+  if (FirstSectionOffset < PeHdr->Pe32.OptionalHeader.SizeOfHeaders) {\r
     //\r
-    // Can't open Map file. Maybe it doesn't exist.\r
+    // If one of the sections should be loaded to an offset overlapping with\r
+    // the executable header, then it cannot be made into an XIP image.\r
     //\r
+    VerboseMsg ("PE/COFF conversion to XIP is impossible due to overlap");\r
+    VerboseMsg ("of section data with the executable header.");\r
     return;\r
   }\r
 \r
-  //\r
-  // Output Functions information into Fv Map file\r
-  //\r
-  while (fgets (Line, MAX_LINE_LEN, fpMapFile) != NULL) {\r
+  if (FirstSectionOffset == *FileLength) {\r
     //\r
-    // Skip blank line\r
+    // If we never found a section with a non-zero size, then we\r
+    // skip the conversion.\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
+    return;\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
+  TotalNecessaryFileSize += FirstSectionOffset;\r
+\r
+  if (!ConversionNeeded) {\r
+    return;\r
+  }\r
+\r
+  if (XipLength > (2 * TotalNecessaryFileSize)) {\r
+    VerboseMsg ("PE/COFF conversion to XIP appears to be larger than necessary.");\r
+    VerboseMsg ("The image linking process may have left unused memory ranges.");\r
   }\r
 \r
-  if (FunctionType != 2) {\r
+  if (PeHdr->Pe32.FileHeader.PointerToSymbolTable != 0) {\r
     //\r
-    // no .xdata section is found\r
+    // This field is obsolete and should be zero\r
     //\r
-    fclose (fpMapFile);\r
+    PeHdr->Pe32.FileHeader.PointerToSymbolTable = 0;\r
+  }\r
+\r
+  //\r
+  // Allocate the extra space that we need to grow the image\r
+  //\r
+  XipFile = malloc (XipLength);\r
+  memset (XipFile, 0, XipLength);\r
+\r
+  //\r
+  // Copy the file headers\r
+  //\r
+  memcpy (XipFile, *FileBuffer, PeHdr->Pe32.OptionalHeader.SizeOfHeaders);\r
+\r
+  NewPeHdr = GetPeCoffHeader ((void *)XipFile);\r
+  if (NewPeHdr == NULL) {\r
+    free (XipFile);\r
     return;\r
   }\r
 \r
   //\r
-  // Zero .xdata Section data\r
+  // Copy the section data over to the appropriate XIP offsets\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
+  SectionHeader = (EFI_IMAGE_SECTION_HEADER *) ((UINT8 *) &(NewPeHdr->Pe32.OptionalHeader) + NewPeHdr->Pe32.FileHeader.SizeOfOptionalHeader);\r
+  for (Index = 0; Index < PeHdr->Pe32.FileHeader.NumberOfSections; Index ++, SectionHeader ++) {\r
+    if (SectionHeader->SizeOfRawData > 0) {\r
+      memcpy (\r
+        XipFile + SectionHeader->VirtualAddress,\r
+        *FileBuffer + SectionHeader->PointerToRawData,\r
+        SectionHeader->SizeOfRawData\r
+        );\r
+    }\r
+    SectionHeader->SizeOfRawData = SectionHeader->Misc.VirtualSize;\r
+    SectionHeader->PointerToRawData = SectionHeader->VirtualAddress;\r
+  }\r
+\r
+  free (*FileBuffer);\r
+  *FileLength = XipLength;\r
+  *FileBuffer = XipFile;\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
@@ -1413,6 +1702,16 @@ 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
+  UINT32                           HiiSectionHeaderSize;\r
+  UINT8                            *HiiSectionHeader;\r
 \r
   SetUtilityName (UTILITY_NAME);\r
 \r
@@ -1445,6 +1744,14 @@ 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
+  HiiSectionHeaderSize   = 0;\r
+  HiiSectionHeader       = NULL;\r
 \r
   if (argc == 1) {\r
     Error (NULL, 0, 1001, "Missing options", "No input options.");\r
@@ -1636,6 +1943,31 @@ 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 (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
@@ -1699,6 +2031,19 @@ 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
+  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
@@ -1739,6 +2084,12 @@ 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
+  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
@@ -1779,6 +2130,134 @@ Returns:
     }\r
   }\r
 \r
+  //\r
+  // Combine multi binary HII package files.\r
+  //\r
+  if (OutImageType == FW_HII_PACKAGE_LIST_RCIMAGE || OutImageType == FW_HII_PACKAGE_LIST_BINIMAGE) {\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
+    //\r
+    // write the hii package into the binary package list file with the resource section header\r
+    //\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
+\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
+      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
   //\r
   // Combine MciBinary files to one file\r
   //\r
@@ -2047,7 +2526,6 @@ Returns:
           stricmp (ModuleType, "DXE_DRIVER") == 0 ||\r
           stricmp (ModuleType, "DXE_SMM_DRIVER") == 0  ||\r
           stricmp (ModuleType, "UEFI_DRIVER") == 0 ||\r
-          stricmp (ModuleType, "SMM_DRIVER") == 0 ||\r
           stricmp (ModuleType, "SMM_CORE") == 0) {\r
         Type = EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER;\r
         VerboseMsg ("Efi Image subsystem type is efi boot service driver.");\r
@@ -2081,6 +2559,12 @@ Returns:
     VerboseMsg ("Convert the input ELF Image to Pe Image");\r
     ConvertElf(&FileBuffer, &FileLength);\r
   }\r
\r
+  //\r
+  // Make sure File Offsets and Virtual Offsets are the same in the image so it is XIP\r
+  // XIP == eXecute In Place\r
+  //\r
+  PeCoffConvertImageToXip (&FileBuffer, &FileLength);\r
 \r
   //\r
   // Remove reloc section from PE or TE image\r
@@ -2471,12 +2955,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
@@ -2546,13 +3031,52 @@ 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
   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
@@ -3077,7 +3601,7 @@ Returns:
     //\r
     // strip space\r
     //\r
-    for (cptr = Line; *cptr && isspace(*cptr); cptr++) {\r
+    for (cptr = Line; *cptr && isspace((int)*cptr); cptr++) {\r
     }\r
 \r
     // Skip Blank Lines and Comment Lines\r
@@ -3092,14 +3616,14 @@ Returns:
   // DD  XXXXXXXXX\r
   //  DD XXXXXXXXX\r
   //\r
-  if ((tolower(cptr[0]) == 'd') && (tolower(cptr[1]) == 'd') && isspace (cptr[2])) {\r
+  if ((tolower((int)cptr[0]) == 'd') && (tolower((int)cptr[1]) == 'd') && isspace ((int)cptr[2])) {\r
     //\r
     // Skip blanks and look for a hex digit\r
     //\r
     cptr += 3;\r
-    for (; *cptr && isspace(*cptr); cptr++) {\r
+    for (; *cptr && isspace((int)*cptr); cptr++) {\r
     }\r
-    if (isxdigit (*cptr)) {\r
+    if (isxdigit ((int)*cptr)) {\r
       if (sscanf (cptr, "%X", &ScannedData) != 1) {\r
         return STATUS_ERROR;\r
       }\r