public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* Re: PE+ & Coff for x86_64 target (Part I)
@ 2006-09-18 14:48 Kai Tietz
  0 siblings, 0 replies; 2+ messages in thread
From: Kai Tietz @ 2006-09-18 14:48 UTC (permalink / raw)
  To: binutils; +Cc: Pedro Alves

[-- Attachment #1: Type: text/plain, Size: 6512 bytes --]

Hallo,

Upps, sorry, I missed a ifdef-clause in coffcode.h to be removed ... After 
applying the main-patch please do this attached patch too:

--- src_n/bfd/coffcode.h        2006-09-18 14:13:41.581286900 +0200
+++ src_n_bld/bfd/coffcode.h    2006-09-18 14:03:29.103410700 +0200
@@ -2727,7 +2727,6 @@
       return TRUE;
 #endif
 
-#ifdef I386MAGIC
 #if defined(I386MAGIC) || defined(AMD64MAGIC)
     case bfd_arch_i386:
 #ifdef I386MAGIC

Regards,
 i.A. Kai Tietz

*** Source does not be released, it escapes ... ***




Kai Tietz/Onevision 
18.09.2006 11:34

To
binutils@sourceware.org
cc
Pedro Alves <pedro_alves@portugalmail.pt>
Subject
PE+ & Coff for x86_64 target (Part I)





Hallo,

It seems to be that I posted a too large patch ("PE+ and new COFF format 
for x86_64 target for XP64 and Vista binaries"). Therefore I split this 
patch into four smaller patches. The first one is the patch for the 
include/coff/ directory and the bfd directory, which are strongly wired 
and therefore not splittable. The biggest change for coff is the change of 
the PEPAOUTHDR structure, which had the wrong size, because it defines in 
the header the field data_start, which does not exists for PE+.

Remark, that you have to enable 64-bit-bfd and specifying the target 
"x86_64-pc-mingw64" for the cross build. This patch also includes the 
main-level build patches to config.guess, config.sub, and configure.in. 
Additionally there is a generated version of configure, too.

        * config.guess: Add MINGW64 target detection
        * config.sub:   Add mingw64 target
        * configure.in: Likewise

A global part of this patch was done in include/coff which defines some 
new constants for the coff-format, the magic signature for x86_64, and a 
change to PEPAOUTHDR which had for PE+ the wrong size. The coff relocation 
definitions in coff/internal.h are taken as defined by AMD&MS, but the 
R_AMD64_PCRQUAD is added to enable gas to define 64-bit wide PC-relative 
relocations. The AMD/MS version does not define such wide PC-relative 
relocations in there object format as I know.

Changes in include/coff:
        * external.h:   Add new  aout header structure for PE+
                external_aouthdr64:     Structure for PE+ aout header 
without the data_start element. This elements led to a size of 28 bytes 
instead of correct 24 bytes in PE+.
                AOUTHDRSZ define:       Defines the sizeof of the 
external_aouthdr64 structure of 24 bytes.
        * internal.h:   Add target specific constants for coff x86_64 
(used mostly in bfd/coff-x86_64.c)
                R_AMD64_ABS define:             Reference is absolute, no 
relocation is necessary 
                R_AMD64_DIR64 define:    64-bit address (VA) 
                R_AMD64_DIR32 define:   32-bit address (VA) R_DIR32 
                R_AMD64_IMAGEBASE define:       32-bit absolute ref w/o 
base R_IMAGEBASE
                R_AMD64_PCRLONG define: 32-bit relative address from byte 
following reloc R_PCRLONG
                R_AMD64_PCRLONG_1define:        32-bit relative address 
from byte distance 1 from reloc
                R_AMD64_PCRLONG_2 define:       32-bit relative address 
from byte distance 2 from reloc
                R_AMD64_PCRLONG_3 define:       32-bit relative address 
from byte distance 3 from reloc
                R_AMD64_PCRLONG_4 define:       32-bit relative address 
from byte distance 4 from reloc
                R_AMD64_PCRLONG_5 define:       32-bit relative address 
from byte distance 5 from reloc
                R_AMD64_SECTION define: Section index
                R_AMD64_SECREL define:  32 bit offset from base of section 
containing target R_SECREL
                R_AMD64_SECREL7 define: 7 bit unsigned offset from base of 
section containing target
                R_AMD64_TOKEN define:   32 bit metadata token (used by #c)
                R_AMD64_PCRQUAD define:  Pseude PC64 relocation - note not 
specified by MS/AMD but need for gas pc-relative 64bit wide relocation 
generated by elf
        * pe.h: Definition of new magic signature and the correction of 
PEPAOUTHDR structure.
                IMAGE_FILE_MACHINE_AMD64 define:                AMD64 (K8) 
coff magic signature
                PEPAOUTHDR structure:                   Changed standard 
element from AOUTHDR to AOUTHDR64 for proper structure size.
                PEPAOUTSZ define:                               Changed to 
reflect the making of the calculated value of 240 bytes.
        * x86_64.h:     New file for the needed coff defines for this new 
target.


Changes in bfd:
        * coff-x86_64.c:                New coff format handler for x86_64
        * coffcode.h:           Changes to reflect the magic signature 
treating of bfd
        * config.bfd:           Added target handling
        * configure.in:         Likewise
        * libpei.h:             Add correct PE+ header access macros for 
PE+ x86_64 (COFF_WITH_pex64)
        * Makefile.am:          Added new file generation and build rules 
for coff-x86_64.c, pe-x86_64.c, pei-x86_64.c, and generated pex64igen.c
        * Makefile.in:          Likewise
        * pe-x86_64.c:          New object format pe-x86_64 handler
        * pei-x86_64.c:         New object format pei-x86_64 handler
        * peicode.h:            Definition of proper coff_swap_filehdr_out 
macro for target, and changed IDATA sizes for PE+
                SIZEOF_IDATA4 macro:    For x86_64 PE+ it has size of 8 
bytes
                SIZEOF_IDATA5 macro:    Likewise
                jtab structure:                 Add new jump table element 
for target
                pe_ILF_build_a_bfd function:    Add handling of ordinals 
for PE+ (IDATA4 & IDATA5)
                pe_ILF_object_p function:       Add magic signature for 
the target object file detection.
        * pexxigen.c:           Make sure the proper architecture file is 
included and the specific code for PE+ x86_64 is enabled.
                pe_print_idata function:                Added proper print 
of PE+ x86_64 imports
                pe_print_pdata function:                Reflect pdata 
handling for x86_64 target.
        * target.c:             Add new object file handlers for coff 
x86_64


Regards,
 i.A. Kai Tietz


----------------------------------------
  Kai Tietz - Software engineering
  OneVision Software Entwicklungs GmbH & Co KG
  Dr.-Leo-Ritter-Str. 9, 93049 Regensburg, Germany
  Phone: +49-941-78004-0
  FAX:   +49-941-78004-489
  WWW:   http://www.OneVision.com

[-- Attachment #2: x86_64coff_bfd.diff --]
[-- Type: application/octet-stream, Size: 60210 bytes --]

diff -rNbu -x CVS src/bfd/Makefile.am src_n/bfd/Makefile.am
--- src/bfd/Makefile.am	2006-09-18 08:51:41.000000000 +0200
+++ src_n/bfd/Makefile.am	2006-09-18 09:49:24.000000000 +0200
@@ -563,7 +563,11 @@
 	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 @@
 	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 @@
 	$(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 @@
 	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 @@
 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 -rNbu -x CVS src/bfd/Makefile.in src_n/bfd/Makefile.in
--- src/bfd/Makefile.in	2006-09-18 08:51:41.000000000 +0200
+++ src_n/bfd/Makefile.in	2006-09-18 09:51:37.000000000 +0200
@@ -796,7 +796,11 @@
 	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 @@
 	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 @@
 	$(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 = \
@@ -1368,6 +1375,11 @@
 	sed -e s/XX/pe/g < $(srcdir)/peXXigen.c > peigen.new
 	mv -f peigen.new peigen.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
+	
 pepigen.c : peXXigen.c
 	rm -f pepigen.c
 	sed -e s/XX/pep/g < $(srcdir)/peXXigen.c > pepigen.new
@@ -2422,6 +2434,9 @@
 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 -rNbu -x CVS src/bfd/coff-x86_64.c src_n/bfd/coff-x86_64.c
--- src/bfd/coff-x86_64.c	1970-01-01 01:00:00.000000000 +0100
+++ src_n/bfd/coff-x86_64.c	2006-09-06 12:28:12.000000000 +0200
@@ -0,0 +1,751 @@
+/* BFD back-end for AMD 64 COFF files.
+   Copyright 1995, 1996, 1999, 2001, 2002, 2004 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"
+
+#define BADMAG(x) AMD64BADMAG(x)
+
+#ifdef COFF_WITH_pex64
+# undef AOUTSZ
+# define AOUTSZ		PEPAOUTSZ
+# define PEAOUTHDR	PEPAOUTHDR
+#endif
+
+static bfd_reloc_status_type coff_amd64_reloc(bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **);
+static reloc_howto_type *coff_amd64_rtype_to_howto(bfd *, asection *, struct internal_reloc *,struct coff_link_hash_entry *, struct internal_syment *,bfd_vma *);
+static reloc_howto_type *coff_amd64_reloc_type_lookup(bfd *, bfd_reloc_code_real_type);
+
+#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,PTR data,asection *input_section ATTRIBUTE_UNUSED,
+				 bfd *output_bfd,char **error_message ATTRIBUTE_UNUSED)
+{
+  symvalue diff;
+
+#if !defined(COFF_WITH_PE)
+  if(output_bfd == (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 == (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 *, reloc_howto_type *);
+
+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 < sizeof (howto_table) / sizeof (howto_table[0])	\
+    ? 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 = (coff_symbol_type *) 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!=(coff_symbol_type *) 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!=(asection *) 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 *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,struct internal_reloc *, struct internal_syment *, asection **);
+
+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 > sizeof (howto_table) / sizeof (howto_table[0])) {
+      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 trough */
+#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 *, const char *);
+
+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 -rNbu -x CVS src/bfd/coffcode.h src_n/bfd/coffcode.h
--- src/bfd/coffcode.h	2006-09-18 08:51:42.000000000 +0200
+++ src_n/bfd/coffcode.h	2006-09-18 09:30:46.000000000 +0200
@@ -1887,6 +1887,12 @@
       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;
@@ -2722,12 +2728,18 @@
 #endif
 
 #ifdef I386MAGIC
+#if defined(I386MAGIC) || defined(AMD64MAGIC)
     case bfd_arch_i386:
+#ifdef I386MAGIC
       *magicp = I386MAGIC;
+#endif
 #ifdef LYNXOS
       /* Just overwrite the usual value if we're doing Lynx.  */
       *magicp = LYNXCOFFMAGIC;
 #endif
+#ifdef AMD64MAGIC
+	  *magicp = AMD64MAGIC;
+#endif
       return TRUE;
 #endif
 
@@ -3759,6 +3771,7 @@
     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 +3780,7 @@
   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,
@@ -3862,8 +3876,12 @@
 #define __A_MAGIC_SET__
 #if defined(LYNXOS)
     internal_a.magic = LYNXCOFFMAGIC;
-#else  /* LYNXOS */
+#else  /* !LYNXOS */
+#ifdef AMD64
+	internal_a.magic = IMAGE_NT_OPTIONAL_HDR64_MAGIC;
+#else
     internal_a.magic = ZMAGIC;
+#endif
 #endif /* LYNXOS */
 #endif /* I386 */
 
diff -rNbu -x CVS src/bfd/config.bfd src_n/bfd/config.bfd
--- src/bfd/config.bfd	2006-09-18 08:51:42.000000000 +0200
+++ src_n/bfd/config.bfd	2006-09-18 09:32:32.000000000 +0200
@@ -98,7 +98,7 @@
 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 @@
     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 -rNbu -x CVS src/bfd/configure src_n/bfd/configure
--- src/bfd/configure	2006-09-18 08:51:42.000000000 +0200
+++ src_n/bfd/configure	2006-09-18 09:36:04.000000000 +0200
@@ -4086,7 +4086,7 @@
   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,6 +4097,9 @@
     case "`/usr/bin/file conftest.o`" in
     *32-bit*)
       case $host in
+        x86_64-*mingw64*)
+          LD="${LD-ld} -m elf_i386"
+          ;;
         x86_64-*linux*)
           LD="${LD-ld} -m elf_i386"
           ;;
@@ -4113,6 +4116,9 @@
       ;;
     *64-bit*)
       case $host in
+        x86_64-*mingw64*)
+          LD="${LD-ld} -m elf_x86_64"
+          ;;
         x86_64-*linux*)
           LD="${LD-ld} -m elf_x86_64"
           ;;
