From efd5cf9aadcaf36f45db5d1c3059197a8479567c Mon Sep 17 00:00:00 2001 From: Michael Brown Date: Mon, 2 May 2016 20:36:54 +0100 Subject: [efi] Eliminate use of libbfd Parse the intermediate ELF file directly instead of using libbfd, in order to allow for cross-compiled ELF objects. As a side bonus, this eliminates libbfd as a build requirement. Signed-off-by: Michael Brown --- src/util/elf2efi.c | 463 ++++++++++++++++++++++++++++++++++------------------- 1 file changed, 294 insertions(+), 169 deletions(-) (limited to 'src/util') diff --git a/src/util/elf2efi.c b/src/util/elf2efi.c index dee70ee7..5e1050e3 100644 --- a/src/util/elf2efi.c +++ b/src/util/elf2efi.c @@ -17,9 +17,6 @@ * 02110-1301, USA. */ -#define _GNU_SOURCE -#define PACKAGE "elf2efi" -#define PACKAGE_VERSION "1" #define FILE_LICENCE(...) extern void __file_licence ( void ) #include #include @@ -30,15 +27,65 @@ #include #include #include -#include +#include +#include +#include +#include +#include #include #include #include #define eprintf(...) fprintf ( stderr, __VA_ARGS__ ) +#ifdef EFI_TARGET32 + +#define EFI_IMAGE_NT_HEADERS EFI_IMAGE_NT_HEADERS32 +#define EFI_IMAGE_NT_OPTIONAL_HDR_MAGIC EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC +#define EFI_IMAGE_FILE_MACHINE EFI_IMAGE_FILE_32BIT_MACHINE +#define ELFCLASS ELFCLASS32 +#define Elf_Ehdr Elf32_Ehdr +#define Elf_Shdr Elf32_Shdr +#define Elf_Sym Elf32_Sym +#define Elf_Addr Elf32_Addr +#define Elf_Rel Elf32_Rel +#define Elf_Rela Elf32_Rela +#define ELF_R_TYPE ELF32_R_TYPE +#define ELF_R_SYM ELF32_R_SYM + +#elif defined(EFI_TARGET64) + +#define EFI_IMAGE_NT_HEADERS EFI_IMAGE_NT_HEADERS64 +#define EFI_IMAGE_NT_OPTIONAL_HDR_MAGIC EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC +#define EFI_IMAGE_FILE_MACHINE 0 +#define ELFCLASS ELFCLASS64 +#define Elf_Ehdr Elf64_Ehdr +#define Elf_Shdr Elf64_Shdr +#define Elf_Sym Elf64_Sym +#define Elf_Addr Elf64_Addr +#define Elf_Rel Elf64_Rel +#define Elf_Rela Elf64_Rela +#define ELF_R_TYPE ELF64_R_TYPE +#define ELF_R_SYM ELF64_R_SYM + +#endif + #define EFI_FILE_ALIGN 0x20 +struct elf_machine { + unsigned int pe_machine; + unsigned int r_none; + unsigned int r_abs; + unsigned int r_pcrel; +}; + +struct elf_file { + void *data; + size_t len; + const Elf_Ehdr *ehdr; + struct elf_machine *machine; +}; + struct pe_section { struct pe_section *next; EFI_IMAGE_SECTION_HEADER hdr; @@ -57,11 +104,7 @@ struct pe_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 + EFI_IMAGE_NT_HEADERS nt; }; static struct pe_header efi_pe_header = { @@ -72,26 +115,15 @@ static struct pe_header efi_pe_header = { .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_MACHINE | 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 + .Magic = EFI_IMAGE_NT_OPTIONAL_HDR_MAGIC, .MajorLinkerVersion = 42, .MinorLinkerVersion = 42, .SectionAlignment = EFI_FILE_ALIGN, @@ -104,6 +136,20 @@ static struct pe_header efi_pe_header = { }, }; +static struct elf_machine machine_i386 = { + .pe_machine = EFI_IMAGE_MACHINE_IA32, + .r_none = R_386_NONE, + .r_abs = R_386_32, + .r_pcrel = R_386_PC32, +}; + +static struct elf_machine machine_x86_64 = { + .pe_machine = EFI_IMAGE_MACHINE_X64, + .r_none = R_X86_64_NONE, + .r_abs = R_X86_64_64, + .r_pcrel = R_X86_64_PC32, +}; + /** Command-line options */ struct options { unsigned int subsystem; @@ -235,110 +281,155 @@ static size_t output_pe_reltab ( struct pe_relocs *pe_reltab, } /** - * Open input BFD file + * Read input ELF file * - * @v filename File name - * @ret ibfd BFD file + * @v name File name + * @v elf ELF 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 ); +static void read_elf_file ( const char *name, struct elf_file *elf ) { + static const unsigned char ident[] = { + ELFMAG0, ELFMAG1, ELFMAG2, ELFMAG3, ELFCLASS, ELFDATA2LSB + }; + struct stat stat; + const Elf_Ehdr *ehdr; + const Elf_Shdr *shdr; + void *data; + size_t offset; + unsigned int i; + int fd; + + /* Open file */ + fd = open ( name, O_RDONLY ); + if ( fd < 0 ) { + eprintf ( "Could not open %s: %s\n", name, strerror ( errno ) ); 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 ); + /* Get file size */ + if ( fstat ( fd, &stat ) < 0 ) { + eprintf ( "Could not get size of %s: %s\n", + name, strerror ( errno ) ); exit ( 1 ); } + elf->len = stat.st_size; - 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" ); + /* Map file */ + data = mmap ( NULL, elf->len, PROT_READ, MAP_SHARED, fd, 0 ); + if ( data == MAP_FAILED ) { + eprintf ( "Could not map %s: %s\n", name, strerror ( errno ) ); exit ( 1 ); } + elf->data = data; - /* Allocate and read symbol table */ - symtab = xmalloc ( symtab_size ); - symcount = bfd_canonicalize_symtab ( bfd, symtab ); - if ( symcount < 0 ) { - bfd_perror ( "Cannot read symbol table" ); + /* Close file */ + close ( fd ); + + /* Check header */ + ehdr = elf->data; + if ( ( elf->len < sizeof ( *ehdr ) ) || + ( memcmp ( ident, ehdr->e_ident, sizeof ( ident ) ) != 0 ) ) { + eprintf ( "Invalid ELF header in %s\n", name ); exit ( 1 ); } + elf->ehdr = ehdr; + + /* Check section headers */ + for ( i = 0 ; i < ehdr->e_shnum ; i++ ) { + offset = ( ehdr->e_shoff + ( i * ehdr->e_shentsize ) ); + if ( elf->len < ( offset + sizeof ( *shdr ) ) ) { + eprintf ( "ELF section header outside file in %s\n", + name ); + exit ( 1 ); + } + shdr = ( data + offset ); + if ( ( shdr->sh_type != SHT_NOBITS ) && + ( ( elf->len < shdr->sh_offset ) || + ( ( ( elf->len - shdr->sh_offset ) < shdr->sh_size ) ))){ + eprintf ( "ELF section %d outside file in %s\n", + i, name ); + exit ( 1 ); + } + if ( shdr->sh_link >= ehdr->e_shnum ) { + eprintf ( "ELF section %d link section %d out of " + "range\n", i, shdr->sh_link ); + exit ( 1 ); + } + } - return symtab; + /* Identify architecture */ + switch ( ehdr->e_machine ) { + case EM_386: + elf->machine = &machine_i386; + break; + case EM_X86_64: + elf->machine = &machine_x86_64; + break; + default: + eprintf ( "Unknown ELF architecture %d\n", ehdr->e_machine ); + exit ( 1 ); + } } /** - * Read relocation table + * Get ELF string * - * @v bfd BFD file - * @v symtab Symbol table - * @v section Section - * @v symtab Symbol table - * @ret reltab Relocation table + * @v elf ELF file + * @v section String table section number + * @v offset String table offset + * @ret string ELF string */ -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" ); +static const char * elf_string ( struct elf_file *elf, unsigned int section, + size_t offset ) { + const Elf_Ehdr *ehdr = elf->ehdr; + const Elf_Shdr *shdr; + char *string; + char *last; + + /* Locate section header */ + if ( section >= ehdr->e_shnum ) { + eprintf ( "Invalid ELF string section %d\n", section ); exit ( 1 ); } + shdr = ( elf->data + ehdr->e_shoff + ( section * ehdr->e_shentsize ) ); - /* 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" ); + /* Sanity check section */ + if ( shdr->sh_type != SHT_STRTAB ) { + eprintf ( "ELF section %d (type %d) is not a string table\n", + section, shdr->sh_type ); + exit ( 1 ); + } + last = ( elf->data + shdr->sh_offset + shdr->sh_size - 1 ); + if ( *last != '\0' ) { + eprintf ( "ELF section %d is not NUL-terminated\n", section ); exit ( 1 ); } - return reltab; + /* Locate string */ + if ( offset >= shdr->sh_size ) { + eprintf ( "Invalid ELF string offset %zd in section %d\n", + offset, section ); + exit ( 1 ); + } + string = ( elf->data + shdr->sh_offset + offset ); + + return string; } /** * Process section * - * @v bfd BFD file + * @v elf ELF file + * @v shdr ELF section header * @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 ) { +static struct pe_section * process_section ( struct elf_file *elf, + const Elf_Shdr *shdr, + struct pe_header *pe_header ) { struct pe_section *new; + const char *name; 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; @@ -349,12 +440,15 @@ static struct pe_section * process_section ( bfd *bfd, unsigned long *applicable_start; unsigned long *applicable_end; + /* Get section name */ + name = elf_string ( elf, elf->ehdr->e_shstrndx, shdr->sh_name ); + /* 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) +#if defined(EFI_TARGET32) data_start = pe_header->nt.OptionalHeader.BaseOfData; -#elif defined(EFI_TARGET_X64) +#elif defined(EFI_TARGET64) data_start = code_end; #endif data_mid = ( data_start + @@ -363,21 +457,21 @@ static struct pe_section * process_section ( bfd *bfd, pe_header->nt.OptionalHeader.SizeOfUninitializedData ); /* Allocate PE section */ - section_memsz = bfd_section_size ( bfd, section ); - section_filesz = ( ( flags & SEC_LOAD ) ? + section_memsz = shdr->sh_size; + section_filesz = ( ( shdr->sh_type == SHT_PROGBITS ) ? 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 ) ); + strncpy ( ( char * ) new->hdr.Name, name, sizeof ( new->hdr.Name ) ); new->hdr.Misc.VirtualSize = section_memsz; - new->hdr.VirtualAddress = bfd_get_section_vma ( bfd, section ); + new->hdr.VirtualAddress = shdr->sh_addr; new->hdr.SizeOfRawData = section_filesz; /* Fill in section characteristics and update RVA limits */ - if ( flags & SEC_CODE ) { + if ( ( shdr->sh_type == SHT_PROGBITS ) && + ( shdr->sh_flags & SHF_EXECINSTR ) ) { /* .text-type section */ new->hdr.Characteristics = ( EFI_IMAGE_SCN_CNT_CODE | @@ -386,7 +480,8 @@ static struct pe_section * process_section ( bfd *bfd, EFI_IMAGE_SCN_MEM_READ ); applicable_start = &code_start; applicable_end = &code_end; - } else if ( flags & SEC_DATA ) { + } else if ( ( shdr->sh_type == SHT_PROGBITS ) && + ( shdr->sh_flags & SHF_WRITE ) ) { /* .data-type section */ new->hdr.Characteristics = ( EFI_IMAGE_SCN_CNT_INITIALIZED_DATA | @@ -395,7 +490,7 @@ static struct pe_section * process_section ( bfd *bfd, EFI_IMAGE_SCN_MEM_WRITE ); applicable_start = &data_start; applicable_end = &data_mid; - } else if ( flags & SEC_READONLY ) { + } else if ( shdr->sh_type == SHT_PROGBITS ) { /* .rodata-type section */ new->hdr.Characteristics = ( EFI_IMAGE_SCN_CNT_INITIALIZED_DATA | @@ -403,7 +498,7 @@ static struct pe_section * process_section ( bfd *bfd, EFI_IMAGE_SCN_MEM_READ ); applicable_start = &data_start; applicable_end = &data_mid; - } else if ( ! ( flags & SEC_LOAD ) ) { + } else if ( shdr->sh_type == SHT_NOBITS ) { /* .bss-type section */ new->hdr.Characteristics = ( EFI_IMAGE_SCN_CNT_UNINITIALIZED_DATA | @@ -413,19 +508,15 @@ static struct pe_section * process_section ( bfd *bfd, applicable_start = &data_mid; applicable_end = &data_end; } else { - eprintf ( "Unrecognised characteristics %#lx for section %s\n", - flags, section->name ); + eprintf ( "Unrecognised characteristics for section %s\n", + 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 ); - } + if ( shdr->sh_type == SHT_PROGBITS ) { + memcpy ( new->contents, ( elf->data + shdr->sh_offset ), + shdr->sh_size ); } /* Update RVA limits */ @@ -445,7 +536,7 @@ static struct pe_section * process_section ( bfd *bfd, /* 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) +#if defined(EFI_TARGET32) pe_header->nt.OptionalHeader.BaseOfData = data_start; #endif pe_header->nt.OptionalHeader.SizeOfInitializedData = @@ -465,46 +556,76 @@ static struct pe_section * process_section ( bfd *bfd, /** * Process relocation record * - * @v bfd BFD file - * @v section Section - * @v rel Relocation entry + * @v elf ELF file + * @v shdr ELF section header + * @v syms Symbol table + * @v nsyms Number of symbol table entries + * @v rel Relocation record * @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 ) ) { +static void process_reloc ( struct elf_file *elf, const Elf_Shdr *shdr, + const Elf_Sym *syms, unsigned int nsyms, + const Elf_Rel *rel, struct pe_relocs **pe_reltab ) { + unsigned int type = ELF_R_TYPE ( rel->r_info ); + unsigned int sym = ELF_R_SYM ( rel->r_info ); + size_t offset = ( shdr->sh_addr + rel->r_offset ); + + /* Look up symbol and process relocation */ + if ( sym >= nsyms ) { + eprintf ( "Symbol out of range\n" ); + exit ( 1 ); + } + if ( syms[sym].st_shndx == SHN_ABS ) { /* 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 ) ) { + } else if ( type == elf->machine->r_none ) { /* 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 ) ) { + } else if ( type == elf->machine->r_abs ) { + /* Generate an 8-byte or 4-byte PE relocation */ + generate_pe_reloc ( pe_reltab, offset, sizeof ( Elf_Addr ) ); + } else if ( type == elf->machine->r_pcrel ) { /* Skip PC-relative relocations; all relative offsets * remain unaltered when the object is loaded. */ } else { - eprintf ( "Unrecognised relocation type %s\n", howto->name ); + eprintf ( "Unrecognised relocation type %d\n", type ); exit ( 1 ); } } +/** + * Process relocation records + * + * @v elf ELF file + * @v shdr ELF section header + * @v stride Relocation record size + * @v pe_reltab PE relocation table to fill in + */ +static void process_relocs ( struct elf_file *elf, const Elf_Shdr *shdr, + size_t stride, struct pe_relocs **pe_reltab ) { + const Elf_Shdr *symtab; + const Elf_Sym *syms; + const Elf_Rel *rel; + unsigned int nsyms; + unsigned int nrels; + unsigned int i; + + /* Identify symbol table */ + symtab = ( elf->data + elf->ehdr->e_shoff + + ( shdr->sh_link * elf->ehdr->e_shentsize ) ); + syms = ( elf->data + symtab->sh_offset ); + nsyms = ( symtab->sh_size / sizeof ( syms[0] ) ); + + /* Process each relocation */ + rel = ( elf->data + shdr->sh_offset ); + nrels = ( shdr->sh_size / stride ); + for ( i = 0 ; i < nrels ; i++ ) { + process_reloc ( elf, shdr, syms, nsyms, rel, pe_reltab ); + rel = ( ( ( const void * ) rel ) + stride ); + } +} + /** * Create relocations section * @@ -696,53 +817,60 @@ static void write_pe_file ( struct pe_header *pe_header, 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; + struct elf_file elf; + const Elf_Shdr *shdr; + size_t offset; + unsigned int i; 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 ); + /* Read ELF file */ + read_elf_file ( elf_name, &elf ); /* 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.FileHeader.Machine = elf.machine->pe_machine; + pe_header.nt.OptionalHeader.AddressOfEntryPoint = elf.ehdr->e_entry; 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 ); + /* Process input sections */ + for ( i = 0 ; i < elf.ehdr->e_shnum ; i++ ) { + offset = ( elf.ehdr->e_shoff + ( i * elf.ehdr->e_shentsize ) ); + shdr = ( elf.data + offset ); + + /* Process section */ + if ( shdr->sh_flags & SHF_ALLOC ) { + + /* Create output section */ + *(next_pe_section) = process_section ( &elf, shdr, + &pe_header ); + next_pe_section = &(*next_pe_section)->next; + + } else if ( shdr->sh_type == SHT_REL ) { + + /* Process .rel relocations */ + process_relocs ( &elf, shdr, sizeof ( Elf_Rel ), + &pe_reltab ); + + } else if ( shdr->sh_type == SHT_RELA ) { + + /* Process .rela relocations */ + process_relocs ( &elf, shdr, sizeof ( Elf_Rela ), + &pe_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 */ + /* Create the .debug section */ *(next_pe_section) = create_debug_section ( &pe_header, basename ( pe_name_tmp ) ); next_pe_section = &(*next_pe_section)->next; @@ -757,8 +885,8 @@ static void elf2pe ( const char *elf_name, const char *pe_name, write_pe_file ( &pe_header, pe_sections, pe ); fclose ( pe ); - /* Close BFD file */ - bfd_close ( bfd ); + /* Unmap ELF file */ + munmap ( elf.data, elf.len ); } /** @@ -825,9 +953,6 @@ int main ( int argc, char **argv ) { 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 ) ) { -- cgit v1.2.3-55-g7522