aboutsummaryrefslogtreecommitdiff
path: root/bfd
diff options
context:
space:
mode:
authorNick Clifton <nickc@redhat.com>2006-09-20 11:35:11 +0000
committerNick Clifton <nickc@redhat.com>2006-09-20 11:35:11 +0000
commit99ad839030c1177eb409a99320fa7e60226f0db3 (patch)
tree31841958e04c69ceb1aeafcf7cdef5e721d23829 /bfd
parenta8bbe5b03e6b16a41a69e570061e34014d30431a (diff)
downloadgdb-99ad839030c1177eb409a99320fa7e60226f0db3.zip
gdb-99ad839030c1177eb409a99320fa7e60226f0db3.tar.gz
gdb-99ad839030c1177eb409a99320fa7e60226f0db3.tar.bz2
Add x86_64-mingw64 target
Diffstat (limited to 'bfd')
-rw-r--r--bfd/ChangeLog33
-rw-r--r--bfd/Makefile.am21
-rw-r--r--bfd/Makefile.in21
-rw-r--r--bfd/coff-x86_64.c768
-rw-r--r--bfd/coffcode.h29
-rw-r--r--bfd/config.bfd8
-rwxr-xr-xbfd/configure9
-rw-r--r--bfd/configure.in3
-rw-r--r--bfd/libpei.h34
-rw-r--r--bfd/pe-x86_64.c53
-rw-r--r--bfd/peXXigen.c71
-rw-r--r--bfd/pei-x86_64.c54
-rw-r--r--bfd/peicode.h43
-rw-r--r--bfd/targets.c12
14 files changed, 1119 insertions, 40 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 16d81db..8b5d2a2 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,36 @@
+2006-09-20 Kai Tietz <Kai.Tietz@onevision.com>
+
+ * configure.in: Added new target-vectors x86_64coff_vec,
+ x86_64pe_vec, and x86_64pei_vec.
+ * configure: Regenerate.
+ * config.bfd: Adjusted x86_64 target architecture detection.
+ * bfd.c: Add for new target "coff-x86-64"
+ (bfd_get_sign_extend): Add target vector idents for pe-x86-64. and pei-x86-64.
+ * coff-x86_64.c: Add new file for x86_64 (AMD64) coff support.
+ * libpei.h: Adjustments for COFF_WITH_pex64.
+ * coffcode.h: Add for new target machine, architecture, signature, and internal
+ signature handler.
+ * Makefile.am: Add new files to target-all and define make-rule for pex64igen.c
+ * Makefile.in: Regenerate.
+ * pe-x86_64.c: Add for new target "pe-x86-64".
+ * pei-x86_64.c: Add for new target "pei-x86-64".
+ * peicode.h: Adjusts for new targets.
+ (coff_swap_filehdr_out): Set for this target to
+ _bfd_pex64_only_swap_filehdr_out.
+ (SIZEOF_IDATA4): Define it as 8 byte size for this target.
+ (SIZEOF_IDATA5): Define it as 8 byte size for this target.
+ (jump_table jtab): Add for AMD64MAGIC.
+ (pe_ILF_build_a_bfd): Adjusts for new size of SIZEOF_IDATA4 and SIZE_IDATA5.
+ (pe_ILF_object_p): Add coff image-file signature to internal
+ signature translation.
+ * peXXigen.c: Adjust proper include of target coff-header and
+ introduced target specific code
+ (COFF_WITH_pex64): New macro for this target.
+ (pe_print_idata): New dumping method for import section of PE+ files.
+ * targets.c: Add new target vectors declarations for x86_64 coff targets.
+ * coffcode.h: Support code to support the x86_64 PE magic number.
+ * coff-x86_64.c: New file.
+
2006-09-17 Hans-Peter Nilsson <hp@axis.com>
* elf.c (special_sections_s): Revert last STRING_COMMA_LEN change
diff --git a/bfd/Makefile.am b/bfd/Makefile.am
index 175820e..df9b2a9 100644
--- a/bfd/Makefile.am
+++ b/bfd/Makefile.am
@@ -563,7 +563,11 @@ BFD64_BACKENDS = \
mmo.lo \
nlm32-alpha.lo \
nlm64.lo \
- pepigen.lo
+ coff-x86_64.lo \
+ pe-x86_64.lo \
+ pei-x86_64.lo \
+ pepigen.lo \
+ pex64igen.lo
BFD64_BACKENDS_CFILES = \
aix5ppc-core.c \
@@ -586,7 +590,10 @@ BFD64_BACKENDS_CFILES = \
elf64.c \
mmo.c \
nlm32-alpha.c \
- nlm64.c
+ nlm64.c \
+ coff-x86_64.c \
+ pe-x86_64.c \
+ pei-x86_64.c
OPTIONAL_BACKENDS = \
aix386-core.lo \
@@ -636,7 +643,7 @@ SOURCE_CFILES = \
$(OPTIONAL_BACKENDS_CFILES)
BUILD_CFILES = \
- elf32-ia64.c elf64-ia64.c peigen.c pepigen.c
+ elf32-ia64.c elf64-ia64.c peigen.c pepigen.c pex64igen.c
CFILES = $(SOURCE_CFILES) $(BUILD_CFILES)
@@ -794,6 +801,11 @@ pepigen.c : peXXigen.c
sed -e s/XX/pep/g < $(srcdir)/peXXigen.c > pepigen.new
mv -f pepigen.new pepigen.c
+pex64igen.c: peXXigen.c
+ rm -f pex64igen.c
+ sed -e s/XX/pex64/g < $(srcdir)/peXXigen.c > pex64igen.new
+ mv -f pex64igen.new pex64igen.c
+
BFD_H_DEPS= $(INCDIR)/ansidecl.h $(INCDIR)/symcat.h
LOCAL_H_DEPS= libbfd.h sysdep.h config.h
$(BFD32_LIBS) \
@@ -1861,4 +1873,7 @@ peigen.lo: peigen.c $(INCDIR)/filenames.h $(INCDIR)/hashtab.h \
pepigen.lo: pepigen.c $(INCDIR)/filenames.h $(INCDIR)/hashtab.h \
$(INCDIR)/coff/internal.h $(INCDIR)/coff/ia64.h $(INCDIR)/coff/external.h \
$(INCDIR)/coff/pe.h libcoff.h $(INCDIR)/bfdlink.h libpei.h
+pex64igen.lo: pex64igen.c $(INCDIR)/filenames.h $(INCDIR)/hashtab.h \
+ $(INCDIR)/coff/internal.h $(INCDIR)/coff/x86_64.h $(INCDIR)/coff/external.h \
+ $(INCDIR)/coff/pe.h libcoff.h $(INCDIR)/bfdlink.h libpei.h
# IF YOU PUT ANYTHING HERE IT WILL GO AWAY
diff --git a/bfd/Makefile.in b/bfd/Makefile.in
index 8a15b44..312b730 100644
--- a/bfd/Makefile.in
+++ b/bfd/Makefile.in
@@ -796,7 +796,11 @@ BFD64_BACKENDS = \
mmo.lo \
nlm32-alpha.lo \
nlm64.lo \
- pepigen.lo
+ coff-x86_64.lo \
+ pe-x86_64.lo \
+ pei-x86_64.lo \
+ pepigen.lo \
+ pex64igen.lo
BFD64_BACKENDS_CFILES = \
aix5ppc-core.c \
@@ -819,7 +823,10 @@ BFD64_BACKENDS_CFILES = \
elf64.c \
mmo.c \
nlm32-alpha.c \
- nlm64.c
+ nlm64.c \
+ coff-x86_64.c \
+ pe-x86_64.c \
+ pei-x86_64.c
OPTIONAL_BACKENDS = \
aix386-core.lo \
@@ -870,7 +877,7 @@ SOURCE_CFILES = \
$(OPTIONAL_BACKENDS_CFILES)
BUILD_CFILES = \
- elf32-ia64.c elf64-ia64.c peigen.c pepigen.c
+ elf32-ia64.c elf64-ia64.c peigen.c pepigen.c pex64igen.c
CFILES = $(SOURCE_CFILES) $(BUILD_CFILES)
SOURCE_HFILES = \
@@ -1372,6 +1379,11 @@ pepigen.c : peXXigen.c
rm -f pepigen.c
sed -e s/XX/pep/g < $(srcdir)/peXXigen.c > pepigen.new
mv -f pepigen.new pepigen.c
+
+pex64igen.c: peXXigen.c
+ rm -f pex64igen.c
+ sed -e s/XX/pex64/g < $(srcdir)/peXXigen.c > pex64igen.new
+ mv -f pex64igen.new pex64igen.c
$(BFD32_LIBS) \
$(BFD64_LIBS) \
$(ALL_MACHINES) \
@@ -2422,6 +2434,9 @@ peigen.lo: peigen.c $(INCDIR)/filenames.h $(INCDIR)/hashtab.h \
pepigen.lo: pepigen.c $(INCDIR)/filenames.h $(INCDIR)/hashtab.h \
$(INCDIR)/coff/internal.h $(INCDIR)/coff/ia64.h $(INCDIR)/coff/external.h \
$(INCDIR)/coff/pe.h libcoff.h $(INCDIR)/bfdlink.h libpei.h
+pex64igen.lo: pex64igen.c $(INCDIR)/filenames.h $(INCDIR)/hashtab.h \
+ $(INCDIR)/coff/internal.h $(INCDIR)/coff/x86_64.h $(INCDIR)/coff/external.h \
+ $(INCDIR)/coff/pe.h libcoff.h $(INCDIR)/bfdlink.h libpei.h
# IF YOU PUT ANYTHING HERE IT WILL GO AWAY
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
diff --git a/bfd/coff-x86_64.c b/bfd/coff-x86_64.c
new file mode 100644
index 0000000..772e1eb
--- /dev/null
+++ b/bfd/coff-x86_64.c
@@ -0,0 +1,768 @@
+/* BFD back-end for AMD 64 COFF files.
+ Copyright 2006 Free Software Foundation, Inc.
+
+ 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., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
+
+ Written by Kai Tietz, OneVision Software GmbH&CoKg. */
+
+#ifndef COFF_WITH_pex64
+#define COFF_WITH_pex64
+#endif
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+#include "coff/x86_64.h"
+#include "coff/internal.h"
+#include "coff/pe.h"
+#include "libcoff.h"
+#include "libiberty.h"
+
+#define BADMAG(x) AMD64BADMAG(x)
+
+#ifdef COFF_WITH_pex64
+# undef AOUTSZ
+# define AOUTSZ PEPAOUTSZ
+# define PEAOUTHDR PEPAOUTHDR
+#endif
+
+#define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (2)
+
+/* The page size is a guess based on ELF. */
+
+#define COFF_PAGE_SIZE 0x1000
+
+/* For some reason when using AMD COFF the value stored in the .text
+ section for a reference to a common symbol is the value itself plus
+ any desired offset. Ian Taylor, Cygnus Support. */
+
+/* If we are producing relocatable output, we need to do some
+ adjustments to the object file that are not done by the
+ bfd_perform_relocation function. This function is called by every
+ reloc type to make any required adjustments. */
+
+static bfd_reloc_status_type
+coff_amd64_reloc (bfd *abfd,
+ arelent *reloc_entry,
+ asymbol *symbol,
+ void * data,
+ asection *input_section ATTRIBUTE_UNUSED,
+ bfd *output_bfd,
+ char **error_message ATTRIBUTE_UNUSED)
+{
+ symvalue diff;
+
+#if !defined(COFF_WITH_PE)
+ if (output_bfd == NULL)
+ return bfd_reloc_continue;
+#endif
+
+ if (bfd_is_com_section (symbol->section))
+ {
+#if !defined(COFF_WITH_PE)
+ /* We are relocating a common symbol. The current value in the
+ object file is ORIG + OFFSET, where ORIG is the value of the
+ common symbol as seen by the object file when it was compiled
+ (this may be zero if the symbol was undefined) and OFFSET is
+ the offset into the common symbol (normally zero, but may be
+ non-zero when referring to a field in a common structure).
+ ORIG is the negative of reloc_entry->addend, which is set by
+ the CALC_ADDEND macro below. We want to replace the value in
+ the object file with NEW + OFFSET, where NEW is the value of
+ the common symbol which we are going to put in the final
+ object file. NEW is symbol->value. */
+ diff = symbol->value + reloc_entry->addend;
+#else
+ /* In PE mode, we do not offset the common symbol. */
+ diff = reloc_entry->addend;
+#endif
+ }
+ else
+ {
+ /* For some reason bfd_perform_relocation always effectively
+ ignores the addend for a COFF target when producing
+ relocatable output. This seems to be always wrong for 386
+ COFF, so we handle the addend here instead. */
+#if defined(COFF_WITH_PE)
+ if (output_bfd == NULL)
+ {
+ reloc_howto_type *howto = reloc_entry->howto;
+
+ /* Although PC relative relocations are very similar between
+ PE and non-PE formats, but they are off by 1 << howto->size
+ bytes. For the external relocation, PE is very different
+ from others. See md_apply_fix3 () in gas/config/tc-amd64.c.
+ When we link PE and non-PE object files together to
+ generate a non-PE executable, we have to compensate it
+ here. */
+ if(howto->pc_relative && howto->pcrel_offset)
+ diff = -(1 << howto->size);
+ else if(symbol->flags & BSF_WEAK)
+ diff = reloc_entry->addend - symbol->value;
+ else
+ diff = -reloc_entry->addend;
+ }
+ else
+#endif
+ diff = reloc_entry->addend;
+ }
+
+#if defined(COFF_WITH_PE)
+ /* FIXME: How should this case be handled? */
+ if (reloc_entry->howto->type == R_AMD64_IMAGEBASE
+ && output_bfd != NULL
+ && bfd_get_flavour (output_bfd) == bfd_target_coff_flavour)
+ diff -= pe_data (output_bfd)->pe_opthdr.ImageBase;
+#endif
+
+#define DOIT(x) \
+ x = ((x & ~howto->dst_mask) | (((x & howto->src_mask) + diff) & howto->dst_mask))
+
+ if (diff != 0)
+ {
+ reloc_howto_type *howto = reloc_entry->howto;
+ unsigned char *addr = (unsigned char *) data + reloc_entry->address;
+
+ switch (howto->size)
+ {
+ case 0:
+ {
+ char x = bfd_get_8 (abfd, addr);
+ DOIT (x);
+ bfd_put_8 (abfd, x, addr);
+ }
+ break;
+
+ case 1:
+ {
+ short x = bfd_get_16 (abfd, addr);
+ DOIT (x);
+ bfd_put_16 (abfd, (bfd_vma) x, addr);
+ }
+ break;
+
+ case 2:
+ {
+ long x = bfd_get_32 (abfd, addr);
+ DOIT (x);
+ bfd_put_32 (abfd, (bfd_vma) x, addr);
+ }
+ break;
+ case 4:
+ {
+ long long x = bfd_get_64 (abfd, addr);
+ DOIT (x);
+ bfd_put_64 (abfd, (bfd_vma) x, addr);
+ }
+ break;
+
+ default:
+ abort ();
+ }
+ }
+
+ /* Now let bfd_perform_relocation finish everything up. */
+ return bfd_reloc_continue;
+}
+
+#if defined(COFF_WITH_PE)
+/* Return TRUE if this relocation should appear in the output .reloc
+ section. */
+
+static bfd_boolean
+in_reloc_p (bfd *abfd ATTRIBUTE_UNUSED, reloc_howto_type *howto)
+{
+ return ! howto->pc_relative && howto->type != R_AMD64_IMAGEBASE;
+}
+#endif /* COFF_WITH_PE */
+
+#ifndef PCRELOFFSET
+#define PCRELOFFSET TRUE
+#endif
+
+static reloc_howto_type howto_table[] =
+{
+ EMPTY_HOWTO (0),
+ HOWTO (R_AMD64_DIR64, /* type 1*/
+ 0, /* rightshift */
+ 4, /* size (0 = byte, 1 = short, 2 = long, 4 = long long) */
+ 64, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ coff_amd64_reloc, /* special_function */
+ "R_X86_64_64", /* name */
+ TRUE, /* partial_inplace */
+ 0xffffffffffffffffll, /* src_mask */
+ 0xffffffffffffffffll, /* dst_mask */
+ TRUE), /* pcrel_offset */
+ HOWTO (R_AMD64_DIR32, /* type 2 */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ coff_amd64_reloc, /* special_function */
+ "R_X86_64_32", /* name */
+ TRUE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+ /* PE IMAGE_REL_AMD64_ADDR32NB relocation (3). */
+ HOWTO (R_AMD64_IMAGEBASE, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ coff_amd64_reloc, /* special_function */
+ "rva32", /* name */
+ TRUE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+ /* 32-bit longword PC relative relocation (4). */
+ HOWTO (R_AMD64_PCRLONG, /* type 4 */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ coff_amd64_reloc, /* special_function */
+ "R_X86_64_PC32", /* name */
+ TRUE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ PCRELOFFSET), /* pcrel_offset */
+
+ HOWTO (R_AMD64_PCRLONG_1, /* type 5 */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ coff_amd64_reloc, /* special_function */
+ "DISP32+1", /* name */
+ TRUE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ PCRELOFFSET), /* pcrel_offset */
+ HOWTO (R_AMD64_PCRLONG_2, /* type 6 */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ coff_amd64_reloc, /* special_function */
+ "DISP32+2", /* name */
+ TRUE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ PCRELOFFSET), /* pcrel_offset */
+ HOWTO (R_AMD64_PCRLONG_3, /* type 7 */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ coff_amd64_reloc, /* special_function */
+ "DISP32+3", /* name */
+ TRUE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ PCRELOFFSET), /* pcrel_offset */
+ HOWTO (R_AMD64_PCRLONG_4, /* type 8 */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ coff_amd64_reloc, /* special_function */
+ "DISP32+4", /* name */
+ TRUE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ PCRELOFFSET), /* pcrel_offset */
+ HOWTO (R_AMD64_PCRLONG_5, /* type 9 */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ coff_amd64_reloc, /* special_function */
+ "DISP32+5", /* name */
+ TRUE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ PCRELOFFSET), /* pcrel_offset */
+ EMPTY_HOWTO (10), /* R_AMD64_SECTION 10 */
+#if defined(COFF_WITH_PE)
+ /* 32-bit longword section relative relocation (11). */
+ HOWTO (R_AMD64_SECREL, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ coff_amd64_reloc, /* special_function */
+ "secrel32", /* name */
+ TRUE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+#else
+ EMPTY_HOWTO (11),
+#endif
+ EMPTY_HOWTO (12),
+ EMPTY_HOWTO (13),
+#ifndef DONT_EXTEND_AMD64
+ HOWTO (R_AMD64_PCRQUAD,
+ 0, /* rightshift */
+ 4, /* size (0 = byte, 1 = short, 2 = long) */
+ 64, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ coff_amd64_reloc, /* special_function */
+ "R_X86_64_PC64", /* name */
+ TRUE, /* partial_inplace */
+ 0xffffffffffffffffll, /* src_mask */
+ 0xffffffffffffffffll, /* dst_mask */
+ PCRELOFFSET), /* pcrel_offset */
+#else
+ EMPTY_HOWTO (14),
+#endif
+ /* Byte relocation (15). */
+ HOWTO (R_RELBYTE, /* type */
+ 0, /* rightshift */
+ 0, /* size (0 = byte, 1 = short, 2 = long) */
+ 8, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ coff_amd64_reloc, /* special_function */
+ "R_X86_64_8", /* name */
+ TRUE, /* partial_inplace */
+ 0x000000ff, /* src_mask */
+ 0x000000ff, /* dst_mask */
+ PCRELOFFSET), /* pcrel_offset */
+ /* 16-bit word relocation (16). */
+ HOWTO (R_RELWORD, /* type */
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ coff_amd64_reloc, /* special_function */
+ "R_X86_64_16", /* name */
+ TRUE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ PCRELOFFSET), /* pcrel_offset */
+ /* 32-bit longword relocation (17). */
+ HOWTO (R_RELLONG, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ coff_amd64_reloc, /* special_function */
+ "R_X86_64_32S", /* name */
+ TRUE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ PCRELOFFSET), /* pcrel_offset */
+ /* Byte PC relative relocation (18). */
+ HOWTO (R_PCRBYTE, /* type */
+ 0, /* rightshift */
+ 0, /* size (0 = byte, 1 = short, 2 = long) */
+ 8, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ coff_amd64_reloc, /* special_function */
+ "R_X86_64_PC8", /* name */
+ TRUE, /* partial_inplace */
+ 0x000000ff, /* src_mask */
+ 0x000000ff, /* dst_mask */
+ PCRELOFFSET), /* pcrel_offset */
+ /* 16-bit word PC relative relocation (19). */
+ HOWTO (R_PCRWORD, /* type */
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ coff_amd64_reloc, /* special_function */
+ "R_X86_64_PC16", /* name */
+ TRUE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ PCRELOFFSET), /* pcrel_offset */
+ /* 32-bit longword PC relative relocation (20). */
+ HOWTO (R_PCRLONG, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ coff_amd64_reloc, /* special_function */
+ "R_X86_64_PC32", /* name */
+ TRUE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ PCRELOFFSET) /* pcrel_offset */
+};
+
+/* Turn a howto into a reloc nunmber */
+
+#define SELECT_RELOC(x,howto) { x.r_type = howto->type; }
+#define I386 1 /* Customize coffcode.h */
+#define AMD64 1
+
+#define RTYPE2HOWTO(cache_ptr, dst) \
+ ((cache_ptr)->howto = \
+ ((dst)->r_type < ARRAY_SIZE (howto_table)) \
+ ? howto_table + (dst)->r_type \
+ : NULL)
+
+/* For 386 COFF a STYP_NOLOAD | STYP_BSS section is part of a shared
+ library. On some other COFF targets STYP_BSS is normally
+ STYP_NOLOAD. */
+#define BSS_NOLOAD_IS_SHARED_LIBRARY
+
+/* Compute the addend of a reloc. If the reloc is to a common symbol,
+ the object file contains the value of the common symbol. By the
+ time this is called, the linker may be using a different symbol
+ from a different object file with a different value. Therefore, we
+ hack wildly to locate the original symbol from this file so that we
+ can make the correct adjustment. This macro sets coffsym to the
+ symbol from the original file, and uses it to set the addend value
+ correctly. If this is not a common symbol, the usual addend
+ calculation is done, except that an additional tweak is needed for
+ PC relative relocs.
+ FIXME: This macro refers to symbols and asect; these are from the
+ calling function, not the macro arguments. */
+
+#define CALC_ADDEND(abfd, ptr, reloc, cache_ptr) \
+ { \
+ coff_symbol_type *coffsym = NULL; \
+ \
+ if (ptr && bfd_asymbol_bfd (ptr) != abfd) \
+ coffsym = (obj_symbols (abfd) \
+ + (cache_ptr->sym_ptr_ptr - symbols)); \
+ else if (ptr) \
+ coffsym = coff_symbol_from (abfd, ptr); \
+ \
+ if (coffsym != NULL \
+ && coffsym->native->u.syment.n_scnum == 0) \
+ cache_ptr->addend = - coffsym->native->u.syment.n_value; \
+ else if (ptr && bfd_asymbol_bfd (ptr) == abfd \
+ && ptr->section != NULL) \
+ cache_ptr->addend = - (ptr->section->vma + ptr->value); \
+ else \
+ cache_ptr->addend = 0; \
+ if (ptr && howto_table[reloc.r_type].pc_relative) \
+ cache_ptr->addend += asect->vma; \
+ }
+
+/* We use the special COFF backend linker. For normal AMD64 COFF, we
+ can use the generic relocate_section routine. For PE, we need our
+ own routine. */
+
+#if !defined(COFF_WITH_PE)
+
+#define coff_relocate_section _bfd_coff_generic_relocate_section
+
+#else /* COFF_WITH_PE */
+
+/* The PE relocate section routine. The only difference between this
+ and the regular routine is that we don't want to do anything for a
+ relocatable link. */
+
+static bfd_boolean
+coff_pe_amd64_relocate_section (bfd *output_bfd,
+ struct bfd_link_info *info,
+ bfd *input_bfd,
+ asection *input_section,
+ bfd_byte *contents,
+ struct internal_reloc *relocs,
+ struct internal_syment *syms,
+ asection **sections)
+{
+ if (info->relocatable)
+ return TRUE;
+
+ return _bfd_coff_generic_relocate_section (output_bfd, info, input_bfd,input_section, contents,relocs, syms, sections);
+}
+
+#define coff_relocate_section coff_pe_amd64_relocate_section
+
+#endif /* COFF_WITH_PE */
+
+/* Convert an rtype to howto for the COFF backend linker. */
+
+static reloc_howto_type *
+coff_amd64_rtype_to_howto (bfd *abfd ATTRIBUTE_UNUSED,
+ asection *sec,
+ struct internal_reloc *rel,
+ struct coff_link_hash_entry *h,
+ struct internal_syment *sym,
+ bfd_vma *addendp)
+{
+ reloc_howto_type *howto;
+
+ if (rel->r_type > ARRAY_SIZE (howto_table))
+ {
+ bfd_set_error (bfd_error_bad_value);
+ return NULL;
+ }
+ if (rel->r_type >= R_AMD64_PCRLONG_1 && rel->r_type <= R_AMD64_PCRLONG_5)
+ {
+ rel->r_vaddr += (bfd_vma)(rel->r_type-R_AMD64_PCRLONG);
+ rel->r_type = R_AMD64_PCRLONG;
+ }
+ howto = howto_table + rel->r_type;
+
+#if defined(COFF_WITH_PE)
+ /* Cancel out code in _bfd_coff_generic_relocate_section. */
+ *addendp = 0;
+#endif
+
+ if (howto->pc_relative)
+ *addendp += sec->vma;
+
+ if (sym != NULL && sym->n_scnum == 0 && sym->n_value != 0)
+ {
+ /* This is a common symbol. The section contents include the
+ size (sym->n_value) as an addend. The relocate_section
+ function will be adding in the final value of the symbol. We
+ need to subtract out the current size in order to get the
+ correct result. */
+ BFD_ASSERT (h != NULL);
+
+#if !defined(COFF_WITH_PE)
+ /* I think we *do* want to bypass this. If we don't, I have
+ seen some data parameters get the wrong relocation address.
+ If I link two versions with and without this section bypassed
+ and then do a binary comparison, the addresses which are
+ different can be looked up in the map. The case in which
+ this section has been bypassed has addresses which correspond
+ to values I can find in the map. */
+ *addendp -= sym->n_value;
+#endif
+ }
+
+#if !defined(COFF_WITH_PE)
+ /* If the output symbol is common (in which case this must be a
+ relocatable link), we need to add in the final size of the
+ common symbol. */
+ if (h != NULL && h->root.type == bfd_link_hash_common)
+ *addendp += h->root.u.c.size;
+#endif
+
+#if defined(COFF_WITH_PE)
+ if (howto->pc_relative)
+ {
+ *addendp -= 4;
+
+ /* If the symbol is defined, then the generic code is going to
+ add back the symbol value in order to cancel out an
+ adjustment it made to the addend. However, we set the addend
+ to 0 at the start of this function. We need to adjust here,
+ to avoid the adjustment the generic code will make. FIXME:
+ This is getting a bit hackish. */
+ if (sym != NULL && sym->n_scnum != 0)
+ *addendp -= sym->n_value;
+ }
+
+ if (rel->r_type == R_AMD64_IMAGEBASE
+ && (bfd_get_flavour (sec->output_section->owner) == bfd_target_coff_flavour))
+ *addendp -= pe_data (sec->output_section->owner)->pe_opthdr.ImageBase;
+
+ if (rel->r_type == R_AMD64_SECREL)
+ {
+ bfd_vma osect_vma;
+
+ if (h && (h->type == bfd_link_hash_defined || h->type == bfd_link_hash_defweak))
+ osect_vma = h->root.u.def.section->output_section->vma;
+ else
+ {
+ asection *sec;
+ int i;
+
+ /* Sigh, the only way to get the section to offset against
+ is to find it the hard way. */
+ for (sec = abfd->sections, i = 1; i < sym->n_scnum; i++)
+ sec = sec->next;
+
+ osect_vma = sec->output_section->vma;
+ }
+
+ *addendp -= osect_vma;
+ }
+#endif
+
+ return howto;
+}
+
+#define coff_bfd_reloc_type_lookup coff_amd64_reloc_type_lookup
+
+static reloc_howto_type *
+coff_amd64_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED, bfd_reloc_code_real_type code)
+{
+ switch (code)
+ {
+ case BFD_RELOC_RVA:
+ return howto_table + R_AMD64_IMAGEBASE;
+ case BFD_RELOC_32:
+ return howto_table + R_AMD64_DIR32;
+ case BFD_RELOC_64:
+ return howto_table + R_AMD64_DIR64;
+ case BFD_RELOC_64_PCREL:
+#ifndef DONT_EXTEND_AMD64
+ return howto_table + R_AMD64_PCRQUAD;
+#else
+ /* Fall through. */
+#endif
+ case BFD_RELOC_32_PCREL:
+ return howto_table + R_AMD64_PCRLONG;
+ case BFD_RELOC_X86_64_32S:
+ return howto_table + R_RELLONG;
+ case BFD_RELOC_16:
+ return howto_table + R_RELWORD;
+ case BFD_RELOC_16_PCREL:
+ return howto_table + R_PCRWORD;
+ case BFD_RELOC_8:
+ return howto_table + R_RELBYTE;
+ case BFD_RELOC_8_PCREL:
+ return howto_table + R_PCRBYTE;
+#if defined(COFF_WITH_PE)
+ case BFD_RELOC_32_SECREL:
+ return howto_table + R_AMD64_SECREL;
+#endif
+ default:
+ BFD_FAIL ();
+ return 0;
+ }
+}
+
+#define coff_rtype_to_howto coff_amd64_rtype_to_howto
+
+#ifdef TARGET_UNDERSCORE
+
+/* If amd64 gcc uses underscores for symbol names, then it does not use
+ a leading dot for local labels, so if TARGET_UNDERSCORE is defined
+ we treat all symbols starting with L as local. */
+
+static bfd_boolean
+coff_amd64_is_local_label_name (bfd *abfd, const char *name)
+{
+ if (name[0] == 'L')
+ return TRUE;
+
+ return _bfd_coff_is_local_label_name (abfd, name);
+}
+
+#define coff_bfd_is_local_label_name coff_amd64_is_local_label_name
+
+#endif /* TARGET_UNDERSCORE */
+
+#include "coffcode.h"
+
+#ifdef PE
+#define amd64coff_object_p pe_bfd_object_p
+#else
+#define amd64coff_object_p coff_object_p
+#endif
+
+const bfd_target
+#ifdef TARGET_SYM
+ TARGET_SYM =
+#else
+ x86_64coff_vec =
+#endif
+{
+#ifdef TARGET_NAME
+ TARGET_NAME,
+#else
+ "coff-x86-64", /* 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),
+
+ (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC /* Section flags. */
+#if defined(COFF_WITH_PE)
+ | SEC_LINK_ONCE | SEC_LINK_DUPLICATES | SEC_READONLY
+#endif
+ | SEC_CODE | SEC_DATA),
+
+#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, amd64coff_object_p, /* BFD_check_format. */
+ bfd_generic_archive_p, amd64coff_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 0c7f897..bc5c72e 100644
--- a/bfd/coffcode.h
+++ b/bfd/coffcode.h
@@ -1882,11 +1882,17 @@ coff_set_arch_mach_hook (bfd *abfd, void * filehdr)
#ifdef I386MAGIC
case I386MAGIC:
case I386PTXMAGIC:
- case I386AIXMAGIC: /* Danbury PS/2 AIX C Compiler */
- case LYNXCOFFMAGIC: /* shadows the m68k Lynx number below, sigh */
+ case I386AIXMAGIC: /* Danbury PS/2 AIX C Compiler. */
+ case LYNXCOFFMAGIC: /* Shadows the m68k Lynx number below, sigh. */
arch = bfd_arch_i386;
break;
#endif
+#ifdef AMD64MAGIC
+ case AMD64MAGIC:
+ arch = bfd_arch_i386;
+ machine = bfd_mach_x86_64;
+ break;
+#endif
#ifdef IA64MAGIC
case IA64MAGIC:
arch = bfd_arch_ia64;
@@ -2721,13 +2727,18 @@ coff_set_flags (bfd * abfd,
return TRUE;
#endif
-#ifdef I386MAGIC
+#if defined(I386MAGIC) || defined(AMD64MAGIC)
case bfd_arch_i386:
+#if defined(I386MAGIC)
*magicp = I386MAGIC;
-#ifdef LYNXOS
+#endif
+#if defined LYNXOS
/* Just overwrite the usual value if we're doing Lynx. */
*magicp = LYNXCOFFMAGIC;
#endif
+#if defined AMD64MAGIC
+ *magicp = AMD64MAGIC;
+#endif
return TRUE;
#endif
@@ -3759,6 +3770,7 @@ coff_write_object_contents (bfd * abfd)
internal_f.f_flags |= IMAGE_FILE_LARGE_ADDRESS_AWARE;
#endif
+#ifndef COFF_WITH_pex64
#ifdef COFF_WITH_PE
internal_f.f_flags |= IMAGE_FILE_32BIT_MACHINE;
#else
@@ -3767,6 +3779,7 @@ coff_write_object_contents (bfd * abfd)
else
internal_f.f_flags |= F_AR32W;
#endif
+#endif
#ifdef TI_TARGET_ID
/* Target id is used in TI COFF v1 and later; COFF0 won't use this field,
@@ -3860,11 +3873,13 @@ coff_write_object_contents (bfd * abfd)
#if defined(I386)
#define __A_MAGIC_SET__
-#if defined(LYNXOS)
+#if defined LYNXOS
internal_a.magic = LYNXCOFFMAGIC;
-#else /* LYNXOS */
+#elif defined AMD64
+ internal_a.magic = IMAGE_NT_OPTIONAL_HDR64_MAGIC;
+#else
internal_a.magic = ZMAGIC;
-#endif /* LYNXOS */
+#endif
#endif /* I386 */
#if defined(IA64)
diff --git a/bfd/config.bfd b/bfd/config.bfd
index 0d0212a..6f6a7b9 100644
--- a/bfd/config.bfd
+++ b/bfd/config.bfd
@@ -98,7 +98,7 @@ sparc*) targ_archs=bfd_sparc_arch ;;
strongarm*) targ_archs=bfd_arm_arch ;;
thumb*) targ_archs=bfd_arm_arch ;;
v850*) targ_archs=bfd_v850_arch ;;
-x86_64) targ_archs=bfd_i386_arch ;;
+x86_64*) targ_archs=bfd_i386_arch ;;
xscale*) targ_archs=bfd_arm_arch ;;
xtensa*) targ_archs=bfd_xtensa_arch ;;
z80|r800) targ_archs=bfd_z80_arch ;;
@@ -578,6 +578,12 @@ case "${targ}" in
targ_selvecs="bfd_elf32_i386_vec i386linux_vec bfd_efi_app_ia32_vec"
want64=true
;;
+ x86_64-*-mingw64*)
+ targ_defvec=x86_64pe_vec
+ targ_selvecs="x86_64pe_vec x86_64pei_vec x86_64coff_vec bfd_elf64_x86_64_vec"
+ want64=true
+ targ_underscore=yes
+ ;;
#endif
i[3-7]86-*-lynxos*)
targ_defvec=bfd_elf32_i386_vec
diff --git a/bfd/configure b/bfd/configure
index ea3c356..1f17d92 100755
--- a/bfd/configure
+++ b/bfd/configure
@@ -4086,7 +4086,7 @@ ia64-*-hpux*)
rm -rf conftest*
;;
-x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*|s390*-*linux*|sparc*-*linux*)
+x86_64-*linux*|x86_64-*mingw64*|ppc*-*linux*|powerpc*-*linux*|s390*-*linux*|sparc*-*linux*)
# Find out which ABI we are using.
echo 'int i;' > conftest.$ac_ext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
@@ -4097,7 +4097,7 @@ x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*|s390*-*linux*|sparc*-*linux*)
case "`/usr/bin/file conftest.o`" in
*32-bit*)
case $host in
- x86_64-*linux*)
+ x86_64-*linux*|x86_64-*mingw64*)
LD="${LD-ld} -m elf_i386"
;;
ppc64-*linux*|powerpc64-*linux*)
@@ -4113,7 +4113,7 @@ x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*|s390*-*linux*|sparc*-*linux*)
;;
*64-bit*)
case $host in
- x86_64-*linux*)
+ x86_64-*linux*|x86_64-*mingw64*)
LD="${LD-ld} -m elf_x86_64"
;;
ppc*-*linux*|powerpc*-*linux*)
@@ -10951,6 +10951,7 @@ do
i386aout_vec) tb="$tb i386aout.lo aout32.lo" ;;
i386bsd_vec) tb="$tb i386bsd.lo aout32.lo" ;;
i386coff_vec) tb="$tb coff-i386.lo cofflink.lo" ;;
+ x86_64coff_vec) tb="$tb coff-x86_64.lo cofflink.lo"; target_size=64 ;;
i386dynix_vec) tb="$tb i386dynix.lo aout32.lo" ;;
i386freebsd_vec) tb="$tb i386freebsd.lo aout32.lo" ;;
i386linux_vec) tb="$tb i386linux.lo aout32.lo" ;;
@@ -10962,6 +10963,8 @@ do
i386os9k_vec) tb="$tb i386os9k.lo aout32.lo" ;;
i386pe_vec) tb="$tb pe-i386.lo peigen.lo cofflink.lo" ;;
i386pei_vec) tb="$tb pei-i386.lo peigen.lo cofflink.lo" ;;
+ x86_64pe_vec) tb="$tb pe-x86_64.lo pex64igen.lo cofflink.lo"; target_size=64 ;;
+ x86_64pei_vec) tb="$tb pei-x86_64.lo pex64igen.lo cofflink.lo"; target_size=64 ;;
i860coff_vec) tb="$tb coff-i860.lo cofflink.lo" ;;
icoff_big_vec) tb="$tb coff-i960.lo cofflink.lo" ;;
icoff_little_vec) tb="$tb coff-i960.lo cofflink.lo" ;;
diff --git a/bfd/configure.in b/bfd/configure.in
index 9af534a..339af93 100644
--- a/bfd/configure.in
+++ b/bfd/configure.in
@@ -741,6 +741,7 @@ do
i386aout_vec) tb="$tb i386aout.lo aout32.lo" ;;
i386bsd_vec) tb="$tb i386bsd.lo aout32.lo" ;;
i386coff_vec) tb="$tb coff-i386.lo cofflink.lo" ;;
+ x86_64coff_vec) tb="$tb coff-x86_64.lo cofflink.lo"; target_size=64 ;;
i386dynix_vec) tb="$tb i386dynix.lo aout32.lo" ;;
i386freebsd_vec) tb="$tb i386freebsd.lo aout32.lo" ;;
i386linux_vec) tb="$tb i386linux.lo aout32.lo" ;;
@@ -752,6 +753,8 @@ do
i386os9k_vec) tb="$tb i386os9k.lo aout32.lo" ;;
i386pe_vec) tb="$tb pe-i386.lo peigen.lo cofflink.lo" ;;
i386pei_vec) tb="$tb pei-i386.lo peigen.lo cofflink.lo" ;;
+ x86_64pe_vec) tb="$tb pe-x86_64.lo pex64igen.lo cofflink.lo"; target_size=64 ;;
+ x86_64pei_vec) tb="$tb pei-x86_64.lo pex64igen.lo cofflink.lo"; target_size=64 ;;
i860coff_vec) tb="$tb coff-i860.lo cofflink.lo" ;;
icoff_big_vec) tb="$tb coff-i960.lo cofflink.lo" ;;
icoff_little_vec) tb="$tb coff-i960.lo cofflink.lo" ;;
diff --git a/bfd/libpei.h b/bfd/libpei.h
index b01e222..10a2a25 100644
--- a/bfd/libpei.h
+++ b/bfd/libpei.h
@@ -204,7 +204,39 @@
#define PUT_SCNHDR_LNNOPTR H_PUT_32
#endif
-#ifdef COFF_WITH_pep
+#ifdef COFF_WITH_pex64
+
+#define GET_OPTHDR_IMAGE_BASE H_GET_64
+#define PUT_OPTHDR_IMAGE_BASE H_PUT_64
+#define GET_OPTHDR_SIZE_OF_STACK_RESERVE H_GET_64
+#define PUT_OPTHDR_SIZE_OF_STACK_RESERVE H_PUT_64
+#define GET_OPTHDR_SIZE_OF_STACK_COMMIT H_GET_64
+#define PUT_OPTHDR_SIZE_OF_STACK_COMMIT H_PUT_64
+#define GET_OPTHDR_SIZE_OF_HEAP_RESERVE H_GET_64
+#define PUT_OPTHDR_SIZE_OF_HEAP_RESERVE H_PUT_64
+#define GET_OPTHDR_SIZE_OF_HEAP_COMMIT H_GET_64
+#define PUT_OPTHDR_SIZE_OF_HEAP_COMMIT H_PUT_64
+#define GET_PDATA_ENTRY bfd_get_32
+
+#define _bfd_XX_bfd_copy_private_bfd_data_common _bfd_pex64_bfd_copy_private_bfd_data_common
+#define _bfd_XX_bfd_copy_private_section_data _bfd_pex64_bfd_copy_private_section_data
+#define _bfd_XX_get_symbol_info _bfd_pex64_get_symbol_info
+#define _bfd_XX_only_swap_filehdr_out _bfd_pex64_only_swap_filehdr_out
+#define _bfd_XX_print_private_bfd_data_common _bfd_pex64_print_private_bfd_data_common
+#define _bfd_XXi_final_link_postscript _bfd_pex64i_final_link_postscript
+#define _bfd_XXi_final_link_postscript _bfd_pex64i_final_link_postscript
+#define _bfd_XXi_only_swap_filehdr_out _bfd_pex64i_only_swap_filehdr_out
+#define _bfd_XXi_swap_aouthdr_in _bfd_pex64i_swap_aouthdr_in
+#define _bfd_XXi_swap_aouthdr_out _bfd_pex64i_swap_aouthdr_out
+#define _bfd_XXi_swap_aux_in _bfd_pex64i_swap_aux_in
+#define _bfd_XXi_swap_aux_out _bfd_pex64i_swap_aux_out
+#define _bfd_XXi_swap_lineno_in _bfd_pex64i_swap_lineno_in
+#define _bfd_XXi_swap_lineno_out _bfd_pex64i_swap_lineno_out
+#define _bfd_XXi_swap_scnhdr_out _bfd_pex64i_swap_scnhdr_out
+#define _bfd_XXi_swap_sym_in _bfd_pex64i_swap_sym_in
+#define _bfd_XXi_swap_sym_out _bfd_pex64i_swap_sym_out
+
+#elif defined COFF_WITH_pep
#define GET_OPTHDR_IMAGE_BASE H_GET_64
#define PUT_OPTHDR_IMAGE_BASE H_PUT_64
diff --git a/bfd/pe-x86_64.c b/bfd/pe-x86_64.c
new file mode 100644
index 0000000..9eb325b
--- /dev/null
+++ b/bfd/pe-x86_64.c
@@ -0,0 +1,53 @@
+/* BFD back-end for Intel/AMD x86_64 PECOFF files.
+ Copyright 2006 Free Software Foundation, Inc.
+
+ 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., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
+
+ Written by Kai Tietz, OneVision Software GmbH&CoKg. */
+
+#include "bfd.h"
+#include "sysdep.h"
+
+#define TARGET_SYM x86_64pe_vec
+#define TARGET_NAME "pe-x86-64"
+#define COFF_WITH_PE
+#define COFF_WITH_pex64
+#define PCRELOFFSET TRUE
+#define TARGET_UNDERSCORE '_'
+#define COFF_LONG_SECTION_NAMES
+#define COFF_SUPPORT_GNU_LINKONCE
+#define COFF_LONG_FILENAMES
+
+#define COFF_SECTION_ALIGNMENT_ENTRIES \
+{ COFF_SECTION_NAME_EXACT_MATCH (".bss"), \
+ COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 4 }, \
+{ COFF_SECTION_NAME_EXACT_MATCH (".data"), \
+ COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 4 }, \
+{ COFF_SECTION_NAME_EXACT_MATCH (".rdata"), \
+ COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 4 }, \
+{ COFF_SECTION_NAME_EXACT_MATCH (".text"), \
+ COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 4 }, \
+{ COFF_SECTION_NAME_PARTIAL_MATCH (".idata"), \
+ COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 2 }, \
+{ COFF_SECTION_NAME_EXACT_MATCH (".pdata"), \
+ COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 2 }, \
+{ COFF_SECTION_NAME_PARTIAL_MATCH (".debug"), \
+ COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 0 }, \
+{ COFF_SECTION_NAME_PARTIAL_MATCH (".gnu.linkonce.wi."), \
+ COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 0 }
+
+#include "coff-x86_64.c"
diff --git a/bfd/peXXigen.c b/bfd/peXXigen.c
index 70ad6cd..5fa874e 100644
--- a/bfd/peXXigen.c
+++ b/bfd/peXXigen.c
@@ -52,8 +52,8 @@
on this code has a chance of getting something accomplished without
wasting too much time. */
-/* This expands into COFF_WITH_pe or COFF_WITH_pep depending on whether
- we're compiling for straight PE or PE+. */
+/* This expands into COFF_WITH_pe, COFF_WITH_pep, or COFF_WITH_pex64
+ depending on whether we're compiling for straight PE or PE+. */
#define COFF_WITH_XX
#include "bfd.h"
@@ -67,7 +67,9 @@
within PE/PEI, so we get them from there. FIXME: The lack of
variance is an assumption which may prove to be incorrect if new
PE/PEI targets are created. */
-#ifdef COFF_WITH_pep
+#if defined COFF_WITH_pex64
+# include "coff/x86_64.h"
+#elif defined COFF_WITH_pep
# include "coff/ia64.h"
#else
# include "coff/i386.h"
@@ -77,7 +79,7 @@
#include "libcoff.h"
#include "libpei.h"
-#ifdef COFF_WITH_pep
+#if defined COFF_WITH_pep || defined COFF_WITH_pex64
# undef AOUTSZ
# define AOUTSZ PEPAOUTSZ
# define PEAOUTHDR PEPAOUTHDR
@@ -399,7 +401,7 @@ _bfd_XXi_swap_aouthdr_in (bfd * abfd,
aouthdr_int->entry = GET_AOUTHDR_ENTRY (abfd, aouthdr_ext->entry);
aouthdr_int->text_start =
GET_AOUTHDR_TEXT_START (abfd, aouthdr_ext->text_start);
-#ifndef COFF_WITH_pep
+#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64)
/* PE32+ does not have data_start member! */
aouthdr_int->data_start =
GET_AOUTHDR_DATA_START (abfd, aouthdr_ext->data_start);
@@ -442,6 +444,7 @@ _bfd_XXi_swap_aouthdr_in (bfd * abfd,
/* If data directory is empty, rva also should be 0. */
int size =
H_GET_32 (abfd, src->DataDirectory[idx][1]);
+
a->DataDirectory[idx].Size = size;
if (size)
@@ -455,7 +458,7 @@ _bfd_XXi_swap_aouthdr_in (bfd * abfd,
if (aouthdr_int->entry)
{
aouthdr_int->entry += a->ImageBase;
-#ifndef COFF_WITH_pep
+#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64)
aouthdr_int->entry &= 0xffffffff;
#endif
}
@@ -463,12 +466,12 @@ _bfd_XXi_swap_aouthdr_in (bfd * abfd,
if (aouthdr_int->tsize)
{
aouthdr_int->text_start += a->ImageBase;
-#ifndef COFF_WITH_pep
+#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64)
aouthdr_int->text_start &= 0xffffffff;
#endif
}
-#ifndef COFF_WITH_pep
+#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64)
/* PE32+ does not have data_start member! */
if (aouthdr_int->dsize)
{
@@ -548,7 +551,7 @@ _bfd_XXi_swap_aouthdr_out (bfd * abfd, void * in, void * out)
if (aouthdr_in->tsize)
{
aouthdr_in->text_start -= ib;
-#ifndef COFF_WITH_pep
+#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64)
aouthdr_in->text_start &= 0xffffffff;
#endif
}
@@ -556,7 +559,7 @@ _bfd_XXi_swap_aouthdr_out (bfd * abfd, void * in, void * out)
if (aouthdr_in->dsize)
{
aouthdr_in->data_start -= ib;
-#ifndef COFF_WITH_pep
+#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64)
aouthdr_in->data_start &= 0xffffffff;
#endif
}
@@ -564,7 +567,7 @@ _bfd_XXi_swap_aouthdr_out (bfd * abfd, void * in, void * out)
if (aouthdr_in->entry)
{
aouthdr_in->entry -= ib;
-#ifndef COFF_WITH_pep
+#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64)
aouthdr_in->entry &= 0xffffffff;
#endif
}
@@ -661,7 +664,7 @@ _bfd_XXi_swap_aouthdr_out (bfd * abfd, void * in, void * out)
PUT_AOUTHDR_TEXT_START (abfd, aouthdr_in->text_start,
aouthdr_out->standard.text_start);
-#ifndef COFF_WITH_pep
+#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64)
/* PE32+ does not have data_start member! */
PUT_AOUTHDR_DATA_START (abfd, aouthdr_in->data_start,
aouthdr_out->standard.data_start);
@@ -1262,6 +1265,38 @@ pe_print_idata (bfd * abfd, void * vfile)
}
/* Print HintName vector entries. */
+#ifdef COFF_WITH_pex64
+ for (j = 0; j < datasize; j += 8)
+ {
+ unsigned long member = bfd_get_32 (abfd, data + idx + j);
+ unsigned long member_high = bfd_get_32 (abfd, data + idx + j + 4);
+
+ if (!member && !member_high)
+ break;
+
+ if (member_high & 0x80000000)
+ fprintf (file, "\t%lx%08lx\t %4lx%08lx <none>",
+ member_high,member, member_high & 0x7fffffff, member);
+ else
+ {
+ int ordinal;
+ char *member_name;
+
+ ordinal = bfd_get_16 (abfd, data + member - adj);
+ member_name = (char *) data + member - adj + 2;
+ fprintf (file, "\t%04lx\t %4d %s",member, ordinal, member_name);
+ }
+
+ /* If the time stamp is not zero, the import address
+ table holds actual addresses. */
+ if (time_stamp != 0
+ && first_thunk != 0
+ && first_thunk != hint_addr)
+ fprintf (file, "\t%04lx",
+ (long) bfd_get_32 (abfd, ft_data + ft_idx + j));
+ fprintf (file, "\n");
+ }
+#else
for (j = 0; j < datasize; j += 4)
{
unsigned long member = bfd_get_32 (abfd, data + idx + j);
@@ -1294,7 +1329,7 @@ pe_print_idata (bfd * abfd, void * vfile)
fprintf (file, "\n");
}
-
+#endif
if (ft_allocated)
free (ft_data);
}
@@ -1534,10 +1569,10 @@ pe_print_edata (bfd * abfd, void * vfile)
static bfd_boolean
pe_print_pdata (bfd * abfd, void * vfile)
{
-#ifdef COFF_WITH_pep
-# define PDATA_ROW_SIZE (3*8)
+#if defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64)
+# define PDATA_ROW_SIZE (3 * 8)
#else
-# define PDATA_ROW_SIZE (5*4)
+# define PDATA_ROW_SIZE (5 * 4)
#endif
FILE *file = (FILE *) vfile;
bfd_byte *data = 0;
@@ -1560,7 +1595,7 @@ pe_print_pdata (bfd * abfd, void * vfile)
fprintf (file,
_("\nThe Function Table (interpreted .pdata section contents)\n"));
-#ifdef COFF_WITH_pep
+#if defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64)
fprintf (file,
_(" vma:\t\t\tBegin Address End Address Unwind Info\n"));
#else
@@ -1614,7 +1649,7 @@ pe_print_pdata (bfd * abfd, void * vfile)
fprintf_vma (file, begin_addr); fputc (' ', file);
fprintf_vma (file, end_addr); fputc (' ', file);
fprintf_vma (file, eh_handler);
-#ifndef COFF_WITH_pep
+#if !defined(COFF_WITH_pep) || defined(COFF_WITH_pex64)
fputc (' ', file);
fprintf_vma (file, eh_data); fputc (' ', file);
fprintf_vma (file, prolog_end_addr);
diff --git a/bfd/pei-x86_64.c b/bfd/pei-x86_64.c
new file mode 100644
index 0000000..caa5db3
--- /dev/null
+++ b/bfd/pei-x86_64.c
@@ -0,0 +1,54 @@
+/* BFD back-end for Intel 386 PE IMAGE COFF files.
+ Copyright 2006 Free Software Foundation, Inc.
+
+ 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., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
+
+ Written by Kai Tietz, OneVision Software GmbH&CoKg. */
+
+#include "bfd.h"
+#include "sysdep.h"
+
+#define TARGET_SYM x86_64pei_vec
+#define TARGET_NAME "pei-x86-64"
+#define COFF_IMAGE_WITH_PE
+#define COFF_WITH_PE
+#define COFF_WITH_pex64
+#define PCRELOFFSET TRUE
+#define TARGET_UNDERSCORE '_'
+#define COFF_LONG_SECTION_NAMES
+#define COFF_SUPPORT_GNU_LINKONCE
+#define COFF_LONG_FILENAMES
+
+#define COFF_SECTION_ALIGNMENT_ENTRIES \
+{ COFF_SECTION_NAME_EXACT_MATCH (".bss"), \
+ COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 4 }, \
+{ COFF_SECTION_NAME_EXACT_MATCH (".data"), \
+ COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 4 }, \
+{ COFF_SECTION_NAME_EXACT_MATCH (".rdata"), \
+ COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 4 }, \
+{ COFF_SECTION_NAME_EXACT_MATCH (".text"), \
+ COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 4 }, \
+{ COFF_SECTION_NAME_PARTIAL_MATCH (".idata"), \
+ COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 2 }, \
+{ COFF_SECTION_NAME_EXACT_MATCH (".pdata"), \
+ COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 2 }, \
+{ COFF_SECTION_NAME_PARTIAL_MATCH (".debug"), \
+ COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 0 }, \
+{ COFF_SECTION_NAME_PARTIAL_MATCH (".gnu.linkonce.wi."), \
+ COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 0 }
+
+#include "coff-x86_64.c"
diff --git a/bfd/peicode.h b/bfd/peicode.h
index 2061f41..22f1bbd 100644
--- a/bfd/peicode.h
+++ b/bfd/peicode.h
@@ -1,6 +1,6 @@
/* Support for the generic parts of PE/PEI, for BFD.
Copyright 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
- 2005 Free Software Foundation, Inc.
+ 2005, 2006 Free Software Foundation, Inc.
Written by Cygnus Solutions.
This file is part of BFD, the Binary File Descriptor library.
@@ -182,6 +182,10 @@ coff_swap_filehdr_in (bfd * abfd, void * src, void * dst)
#ifdef COFF_IMAGE_WITH_PE
# define coff_swap_filehdr_out _bfd_XXi_only_swap_filehdr_out
+#elif defined COFF_WITH_pex64
+# define coff_swap_filehdr_out _bfd_pex64_only_swap_filehdr_out
+#elif defined COFF_WITH_pep
+# define coff_swap_filehdr_out _bfd_pep_only_swap_filehdr_out
#else
# define coff_swap_filehdr_out _bfd_pe_only_swap_filehdr_out
#endif
@@ -217,7 +221,10 @@ coff_swap_scnhdr_in (bfd * abfd, void * ext, void * in)
if (scnhdr_int->s_vaddr != 0)
{
scnhdr_int->s_vaddr += pe_data (abfd)->pe_opthdr.ImageBase;
+ /* Do not cut upper 32-bits for 64-bit vma. */
+#ifndef COFF_WITH_pex64
scnhdr_int->s_vaddr &= 0xffffffff;
+#endif
}
#ifndef COFF_NO_HACK_SCNHDR_SIZE
@@ -405,8 +412,16 @@ pe_bfd_copy_private_bfd_data (bfd *ibfd, bfd *obfd)
+ NUM_ILF_SECTIONS * 9 \
+ STRING_SIZE_SIZE)
#define SIZEOF_IDATA2 (5 * 4)
+
+/* For PEx64 idata4 & 5 have thumb size of 8 bytes. */
+#ifdef COFF_WITH_pex64
+#define SIZEOF_IDATA4 (2 * 4)
+#define SIZEOF_IDATA5 (2 * 4)
+#else
#define SIZEOF_IDATA4 (1 * 4)
#define SIZEOF_IDATA5 (1 * 4)
+#endif
+
#define SIZEOF_IDATA6 (2 + strlen (symbol_name) + 1 + 1)
#define SIZEOF_IDATA7 (strlen (source_dll) + 1 + 1)
#define SIZEOF_ILF_SECTIONS (NUM_ILF_SECTIONS * sizeof (struct coff_section_tdata))
@@ -656,9 +671,20 @@ static jump_table jtab[] =
},
#endif
+#ifdef AMD64MAGIC
+ { AMD64MAGIC,
+ { 0xff, 0x25, 0x00, 0x00, 0x00, 0x00, 0x90, 0x90 },
+ 8, 2
+ },
+#endif
+
#ifdef MC68MAGIC
- { MC68MAGIC, { /* XXX fill me in */ }, 0, 0 },
+ { MC68MAGIC,
+ { /* XXX fill me in */ },
+ 0, 0
+ },
#endif
+
#ifdef MIPS_ARCH_MAGIC_WINCE
{ MIPS_ARCH_MAGIC_WINCE,
{ 0x00, 0x00, 0x08, 0x3c, 0x00, 0x00, 0x08, 0x8d,
@@ -830,8 +856,15 @@ pe_ILF_build_a_bfd (bfd * abfd,
/* XXX - treat as IMPORT_NAME ??? */
abort ();
+#ifdef COFF_WITH_pex64
+ ((unsigned int *) id4->contents)[0] = ordinal;
+ ((unsigned int *) id4->contents)[1] = 0x80000000;
+ ((unsigned int *) id5->contents)[0] = ordinal;
+ ((unsigned int *) id5->contents)[1] = 0x80000000;
+#else
* (unsigned int *) id4->contents = ordinal | 0x80000000;
* (unsigned int *) id5->contents = ordinal | 0x80000000;
+#endif
}
else
{
@@ -1071,6 +1104,12 @@ pe_ILF_object_p (bfd * abfd)
#endif
break;
+ case IMAGE_FILE_MACHINE_AMD64:
+#ifdef AMD64MAGIC
+ magic = AMD64MAGIC;
+#endif
+ break;
+
case IMAGE_FILE_MACHINE_M68K:
#ifdef MC68AGIC
magic = MC68MAGIC;
diff --git a/bfd/targets.c b/bfd/targets.c
index 489d0ce..117e7c6 100644
--- a/bfd/targets.c
+++ b/bfd/targets.c
@@ -789,6 +789,9 @@ extern const bfd_target vms_alpha_vec;
extern const bfd_target vms_vax_vec;
extern const bfd_target w65_vec;
extern const bfd_target we32kcoff_vec;
+extern const bfd_target x86_64pe_vec;
+extern const bfd_target x86_64pei_vec;
+extern const bfd_target x86_64coff_vec;
extern const bfd_target z80coff_vec;
extern const bfd_target z8kcoff_vec;
@@ -813,8 +816,8 @@ extern const bfd_target sco5_core_vec;
extern const bfd_target trad_core_vec;
extern const bfd_target bfd_elf32_am33lin_vec;
-static const bfd_target * const _bfd_target_vector[] = {
-
+static const bfd_target * const _bfd_target_vector[] =
+{
#ifdef SELECT_VECS
SELECT_VECS,
@@ -1054,6 +1057,11 @@ static const bfd_target * const _bfd_target_vector[] = {
&i386os9k_vec,
&i386pe_vec,
&i386pei_vec,
+#ifdef BFD64
+ &x86_64coff_vec,
+ &x86_64pe_vec,
+ &x86_64pei_vec,
+#endif
&i860coff_vec,
&icoff_big_vec,
&icoff_little_vec,