@@ -10951,6 +10957,7 @@
     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" ;;
@@ -10961,7 +10968,9 @@
     i386netbsd_vec)		tb="$tb i386netbsd.lo aout32.lo" ;;
     i386os9k_vec)		tb="$tb i386os9k.lo aout32.lo" ;;
     i386pe_vec)			tb="$tb pe-i386.lo peigen.lo cofflink.lo" ;;
+    x86_64pe_vec)		tb="$tb pe-x86_64.lo pex64igen.lo cofflink.lo"; target_size=64 ;;
     i386pei_vec)		tb="$tb pei-i386.lo peigen.lo cofflink.lo" ;;
+    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 -rNbu -x CVS src/bfd/configure.in src_n/bfd/configure.in
--- src/bfd/configure.in	2006-09-18 08:51:42.000000000 +0200
+++ src_n/bfd/configure.in	2006-09-18 09:37:10.000000000 +0200
@@ -741,6 +741,7 @@
     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" ;;
@@ -751,7 +752,9 @@
     i386netbsd_vec)		tb="$tb i386netbsd.lo aout32.lo" ;;
     i386os9k_vec)		tb="$tb i386os9k.lo aout32.lo" ;;
     i386pe_vec)			tb="$tb pe-i386.lo peigen.lo cofflink.lo" ;;
+    x86_64pe_vec)		tb="$tb pe-x86_64.lo pex64igen.lo cofflink.lo"; target_size=64 ;;
     i386pei_vec)		tb="$tb pei-i386.lo peigen.lo cofflink.lo" ;;
+    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 -rNbu -x CVS src/bfd/libpei.h src_n/bfd/libpei.h
--- src/bfd/libpei.h	2006-09-18 08:51:48.000000000 +0200
+++ src_n/bfd/libpei.h	2006-09-18 09:39:13.000000000 +0200
@@ -204,6 +204,38 @@
 #define PUT_SCNHDR_LNNOPTR H_PUT_32
 #endif
 
+#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
+
+#else /* !COFF_WITH_pex64 */
 #ifdef COFF_WITH_pep
 
 #define GET_OPTHDR_IMAGE_BASE H_GET_64
@@ -269,6 +301,7 @@
 #define _bfd_XXi_swap_sym_out				_bfd_pei_swap_sym_out
 
 #endif /* !COFF_WITH_pep */
+#endif /* !COFF_WITG_pex64 */
 
 /* Macro: Returns true if the bfd is a PE executable as opposed to a PE object file.  */
 #define bfd_pe_executable_p(abfd)			\
diff -rNbu -x CVS src/bfd/pe-x86_64.c src_n/bfd/pe-x86_64.c
--- src/bfd/pe-x86_64.c	1970-01-01 01:00:00.000000000 +0100
+++ src_n/bfd/pe-x86_64.c	2006-09-06 12:23:54.000000000 +0200
@@ -0,0 +1,54 @@
+/* BFD back-end for Intel/AMD x86_64 PECOFF files.
+   Copyright 1995, 1996, 1999, 2001, 2002, 2004 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 -rNbu -x CVS src/bfd/peXXigen.c src_n/bfd/peXXigen.c
--- src/bfd/peXXigen.c	2006-07-24 18:51:26.000000000 +0200
+++ src_n/bfd/peXXigen.c	2006-09-18 10:04:10.000000000 +0200
@@ -67,17 +67,21 @@
    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
-# include "coff/ia64.h"
+#ifdef COFF_WITH_pex64
+# include "coff/x86_64.h"
 #else
+# ifdef COFF_WITH_pep
+#  include "coff/ia64.h"
+# else
 # include "coff/i386.h"
+# endif
 #endif
 
 #include "coff/pe.h"
 #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 +403,7 @@
   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);
@@ -455,7 +459,7 @@
   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 +467,12 @@
   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 +552,7 @@
   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 +560,7 @@
   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 +568,7 @@
   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 +665,7 @@
   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 +1266,35 @@
 	    }
 
 	  /* 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,6 +1327,7 @@
 
 	      fprintf (file, "\n");
 	    }
+#endif /* !defined(COFF_WITH_pex64) */
 
 	  if (ft_allocated)
 	    free (ft_data);
