]> git.proxmox.com Git - mirror_edk2.git/blobdiff - BaseTools/Source/C/GenFw/GenFw.c
Sync BaseTools Branch (version r2321) to EDKII main trunk.
[mirror_edk2.git] / BaseTools / Source / C / GenFw / GenFw.c
index d42c88e23d9f193baef5e6b7d3871b4d8406016b..d511834fc0aaaa7d1ff4cf62397eeef261299d19 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
 \r
-Copyright (c) 2004 - 2010, Intel Corporation\r
-All rights reserved. This program and the accompanying materials\r
+Copyright (c) 2004 - 2011, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials\r
 are licensed and made available under the terms and conditions of the BSD License\r
 which accompanies this distribution.  The full text of the license may be found at\r
 http://opensource.org/licenses/bsd-license.php\r
@@ -24,6 +24,8 @@ Abstract:
 #ifndef __GNUC__\r
 #include <windows.h>\r
 #include <io.h>\r
+#include <sys/types.h>\r
+#include <sys/stat.h>\r
 #endif\r
 #include <stdio.h>\r
 #include <stdlib.h>\r
@@ -49,10 +51,7 @@ Abstract:
 #include "ParseInf.h"\r
 #include "EfiUtilityMsgs.h"\r
 \r
-#include "elf_common.h"\r
-#include "elf32.h"\r
-#include "elf64.h"\r
-\r
+#include "GenFw.h"\r
 \r
 //\r
 // Version of this utility\r
@@ -63,25 +62,6 @@ Abstract:
 \r
 #define HII_RESOURCE_SECTION_INDEX  1\r
 #define HII_RESOURCE_SECTION_NAME   "HII"\r
-//\r
-// Action for this tool.\r
-//\r
-#define FW_DUMMY_IMAGE       0\r
-#define FW_EFI_IMAGE         1\r
-#define FW_TE_IMAGE          2\r
-#define FW_ACPI_IMAGE        3\r
-#define FW_BIN_IMAGE         4\r
-#define FW_ZERO_DEBUG_IMAGE  5\r
-#define FW_SET_STAMP_IMAGE   6\r
-#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
-#define FW_REBASE_IMAGE      12\r
-#define FW_SET_ADDRESS_IMAGE 13\r
-\r
-#define DUMP_TE_HEADER       0x11\r
 \r
 #define DEFAULT_MC_PAD_BYTE_VALUE  0xFF\r
 #define DEFAULT_MC_ALIGNMENT       16\r
@@ -90,7 +70,7 @@ Abstract:
 #define _MAX_PATH 500\r
 #endif\r
 \r
-#define STATUS_IGNORE        0xA\r
+#define STATUS_IGNORE 0xA\r
 //\r
 // Structure definition for a microcode header\r
 //\r
@@ -116,13 +96,14 @@ static const char *gHiiPackageRCFileHeader[] = {
   NULL\r
 };\r
 \r
-STATIC CHAR8 *mInImageName;\r
-\r
 //\r
 // Module image information\r
 //\r
-STATIC UINT32 mImageTimeStamp = 0;\r
-STATIC UINT32 mImageSize = 0;\r
+CHAR8  *mInImageName;\r
+UINT32 mImageTimeStamp = 0;\r
+UINT32 mImageSize = 0;\r
+UINT32 mOutImageType = FW_DUMMY_IMAGE;\r
+\r
 \r
 STATIC\r
 EFI_STATUS\r
@@ -166,7 +147,7 @@ Returns:
 \r
 --*/\r
 {\r
-  fprintf (stdout, "%s Version %d.%d\n", UTILITY_NAME, UTILITY_MAJOR_VERSION, UTILITY_MINOR_VERSION);\r
+  fprintf (stdout, "%s Version %d.%d %s \n", UTILITY_NAME, UTILITY_MAJOR_VERSION, UTILITY_MINOR_VERSION, __BUILD_VERSION);\r
 }\r
 \r
 STATIC\r
@@ -470,186 +451,6 @@ Returns:
   return STATUS_SUCCESS;\r
 }\r
 \r
