From bb756eebdac6fd24e8919e2c43f7d2c8c4091f59 Mon Sep 17 00:00:00 2001 From: RajithaY Date: Tue, 25 Apr 2017 03:31:15 -0700 Subject: Adding qemu as a submodule of KVMFORNFV This Patch includes the changes to add qemu as a submodule to kvmfornfv repo and make use of the updated latest qemu for the execution of all testcase Change-Id: I1280af507a857675c7f81d30c95255635667bdd7 Signed-off-by:RajithaY --- qemu/roms/ipxe/src/util/elf2efi.c | 822 -------------------------------------- 1 file changed, 822 deletions(-) delete mode 100644 qemu/roms/ipxe/src/util/elf2efi.c (limited to 'qemu/roms/ipxe/src/util/elf2efi.c') diff --git a/qemu/roms/ipxe/src/util/elf2efi.c b/qemu/roms/ipxe/src/util/elf2efi.c deleted file mode 100644 index e68fa5d14..000000000 --- a/qemu/roms/ipxe/src/util/elf2efi.c +++ /dev/null @@ -1,822 +0,0 @@ -/* - * Copyright (C) 2009 Michael Brown . - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -#define _GNU_SOURCE -#define PACKAGE "elf2efi" -#define PACKAGE_VERSION "1" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define eprintf(...) fprintf ( stderr, __VA_ARGS__ ) - -#define EFI_FILE_ALIGN 0x20 - -struct pe_section { - struct pe_section *next; - EFI_IMAGE_SECTION_HEADER hdr; - uint8_t contents[0]; -}; - -struct pe_relocs { - struct pe_relocs *next; - unsigned long start_rva; - unsigned int used_relocs; - unsigned int total_relocs; - uint16_t *relocs; -}; - -struct pe_header { - EFI_IMAGE_DOS_HEADER dos; - uint8_t padding[128]; -#if defined(EFI_TARGET_IA32) - EFI_IMAGE_NT_HEADERS32 nt; -#elif defined(EFI_TARGET_X64) - EFI_IMAGE_NT_HEADERS64 nt; -#endif -}; - -static struct pe_header efi_pe_header = { - .dos = { - .e_magic = EFI_IMAGE_DOS_SIGNATURE, - .e_lfanew = offsetof ( typeof ( efi_pe_header ), nt ), - }, - .nt = { - .Signature = EFI_IMAGE_NT_SIGNATURE, - .FileHeader = { -#if defined(EFI_TARGET_IA32) - .Machine = EFI_IMAGE_MACHINE_IA32, -#elif defined(EFI_TARGET_X64) - .Machine = EFI_IMAGE_MACHINE_X64, -#endif - .TimeDateStamp = 0x10d1a884, - .SizeOfOptionalHeader = - sizeof ( efi_pe_header.nt.OptionalHeader ), - .Characteristics = ( EFI_IMAGE_FILE_DLL | -#if defined(EFI_TARGET_IA32) - EFI_IMAGE_FILE_32BIT_MACHINE | -#endif - EFI_IMAGE_FILE_EXECUTABLE_IMAGE ), - }, - .OptionalHeader = { -#if defined(EFI_TARGET_IA32) - .Magic = EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC, -#elif defined(EFI_TARGET_X64) - .Magic = EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC, -#endif - .SectionAlignment = EFI_FILE_ALIGN, - .FileAlignment = EFI_FILE_ALIGN, - .SizeOfImage = sizeof ( efi_pe_header ), - .SizeOfHeaders = sizeof ( efi_pe_header ), - .NumberOfRvaAndSizes = - EFI_IMAGE_NUMBER_OF_DIRECTORY_ENTRIES, - }, - }, -}; - -/** Command-line options */ -struct options { - unsigned int subsystem; -}; - -/** - * Allocate memory - * - * @v len Length of memory to allocate - * @ret ptr Pointer to allocated memory - */ -static void * xmalloc ( size_t len ) { - void *ptr; - - ptr = malloc ( len ); - if ( ! ptr ) { - eprintf ( "Could not allocate %zd bytes\n", len ); - exit ( 1 ); - } - - return ptr; -} - -/** - * Align section within PE file - * - * @v offset Unaligned offset - * @ret aligned_offset Aligned offset - */ -static unsigned long efi_file_align ( unsigned long offset ) { - return ( ( offset + EFI_FILE_ALIGN - 1 ) & ~( EFI_FILE_ALIGN - 1 ) ); -} - -/** - * Generate entry in PE relocation table - * - * @v pe_reltab PE relocation table - * @v rva RVA - * @v size Size of relocation entry - */ -static void generate_pe_reloc ( struct pe_relocs **pe_reltab, - unsigned long rva, size_t size ) { - unsigned long start_rva; - uint16_t reloc; - struct pe_relocs *pe_rel; - uint16_t *relocs; - - /* Construct */ - start_rva = ( rva & ~0xfff ); - reloc = ( rva & 0xfff ); - switch ( size ) { - case 8: - reloc |= 0xa000; - break; - case 4: - reloc |= 0x3000; - break; - case 2: - reloc |= 0x2000; - break; - default: - eprintf ( "Unsupported relocation size %zd\n", size ); - exit ( 1 ); - } - - /* Locate or create PE relocation table */ - for ( pe_rel = *pe_reltab ; pe_rel ; pe_rel = pe_rel->next ) { - if ( pe_rel->start_rva == start_rva ) - break; - } - if ( ! pe_rel ) { - pe_rel = xmalloc ( sizeof ( *pe_rel ) ); - memset ( pe_rel, 0, sizeof ( *pe_rel ) ); - pe_rel->next = *pe_reltab; - *pe_reltab = pe_rel; - pe_rel->start_rva = start_rva; - } - - /* Expand relocation list if necessary */ - if ( pe_rel->used_relocs < pe_rel->total_relocs ) { - relocs = pe_rel->relocs; - } else { - pe_rel->total_relocs = ( pe_rel->total_relocs ? - ( pe_rel->total_relocs * 2 ) : 256 ); - relocs = xmalloc ( pe_rel->total_relocs * - sizeof ( pe_rel->relocs[0] ) ); - memset ( relocs, 0, - pe_rel->total_relocs * sizeof ( pe_rel->relocs[0] ) ); - memcpy ( relocs, pe_rel->relocs, - pe_rel->used_relocs * sizeof ( pe_rel->relocs[0] ) ); - free ( pe_rel->relocs ); - pe_rel->relocs = relocs; - } - - /* Store relocation */ - pe_rel->relocs[ pe_rel->used_relocs++ ] = reloc; -} - -/** - * Calculate size of binary PE relocation table - * - * @v pe_reltab PE relocation table - * @v buffer Buffer to contain binary table, or NULL - * @ret size Size of binary table - */ -static size_t output_pe_reltab ( struct pe_relocs *pe_reltab, - void *buffer ) { - struct pe_relocs *pe_rel; - unsigned int num_relocs; - size_t size; - size_t total_size = 0; - - for ( pe_rel = pe_reltab ; pe_rel ; pe_rel = pe_rel->next ) { - num_relocs = ( ( pe_rel->used_relocs + 1 ) & ~1 ); - size = ( sizeof ( uint32_t ) /* VirtualAddress */ + - sizeof ( uint32_t ) /* SizeOfBlock */ + - ( num_relocs * sizeof ( uint16_t ) ) ); - if ( buffer ) { - *( (uint32_t *) ( buffer + total_size + 0 ) ) - = pe_rel->start_rva; - *( (uint32_t *) ( buffer + total_size + 4 ) ) = size; - memcpy ( ( buffer + total_size + 8 ), pe_rel->relocs, - ( num_relocs * sizeof ( uint16_t ) ) ); - } - total_size += size; - } - - return total_size; -} - -/** - * Open input BFD file - * - * @v filename File name - * @ret ibfd BFD file - */ -static bfd * open_input_bfd ( const char *filename ) { - bfd *bfd; - - /* Open the file */ - bfd = bfd_openr ( filename, NULL ); - if ( ! bfd ) { - eprintf ( "Cannot open %s: ", filename ); - bfd_perror ( NULL ); - exit ( 1 ); - } - - /* The call to bfd_check_format() must be present, otherwise - * we get a segfault from later BFD calls. - */ - if ( ! bfd_check_format ( bfd, bfd_object ) ) { - eprintf ( "%s is not an object file: ", filename ); - bfd_perror ( NULL ); - exit ( 1 ); - } - - return bfd; -} - -/** - * Read symbol table - * - * @v bfd BFD file - */ -static asymbol ** read_symtab ( bfd *bfd ) { - long symtab_size; - asymbol **symtab; - long symcount; - - /* Get symbol table size */ - symtab_size = bfd_get_symtab_upper_bound ( bfd ); - if ( symtab_size < 0 ) { - bfd_perror ( "Could not get symbol table upper bound" ); - exit ( 1 ); - } - - /* Allocate and read symbol table */ - symtab = xmalloc ( symtab_size ); - symcount = bfd_canonicalize_symtab ( bfd, symtab ); - if ( symcount < 0 ) { - bfd_perror ( "Cannot read symbol table" ); - exit ( 1 ); - } - - return symtab; -} - -/** - * Read relocation table - * - * @v bfd BFD file - * @v symtab Symbol table - * @v section Section - * @v symtab Symbol table - * @ret reltab Relocation table - */ -static arelent ** read_reltab ( bfd *bfd, asymbol **symtab, - asection *section ) { - long reltab_size; - arelent **reltab; - long numrels; - - /* Get relocation table size */ - reltab_size = bfd_get_reloc_upper_bound ( bfd, section ); - if ( reltab_size < 0 ) { - bfd_perror ( "Could not get relocation table upper bound" ); - exit ( 1 ); - } - - /* Allocate and read relocation table */ - reltab = xmalloc ( reltab_size ); - numrels = bfd_canonicalize_reloc ( bfd, section, reltab, symtab ); - if ( numrels < 0 ) { - bfd_perror ( "Cannot read relocation table" ); - exit ( 1 ); - } - - return reltab; -} - -/** - * Process section - * - * @v bfd BFD file - * @v pe_header PE file header - * @v section Section - * @ret new New PE section - */ -static struct pe_section * process_section ( bfd *bfd, - struct pe_header *pe_header, - asection *section ) { - struct pe_section *new; - size_t section_memsz; - size_t section_filesz; - unsigned long flags = bfd_get_section_flags ( bfd, section ); - unsigned long code_start; - unsigned long code_end; - unsigned long data_start; - unsigned long data_mid; - unsigned long data_end; - unsigned long start; - unsigned long end; - unsigned long *applicable_start; - unsigned long *applicable_end; - - /* Extract current RVA limits from file header */ - code_start = pe_header->nt.OptionalHeader.BaseOfCode; - code_end = ( code_start + pe_header->nt.OptionalHeader.SizeOfCode ); -#if defined(EFI_TARGET_IA32) - data_start = pe_header->nt.OptionalHeader.BaseOfData; -#elif defined(EFI_TARGET_X64) - data_start = code_end; -#endif - data_mid = ( data_start + - pe_header->nt.OptionalHeader.SizeOfInitializedData ); - data_end = ( data_mid + - pe_header->nt.OptionalHeader.SizeOfUninitializedData ); - - /* Allocate PE section */ - section_memsz = bfd_section_size ( bfd, section ); - section_filesz = ( ( flags & SEC_LOAD ) ? - efi_file_align ( section_memsz ) : 0 ); - new = xmalloc ( sizeof ( *new ) + section_filesz ); - memset ( new, 0, sizeof ( *new ) + section_filesz ); - - /* Fill in section header details */ - strncpy ( ( char * ) new->hdr.Name, section->name, - sizeof ( new->hdr.Name ) ); - new->hdr.Misc.VirtualSize = section_memsz; - new->hdr.VirtualAddress = bfd_get_section_vma ( bfd, section ); - new->hdr.SizeOfRawData = section_filesz; - - /* Fill in section characteristics and update RVA limits */ - if ( flags & SEC_CODE ) { - /* .text-type section */ - new->hdr.Characteristics = - ( EFI_IMAGE_SCN_CNT_CODE | - EFI_IMAGE_SCN_MEM_NOT_PAGED | - EFI_IMAGE_SCN_MEM_EXECUTE | - EFI_IMAGE_SCN_MEM_READ ); - applicable_start = &code_start; - applicable_end = &code_end; - } else if ( flags & SEC_DATA ) { - /* .data-type section */ - new->hdr.Characteristics = - ( EFI_IMAGE_SCN_CNT_INITIALIZED_DATA | - EFI_IMAGE_SCN_MEM_NOT_PAGED | - EFI_IMAGE_SCN_MEM_READ | - EFI_IMAGE_SCN_MEM_WRITE ); - applicable_start = &data_start; - applicable_end = &data_mid; - } else if ( flags & SEC_READONLY ) { - /* .rodata-type section */ - new->hdr.Characteristics = - ( EFI_IMAGE_SCN_CNT_INITIALIZED_DATA | - EFI_IMAGE_SCN_MEM_NOT_PAGED | - EFI_IMAGE_SCN_MEM_READ ); - applicable_start = &data_start; - applicable_end = &data_mid; - } else if ( ! ( flags & SEC_LOAD ) ) { - /* .bss-type section */ - new->hdr.Characteristics = - ( EFI_IMAGE_SCN_CNT_UNINITIALIZED_DATA | - EFI_IMAGE_SCN_MEM_NOT_PAGED | - EFI_IMAGE_SCN_MEM_READ | - EFI_IMAGE_SCN_MEM_WRITE ); - applicable_start = &data_mid; - applicable_end = &data_end; - } else { - eprintf ( "Unrecognised characteristics %#lx for section %s\n", - flags, section->name ); - exit ( 1 ); - } - - /* Copy in section contents */ - if ( flags & SEC_LOAD ) { - if ( ! bfd_get_section_contents ( bfd, section, new->contents, - 0, section_memsz ) ) { - eprintf ( "Cannot read section %s: ", section->name ); - bfd_perror ( NULL ); - exit ( 1 ); - } - } - - /* Update RVA limits */ - start = new->hdr.VirtualAddress; - end = ( start + new->hdr.Misc.VirtualSize ); - if ( ( ! *applicable_start ) || ( *applicable_start >= start ) ) - *applicable_start = start; - if ( *applicable_end < end ) - *applicable_end = end; - if ( data_start < code_end ) - data_start = code_end; - if ( data_mid < data_start ) - data_mid = data_start; - if ( data_end < data_mid ) - data_end = data_mid; - - /* Write RVA limits back to file header */ - pe_header->nt.OptionalHeader.BaseOfCode = code_start; - pe_header->nt.OptionalHeader.SizeOfCode = ( code_end - code_start ); -#if defined(EFI_TARGET_IA32) - pe_header->nt.OptionalHeader.BaseOfData = data_start; -#endif - pe_header->nt.OptionalHeader.SizeOfInitializedData = - ( data_mid - data_start ); - pe_header->nt.OptionalHeader.SizeOfUninitializedData = - ( data_end - data_mid ); - - /* Update remaining file header fields */ - pe_header->nt.FileHeader.NumberOfSections++; - pe_header->nt.OptionalHeader.SizeOfHeaders += sizeof ( new->hdr ); - pe_header->nt.OptionalHeader.SizeOfImage = - efi_file_align ( data_end ); - - return new; -} - -/** - * Process relocation record - * - * @v bfd BFD file - * @v section Section - * @v rel Relocation entry - * @v pe_reltab PE relocation table to fill in - */ -static void process_reloc ( bfd *bfd __attribute__ (( unused )), - asection *section, arelent *rel, - struct pe_relocs **pe_reltab ) { - reloc_howto_type *howto = rel->howto; - asymbol *sym = *(rel->sym_ptr_ptr); - unsigned long offset = ( bfd_get_section_vma ( bfd, section ) + - rel->address ); - - if ( bfd_is_abs_section ( sym->section ) ) { - /* Skip absolute symbols; the symbol value won't - * change when the object is loaded. - */ - } else if ( ( strcmp ( howto->name, "R_386_NONE" ) == 0 ) || - ( strcmp ( howto->name, "R_X86_64_NONE" ) == 0 ) ) { - /* Ignore dummy relocations used by REQUIRE_SYMBOL() */ - } else if ( strcmp ( howto->name, "R_X86_64_64" ) == 0 ) { - /* Generate an 8-byte PE relocation */ - generate_pe_reloc ( pe_reltab, offset, 8 ); - } else if ( strcmp ( howto->name, "R_386_32" ) == 0 ) { - /* Generate a 4-byte PE relocation */ - generate_pe_reloc ( pe_reltab, offset, 4 ); - } else if ( strcmp ( howto->name, "R_386_16" ) == 0 ) { - /* Generate a 2-byte PE relocation */ - generate_pe_reloc ( pe_reltab, offset, 2 ); - } else if ( ( strcmp ( howto->name, "R_386_PC32" ) == 0 ) || - ( strcmp ( howto->name, "R_X86_64_PC32" ) == 0 ) ) { - /* Skip PC-relative relocations; all relative offsets - * remain unaltered when the object is loaded. - */ - } else { - eprintf ( "Unrecognised relocation type %s\n", howto->name ); - exit ( 1 ); - } -} - -/** - * Create relocations section - * - * @v pe_header PE file header - * @v pe_reltab PE relocation table - * @ret section Relocation section - */ -static struct pe_section * -create_reloc_section ( struct pe_header *pe_header, - struct pe_relocs *pe_reltab ) { - struct pe_section *reloc; - size_t section_memsz; - size_t section_filesz; - EFI_IMAGE_DATA_DIRECTORY *relocdir; - - /* Allocate PE section */ - section_memsz = output_pe_reltab ( pe_reltab, NULL ); - section_filesz = efi_file_align ( section_memsz ); - reloc = xmalloc ( sizeof ( *reloc ) + section_filesz ); - memset ( reloc, 0, sizeof ( *reloc ) + section_filesz ); - - /* Fill in section header details */ - strncpy ( ( char * ) reloc->hdr.Name, ".reloc", - sizeof ( reloc->hdr.Name ) ); - reloc->hdr.Misc.VirtualSize = section_memsz; - reloc->hdr.VirtualAddress = pe_header->nt.OptionalHeader.SizeOfImage; - reloc->hdr.SizeOfRawData = section_filesz; - reloc->hdr.Characteristics = ( EFI_IMAGE_SCN_CNT_INITIALIZED_DATA | - EFI_IMAGE_SCN_MEM_NOT_PAGED | - EFI_IMAGE_SCN_MEM_READ ); - - /* Copy in section contents */ - output_pe_reltab ( pe_reltab, reloc->contents ); - - /* Update file header details */ - pe_header->nt.FileHeader.NumberOfSections++; - pe_header->nt.OptionalHeader.SizeOfHeaders += sizeof ( reloc->hdr ); - pe_header->nt.OptionalHeader.SizeOfImage += section_filesz; - relocdir = &(pe_header->nt.OptionalHeader.DataDirectory - [EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC]); - relocdir->VirtualAddress = reloc->hdr.VirtualAddress; - relocdir->Size = reloc->hdr.Misc.VirtualSize; - - return reloc; -} - -/** - * Create debug section - * - * @v pe_header PE file header - * @ret section Debug section - */ -static struct pe_section * -create_debug_section ( struct pe_header *pe_header, const char *filename ) { - struct pe_section *debug; - size_t section_memsz; - size_t section_filesz; - EFI_IMAGE_DATA_DIRECTORY *debugdir; - struct { - EFI_IMAGE_DEBUG_DIRECTORY_ENTRY debug; - EFI_IMAGE_DEBUG_CODEVIEW_RSDS_ENTRY rsds; - char name[ strlen ( filename ) + 1 ]; - } *contents; - - /* Allocate PE section */ - section_memsz = sizeof ( *contents ); - section_filesz = efi_file_align ( section_memsz ); - debug = xmalloc ( sizeof ( *debug ) + section_filesz ); - memset ( debug, 0, sizeof ( *debug ) + section_filesz ); - contents = ( void * ) debug->contents; - - /* Fill in section header details */ - strncpy ( ( char * ) debug->hdr.Name, ".debug", - sizeof ( debug->hdr.Name ) ); - debug->hdr.Misc.VirtualSize = section_memsz; - debug->hdr.VirtualAddress = pe_header->nt.OptionalHeader.SizeOfImage; - debug->hdr.SizeOfRawData = section_filesz; - debug->hdr.Characteristics = ( EFI_IMAGE_SCN_CNT_INITIALIZED_DATA | - EFI_IMAGE_SCN_MEM_NOT_PAGED | - EFI_IMAGE_SCN_MEM_READ ); - - /* Create section contents */ - contents->debug.TimeDateStamp = 0x10d1a884; - contents->debug.Type = EFI_IMAGE_DEBUG_TYPE_CODEVIEW; - contents->debug.SizeOfData = - ( sizeof ( *contents ) - sizeof ( contents->debug ) ); - contents->debug.RVA = ( debug->hdr.VirtualAddress + - offsetof ( typeof ( *contents ), rsds ) ); - contents->rsds.Signature = CODEVIEW_SIGNATURE_RSDS; - snprintf ( contents->name, sizeof ( contents->name ), "%s", - filename ); - - /* Update file header details */ - pe_header->nt.FileHeader.NumberOfSections++; - pe_header->nt.OptionalHeader.SizeOfHeaders += sizeof ( debug->hdr ); - pe_header->nt.OptionalHeader.SizeOfImage += section_filesz; - debugdir = &(pe_header->nt.OptionalHeader.DataDirectory - [EFI_IMAGE_DIRECTORY_ENTRY_DEBUG]); - debugdir->VirtualAddress = debug->hdr.VirtualAddress; - debugdir->Size = debug->hdr.Misc.VirtualSize; - - return debug; -} - -/** - * Write out PE file - * - * @v pe_header PE file header - * @v pe_sections List of PE sections - * @v pe Output file - */ -static void write_pe_file ( struct pe_header *pe_header, - struct pe_section *pe_sections, - FILE *pe ) { - struct pe_section *section; - unsigned long fpos = 0; - - /* Align length of headers */ - fpos = pe_header->nt.OptionalHeader.SizeOfHeaders = - efi_file_align ( pe_header->nt.OptionalHeader.SizeOfHeaders ); - - /* Assign raw data pointers */ - for ( section = pe_sections ; section ; section = section->next ) { - if ( section->hdr.SizeOfRawData ) { - section->hdr.PointerToRawData = fpos; - fpos += section->hdr.SizeOfRawData; - fpos = efi_file_align ( fpos ); - } - } - - /* Write file header */ - if ( fwrite ( pe_header, sizeof ( *pe_header ), 1, pe ) != 1 ) { - perror ( "Could not write PE header" ); - exit ( 1 ); - } - - /* Write section headers */ - for ( section = pe_sections ; section ; section = section->next ) { - if ( fwrite ( §ion->hdr, sizeof ( section->hdr ), - 1, pe ) != 1 ) { - perror ( "Could not write section header" ); - exit ( 1 ); - } - } - - /* Write sections */ - for ( section = pe_sections ; section ; section = section->next ) { - if ( fseek ( pe, section->hdr.PointerToRawData, - SEEK_SET ) != 0 ) { - eprintf ( "Could not seek to %x: %s\n", - section->hdr.PointerToRawData, - strerror ( errno ) ); - exit ( 1 ); - } - if ( section->hdr.SizeOfRawData && - ( fwrite ( section->contents, section->hdr.SizeOfRawData, - 1, pe ) != 1 ) ) { - eprintf ( "Could not write section %.8s: %s\n", - section->hdr.Name, strerror ( errno ) ); - exit ( 1 ); - } - } -} - -/** - * Convert ELF to PE - * - * @v elf_name ELF file name - * @v pe_name PE file name - */ -static void elf2pe ( const char *elf_name, const char *pe_name, - struct options *opts ) { - char pe_name_tmp[ strlen ( pe_name ) + 1 ]; - bfd *bfd; - asymbol **symtab; - asection *section; - arelent **reltab; - arelent **rel; - struct pe_relocs *pe_reltab = NULL; - struct pe_section *pe_sections = NULL; - struct pe_section **next_pe_section = &pe_sections; - struct pe_header pe_header; - FILE *pe; - - /* Create a modifiable copy of the PE name */ - memcpy ( pe_name_tmp, pe_name, sizeof ( pe_name_tmp ) ); - - /* Open the file */ - bfd = open_input_bfd ( elf_name ); - symtab = read_symtab ( bfd ); - - /* Initialise the PE header */ - memcpy ( &pe_header, &efi_pe_header, sizeof ( pe_header ) ); - pe_header.nt.OptionalHeader.AddressOfEntryPoint = - bfd_get_start_address ( bfd ); - pe_header.nt.OptionalHeader.Subsystem = opts->subsystem; - - /* For each input section, build an output section and create - * the appropriate relocation records - */ - for ( section = bfd->sections ; section ; section = section->next ) { - /* Discard non-allocatable sections */ - if ( ! ( bfd_get_section_flags ( bfd, section ) & SEC_ALLOC ) ) - continue; - /* Create output section */ - *(next_pe_section) = process_section ( bfd, &pe_header, - section ); - next_pe_section = &(*next_pe_section)->next; - /* Add relocations from this section */ - reltab = read_reltab ( bfd, symtab, section ); - for ( rel = reltab ; *rel ; rel++ ) - process_reloc ( bfd, section, *rel, &pe_reltab ); - free ( reltab ); - } - - /* Create the .reloc section */ - *(next_pe_section) = create_reloc_section ( &pe_header, pe_reltab ); - next_pe_section = &(*next_pe_section)->next; - - /* Create the .reloc section */ - *(next_pe_section) = create_debug_section ( &pe_header, - basename ( pe_name_tmp ) ); - next_pe_section = &(*next_pe_section)->next; - - /* Write out PE file */ - pe = fopen ( pe_name, "w" ); - if ( ! pe ) { - eprintf ( "Could not open %s for writing: %s\n", - pe_name, strerror ( errno ) ); - exit ( 1 ); - } - write_pe_file ( &pe_header, pe_sections, pe ); - fclose ( pe ); - - /* Close BFD file */ - bfd_close ( bfd ); -} - -/** - * Print help - * - * @v program_name Program name - */ -static void print_help ( const char *program_name ) { - eprintf ( "Syntax: %s [--subsystem=] infile outfile\n", - program_name ); -} - -/** - * Parse command-line options - * - * @v argc Argument count - * @v argv Argument list - * @v opts Options structure to populate - */ -static int parse_options ( const int argc, char **argv, - struct options *opts ) { - char *end; - int c; - - while (1) { - int option_index = 0; - static struct option long_options[] = { - { "subsystem", required_argument, NULL, 's' }, - { "help", 0, NULL, 'h' }, - { 0, 0, 0, 0 } - }; - - if ( ( c = getopt_long ( argc, argv, "s:h", - long_options, - &option_index ) ) == -1 ) { - break; - } - - switch ( c ) { - case 's': - opts->subsystem = strtoul ( optarg, &end, 0 ); - if ( *end ) { - eprintf ( "Invalid subsytem \"%s\"\n", - optarg ); - exit ( 2 ); - } - break; - case 'h': - print_help ( argv[0] ); - exit ( 0 ); - case '?': - default: - exit ( 2 ); - } - } - return optind; -} - -int main ( int argc, char **argv ) { - struct options opts = { - .subsystem = EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION, - }; - int infile_index; - const char *infile; - const char *outfile; - - /* Initialise libbfd */ - bfd_init(); - - /* Parse command-line arguments */ - infile_index = parse_options ( argc, argv, &opts ); - if ( argc != ( infile_index + 2 ) ) { - print_help ( argv[0] ); - exit ( 2 ); - } - infile = argv[infile_index]; - outfile = argv[infile_index + 1]; - - /* Convert file */ - elf2pe ( infile, outfile, &opts ); - - return 0; -} -- cgit 1.2.3-korg