@@ -1534,7 +1568,7 @@
 static bfd_boolean
 pe_print_pdata (bfd * abfd, void * vfile)
 {
-#ifdef COFF_WITH_pep
+#if defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64)
 # define PDATA_ROW_SIZE	(3*8)
 #else
 # define PDATA_ROW_SIZE	(5*4)
@@ -1560,7 +1594,7 @@
 
   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 +1648,7 @@
       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 -rNbu -x CVS src/bfd/pei-x86_64.c src_n/bfd/pei-x86_64.c
--- src/bfd/pei-x86_64.c	1970-01-01 01:00:00.000000000 +0100
+++ src_n/bfd/pei-x86_64.c	2006-09-06 12:23:58.000000000 +0200
@@ -0,0 +1,55 @@
+/* BFD back-end for Intel 386 PE IMAGE COFF files.
+   Copyright 1995, 1996, 1999, 2001, 2002, 2004 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 -rNbu -x CVS src/bfd/peicode.h src_n/bfd/peicode.h
--- src/bfd/peicode.h	2005-05-04 17:53:37.000000000 +0200
+++ src_n/bfd/peicode.h	2006-09-18 09:56:19.000000000 +0200
@@ -183,7 +183,15 @@
 #ifdef COFF_IMAGE_WITH_PE
 # define coff_swap_filehdr_out _bfd_XXi_only_swap_filehdr_out
 #else
+# ifdef COFF_WITH_pex64
+#  define coff_swap_filehdr_out _bfd_pex64_only_swap_filehdr_out
+# else
+#  ifdef 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
+# endif
 #endif
 
 static void
@@ -405,8 +413,15 @@
 					+ NUM_ILF_SECTIONS * 9 \
 					+ STRING_SIZE_SIZE)
 #define SIZEOF_IDATA2		(5 * 4)
+/* For PE+ idata4 & 5 have thumb size of 8 bytes ! */
+#ifndef COFF_WITH_pex64
 #define SIZEOF_IDATA4		(1 * 4)
 #define SIZEOF_IDATA5		(1 * 4)
+#else
+#define SIZEOF_IDATA4		(2 * 4)
+#define SIZEOF_IDATA5		(2 * 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,6 +671,13 @@
   },
 #endif
 
+#ifdef AMD64MAGIC
+  { AMD64MAGIC,
+  { 0xff,0x25,0x00,0x00,0x00,0x00,0x90,0x90 },
+  8,2
+  },
+#endif
+
 #ifdef  MC68MAGIC
   { MC68MAGIC, { /* XXX fill me in */ }, 0, 0 },
 #endif
@@ -830,8 +852,15 @@
 	/* XXX - treat as IMPORT_NAME ??? */
 	abort ();
 
+#ifndef COFF_WITH_pex64
       * (unsigned int *) id4->contents = ordinal | 0x80000000;
       * (unsigned int *) id5->contents = ordinal | 0x80000000;
+#else
+      * (unsigned int *) id4->contents = ordinal;
+	  ((unsigned int *) id4->contents)[1] = 0x80000000;
+      * (unsigned int *) id5->contents = ordinal;
+      ((unsigned int *) id5->contents)[1] = 0x80000000;
+#endif
     }
   else
     {
@@ -1070,6 +1099,12 @@
       magic = I386MAGIC;
 #endif
       break;
+    case IMAGE_FILE_MACHINE_AMD64:
+#ifdef AMD64MAGIC
+      magic=AMD64MAGIC;
+#endif
+      break;
+
 
     case IMAGE_FILE_MACHINE_M68K:
 #ifdef MC68AGIC
diff -rNbu -x CVS src/bfd/targets.c src_n/bfd/targets.c
--- src/bfd/targets.c	2006-09-18 08:51:50.000000000 +0200
+++ src_n/bfd/targets.c	2006-09-18 10:05:31.000000000 +0200
@@ -791,6 +791,9 @@
 extern const bfd_target we32kcoff_vec;
 extern const bfd_target z80coff_vec;
 extern const bfd_target z8kcoff_vec;
+extern const bfd_target x86_64pe_vec;
+extern const bfd_target x86_64pei_vec;
+extern const bfd_target x86_64coff_vec;
 
 /* These are always included.  */
 extern const bfd_target srec_vec;
@@ -1037,6 +1040,11 @@
 #if 0
 	&i386dynix_vec,
 #endif
+#ifdef BFD64
+	&x86_64coff_vec,
+	&x86_64pe_vec,
+	&x86_64pei_vec,
+#endif
 	&i386freebsd_vec,
 #if 0
 	/* Since a.out files lack decent magic numbers, no way to recognize
diff -rNbu -x CVS src/config.guess src_n/config.guess
--- src/config.guess	2006-05-14 02:51:19.000000000 +0200
+++ src_n/config.guess	2006-09-18 09:20:25.000000000 +0200
@@ -780,7 +780,13 @@
     i*:CYGWIN*:*)
 	echo ${UNAME_MACHINE}-pc-cygwin
 	exit ;;
-    i*:MINGW*:*)
+    x86*:MINGW64*:*)
+	echo ${UNAME_MACHINE}-pc-mingw64
+	exit ;;
+    i*:MINGW64*:*)
+	echo ${UNAME_MACHINE}-pc-mingw64
+	exit ;;
+    i*:MINGW32*:*)
 	echo ${UNAME_MACHINE}-pc-mingw32
 	exit ;;
     i*:windows32*:*)
diff -rNbu -x CVS src/config.sub src_n/config.sub
--- src/config.sub	2006-08-15 20:23:07.000000000 +0200
+++ src_n/config.sub	2006-09-18 09:22:13.000000000 +0200
@@ -682,6 +682,10 @@
 		basic_machine=i386-pc
 		os=-mingw32
 		;;
+	mingw64)
+		basic_machine=x86_64-pc
+		os=-mingw64
+		;;
 	miniframe)
 		basic_machine=m68000-convergent
 		;;
@@ -1210,7 +1214,7 @@
 	      | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
 	      | -chorusos* | -chorusrdb* \
 	      | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
-	      | -mingw32* | -linux-gnu* | -linux-newlib* | -linux-uclibc* \
+	      | -mingw32* | -mingw64* | -linux-gnu* | -linux-newlib* | -linux-uclibc* \
 	      | -uxpv* | -beos* | -mpeix* | -udk* \
 	      | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
 	      | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
diff -rNbu -x CVS src/configure src_n/configure
--- src/configure	2006-08-30 15:14:18.000000000 +0200
+++ src_n/configure	2006-09-18 09:24:03.000000000 +0200
@@ -1097,6 +1097,10 @@
     # noconfigdirs="tcl tk expect dejagnu make texinfo bison patch flex byacc send-pr uudecode dejagnu diff guile perl itcl gnuserv"
     noconfigdirs="$noconfigdirs expect dejagnu autoconf automake send-pr rcs guile perl texinfo libtool newlib"
     ;;
+  x86_64-*-mingw64*)
+    # noconfigdirs="tcl tk expect dejagnu make texinfo bison patch flex byacc send-pr uudecode dejagnu diff guile perl itcl gnuserv"
+    noconfigdirs="$noconfigdirs expect dejagnu autoconf automake send-pr rcs guile perl texinfo libtool newlib"
+    ;;
   i[3456789]86-*-beos*)
     noconfigdirs="$noconfigdirs tk itcl libgui gdb"
     ;;
@@ -1442,6 +1446,10 @@
     target_configdirs="$target_configdirs target-winsup"
     noconfigdirs="$noconfigdirs expect target-libgloss target-newlib ${libgcj}"
     ;;    
+  x86_64-*-mingw64*)
+    target_configdirs="$target_configdirs target-winsup"
+    noconfigdirs="$noconfigdirs expect target-libgloss target-newlib ${libgcj}"
+    ;;    
   *-*-cygwin*)
     target_configdirs="$target_configdirs target-libtermcap target-winsup"
     noconfigdirs="$noconfigdirs target-gperf target-libgloss ${libgcj}"
@@ -1760,6 +1768,8 @@
     ;;
   *-mingw32*)
     ;;
+  *-mingw64*)
+    ;;
   *-interix*)
     host_makefile_frag="config/mh-interix"
     ;;
diff -rNbu -x CVS src/configure.in src_n/configure.in
--- src/configure.in	2006-08-30 15:14:18.000000000 +0200
+++ src_n/configure.in	2006-09-18 09:25:14.000000000 +0200
@@ -281,6 +281,10 @@
     # noconfigdirs="tcl tk expect dejagnu make texinfo bison patch flex byacc send-pr uudecode dejagnu diff guile perl itcl gnuserv"
     noconfigdirs="$noconfigdirs expect dejagnu autoconf automake send-pr rcs guile perl texinfo libtool newlib"
     ;;
+  x86_64-*-mingw64*)
+    # noconfigdirs="tcl tk expect dejagnu make texinfo bison patch flex byacc send-pr uudecode dejagnu diff guile perl itcl gnuserv"
+    noconfigdirs="$noconfigdirs expect dejagnu autoconf automake send-pr rcs guile perl texinfo libtool newlib"
+    ;;
   i[[3456789]]86-*-beos*)
     noconfigdirs="$noconfigdirs tk itcl libgui gdb"
     ;;
@@ -618,6 +622,10 @@
     target_configdirs="$target_configdirs target-winsup"
     noconfigdirs="$noconfigdirs expect target-libgloss target-newlib ${libgcj}"
     ;;    
+  x86_64-*-mingw64*)
+    target_configdirs="$target_configdirs target-winsup"
+    noconfigdirs="$noconfigdirs expect target-libgloss target-newlib ${libgcj}"
+    ;;    
   *-*-cygwin*)
     target_configdirs="$target_configdirs target-libtermcap target-winsup"
     noconfigdirs="$noconfigdirs target-gperf target-libgloss ${libgcj}"
@@ -936,6 +944,8 @@
     ;;
   *-mingw32*)
     ;;
+  *-mingw64*)
+    ;;
   *-interix*)
     host_makefile_frag="config/mh-interix"
     ;;
diff -rNbu -x CVS src/include/coff/external.h src_n/include/coff/external.h
--- src/include/coff/external.h	2005-05-10 12:21:09.000000000 +0200
+++ src_n/include/coff/external.h	2006-09-18 10:06:55.000000000 +0200
@@ -55,6 +55,20 @@
 
 #define AOUTHDRSZ 28
 #define AOUTSZ 28
+
+typedef struct external_aouthdr64
+  {
+    char magic[2];	/* type of file				*/
+    char vstamp[2];	/* version stamp			*/
+    char tsize[4];	/* text size in bytes, padded to FW bdry*/
+    char dsize[4];	/* initialized data "  "		*/
+    char bsize[4];	/* uninitialized data "   "		*/
+    char entry[4];	/* entry pt.				*/
+    char text_start[4];	/* base of text used for this file 	*/
+  }
+AOUTHDR64;
+#define AOUTHDRSZ64	24
+
 #endif
 
 #ifndef DO_NOT_DEFINE_SCNHDR