-\r
-INTN\r
-IsElfHeader(\r
-  UINT8  *FileBuffer\r
-)\r
-{\r
-  return (FileBuffer[EI_MAG0] == ELFMAG0\r
-    && FileBuffer[EI_MAG1] == ELFMAG1\r
-    && FileBuffer[EI_MAG2] == ELFMAG2\r
-    && FileBuffer[EI_MAG3] == ELFMAG3);\r
-}\r
-\r
-typedef Elf32_Shdr Elf_Shdr;\r
-typedef Elf32_Ehdr Elf_Ehdr;\r
-typedef Elf32_Rel Elf_Rel;\r
-typedef Elf32_Sym Elf_Sym;\r
-typedef Elf32_Phdr Elf_Phdr;\r
-typedef Elf32_Dyn Elf_Dyn;\r
-\r
-#define ELFCLASS ELFCLASS32\r
-#define ELF_R_TYPE(r) ELF32_R_TYPE(r)\r
-#define ELF_R_SYM(r) ELF32_R_SYM(r)\r
-#define ELF_HII_SECTION_NAME ".hii"\r
-//\r
-// Well known ELF structures.\r
-//\r
-Elf_Ehdr *Ehdr;\r
-Elf_Shdr *ShdrBase;\r
-Elf_Phdr *gPhdrBase;\r
-\r
-//\r
-// PE section alignment.\r
-//\r
-const UINT32 CoffAlignment = 0x20;\r
-const UINT16 CoffNbrSections = 5;\r
-\r
-//\r
-// Current offset in coff file.\r
-//\r
-UINT32 CoffOffset;\r
-\r
-//\r
-// Result Coff file in memory.\r
-//\r
-UINT8 *CoffFile = NULL;\r
-//\r
-// ELF sections to offset in Coff file.\r
-//\r
-UINT32 *CoffSectionsOffset = NULL;\r
-\r
-//\r
-// Offset in Coff file of headers and sections.\r
-//\r
-UINT32 NtHdrOffset;\r
-UINT32 TableOffset;\r
-UINT32 TextOffset;\r
-UINT32 DataOffset;\r
-UINT32 HiiRsrcOffset;\r
-UINT32 RelocOffset;\r
-\r
-EFI_IMAGE_BASE_RELOCATION *CoffBaseRel;\r
-UINT16 *CoffEntryRel;\r
-\r
-UINT32\r
-CoffAlign(\r
-  UINT32 Offset\r
-  )\r
-{\r
-  return (Offset + CoffAlignment - 1) & ~(CoffAlignment - 1);\r
-}\r
-\r
-Elf_Shdr *\r
-GetShdrByIndex(\r
-  UINT32 Num\r
-  )\r
-{\r
-  if (Num >= Ehdr->e_shnum)\r
-    return NULL;\r
-  return (Elf_Shdr*)((UINT8*)ShdrBase + Num * Ehdr->e_shentsize);\r
-}\r
-\r
-INTN\r
-CheckElfHeader(\r
-  VOID\r
-  )\r
-{\r
-  //\r
-  // Note: Magic has already been tested.\r
-  //\r
-  if (Ehdr->e_ident[EI_CLASS] != ELFCLASS) {\r
-    Error (NULL, 0, 3000, "Unsupported", "%s needs to be ported for 64-bit ELF.", mInImageName);\r
-    return 0;\r
-  }\r
-  if (Ehdr->e_ident[EI_DATA] != ELFDATA2LSB) {\r
-    Error (NULL, 0, 3000, "Unsupported", "ELF EI_DATA not ELFDATA2LSB");\r
-    return 0;\r
-  }\r
-  if ((Ehdr->e_type != ET_EXEC) && (Ehdr->e_type != ET_DYN)) {\r
-    Error (NULL, 0, 3000, "Unsupported", "ELF e_type not ET_EXEC or ET_DYN");\r
-    return 0;\r
-  }\r
-  if (!((Ehdr->e_machine == EM_386) || (Ehdr->e_machine == EM_ARM))) { \r
-    Error (NULL, 0, 3000, "Unsupported", "ELF e_machine not EM_386 or EM_ARM");\r
-    return 0;\r
-  }\r
-  if (Ehdr->e_version != EV_CURRENT) {\r
-    Error (NULL, 0, 3000, "Unsupported", "ELF e_version (%u) not EV_CURRENT (%d)", (unsigned) Ehdr->e_version, EV_CURRENT);\r
-    return 0;\r
-  }\r
-\r
-  //\r
-  // Find the section header table\r
-  //\r
-  ShdrBase  = (Elf_Shdr *)((UINT8 *)Ehdr + Ehdr->e_shoff);\r
-  gPhdrBase = (Elf_Phdr *)((UINT8 *)Ehdr + Ehdr->e_phoff);\r
-\r
-  CoffSectionsOffset = (UINT32 *)malloc(Ehdr->e_shnum * sizeof (UINT32));\r
-\r
-  memset(CoffSectionsOffset, 0, Ehdr->e_shnum * sizeof(UINT32));\r
-  return 1;\r
-}\r
-\r
-int\r
-IsTextShdr(\r
-  Elf_Shdr *Shdr\r
-  )\r
-{\r
-  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
-VOID\r
-CreateSectionHeader(\r
-  const CHAR8 *Name,\r
-  UINT32      Offset,\r
-  UINT32      Size,\r
-  UINT32      Flags\r
-  )\r
-{\r
-  EFI_IMAGE_SECTION_HEADER *Hdr;\r
-  Hdr = (EFI_IMAGE_SECTION_HEADER*)(CoffFile + TableOffset);\r
-\r
-  strcpy((char *)Hdr->Name, Name);\r
-  Hdr->Misc.VirtualSize = Size;\r
-  Hdr->VirtualAddress = Offset;\r
-  Hdr->SizeOfRawData = Size;\r
-  Hdr->PointerToRawData = Offset;\r
-  Hdr->PointerToRelocations = 0;\r
-  Hdr->PointerToLinenumbers = 0;\r
-  Hdr->NumberOfRelocations = 0;\r
-  Hdr->NumberOfLinenumbers = 0;\r
-  Hdr->Characteristics = Flags;\r
-\r
-  TableOffset += sizeof (EFI_IMAGE_SECTION_HEADER);\r
-}\r
-\r
 VOID\r
 SetHiiResourceHeader (\r
   UINT8   *HiiBinData,\r
@@ -710,686 +511,6 @@ SetHiiResourceHeader (
   return;\r
 }\r
 \r
-VOID\r
-ScanSections(\r
-  VOID\r
-  )\r
-{\r
-  UINT32                          i;\r
-  EFI_IMAGE_DOS_HEADER            *DosHdr;\r
-  EFI_IMAGE_OPTIONAL_HEADER_UNION *NtHdr;\r
-  UINT32                          CoffEntry;\r
-\r
-  CoffEntry = 0;\r
-  CoffOffset = 0;\r
-\r
-  //\r
-  // Coff file start with a DOS header.\r
-  //\r
-  CoffOffset = sizeof(EFI_IMAGE_DOS_HEADER) + 0x40;\r
-  NtHdrOffset = CoffOffset;\r
-  switch (Ehdr->e_machine) {\r
-  case EM_386:\r
-  case EM_ARM:\r
-    CoffOffset += sizeof (EFI_IMAGE_NT_HEADERS32);\r
-       break;\r
-  case EM_X86_64:\r
-  case EM_IA_64:\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
-       break;\r
-  }\r
-\r
-  TableOffset = CoffOffset;\r
-  CoffOffset += CoffNbrSections * sizeof(EFI_IMAGE_SECTION_HEADER);\r
-\r
-  //\r
-  // First text sections.\r
-  //\r
-  CoffOffset = CoffAlign(CoffOffset);\r
-  TextOffset = CoffOffset;\r
-  for (i = 0; i < Ehdr->e_shnum; i++) {\r
-    Elf_Shdr *shdr = GetShdrByIndex(i);\r
-    if (IsTextShdr(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
-      \r
-      /* Relocate entry.  */\r
-      if ((Ehdr->e_entry >= shdr->sh_addr) &&\r
-          (Ehdr->e_entry < shdr->sh_addr + shdr->sh_size)) {\r
-        CoffEntry = CoffOffset + Ehdr->e_entry - shdr->sh_addr;\r
-      }\r
-      CoffSectionsOffset[i] = CoffOffset;\r
-      CoffOffset += shdr->sh_size;\r
-    }\r
-  }\r
-\r
-  if (Ehdr->e_machine != EM_ARM) {\r
-    CoffOffset = CoffAlign(CoffOffset);\r
-  }\r
-\r
-  //\r
-  //  Then data sections.\r
-  //\r
-  DataOffset = CoffOffset;\r
-  for (i = 0; i < Ehdr->e_shnum; i++) {\r
-    Elf_Shdr *shdr = GetShdrByIndex(i);\r
-    if (IsDataShdr(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
-      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
-  // Allocate base Coff file.  Will be expanded later for relocations.\r
-  //\r
-  CoffFile = (UINT8 *)malloc(CoffOffset);\r
-  memset(CoffFile, 0, CoffOffset);\r
-\r
-  //\r
-  // Fill headers.\r
-  //\r
-  DosHdr = (EFI_IMAGE_DOS_HEADER *)CoffFile;\r
-  DosHdr->e_magic = EFI_IMAGE_DOS_SIGNATURE;\r
-  DosHdr->e_lfanew = NtHdrOffset;\r
-\r
-  NtHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION*)(CoffFile + NtHdrOffset);\r
-\r
-  NtHdr->Pe32.Signature = EFI_IMAGE_NT_SIGNATURE;\r
-\r
-  switch (Ehdr->e_machine) {\r
-  case EM_386:\r
-    NtHdr->Pe32.FileHeader.Machine = EFI_IMAGE_MACHINE_IA32;\r
-    NtHdr->Pe32.OptionalHeader.Magic = EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC;\r
-    break;\r
-  case EM_X86_64:\r
-    NtHdr->Pe32.FileHeader.Machine = EFI_IMAGE_MACHINE_X64;\r
-    NtHdr->Pe32.OptionalHeader.Magic = EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC;\r
-    break;\r
-  case EM_IA_64:\r
-    NtHdr->Pe32.FileHeader.Machine = EFI_IMAGE_MACHINE_IPF;\r
-    NtHdr->Pe32.OptionalHeader.Magic = EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC;\r
-    break;\r
-  case EM_ARM:\r
-    NtHdr->Pe32.FileHeader.Machine = EFI_IMAGE_MACHINE_ARMT;\r
-    NtHdr->Pe32.OptionalHeader.Magic = EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC;\r
-    break;\r
-  default:\r
-    VerboseMsg ("%s unknown e_machine type. Assume IA-32", (UINTN)Ehdr->e_machine);\r
-    NtHdr->Pe32.FileHeader.Machine = EFI_IMAGE_MACHINE_IA32;\r
-    NtHdr->Pe32.OptionalHeader.Magic = EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC;\r
-  }\r
-\r
-  NtHdr->Pe32.FileHeader.NumberOfSections = CoffNbrSections;\r
-  NtHdr->Pe32.FileHeader.TimeDateStamp = (UINT32) time(NULL);\r
-  mImageTimeStamp = NtHdr->Pe32.FileHeader.TimeDateStamp;\r
-  NtHdr->Pe32.FileHeader.PointerToSymbolTable = 0;\r
-  NtHdr->Pe32.FileHeader.NumberOfSymbols = 0;\r
-  NtHdr->Pe32.FileHeader.SizeOfOptionalHeader = sizeof(NtHdr->Pe32.OptionalHeader);\r
-  NtHdr->Pe32.FileHeader.Characteristics = EFI_IMAGE_FILE_EXECUTABLE_IMAGE\r
-    | EFI_IMAGE_FILE_LINE_NUMS_STRIPPED\r
-    | EFI_IMAGE_FILE_LOCAL_SYMS_STRIPPED\r
-    | EFI_IMAGE_FILE_32BIT_MACHINE;\r
-\r
-  NtHdr->Pe32.OptionalHeader.SizeOfCode = DataOffset - TextOffset;\r
-  NtHdr->Pe32.OptionalHeader.SizeOfInitializedData = RelocOffset - DataOffset;\r
-  NtHdr->Pe32.OptionalHeader.SizeOfUninitializedData = 0;\r
-  NtHdr->Pe32.OptionalHeader.AddressOfEntryPoint = CoffEntry;\r
-\r
-  NtHdr->Pe32.OptionalHeader.BaseOfCode = TextOffset;\r
-\r
-  NtHdr->Pe32.OptionalHeader.BaseOfData = DataOffset;\r
-  NtHdr->Pe32.OptionalHeader.ImageBase = 0;\r
-  NtHdr->Pe32.OptionalHeader.SectionAlignment = CoffAlignment;\r
-  NtHdr->Pe32.OptionalHeader.FileAlignment = CoffAlignment;\r
-  NtHdr->Pe32.OptionalHeader.SizeOfImage = 0;\r
-\r
-  NtHdr->Pe32.OptionalHeader.SizeOfHeaders = TextOffset;\r
-  NtHdr->Pe32.OptionalHeader.NumberOfRvaAndSizes = EFI_IMAGE_NUMBER_OF_DIRECTORY_ENTRIES;\r
-\r
-  //\r
-  // Section headers.\r
-  //\r
-  if ((DataOffset - TextOffset) > 0) {\r
-    CreateSectionHeader (".text", TextOffset, DataOffset - TextOffset,\r
-            EFI_IMAGE_SCN_CNT_CODE\r
-            | EFI_IMAGE_SCN_MEM_EXECUTE\r
-            | EFI_IMAGE_SCN_MEM_READ);\r
-  } else {\r
-    // Don't make a section of size 0. \r
-    NtHdr->Pe32.FileHeader.NumberOfSections--;\r
-  }\r
-\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
-  } else {\r
-    // 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
-WriteSections(\r
-  int   (*Filter)(Elf_Shdr *)\r
-  )\r
-{\r
-  UINT32      Idx;\r
-  Elf_Shdr  *SecShdr;\r
-  UINT32      SecOffset;\r
-\r
-  //\r
-  // First: copy sections.\r
-  //\r
-  for (Idx = 0; Idx < Ehdr->e_shnum; Idx++) {\r
-    Elf_Shdr *Shdr = GetShdrByIndex(Idx);\r
-    if ((*Filter)(Shdr)) {\r
-      switch (Shdr->sh_type) {\r
-      case SHT_PROGBITS:\r
-        /* Copy.  */\r
-        memcpy(CoffFile + CoffSectionsOffset[Idx],\r
-              (UINT8*)Ehdr + Shdr->sh_offset,\r
-              Shdr->sh_size);\r
-        break;\r
-      \r
-      case SHT_NOBITS:\r
-        memset(CoffFile + CoffSectionsOffset[Idx], 0, Shdr->sh_size);\r
-        break;\r
-      \r
-      default:\r
-        //\r
-        //  Ignore for unkown section type.\r
-        //\r
-        VerboseMsg ("%s unknown section type %x. We directly copy this section into Coff file", mInImageName, (unsigned)Shdr->sh_type);\r
-        break;\r
-      }\r
-    }\r
-  }\r
-\r
-  //\r
-  // Second: apply relocations.\r
-  //\r
-  for (Idx = 0; Idx < Ehdr->e_shnum; Idx++) {\r
-    Elf_Shdr *RelShdr = GetShdrByIndex(Idx);\r
-    if (RelShdr->sh_type != SHT_REL)\r
-      continue;\r
-    SecShdr = GetShdrByIndex(RelShdr->sh_info);\r
-    SecOffset = CoffSectionsOffset[RelShdr->sh_info];\r
-    if (RelShdr->sh_type == SHT_REL && (*Filter)(SecShdr)) {\r
-      UINT32 RelIdx;\r
-      Elf_Shdr *SymtabShdr = GetShdrByIndex(RelShdr->sh_link);\r
-      UINT8 *Symtab = (UINT8*)Ehdr + SymtabShdr->sh_offset;\r
-\r
-      for (RelIdx = 0; RelIdx < RelShdr->sh_size; RelIdx += RelShdr->sh_entsize) {\r
-        Elf_Rel *Rel = (Elf_Rel *)((UINT8*)Ehdr + RelShdr->sh_offset + RelIdx);\r
-        Elf_Sym *Sym = (Elf_Sym *)(Symtab + ELF_R_SYM(Rel->r_info) * SymtabShdr->sh_entsize);\r
-        Elf_Shdr *SymShdr;\r
-        UINT8 *Targ;\r
-\r
-        if (Sym->st_shndx == SHN_UNDEF\r
-            || Sym->st_shndx == SHN_ABS\r
-            || Sym->st_shndx > Ehdr->e_shnum) {\r
-          Error (NULL, 0, 3000, "Invalid", "%s bad symbol definition.", mInImageName);\r
-        }\r
-        SymShdr = GetShdrByIndex(Sym->st_shndx);\r
-\r
-        //\r
-        // Note: r_offset in a memory address.\r
-        //  Convert it to a pointer in the coff file.\r
-        //\r
-        Targ = CoffFile + SecOffset + (Rel->r_offset - SecShdr->sh_addr);\r
-\r
-        if (Ehdr->e_machine == EM_386) {\r
-          switch (ELF_R_TYPE(Rel->r_info)) {\r
-          case R_386_NONE:\r
-            break;\r
-          case R_386_32:\r
-            //\r
-            // Absolute relocation.\r
-            //\r
-            *(UINT32 *)Targ = *(UINT32 *)Targ - SymShdr->sh_addr\r
-              + CoffSectionsOffset[Sym->st_shndx];\r
-            break;\r
-          case R_386_PC32:\r
-            //\r
-            // Relative relocation: Symbol - Ip + Addend\r
-            //\r
-            *(UINT32 *)Targ = *(UINT32 *)Targ\r
-              + (CoffSectionsOffset[Sym->st_shndx] - SymShdr->sh_addr)\r
-              - (SecOffset - SecShdr->sh_addr);\r
-            break;\r
-          default:\r
-            Error (NULL, 0, 3000, "Invalid", "%s unhandled section type %x.", mInImageName, (unsigned) ELF_R_TYPE(Rel->r_info));\r
-          }\r
-        } else if (Ehdr->e_machine == EM_ARM) {\r
-          switch (ELF32_R_TYPE(Rel->r_info)) {\r
-          case R_ARM_RBASE:   // No relocation - no action required\r
-          case R_ARM_PC24:    // PC-relative relocations don't require modification\r
-          case R_ARM_XPC25:   // PC-relative relocations don't require modification\r
-            break;\r
-          case R_ARM_ABS32:\r
-          case R_ARM_RABS32:\r
-            //\r
-            // Absolute relocation.\r
-            //\r
-            *(UINT32 *)Targ = *(UINT32 *)Targ - SymShdr->sh_addr + CoffSectionsOffset[Sym->st_shndx];\r
-            break;\r
-          default:\r
-            Error (NULL, 0, 3000, "Invalid", "%s unhandled section type %x.", mInImageName, (unsigned) ELF32_R_TYPE(Rel->r_info));\r
-          }\r
-        }\r
-      }\r
-    }\r
-  }\r
-}\r
-\r
-VOID\r
-CoffAddFixupEntry(\r
-  UINT16 Val\r
-  )\r
-{\r
-  *CoffEntryRel = Val;\r
-  CoffEntryRel++;\r
-  CoffBaseRel->SizeOfBlock += 2;\r
-  CoffOffset += 2;\r
-}\r
-\r
-VOID\r
-CoffAddFixup(\r
-  UINT32 Offset,\r
-  UINT8  Type\r
-  )\r
-{\r
-  if (CoffBaseRel == NULL\r
-      || CoffBaseRel->VirtualAddress != (Offset & ~0xfff)) {\r
-    if (CoffBaseRel != NULL) {\r
-      //\r
-      // Add a null entry (is it required ?)\r
-      //\r
-      CoffAddFixupEntry (0);\r
-      //\r
-      // Pad for alignment.\r
-      //\r
-      if (CoffOffset % 4 != 0)\r
-        CoffAddFixupEntry (0);\r
-    }\r
-\r
-    CoffFile = realloc\r
-      (CoffFile,\r
-       CoffOffset + sizeof(EFI_IMAGE_BASE_RELOCATION) + 2*0x1000);\r
-    memset(CoffFile + CoffOffset, 0,\r
-     sizeof(EFI_IMAGE_BASE_RELOCATION) + 2*0x1000);\r
-\r
-    CoffBaseRel = (EFI_IMAGE_BASE_RELOCATION*)(CoffFile + CoffOffset);\r
-    CoffBaseRel->VirtualAddress = Offset & ~0xfff;\r
-    CoffBaseRel->SizeOfBlock = sizeof(EFI_IMAGE_BASE_RELOCATION);\r
-\r
-    CoffEntryRel = (UINT16 *)(CoffBaseRel + 1);\r
-    CoffOffset += sizeof(EFI_IMAGE_BASE_RELOCATION);\r
-  }\r
-\r
-  //\r
-  // Fill the entry.\r
-  //\r
-  CoffAddFixupEntry((UINT16) ((Type << 12) | (Offset & 0xfff)));\r
-}\r
-\r
-\r
-Elf_Phdr *\r
-GetPhdrByIndex (\r
-  UINT32 num\r
-  )\r
-{\r
-  if (num >= Ehdr->e_phnum) {\r
-    return NULL;\r
-  }\r
-  \r
-  return (Elf32_Phdr *)((UINT8*)gPhdrBase + num * Ehdr->e_phentsize);\r
-}\r
-\r
-\r
-VOID\r
-WriteRelocations(\r
-  VOID\r
-  )\r
-{\r
-  UINT32                           Index;\r
-  EFI_IMAGE_OPTIONAL_HEADER_UNION  *NtHdr;\r
-  EFI_IMAGE_DATA_DIRECTORY         *Dir;\r
-  BOOLEAN                          FoundRelocations;\r
-  Elf_Dyn                          *Dyn;\r
-  Elf_Rel                          *Rel;\r
-  UINTN                            RelElementSize;\r
-  UINTN                            RelSize;\r
-  UINTN                            RelOffset;\r
-  UINTN                            K;\r
-  UINT8                            *Targ;\r
-  Elf32_Phdr                       *DynamicSegment;\r
-  Elf32_Phdr                       *TargetSegment;\r
-\r
-  for (Index = 0, FoundRelocations = FALSE; Index < Ehdr->e_shnum; Index++) {\r
-    Elf_Shdr *RelShdr = GetShdrByIndex(Index);\r
-    if (RelShdr->sh_type == SHT_REL) {\r
-      Elf_Shdr *SecShdr = GetShdrByIndex(RelShdr->sh_info);\r
-      if (IsTextShdr(SecShdr) || IsDataShdr(SecShdr)) {\r
-        UINT32 RelIdx;\r
-        FoundRelocations = TRUE;\r
-        for (RelIdx = 0; RelIdx < RelShdr->sh_size; RelIdx += RelShdr->sh_entsize) {\r
-          Elf_Rel *Rel = (Elf_Rel *)\r
-            ((UINT8*)Ehdr + RelShdr->sh_offset + RelIdx);\r
-          \r
-          if (Ehdr->e_machine == EM_386) { \r
-            switch (ELF_R_TYPE(Rel->r_info)) {\r
-            case R_386_NONE:\r
-            case R_386_PC32:\r
-              break;\r
-            case R_386_32:\r
-              CoffAddFixup(CoffSectionsOffset[RelShdr->sh_info]\r
-              + (Rel->r_offset - SecShdr->sh_addr),\r
-              EFI_IMAGE_REL_BASED_HIGHLOW);\r
-              break;\r
-            default:\r
-              Error (NULL, 0, 3000, "Invalid", "%s unhandled section type %x.", mInImageName, (unsigned) ELF_R_TYPE(Rel->r_info));\r
-            }\r
-          } else if (Ehdr->e_machine == EM_ARM) {\r
-            switch (ELF32_R_TYPE(Rel->r_info)) {\r
-            case R_ARM_RBASE:\r
-            case R_ARM_PC24:\r
-            case R_ARM_XPC25:\r
-              break;\r
-            case R_ARM_ABS32:\r
-            case R_ARM_RABS32:\r
-              CoffAddFixup (\r
-                CoffSectionsOffset[RelShdr->sh_info]\r
-                + (Rel->r_offset - SecShdr->sh_addr),\r
-                EFI_IMAGE_REL_BASED_HIGHLOW\r
-                );\r
-              break;\r
-            default:\r
-              Error (NULL, 0, 3000, "Invalid", "%s unhandled section type %x.", mInImageName, (unsigned) ELF32_R_TYPE(Rel->r_info));\r
-            }\r
-          } else {\r
-            Error (NULL, 0, 3000, "Not Supported", "This tool does not support relocations for ELF with e_machine %u (processor type).", (unsigned) Ehdr->e_machine);\r
-          }\r
-        }\r
-      }\r
-    }\r
-  }\r
-\r
-  if (!FoundRelocations && (Ehdr->e_machine == EM_ARM)) {\r
-    /* Try again, but look for PT_DYNAMIC instead of SHT_REL */\r
-\r
-    for (Index = 0; Index < Ehdr->e_phnum; Index++) {\r
-      RelElementSize = 0;\r
-      RelSize = 0;\r
-      RelOffset = 0;\r
-\r
-      DynamicSegment = GetPhdrByIndex (Index);\r
-\r
-      if (DynamicSegment->p_type == PT_DYNAMIC) {\r
-        Dyn = (Elf32_Dyn *) ((UINT8 *)Ehdr + DynamicSegment->p_offset);\r
-\r
-        while (Dyn->d_tag != DT_NULL) {\r
-          switch (Dyn->d_tag) {\r
-            case  DT_REL:\r
-              RelOffset = Dyn->d_un.d_val;\r
-              break;\r
-\r
-            case  DT_RELSZ:\r
-              RelSize = Dyn->d_un.d_val;\r
-              break;\r
-\r
-            case  DT_RELENT:\r
-              RelElementSize = Dyn->d_un.d_val;\r
-              break;\r
-          }\r
-          Dyn++;\r
-        }\r
-        if (( RelOffset == 0 ) || ( RelSize == 0 ) || ( RelElementSize == 0 )) {\r
-          Error (NULL, 0, 3000, "Invalid", "%s bad ARM dynamic relocations.", mInImageName);\r
-        }\r
-\r
-        for (K = 0; K < RelSize; K += RelElementSize) {\r
-\r
-          Rel = (Elf32_Rel *) ((UINT8 *) Ehdr + DynamicSegment->p_offset + RelOffset + K);\r
-\r
-          switch (ELF32_R_TYPE (Rel->r_info)) {\r
-          case  R_ARM_RBASE:\r
-            break;\r
-          case  R_ARM_RABS32:\r
-            TargetSegment = GetPhdrByIndex (ELF32_R_SYM (Rel->r_info) - 1);\r
-\r
-            // Note: r_offset in a memory address.  Convert it to a pointer in the coff file.\r
-            Targ = CoffFile + CoffSectionsOffset[ ELF32_R_SYM( Rel->r_info ) ] + Rel->r_offset - TargetSegment->p_vaddr;\r
-\r
-            *(UINT32 *)Targ = *(UINT32 *)Targ + CoffSectionsOffset [ELF32_R_SYM( Rel->r_info )];\r
-\r
-            CoffAddFixup (CoffSectionsOffset[ELF32_R_SYM (Rel->r_info)] + (Rel->r_offset - TargetSegment->p_vaddr), EFI_IMAGE_REL_BASED_HIGHLOW);\r
-            break;\r
-          default:\r
-            Error (NULL, 0, 3000, "Invalid", "%s bad ARM dynamic relocations, unkown type.", mInImageName);\r
-          }\r
-        }\r
-        break;\r
-      }\r
-    }\r
-  }\r
-\r
-  //\r
-  // Pad by adding empty entries.\r
-  //\r
-  while (CoffOffset & (CoffAlignment - 1)) {\r
-    CoffAddFixupEntry(0);\r
-  }\r
-\r
-\r
-  NtHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)(CoffFile + NtHdrOffset);\r
-  Dir = &NtHdr->Pe32.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC];\r
-  Dir->Size = CoffOffset - RelocOffset;\r
-  if (Dir->Size == 0) {\r
-    // If no relocations, null out the directory entry and don't add the .reloc section\r
-    Dir->VirtualAddress = 0;\r
-    NtHdr->Pe32.FileHeader.NumberOfSections--;\r
-  } else {\r
-    Dir->VirtualAddress = RelocOffset;\r
-    CreateSectionHeader (".reloc", RelocOffset, CoffOffset - RelocOffset,\r
-            EFI_IMAGE_SCN_CNT_INITIALIZED_DATA\r
-            | EFI_IMAGE_SCN_MEM_DISCARDABLE\r
-            | EFI_IMAGE_SCN_MEM_READ);\r
-  }\r
-\r
-}\r
-\r
-VOID\r
-WriteDebug(\r
-  VOID\r
-  )\r
-{\r
-  UINT32                              Len;\r
-  UINT32                              DebugOffset;\r
-  EFI_IMAGE_OPTIONAL_HEADER_UNION     *NtHdr;\r
-  EFI_IMAGE_DATA_DIRECTORY            *DataDir;\r
-  EFI_IMAGE_DEBUG_DIRECTORY_ENTRY     *Dir;\r
-  EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY *Nb10;\r
-\r
-  Len = strlen(mInImageName) + 1;\r
-  DebugOffset = CoffOffset;\r
-\r
-  CoffOffset += sizeof(EFI_IMAGE_DEBUG_DIRECTORY_ENTRY)\r
-    + sizeof(EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY)\r
-    + Len;\r
-  CoffOffset = CoffAlign(CoffOffset);\r
-\r
-  CoffFile = realloc(CoffFile, CoffOffset);\r
-  memset(CoffFile + DebugOffset, 0, CoffOffset - DebugOffset);\r
-\r
-  Dir = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY*)(CoffFile + DebugOffset);\r
-  Dir->Type = EFI_IMAGE_DEBUG_TYPE_CODEVIEW;\r
-  Dir->SizeOfData = sizeof(EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY) + Len;\r
-  Dir->RVA = DebugOffset + sizeof(EFI_IMAGE_DEBUG_DIRECTORY_ENTRY);\r
-  Dir->FileOffset = DebugOffset + sizeof(EFI_IMAGE_DEBUG_DIRECTORY_ENTRY);\r
-\r
-  Nb10 = (EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY*)(Dir + 1);\r
-  Nb10->Signature = CODEVIEW_SIGNATURE_NB10;\r
-  strcpy ((char *)(Nb10 + 1), mInImageName);\r
-\r
-\r
-  NtHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)(CoffFile + NtHdrOffset);\r
-  DataDir = &NtHdr->Pe32.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG];\r
-  DataDir->VirtualAddress = DebugOffset;\r
-  DataDir->Size = CoffOffset - DebugOffset;\r
-  if (DataDir->Size == 0) {\r
-    // If no debug, null out the directory entry and don't add the .debug section\r
-    DataDir->VirtualAddress = 0;\r
-    NtHdr->Pe32.FileHeader.NumberOfSections--;\r
-  } else {\r
-    DataDir->VirtualAddress = DebugOffset;\r
-    CreateSectionHeader (".debug", DebugOffset, CoffOffset - DebugOffset,\r
-            EFI_IMAGE_SCN_CNT_INITIALIZED_DATA\r
-            | EFI_IMAGE_SCN_MEM_DISCARDABLE\r
-            | EFI_IMAGE_SCN_MEM_READ);\r
-\r
-  }\r
-}\r
-\r
-VOID\r
-ConvertElf (\r
-  UINT8  **FileBuffer,\r
-  UINT32 *FileLength\r
-  )\r
-{\r
-  EFI_IMAGE_OPTIONAL_HEADER_UNION *NtHdr;\r
-\r
-  //\r
-  // Check header, read section table.\r
-  //\r
-  Ehdr = (Elf32_Ehdr*)*FileBuffer;\r
-  if (!CheckElfHeader())\r
-    return;\r
-\r
-  VerboseMsg ("Check Efl Image Header");\r
-  //\r
-  // Compute sections new address.\r
-  //\r
-  \r
-  ScanSections();\r
-\r
-  VerboseMsg ("Compute sections new address.");\r
-\r
-  //\r
-  // Write and relocate sections.\r
-  //\r
-  WriteSections(IsTextShdr);\r
-  WriteSections(IsDataShdr);\r
-  WriteSections(IsHiiRsrcShdr);\r
-  VerboseMsg ("Write and relocate sections.");\r
-\r
-  //\r
-  // Translate and write relocations.\r
-  //\r
-  WriteRelocations();\r
-  VerboseMsg ("Translate and write relocations.");\r
-\r
-  //\r
-  // Write debug info.\r
-  //\r
-  WriteDebug();\r
-  VerboseMsg ("Write debug info.");\r
-\r
-  NtHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)(CoffFile + NtHdrOffset);\r
-  NtHdr->Pe32.OptionalHeader.SizeOfImage = CoffOffset;\r
-\r
-  //\r
-  // Replace.\r
-  //\r
-  free(*FileBuffer);\r
-  *FileBuffer = CoffFile;\r
-  *FileLength = CoffOffset;\r
-\r
-  //\r
-  // Free memory space\r
-  //\r
-  if (CoffSectionsOffset != NULL) {\r
-    free (CoffSectionsOffset);\r
-  }\r
-}\r
-\r
-\r
 EFI_IMAGE_OPTIONAL_HEADER_UNION *\r
 GetPeCoffHeader (\r
   void *Data\r
@@ -1537,7 +658,10 @@ PeCoffConvertImageToXip (
         SectionHeader->SizeOfRawData\r
         );\r
     }\r
