//\r
// List of OS and CPU which support ELF to PE conversion\r
//\r
-#if defined(linux)
-#if defined (__i386__) || defined(__x86_64__)
-#define HAVE_ELF
-#endif
-#endif
-
+#if defined(linux)\r
+#if defined (__i386__) || defined(__x86_64__)\r
+#define HAVE_ELF\r
+#endif\r
+#endif\r
+\r
#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
+#ifdef HAVE_ELF\r
+#include <elf.h>\r
+#endif\r
\r
#include <Common/UefiBaseTypes.h>\r
#include <IndustryStandard/PeImage.h>\r
IN CHAR8 *TimeStamp\r
);\r
\r
+STATIC \r
+STATUS\r
+MicrocodeReadData (\r
+ FILE *InFptr,\r
+ UINTN *Data\r
+ );\r
+\r
STATIC\r
VOID\r
Version (\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 = NULL;
-//
-// ELF sections to offset in Coff file.
-//
+#ifdef HAVE_ELF\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
+#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
+//\r
+// Well known ELF structures.\r
+//\r
+Elf_Ehdr *Ehdr;\r
+Elf_Shdr *ShdrBase;\r
+\r
+//\r
+// PE section alignment.\r
+//\r
+const UINT32 CoffAlignment = 0x20;\r
+const UINT32 CoffNbrSections = 4;\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
-
-//
-// Offset in Coff file of headers and sections.
-//
-UINT32 NtHdrOffset;
-UINT32 TableOffset;
-UINT32 TextOffset;
-UINT32 DataOffset;
-UINT32 RelocOffset;
-
-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
+//\r
+// Offset in Coff file of headers and sections.\r
+//\r
+UINT32 NtHdrOffset;\r
+UINT32 TableOffset;\r
+UINT32 TextOffset;\r
+UINT32 DataOffset;\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
- //
- // 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;
+ 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
+ return 0;\r
+ if (Ehdr->e_ident[EI_DATA] != ELFDATA2LSB)\r
+ return 0;\r
+ if (Ehdr->e_type != ET_EXEC)\r
+ return 0;\r
+ if (Ehdr->e_machine != EM_386)\r
+ return 0;\r
+ if (Ehdr->e_version != EV_CURRENT)\r
+ return 0;\r
\r
//\r
// Find the section header table\r
- //
- ShdrBase = (Elf_Shdr *)((UINT8 *)Ehdr + Ehdr->e_shoff);
-
+ // \r
+ ShdrBase = (Elf_Shdr *)((UINT8 *)Ehdr + Ehdr->e_shoff);\r
+\r
CoffSectionsOffset = (UINT32 *)malloc(Ehdr->e_shnum * sizeof (UINT32));\r
-
+\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 CHAR8 *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);
+ 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
+IsDataShdr(\r
+ Elf_Shdr *Shdr\r
+ )\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(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
+ScanSections(\r
+ VOID\r
+ )\r
+{\r
+ UINT32 i;\r
+ EFI_IMAGE_DOS_HEADER *DosHdr;\r
+ EFI_IMAGE_NT_HEADERS *NtHdr;\r
+ UINT32 CoffEntry = 0;\r
+\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
+ CoffOffset += sizeof(EFI_IMAGE_NT_HEADERS);\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
//\r
// Align the coff offset to meet with the alignment requirement of section\r
CoffOffset = (CoffOffset + shdr->sh_addralign - 1) & ~(shdr->sh_addralign - 1);\r
}\r
\r
- /* Relocate entry. */
+ /* Relocate entry. */\r
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;
- }
+ (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;
+ CoffOffset += shdr->sh_size;\r
}\r
}\r
- CoffOffset = CoffAlign(CoffOffset);
-\r
- //
- // Then data sections.
- //
- DataOffset = CoffOffset;
- for (i = 0; i < Ehdr->e_shnum; i++) {
- Elf_Shdr *shdr = GetShdrByIndex(i);
+ CoffOffset = CoffAlign(CoffOffset);\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
//\r
// Align the coff offset to meet with the alignment requirement of section\r
// \r
if ((shdr->sh_addralign != 0) && (shdr->sh_addralign != 1)) {\r
CoffOffset = (CoffOffset + shdr->sh_addralign - 1) & ~(shdr->sh_addralign - 1);\r
- }
+ }\r
\r
- 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;
+ CoffSectionsOffset[i] = CoffOffset;\r
+ CoffOffset += shdr->sh_size;\r
+ }\r
+ }\r
+ CoffOffset = CoffAlign(CoffOffset);\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_NT_HEADERS*)(CoffFile + NtHdrOffset);\r
+\r
+ NtHdr->Signature = EFI_IMAGE_NT_SIGNATURE;\r
+\r
+ NtHdr->FileHeader.Machine = EFI_IMAGE_MACHINE_IA32;\r
+ NtHdr->FileHeader.NumberOfSections = CoffNbrSections;\r
+ NtHdr->FileHeader.TimeDateStamp = time(NULL);\r
+ NtHdr->FileHeader.PointerToSymbolTable = 0;\r
+ NtHdr->FileHeader.NumberOfSymbols = 0;\r
+ NtHdr->FileHeader.SizeOfOptionalHeader = sizeof(NtHdr->OptionalHeader);\r
+ NtHdr->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->OptionalHeader.Magic = EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC;\r
+ NtHdr->OptionalHeader.SizeOfCode = DataOffset - TextOffset;\r
+ NtHdr->OptionalHeader.SizeOfInitializedData = RelocOffset - DataOffset;\r
+ NtHdr->OptionalHeader.SizeOfUninitializedData = 0;\r
+ NtHdr->OptionalHeader.AddressOfEntryPoint = CoffEntry;\r
+ NtHdr->OptionalHeader.BaseOfCode = TextOffset;\r
+\r
+ NtHdr->OptionalHeader.BaseOfData = DataOffset;\r
+ NtHdr->OptionalHeader.ImageBase = 0;\r
+ NtHdr->OptionalHeader.SectionAlignment = CoffAlignment;\r
+ NtHdr->OptionalHeader.FileAlignment = CoffAlignment;\r
+ NtHdr->OptionalHeader.SizeOfImage = 0;\r
+\r
+ NtHdr->OptionalHeader.SizeOfHeaders = TextOffset;\r
+ NtHdr->OptionalHeader.NumberOfRvaAndSizes = EFI_IMAGE_NUMBER_OF_DIRECTORY_ENTRIES;\r
+\r
+ //\r
+ // Section headers.\r
+ //\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
+ CreateSectionHeader (".data", DataOffset, RelocOffset - DataOffset,\r
+ EFI_IMAGE_SCN_CNT_INITIALIZED_DATA\r
+ | EFI_IMAGE_SCN_MEM_WRITE\r
+ | EFI_IMAGE_SCN_MEM_READ);\r
+}\r
+\r
+VOID\r
+WriteSections(\r
+ int (*Filter)(Elf_Shdr *)\r
+ )\r
+{\r
+ UINT32 Idx;\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
+ case SHT_NOBITS:\r
+ memset(CoffFile + CoffSectionsOffset[Idx], 0, Shdr->sh_size);\r
+ break;\r
default:\r
- Error (NULL, 0, 3000, "Invalid", "%s unhandle section type %x", mInImageName, (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, 3000, "Invalid", "%s bad symbol definition", mInImageName);
- }
- 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, 3000, "Invalid", "%s unhandle section type %x", mInImageName, (UINTN)Shdr->sh_type);\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
+ Elf_Shdr *SecShdr = GetShdrByIndex(RelShdr->sh_info);\r
+ UINT32 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 *)\r
+ (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
+ 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 unhandle section type %x", mInImageName, ELF_R_TYPE(Rel->r_info));\r
- }
- }
- }
- }
-}
-
-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, 3000, "Invalid", "%s unhandle section type %x", mInImageName, 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(mInImageName) + 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 ((UINT8 *)(Nb10 + 1), mInImageName);
-
- 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;
+ }\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((Type << 12) | (Offset & 0xfff));\r
+}\r
+\r
+VOID\r
+WriteRelocations(\r
+ VOID\r
+ )\r
+{\r
+ UINT32 Idx;\r
+ EFI_IMAGE_NT_HEADERS *NtHdr;\r
+ EFI_IMAGE_DATA_DIRECTORY *Dir;\r
+\r
+ for (Idx = 0; Idx < Ehdr->e_shnum; Idx++) {\r
+ Elf_Shdr *RelShdr = GetShdrByIndex(Idx);\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
+ 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
+ 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 unhandle section type %x", mInImageName, ELF_R_TYPE(Rel->r_info));\r
+ }\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ //\r
+ // Pad by adding empty entries. \r
+ //\r
+ while (CoffOffset & (CoffAlignment - 1)) {\r
+ CoffAddFixupEntry(0);\r
+ }\r
+\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
+ NtHdr = (EFI_IMAGE_NT_HEADERS *)(CoffFile + NtHdrOffset);\r
+ Dir = &NtHdr->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC];\r
+ Dir->VirtualAddress = RelocOffset;\r
+ Dir->Size = CoffOffset - RelocOffset;\r
+}\r
+\r
+VOID\r
+WriteDebug(\r
+ VOID\r
+ )\r
+{\r
+ UINT32 Len = strlen(mInImageName) + 1;\r
+ UINT32 DebugOffset = CoffOffset;\r
+ EFI_IMAGE_NT_HEADERS *NtHdr;\r
+ EFI_IMAGE_DATA_DIRECTORY *DataDir;\r
+ EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *Dir;\r
+ EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY *Nb10;\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\r
+ (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_DIRECTORY_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 ((UINT8 *)(Nb10 + 1), mInImageName);\r
+\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
+ NtHdr = (EFI_IMAGE_NT_HEADERS *)(CoffFile + NtHdrOffset);\r
+ DataDir = &NtHdr->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG];\r
+ DataDir->VirtualAddress = DebugOffset;\r
+ DataDir->Size = CoffOffset - DebugOffset;\r
+}\r
+\r
+VOID\r
+ConvertElf (\r
+ UINT8 **FileBuffer,\r
+ UINTN *FileLength\r
+ )\r
+{\r
+ EFI_IMAGE_NT_HEADERS *NtHdr;\r
+\r
+ //\r
+ // Check header, read section table.\r
+ //\r
+ Ehdr = (Elf32_Ehdr*)*FileBuffer;\r
+ if (!CheckElfHeader())\r
+ return;\r
+\r
+ //\r
+ // Compute sections new address.\r
+ //\r
+ ScanSections();\r
+\r
+ //\r
+ // Write and relocate sections.\r
+ //\r
+ WriteSections(IsTextShdr);\r
+ WriteSections(IsDataShdr);\r
+\r
+ //\r
+ // Translate and write relocations.\r
+ //\r
+ WriteRelocations();\r
+\r
+ //\r
+ // Write debug info.\r
+ //\r
+ WriteDebug();\r
+\r
+ NtHdr = (EFI_IMAGE_NT_HEADERS *)(CoffFile + NtHdrOffset);\r
+ NtHdr->OptionalHeader.SizeOfImage = CoffOffset;\r
+\r
+ //\r
+ // Replace.\r
+ //\r
+ free(*FileBuffer);\r
+ *FileBuffer = CoffFile;\r
*FileLength = CoffOffset;\r
\r
//\r
//\r
if (CoffSectionsOffset != NULL) {\r
free (CoffSectionsOffset);\r
- }
-}
-#endif // HAVE_ELF
-
+ }\r
+}\r
+#endif // HAVE_ELF\r
+\r
int\r
main (\r
int argc,\r
Error (NULL, 0, 1001, "Missing option", "output file");\r
goto Finish;\r
}\r
- }
+ }\r
\r
//\r
// Combine MciBinary files to one file\r
//\r
// Convert EFL image to PeImage\r
//\r
-#ifdef HAVE_ELF
+#ifdef HAVE_ELF\r
if (IsElfHeader(FileBuffer)) {\r
- VerboseMsg ("Convert the input ELF Image to Pe Image");
- ConvertElf(&FileBuffer, &FileLength);
- }
+ VerboseMsg ("Convert the input ELF Image to Pe Image");\r
+ ConvertElf(&FileBuffer, &FileLength);\r
+ }\r
#endif\r
\r
//\r