diff -rNbu -x CVS src/include/coff/internal.h src_n/include/coff/internal.h
--- src/include/coff/internal.h	2006-02-05 12:57:34.000000000 +0100
+++ src_n/include/coff/internal.h	2006-09-18 10:07:32.000000000 +0200
@@ -604,6 +604,24 @@
   unsigned long r_offset;	/* Used by Alpha ECOFF, SPARC, others */
 };
 
+/* X86-64 relocations */
+#define R_AMD64_ABS 0 /* Reference is absolute, no relocation is necessary */
+#define R_AMD64_DIR64	1 /* 64-bit address (VA) */
+#define R_AMD64_DIR32	2 /* 32-bit address (VA) R_DIR32 */
+#define R_AMD64_IMAGEBASE	 3 /* 32-bit absolute ref w/o base R_IMAGEBASE */
+#define R_AMD64_PCRLONG		 4 /* 32-bit relative address from byte following reloc R_PCRLONG */
+#define R_AMD64_PCRLONG_1		 5 /* 32-bit relative address from byte distance 1 from reloc */
+#define R_AMD64_PCRLONG_2		 6 /* 32-bit relative address from byte distance 2 from reloc */
+#define R_AMD64_PCRLONG_3		 7 /* 32-bit relative address from byte distance 3 from reloc */
+#define R_AMD64_PCRLONG_4		 8 /* 32-bit relative address from byte distance 4 from reloc */
+#define R_AMD64_PCRLONG_5		 9 /* 32-bit relative address from byte distance 5 from reloc */
+#define R_AMD64_SECTION	10 /* Section index */
+#define R_AMD64_SECREL	11 /* 32 bit offset from base of section containing target R_SECREL*/
+#define R_AMD64_SECREL7	12 /* 7 bit unsigned offset from base of section containing target */
+#define R_AMD64_TOKEN	13 /* 32 bit metadata token */
+/* Pseude PC64 relocation - note not specified by MS/AMD but need for gas pc-relative 64bit wide relocation generated by elf*/
+#define R_AMD64_PCRQUAD	14
+
 #define R_DIR16 	 1
 #define R_REL24          5
 #define R_DIR32 	 6
diff -rNbu -x CVS src/include/coff/pe.h src_n/include/coff/pe.h
--- src/include/coff/pe.h	2005-05-10 12:21:09.000000000 +0200
+++ src_n/include/coff/pe.h	2006-09-18 10:09:19.000000000 +0200
@@ -119,6 +119,7 @@
 #define IMAGE_FILE_MACHINE_THUMB             0x01c2
 #define IMAGE_FILE_MACHINE_TRICORE           0x0520
 #define IMAGE_FILE_MACHINE_WCEMIPSV2         0x0169
+#define IMAGE_FILE_MACHINE_AMD64             0x8664  // AMD64 (K8)
 
 #define IMAGE_SUBSYSTEM_UNKNOWN			 0
 #define IMAGE_SUBSYSTEM_NATIVE			 1
@@ -267,7 +268,7 @@
    of just 4 bytes long.  */
 typedef struct 
 {
-  AOUTHDR standard;
+  AOUTHDR64 standard;
 
   /* NT extra fields; see internal.h for descriptions.  */
   char  ImageBase[8];
@@ -294,7 +295,7 @@
   /* IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];  */
   char  DataDirectory[16][2][4]; /* 16 entries, 2 elements/entry, 4 chars.  */
 } PEPAOUTHDR;
-#define PEPAOUTSZ	240
+#define PEPAOUTSZ	(AOUTHDRSZ64+216) /* 240 */
   
 #undef  E_FILNMLEN
 #define E_FILNMLEN	18	/* # characters in a file name.  */
diff -rNbu -x CVS src/include/coff/x86_64.h src_n/include/coff/x86_64.h
--- src/include/coff/x86_64.h	1970-01-01 01:00:00.000000000 +0100
+++ src_n/include/coff/x86_64.h	2006-08-17 09:12:24.000000000 +0200
@@ -0,0 +1,67 @@
+/* coff information for AMD 64.
+   Copyright 1995, 1996, 1999, 2001, 2002, 2004 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.
+*/
+
+#define L_LNNO_SIZE 2
+#define INCLUDE_COMDAT_FIELDS_IN_AUXENT
+#include "coff/external.h"
+
+/* Bits for f_flags:
+ 	F_RELFLG	relocation info stripped from file
+ 	F_EXEC		file is executable (no unresolved external references)
+ 	F_LNNO		line numbers stripped from file
+ 	F_LSYMS		local symbols stripped from file
+ 	F_AR32WR	file has byte ordering of an AR32WR machine (e.g. vax).  */
+
+#define F_RELFLG	(0x0001)
+#define F_EXEC		(0x0002)
+#define F_LNNO		(0x0004)
+#define F_LSYMS		(0x0008)
+
+#define AMD64MAGIC	0x8664
+
+#define AMD64BADMAG(x)	( (x).f_magic != AMD64MAGIC)
+#define IMAGE_NT_OPTIONAL_HDR64_MAGIC      0x20b
+
+#define OMAGIC          0404    /* object files, eg as output */
+#define ZMAGIC          IMAGE_NT_OPTIONAL_HDR64_MAGIC    /* demand load format, eg normal ld output 0x10b */
+#define STMAGIC		0401	/* target shlib */
+#define SHMAGIC		0443	/* host   shlib */
+
+/* define some NT default values */
+/*  #define NT_IMAGE_BASE        0x400000 moved to internal.h */
+#define NT_SECTION_ALIGNMENT 0x1000
+#define NT_FILE_ALIGNMENT    0x200
+#define NT_DEF_RESERVE       0x100000
+#define NT_DEF_COMMIT        0x1000
+
+/********************** RELOCATION DIRECTIVES **********************/
+
+struct external_reloc
+{
+  char r_vaddr[4];
+  char r_symndx[4];
+  char r_type[2];
+};
+
+#define RELOC struct external_reloc
+#define RELSZ 10
+