-    SectionHeader->SizeOfRawData = SectionHeader->Misc.VirtualSize;\r
+    //\r
+    // Make the size of raw data in section header alignment.\r
+    //\r
+    SectionHeader->SizeOfRawData = (SectionHeader->Misc.VirtualSize + PeHdr->Pe32.OptionalHeader.FileAlignment - 1) & (~(PeHdr->Pe32.OptionalHeader.FileAlignment - 1));\r
     SectionHeader->PointerToRawData = SectionHeader->VirtualAddress;\r
   }\r
 \r
@@ -1941,7 +1065,6 @@ Returns:
   char                             *OutImageName;\r
   char                             *ModuleType;\r
   CHAR8                            *TimeStamp;\r
-  UINT32                           OutImageType;\r
   FILE                             *fpIn;\r
   FILE                             *fpOut;\r
   FILE                             *fpInOut;\r
@@ -1993,6 +1116,9 @@ Returns:
   FILE                             *ReportFile;\r
   CHAR8                            *ReportFileName;\r
   UINTN                            FileLen;\r
+  time_t                           InputFileTime;\r
+  time_t                           OutputFileTime;\r
+  struct stat                      Stat_Buf;\r
 \r
   SetUtilityName (UTILITY_NAME);\r
 \r
@@ -2005,7 +1131,6 @@ Returns:
   mInImageName      = NULL;\r
   OutImageName      = NULL;\r
   ModuleType        = NULL;\r
