/*++\r
\r
-Copyright (c) 2004, Intel Corporation \r
+Copyright (c) 2004 - 2007, Intel Corporation \r
All rights reserved. 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
\r
#include "WinNtInclude.h"\r
\r
+//\r
+// List of OS and CPU which support ELF to PE conversion\r
+//\r
+#if defined(linux)
+#if defined(i386)
+#define HAVE_ELF
+#endif
+#endif
+
#ifndef __GNUC__\r
#include <windows.h>\r
#endif\r
#include <stdlib.h>\r
#include <string.h>\r
#include <time.h>\r
+
+#ifdef HAVE_ELF
+#include <elf.h>
+#endif
\r
#include <Common/UefiBaseTypes.h>\r
#include <Common/EfiImage.h>\r
#include "CommonLib.h"\r
#include "EfiUtilityMsgs.c"\r
\r
-#define UTILITY_NAME "FwImage"\r
+//\r
+// Version of this utility\r
+//\r
+#define UTILITY_NAME "FwImage"\r
+#define UTILITY_MAJOR_VERSION 1\r
+#define UTILITY_MINOR_VERSION 0\r
\r
#ifdef __GNUC__\r
typedef unsigned long ULONG;\r
typedef unsigned short USHORT;\r
#endif\r
\r
+PUCHAR InImageName;\r
+\r
+static\r
+void\r
+Version (\r
+ VOID\r
+ )\r
+{\r
+ printf ("%s v%d.%d -EDK Utility for Converting a pe32+ image to an FW image type.\n", UTILITY_NAME, UTILITY_MAJOR_VERSION, UTILITY_MINOR_VERSION);\r
+ printf ("Copyright (c) 1999-2006 Intel Corporation. All rights reserved.\n");\r
+}\r
+\r
+\r
VOID\r
Usage (\r
VOID\r
)\r
{\r
- printf ("Usage: " UTILITY_NAME " {-t time-date} [BASE|SEC|PEI_CORE|PEIM|DXE_CORE|DXE_DRIVER|DXE_RUNTIME_DRIVER|DXE_SAL_DRIVER|DXE_SMM_DRIVER|TOOL|UEFI_DRIVER|UEFI_APPLICATION|USER_DEFINED] peimage [outimage]");\r
+ Version();\r
+ printf ("\nUsage: " UTILITY_NAME " {-t time-date} {-h|--help|-?|/?|-V|--version} \n\\r
+ [BASE|SEC|PEI_CORE|PEIM|DXE_CORE|DXE_DRIVER|DXE_RUNTIME_DRIVER|\n\\r
+ DXE_SAL_DRIVER|DXE_SMM_DRIVER|TOOL|UEFI_DRIVER|UEFI_APPLICATION|\n\\r
+ USER_DEFINED] peimage [outimage]\n");\r
}\r
\r
static\r
return STATUS_SUCCESS;\r
}\r
\r
+#ifdef HAVE_ELF
+INTN
+IsElfHeader(
+ UINT8 *FileBuffer
+)
+{
+ return (FileBuffer[EI_MAG0] == ELFMAG0
+ && FileBuffer[EI_MAG1] == ELFMAG1
+ && FileBuffer[EI_MAG2] == ELFMAG2
+ && FileBuffer[EI_MAG3] == ELFMAG3);
+}
+
+typedef Elf32_Shdr Elf_Shdr;
+typedef Elf32_Ehdr Elf_Ehdr;
+typedef Elf32_Rel Elf_Rel;
+typedef Elf32_Sym Elf_Sym;
+#define ELFCLASS ELFCLASS32
+#define ELF_R_TYPE(r) ELF32_R_TYPE(r)
+#define ELF_R_SYM(r) ELF32_R_SYM(r)
+
+//
+// Well known ELF structures.
+//
+Elf_Ehdr *Ehdr;
+Elf_Shdr *ShdrBase;
+
+//
+// PE section alignment.
+//
+const UINT32 CoffAlignment = 0x20;
+const UINT32 CoffNbrSections = 4;
+
+//
+// Current offset in coff file.
+//
+UINT32 CoffOffset;
+
+//
+// Result Coff file in memory.
+//
+UINT8 *CoffFile;
+
+//
+// Offset in Coff file of headers and sections.
+//
+UINT32 NtHdrOffset;
+UINT32 TableOffset;
+UINT32 TextOffset;
+UINT32 DataOffset;
+UINT32 RelocOffset;
+
+//
+// ELF sections to offset in Coff file.
+//
+UINT32 *CoffSectionsOffset;
+
+EFI_IMAGE_BASE_RELOCATION *CoffBaseRel;
+UINT16 *CoffEntryRel;
+
+UINT32
+CoffAlign(
+ UINT32 Offset
+ )
+{
+ return (Offset + CoffAlignment - 1) & ~(CoffAlignment - 1);
+}
+
+Elf_Shdr *
+GetShdrByIndex(
+ UINT32 Num
+ )
+{
+ if (Num >= Ehdr->e_shnum)
+ return NULL;
+ return (Elf_Shdr*)((UINT8*)ShdrBase + Num * Ehdr->e_shentsize);
+}
+
+INTN
+CheckElfHeader(
+ VOID
+ )
+{\r
+ //
+ // Note: Magic has already been tested.
+ //
+ if (Ehdr->e_ident[EI_CLASS] != ELFCLASS)
+ return 0;
+ if (Ehdr->e_ident[EI_DATA] != ELFDATA2LSB)
+ return 0;
+ if (Ehdr->e_type != ET_EXEC)
+ return 0;
+ if (Ehdr->e_machine != EM_386)
+ return 0;
+ if (Ehdr->e_version != EV_CURRENT)
+ return 0;
+\r
+ //\r
+ // Find the section header table\r
+ //
+ ShdrBase = (Elf_Shdr *)((UINT8 *)Ehdr + Ehdr->e_shoff);
+
+ CoffSectionsOffset = (UINT32 *)malloc(Ehdr->e_shnum * sizeof (UINT32));\r
+
+ memset(CoffSectionsOffset, 0, Ehdr->e_shnum * sizeof(UINT32));\r
+ return 1;
+}
+
+int
+IsTextShdr(
+ Elf_Shdr *Shdr
+ )
+{
+ return (Shdr->sh_flags & (SHF_WRITE | SHF_ALLOC)) == SHF_ALLOC;
+}
+\r
+int
+IsDataShdr(
+ Elf_Shdr *Shdr
+ )
+{
+ return (Shdr->sh_flags & (SHF_WRITE | SHF_ALLOC)) == (SHF_ALLOC | SHF_WRITE);
+}
+
+void
+CreateSectionHeader(
+ const char *Name,
+ UINT32 Offset,
+ UINT32 Size,
+ UINT32 Flags
+ )
+{
+ EFI_IMAGE_SECTION_HEADER *Hdr;
+ Hdr = (EFI_IMAGE_SECTION_HEADER*)(CoffFile + TableOffset);
+
+ strcpy(Hdr->Name, Name);
+ Hdr->Misc.VirtualSize = Size;
+ Hdr->VirtualAddress = Offset;
+ Hdr->SizeOfRawData = Size;
+ Hdr->PointerToRawData = Offset;
+ Hdr->PointerToRelocations = 0;
+ Hdr->PointerToLinenumbers = 0;
+ Hdr->NumberOfRelocations = 0;
+ Hdr->NumberOfLinenumbers = 0;
+ Hdr->Characteristics = Flags;
+
+ TableOffset += sizeof (EFI_IMAGE_SECTION_HEADER);
+}
+
+void
+ScanSections(
+ VOID
+ )
+{
+ UINT32 i;
+ EFI_IMAGE_DOS_HEADER *DosHdr;
+ EFI_IMAGE_NT_HEADERS *NtHdr;
+ UINT32 CoffEntry = 0;
+
+ CoffOffset = 0;
+
+ //
+ // Coff file start with a DOS header.
+ //
+ CoffOffset = sizeof(EFI_IMAGE_DOS_HEADER) + 0x40;
+ NtHdrOffset = CoffOffset;
+ CoffOffset += sizeof(EFI_IMAGE_NT_HEADERS);
+ TableOffset = CoffOffset;
+ CoffOffset += CoffNbrSections * sizeof(EFI_IMAGE_SECTION_HEADER);
+
+ //
+ // First text sections.
+ //
+ CoffOffset = CoffAlign(CoffOffset);
+ TextOffset = CoffOffset;
+ for (i = 0; i < Ehdr->e_shnum; i++) {
+ Elf_Shdr *shdr = GetShdrByIndex(i);
+ if (IsTextShdr(shdr)) {\r
+ //\r
+ // Align the coff offset\r
+ // \r
+ CoffOffset = (CoffOffset + shdr->sh_addralign - 1) & ~(shdr->sh_addralign - 1);\r
+ /* Relocate entry. */
+ if ((Ehdr->e_entry >= shdr->sh_addr) && \r
+ (Ehdr->e_entry < shdr->sh_addr + shdr->sh_size)) {
+ CoffEntry = CoffOffset + Ehdr->e_entry - shdr->sh_addr;
+ }
+ CoffSectionsOffset[i] = CoffOffset;\r
+ CoffOffset += shdr->sh_size;
+ }\r
+ }\r
+ CoffOffset = CoffAlign(CoffOffset);
+\r
+ //
+ // Then data sections.
+ //
+ DataOffset = CoffOffset;
+ for (i = 0; i < Ehdr->e_shnum; i++) {
+ Elf_Shdr *shdr = GetShdrByIndex(i);
+ if (IsDataShdr(shdr)) {
+ CoffSectionsOffset[i] = CoffOffset;
+ CoffOffset += shdr->sh_size;
+ }
+ }
+ CoffOffset = CoffAlign(CoffOffset);
+
+ RelocOffset = CoffOffset;
+
+ //
+ // Allocate base Coff file. Will be expanded later for relocations.
+ //
+ CoffFile = (UINT8 *)malloc(CoffOffset);
+ memset(CoffFile, 0, CoffOffset);
+
+ //
+ // Fill headers.
+ //
+ DosHdr = (EFI_IMAGE_DOS_HEADER *)CoffFile;
+ DosHdr->e_magic = EFI_IMAGE_DOS_SIGNATURE;
+ DosHdr->e_lfanew = NtHdrOffset;
+
+ NtHdr = (EFI_IMAGE_NT_HEADERS*)(CoffFile + NtHdrOffset);
+
+ NtHdr->Signature = EFI_IMAGE_NT_SIGNATURE;
+
+ NtHdr->FileHeader.Machine = EFI_IMAGE_MACHINE_IA32;
+ NtHdr->FileHeader.NumberOfSections = CoffNbrSections;
+ NtHdr->FileHeader.TimeDateStamp = time(NULL);
+ NtHdr->FileHeader.PointerToSymbolTable = 0;
+ NtHdr->FileHeader.NumberOfSymbols = 0;
+ NtHdr->FileHeader.SizeOfOptionalHeader = sizeof(NtHdr->OptionalHeader);
+ NtHdr->FileHeader.Characteristics = EFI_IMAGE_FILE_EXECUTABLE_IMAGE
+ | EFI_IMAGE_FILE_LINE_NUMS_STRIPPED
+ | EFI_IMAGE_FILE_LOCAL_SYMS_STRIPPED
+ | EFI_IMAGE_FILE_32BIT_MACHINE;
+
+ NtHdr->OptionalHeader.Magic = EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC;
+ NtHdr->OptionalHeader.SizeOfCode = DataOffset - TextOffset;
+ NtHdr->OptionalHeader.SizeOfInitializedData = RelocOffset - DataOffset;
+ NtHdr->OptionalHeader.SizeOfUninitializedData = 0;
+ NtHdr->OptionalHeader.AddressOfEntryPoint = CoffEntry;
+ NtHdr->OptionalHeader.BaseOfCode = TextOffset;
+
+ NtHdr->OptionalHeader.BaseOfData = DataOffset;
+ NtHdr->OptionalHeader.ImageBase = 0;
+ NtHdr->OptionalHeader.SectionAlignment = CoffAlignment;
+ NtHdr->OptionalHeader.FileAlignment = CoffAlignment;
+ NtHdr->OptionalHeader.SizeOfImage = 0;
+
+ NtHdr->OptionalHeader.SizeOfHeaders = TextOffset;
+ NtHdr->OptionalHeader.NumberOfRvaAndSizes = EFI_IMAGE_NUMBER_OF_DIRECTORY_ENTRIES;
+
+ //
+ // Section headers.
+ //
+ CreateSectionHeader (".text", TextOffset, DataOffset - TextOffset,
+ EFI_IMAGE_SCN_CNT_CODE
+ | EFI_IMAGE_SCN_MEM_EXECUTE
+ | EFI_IMAGE_SCN_MEM_READ);
+ CreateSectionHeader (".data", DataOffset, RelocOffset - DataOffset,
+ EFI_IMAGE_SCN_CNT_INITIALIZED_DATA
+ | EFI_IMAGE_SCN_MEM_WRITE
+ | EFI_IMAGE_SCN_MEM_READ);
+}
+
+void
+WriteSections(
+ int (*Filter)(Elf_Shdr *)
+ )
+{
+ UINT32 Idx;
+
+ //
+ // First: copy sections.
+ //
+ for (Idx = 0; Idx < Ehdr->e_shnum; Idx++) {
+ Elf_Shdr *Shdr = GetShdrByIndex(Idx);
+ if ((*Filter)(Shdr)) {
+ switch (Shdr->sh_type) {
+ case SHT_PROGBITS:
+ /* Copy. */
+ memcpy(CoffFile + CoffSectionsOffset[Idx],
+ (UINT8*)Ehdr + Shdr->sh_offset,
+ Shdr->sh_size);
+ break;
+ case SHT_NOBITS:
+ memset(CoffFile + CoffSectionsOffset[Idx], 0, Shdr->sh_size);
+ break;
+ default:
+ Error (NULL, 0, 0, InImageName, "unhandle section type %x",
+ (UINTN)Shdr->sh_type);
+ }
+ }
+ }
+
+ //
+ // Second: apply relocations.
+ //
+ for (Idx = 0; Idx < Ehdr->e_shnum; Idx++) {
+ Elf_Shdr *RelShdr = GetShdrByIndex(Idx);
+ if (RelShdr->sh_type != SHT_REL)
+ continue;
+ Elf_Shdr *SecShdr = GetShdrByIndex(RelShdr->sh_info);
+ UINT32 SecOffset = CoffSectionsOffset[RelShdr->sh_info];
+ if (RelShdr->sh_type == SHT_REL && (*Filter)(SecShdr)) {
+ UINT32 RelIdx;
+ Elf_Shdr *SymtabShdr = GetShdrByIndex(RelShdr->sh_link);
+ UINT8 *Symtab = (UINT8*)Ehdr + SymtabShdr->sh_offset;
+
+ for (RelIdx = 0; RelIdx < RelShdr->sh_size; RelIdx += RelShdr->sh_entsize) {
+ Elf_Rel *Rel = (Elf_Rel *)((UINT8*)Ehdr + RelShdr->sh_offset + RelIdx);
+ Elf_Sym *Sym = (Elf_Sym *)
+ (Symtab + ELF_R_SYM(Rel->r_info) * SymtabShdr->sh_entsize);
+ Elf_Shdr *SymShdr;
+ UINT8 *Targ;
+
+ if (Sym->st_shndx == SHN_UNDEF
+ || Sym->st_shndx == SHN_ABS
+ || Sym->st_shndx > Ehdr->e_shnum) {
+ Error (NULL, 0, 0, InImageName, "bad symbol definition");
+ }
+ SymShdr = GetShdrByIndex(Sym->st_shndx);
+
+ //
+ // Note: r_offset in a memory address.
+ // Convert it to a pointer in the coff file.
+ //
+ Targ = CoffFile + SecOffset + (Rel->r_offset - SecShdr->sh_addr);
+
+ switch (ELF_R_TYPE(Rel->r_info)) {
+ case R_386_NONE:
+ break;
+ case R_386_32:
+ //
+ // Absolute relocation.
+ //
+ *(UINT32 *)Targ = *(UINT32 *)Targ - SymShdr->sh_addr
+ + CoffSectionsOffset[Sym->st_shndx];
+ break;
+ case R_386_PC32:
+ //
+ // Relative relocation: Symbol - Ip + Addend
+ //
+ *(UINT32 *)Targ = *(UINT32 *)Targ
+ + (CoffSectionsOffset[Sym->st_shndx] - SymShdr->sh_addr)
+ - (SecOffset - SecShdr->sh_addr);
+ break;
+ default:
+ Error (NULL, 0, 0, InImageName, "unhandled relocation type %x",
+ ELF_R_TYPE(Rel->r_info));
+ }
+ }
+ }
+ }
+}
+
+void
+CoffAddFixupEntry(
+ UINT16 Val
+ )
+{
+ *CoffEntryRel = Val;
+ CoffEntryRel++;
+ CoffBaseRel->SizeOfBlock += 2;
+ CoffOffset += 2;
+}
+
+void
+CoffAddFixup(
+ UINT32 Offset,
+ UINT8 Type
+ )
+{
+ if (CoffBaseRel == NULL
+ || CoffBaseRel->VirtualAddress != (Offset & ~0xfff)) {
+ if (CoffBaseRel != NULL) {
+ //
+ // Add a null entry (is it required ?)
+ //
+ CoffAddFixupEntry (0);
+ //
+ // Pad for alignment.
+ //
+ if (CoffOffset % 4 != 0)
+ CoffAddFixupEntry (0);
+ }
+
+ CoffFile = realloc
+ (CoffFile,
+ CoffOffset + sizeof(EFI_IMAGE_BASE_RELOCATION) + 2*0x1000);
+ memset(CoffFile + CoffOffset, 0,
+ sizeof(EFI_IMAGE_BASE_RELOCATION) + 2*0x1000);
+
+ CoffBaseRel = (EFI_IMAGE_BASE_RELOCATION*)(CoffFile + CoffOffset);
+ CoffBaseRel->VirtualAddress = Offset & ~0xfff;
+ CoffBaseRel->SizeOfBlock = sizeof(EFI_IMAGE_BASE_RELOCATION);
+
+ CoffEntryRel = (UINT16 *)(CoffBaseRel + 1);
+ CoffOffset += sizeof(EFI_IMAGE_BASE_RELOCATION);
+ }
+
+ //
+ // Fill the entry.
+ //
+ CoffAddFixupEntry((Type << 12) | (Offset & 0xfff));
+}
+
+void
+WriteRelocations(
+ VOID
+ )
+{
+ UINT32 Idx;
+ EFI_IMAGE_NT_HEADERS *NtHdr;
+ EFI_IMAGE_DATA_DIRECTORY *Dir;
+
+ for (Idx = 0; Idx < Ehdr->e_shnum; Idx++) {
+ Elf_Shdr *RelShdr = GetShdrByIndex(Idx);
+ if (RelShdr->sh_type == SHT_REL) {
+ Elf_Shdr *SecShdr = GetShdrByIndex(RelShdr->sh_info);
+ if (IsTextShdr(SecShdr) || IsDataShdr(SecShdr)) {
+ UINT32 RelIdx;
+ for (RelIdx = 0; RelIdx < RelShdr->sh_size; RelIdx += RelShdr->sh_entsize) {
+ Elf_Rel *Rel = (Elf_Rel *)
+ ((UINT8*)Ehdr + RelShdr->sh_offset + RelIdx);
+ switch (ELF_R_TYPE(Rel->r_info)) {
+ case R_386_NONE:
+ case R_386_PC32:
+ break;
+ case R_386_32:
+ CoffAddFixup(CoffSectionsOffset[RelShdr->sh_info]
+ + (Rel->r_offset - SecShdr->sh_addr),
+ EFI_IMAGE_REL_BASED_HIGHLOW);
+ break;
+ default:
+ Error (NULL, 0, 0, InImageName, "unhandled relocation type %x",
+ ELF_R_TYPE(Rel->r_info));
+ }
+ }
+ }
+ }
+ }
+
+ //
+ // Pad by adding empty entries.
+ //
+ while (CoffOffset & (CoffAlignment - 1)) {
+ CoffAddFixupEntry(0);
+ }
+
+ CreateSectionHeader (".reloc", RelocOffset, CoffOffset - RelocOffset,
+ EFI_IMAGE_SCN_CNT_INITIALIZED_DATA
+ | EFI_IMAGE_SCN_MEM_DISCARDABLE
+ | EFI_IMAGE_SCN_MEM_READ);
+
+ NtHdr = (EFI_IMAGE_NT_HEADERS *)(CoffFile + NtHdrOffset);
+ Dir = &NtHdr->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC];
+ Dir->VirtualAddress = RelocOffset;
+ Dir->Size = CoffOffset - RelocOffset;
+}
+
+void
+WriteDebug(
+ VOID
+ )
+{
+ UINT32 Len = strlen(InImageName) + 1;
+ UINT32 DebugOffset = CoffOffset;
+ EFI_IMAGE_NT_HEADERS *NtHdr;
+ EFI_IMAGE_DATA_DIRECTORY *DataDir;
+ EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *Dir;
+ EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY *Nb10;
+
+ CoffOffset += sizeof(EFI_IMAGE_DEBUG_DIRECTORY_ENTRY)
+ + sizeof(EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY)
+ + Len;
+ CoffOffset = CoffAlign(CoffOffset);
+
+ CoffFile = realloc
+ (CoffFile, CoffOffset);
+ memset(CoffFile + DebugOffset, 0, CoffOffset - DebugOffset);
+
+ Dir = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY*)(CoffFile + DebugOffset);
+ Dir->Type = EFI_IMAGE_DEBUG_TYPE_CODEVIEW;
+ Dir->SizeOfData = sizeof(EFI_IMAGE_DEBUG_DIRECTORY_ENTRY) + Len;
+ Dir->RVA = DebugOffset + sizeof(EFI_IMAGE_DEBUG_DIRECTORY_ENTRY);
+ Dir->FileOffset = DebugOffset + sizeof(EFI_IMAGE_DEBUG_DIRECTORY_ENTRY);
+
+ Nb10 = (EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY*)(Dir + 1);
+ Nb10->Signature = CODEVIEW_SIGNATURE_NB10;
+ strcpy ((PUCHAR)(Nb10 + 1), InImageName);
+
+ CreateSectionHeader (".debug", DebugOffset, CoffOffset - DebugOffset,
+ EFI_IMAGE_SCN_CNT_INITIALIZED_DATA
+ | EFI_IMAGE_SCN_MEM_DISCARDABLE
+ | EFI_IMAGE_SCN_MEM_READ);
+
+ NtHdr = (EFI_IMAGE_NT_HEADERS *)(CoffFile + NtHdrOffset);
+ DataDir = &NtHdr->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG];
+ DataDir->VirtualAddress = DebugOffset;
+ DataDir->Size = CoffOffset - DebugOffset;
+}
+
+void
+ConvertElf (
+ UINT8 **FileBuffer,
+ UINTN *FileLength
+ )
+{
+ EFI_IMAGE_NT_HEADERS *NtHdr;
+
+ //
+ // Check header, read section table.
+ //
+ Ehdr = (Elf32_Ehdr*)*FileBuffer;
+ if (!CheckElfHeader())
+ return;
+
+ //
+ // Compute sections new address.
+ //
+ ScanSections();
+
+ //
+ // Write and relocate sections.
+ //
+ WriteSections(IsTextShdr);
+ WriteSections(IsDataShdr);
+
+ //
+ // Translate and write relocations.
+ //
+ WriteRelocations();
+
+ //
+ // Write debug info.
+ //
+ WriteDebug();
+
+ NtHdr = (EFI_IMAGE_NT_HEADERS *)(CoffFile + NtHdrOffset);
+ NtHdr->OptionalHeader.SizeOfImage = CoffOffset;
+
+ //
+ // Replace.
+ //
+ free(*FileBuffer);
+ *FileBuffer = CoffFile;
+ *FileLength = CoffOffset;
+}
+#endif // HAVE_ELF
+
int\r
main (\r
int argc,\r
TimeStamp = 0;\r
TimeStampPresent = FALSE;\r
\r
+ if (argc == 1) {\r
+ Usage();\r
+ return STATUS_ERROR;\r
+ }\r
+ \r
+ if ((strcmp(argv[1], "-h") == 0) || (strcmp(argv[1], "--help") == 0) ||\r
+ (strcmp(argv[1], "-?") == 0) || (strcmp(argv[1], "/?") == 0)) {\r
+ Usage();\r
+ return STATUS_ERROR;\r
+ }\r
+ \r
+ if ((strcmp(argv[1], "-V") == 0) || (strcmp(argv[1], "--version") == 0)) {\r
+ Version();\r
+ return STATUS_ERROR;\r
+ }\r
+ \r
//\r
// Look for -t time-date option first. If the time is "0", then\r
// skip it.\r
return STATUS_ERROR;\r
}\r
\r
+ InImageName = argv[2];\r
+\r
if (argc == 4) {\r
OutImageName = argv[3];\r
}\r
//\r
// open source file\r
//\r
- fpIn = fopen (argv[2], "rb");\r
+ fpIn = fopen (InImageName, "rb");\r
if (!fpIn) {\r
- Error (NULL, 0, 0, argv[2], "failed to open input file for reading");\r
+ Error (NULL, 0, 0, InImageName, "failed to open input file for reading");\r
return STATUS_ERROR;\r
}\r
\r
FReadFile (fpIn, (VOID **)&FileBuffer, &FileLength);\r
\r
+#ifdef HAVE_ELF
+ if (IsElfHeader(FileBuffer)) {
+ ConvertElf(&FileBuffer, &FileLength);
+ }
+#endif
//\r
// Read the dos & pe hdrs of the image\r
//\r
DosHdr = (EFI_IMAGE_DOS_HEADER *)FileBuffer;\r
if (DosHdr->e_magic != EFI_IMAGE_DOS_SIGNATURE) {\r
- Error (NULL, 0, 0, argv[2], "DOS header signature not found in source image");\r
+ Error (NULL, 0, 0, InImageName, "DOS header signature not found in source image");\r
fclose (fpIn);\r
return STATUS_ERROR;\r
}\r
\r
PeHdr = (EFI_IMAGE_NT_HEADERS *)(FileBuffer + DosHdr->e_lfanew);\r
if (PeHdr->Signature != EFI_IMAGE_NT_SIGNATURE) {\r
- Error (NULL, 0, 0, argv[2], "PE header signature not found in source image");\r
+ Error (NULL, 0, 0, InImageName, "PE header signature not found in source image");\r
fclose (fpIn);\r
return STATUS_ERROR;\r
}\r
//\r
// open output file\r
//\r
- strcpy (outname, argv[2]);\r
+ strcpy (outname, InImageName);\r
pe = NULL;\r
for (p = outname; *p; p++) {\r
if (*p == '.') {\r
}\r
\r
//\r
- // Path the PE header\r
+ // Patch the PE header\r
//\r
PeHdr->OptionalHeader.Subsystem = (USHORT) Type;\r
if (TimeStampPresent) {\r