^ permalink raw reply	[flat|nested] 2+ messages in thread

* PE+ & Coff for x86_64 target (Part I)
@ 2006-09-18 13:26 Kai Tietz
  0 siblings, 0 replies; 2+ messages in thread
From: Kai Tietz @ 2006-09-18 13:26 UTC (permalink / raw)
  To: binutils; +Cc: Pedro Alves

[-- Attachment #1: Type: text/plain, Size: 5826 bytes --]

Hallo,

It seems to be that I posted a too large patch ("PE+ and new COFF format 
for x86_64 target for XP64 and Vista binaries"). Therefore I split this 
patch into four smaller patches. The first one is the patch for the 
include/coff/ directory and the bfd directory, which are strongly wired 
and therefore not splittable. The biggest change for coff is the change of 
the PEPAOUTHDR structure, which had the wrong size, because it defines in 
the header the field data_start, which does not exists for PE+.

Remark, that you have to enable 64-bit-bfd and specifying the target 
"x86_64-pc-mingw64" for the cross build. This patch also includes the 
main-level build patches to config.guess, config.sub, and configure.in. 
Additionally there is a generated version of configure, too.

        * config.guess: Add MINGW64 target detection
        * config.sub:   Add mingw64 target
        * configure.in: Likewise

A global part of this patch was done in include/coff which defines some 
new constants for the coff-format, the magic signature for x86_64, and a 
change to PEPAOUTHDR which had for PE+ the wrong size. The coff relocation 
definitions in coff/internal.h are taken as defined by AMD&MS, but the 
R_AMD64_PCRQUAD is added to enable gas to define 64-bit wide PC-relative 
relocations. The AMD/MS version does not define such wide PC-relative 
relocations in there object format as I know.

Changes in include/coff:
        * external.h:   Add new  aout header structure for PE+
                external_aouthdr64:     Structure for PE+ aout header 
without the data_start element. This elements led to a size of 28 bytes 
instead of correct 24 bytes in PE+.
                AOUTHDRSZ define:       Defines the sizeof of the 
external_aouthdr64 structure of 24 bytes.
        * internal.h:   Add target specific constants for coff x86_64 
(used mostly in bfd/coff-x86_64.c)
                R_AMD64_ABS define:             Reference is absolute, no 
relocation is necessary 
                R_AMD64_DIR64 define:    64-bit address (VA) 
                R_AMD64_DIR32 define:   32-bit address (VA) R_DIR32 
                R_AMD64_IMAGEBASE define:       32-bit absolute ref w/o 
base R_IMAGEBASE
                R_AMD64_PCRLONG define: 32-bit relative address from byte 
following reloc R_PCRLONG
                R_AMD64_PCRLONG_1define:        32-bit relative address 
from byte distance 1 from reloc
                R_AMD64_PCRLONG_2 define:       32-bit relative address 
from byte distance 2 from reloc
                R_AMD64_PCRLONG_3 define:       32-bit relative address 
from byte distance 3 from reloc
                R_AMD64_PCRLONG_4 define:       32-bit relative address 
from byte distance 4 from reloc
                R_AMD64_PCRLONG_5 define:       32-bit relative address 
from byte distance 5 from reloc
                R_AMD64_SECTION define: Section index
                R_AMD64_SECREL define:  32 bit offset from base of section 
containing target R_SECREL
                R_AMD64_SECREL7 define: 7 bit unsigned offset from base of 
section containing target
                R_AMD64_TOKEN define:   32 bit metadata token (used by #c)
                R_AMD64_PCRQUAD define:  Pseude PC64 relocation - note not 
specified by MS/AMD but need for gas pc-relative 64bit wide relocation 
generated by elf
        * pe.h: Definition of new magic signature and the correction of 
PEPAOUTHDR structure.
                IMAGE_FILE_MACHINE_AMD64 define:                AMD64 (K8) 
coff magic signature
                PEPAOUTHDR structure:                   Changed standard 
element from AOUTHDR to AOUTHDR64 for proper structure size.
                PEPAOUTSZ define:                               Changed to 
reflect the making of the calculated value of 240 bytes.
        * x86_64.h:     New file for the needed coff defines for this new 
target.


Changes in bfd:
        * coff-x86_64.c:                New coff format handler for x86_64
        * coffcode.h:           Changes to reflect the magic signature 
treating of bfd
        * config.bfd:           Added target handling
        * configure.in:         Likewise
        * libpei.h:             Add correct PE+ header access macros for 
PE+ x86_64 (COFF_WITH_pex64)
        * Makefile.am:          Added new file generation and build rules 
for coff-x86_64.c, pe-x86_64.c, pei-x86_64.c, and generated pex64igen.c
        * Makefile.in:          Likewise
        * pe-x86_64.c:          New object format pe-x86_64 handler
        * pei-x86_64.c:         New object format pei-x86_64 handler
        * peicode.h:            Definition of proper coff_swap_filehdr_out 
macro for target, and changed IDATA sizes for PE+
                SIZEOF_IDATA4 macro:    For x86_64 PE+ it has size of 8 
bytes
                SIZEOF_IDATA5 macro:    Likewise
                jtab structure:                 Add new jump table element 
for target
                pe_ILF_build_a_bfd function:    Add handling of ordinals 
for PE+ (IDATA4 & IDATA5)
                pe_ILF_object_p function:       Add magic signature for 
the target object file detection.
        * pexxigen.c:           Make sure the proper architecture file is 
included and the specific code for PE+ x86_64 is enabled.
                pe_print_idata function:                Added proper print 
of PE+ x86_64 imports
                pe_print_pdata function:                Reflect pdata 
handling for x86_64 target.
        * target.c:             Add new object file handlers for coff 
x86_64


Regards,
 i.A. Kai Tietz


----------------------------------------
  Kai Tietz - Software engineering
  OneVision Software Entwicklungs GmbH & Co KG
  Dr.-Leo-Ritter-Str. 9, 93049 Regensburg, Germany
  Phone: +49-941-78004-0
  FAX:   +49-941-78004-489
  WWW:   http://www.OneVision.com

[-- Attachment #2: x86_64coff_bfd.diff --]
[-- Type: application/octet-stream, Size: 60210 bytes --]

diff -rNbu -x CVS src/bfd/Makefile.am src_n/bfd/Makefile.am
--- src/bfd/Makefile.am	2006-09-18 08:51:41.000000000 +0200
+++ src_n/bfd/Makefile.am	2006-09-18 09:49:24.000000000 +0200
@@ -563,7 +563,11 @@
 	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 @@
 	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 @@
 	$(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 @@
 	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 @@
 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 -rNbu -x CVS src/bfd/Makefile.in src_n/bfd/Makefile.in
--- src/bfd/Makefile.in	2006-09-18 08:51:41.000000000 +0200
+++ src_n/bfd/Makefile.in	2006-09-18 09:51:37.000000000 +0200
@@ -796,7 +796,11 @@
 	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 @@
 	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 @@
 	$(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 = \
@@ -1368,6 +1375,11 @@
 	sed -e s/XX/pe/g < $(srcdir)/peXXigen.c > peigen.new
 	mv -f peigen.new peigen.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
+	
 pepigen.c : peXXigen.c
 	rm -f pepigen.c
 	sed -e s/XX/pep/g < $(srcdir)/peXXigen.c > pepigen.new
@@ -2422,6 +2434,9 @@
 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 -rNbu -x CVS src/bfd/coff-x86_64.c src_n/bfd/coff-x86_64.c
--- src/bfd/coff-x86_64.c	1970-01-01 01:00:00.000000000 +0100
+++ src_n/bfd/coff-x86_64.c	2006-09-06 12:28:12.000000000 +0200
@@ -0,0 +1,751 @@
+/* BFD back-end for AMD 64 COFF files.
+   Copyright 1995, 1996, 1999, 2001, 2002, 2004 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"
+
+#define BADMAG(x) AMD64BADMAG(x)
+
+#ifdef COFF_WITH_pex64
+# undef AOUTSZ
+# define AOUTSZ		PEPAOUTSZ
+# define PEAOUTHDR	PEPAOUTHDR
+#endif
+
+static bfd_reloc_status_type coff_amd64_reloc(bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **);
+static reloc_howto_type *coff_amd64_rtype_to_howto(bfd *, asection *, struct internal_reloc *,struct coff_link_hash_entry *, struct internal_syment *,bfd_vma *);
+static reloc_howto_type *coff_amd64_reloc_type_lookup(bfd *, bfd_reloc_code_real_type);
+
+#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,PTR data,asection *input_section ATTRIBUTE_UNUSED,
+				 bfd *output_bfd,char **error_message ATTRIBUTE_UNUSED)
+{
+  symvalue diff;
+
+#if !defined(COFF_WITH_PE)
+  if(output_bfd == (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 == (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 *, reloc_howto_type *);
+
+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 < sizeof (howto_table) / sizeof (howto_table[0])	\
+    ? 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 = (coff_symbol_type *) 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!=(coff_symbol_type *) 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!=(asection *) 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 *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,struct internal_reloc *, struct internal_syment *, asection **);
+
+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 > sizeof (howto_table) / sizeof (howto_table[0])) {
+      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 trough */
+#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 *, const char *);
+
+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 -rNbu -x CVS src/bfd/coffcode.h src_n/bfd/coffcode.h
--- src/bfd/coffcode.h	2006-09-18 08:51:42.000000000 +0200
+++ src_n/bfd/coffcode.h	2006-09-18 09:30:46.000000000 +0200
@@ -1887,6 +1887,12 @@
       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;
@@ -2722,12 +2728,18 @@
 #endif
 
 #ifdef I386MAGIC
+#if defined(I386MAGIC) || defined(AMD64MAGIC)
     case bfd_arch_i386:
+#ifdef I386MAGIC
       *magicp = I386MAGIC;
+#endif
 #ifdef LYNXOS
       /* Just overwrite the usual value if we're doing Lynx.  */
       *magicp = LYNXCOFFMAGIC;
 #endif
+#ifdef AMD64MAGIC
+	  *magicp = AMD64MAGIC;
+#endif
       return TRUE;
 #endif
 
@@ -3759,6 +3771,7 @@
     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 +3780,7 @@
   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,
@@ -3862,8 +3876,12 @@
 #define __A_MAGIC_SET__
 #if defined(LYNXOS)
     internal_a.magic = LYNXCOFFMAGIC;
-#else  /* LYNXOS */
+#else  /* !LYNXOS */
+#ifdef AMD64
+	internal_a.magic = IMAGE_NT_OPTIONAL_HDR64_MAGIC;
+#else
     internal_a.magic = ZMAGIC;
+#endif
 #endif /* LYNXOS */
 #endif /* I386 */
 
diff -rNbu -x CVS src/bfd/config.bfd src_n/bfd/config.bfd
--- src/bfd/config.bfd	2006-09-18 08:51:42.000000000 +0200
+++ src_n/bfd/config.bfd	2006-09-18 09:32:32.000000000 +0200
@@ -98,7 +98,7 @@
 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 @@
     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 -rNbu -x CVS src/bfd/configure src_n/bfd/configure
--- src/bfd/configure	2006-09-18 08:51:42.000000000 +0200
+++ src_n/bfd/configure	2006-09-18 09:36:04.000000000 +0200
@@ -4086,7 +4086,7 @@
   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,6 +4097,9 @@
     case "`/usr/bin/file conftest.o`" in
     *32-bit*)
       case $host in
+        x86_64-*mingw64*)
+          LD="${LD-ld} -m elf_i386"
+          ;;
         x86_64-*linux*)
           LD="${LD-ld} -m elf_i386"
           ;;
@@ -4113,6 +4116,9 @@
       ;;
     *64-bit*)
       case $host in
+        x86_64-*mingw64*)
+          LD="${LD-ld} -m elf_x86_64"
+          ;;
         x86_64-*linux*)
           LD="${LD-ld} -m elf_x86_64"
           ;;