-  OutImageType      = FW_DUMMY_IMAGE;\r
   Type              = 0;\r
   Status            = STATUS_SUCCESS;\r
   FileBuffer        = NULL;\r
@@ -2038,6 +1163,8 @@ Returns:
   HiiSectionHeader       = NULL;\r
   NewBaseAddress         = 0;\r
   NegativeAddr           = FALSE;\r
+  InputFileTime          = 0;\r
+  OutputFileTime         = 0;\r
 \r
   if (argc == 1) {\r
     Error (NULL, 0, 1001, "Missing options", "No input options.");\r
@@ -2077,8 +1204,8 @@ Returns:
         goto Finish;\r
       }\r
       ModuleType = argv[1];\r
-      if (OutImageType != FW_TE_IMAGE) {\r
-        OutImageType = FW_EFI_IMAGE;\r
+      if (mOutImageType != FW_TE_IMAGE) {\r
+        mOutImageType = FW_EFI_IMAGE;\r
       }\r
       argc -= 2;\r
       argv += 2;\r
@@ -2086,49 +1213,49 @@ Returns:
     }\r
 \r
     if ((stricmp (argv[0], "-l") == 0) || (stricmp (argv[0], "--stripped") == 0)) {\r
-      OutImageType = FW_RELOC_STRIPEED_IMAGE;\r
+      mOutImageType = FW_RELOC_STRIPEED_IMAGE;\r
       argc --;\r
       argv ++;\r
       continue;\r
     }\r
 \r
     if ((stricmp (argv[0], "-c") == 0) || (stricmp (argv[0], "--acpi") == 0)) {\r
-      OutImageType = FW_ACPI_IMAGE;\r
+      mOutImageType = FW_ACPI_IMAGE;\r
       argc --;\r
       argv ++;\r
       continue;\r
     }\r
 \r
     if ((stricmp (argv[0], "-t") == 0) || (stricmp (argv[0], "--terse") == 0)) {\r
-      OutImageType = FW_TE_IMAGE;\r
+      mOutImageType = FW_TE_IMAGE;\r
       argc --;\r
       argv ++;\r
       continue;\r
     }\r
 \r
     if ((stricmp (argv[0], "-u") == 0) || (stricmp (argv[0], "--dump") == 0)) {\r
-      OutImageType = DUMP_TE_HEADER;\r
+      mOutImageType = DUMP_TE_HEADER;\r
       argc --;\r
       argv ++;\r
       continue;\r
     }\r
 \r
     if ((stricmp (argv[0], "-b") == 0) || (stricmp (argv[0], "--exe2bin") == 0)) {\r
-      OutImageType = FW_BIN_IMAGE;\r
+      mOutImageType = FW_BIN_IMAGE;\r
       argc --;\r
       argv ++;\r
       continue;\r
     }\r
 \r
     if ((stricmp (argv[0], "-z") == 0) || (stricmp (argv[0], "--zero") == 0)) {\r
-      OutImageType = FW_ZERO_DEBUG_IMAGE;\r
+      mOutImageType = FW_ZERO_DEBUG_IMAGE;\r
       argc --;\r
       argv ++;\r
       continue;\r
     }\r
 \r
     if ((stricmp (argv[0], "-s") == 0) || (stricmp (argv[0], "--stamp") == 0)) {\r
-      OutImageType = FW_SET_STAMP_IMAGE;\r
+      mOutImageType = FW_SET_STAMP_IMAGE;\r
       if (argv[1] == NULL || argv[1][0] == '-') {\r
         Error (NULL, 0, 1003, "Invalid option value", "time stamp is missing for -s option");\r
         goto Finish;\r
@@ -2161,14 +1288,14 @@ Returns:
     }\r
 \r
     if ((stricmp (argv[0], "-m") == 0) || (stricmp (argv[0], "--mcifile") == 0)) {\r
-      OutImageType = FW_MCI_IMAGE;\r
+      mOutImageType = FW_MCI_IMAGE;\r
       argc --;\r
       argv ++;\r
       continue;\r
     }\r
 \r
     if ((stricmp (argv[0], "-j") == 0) || (stricmp (argv[0], "--join") == 0)) {\r
-      OutImageType = FW_MERGE_IMAGE;\r
+      mOutImageType = FW_MERGE_IMAGE;\r
       argc --;\r
       argv ++;\r
       continue;\r
@@ -2197,7 +1324,7 @@ Returns:
         Error (NULL, 0, 1003, "Invalid option value", "%s = %s", argv[0], argv[1]);\r
         goto Finish;\r
       }\r
-      OutImageType = FW_REBASE_IMAGE;\r
+      mOutImageType = FW_REBASE_IMAGE;\r
       NewBaseAddress = (UINT64) Temp64;\r
       argc -= 2;\r
       argv += 2;\r
@@ -2216,7 +1343,7 @@ Returns:
         Error (NULL, 0, 1003, "Invalid option value", "%s = %s", argv[0], argv[1]);\r
         goto Finish;\r
       }\r
