From fac417805a7d6be67dae8e8146edd818a308f8a3 Mon Sep 17 00:00:00 2001 From: Jim Wilson Date: Tue, 18 Apr 2000 04:03:16 +0000 Subject: [PATCH] Bfd support for generating IA-64 EFI binaries. * Makefile.am (BFD64_BACKENDS): Mention coff-ia64.lo. (BFD64_BACKENDS_CFILES): Mention coff-ia64.c (coff-ia64.lo): Add dependency. * Makefile.in: Regenerate. * coff-ia64.c: New file. * efi-app-ia32.c: Ditto. * efi-app-ia64.c: Ditto. ... --- bfd/ChangeLog | 52 ++++++++++++++ bfd/Makefile.am | 4 ++ bfd/Makefile.in | 4 ++ bfd/coff-ia64.c | 198 +++++++++++++++++++++++++++++++++++++++++++++++++++++ bfd/coffcode.h | 17 +++++ bfd/config.bfd | 2 +- bfd/configure | 27 ++++---- bfd/configure.in | 3 + bfd/efi-app-ia32.c | 35 ++++++++++ bfd/efi-app-ia64.c | 35 ++++++++++ bfd/libpei.h | 30 ++++++++ bfd/peigen.c | 167 ++++++++++++++++++++++++++++++++------------ bfd/targets.c | 7 ++ 13 files changed, 526 insertions(+), 55 deletions(-) create mode 100644 bfd/coff-ia64.c create mode 100644 bfd/efi-app-ia32.c create mode 100644 bfd/efi-app-ia64.c diff --git a/bfd/ChangeLog b/bfd/ChangeLog index a58eefb..cdc1b94 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,55 @@ +Mon Apr 17 19:14:36 2000 David Mosberger + + * Makefile.am (BFD64_BACKENDS): Mention coff-ia64.lo. + (BFD64_BACKENDS_CFILES): Mention coff-ia64.c + (coff-ia64.lo): Add dependency. + * Makefile.in: Regenerate. + * coff-ia64.c: New file. + * efi-app-ia32.c: Ditto. + * efi-app-ia64.c: Ditto. + * coffcode.h (coff_set_arch_mach_hook): Handle IA64MAGIC. + (coff_set_flags): Ditto. + (coff_write_object_contents) [IA64]: Set magic number to ZMAGIC. + * config.bfd (i[3456]86-*-linux-gnu*): Mention bfd_efi_app_ia32_vec. + * configure.in (elf): Handle bfd_efi_app_ia32 and bfd_efi_app_ia64_vec. + * configure: Regenerate. + * libpei.h (GET_OPTHDR_IMAGE_BASE): New macro. + (PUT_OPTHDR_IMAGE_BASE): Ditto. + (GET_OPTHDR_SIZE_OF_STACK_RESERVE): Ditto. + (PUT_OPTHDR_SIZE_OF_STACK_RESERVE): Ditto. + (GET_OPTHDR_SIZE_OF_STACK_COMMIT): Ditto. + (PUT_OPTHDR_SIZE_OF_STACK_COMMIT): Ditto. + (GET_OPTHDR_SIZE_OF_HEAP_RESERVE): Ditto. + (PUT_OPTHDR_SIZE_OF_HEAP_RESERVE): Ditto. + (GET_OPTHDR_SIZE_OF_HEAP_COMMIT): Ditto. + (PUT_OPTHDR_SIZE_OF_HEAP_COMMIT): Ditto. + (GET_PDATA_ENTRY): Ditto. + * peigen.c (_bfd_pei_swap_aouthdr_in) [COFF_WITH_PEP64]: Don't read + data_start. Use above macros to read fields that are 64 bit wide for + COFF_WITH_PEP64. Don't truncate entry and text_start to 32 bits. + (_bfd_pei_swap_aouthdr_out) [PEI_FORCE_MINIMUM_ALIGNMENT]: Force + FileAlignment and SectionAlignment to minimum alignment if they + are zero. + (_bfd_pei_swap_aouthdr_out) [PEI_DEFAULT_TARGET_SUBSYSTEM]: Set + Subsystem to default PEI_DEFAULT_TARGET_SUBSYSTEM. + (_bfd_pei_swap_aouthdr_out) [COFF_WITH_PEP64]: Don't set data_start. + Use above macros to write fields that are 64 bit wide for + COFF_WITH_PEP64. + (pe_print_pdata): Set PDATA_ROW_SIZE to 3*8 for COFF_WITH_PEP64, + 5*4 otherwise. This should be right for IA-32 and IA-64, but may + be wrong for platforms. Use PDATA_ROW_SIZE instead of hardcoded + value of 20 bytes. Modify printing for COFF_WITH_PEP64 to print + begin address, end address, and unwind info address only. Use + GET_PDATA_ENTRY() to read .pdata entries. Use fprintf_vma() to + print addresses. + (tbl): Add SECTION, REL32, RESERVED1, MIPS_JMPADDR16, DIR64, and + HIGH3ADJ relocation names. + (_bfd_pe_print_private_bfd_data): Print Subsystem name in legible form. + * targets.c: Declare bfd_efi_app_ia32_vec and + bfd_efi_app_ia64_vec. + (bfd_target_vector): Mention bfd_efi_app_ia32_vec and + bfd_efi_app_ia64_vec. + 2000-04-17 Timothy Wall * bfd-in2.h: Add prototypes for tic54x load page access. diff --git a/bfd/Makefile.am b/bfd/Makefile.am index f5dd526..142fa6d 100644 --- a/bfd/Makefile.am +++ b/bfd/Makefile.am @@ -385,6 +385,7 @@ BFD32_BACKENDS_CFILES = \ BFD64_BACKENDS = \ aout64.lo \ coff-alpha.lo \ + coff-ia64.lo \ demo64.lo \ elf64-alpha.lo \ elf64-gen.lo \ @@ -397,6 +398,7 @@ BFD64_BACKENDS = \ BFD64_BACKENDS_CFILES = \ aout64.c \ coff-alpha.c \ + coff-ia64.c \ demo64.c \ elf64-alpha.c \ elf64-gen.c \ @@ -1093,6 +1095,8 @@ coff-alpha.lo: coff-alpha.c $(INCDIR)/bfdlink.h $(INCDIR)/coff/internal.h \ $(INCDIR)/coff/sym.h $(INCDIR)/coff/symconst.h $(INCDIR)/coff/ecoff.h \ $(INCDIR)/coff/alpha.h $(INCDIR)/aout/ar.h libcoff.h \ libecoff.h coffswap.h ecoffswap.h +coff-ia64.lo: coff-ia64.c $(INCDIR)/coff/ia64.h $(INCDIR)/coff/internal.h \ + $(INCDIR)/coff/pe.h libcoff.h $(INCDIR)/bfdlink.h coffcode.h coffswap.h demo64.lo: demo64.c aoutf1.h $(INCDIR)/aout/sun4.h \ libaout.h $(INCDIR)/bfdlink.h $(INCDIR)/aout/aout64.h \ $(INCDIR)/aout/stab_gnu.h $(INCDIR)/aout/stab.def $(INCDIR)/aout/ar.h \ diff --git a/bfd/Makefile.in b/bfd/Makefile.in index 5e0e973..1421bb2 100644 --- a/bfd/Makefile.in +++ b/bfd/Makefile.in @@ -504,6 +504,7 @@ BFD32_BACKENDS_CFILES = \ BFD64_BACKENDS = \ aout64.lo \ coff-alpha.lo \ + coff-ia64.lo \ demo64.lo \ elf64-alpha.lo \ elf64-gen.lo \ @@ -517,6 +518,7 @@ BFD64_BACKENDS = \ BFD64_BACKENDS_CFILES = \ aout64.c \ coff-alpha.c \ + coff-ia64.c \ demo64.c \ elf64-alpha.c \ elf64-gen.c \ @@ -1621,6 +1623,8 @@ coff-alpha.lo: coff-alpha.c $(INCDIR)/bfdlink.h $(INCDIR)/coff/internal.h \ $(INCDIR)/coff/sym.h $(INCDIR)/coff/symconst.h $(INCDIR)/coff/ecoff.h \ $(INCDIR)/coff/alpha.h $(INCDIR)/aout/ar.h libcoff.h \ libecoff.h coffswap.h ecoffswap.h +coff-ia64.lo: coff-ia64.c $(INCDIR)/coff/ia64.h $(INCDIR)/coff/internal.h \ + $(INCDIR)/coff/pe.h libcoff.h $(INCDIR)/bfdlink.h coffcode.h coffswap.h demo64.lo: demo64.c aoutf1.h $(INCDIR)/aout/sun4.h \ libaout.h $(INCDIR)/bfdlink.h $(INCDIR)/aout/aout64.h \ $(INCDIR)/aout/stab_gnu.h $(INCDIR)/aout/stab.def $(INCDIR)/aout/ar.h \ diff --git a/bfd/coff-ia64.c b/bfd/coff-ia64.c new file mode 100644 index 0000000..df867e7 --- /dev/null +++ b/bfd/coff-ia64.c @@ -0,0 +1,198 @@ +/* BFD back-end for HP/Intel IA-64 COFF files. + Copyright 1999 Free Software Foundation, Inc. + Contributed by David Mosberger + +This file is part of BFD, the Binary File Descriptor library. + +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 +(at your option) 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#include "bfd.h" +#include "sysdep.h" +#include "libbfd.h" + +#include "coff/ia64.h" + +#include "coff/internal.h" + +#include "coff/pe.h" + +#include "libcoff.h" + +#define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (2) +/* The page size is a guess based on ELF. */ + +#define COFF_PAGE_SIZE 0x1000 + +static reloc_howto_type howto_table[] = +{ + {0}, +}; + +#define BADMAG(x) IA64BADMAG(x) +#define IA64 1 /* Customize coffcode.h */ + +#ifdef COFF_WITH_PEP64 +# undef AOUTSZ +# define AOUTSZ PEP64AOUTSZ +# define PEAOUTHDR PEP64AOUTHDR +#endif + +#define RTYPE2HOWTO(cache_ptr, dst) \ + (cache_ptr)->howto = howto_table + (dst)->r_type; + +#ifdef COFF_WITH_PE +/* Return true if this relocation should + appear in the output .reloc section. */ + +static boolean +in_reloc_p(abfd, howto) + bfd * abfd; + reloc_howto_type *howto; +{ + return 0; /* We don't do relocs for now... */ +} +#endif + +#include "coffcode.h" + +static const bfd_target * +ia64coff_object_p (abfd) + bfd *abfd; +{ +#ifdef COFF_IMAGE_WITH_PE + /* We need to hack badly to handle a PE image correctly. In PE + images created by the GNU linker, the offset to the COFF header + is always the size. However, this is not the case in images + generated by other PE linkers. The PE format stores a four byte + offset to the PE signature just before the COFF header at + location 0x3c of the file. We pick up that offset, verify that + the PE signature is there, and then set ourselves up to read in + the COFF header. */ + { + bfd_byte ext_offset[4]; + file_ptr offset; + bfd_byte ext_signature[4]; + unsigned long signature; + + if (bfd_seek (abfd, 0x3c, SEEK_SET) != 0 + || bfd_read (ext_offset, 1, 4, abfd) != 4) + { + if (bfd_get_error () != bfd_error_system_call) + bfd_set_error (bfd_error_wrong_format); + return NULL; + } + offset = bfd_h_get_32 (abfd, ext_offset); + if (bfd_seek (abfd, offset, SEEK_SET) != 0 + || bfd_read (ext_signature, 1, 4, abfd) != 4) + { + if (bfd_get_error () != bfd_error_system_call) + bfd_set_error (bfd_error_wrong_format); + return NULL; + } + signature = bfd_h_get_32 (abfd, ext_signature); + + if (signature != 0x4550) + { + bfd_set_error (bfd_error_wrong_format); + return NULL; + } + + /* Here is the hack. coff_object_p wants to read filhsz bytes to + pick up the COFF header. We adjust so that that will work. 20 + is the size of the COFF filehdr. */ + + if (bfd_seek (abfd, + (bfd_tell (abfd) + - bfd_coff_filhsz (abfd) + + 20), + SEEK_SET) + != 0) + { + if (bfd_get_error () != bfd_error_system_call) + bfd_set_error (bfd_error_wrong_format); + return NULL; + } + } +#endif + + return coff_object_p (abfd); +} + +const bfd_target +#ifdef TARGET_SYM + TARGET_SYM = +#else + ia64coff_vec = +#endif +{ +#ifdef TARGET_NAME + TARGET_NAME, +#else + "coff-ia64", /* name */ +#endif + bfd_target_coff_flavour, + BFD_ENDIAN_LITTLE, /* data byte order is little */ + BFD_ENDIAN_LITTLE, /* header byte order is little */ + + (HAS_RELOC | EXEC_P | /* object flags */ + HAS_LINENO | HAS_DEBUG | + HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED), + +#ifndef COFF_WITH_PE + (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC /* section flags */ + | SEC_CODE | SEC_DATA), +#else + (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC /* section flags */ + | SEC_CODE | SEC_DATA + | SEC_LINK_ONCE | SEC_LINK_DUPLICATES), +#endif + +#ifdef TARGET_UNDERSCORE + TARGET_UNDERSCORE, /* leading underscore */ +#else + 0, /* leading underscore */ +#endif + '/', /* ar_pad_char */ + 15, /* ar_max_namelen */ + + bfd_getl64, bfd_getl_signed_64, bfd_putl64, + bfd_getl32, bfd_getl_signed_32, bfd_putl32, + bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */ + bfd_getl64, bfd_getl_signed_64, bfd_putl64, + bfd_getl32, bfd_getl_signed_32, bfd_putl32, + bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */ + +/* Note that we allow an object file to be treated as a core file as well. */ + {_bfd_dummy_target, ia64coff_object_p, /* bfd_check_format */ + bfd_generic_archive_p, ia64coff_object_p}, + {bfd_false, coff_mkobject, _bfd_generic_mkarchive, /* bfd_set_format */ + bfd_false}, + {bfd_false, coff_write_object_contents, /* bfd_write_contents */ + _bfd_write_archive_contents, bfd_false}, + + BFD_JUMP_TABLE_GENERIC (coff), + BFD_JUMP_TABLE_COPY (coff), + BFD_JUMP_TABLE_CORE (_bfd_nocore), + BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff), + BFD_JUMP_TABLE_SYMBOLS (coff), + BFD_JUMP_TABLE_RELOCS (coff), + BFD_JUMP_TABLE_WRITE (coff), + BFD_JUMP_TABLE_LINK (coff), + BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), + + NULL, + + COFF_SWAP_TABLE +}; diff --git a/bfd/coffcode.h b/bfd/coffcode.h index a6e8b08..9474e93 100644 --- a/bfd/coffcode.h +++ b/bfd/coffcode.h @@ -1787,6 +1787,12 @@ coff_set_arch_mach_hook (abfd, filehdr) machine = 0; break; #endif +#ifdef IA64MAGIC + case IA64MAGIC: + arch = bfd_arch_ia64; + machine = 0; + break; +#endif #ifdef A29K_MAGIC_BIG case A29K_MAGIC_BIG: case A29K_MAGIC_LITTLE: @@ -2557,6 +2563,12 @@ coff_set_flags (abfd, magicp, flagsp) return true; break; #endif +#ifdef IA64MAGIC + case bfd_arch_ia64: + *magicp = IA64MAGIC; + return true; + break; +#endif #ifdef MC68MAGIC case bfd_arch_m68k: #ifdef APOLLOM68KMAGIC @@ -3635,6 +3647,11 @@ coff_write_object_contents (abfd) #endif /* LYNXOS */ #endif /* I386 */ +#if defined(IA64) +#define __A_MAGIC_SET__ + internal_a.magic = ZMAGIC; +#endif /* IA64 */ + #if defined(SPARC) #define __A_MAGIC_SET__ #if defined(LYNXOS) diff --git a/bfd/config.bfd b/bfd/config.bfd index 3d290a4..eaaac05 100644 --- a/bfd/config.bfd +++ b/bfd/config.bfd @@ -303,7 +303,7 @@ case "${targ}" in ;; i[3456]86-*-linux-gnu*) targ_defvec=bfd_elf32_i386_vec - targ_selvecs=i386linux_vec + targ_selvecs="i386linux_vec bfd_efi_app_ia32_vec" ;; i[3456]86-*-lynxos*) targ_defvec=i386lynx_coff_vec diff --git a/bfd/configure b/bfd/configure index 2f3ba7c..feaae04 100755 --- a/bfd/configure +++ b/bfd/configure @@ -5107,6 +5107,9 @@ do apollocoff_vec) tb="$tb coff-apollo.lo" ;; b_out_vec_big_host) tb="$tb bout.lo aout32.lo" ;; b_out_vec_little_host) tb="$tb bout.lo aout32.lo" ;; + bfd_efi_app_ia32_vec) tb="$tb efi-app-ia32.lo peigen.lo cofflink.lo" ;; + bfd_efi_app_ia64_vec) tb="$tb efi-app-ia64.lo peigen.lo cofflink.lo" + target64=true ;; bfd_elf64_alpha_vec) tb="$tb elf64-alpha.lo elf64.lo $elf" target64=true ;; bfd_elf32_avr_vec) tb="$tb elf32-avr.lo elf32.lo $elf" ;; @@ -5333,17 +5336,17 @@ for ac_hdr in unistd.h do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:5337: checking for $ac_hdr" >&5 +echo "configure:5340: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:5347: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:5350: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -5372,12 +5375,12 @@ done for ac_func in getpagesize do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:5376: checking for $ac_func" >&5 +echo "configure:5379: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:5407: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -5425,7 +5428,7 @@ fi done echo $ac_n "checking for working mmap""... $ac_c" 1>&6 -echo "configure:5429: checking for working mmap" >&5 +echo "configure:5432: checking for working mmap" >&5 if eval "test \"`echo '$''{'ac_cv_func_mmap_fixed_mapped'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -5433,7 +5436,7 @@ else ac_cv_func_mmap_fixed_mapped=no else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:5580: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then ac_cv_func_mmap_fixed_mapped=yes else @@ -5598,12 +5601,12 @@ fi for ac_func in madvise mprotect do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:5602: checking for $ac_func" >&5 +echo "configure:5605: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:5633: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else diff --git a/bfd/configure.in b/bfd/configure.in index 3e3a689..e62fcee 100644 --- a/bfd/configure.in +++ b/bfd/configure.in @@ -464,6 +464,9 @@ do apollocoff_vec) tb="$tb coff-apollo.lo" ;; b_out_vec_big_host) tb="$tb bout.lo aout32.lo" ;; b_out_vec_little_host) tb="$tb bout.lo aout32.lo" ;; + bfd_efi_app_ia32_vec) tb="$tb efi-app-ia32.lo peigen.lo cofflink.lo" ;; + bfd_efi_app_ia64_vec) tb="$tb efi-app-ia64.lo peigen.lo cofflink.lo" + target64=true ;; bfd_elf64_alpha_vec) tb="$tb elf64-alpha.lo elf64.lo $elf" target64=true ;; bfd_elf32_avr_vec) tb="$tb elf32-avr.lo elf32.lo $elf" ;; diff --git a/bfd/efi-app-ia32.c b/bfd/efi-app-ia32.c new file mode 100644 index 0000000..5784178 --- /dev/null +++ b/bfd/efi-app-ia32.c @@ -0,0 +1,35 @@ +/* BFD back-end for Intel IA-32 EFI application files. + Copyright 1999 Free Software Foundation, Inc. + Contributed by David Mosberger + +This file is part of BFD, the Binary File Descriptor library. + +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 +(at your option) 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#include "bfd.h" +#include "sysdep.h" + +#define TARGET_SYM bfd_efi_app_ia32_vec +#define TARGET_NAME "efi-app-ia32" +#define COFF_IMAGE_WITH_PE +#define COFF_WITH_PE +#define PCRELOFFSET true +#define TARGET_UNDERSCORE '_' +#define COFF_LONG_SECTION_NAMES +#define ALIGN_SECTIONS_IN_FILE +#define PEI_DEFAULT_TARGET_SUBSYSTEM IMAGE_SUBSYSTEM_EFI_APPLICATION +#define PEI_FORCE_MINIMUM_ALIGNMENT + +#include "coff-i386.c" diff --git a/bfd/efi-app-ia64.c b/bfd/efi-app-ia64.c new file mode 100644 index 0000000..b3182dc --- /dev/null +++ b/bfd/efi-app-ia64.c @@ -0,0 +1,35 @@ +/* BFD back-end for HP/Intel IA-64 EFI application files. + Copyright 1999 Free Software Foundation, Inc. + Contributed by David Mosberger + +This file is part of BFD, the Binary File Descriptor library. + +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 +(at your option) 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#include "bfd.h" +#include "sysdep.h" + +#define TARGET_SYM bfd_efi_app_ia64_vec +#define TARGET_NAME "efi-app-ia64" +#define COFF_IMAGE_WITH_PE +#define COFF_WITH_PE +#define COFF_WITH_PEP64 +#define PCRELOFFSET true +#define TARGET_UNDERSCORE '_' +#define COFF_LONG_SECTION_NAMES +#define PEI_DEFAULT_TARGET_SUBSYSTEM IMAGE_SUBSYSTEM_EFI_APPLICATION +#define PEI_FORCE_MINIMUM_ALIGNMENT + +#include "coff-ia64.c" diff --git a/bfd/libpei.h b/bfd/libpei.h index 88f9f73..db47e37 100644 --- a/bfd/libpei.h +++ b/bfd/libpei.h @@ -192,6 +192,36 @@ PE/PEI rearrangement (and code added): Donn Terry #define PUT_SCNHDR_LNNOPTR bfd_h_put_32 #endif +#ifdef COFF_WITH_PEP64 + +#define GET_OPTHDR_IMAGE_BASE bfd_h_get_64 +#define PUT_OPTHDR_IMAGE_BASE bfd_h_put_64 +#define GET_OPTHDR_SIZE_OF_STACK_RESERVE bfd_h_get_64 +#define PUT_OPTHDR_SIZE_OF_STACK_RESERVE bfd_h_put_64 +#define GET_OPTHDR_SIZE_OF_STACK_COMMIT bfd_h_get_64 +#define PUT_OPTHDR_SIZE_OF_STACK_COMMIT bfd_h_put_64 +#define GET_OPTHDR_SIZE_OF_HEAP_RESERVE bfd_h_get_64 +#define PUT_OPTHDR_SIZE_OF_HEAP_RESERVE bfd_h_put_64 +#define GET_OPTHDR_SIZE_OF_HEAP_COMMIT bfd_h_get_64 +#define PUT_OPTHDR_SIZE_OF_HEAP_COMMIT bfd_h_put_64 +#define GET_PDATA_ENTRY bfd_get_64 + +#else /* !COFF_WITH_PEP64 */ + +#define GET_OPTHDR_IMAGE_BASE bfd_h_get_32 +#define PUT_OPTHDR_IMAGE_BASE bfd_h_put_32 +#define GET_OPTHDR_SIZE_OF_STACK_RESERVE bfd_h_get_32 +#define PUT_OPTHDR_SIZE_OF_STACK_RESERVE bfd_h_put_32 +#define GET_OPTHDR_SIZE_OF_STACK_COMMIT bfd_h_get_32 +#define PUT_OPTHDR_SIZE_OF_STACK_COMMIT bfd_h_put_32 +#define GET_OPTHDR_SIZE_OF_HEAP_RESERVE bfd_h_get_32 +#define PUT_OPTHDR_SIZE_OF_HEAP_RESERVE bfd_h_put_32 +#define GET_OPTHDR_SIZE_OF_HEAP_COMMIT bfd_h_get_32 +#define PUT_OPTHDR_SIZE_OF_HEAP_COMMIT bfd_h_put_32 +#define GET_PDATA_ENTRY bfd_get_32 + +#endif /* !COFF_WITH_PEP64 */ + /* These functions are architecture dependent, and are in peicode.h: coff_swap_reloc_in int coff_swap_reloc_out diff --git a/bfd/peigen.c b/bfd/peigen.c index 639ea89..aad3cd6 100644 --- a/bfd/peigen.c +++ b/bfd/peigen.c @@ -434,11 +434,14 @@ _bfd_pei_swap_aouthdr_in (abfd, aouthdr_ext1, aouthdr_int1) GET_AOUTHDR_ENTRY (abfd, (bfd_byte *) aouthdr_ext->entry); aouthdr_int->text_start = GET_AOUTHDR_TEXT_START (abfd, (bfd_byte *) aouthdr_ext->text_start); +#ifndef COFF_WITH_PEP64 + /* PE32+ does not have data_start member! */ aouthdr_int->data_start = GET_AOUTHDR_DATA_START (abfd, (bfd_byte *) aouthdr_ext->data_start); +#endif a = &aouthdr_int->pe; - a->ImageBase = bfd_h_get_32 (abfd, (bfd_byte *)src->ImageBase); + a->ImageBase = GET_OPTHDR_IMAGE_BASE (abfd, (bfd_byte *)src->ImageBase); a->SectionAlignment = bfd_h_get_32 (abfd, (bfd_byte *)src->SectionAlignment); a->FileAlignment = bfd_h_get_32 (abfd, (bfd_byte *)src->FileAlignment); a->MajorOperatingSystemVersion = @@ -455,10 +458,10 @@ _bfd_pei_swap_aouthdr_in (abfd, aouthdr_ext1, aouthdr_int1) a->CheckSum = bfd_h_get_32 (abfd, (bfd_byte *)src->CheckSum); a->Subsystem = bfd_h_get_16 (abfd, (bfd_byte *)src->Subsystem); a->DllCharacteristics = bfd_h_get_16 (abfd, (bfd_byte *)src->DllCharacteristics); - a->SizeOfStackReserve = bfd_h_get_32 (abfd, (bfd_byte *)src->SizeOfStackReserve); - a->SizeOfStackCommit = bfd_h_get_32 (abfd, (bfd_byte *)src->SizeOfStackCommit); - a->SizeOfHeapReserve = bfd_h_get_32 (abfd, (bfd_byte *)src->SizeOfHeapReserve); - a->SizeOfHeapCommit = bfd_h_get_32 (abfd, (bfd_byte *)src->SizeOfHeapCommit); + a->SizeOfStackReserve = GET_OPTHDR_SIZE_OF_STACK_RESERVE (abfd, (bfd_byte *)src->SizeOfStackReserve); + a->SizeOfStackCommit = GET_OPTHDR_SIZE_OF_STACK_COMMIT (abfd, (bfd_byte *)src->SizeOfStackCommit); + a->SizeOfHeapReserve = GET_OPTHDR_SIZE_OF_HEAP_RESERVE (abfd, (bfd_byte *)src->SizeOfHeapReserve); + a->SizeOfHeapCommit = GET_OPTHDR_SIZE_OF_HEAP_COMMIT (abfd, (bfd_byte *)src->SizeOfHeapCommit); a->LoaderFlags = bfd_h_get_32 (abfd, (bfd_byte *)src->LoaderFlags); a->NumberOfRvaAndSizes = bfd_h_get_32 (abfd, (bfd_byte *)src->NumberOfRvaAndSizes); @@ -476,18 +479,25 @@ _bfd_pei_swap_aouthdr_in (abfd, aouthdr_ext1, aouthdr_int1) if (aouthdr_int->entry) { aouthdr_int->entry += a->ImageBase; +#ifndef COFF_WITH_PEP64 aouthdr_int->entry &= 0xffffffff; +#endif } if (aouthdr_int->tsize) { aouthdr_int->text_start += a->ImageBase; +#ifndef COFF_WITH_PEP64 aouthdr_int->text_start &= 0xffffffff; +#endif } +#ifndef COFF_WITH_PEP64 + /* PE32+ does not have data_start member! */ if (aouthdr_int->dsize) { aouthdr_int->data_start += a->ImageBase; aouthdr_int->data_start &= 0xffffffff; } +#endif #ifdef POWERPC_LE_PE /* These three fields are normally set up by ppc_relocate_section. @@ -532,10 +542,28 @@ _bfd_pei_swap_aouthdr_out (abfd, in, out) struct internal_aouthdr *aouthdr_in = (struct internal_aouthdr *)in; struct internal_extra_pe_aouthdr *extra = &pe_data (abfd)->pe_opthdr; PEAOUTHDR *aouthdr_out = (PEAOUTHDR *)out; + bfd_vma sa, fa, ib; + + /* The following definitely is required for EFI applications. + Perhaps it's needed for other PEI targets as well, but I don't + know that for a fact, so we play it safe here and tweak the + alignments only if PEI_FORCE_MINIMUM_ALIGNMENT is + defined. --davidm */ +#ifdef PEI_FORCE_MINIMUM_ALIGNMENT + if (!extra->FileAlignment) + extra->FileAlignment = PE_DEF_FILE_ALIGNMENT; + if (!extra->SectionAlignment) + extra->SectionAlignment = PE_DEF_SECTION_ALIGNMENT; +#endif - bfd_vma sa = extra->SectionAlignment; - bfd_vma fa = extra->FileAlignment; - bfd_vma ib = extra->ImageBase ; +#ifdef PEI_DEFAULT_TARGET_SUBSYSTEM + if (extra->Subsystem == IMAGE_SUBSYSTEM_UNKNOWN) + extra->Subsystem = PEI_DEFAULT_TARGET_SUBSYSTEM; +#endif + + sa = extra->SectionAlignment; + fa = extra->FileAlignment; + ib = extra->ImageBase; if (aouthdr_in->tsize) { @@ -633,12 +661,14 @@ _bfd_pei_swap_aouthdr_out (abfd, in, out) PUT_AOUTHDR_TEXT_START (abfd, aouthdr_in->text_start, (bfd_byte *) aouthdr_out->standard.text_start); +#ifndef COFF_WITH_PEP64 + /* PE32+ does not have data_start member! */ PUT_AOUTHDR_DATA_START (abfd, aouthdr_in->data_start, (bfd_byte *) aouthdr_out->standard.data_start); +#endif - - bfd_h_put_32 (abfd, extra->ImageBase, - (bfd_byte *) aouthdr_out->ImageBase); + PUT_OPTHDR_IMAGE_BASE (abfd, extra->ImageBase, + (bfd_byte *) aouthdr_out->ImageBase); bfd_h_put_32 (abfd, extra->SectionAlignment, (bfd_byte *) aouthdr_out->SectionAlignment); bfd_h_put_32 (abfd, extra->FileAlignment, @@ -667,14 +697,14 @@ _bfd_pei_swap_aouthdr_out (abfd, in, out) (bfd_byte *) aouthdr_out->Subsystem); bfd_h_put_16 (abfd, extra->DllCharacteristics, (bfd_byte *) aouthdr_out->DllCharacteristics); - bfd_h_put_32 (abfd, extra->SizeOfStackReserve, - (bfd_byte *) aouthdr_out->SizeOfStackReserve); - bfd_h_put_32 (abfd, extra->SizeOfStackCommit, - (bfd_byte *) aouthdr_out->SizeOfStackCommit); - bfd_h_put_32 (abfd, extra->SizeOfHeapReserve, - (bfd_byte *) aouthdr_out->SizeOfHeapReserve); - bfd_h_put_32 (abfd, extra->SizeOfHeapCommit, - (bfd_byte *) aouthdr_out->SizeOfHeapCommit); + PUT_OPTHDR_SIZE_OF_STACK_RESERVE (abfd, extra->SizeOfStackReserve, + (bfd_byte *) aouthdr_out->SizeOfStackReserve); + PUT_OPTHDR_SIZE_OF_STACK_COMMIT (abfd, extra->SizeOfStackCommit, + (bfd_byte *) aouthdr_out->SizeOfStackCommit); + PUT_OPTHDR_SIZE_OF_HEAP_RESERVE (abfd, extra->SizeOfHeapReserve, + (bfd_byte *) aouthdr_out->SizeOfHeapReserve); + PUT_OPTHDR_SIZE_OF_HEAP_COMMIT (abfd, extra->SizeOfHeapCommit, + (bfd_byte *) aouthdr_out->SizeOfHeapCommit); bfd_h_put_32 (abfd, extra->LoaderFlags, (bfd_byte *) aouthdr_out->LoaderFlags); bfd_h_put_32 (abfd, extra->NumberOfRvaAndSizes, @@ -1473,18 +1503,27 @@ pe_print_edata (abfd, vfile) return true; } +/* This really is architecture dependent. On IA-64, a .pdata entry + consists of three dwords containing relative virtual addresses that + specify the start and end address of the code range the entry + covers and the address of the corresponding unwind info data. */ static boolean pe_print_pdata (abfd, vfile) bfd *abfd; PTR vfile; { +#ifdef COFF_WITH_PEP64 +# define PDATA_ROW_SIZE (3*8) +#else +# define PDATA_ROW_SIZE (5*4) +#endif FILE *file = (FILE *) vfile; bfd_byte *data = 0; asection *section = bfd_get_section_by_name (abfd, ".pdata"); bfd_size_type datasize = 0; bfd_size_type i; bfd_size_type start, stop; - int onaline = 20; + int onaline = PDATA_ROW_SIZE; if (section == NULL || coff_section_data (abfd, section) == NULL @@ -1498,10 +1537,15 @@ pe_print_pdata (abfd, vfile) fprintf (file, _("\nThe Function Table (interpreted .pdata section contents)\n")); +#ifdef COFF_WITH_PEP64 + fprintf(file, + _(" vma:\t\t\tBegin Address End Address Unwind Info\n")); +#else fprintf (file, _(" vma:\t\tBegin End EH EH PrologEnd Exception\n")); fprintf (file, _(" \t\tAddress Address Handler Data Address Mask\n")); +#endif if (bfd_section_size (abfd, section) == 0) return true; @@ -1527,14 +1571,14 @@ pe_print_pdata (abfd, vfile) bfd_vma prolog_end_addr; int em_data; - if (i + 20 > stop) + if (i + PDATA_ROW_SIZE > stop) break; - begin_addr = bfd_get_32(abfd, data+i); - end_addr = bfd_get_32(abfd, data+i+4); - eh_handler = bfd_get_32(abfd, data+i+8); - eh_data = bfd_get_32(abfd, data+i+12); - prolog_end_addr = bfd_get_32(abfd, data+i+16); + begin_addr = GET_PDATA_ENTRY(abfd, data+i); + end_addr = GET_PDATA_ENTRY(abfd, data+i+4); + eh_handler = GET_PDATA_ENTRY(abfd, data+i+8); + eh_data = GET_PDATA_ENTRY(abfd, data+i+12); + prolog_end_addr = GET_PDATA_ENTRY(abfd, data+i+16); if (begin_addr == 0 && end_addr == 0 && eh_handler == 0 && eh_data == 0 && prolog_end_addr == 0) @@ -1543,21 +1587,21 @@ pe_print_pdata (abfd, vfile) break; } - fprintf (file, - " %08lx\t", - (unsigned long int) (i + section->vma)); - em_data = ((eh_handler & 0x1) << 2) | (prolog_end_addr & 0x3); - eh_handler &= 0xfffffffc; - prolog_end_addr &= 0xfffffffc; - - fprintf (file, "%08lx %08lx %08lx %08lx %08lx %x", - begin_addr, - end_addr, - eh_handler, - eh_data, - prolog_end_addr, - em_data); + eh_handler &= ~ (bfd_vma) 0x3; + prolog_end_addr &= ~ (bfd_vma) 0x3; + + fputc (' ', file); + fprintf_vma (file, i + section->vma); fputc ('\t', file); + fprintf_vma (file, begin_addr); fputc (' ', file); + fprintf_vma (file, end_addr); fputc (' ', file); + fprintf_vma (file, eh_handler); +#ifndef COFF_WITH_PEP64 + fputc (' ', file); + fprintf_vma (file, eh_data); fputc (' ', file); + fprintf_vma (file, prolog_end_addr); + fprintf (file, " %x", em_data); +#endif #ifdef POWERPC_LE_PE if (eh_handler == 0 && eh_data != 0) @@ -1603,6 +1647,12 @@ static const char * const tbl[] = "HIGHLOW", "HIGHADJ", "MIPS_JMPADDR", +"SECTION", +"REL32", +"RESERVED1", +"MIPS_JMPADDR16", +"DIR64", +"HIGH3ADJ" "UNKNOWN", /* MUST be last */ }; @@ -1707,6 +1757,7 @@ _bfd_pe_print_private_bfd_data_common (abfd, vfile) int j; pe_data_type *pe = pe_data (abfd); struct internal_extra_pe_aouthdr *i = &pe->pe_opthdr; + const char *subsystem_name = NULL; /* The MS dumpbin program reportedly ands with 0xff0f before printing the characteristics field. Not sure why. No reason to @@ -1744,8 +1795,40 @@ _bfd_pe_print_private_bfd_data_common (abfd, vfile) fprintf (file,"SizeOfImage\t\t%08lx\n", i->SizeOfImage); fprintf (file,"SizeOfHeaders\t\t%08lx\n", i->SizeOfHeaders); fprintf (file,"CheckSum\t\t%08lx\n", i->CheckSum); - fprintf (file,"Subsystem\t\t%08x\n", i->Subsystem); - fprintf (file,"DllCharacteristics\t%08x\n", i->DllCharacteristics); + switch (i->Subsystem) + { + case IMAGE_SUBSYSTEM_UNKNOWN: + subsystem_name = "unspecified"; + break; + case IMAGE_SUBSYSTEM_NATIVE: + subsystem_name = "NT native"; + break; + case IMAGE_SUBSYSTEM_WINDOWS_GUI: + subsystem_name = "Windows GUI"; + break; + case IMAGE_SUBSYSTEM_WINDOWS_CUI: + subsystem_name = "Windows CUI"; + break; + case IMAGE_SUBSYSTEM_POSIX_CUI: + subsystem_name = "POSIX CUI"; + break; + case IMAGE_SUBSYSTEM_WINDOWS_CE_GUI: + subsystem_name = "Wince CUI"; + break; + case IMAGE_SUBSYSTEM_EFI_APPLICATION: + subsystem_name = "EFI application"; + break; + case IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER: + subsystem_name = "EFI boot service driver"; + break; + case IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER: + subsystem_name = "EFI runtime driver"; + break; + } + fprintf (file,"Subsystem\t\t%08x", i->Subsystem); + if (subsystem_name) + fprintf (file, "\t(%s)", subsystem_name); + fprintf (file,"\nDllCharacteristics\t%08x\n", i->DllCharacteristics); fprintf (file,"SizeOfStackReserve\t"); fprintf_vma (file, i->SizeOfStackReserve); fprintf (file,"\nSizeOfStackCommit\t"); diff --git a/bfd/targets.c b/bfd/targets.c index e54eb29..8217d56 100644 --- a/bfd/targets.c +++ b/bfd/targets.c @@ -505,6 +505,8 @@ extern const bfd_target arm_epoc_pei_little_vec; extern const bfd_target arm_epoc_pei_big_vec; extern const bfd_target b_out_vec_big_host; extern const bfd_target b_out_vec_little_host; +extern const bfd_target bfd_efi_app_ia32_vec; +extern const bfd_target bfd_efi_app_ia64_vec; extern const bfd_target bfd_elf64_alpha_vec; extern const bfd_target bfd_elf32_avr_vec; extern const bfd_target bfd_elf32_bigarc_vec; @@ -689,6 +691,11 @@ const bfd_target * const bfd_target_vector[] = { &b_out_vec_big_host, &b_out_vec_little_host, + &bfd_efi_app_ia32_vec, +#ifdef BFD64 + &bfd_efi_app_ia64_vec, +#endif + /* This, and other vectors, may not be used in any *.mt configuration. But that does not mean they are unnecessary. If configured with --enable-targets=all, objdump or gdb should be able to examine -- 2.7.4