@@ -10951,6 +10957,7 @@
     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" ;;
@@ -10961,7 +10968,9 @@
     i386netbsd_vec)		tb="$tb i386netbsd.lo aout32.lo" ;;
     i386os9k_vec)		tb="$tb i386os9k.lo aout32.lo" ;;
     i386pe_vec)			tb="$tb pe-i386.lo peigen.lo cofflink.lo" ;;
+    x86_64pe_vec)		tb="$tb pe-x86_64.lo pex64igen.lo cofflink.lo"; target_size=64 ;;
     i386pei_vec)		tb="$tb pei-i386.lo peigen.lo cofflink.lo" ;;
+    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 -rNbu -x CVS src/bfd/configure.in src_n/bfd/configure.in
--- src/bfd/configure.in	2006-09-18 08:51:42.000000000 +0200
+++ src_n/bfd/configure.in	2006-09-18 09:37:10.000000000 +0200
@@ -741,6 +741,7 @@
     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" ;;
@@ -751,7 +752,9 @@
     i386netbsd_vec)		tb="$tb i386netbsd.lo aout32.lo" ;;
     i386os9k_vec)		tb="$tb i386os9k.lo aout32.lo" ;;
     i386pe_vec)			tb="$tb pe-i386.lo peigen.lo cofflink.lo" ;;
+    x86_64pe_vec)		tb="$tb pe-x86_64.lo pex64igen.lo cofflink.lo"; target_size=64 ;;
     i386pei_vec)		tb="$tb pei-i386.lo peigen.lo cofflink.lo" ;;
+    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 -rNbu -x CVS src/bfd/libpei.h src_n/bfd/libpei.h
--- src/bfd/libpei.h	2006-09-18 08:51:48.000000000 +0200
+++ src_n/bfd/libpei.h	2006-09-18 09:39:13.000000000 +0200
@@ -204,6 +204,38 @@
 #define PUT_SCNHDR_LNNOPTR H_PUT_32
 #endif
 
+#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
+
+#else /* !COFF_WITH_pex64 */
 #ifdef COFF_WITH_pep
 
 #define GET_OPTHDR_IMAGE_BASE H_GET_64
@@ -269,6 +301,7 @@
 #define _bfd_XXi_swap_sym_out				_bfd_pei_swap_sym_out
 
 #endif /* !COFF_WITH_pep */
+#endif /* !COFF_WITG_pex64 */
 
 /* Macro: Returns true if the bfd is a PE executable as opposed to a PE object file.  */
 #define bfd_pe_executable_p(abfd)			\
diff -rNbu -x CVS src/bfd/pe-x86_64.c src_n/bfd/pe-x86_64.c
--- src/bfd/pe-x86_64.c	1970-01-01 01:00:00.000000000 +0100
+++ src_n/bfd/pe-x86_64.c	2006-09-06 12:23:54.000000000 +0200
@@ -0,0 +1,54 @@
+/* BFD back-end for Intel/AMD x86_64 PECOFF files.
+   Copyright 1995, 1996, 1999, 2001, 2002, 2004 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 -rNbu -x CVS src/bfd/peXXigen.c src_n/bfd/peXXigen.c
--- src/bfd/peXXigen.c	2006-07-24 18:51:26.000000000 +0200
+++ src_n/bfd/peXXigen.c	2006-09-18 10:04:10.000000000 +0200
@@ -67,17 +67,21 @@
    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
-# include "coff/ia64.h"
+#ifdef COFF_WITH_pex64
+# include "coff/x86_64.h"
 #else
+# ifdef COFF_WITH_pep
+#  include "coff/ia64.h"
+# else
 # include "coff/i386.h"
+# endif
 #endif
 
 #include "coff/pe.h"
 #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 +403,7 @@
   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);
@@ -455,7 +459,7 @@
   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 +467,12 @@
   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 +552,7 @@
   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 +560,7 @@
   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 +568,7 @@
   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 +665,7 @@
   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 +1266,35 @@
 	    }
 
 	  /* 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,6 +1327,7 @@
 
 	      fprintf (file, "\n");
 	    }
+#endif /* !defined(COFF_WITH_pex64) */
 
 	  if (ft_allocated)
 	    free (ft_data);