-      OutImageType = FW_SET_ADDRESS_IMAGE;\r
+      mOutImageType = FW_SET_ADDRESS_IMAGE;\r
       NewBaseAddress = (UINT64) Temp64;\r
       argc -= 2;\r
       argv += 2;\r
@@ -2279,14 +1406,14 @@ Returns:
     }\r
 \r
     if (stricmp (argv[0], "--hiipackage") == 0) {\r
-      OutImageType = FW_HII_PACKAGE_LIST_RCIMAGE;\r
+      mOutImageType = 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
+      mOutImageType = FW_HII_PACKAGE_LIST_BINIMAGE;\r
       argc --;\r
       argv ++;\r
       continue;\r
@@ -2331,7 +1458,7 @@ Returns:
 \r
   VerboseMsg ("%s tool start.", UTILITY_NAME);\r
 \r
-  if (OutImageType == FW_DUMMY_IMAGE) {\r
+  if (mOutImageType == FW_DUMMY_IMAGE) {\r
     Error (NULL, 0, 1001, "Missing option", "No create file action specified; pls specify -e, -c or -t option to create efi image, or acpi table or TeImage!");\r
     if (ReplaceFlag) {\r
       Error (NULL, 0, 1001, "Missing option", "-r option is not supported as the independent option. It can be used together with other create file option specified at the above.");\r
@@ -2350,7 +1477,7 @@ Returns:
   //\r
   // Combine MciBinary files to one file\r
   //\r
-  if ((OutImageType == FW_MERGE_IMAGE) && ReplaceFlag) {\r
+  if ((mOutImageType == FW_MERGE_IMAGE) && ReplaceFlag) {\r
     Error (NULL, 0, 1002, "Conflicting option", "-r replace option cannot be used with -j merge files option.");\r
     goto Finish;\r
   }\r
@@ -2358,12 +1485,12 @@ Returns:
   //\r
   // Combine HiiBinary packages to a single package list\r
   //\r
-  if ((OutImageType == FW_HII_PACKAGE_LIST_RCIMAGE) && ReplaceFlag) {\r
+  if ((mOutImageType == 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
+  if ((mOutImageType == 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
@@ -2377,7 +1504,7 @@ Returns:
   //\r
   // Action will be taken for the input file.\r
   //\r
-  switch (OutImageType) {\r
+  switch (mOutImageType) {\r
   case FW_EFI_IMAGE:\r
     VerboseMsg ("Create efi image on module type %s based on the input PE image.", ModuleType);\r
     break;\r
@@ -2434,6 +1561,14 @@ Returns:
   if (OutImageName != NULL) {\r
     fpOut = fopen (OutImageName, "rb");\r
     if (fpOut != NULL) {\r
+      //\r
+      // Get Output file time stamp\r
+      //\r
+      fstat(fileno (fpOut), &Stat_Buf);\r
+      OutputFileTime = Stat_Buf.st_mtime;\r
+      //\r
+      // Get Output file data\r
+      //\r
       OutputFileLength = _filelength (fileno (fpOut));\r
       OutputFileBuffer = malloc (OutputFileLength);\r
       if (OutputFileBuffer == NULL) {\r
@@ -2447,7 +1582,7 @@ Returns:
       fpOut = NULL;\r
     }\r
     VerboseMsg ("Output file name is %s", OutImageName);\r
-  } else if (!ReplaceFlag && OutImageType != DUMP_TE_HEADER) {\r
+  } else if (!ReplaceFlag && mOutImageType != DUMP_TE_HEADER) {\r
     Error (NULL, 0, 1001, "Missing option", "output file");\r
     goto Finish;\r
   }\r
@@ -2460,6 +1595,14 @@ Returns:
     Error (NULL, 0, 0001, "Error opening file", mInImageName);\r
     goto Finish;\r
   }\r
+  //\r
+  // Get Iutput file time stamp\r
+  //\r
+  fstat(fileno (fpIn), &Stat_Buf);\r
+  InputFileTime = Stat_Buf.st_mtime;\r
+  //\r
+  // Get Input file data\r
+  //\r
   InputFileLength = _filelength (fileno (fpIn));\r
   InputFileBuffer = malloc (InputFileLength);\r
   if (InputFileBuffer == NULL) {\r
@@ -2474,7 +1617,7 @@ Returns:
   //\r
   // Combine multi binary HII package files.\r
   //\r
-  if (OutImageType == FW_HII_PACKAGE_LIST_RCIMAGE || OutImageType == FW_HII_PACKAGE_LIST_BINIMAGE) {\r
+  if (mOutImageType == FW_HII_PACKAGE_LIST_RCIMAGE || mOutImageType == FW_HII_PACKAGE_LIST_BINIMAGE) {\r
     //\r
     // Open output file handle.\r
     //\r
@@ -2551,7 +1694,7 @@ Returns:
     //\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
+    if (mOutImageType == FW_HII_PACKAGE_LIST_BINIMAGE) {\r
       //\r
       // Create the resource section header\r
       //\r
@@ -2575,7 +1718,7 @@ Returns:
     //\r
     // write the hii package into the text package list rc file.\r
     //\r
-    if (OutImageType == FW_HII_PACKAGE_LIST_RCIMAGE) {\r
+    if (mOutImageType == FW_HII_PACKAGE_LIST_RCIMAGE) {\r
       for (Index = 0; gHiiPackageRCFileHeader[Index] != NULL; Index++) {\r
         fprintf (fpOut, "%s\n", gHiiPackageRCFileHeader[Index]);\r
       }\r
@@ -2610,7 +1753,7 @@ Returns:
   //\r
   // Combine MciBinary files to one file\r
   //\r
-  if (OutImageType == FW_MERGE_IMAGE) {\r
+  if (mOutImageType == FW_MERGE_IMAGE) {\r
     //\r
     // Open output file handle.\r
     //\r
@@ -2661,7 +1804,7 @@ Returns:
   //\r
   // Convert MicroCode.txt file to MicroCode.bin file\r
   //\r
-  if (OutImageType == FW_MCI_IMAGE) {\r
+  if (mOutImageType == FW_MCI_IMAGE) {\r
     fpIn = fopen (mInImageName, "r");\r
     if (fpIn == NULL) {\r
       Error (NULL, 0, 0001, "Error opening file", mInImageName);\r
@@ -2775,7 +1918,7 @@ Returns:
   //\r
   // Dump TeImage Header into output file.\r
   //\r
-  if (OutImageType == DUMP_TE_HEADER) {\r
+  if (mOutImageType == DUMP_TE_HEADER) {\r
     memcpy (&TEImageHeader, FileBuffer, sizeof (TEImageHeader));\r
     if (TEImageHeader.Signature != EFI_TE_IMAGE_HEADER_SIGNATURE) {\r
       Error (NULL, 0, 3000, "Invalid", "TE header signature of file %s is not correct.", mInImageName);\r
@@ -2834,12 +1977,12 @@ Returns:
   // Following code to convert dll to efi image or te image.\r
   // Get new image type\r
   //\r
-  if ((OutImageType == FW_EFI_IMAGE) || (OutImageType == FW_TE_IMAGE)) {\r
+  if ((mOutImageType == FW_EFI_IMAGE) || (mOutImageType == FW_TE_IMAGE)) {\r
     if (ModuleType == NULL) {\r
-      if (OutImageType == FW_EFI_IMAGE) {\r
+      if (mOutImageType == FW_EFI_IMAGE) {\r
         Error (NULL, 0, 1001, "Missing option", "EFI_FILETYPE");\r
         goto Finish;\r
-      } else if (OutImageType == FW_TE_IMAGE) {\r
+      } else if (mOutImageType == FW_TE_IMAGE) {\r
         //\r
         // Default TE Image Type is Boot service driver\r
         //\r
@@ -2887,11 +2030,14 @@ Returns:
   }\r
 \r
   //\r
-  // Convert EFL image to PeImage\r
+  // Convert ELF image to PeImage\r
   //\r
   if (IsElfHeader(FileBuffer)) {\r
-    VerboseMsg ("Convert the input ELF Image to Pe Image");\r
-    ConvertElf(&FileBuffer, &FileLength);\r
+    VerboseMsg ("Convert %s from ELF to PE/COFF.", mInImageName);\r
+    if (!ConvertElf(&FileBuffer, &FileLength)) {\r
+      Error (NULL, 0, 3000, "Invalid", "Unable to convert %s from ELF to PE/COFF.", mInImageName);\r
+      goto Finish;\r
+    }\r
   }\r
 \r
   //\r
@@ -2903,7 +2049,7 @@ Returns:
   //\r
   // Remove reloc section from PE or TE image\r
   //\r
-  if (OutImageType == FW_RELOC_STRIPEED_IMAGE) {\r
+  if (mOutImageType == FW_RELOC_STRIPEED_IMAGE) {\r
     //\r
     // Check TeImage\r
     //\r
@@ -3021,7 +2167,7 @@ Returns:
   //\r
   // Set new base address into image\r
   //\r
-  if (OutImageType == FW_REBASE_IMAGE || OutImageType == FW_SET_ADDRESS_IMAGE) {\r
+  if (mOutImageType == FW_REBASE_IMAGE || mOutImageType == FW_SET_ADDRESS_IMAGE) {\r
     if ((PeHdr->Pe32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) && (PeHdr->Pe32.FileHeader.Machine != IMAGE_FILE_MACHINE_IA64)) {\r
       if (NewBaseAddress >= 0x100000000ULL) {\r
         Error (NULL, 0, 3000, "Invalid", "New base address is larger than 4G for 32bit PE image");\r
@@ -3035,7 +2181,7 @@ Returns:
       //\r
       NewBaseAddress = (UINT64) (0 - NewBaseAddress);\r
     }\r
-    if (OutImageType == FW_REBASE_IMAGE) {\r
+    if (mOutImageType == FW_REBASE_IMAGE) {\r
       Status = RebaseImage (mInImageName, FileBuffer, NewBaseAddress);\r
     } else {\r
       Status = SetAddressToSectionHeader (mInImageName, FileBuffer, NewBaseAddress);\r
@@ -3058,7 +2204,7 @@ Returns:
   //\r
   // Extract bin data from Pe image.\r
   //\r
-  if (OutImageType == FW_BIN_IMAGE) {\r
+  if (mOutImageType == FW_BIN_IMAGE) {\r
     if (FileLength < PeHdr->Pe32.OptionalHeader.SizeOfHeaders) {\r
       Error (NULL, 0, 3000, "Invalid", "FileSize of %s is not a legal size.", mInImageName);\r
       goto Finish;\r
@@ -3067,7 +2213,7 @@ Returns:
     // Output bin data from exe file\r
     //\r
     FileLength = FileLength - PeHdr->Pe32.OptionalHeader.SizeOfHeaders;\r
-    memcpy (FileBuffer, FileBuffer + PeHdr->Pe32.OptionalHeader.SizeOfHeaders, FileLength);\r
+    memmove (FileBuffer, FileBuffer + PeHdr->Pe32.OptionalHeader.SizeOfHeaders, FileLength);\r
     VerboseMsg ("the size of output file is %u bytes", (unsigned) FileLength);\r
     goto WriteFile;\r
   }\r
@@ -3075,7 +2221,7 @@ Returns:
   //\r
   // Zero Debug Information of Pe Image\r
   //\r
-  if (OutImageType == FW_ZERO_DEBUG_IMAGE) {\r
+  if (mOutImageType == FW_ZERO_DEBUG_IMAGE) {\r
     Status = ZeroDebugData (FileBuffer, TRUE);\r
     if (EFI_ERROR (Status)) {\r
       Error (NULL, 0, 3000, "Invalid", "Zero DebugData Error status is 0x%x", (int) Status);\r
@@ -3092,7 +2238,7 @@ Returns:
   //\r
   // Set Time Stamp of Pe Image\r
   //\r
-  if (OutImageType == FW_SET_STAMP_IMAGE) {\r
+  if (mOutImageType == FW_SET_STAMP_IMAGE) {\r
     Status = SetStamp (FileBuffer, TimeStamp);\r
     if (EFI_ERROR (Status)) {\r
       goto Finish;\r
@@ -3108,7 +2254,7 @@ Returns:
   //\r
   // Extract acpi data from pe image.\r
   //\r
-  if (OutImageType == FW_ACPI_IMAGE) {\r
+  if (mOutImageType == FW_ACPI_IMAGE) {\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
       if (strcmp ((char *)SectionHeader->Name, ".data") == 0 || strcmp ((char *)SectionHeader->Name, ".sdata") == 0) {\r
@@ -3129,7 +2275,7 @@ Returns:
         //\r
         // Output Apci data to file\r
         //\r
-        memcpy (FileBuffer, FileBuffer + SectionHeader->PointerToRawData, FileLength);\r
+        memmove (FileBuffer, FileBuffer + SectionHeader->PointerToRawData, FileLength);\r
         VerboseMsg ("the size of output file is %u bytes", (unsigned) FileLength);\r
         goto WriteFile;\r
       }\r
@@ -3168,8 +2314,6 @@ Returns:
 \r
   if (PeHdr->Pe32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
     Optional32 = (EFI_IMAGE_OPTIONAL_HEADER32 *)&PeHdr->Pe32.OptionalHeader;\r
-    Optional32->MajorLinkerVersion          = 0;\r
-    Optional32->MinorLinkerVersion          = 0;\r
     Optional32->MajorOperatingSystemVersion = 0;\r
     Optional32->MinorOperatingSystemVersion = 0;\r
     Optional32->MajorImageVersion           = 0;\r
@@ -3262,8 +2406,6 @@ Returns:
     }\r
   } else if (PeHdr->Pe32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) {\r
     Optional64 = (EFI_IMAGE_OPTIONAL_HEADER64 *)&PeHdr->Pe32.OptionalHeader;\r
-    Optional64->MajorLinkerVersion          = 0;\r
-    Optional64->MinorLinkerVersion          = 0;\r
     Optional64->MajorOperatingSystemVersion = 0;\r
     Optional64->MinorOperatingSystemVersion = 0;\r
     Optional64->MajorImageVersion           = 0;\r
@@ -3440,7 +2582,7 @@ Returns:
   //\r
   ZeroDebugData (FileBuffer, FALSE);\r
 \r
-  if (OutImageType == FW_TE_IMAGE) {\r
+  if (mOutImageType == FW_TE_IMAGE) {\r
     if ((PeHdr->Pe32.FileHeader.NumberOfSections &~0xFF) || (Type &~0xFF)) {\r
       //\r
       // Pack the subsystem and NumberOfSections into 1 byte. Make sure they fit both.\r
@@ -3463,10 +2605,31 @@ Returns:
     // Update Image to TeImage\r
     //\r
     FileLength = FileLength - TEImageHeader.StrippedSize;\r
-    memcpy (FileBuffer + sizeof (EFI_TE_IMAGE_HEADER), FileBuffer + TEImageHeader.StrippedSize, FileLength);\r
+    memmove (FileBuffer + sizeof (EFI_TE_IMAGE_HEADER), FileBuffer + TEImageHeader.StrippedSize, FileLength);\r
     FileLength = FileLength + sizeof (EFI_TE_IMAGE_HEADER);\r
     memcpy (FileBuffer, &TEImageHeader, sizeof (EFI_TE_IMAGE_HEADER));\r
     VerboseMsg ("the size of output file is %u bytes", (unsigned) (FileLength));\r
+  } else {\r
+\r
+    //\r
+    // Following codes are to fix the objcopy's issue:\r
+    // objcopy in binutil 2.50.18 will set PE image's charactices to "RELOC_STRIPPED" if image has no ".reloc" section\r
+    // It cause issue for EFI image which has no ".reloc" sections.\r
+    // Following codes will be removed when objcopy in binutil fix this problem for PE image.\r
+    //\r
+    if ((PeHdr->Pe32.FileHeader.Characteristics & EFI_IMAGE_FILE_RELOCS_STRIPPED) != 0) {\r
+      if (PeHdr->Pe32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
+        Optional32 = (EFI_IMAGE_OPTIONAL_HEADER32 *)&PeHdr->Pe32.OptionalHeader;\r
+        if (Optional32->ImageBase == 0) {\r
+          PeHdr->Pe32.FileHeader.Characteristics &= ~EFI_IMAGE_FILE_RELOCS_STRIPPED;\r
+        }\r
+      } else if (PeHdr->Pe32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) {\r
+        Optional64 = (EFI_IMAGE_OPTIONAL_HEADER64 *)&PeHdr->Pe32.OptionalHeader;\r
+        if (Optional64->ImageBase == 0) {\r
+          PeHdr->Pe32.FileHeader.Characteristics &= ~EFI_IMAGE_FILE_RELOCS_STRIPPED;\r
+        }\r
+      }\r
+    }\r
   }\r
 \r
 WriteFile:\r
@@ -3487,7 +2650,10 @@ WriteFile:
       VerboseMsg ("the size of output file is %u bytes", (unsigned) FileLength);\r
     }\r
   } else {\r
-    if ((FileLength != OutputFileLength) || (memcmp (FileBuffer, OutputFileBuffer, FileLength) != 0)) {\r
+    if ((OutputFileTime < InputFileTime) || (FileLength != OutputFileLength) || (memcmp (FileBuffer, OutputFileBuffer, FileLength) != 0)) {\r
+      //\r
+      // Update File when File is changed or File is old.\r
+      //\r
       fpOut = fopen (OutImageName, "wb");\r
       if (fpOut == NULL) {\r
         Error (NULL, 0, 0001, "Error opening output file", OutImageName);\r