@@ -1534,7 +1568,7 @@
 static bfd_boolean
 pe_print_pdata (bfd * abfd, void * vfile)
 {
-#ifdef COFF_WITH_pep
+#if defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64)
 # define PDATA_ROW_SIZE	(3*8)
 #else
 # define PDATA_ROW_SIZE	(5*4)
@@ -1560,7 +1594,7 @@
 
   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 +1648,7 @@
       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 -rNbu -x CVS src/bfd/pei-x86_64.c src_n/bfd/pei-x86_64.c
--- src/bfd/pei-x86_64.c	1970-01-01 01:00:00.000000000 +0100
+++ src_n/bfd/pei-x86_64.c	2006-09-06 12:23:58.000000000 +0200
@@ -0,0 +1,55 @@
+/* BFD back-end for Intel 386 PE IMAGE COFF files.
+   Copyright 1995, 1996, 1999, 2001, 2002, 2004 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 -rNbu -x CVS src/bfd/peicode.h src_n/bfd/peicode.h
--- src/bfd/peicode.h	2005-05-04 17:53:37.000000000 +0200
+++ src_n/bfd/peicode.h	2006-09-18 09:56:19.000000000 +0200
@@ -183,7 +183,15 @@
 #ifdef COFF_IMAGE_WITH_PE
 # define coff_swap_filehdr_out _bfd_XXi_only_swap_filehdr_out
 #else
+# ifdef COFF_WITH_pex64
+#  define coff_swap_filehdr_out _bfd_pex64_only_swap_filehdr_out
+# else
+#  ifdef 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
+# endif
 #endif
 
 static void
@@ -405,8 +413,15 @@
 					+ NUM_ILF_SECTIONS * 9 \
 					+ STRING_SIZE_SIZE)
 #define SIZEOF_IDATA2		(5 * 4)
+/* For PE+ idata4 & 5 have thumb size of 8 bytes ! */
+#ifndef COFF_WITH_pex64
 #define SIZEOF_IDATA4		(1 * 4)
 #define SIZEOF_IDATA5		(1 * 4)
+#else
+#define SIZEOF_IDATA4		(2 * 4)
+#define SIZEOF_IDATA5		(2 * 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,6 +671,13 @@
   },
 #endif
 
+#ifdef AMD64MAGIC
+  { AMD64MAGIC,
+  { 0xff,0x25,0x00,0x00,0x00,0x00,0x90,0x90 },
+  8,2
+  },
+#endif
+
 #ifdef  MC68MAGIC
   { MC68MAGIC, { /* XXX fill me in */ }, 0, 0 },
 #endif
@@ -830,8 +852,15 @@
 	/* XXX - treat as IMPORT_NAME ??? */
 	abort ();
 
+#ifndef COFF_WITH_pex64
       * (unsigned int *) id4->contents = ordinal | 0x80000000;
       * (unsigned int *) id5->contents = ordinal | 0x80000000;
+#else
+      * (unsigned int *) id4->contents = ordinal;
+	  ((unsigned int *) id4->contents)[1] = 0x80000000;
+      * (unsigned int *) id5->contents = ordinal;
+      ((unsigned int *) id5->contents)[1] = 0x80000000;
+#endif
     }
   else
     {
@@ -1070,6 +1099,12 @@
       magic = I386MAGIC;
 #endif
       break;
+    case IMAGE_FILE_MACHINE_AMD64:
+#ifdef AMD64MAGIC
+      magic=AMD64MAGIC;
+#endif
+      break;
+
 
     case IMAGE_FILE_MACHINE_M68K:
 #ifdef MC68AGIC
diff -rNbu -x CVS src/bfd/targets.c src_n/bfd/targets.c
--- src/bfd/targets.c	2006-09-18 08:51:50.000000000 +0200
+++ src_n/bfd/targets.c	2006-09-18 10:05:31.000000000 +0200
@@ -791,6 +791,9 @@
 extern const bfd_target we32kcoff_vec;
 extern const bfd_target z80coff_vec;
 extern const bfd_target z8kcoff_vec;
+extern const bfd_target x86_64pe_vec;
+extern const bfd_target x86_64pei_vec;
+extern const bfd_target x86_64coff_vec;
 
 /* These are always included.  */
 extern const bfd_target srec_vec;
@@ -1037,6 +1040,11 @@
 #if 0
 	&i386dynix_vec,
 #endif
+#ifdef BFD64
+	&x86_64coff_vec,
+	&x86_64pe_vec,
+	&x86_64pei_vec,
+#endif
 	&i386freebsd_vec,
 #if 0
 	/* Since a.out files lack decent magic numbers, no way to recognize
diff -rNbu -x CVS src/config.guess src_n/config.guess
--- src/config.guess	2006-05-14 02:51:19.000000000 +0200
+++ src_n/config.guess	2006-09-18 09:20:25.000000000 +0200
@@ -780,7 +780,13 @@
     i*:CYGWIN*:*)
 	echo ${UNAME_MACHINE}-pc-cygwin
 	exit ;;
-    i*:MINGW*:*)
+    x86*:MINGW64*:*)
+	echo ${UNAME_MACHINE}-pc-mingw64
+	exit ;;
+    i*:MINGW64*:*)
+	echo ${UNAME_MACHINE}-pc-mingw64
+	exit ;;
+    i*:MINGW32*:*)
 	echo ${UNAME_MACHINE}-pc-mingw32
 	exit ;;
     i*:windows32*:*)
diff -rNbu -x CVS src/config.sub src_n/config.sub
--- src/config.sub	2006-08-15 20:23:07.000000000 +0200
+++ src_n/config.sub	2006-09-18 09:22:13.000000000 +0200
@@ -682,6 +682,10 @@
 		basic_machine=i386-pc
 		os=-mingw32
 		;;
+	mingw64)
+		basic_machine=x86_64-pc
+		os=-mingw64
+		;;
 	miniframe)
 		basic_machine=m68000-convergent
 		;;
@@ -1210,7 +1214,7 @@
 	      | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
 	      | -chorusos* | -chorusrdb* \
 	      | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
-	      | -mingw32* | -linux-gnu* | -linux-newlib* | -linux-uclibc* \
+	      | -mingw32* | -mingw64* | -linux-gnu* | -linux-newlib* | -linux-uclibc* \
 	      | -uxpv* | -beos* | -mpeix* | -udk* \
 	      | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
 	      | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
diff -rNbu -x CVS src/configure src_n/configure
--- src/configure	2006-08-30 15:14:18.000000000 +0200
+++ src_n/configure	2006-09-18 09:24:03.000000000 +0200
@@ -1097,6 +1097,10 @@
     # noconfigdirs="tcl tk expect dejagnu make texinfo bison patch flex byacc send-pr uudecode dejagnu diff guile perl itcl gnuserv"
     noconfigdirs="$noconfigdirs expect dejagnu autoconf automake send-pr rcs guile perl texinfo libtool newlib"
     ;;
+  x86_64-*-mingw64*)
+    # noconfigdirs="tcl tk expect dejagnu make texinfo bison patch flex byacc send-pr uudecode dejagnu diff guile perl itcl gnuserv"
+    noconfigdirs="$noconfigdirs expect dejagnu autoconf automake send-pr rcs guile perl texinfo libtool newlib"
+    ;;
   i[3456789]86-*-beos*)
     noconfigdirs="$noconfigdirs tk itcl libgui gdb"
     ;;
@@ -1442,6 +1446,10 @@
     target_configdirs="$target_configdirs target-winsup"
     noconfigdirs="$noconfigdirs expect target-libgloss target-newlib ${libgcj}"
     ;;    
+  x86_64-*-mingw64*)
+    target_configdirs="$target_configdirs target-winsup"
+    noconfigdirs="$noconfigdirs expect target-libgloss target-newlib ${libgcj}"
+    ;;    
   *-*-cygwin*)
     target_configdirs="$target_configdirs target-libtermcap target-winsup"
     noconfigdirs="$noconfigdirs target-gperf target-libgloss ${libgcj}"
@@ -1760,6 +1768,8 @@
     ;;
   *-mingw32*)
     ;;
+  *-mingw64*)
+    ;;
   *-interix*)
     host_makefile_frag="config/mh-interix"
     ;;
diff -rNbu -x CVS src/configure.in src_n/configure.in
--- src/configure.in	2006-08-30 15:14:18.000000000 +0200
+++ src_n/configure.in	2006-09-18 09:25:14.000000000 +0200
@@ -281,6 +281,10 @@
     # noconfigdirs="tcl tk expect dejagnu make texinfo bison patch flex byacc send-pr uudecode dejagnu diff guile perl itcl gnuserv"
     noconfigdirs="$noconfigdirs expect dejagnu autoconf automake send-pr rcs guile perl texinfo libtool newlib"
     ;;
+  x86_64-*-mingw64*)
+    # noconfigdirs="tcl tk expect dejagnu make texinfo bison patch flex byacc send-pr uudecode dejagnu diff guile perl itcl gnuserv"
+    noconfigdirs="$noconfigdirs expect dejagnu autoconf automake send-pr rcs guile perl texinfo libtool newlib"
+    ;;
   i[[3456789]]86-*-beos*)
     noconfigdirs="$noconfigdirs tk itcl libgui gdb"
     ;;
@@ -618,6 +622,10 @@
     target_configdirs="$target_configdirs target-winsup"
     noconfigdirs="$noconfigdirs expect target-libgloss target-newlib ${libgcj}"
     ;;    
+  x86_64-*-mingw64*)
+    target_configdirs="$target_configdirs target-winsup"
+    noconfigdirs="$noconfigdirs expect target-libgloss target-newlib ${libgcj}"
+    ;;    
   *-*-cygwin*)
     target_configdirs="$target_configdirs target-libtermcap target-winsup"
     noconfigdirs="$noconfigdirs target-gperf target-libgloss ${libgcj}"
@@ -936,6 +944,8 @@
     ;;
   *-mingw32*)
     ;;
+  *-mingw64*)
+    ;;
   *-interix*)
     host_makefile_frag="config/mh-interix"
     ;;
diff -rNbu -x CVS src/include/coff/external.h src_n/include/coff/external.h
--- src/include/coff/external.h	2005-05-10 12:21:09.000000000 +0200
+++ src_n/include/coff/external.h	2006-09-18 10:06:55.000000000 +0200
@@ -55,6 +55,20 @@
 
 #define AOUTHDRSZ 28
 #define AOUTSZ 28
+
+typedef struct external_aouthdr64
+  {
+    char magic[2];	/* type of file				*/
+    char vstamp[2];	/* version stamp			*/
+    char tsize[4];	/* text size in bytes, padded to FW bdry*/
+    char dsize[4];	/* initialized data "  "		*/
+    char bsize[4];	/* uninitialized data "   "		*/
+    char entry[4];	/* entry pt.				*/
+    char text_start[4];	/* base of text used for this file 	*/
+  }
+AOUTHDR64;
+#define AOUTHDRSZ64	24
+
 #endif
 
 #ifndef DO_NOT_DEFINE_SCNHDR
diff -rNbu -x CVS src/include/coff/internal.h src_n/include/coff/internal.h
--- src/include/coff/internal.h	2006-02-05 12:57:34.000000000 +0100
+++ src_n/include/coff/internal.h	2006-09-18 10:07:32.000000000 +0200
@@ -604,6 +604,24 @@
   unsigned long r_offset;	/* Used by Alpha ECOFF, SPARC, others */
 };
 
+/* X86-64 relocations */
+#define R_AMD64_ABS 0 /* Reference is absolute, no relocation is necessary */
+#define R_AMD64_DIR64	1 /* 64-bit address (VA) */
+#define R_AMD64_DIR32	2 /* 32-bit address (VA) R_DIR32 */
+#define R_AMD64_IMAGEBASE	 3 /* 32-bit absolute ref w/o base R_IMAGEBASE */
+#define R_AMD64_PCRLONG		 4 /* 32-bit relative address from byte following reloc R_PCRLONG */
+#define R_AMD64_PCRLONG_1		 5 /* 32-bit relative address from byte distance 1 from reloc */
+#define R_AMD64_PCRLONG_2		 6 /* 32-bit relative address from byte distance 2 from reloc */
+#define R_AMD64_PCRLONG_3		 7 /* 32-bit relative address from byte distance 3 from reloc */
+#define R_AMD64_PCRLONG_4		 8 /* 32-bit relative address from byte distance 4 from reloc */
+#define R_AMD64_PCRLONG_5		 9 /* 32-bit relative address from byte distance 5 from reloc */
+#define R_AMD64_SECTION	10 /* Section index */
+#define R_AMD64_SECREL	11 /* 32 bit offset from base of section containing target R_SECREL*/
+#define R_AMD64_SECREL7	12 /* 7 bit unsigned offset from base of section containing target */
+#define R_AMD64_TOKEN	13 /* 32 bit metadata token */
+/* Pseude PC64 relocation - note not specified by MS/AMD but need for gas pc-relative 64bit wide relocation generated by elf*/
+#define R_AMD64_PCRQUAD	14
+
 #define R_DIR16 	 1
 #define R_REL24          5
 #define R_DIR32 	 6
diff -rNbu -x CVS src/include/coff/pe.h src_n/include/coff/pe.h
--- src/include/coff/pe.h	2005-05-10 12:21:09.000000000 +0200
+++ src_n/include/coff/pe.h	2006-09-18 10:09:19.000000000 +0200
@@ -119,6 +119,7 @@
 #define IMAGE_FILE_MACHINE_THUMB             0x01c2
 #define IMAGE_FILE_MACHINE_TRICORE           0x0520
 #define IMAGE_FILE_MACHINE_WCEMIPSV2         0x0169
+#define IMAGE_FILE_MACHINE_AMD64             0x8664  // AMD64 (K8)
 
 #define IMAGE_SUBSYSTEM_UNKNOWN			 0
 #define IMAGE_SUBSYSTEM_NATIVE			 1
@@ -267,7 +268,7 @@
    of just 4 bytes long.  */
 typedef struct 
 {
-  AOUTHDR standard;
+  AOUTHDR64 standard;
 
   /* NT extra fields; see internal.h for descriptions.  */
   char  ImageBase[8];
@@ -294,7 +295,7 @@
   /* IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];  */
   char  DataDirectory[16][2][4]; /* 16 entries, 2 elements/entry, 4 chars.  */
 } PEPAOUTHDR;
-#define PEPAOUTSZ	240
+#define PEPAOUTSZ	(AOUTHDRSZ64+216) /* 240 */
   
 #undef  E_FILNMLEN
 #define E_FILNMLEN	18	/* # characters in a file name.  */
diff -rNbu -x CVS src/include/coff/x86_64.h src_n/include/coff/x86_64.h
--- src/include/coff/x86_64.h	1970-01-01 01:00:00.000000000 +0100
+++ src_n/include/coff/x86_64.h	2006-08-17 09:12:24.000000000 +0200
@@ -0,0 +1,67 @@
+/* coff information for AMD 64.
+   Copyright 1995, 1996, 1999, 2001, 2002, 2004 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.
+*/
+
+#define L_LNNO_SIZE 2
+#define INCLUDE_COMDAT_FIELDS_IN_AUXENT
+#include "coff/external.h"
+
+/* Bits for f_flags:
+ 	F_RELFLG	relocation info stripped from file
+ 	F_EXEC		file is executable (no unresolved external references)
+ 	F_LNNO		line numbers stripped from file
+ 	F_LSYMS		local symbols stripped from file
+ 	F_AR32WR	file has byte ordering of an AR32WR machine (e.g. vax).  */
+
+#define F_RELFLG	(0x0001)
+#define F_EXEC		(0x0002)
+#define F_LNNO		(0x0004)
+#define F_LSYMS		(0x0008)
+
+#define AMD64MAGIC	0x8664
+
+#define AMD64BADMAG(x)	( (x).f_magic != AMD64MAGIC)
+#define IMAGE_NT_OPTIONAL_HDR64_MAGIC      0x20b
+
+#define OMAGIC          0404    /* object files, eg as output */
+#define ZMAGIC          IMAGE_NT_OPTIONAL_HDR64_MAGIC    /* demand load format, eg normal ld output 0x10b */
+#define STMAGIC		0401	/* target shlib */
+#define SHMAGIC		0443	/* host   shlib */
+
+/* define some NT default values */
+/*  #define NT_IMAGE_BASE        0x400000 moved to internal.h */
+#define NT_SECTION_ALIGNMENT 0x1000
+#define NT_FILE_ALIGNMENT    0x200
+#define NT_DEF_RESERVE       0x100000
+#define NT_DEF_COMMIT        0x1000
+
+/********************** RELOCATION DIRECTIVES **********************/
+
+struct external_reloc
+{
+  char r_vaddr[4];
+  char r_symndx[4];
+  char r_type[2];
+};
+
+#define RELOC struct external_reloc
+#define RELSZ 10
+

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2006-09-18 12:31 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2006-09-18 14:48 PE+ & Coff for x86_64 target (Part I) Kai Tietz
  -- strict thread matches above, loose matches on Subject: below --
2006-09-18 13:26 Kai Tietz

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).