+2006-09-20 Kai Tietz <Kai.Tietz@onevision.com>
+
+ * configure.in: Added new target-vectors x86_64coff_vec,
+ x86_64pe_vec, and x86_64pei_vec.
+ * configure: Regenerate.
+ * config.bfd: Adjusted x86_64 target architecture detection.
+ * bfd.c: Add for new target "coff-x86-64"
+ (bfd_get_sign_extend): Add target vector idents for pe-x86-64. and pei-x86-64.
+ * coff-x86_64.c: Add new file for x86_64 (AMD64) coff support.
+ * libpei.h: Adjustments for COFF_WITH_pex64.
+ * coffcode.h: Add for new target machine, architecture, signature, and internal
+ signature handler.
+ * Makefile.am: Add new files to target-all and define make-rule for pex64igen.c
+ * Makefile.in: Regenerate.
+ * pe-x86_64.c: Add for new target "pe-x86-64".
+ * pei-x86_64.c: Add for new target "pei-x86-64".
+ * peicode.h: Adjusts for new targets.
+ (coff_swap_filehdr_out): Set for this target to
+ _bfd_pex64_only_swap_filehdr_out.
+ (SIZEOF_IDATA4): Define it as 8 byte size for this target.
+ (SIZEOF_IDATA5): Define it as 8 byte size for this target.
+ (jump_table jtab): Add for AMD64MAGIC.
+ (pe_ILF_build_a_bfd): Adjusts for new size of SIZEOF_IDATA4 and SIZE_IDATA5.
+ (pe_ILF_object_p): Add coff image-file signature to internal
+ signature translation.
+ * peXXigen.c: Adjust proper include of target coff-header and
+ introduced target specific code
+ (COFF_WITH_pex64): New macro for this target.
+ (pe_print_idata): New dumping method for import section of PE+ files.
+ * targets.c: Add new target vectors declarations for x86_64 coff targets.
+ * coffcode.h: Support code to support the x86_64 PE magic number.
+ * coff-x86_64.c: New file.
+
2006-09-17 Hans-Peter Nilsson <hp@axis.com>
* elf.c (special_sections_s): Revert last STRING_COMMA_LEN change
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 \
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 \
$(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)
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) \
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
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 \
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 \
$(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 = \
rm -f pepigen.c
sed -e s/XX/pep/g < $(srcdir)/peXXigen.c > pepigen.new
mv -f pepigen.new pepigen.c
+
+pex64igen.c: peXXigen.c
+ rm -f pex64igen.c
+ sed -e s/XX/pex64/g < $(srcdir)/peXXigen.c > pex64igen.new
+ mv -f pex64igen.new pex64igen.c
$(BFD32_LIBS) \
$(BFD64_LIBS) \
$(ALL_MACHINES) \
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.
--- /dev/null
+/* BFD back-end for AMD 64 COFF files.
+ Copyright 2006 Free Software Foundation, Inc.
+
+ This file is part of BFD, the Binary File Descriptor library.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
+
+ Written by Kai Tietz, OneVision Software GmbH&CoKg. */
+
+#ifndef COFF_WITH_pex64
+#define COFF_WITH_pex64
+#endif
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+#include "coff/x86_64.h"
+#include "coff/internal.h"
+#include "coff/pe.h"
+#include "libcoff.h"
+#include "libiberty.h"
+
+#define BADMAG(x) AMD64BADMAG(x)
+
+#ifdef COFF_WITH_pex64
+# undef AOUTSZ
+# define AOUTSZ PEPAOUTSZ
+# define PEAOUTHDR PEPAOUTHDR
+#endif
+
+#define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (2)
+
+/* The page size is a guess based on ELF. */
+
+#define COFF_PAGE_SIZE 0x1000
+
+/* For some reason when using AMD COFF the value stored in the .text
+ section for a reference to a common symbol is the value itself plus
+ any desired offset. Ian Taylor, Cygnus Support. */
+
+/* If we are producing relocatable output, we need to do some
+ adjustments to the object file that are not done by the
+ bfd_perform_relocation function. This function is called by every
+ reloc type to make any required adjustments. */
+
+static bfd_reloc_status_type
+coff_amd64_reloc (bfd *abfd,
+ arelent *reloc_entry,
+ asymbol *symbol,
+ void * data,
+ asection *input_section ATTRIBUTE_UNUSED,
+ bfd *output_bfd,
+ char **error_message ATTRIBUTE_UNUSED)
+{
+ symvalue diff;
+
+#if !defined(COFF_WITH_PE)
+ if (output_bfd == NULL)
+ return bfd_reloc_continue;
+#endif
+
+ if (bfd_is_com_section (symbol->section))
+ {
+#if !defined(COFF_WITH_PE)
+ /* We are relocating a common symbol. The current value in the
+ object file is ORIG + OFFSET, where ORIG is the value of the
+ common symbol as seen by the object file when it was compiled
+ (this may be zero if the symbol was undefined) and OFFSET is
+ the offset into the common symbol (normally zero, but may be
+ non-zero when referring to a field in a common structure).
+ ORIG is the negative of reloc_entry->addend, which is set by
+ the CALC_ADDEND macro below. We want to replace the value in
+ the object file with NEW + OFFSET, where NEW is the value of
+ the common symbol which we are going to put in the final
+ object file. NEW is symbol->value. */
+ diff = symbol->value + reloc_entry->addend;
+#else
+ /* In PE mode, we do not offset the common symbol. */
+ diff = reloc_entry->addend;
+#endif
+ }
+ else
+ {
+ /* For some reason bfd_perform_relocation always effectively
+ ignores the addend for a COFF target when producing
+ relocatable output. This seems to be always wrong for 386
+ COFF, so we handle the addend here instead. */
+#if defined(COFF_WITH_PE)
+ if (output_bfd == NULL)
+ {
+ reloc_howto_type *howto = reloc_entry->howto;
+
+ /* Although PC relative relocations are very similar between
+ PE and non-PE formats, but they are off by 1 << howto->size
+ bytes. For the external relocation, PE is very different
+ from others. See md_apply_fix3 () in gas/config/tc-amd64.c.
+ When we link PE and non-PE object files together to
+ generate a non-PE executable, we have to compensate it
+ here. */
+ if(howto->pc_relative && howto->pcrel_offset)
+ diff = -(1 << howto->size);
+ else if(symbol->flags & BSF_WEAK)
+ diff = reloc_entry->addend - symbol->value;
+ else
+ diff = -reloc_entry->addend;
+ }
+ else
+#endif
+ diff = reloc_entry->addend;
+ }
+
+#if defined(COFF_WITH_PE)
+ /* FIXME: How should this case be handled? */
+ if (reloc_entry->howto->type == R_AMD64_IMAGEBASE
+ && output_bfd != NULL
+ && bfd_get_flavour (output_bfd) == bfd_target_coff_flavour)
+ diff -= pe_data (output_bfd)->pe_opthdr.ImageBase;
+#endif
+
+#define DOIT(x) \
+ x = ((x & ~howto->dst_mask) | (((x & howto->src_mask) + diff) & howto->dst_mask))
+
+ if (diff != 0)
+ {
+ reloc_howto_type *howto = reloc_entry->howto;
+ unsigned char *addr = (unsigned char *) data + reloc_entry->address;
+
+ switch (howto->size)
+ {
+ case 0:
+ {
+ char x = bfd_get_8 (abfd, addr);
+ DOIT (x);
+ bfd_put_8 (abfd, x, addr);
+ }
+ break;
+
+ case 1:
+ {
+ short x = bfd_get_16 (abfd, addr);
+ DOIT (x);
+ bfd_put_16 (abfd, (bfd_vma) x, addr);
+ }
+ break;
+
+ case 2:
+ {
+ long x = bfd_get_32 (abfd, addr);
+ DOIT (x);
+ bfd_put_32 (abfd, (bfd_vma) x, addr);
+ }
+ break;
+ case 4:
+ {
+ long long x = bfd_get_64 (abfd, addr);
+ DOIT (x);
+ bfd_put_64 (abfd, (bfd_vma) x, addr);
+ }
+ break;
+
+ default:
+ abort ();
+ }
+ }
+
+ /* Now let bfd_perform_relocation finish everything up. */
+ return bfd_reloc_continue;
+}
+
+#if defined(COFF_WITH_PE)
+/* Return TRUE if this relocation should appear in the output .reloc
+ section. */
+
+static bfd_boolean
+in_reloc_p (bfd *abfd ATTRIBUTE_UNUSED, reloc_howto_type *howto)
+{
+ return ! howto->pc_relative && howto->type != R_AMD64_IMAGEBASE;
+}
+#endif /* COFF_WITH_PE */
+
+#ifndef PCRELOFFSET
+#define PCRELOFFSET TRUE
+#endif
+
+static reloc_howto_type howto_table[] =
+{
+ EMPTY_HOWTO (0),
+ HOWTO (R_AMD64_DIR64, /* type 1*/
+ 0, /* rightshift */
+ 4, /* size (0 = byte, 1 = short, 2 = long, 4 = long long) */
+ 64, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ coff_amd64_reloc, /* special_function */
+ "R_X86_64_64", /* name */
+ TRUE, /* partial_inplace */
+ 0xffffffffffffffffll, /* src_mask */
+ 0xffffffffffffffffll, /* dst_mask */
+ TRUE), /* pcrel_offset */
+ HOWTO (R_AMD64_DIR32, /* type 2 */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ coff_amd64_reloc, /* special_function */
+ "R_X86_64_32", /* name */
+ TRUE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+ /* PE IMAGE_REL_AMD64_ADDR32NB relocation (3). */
+ HOWTO (R_AMD64_IMAGEBASE, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ coff_amd64_reloc, /* special_function */
+ "rva32", /* name */
+ TRUE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ FALSE), /* pcrel_offset */
+ /* 32-bit longword PC relative relocation (4). */
+ HOWTO (R_AMD64_PCRLONG, /* type 4 */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ coff_amd64_reloc, /* special_function */
+ "R_X86_64_PC32", /* name */
+ TRUE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ PCRELOFFSET), /* pcrel_offset */
+
+ HOWTO (R_AMD64_PCRLONG_1, /* type 5 */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ coff_amd64_reloc, /* special_function */
+ "DISP32+1", /* name */
+ TRUE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ PCRELOFFSET), /* pcrel_offset */
+ HOWTO (R_AMD64_PCRLONG_2, /* type 6 */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ coff_amd64_reloc, /* special_function */
+ "DISP32+2", /* name */
+ TRUE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ PCRELOFFSET), /* pcrel_offset */
+ HOWTO (R_AMD64_PCRLONG_3, /* type 7 */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ coff_amd64_reloc, /* special_function */
+ "DISP32+3", /* name */
+ TRUE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ PCRELOFFSET), /* pcrel_offset */
+ HOWTO (R_AMD64_PCRLONG_4, /* type 8 */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ coff_amd64_reloc, /* special_function */
+ "DISP32+4", /* name */
+ TRUE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ PCRELOFFSET), /* pcrel_offset */
+ HOWTO (R_AMD64_PCRLONG_5, /* type 9 */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ coff_amd64_reloc, /* special_function */
+ "DISP32+5", /* name */
+ TRUE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ PCRELOFFSET), /* pcrel_offset */
+ EMPTY_HOWTO (10), /* R_AMD64_SECTION 10 */
+#if defined(COFF_WITH_PE)
+ /* 32-bit longword section relative relocation (11). */
+ HOWTO (R_AMD64_SECREL, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ coff_amd64_reloc, /* special_function */
+ "secrel32", /* name */
+ TRUE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+#else
+ EMPTY_HOWTO (11),
+#endif
+ EMPTY_HOWTO (12),
+ EMPTY_HOWTO (13),
+#ifndef DONT_EXTEND_AMD64
+ HOWTO (R_AMD64_PCRQUAD,
+ 0, /* rightshift */
+ 4, /* size (0 = byte, 1 = short, 2 = long) */
+ 64, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ coff_amd64_reloc, /* special_function */
+ "R_X86_64_PC64", /* name */
+ TRUE, /* partial_inplace */
+ 0xffffffffffffffffll, /* src_mask */
+ 0xffffffffffffffffll, /* dst_mask */
+ PCRELOFFSET), /* pcrel_offset */
+#else
+ EMPTY_HOWTO (14),
+#endif
+ /* Byte relocation (15). */
+ HOWTO (R_RELBYTE, /* type */
+ 0, /* rightshift */
+ 0, /* size (0 = byte, 1 = short, 2 = long) */
+ 8, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ coff_amd64_reloc, /* special_function */
+ "R_X86_64_8", /* name */
+ TRUE, /* partial_inplace */
+ 0x000000ff, /* src_mask */
+ 0x000000ff, /* dst_mask */
+ PCRELOFFSET), /* pcrel_offset */
+ /* 16-bit word relocation (16). */
+ HOWTO (R_RELWORD, /* type */
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ coff_amd64_reloc, /* special_function */
+ "R_X86_64_16", /* name */
+ TRUE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ PCRELOFFSET), /* pcrel_offset */
+ /* 32-bit longword relocation (17). */
+ HOWTO (R_RELLONG, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ coff_amd64_reloc, /* special_function */
+ "R_X86_64_32S", /* name */
+ TRUE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ PCRELOFFSET), /* pcrel_offset */
+ /* Byte PC relative relocation (18). */
+ HOWTO (R_PCRBYTE, /* type */
+ 0, /* rightshift */
+ 0, /* size (0 = byte, 1 = short, 2 = long) */
+ 8, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ coff_amd64_reloc, /* special_function */
+ "R_X86_64_PC8", /* name */
+ TRUE, /* partial_inplace */
+ 0x000000ff, /* src_mask */
+ 0x000000ff, /* dst_mask */
+ PCRELOFFSET), /* pcrel_offset */
+ /* 16-bit word PC relative relocation (19). */
+ HOWTO (R_PCRWORD, /* type */
+ 0, /* rightshift */
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
+ 16, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ coff_amd64_reloc, /* special_function */
+ "R_X86_64_PC16", /* name */
+ TRUE, /* partial_inplace */
+ 0x0000ffff, /* src_mask */
+ 0x0000ffff, /* dst_mask */
+ PCRELOFFSET), /* pcrel_offset */
+ /* 32-bit longword PC relative relocation (20). */
+ HOWTO (R_PCRLONG, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ TRUE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_signed, /* complain_on_overflow */
+ coff_amd64_reloc, /* special_function */
+ "R_X86_64_PC32", /* name */
+ TRUE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ PCRELOFFSET) /* pcrel_offset */
+};
+
+/* Turn a howto into a reloc nunmber */
+
+#define SELECT_RELOC(x,howto) { x.r_type = howto->type; }
+#define I386 1 /* Customize coffcode.h */
+#define AMD64 1
+
+#define RTYPE2HOWTO(cache_ptr, dst) \
+ ((cache_ptr)->howto = \
+ ((dst)->r_type < ARRAY_SIZE (howto_table)) \
+ ? howto_table + (dst)->r_type \
+ : NULL)
+
+/* For 386 COFF a STYP_NOLOAD | STYP_BSS section is part of a shared
+ library. On some other COFF targets STYP_BSS is normally
+ STYP_NOLOAD. */
+#define BSS_NOLOAD_IS_SHARED_LIBRARY
+
+/* Compute the addend of a reloc. If the reloc is to a common symbol,
+ the object file contains the value of the common symbol. By the
+ time this is called, the linker may be using a different symbol
+ from a different object file with a different value. Therefore, we
+ hack wildly to locate the original symbol from this file so that we
+ can make the correct adjustment. This macro sets coffsym to the
+ symbol from the original file, and uses it to set the addend value
+ correctly. If this is not a common symbol, the usual addend
+ calculation is done, except that an additional tweak is needed for
+ PC relative relocs.
+ FIXME: This macro refers to symbols and asect; these are from the
+ calling function, not the macro arguments. */
+
+#define CALC_ADDEND(abfd, ptr, reloc, cache_ptr) \
+ { \
+ coff_symbol_type *coffsym = NULL; \
+ \
+ if (ptr && bfd_asymbol_bfd (ptr) != abfd) \
+ coffsym = (obj_symbols (abfd) \
+ + (cache_ptr->sym_ptr_ptr - symbols)); \
+ else if (ptr) \
+ coffsym = coff_symbol_from (abfd, ptr); \
+ \
+ if (coffsym != NULL \
+ && coffsym->native->u.syment.n_scnum == 0) \
+ cache_ptr->addend = - coffsym->native->u.syment.n_value; \
+ else if (ptr && bfd_asymbol_bfd (ptr) == abfd \
+ && ptr->section != NULL) \
+ cache_ptr->addend = - (ptr->section->vma + ptr->value); \
+ else \
+ cache_ptr->addend = 0; \
+ if (ptr && howto_table[reloc.r_type].pc_relative) \
+ cache_ptr->addend += asect->vma; \
+ }
+
+/* We use the special COFF backend linker. For normal AMD64 COFF, we
+ can use the generic relocate_section routine. For PE, we need our
+ own routine. */
+
+#if !defined(COFF_WITH_PE)
+
+#define coff_relocate_section _bfd_coff_generic_relocate_section
+
+#else /* COFF_WITH_PE */
+
+/* The PE relocate section routine. The only difference between this
+ and the regular routine is that we don't want to do anything for a
+ relocatable link. */
+
+static bfd_boolean
+coff_pe_amd64_relocate_section (bfd *output_bfd,
+ struct bfd_link_info *info,
+ bfd *input_bfd,
+ asection *input_section,
+ bfd_byte *contents,
+ struct internal_reloc *relocs,
+ struct internal_syment *syms,
+ asection **sections)
+{
+ if (info->relocatable)
+ return TRUE;
+
+ return _bfd_coff_generic_relocate_section (output_bfd, info, input_bfd,input_section, contents,relocs, syms, sections);
+}
+
+#define coff_relocate_section coff_pe_amd64_relocate_section
+
+#endif /* COFF_WITH_PE */
+
+/* Convert an rtype to howto for the COFF backend linker. */
+
+static reloc_howto_type *
+coff_amd64_rtype_to_howto (bfd *abfd ATTRIBUTE_UNUSED,
+ asection *sec,
+ struct internal_reloc *rel,
+ struct coff_link_hash_entry *h,
+ struct internal_syment *sym,
+ bfd_vma *addendp)
+{
+ reloc_howto_type *howto;
+
+ if (rel->r_type > ARRAY_SIZE (howto_table))
+ {
+ bfd_set_error (bfd_error_bad_value);
+ return NULL;
+ }
+ if (rel->r_type >= R_AMD64_PCRLONG_1 && rel->r_type <= R_AMD64_PCRLONG_5)
+ {
+ rel->r_vaddr += (bfd_vma)(rel->r_type-R_AMD64_PCRLONG);
+ rel->r_type = R_AMD64_PCRLONG;
+ }
+ howto = howto_table + rel->r_type;
+
+#if defined(COFF_WITH_PE)
+ /* Cancel out code in _bfd_coff_generic_relocate_section. */
+ *addendp = 0;
+#endif
+
+ if (howto->pc_relative)
+ *addendp += sec->vma;
+
+ if (sym != NULL && sym->n_scnum == 0 && sym->n_value != 0)
+ {
+ /* This is a common symbol. The section contents include the
+ size (sym->n_value) as an addend. The relocate_section
+ function will be adding in the final value of the symbol. We
+ need to subtract out the current size in order to get the
+ correct result. */
+ BFD_ASSERT (h != NULL);
+
+#if !defined(COFF_WITH_PE)
+ /* I think we *do* want to bypass this. If we don't, I have
+ seen some data parameters get the wrong relocation address.
+ If I link two versions with and without this section bypassed
+ and then do a binary comparison, the addresses which are
+ different can be looked up in the map. The case in which
+ this section has been bypassed has addresses which correspond
+ to values I can find in the map. */
+ *addendp -= sym->n_value;
+#endif
+ }
+
+#if !defined(COFF_WITH_PE)
+ /* If the output symbol is common (in which case this must be a
+ relocatable link), we need to add in the final size of the
+ common symbol. */
+ if (h != NULL && h->root.type == bfd_link_hash_common)
+ *addendp += h->root.u.c.size;
+#endif
+
+#if defined(COFF_WITH_PE)
+ if (howto->pc_relative)
+ {
+ *addendp -= 4;
+
+ /* If the symbol is defined, then the generic code is going to
+ add back the symbol value in order to cancel out an
+ adjustment it made to the addend. However, we set the addend
+ to 0 at the start of this function. We need to adjust here,
+ to avoid the adjustment the generic code will make. FIXME:
+ This is getting a bit hackish. */
+ if (sym != NULL && sym->n_scnum != 0)
+ *addendp -= sym->n_value;
+ }
+
+ if (rel->r_type == R_AMD64_IMAGEBASE
+ && (bfd_get_flavour (sec->output_section->owner) == bfd_target_coff_flavour))
+ *addendp -= pe_data (sec->output_section->owner)->pe_opthdr.ImageBase;
+
+ if (rel->r_type == R_AMD64_SECREL)
+ {
+ bfd_vma osect_vma;
+
+ if (h && (h->type == bfd_link_hash_defined || h->type == bfd_link_hash_defweak))
+ osect_vma = h->root.u.def.section->output_section->vma;
+ else
+ {
+ asection *sec;
+ int i;
+
+ /* Sigh, the only way to get the section to offset against
+ is to find it the hard way. */
+ for (sec = abfd->sections, i = 1; i < sym->n_scnum; i++)
+ sec = sec->next;
+
+ osect_vma = sec->output_section->vma;
+ }
+
+ *addendp -= osect_vma;
+ }
+#endif
+
+ return howto;
+}
+
+#define coff_bfd_reloc_type_lookup coff_amd64_reloc_type_lookup
+
+static reloc_howto_type *
+coff_amd64_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED, bfd_reloc_code_real_type code)
+{
+ switch (code)
+ {
+ case BFD_RELOC_RVA:
+ return howto_table + R_AMD64_IMAGEBASE;
+ case BFD_RELOC_32:
+ return howto_table + R_AMD64_DIR32;
+ case BFD_RELOC_64:
+ return howto_table + R_AMD64_DIR64;
+ case BFD_RELOC_64_PCREL:
+#ifndef DONT_EXTEND_AMD64
+ return howto_table + R_AMD64_PCRQUAD;
+#else
+ /* Fall through. */
+#endif
+ case BFD_RELOC_32_PCREL:
+ return howto_table + R_AMD64_PCRLONG;
+ case BFD_RELOC_X86_64_32S:
+ return howto_table + R_RELLONG;
+ case BFD_RELOC_16:
+ return howto_table + R_RELWORD;
+ case BFD_RELOC_16_PCREL:
+ return howto_table + R_PCRWORD;
+ case BFD_RELOC_8:
+ return howto_table + R_RELBYTE;
+ case BFD_RELOC_8_PCREL:
+ return howto_table + R_PCRBYTE;
+#if defined(COFF_WITH_PE)
+ case BFD_RELOC_32_SECREL:
+ return howto_table + R_AMD64_SECREL;
+#endif
+ default:
+ BFD_FAIL ();
+ return 0;
+ }
+}
+
+#define coff_rtype_to_howto coff_amd64_rtype_to_howto
+
+#ifdef TARGET_UNDERSCORE
+
+/* If amd64 gcc uses underscores for symbol names, then it does not use
+ a leading dot for local labels, so if TARGET_UNDERSCORE is defined
+ we treat all symbols starting with L as local. */
+
+static bfd_boolean
+coff_amd64_is_local_label_name (bfd *abfd, const char *name)
+{
+ if (name[0] == 'L')
+ return TRUE;
+
+ return _bfd_coff_is_local_label_name (abfd, name);
+}
+
+#define coff_bfd_is_local_label_name coff_amd64_is_local_label_name
+
+#endif /* TARGET_UNDERSCORE */
+
+#include "coffcode.h"
+
+#ifdef PE
+#define amd64coff_object_p pe_bfd_object_p
+#else
+#define amd64coff_object_p coff_object_p
+#endif
+
+const bfd_target
+#ifdef TARGET_SYM
+ TARGET_SYM =
+#else
+ x86_64coff_vec =
+#endif
+{
+#ifdef TARGET_NAME
+ TARGET_NAME,
+#else
+ "coff-x86-64", /* Name. */
+#endif
+ bfd_target_coff_flavour,
+ BFD_ENDIAN_LITTLE, /* Data byte order is little. */
+ BFD_ENDIAN_LITTLE, /* Header byte order is little. */
+
+ (HAS_RELOC | EXEC_P | /* Object flags. */
+ HAS_LINENO | HAS_DEBUG |
+ HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
+
+ (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC /* Section flags. */
+#if defined(COFF_WITH_PE)
+ | SEC_LINK_ONCE | SEC_LINK_DUPLICATES | SEC_READONLY
+#endif
+ | SEC_CODE | SEC_DATA),
+
+#ifdef TARGET_UNDERSCORE
+ TARGET_UNDERSCORE, /* Leading underscore. */
+#else
+ 0, /* Leading underscore. */
+#endif
+ '/', /* Ar_pad_char. */
+ 15, /* Ar_max_namelen. */
+
+ bfd_getl64, bfd_getl_signed_64, bfd_putl64,
+ bfd_getl32, bfd_getl_signed_32, bfd_putl32,
+ bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* Data. */
+ bfd_getl64, bfd_getl_signed_64, bfd_putl64,
+ bfd_getl32, bfd_getl_signed_32, bfd_putl32,
+ bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* Hdrs. */
+
+ /* Note that we allow an object file to be treated as a core file as well. */
+ { _bfd_dummy_target, amd64coff_object_p, /* BFD_check_format. */
+ bfd_generic_archive_p, amd64coff_object_p },
+ { bfd_false, coff_mkobject, _bfd_generic_mkarchive, /* bfd_set_format. */
+ bfd_false },
+ { bfd_false, coff_write_object_contents, /* bfd_write_contents. */
+ _bfd_write_archive_contents, bfd_false },
+
+ BFD_JUMP_TABLE_GENERIC (coff),
+ BFD_JUMP_TABLE_COPY (coff),
+ BFD_JUMP_TABLE_CORE (_bfd_nocore),
+ BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff),
+ BFD_JUMP_TABLE_SYMBOLS (coff),
+ BFD_JUMP_TABLE_RELOCS (coff),
+ BFD_JUMP_TABLE_WRITE (coff),
+ BFD_JUMP_TABLE_LINK (coff),
+ BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
+
+ NULL,
+
+ COFF_SWAP_TABLE
+};
#ifdef I386MAGIC
case I386MAGIC:
case I386PTXMAGIC:
- case I386AIXMAGIC: /* Danbury PS/2 AIX C Compiler */
- case LYNXCOFFMAGIC: /* shadows the m68k Lynx number below, sigh */
+ case I386AIXMAGIC: /* Danbury PS/2 AIX C Compiler. */
+ case LYNXCOFFMAGIC: /* Shadows the m68k Lynx number below, sigh. */
arch = bfd_arch_i386;
break;
#endif
+#ifdef AMD64MAGIC
+ case AMD64MAGIC:
+ arch = bfd_arch_i386;
+ machine = bfd_mach_x86_64;
+ break;
+#endif
#ifdef IA64MAGIC
case IA64MAGIC:
arch = bfd_arch_ia64;
return TRUE;
#endif
-#ifdef I386MAGIC
+#if defined(I386MAGIC) || defined(AMD64MAGIC)
case bfd_arch_i386:
+#if defined(I386MAGIC)
*magicp = I386MAGIC;
-#ifdef LYNXOS
+#endif
+#if defined LYNXOS
/* Just overwrite the usual value if we're doing Lynx. */
*magicp = LYNXCOFFMAGIC;
+#endif
+#if defined AMD64MAGIC
+ *magicp = AMD64MAGIC;
#endif
return TRUE;
#endif
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
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,
#if defined(I386)
#define __A_MAGIC_SET__
-#if defined(LYNXOS)
+#if defined LYNXOS
internal_a.magic = LYNXCOFFMAGIC;
-#else /* LYNXOS */
+#elif defined AMD64
+ internal_a.magic = IMAGE_NT_OPTIONAL_HDR64_MAGIC;
+#else
internal_a.magic = ZMAGIC;
-#endif /* LYNXOS */
+#endif
#endif /* I386 */
#if defined(IA64)
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 ;;
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
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
case "`/usr/bin/file conftest.o`" in
*32-bit*)
case $host in
- x86_64-*linux*)
+ x86_64-*linux*|x86_64-*mingw64*)
LD="${LD-ld} -m elf_i386"
;;
ppc64-*linux*|powerpc64-*linux*)
;;
*64-bit*)
case $host in
- x86_64-*linux*)
+ x86_64-*linux*|x86_64-*mingw64*)
LD="${LD-ld} -m elf_x86_64"
;;
ppc*-*linux*|powerpc*-*linux*)
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" ;;
i386os9k_vec) tb="$tb i386os9k.lo aout32.lo" ;;
i386pe_vec) tb="$tb pe-i386.lo peigen.lo cofflink.lo" ;;
i386pei_vec) tb="$tb pei-i386.lo peigen.lo cofflink.lo" ;;
+ x86_64pe_vec) tb="$tb pe-x86_64.lo pex64igen.lo cofflink.lo"; target_size=64 ;;
+ x86_64pei_vec) tb="$tb pei-x86_64.lo pex64igen.lo cofflink.lo"; target_size=64 ;;
i860coff_vec) tb="$tb coff-i860.lo cofflink.lo" ;;
icoff_big_vec) tb="$tb coff-i960.lo cofflink.lo" ;;
icoff_little_vec) tb="$tb coff-i960.lo cofflink.lo" ;;
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" ;;
i386os9k_vec) tb="$tb i386os9k.lo aout32.lo" ;;
i386pe_vec) tb="$tb pe-i386.lo peigen.lo cofflink.lo" ;;
i386pei_vec) tb="$tb pei-i386.lo peigen.lo cofflink.lo" ;;
+ x86_64pe_vec) tb="$tb pe-x86_64.lo pex64igen.lo cofflink.lo"; target_size=64 ;;
+ x86_64pei_vec) tb="$tb pei-x86_64.lo pex64igen.lo cofflink.lo"; target_size=64 ;;
i860coff_vec) tb="$tb coff-i860.lo cofflink.lo" ;;
icoff_big_vec) tb="$tb coff-i960.lo cofflink.lo" ;;
icoff_little_vec) tb="$tb coff-i960.lo cofflink.lo" ;;
#define PUT_SCNHDR_LNNOPTR H_PUT_32
#endif
-#ifdef COFF_WITH_pep
+#ifdef COFF_WITH_pex64
+
+#define GET_OPTHDR_IMAGE_BASE H_GET_64
+#define PUT_OPTHDR_IMAGE_BASE H_PUT_64
+#define GET_OPTHDR_SIZE_OF_STACK_RESERVE H_GET_64
+#define PUT_OPTHDR_SIZE_OF_STACK_RESERVE H_PUT_64
+#define GET_OPTHDR_SIZE_OF_STACK_COMMIT H_GET_64
+#define PUT_OPTHDR_SIZE_OF_STACK_COMMIT H_PUT_64
+#define GET_OPTHDR_SIZE_OF_HEAP_RESERVE H_GET_64
+#define PUT_OPTHDR_SIZE_OF_HEAP_RESERVE H_PUT_64
+#define GET_OPTHDR_SIZE_OF_HEAP_COMMIT H_GET_64
+#define PUT_OPTHDR_SIZE_OF_HEAP_COMMIT H_PUT_64
+#define GET_PDATA_ENTRY bfd_get_32
+
+#define _bfd_XX_bfd_copy_private_bfd_data_common _bfd_pex64_bfd_copy_private_bfd_data_common
+#define _bfd_XX_bfd_copy_private_section_data _bfd_pex64_bfd_copy_private_section_data
+#define _bfd_XX_get_symbol_info _bfd_pex64_get_symbol_info
+#define _bfd_XX_only_swap_filehdr_out _bfd_pex64_only_swap_filehdr_out
+#define _bfd_XX_print_private_bfd_data_common _bfd_pex64_print_private_bfd_data_common
+#define _bfd_XXi_final_link_postscript _bfd_pex64i_final_link_postscript
+#define _bfd_XXi_final_link_postscript _bfd_pex64i_final_link_postscript
+#define _bfd_XXi_only_swap_filehdr_out _bfd_pex64i_only_swap_filehdr_out
+#define _bfd_XXi_swap_aouthdr_in _bfd_pex64i_swap_aouthdr_in
+#define _bfd_XXi_swap_aouthdr_out _bfd_pex64i_swap_aouthdr_out
+#define _bfd_XXi_swap_aux_in _bfd_pex64i_swap_aux_in
+#define _bfd_XXi_swap_aux_out _bfd_pex64i_swap_aux_out
+#define _bfd_XXi_swap_lineno_in _bfd_pex64i_swap_lineno_in
+#define _bfd_XXi_swap_lineno_out _bfd_pex64i_swap_lineno_out
+#define _bfd_XXi_swap_scnhdr_out _bfd_pex64i_swap_scnhdr_out
+#define _bfd_XXi_swap_sym_in _bfd_pex64i_swap_sym_in
+#define _bfd_XXi_swap_sym_out _bfd_pex64i_swap_sym_out
+
+#elif defined COFF_WITH_pep
#define GET_OPTHDR_IMAGE_BASE H_GET_64
#define PUT_OPTHDR_IMAGE_BASE H_PUT_64
--- /dev/null
+/* BFD back-end for Intel/AMD x86_64 PECOFF files.
+ Copyright 2006 Free Software Foundation, Inc.
+
+ This file is part of BFD, the Binary File Descriptor library.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
+
+ Written by Kai Tietz, OneVision Software GmbH&CoKg. */
+
+#include "bfd.h"
+#include "sysdep.h"
+
+#define TARGET_SYM x86_64pe_vec
+#define TARGET_NAME "pe-x86-64"
+#define COFF_WITH_PE
+#define COFF_WITH_pex64
+#define PCRELOFFSET TRUE
+#define TARGET_UNDERSCORE '_'
+#define COFF_LONG_SECTION_NAMES
+#define COFF_SUPPORT_GNU_LINKONCE
+#define COFF_LONG_FILENAMES
+
+#define COFF_SECTION_ALIGNMENT_ENTRIES \
+{ COFF_SECTION_NAME_EXACT_MATCH (".bss"), \
+ COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 4 }, \
+{ COFF_SECTION_NAME_EXACT_MATCH (".data"), \
+ COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 4 }, \
+{ COFF_SECTION_NAME_EXACT_MATCH (".rdata"), \
+ COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 4 }, \
+{ COFF_SECTION_NAME_EXACT_MATCH (".text"), \
+ COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 4 }, \
+{ COFF_SECTION_NAME_PARTIAL_MATCH (".idata"), \
+ COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 2 }, \
+{ COFF_SECTION_NAME_EXACT_MATCH (".pdata"), \
+ COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 2 }, \
+{ COFF_SECTION_NAME_PARTIAL_MATCH (".debug"), \
+ COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 0 }, \
+{ COFF_SECTION_NAME_PARTIAL_MATCH (".gnu.linkonce.wi."), \
+ COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 0 }
+
+#include "coff-x86_64.c"
on this code has a chance of getting something accomplished without
wasting too much time. */
-/* This expands into COFF_WITH_pe or COFF_WITH_pep depending on whether
- we're compiling for straight PE or PE+. */
+/* This expands into COFF_WITH_pe, COFF_WITH_pep, or COFF_WITH_pex64
+ depending on whether we're compiling for straight PE or PE+. */
#define COFF_WITH_XX
#include "bfd.h"
within PE/PEI, so we get them from there. FIXME: The lack of
variance is an assumption which may prove to be incorrect if new
PE/PEI targets are created. */
-#ifdef COFF_WITH_pep
+#if defined COFF_WITH_pex64
+# include "coff/x86_64.h"
+#elif defined COFF_WITH_pep
# include "coff/ia64.h"
#else
# include "coff/i386.h"
#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
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);
/* If data directory is empty, rva also should be 0. */
int size =
H_GET_32 (abfd, src->DataDirectory[idx][1]);
+
a->DataDirectory[idx].Size = size;
if (size)
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
}
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)
{
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
}
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
}
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
}
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);
}
/* 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);
fprintf (file, "\n");
}
-
+#endif
if (ft_allocated)
free (ft_data);
}
static bfd_boolean
pe_print_pdata (bfd * abfd, void * vfile)
{
-#ifdef COFF_WITH_pep
-# define PDATA_ROW_SIZE (3*8)
+#if defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64)
+# define PDATA_ROW_SIZE (3 * 8)
#else
-# define PDATA_ROW_SIZE (5*4)
+# define PDATA_ROW_SIZE (5 * 4)
#endif
FILE *file = (FILE *) vfile;
bfd_byte *data = 0;
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
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);
--- /dev/null
+/* BFD back-end for Intel 386 PE IMAGE COFF files.
+ Copyright 2006 Free Software Foundation, Inc.
+
+ This file is part of BFD, the Binary File Descriptor library.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
+
+ Written by Kai Tietz, OneVision Software GmbH&CoKg. */
+
+#include "bfd.h"
+#include "sysdep.h"
+
+#define TARGET_SYM x86_64pei_vec
+#define TARGET_NAME "pei-x86-64"
+#define COFF_IMAGE_WITH_PE
+#define COFF_WITH_PE
+#define COFF_WITH_pex64
+#define PCRELOFFSET TRUE
+#define TARGET_UNDERSCORE '_'
+#define COFF_LONG_SECTION_NAMES
+#define COFF_SUPPORT_GNU_LINKONCE
+#define COFF_LONG_FILENAMES
+
+#define COFF_SECTION_ALIGNMENT_ENTRIES \
+{ COFF_SECTION_NAME_EXACT_MATCH (".bss"), \
+ COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 4 }, \
+{ COFF_SECTION_NAME_EXACT_MATCH (".data"), \
+ COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 4 }, \
+{ COFF_SECTION_NAME_EXACT_MATCH (".rdata"), \
+ COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 4 }, \
+{ COFF_SECTION_NAME_EXACT_MATCH (".text"), \
+ COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 4 }, \
+{ COFF_SECTION_NAME_PARTIAL_MATCH (".idata"), \
+ COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 2 }, \
+{ COFF_SECTION_NAME_EXACT_MATCH (".pdata"), \
+ COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 2 }, \
+{ COFF_SECTION_NAME_PARTIAL_MATCH (".debug"), \
+ COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 0 }, \
+{ COFF_SECTION_NAME_PARTIAL_MATCH (".gnu.linkonce.wi."), \
+ COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 0 }
+
+#include "coff-x86_64.c"
/* Support for the generic parts of PE/PEI, for BFD.
Copyright 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
- 2005 Free Software Foundation, Inc.
+ 2005, 2006 Free Software Foundation, Inc.
Written by Cygnus Solutions.
This file is part of BFD, the Binary File Descriptor library.
#ifdef COFF_IMAGE_WITH_PE
# define coff_swap_filehdr_out _bfd_XXi_only_swap_filehdr_out
+#elif defined COFF_WITH_pex64
+# define coff_swap_filehdr_out _bfd_pex64_only_swap_filehdr_out
+#elif defined COFF_WITH_pep
+# define coff_swap_filehdr_out _bfd_pep_only_swap_filehdr_out
#else
# define coff_swap_filehdr_out _bfd_pe_only_swap_filehdr_out
#endif
if (scnhdr_int->s_vaddr != 0)
{
scnhdr_int->s_vaddr += pe_data (abfd)->pe_opthdr.ImageBase;
+ /* Do not cut upper 32-bits for 64-bit vma. */
+#ifndef COFF_WITH_pex64
scnhdr_int->s_vaddr &= 0xffffffff;
+#endif
}
#ifndef COFF_NO_HACK_SCNHDR_SIZE
+ NUM_ILF_SECTIONS * 9 \
+ STRING_SIZE_SIZE)
#define SIZEOF_IDATA2 (5 * 4)
+
+/* For PEx64 idata4 & 5 have thumb size of 8 bytes. */
+#ifdef COFF_WITH_pex64
+#define SIZEOF_IDATA4 (2 * 4)
+#define SIZEOF_IDATA5 (2 * 4)
+#else
#define SIZEOF_IDATA4 (1 * 4)
#define SIZEOF_IDATA5 (1 * 4)
+#endif
+
#define SIZEOF_IDATA6 (2 + strlen (symbol_name) + 1 + 1)
#define SIZEOF_IDATA7 (strlen (source_dll) + 1 + 1)
#define SIZEOF_ILF_SECTIONS (NUM_ILF_SECTIONS * sizeof (struct coff_section_tdata))
},
#endif
+#ifdef AMD64MAGIC
+ { AMD64MAGIC,
+ { 0xff, 0x25, 0x00, 0x00, 0x00, 0x00, 0x90, 0x90 },
+ 8, 2
+ },
+#endif
+
#ifdef MC68MAGIC
- { MC68MAGIC, { /* XXX fill me in */ }, 0, 0 },
+ { MC68MAGIC,
+ { /* XXX fill me in */ },
+ 0, 0
+ },
#endif
+
#ifdef MIPS_ARCH_MAGIC_WINCE
{ MIPS_ARCH_MAGIC_WINCE,
{ 0x00, 0x00, 0x08, 0x3c, 0x00, 0x00, 0x08, 0x8d,
/* XXX - treat as IMPORT_NAME ??? */
abort ();
+#ifdef COFF_WITH_pex64
+ ((unsigned int *) id4->contents)[0] = ordinal;
+ ((unsigned int *) id4->contents)[1] = 0x80000000;
+ ((unsigned int *) id5->contents)[0] = ordinal;
+ ((unsigned int *) id5->contents)[1] = 0x80000000;
+#else
* (unsigned int *) id4->contents = ordinal | 0x80000000;
* (unsigned int *) id5->contents = ordinal | 0x80000000;
+#endif
}
else
{
#endif
break;
+ case IMAGE_FILE_MACHINE_AMD64:
+#ifdef AMD64MAGIC
+ magic = AMD64MAGIC;
+#endif
+ break;
+
case IMAGE_FILE_MACHINE_M68K:
#ifdef MC68AGIC
magic = MC68MAGIC;
extern const bfd_target vms_vax_vec;
extern const bfd_target w65_vec;
extern const bfd_target we32kcoff_vec;
+extern const bfd_target x86_64pe_vec;
+extern const bfd_target x86_64pei_vec;
+extern const bfd_target x86_64coff_vec;
extern const bfd_target z80coff_vec;
extern const bfd_target z8kcoff_vec;
extern const bfd_target trad_core_vec;
extern const bfd_target bfd_elf32_am33lin_vec;
-static const bfd_target * const _bfd_target_vector[] = {
-
+static const bfd_target * const _bfd_target_vector[] =
+{
#ifdef SELECT_VECS
SELECT_VECS,
&i386os9k_vec,
&i386pe_vec,
&i386pei_vec,
+#ifdef BFD64
+ &x86_64coff_vec,
+ &x86_64pe_vec,
+ &x86_64pei_vec,
+#endif
&i860coff_vec,
&icoff_big_vec,
&icoff_little_vec,
+2006-09-20 Kai Tietz <Kai.Tietz@onevision.com>
+
+ * configure.in: Add new target x86_64-pc-mingw64.
+ * configure: Regenerate.
+ * dlltool.c: Adjust include for this target.
+ (DLLTOOL_MX86_64): Added macro to handle target specific code.
+ (mname): Added default target static as "i386:x86-64".
+ (MX86): Added macro for target ident.
+ (mtable): Added target specific definitions.
+ (rvaafter): Add handling of MX86.
+ (rvabefore): Add handling of MX86.
+ (asmprefix): Add handling of MX86.
+
2006-09-17 Mei Ligang <ligang@sunnorth.com.cn>
* readelf.c: Add support for Score binaries.
DLLTOOL_DEFS="$DLLTOOL_DEFS -DDLLTOOL_ARM"
BUILD_WINDRES='$(WINDRES_PROG)$(EXEEXT)'
;;
+ x86_64-*-mingw64*)
+ BUILD_DLLTOOL='$(DLLTOOL_PROG)$(EXEEXT)'
+ DLLTOOL_DEFS="$DLLTOOL_DEFS -DDLLTOOL_MX86_64"
+ BUILD_WINDRES='$(WINDRES_PROG)$(EXEEXT)'
+ BUILD_DLLWRAP='$(DLLWRAP_PROG)$(EXEEXT)'
+ ;;
i[3-7]86-*-pe* | i[3-7]86-*-cygwin* | i[3-7]86-*-mingw32** | i[3-7]86-*-netbsdpe*)
BUILD_DLLTOOL='$(DLLTOOL_PROG)$(EXEEXT)'
DLLTOOL_DEFS="$DLLTOOL_DEFS -DDLLTOOL_I386"
DLLTOOL_DEFS="$DLLTOOL_DEFS -DDLLTOOL_ARM"
BUILD_WINDRES='$(WINDRES_PROG)$(EXEEXT)'
;;
+ x86_64-*-mingw64*)
+changequote([,])dnl
+ BUILD_DLLTOOL='$(DLLTOOL_PROG)$(EXEEXT)'
+ DLLTOOL_DEFS="$DLLTOOL_DEFS -DDLLTOOL_MX86_64"
+ BUILD_WINDRES='$(WINDRES_PROG)$(EXEEXT)'
+ BUILD_DLLWRAP='$(DLLWRAP_PROG)$(EXEEXT)'
+ ;;
+changequote(,)dnl
changequote(,)dnl
i[3-7]86-*-pe* | i[3-7]86-*-cygwin* | i[3-7]86-*-mingw32** | i[3-7]86-*-netbsdpe*)
changequote([,])dnl
#include "coff/arm.h"
#include "coff/internal.h"
#endif
+#ifdef DLLTOOL_MX86_64
+#include "coff/x86_64.h"
+#endif
/* Forward references. */
static char *look_for_prog (const char *, const char *, int);
static const char *mname = "i386";
#endif
+#ifdef DLLTOOL_MX86_64
+static const char *mname = "i386:x86-64";
+#endif
+
#ifdef DLLTOOL_PPC
static const char *mname = "ppc";
#endif
arm_jtab, sizeof (arm_jtab), 8
}
,
+ {
+#define MX86 11
+ "i386:x86-64", ".byte", ".short", ".long", ".asciz", "#",
+ "jmp *", ".global", ".space", ".align\t2",".align\t4", "",
+ "pe-x86-64",bfd_arch_i386,
+ i386_jtab, sizeof (i386_jtab), 2
+ }
+ ,
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
};
{
case MARM:
case M386:
+ case MX86:
case MPPC:
case MTHUMB:
case MARM_INTERWORK:
{
case MARM:
case M386:
+ case MX86:
case MPPC:
case MTHUMB:
case MARM_INTERWORK:
case MARM_WINCE:
break;
case M386:
+ case MX86:
/* Symbol names starting with ? do not have a leading underscore. */
if (name && *name == '?')
break;
for (headptr = import_list; headptr != NULL; headptr = headptr->next)
{
fprintf (filvar, "listone%d:\n", headindex);
- for ( funcindex = 0; funcindex < headptr->nfuncs; funcindex++ )
+ for (funcindex = 0; funcindex < headptr->nfuncs; funcindex++)
+#ifdef DLLTOOL_MX86_64
+ fprintf (filvar, "\t%sfuncptr%d_%d%s\n%s\t0\n",
+ ASM_RVA_BEFORE, headindex, funcindex, ASM_RVA_AFTER,ASM_LONG);
+#else
fprintf (filvar, "\t%sfuncptr%d_%d%s\n",
ASM_RVA_BEFORE, headindex, funcindex, ASM_RVA_AFTER);
- fprintf (filvar,"\t%s\t0\n", ASM_LONG); /* NULL terminating list */
+#endif
+#ifdef DLLTOOL_MX86_64
+ fprintf (filvar, "\t%s\t0\n\t%s\t0\n", ASM_LONG, ASM_LONG); /* NULL terminating list. */
+#else
+ fprintf (filvar, "\t%s\t0\n", ASM_LONG); /* NULL terminating list. */
+#endif
headindex++;
}
for (headptr = import_list; headptr != NULL; headptr = headptr->next)
{
fprintf (filvar, "listtwo%d:\n", headindex);
- for ( funcindex = 0; funcindex < headptr->nfuncs; funcindex++ )
+ for (funcindex = 0; funcindex < headptr->nfuncs; funcindex++)
+#ifdef DLLTOOL_MX86_64
+ fprintf (filvar, "\t%sfuncptr%d_%d%s\n%s\t0\n",
+ ASM_RVA_BEFORE, headindex, funcindex, ASM_RVA_AFTER,ASM_LONG);
+#else
fprintf (filvar, "\t%sfuncptr%d_%d%s\n",
ASM_RVA_BEFORE, headindex, funcindex, ASM_RVA_AFTER);
- fprintf (filvar, "\t%s\t0\n", ASM_LONG); /* NULL terminating list */
+#endif
+#ifdef DLLTOOL_MX86_64
+ fprintf (filvar, "\t%s\t0\n\t%s\t0\n", ASM_LONG, ASM_LONG); /* NULL terminating list. */
+#else
+ fprintf (filvar, "\t%s\t0\n", ASM_LONG); /* NULL terminating list. */
+#endif
headindex++;
}
si->data = xmalloc (HOW_JTAB_SIZE);
memcpy (si->data, HOW_JTAB, HOW_JTAB_SIZE);
- /* add the reloc into idata$5 */
+ /* Add the reloc into idata$5. */
rel = xmalloc (sizeof (arelent));
rpp = xmalloc (sizeof (arelent *) * 2);
/* An idata$4 or idata$5 is one word long, and has an
rva to idata$6. */
+#ifdef DLLTOOL_MX86_64
+ si->data = xmalloc (8);
+ si->size = 8;
+
+ if (exp->noname)
+ {
+ si->data[0] = exp->ordinal ;
+ si->data[1] = exp->ordinal >> 8;
+ si->data[2] = exp->ordinal >> 16;
+ si->data[3] = exp->ordinal >> 24;
+ si->data[4] = 0;
+ si->data[5] = 0;
+ si->data[6] = 0;
+ si->data[7] = 0x80;
+ }
+ else
+ {
+ sec->reloc_count = 1;
+ memset (si->data, 0, si->size);
+ rel = xmalloc (sizeof (arelent));
+ rpp = xmalloc (sizeof (arelent *) * 2);
+ rpp[0] = rel;
+ rpp[1] = 0;
+ rel->address = 0;
+ rel->addend = 0;
+ rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_RVA);
+ rel->sym_ptr_ptr = secdata[IDATA6].sympp;
+ sec->orelocation = rpp;
+ }
+#else
si->data = xmalloc (4);
si->size = 4;
rel->sym_ptr_ptr = secdata[IDATA6].sympp;
sec->orelocation = rpp;
}
-
+#endif
break;
case IDATA6:
if (!no_idata5)
{
fprintf (f, "\t.section\t.idata$5\n");
- fprintf (f, "\t%s\t0\n", ASM_LONG);
+#ifdef DLLTOOL_MX86_64
+ fprintf (f,"\t%s\t0\n\t%s\t0\n", ASM_LONG, ASM_LONG); /* NULL terminating list. */
+#else
+ fprintf (f,"\t%s\t0\n", ASM_LONG); /* NULL terminating list. */
+#endif
fprintf (f, "fthunk:\n");
}
if (!no_idata4)
{
fprintf (f, "\t.section\t.idata$4\n");
-
fprintf (f, "\t%s\t0\n", ASM_LONG);
fprintf (f, "\t.section .idata$4\n");
fprintf (f, "hname:\n");
if (!no_idata4)
{
fprintf (f, "\t.section .idata$4\n");
- fprintf (f, "\t%s\t0\n", ASM_LONG);
+#ifdef DLLTOOL_MX86_64
+ fprintf (f,"\t%s\t0\n\t%s\t0\n", ASM_LONG, ASM_LONG); /* NULL terminating list. */
+#else
+ fprintf (f,"\t%s\t0\n", ASM_LONG); /* NULL terminating list. */
+#endif
}
if (!no_idata5)
{
fprintf (f, "\t.section .idata$5\n");
- fprintf (f, "\t%s\t0\n", ASM_LONG);
+#ifdef DLLTOOL_MX86_64
+ fprintf (f,"\t%s\t0\n\t%s\t0\n", ASM_LONG, ASM_LONG); /* NULL terminating list. */
+#else
+ fprintf (f,"\t%s\t0\n", ASM_LONG); /* NULL terminating list. */
+#endif
}
#ifdef DLLTOOL_PPC
+2006-09-20 Kai Tietz <Kai.Tietz@onevision.com>
+
+ * binutils-all/copy-3.d: Add support for target x86_64-pc-mingw64.
+ * binutils-all/dlltool.exp: Likewise.
+ * binutils-all/objcopy.exp: Likewise.
+ * binutils-all/windres/windres.exp: Likewise.
+ * binutils-all/windres/lang.rc: xfail it as long as there is no windows.h.
+ * binutils-all/windres/strtab1.rc: Likewise.
+ * lib/utils-lib.exp: Adjust executable prefix detection (as .exe).
+
2006-09-14 H.J. Lu <hongjiu.lu@intel.com>
PR binutils/3181
#objcopy: --set-section-flags .text=alloc,data
#name: copy with setting section flags 3
#source: bintest.s
-#not-target: *-*-aout *-*-*pe *-*-*coff i*86-*-cygwin* i*86-*-mingw32*
+#not-target: *-*-aout *-*-*pe *-*-*coff i*86-*-cygwin* i*86-*-mingw32* x86_64-*-mingw64*
# The .text # section in PE/COFF has a fixed set of flags and these
# cannot be changed. We skip it for them.
-# Copyright 2002, 2004 Free Software Foundation, Inc.
+# Copyright 2002, 2004, 2006 Free Software Foundation, Inc.
# 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
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
-if {![istarget "i*86-*-*"]} {
+if {![istarget "i*86-*-*"] && ![istarget "x86_64-*-mingw64*"] } {
return
}
if {![istarget "i*86-*-*pe*"] \
&& ![istarget "i*86-*-cygwin*"] \
- && ![istarget "i*86-*-mingw32*"] } {
+ && ![istarget "i*86-*-mingw32*"] \
+ && ![istarget "x86_64-*-mingw64*"] } {
set target_xfail "yes"
} else {
set target_xfail "no"
# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
-# 2004
+# 2004, 2006
# Free Software Foundation, Inc.
# This program is free software; you can redistribute it and/or modify
# Build a final executable.
-if { [istarget *-*-cygwin] || [istarget *-*-mingw32] } {
+if { [istarget *-*-cygwin] || [istarget *-*-mingw*] } {
set test_prog "testprog.exe"
} else {
set test_prog "testprog"
+//#xfail *-*-mingw64
#include "windows.h"
LANGUAGE 0, 0
+//#xfail *-*-mingw64
#include "windows.h"
LANGUAGE 0, 0
-# Copyright 2001, 2003, 2004 Free Software Foundation, Inc.
+# Copyright 2001, 2003, 2004, 2006 Free Software Foundation, Inc.
# 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
# Written by DJ Delorie <dj@redhat.com>
-if {![istarget "i*86-*-*"]} {
+if {![istarget "i*86-*-*"] && ![istarget "x86_64-*-mingw64"] } {
return
}
if {![istarget "i*86-*-*pe*"] \
&& ![istarget "i*86-*-cygwin*"] \
- && ![istarget "i*86-*-mingw32*"] } {
+ && ![istarget "i*86-*-mingw32*"] \
+ && ![istarget "x86_64-*-mingw64*"] } {
set target_xfail "yes"
} else {
set target_xfail "no"
-# Copyright 1993, 1994, 1995, 1996, 1997, 2000, 2001, 2003, 2004
+# Copyright 1993, 1994, 1995, 1996, 1997, 2000, 2001, 2003, 2004, 2006
# Free Software Foundation, Inc.
# This program is free software; you can redistribute it and/or modify
# Returns target executable extension, if any.
#
proc exe_ext {} {
- if { [istarget *-*-mingw32] || [istarget *-*-cygwin*] } {
+ if { [istarget *-*-mingw*] || [istarget *-*-cygwin*] } {
return ".exe"
} else {
return ""
+2006-09-20 Kai Tietz <Kai.Tietz@onevision.com>
+
+ * configure.in: Add new target x86_64-pc-mingw64.
+ * configure: Regenerate.
+ * configure.tgt: Add new target x86_64-pc-mingw64.
+ * config/obj-coff.h: Add handling for TE_PEP target specific code and definitions.
+ * config/tc-i386.c: Add new targets.
+ (md_parse_option): Add targets to OPTION_64.
+ (x86_64_target_format): Add new method for setup proper default target cpu mode.
+ * config/te-pep.h: Add new target definition header.
+ (TE_PEP): New macro: Identifies new target architecture.
+ (COFF_WITH_pex64): Set proper includes in bfd.
+ * NEWS: Mention new target.
+
2006-09-18 Bernd Schmidt <bernd.schmidt@analog.com>
* config/bfin-parse.y (binary): Change sub of const to add of negated
-*- text -*-
+* Add support for x86_64 PE+ target.
+
* Add support for Score target.
* Support for the Infineon XC16X has been added by KPIT Cummins Infosystems.
#endif
#ifdef TC_I386
+#ifndef TE_PEP
+#include "coff/x86_64.h"
+#else
#include "coff/i386.h"
+#endif
#ifdef TE_PE
+#ifdef TE_PEP
+extern const char * x86_64_target_format (void);
+#define TARGET_FORMAT x86_64_target_format ()
+#define COFF_TARGET_FORMAT "pe-x86-64"
+#else
#define TARGET_FORMAT "pe-i386"
#endif
+#endif
#ifndef TARGET_FORMAT
+#ifdef TE_PEP
+#define TARGET_FORMAT "coff-x86-64"
+#else
#define TARGET_FORMAT "coff-i386"
#endif
#endif
+#endif
#ifdef TC_M68K
#include "coff/m68k.h"
#define OPTION_MARCH (OPTION_MD_BASE + 3)
#define OPTION_MTUNE (OPTION_MD_BASE + 4)
-struct option md_longopts[] = {
+struct option md_longopts[] =
+{
{"32", no_argument, NULL, OPTION_32},
-#if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
+#if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF) || defined(TE_PEP)
{"64", no_argument, NULL, OPTION_64},
#endif
{"divide", no_argument, NULL, OPTION_DIVIDE},
/* -s: On i386 Solaris, this tells the native assembler to use
.stab instead of .stab.excl. We always use .stab anyhow. */
break;
-
+#endif
+#if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF) || defined(TE_PEP)
case OPTION_64:
{
const char **list, **l;
list = bfd_target_list ();
for (l = list; *l != NULL; l++)
- if (strncmp (*l, "elf64-x86-64", 12) == 0)
+ if ( strncmp (*l, "elf64-x86-64", 12) == 0
+ || strcmp (*l, "coff-x86-64") == 0
+ || strcmp (*l, "pe-x86-64") == 0
+ || strcmp (*l, "pei-x86-64") == 0)
{
default_arch = "x86_64";
break;
}
+#if defined(TE_PEP)
+const char *
+x86_64_target_format (void)
+{
+ if (strcmp (default_arch, "x86_64") == 0)
+ {
+ set_code_flag (CODE_64BIT);
+ return COFF_TARGET_FORMAT;
+ }
+ else if (strcmp (default_arch, "i386") == 0)
+ {
+ set_code_flag (CODE_32BIT);
+ return "coff-i386";
+ }
+
+ as_fatal (_("Unknown architecture"));
+ return NULL;
+}
+#endif
+
#if ((defined (OBJ_MAYBE_COFF) && defined (OBJ_MAYBE_AOUT)) \
|| defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF))
--- /dev/null
+#define TE_PEP
+#define COFF_WITH_pex64
+
+#define TE_PE
+#define LEX_AT (LEX_BEGIN_NAME | LEX_NAME) /* Can have @'s inside labels. */
+
+/* The PE format supports long section names. */
+#define COFF_LONG_SECTION_NAMES
+
+#include "obj-format.h"
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
case "`/usr/bin/file conftest.o`" in
*32-bit*)
case $host in
- x86_64-*linux*)
+ x86_64-*linux*|x86_64-*mingw64*)
LD="${LD-ld} -m elf_i386"
;;
ppc64-*linux*|powerpc64-*linux*)
;;
*64-bit*)
case $host in
- x86_64-*linux*)
+ x86_64-*linux*|x86_64-*mingw64*)
LD="${LD-ld} -m elf_x86_64"
;;
ppc*-*linux*|powerpc*-*linux*)
;;
esac
;;
+ x86_64)
+ case ${obj_format} in
+ aout)
+ emulations="$emulations i386coff i386elf"
+ ;;
+ coff)
+ emulations="$emulations i386aout i386elf"
+ ;;
+ elf)
+ emulations="$emulations i386aout i386coff"
+ ;;
+ esac
+ ;;
esac
fi
m88k)
cat >>confdefs.h <<\_ACEOF
#define M88KCOFF 1
+_ACEOF
+ ;;
+ x86_64)
+cat >>confdefs.h <<\_ACEOF
+#define I386COFF 1
_ACEOF
;;
esac
;;
esac
;;
+ x86_64)
+ case ${obj_format} in
+ aout)
+ emulations="$emulations i386coff i386elf"
+ ;;
+ coff)
+ emulations="$emulations i386aout i386elf"
+ ;;
+ elf)
+ emulations="$emulations i386aout i386coff"
+ ;;
+ esac
+ ;;
esac
fi
i386) AC_DEFINE(I386COFF, 1, [Using i386 COFF?]) ;;
m68k) AC_DEFINE(M68KCOFF, 1, [Using m68k COFF?]) ;;
m88k) AC_DEFINE(M88KCOFF, 1, [Using m88k COFF?]) ;;
+ x86_64) AC_DEFINE(I386COFF, 1, [Using i386 COFF?]) ;;
esac
;;
esac
strongarm*b) cpu_type=arm endian=big ;;
strongarm*) cpu_type=arm endian=little ;;
v850*) cpu_type=v850 ;;
- x86_64) cpu_type=i386 arch=x86_64;;
+ x86_64*) cpu_type=i386 arch=x86_64;;
xscale*be|xscale*b) cpu_type=arm endian=big ;;
xscale*) cpu_type=arm endian=little ;;
xtensa*) cpu_type=xtensa arch=xtensa ;;
i386-*-cygwin*) fmt=coff em=pe ;;
i386-*-interix*) fmt=coff em=interix ;;
i386-*-mingw32*) fmt=coff em=pe ;;
+ i386-*-mingw64*) fmt=coff em=pep ;;
i386-*-nto-qnx*) fmt=elf ;;
i386-*-*nt*) fmt=coff em=pe ;;
i386-*-chaos) fmt=elf ;;
+2006-09-20 Kai Tietz <Kai.Tietz@onevision.com>
+
+ * gas/all/gas.exp: Add support for x86_64-*-mingw64.
+ * gas/i386/immed64.d: Add #pass for avoid proplems with alignment paddings.
+ * gas/i386/rex.d: Changed for x86_64-mingw32 target matching and padding.
+ * gas/i386/i386.d: Likewise.
+ * gas/i386/x86-64-addr32.d: Likewise.
+ * gas/i386/x86-64-branch.d: Likewise.
+ * gas/i386/x86-64-crx-suffix.d: Likewise.
+ * gas/i386/x86-64-crx.d: Likewise.
+ * gas/i386/x86-64-drx-suffix.d: Likewise.
+ * gas/i386/x86-64-crx-suffix.d: Likewise.
+ * gas/i386/x86-64-opcode.d: Likewise.
+ * gas/i386/x86-64-pcrel.d: Likewise.
+
2006-09-19 Bernd Schmidt <bernd.schmidt@analog.com>
* gas/bfin/load.s, gas/bfin/load.d: Add constant folding tests.
|| [istarget i*86-*-isc*] \
|| [istarget i*86-*-go32*] \
|| [istarget i*86-*-cygwin*] \
+ || [istarget x86_64-*-mingw64*] \
|| [istarget i*86-*-*nt] \
|| [istarget i*86-*-interix*] \
|| ([istarget i960-*-vxworks5.*] && ![istarget i960-*-vxworks5.0*]) } {
run_dump_test "x86-64-rep-suffix"
run_dump_test "x86-64-gidt"
run_dump_test "x86-64-nops"
+ if ![istarget "*-*-mingw64*"] then {
run_dump_test "x86-64-nops-1"
+ }
run_dump_test "x86-64-nops-1-k8"
run_dump_test "x86-64-nops-1-nocona"
run_dump_test "x86-64-nops-1-merom"
[ ]*[0-9a-fA-F]+:[ ]+e5 04[ ]+inl? +\$0x4,%eax
[ ]*[0-9a-fA-F]+:[ ]+e5 08[ ]+inl? +\$0x8,%eax
[ ]*[0-9a-fA-F]+:[ ]+e5 00[ ]+inl? +\$0x0,%eax
+#pass
#objdump: -dw
#name: x86-64 manual rex prefix use
-.*: +file format elf64-x86-64
+.*: +file format .*
Disassembly of section .text:
#objdump: -drw
#name: x86-64 32-bit addressing
-.*: +file format elf64-x86-64
+.*: +file format .*
Disassembly of section .text:
[ ]*8:[ ]+67 49 8d 80 00 00 00 00[ ]+addr32[ ]+lea[ ]+0x0\(%r8d?\),%rax.*
[ ]*10:[ ]+67 48 8d 05 00 00 00 00[ ]+addr32[ ]+lea[ ]+0\(%[re]ip\),%rax.*
[ ]*18:[ ]+67 48 8d 04 25 00 00 00 00[ ]+addr32[ ]+lea[ ]+0x0,%rax.*
+#pass
#objdump: -drw
#name: x86-64 indirect branch
-.*: +file format elf64-x86-64
+.*: +file format .*
Disassembly of section .text:
[ ]*2:[ ]+ff d0[ ]+callq[ ]+\*%rax
[ ]*4:[ ]+ff e0[ ]+jmpq[ ]+\*%rax
[ ]*6:[ ]+ff e0[ ]+jmpq[ ]+\*%rax
+#pass
#name: x86-64 control register related opcodes (with suffixes)
#source: x86-64-crx.s
-.*: +file format elf64-x86-64
+.*: +file format .*
Disassembly of section .text:
#name: x86-64 control register related opcodes
#source: x86-64-crx.s
-.*: +file format elf64-x86-64
+.*: +file format .*
Disassembly of section .text:
#name: x86-64 debug register related opcodes (with suffixes)
#source: x86-64-drx.s
-.*: +file format elf64-x86-64
+.*: +file format .*
Disassembly of section .text:
#objdump: -dw
#name: x86-64 debug register related opcodes
-.*: +file format elf64-x86-64
+.*: +file format .*
Disassembly of section .text:
#objdump: -drw
#name: x86-64 opcode
-.*: +file format elf64-x86-64
+.*: +file format .*
Disassembly of section .text:
#objdump: -drw
#name: x86-64 pcrel
-.*: +file format elf64-x86-64
+.*: +file format .*
Disassembly of section .text:
#objdump: -drw
#name: x86-64 rip addressing
-.*: +file format elf64-x86-64
+.*: +file format .*
Disassembly of section .text:
[ ]*6:[ ]+8d 05 11 11 11 11[ ]+lea[ ]+286331153\(%rip\),%eax[ ]*(#.*)?
[ ]*c:[ ]+8d 05 01 00 00 00[ ]+lea[ ]+1\(%rip\),%eax[ ]*(#.*)?
[ ]*12:[ ]+8d 05 00 00 00 00[ ]+lea[ ]+0\(%rip\),%eax[ ]*(#.*)?
+#pass
#name: x86-64 stack-related opcodes (Intel mode)
#source: x86-64-stack.s
-.*: +file format elf64-x86-64
+.*: +file format .*
Disassembly of section .text:
#name: x86-64 stack-related opcodes (with suffixes)
#source: x86-64-stack.s
-.*: +file format elf64-x86-64
+.*: +file format .*
Disassembly of section .text:
#objdump: -dw
#name: x86-64 stack-related opcodes
-.*: +file format elf64-x86-64
+.*: +file format .*
Disassembly of section .text:
Disassembly of section .text:
-0+ <bar-0x1a7>:
+0+ <.*>:
[ ]+0: 01 ca[ ]+add[ ]+%ecx,%edx
[ ]+2: 44 01 ca[ ]+add[ ]+%r9d,%edx
[ ]+5: 41 01 ca[ ]+add[ ]+%ecx,%r10d
+2006-09-20 Kai Tietz <Kai.Tietz@onevision.com>
+
+ * external.h: Add proper external_aouthdr64 structure (without
+ data_start member).
+ (AOUTHDRSZ64): Set according structure size.
+ (AOUTHDR64): As typedef of external_aouthdr64 structure.
+ * internal.h: Add relocation identifiers for coff.
+ * pe.h: Add define IMAGE_FILE_MACHINE_AMD64 the coff signature.
+ (PEPAOUTHDR): Adjust structure to have proper size (using AOUTHDR64).
+ (PEPAOUTSZ): Calculated size of 240.
+ * x86_64.h: Coff information for x86_64 (AMD64).
+
2006-02-05 Arnold Metselaar <arnold.metselaar@planet.nl>
* internal.h: Add relocation number R_IMM24 for Z80.
/* external.h -- External COFF structures
- Copyright 2001 Free Software Foundation, Inc.
+ Copyright 2001, 2006 Free Software Foundation, Inc.
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
#define AOUTHDRSZ 28
#define AOUTSZ 28
-#endif
+
+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 /* not DO_NOT_DEFINE_AOUTHDR */
#ifndef DO_NOT_DEFINE_SCNHDR
/********************** SECTION HEADER **********************/
/* Internal format of COFF object file data structures, for GNU BFD.
This file is part of BFD, the Binary File Descriptor library.
- Copyright 1999, 2000, 2001, 2002, 2003, 2004. 2005
+ Copyright 1999, 2000, 2001, 2002, 2003, 2004. 2005, 2006
Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
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. */
+#define R_AMD64_PCRQUAD 14 /* Pseude PC64 relocation - Note: not specified by MS/AMD but need for gas pc-relative 64bit wide relocation generated by ELF. */
+
+/* i386 Relocations. */
+
#define R_DIR16 1
#define R_REL24 5
#define R_DIR32 6
/* pe.h - PE COFF header information
- Copyright 1999, 2000, 2001, 2003, 2004 Free Software Foundation, Inc.
+ Copyright 1999, 2000, 2001, 2003, 2004, 2006 Free Software Foundation, Inc.
This file is part of BFD, the Binary File Descriptor library.
#define IMAGE_FILE_MACHINE_THUMB 0x01c2
#define IMAGE_FILE_MACHINE_TRICORE 0x0520
#define IMAGE_FILE_MACHINE_WCEMIPSV2 0x0169
+#define IMAGE_FILE_MACHINE_AMD64 0x8664
#define IMAGE_SUBSYSTEM_UNKNOWN 0
#define IMAGE_SUBSYSTEM_NATIVE 1
/* IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]; */
char DataDirectory[16][2][4]; /* 16 entries, 2 elements/entry, 4 chars. */
} PEAOUTHDR;
+
#undef AOUTSZ
#define AOUTSZ (AOUTHDRSZ + 196)
of just 4 bytes long. */
typedef struct
{
+#ifdef AOUTHDRSZ64
+ AOUTHDR64 standard;
+#else
AOUTHDR standard;
-
+#endif
/* NT extra fields; see internal.h for descriptions. */
char ImageBase[8];
char SectionAlignment[4];
/* IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]; */
char DataDirectory[16][2][4]; /* 16 entries, 2 elements/entry, 4 chars. */
} PEPAOUTHDR;
+
+#ifdef AOUTHDRSZ64
+#define PEPAOUTSZ (AOUTHDRSZ64 + 196 + 5 * 4) /* = 240 */
+#else
#define PEPAOUTSZ 240
+#endif
#undef E_FILNMLEN
#define E_FILNMLEN 18 /* # characters in a file name. */
--- /dev/null
+/* COFF information for AMD 64.
+ Copyright 2006 Free Software Foundation, Inc.
+
+ This file is part of BFD, the Binary File Descriptor library.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
+
+ Written by Kai Tietz, OneVision Software GmbH&CoKg. */
+
+#define L_LNNO_SIZE 2
+#define INCLUDE_COMDAT_FIELDS_IN_AUXENT
+
+#include "coff/external.h"
+
+#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
+2006-09-20 Kai Tietz <Kai.Tietz@onevision.com>
+
+ * configure.in: Add new target x86_64-pc-mingw64.
+ * configure: Regenerate.
+ * configure.tgt: Add definition of target emulation i386pep.
+ * Makefile.am: Add new target files for target-all.
+ * Makefile.in: Regenerate.
+ * pe-dll.c: Adjust to be inheritable by pep_dll.c as include.
+ Fix memory out of bounds excess for idata relocation section data.
+ * pep-dll.c: Add target specific shared object handling.
+ * pep-dll.h: Add target specific definitions for shared object handling.
+ * emulparams/i386pep.sh: Add new emulation params for target x86_64 coff.
+ * emultempl/pep.em: Add new emulation file for target x86_64 coff.
+ * po/POTFILES.in: Regenerate.
+ * scripttempl/pep.sc: Add linker script template for target x86_64 coff.
+ * NEWS: Mention new target.
+
2006-09-18 Thiemo Seufer <ths@networkno.de>
* configure.tgt: Add mips*el-sde-elf* and mips*-sde-elf*
ei386nw.o \
ei386pe.o \
ei386pe_posix.o \
+ ei386pep.o \
elnk960.o \
em32relf.o \
em32rlelf.o \
ALL_EMUL_EXTRA_OFILES = \
deffilep.o \
- pe-dll.o
+ pe-dll.o \
+ pep-dll.o
CFILES = ldctor.c ldemul.c ldexp.c ldfile.c ldlang.c \
ldmain.c ldmisc.c ldver.c ldwrite.c lexsup.c \
- mri.c ldcref.c pe-dll.c
+ mri.c ldcref.c pe-dll.c pep-dll.c
HFILES = ld.h ldctor.h ldemul.h ldexp.h ldfile.h \
ldlang.h ldlex.h ldmain.h ldmisc.h ldver.h \
- ldwrite.h mri.h deffile.h pe-dll.h elf-hints-local.h
+ ldwrite.h mri.h deffile.h pe-dll.h pep-dll.h elf-hints-local.h
GENERATED_CFILES = ldgram.c ldlex.c deffilep.c
GENERATED_HFILES = ldgram.h ldemul-list.h deffilep.h
ei386pe_posix.c: $(srcdir)/emulparams/i386pe_posix.sh \
$(srcdir)/emultempl/pe.em $(srcdir)/scripttempl/pe.sc ${GEN_DEPENDS}
${GENSCRIPTS} i386pe_posix "$(tdir_i386pe_posix)"
+ei386pep.c: $(srcdir)/emulparams/i386pep.sh \
+ $(srcdir)/emultempl/pep.em $(srcdir)/scripttempl/pep.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} i386pep "$(tdir_i386pe)"
elnk960.c: $(srcdir)/emulparams/lnk960.sh \
$(srcdir)/emultempl/lnk960.em $(srcdir)/scripttempl/i960.sc ${GEN_DEPENDS}
${GENSCRIPTS} lnk960 "$(tdir_lnk960)"
ld.h $(INCDIR)/bin-bugs.h ldexp.h ldlang.h ldwrite.h \
ldmisc.h ldgram.h ldmain.h ldfile.h ldemul.h $(INCDIR)/coff/internal.h \
$(BFDDIR)/libcoff.h deffile.h pe-dll.h
+pep-dll.o: pep-dll.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \
+ $(INCDIR)/symcat.h sysdep.h config.h $(INCDIR)/fopen-same.h \
+ $(INCDIR)/bfdlink.h $(INCDIR)/libiberty.h $(INCDIR)/safe-ctype.h \
+ ld.h $(INCDIR)/bin-bugs.h ldexp.h ldlang.h ldwrite.h \
+ ldmisc.h ldgram.h ldmain.h ldfile.h ldemul.h $(INCDIR)/coff/internal.h \
+ $(BFDDIR)/libcoff.h deffile.h pep-dll.h
ldgram.o: ldgram.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \
$(INCDIR)/symcat.h sysdep.h config.h $(INCDIR)/fopen-same.h \
$(INCDIR)/bfdlink.h ld.h $(INCDIR)/bin-bugs.h ldexp.h \
ei386nw.o \
ei386pe.o \
ei386pe_posix.o \
+ ei386pep.o \
elnk960.o \
em32relf.o \
em32rlelf.o \
ALL_EMUL_EXTRA_OFILES = \
deffilep.o \
- pe-dll.o
+ pe-dll.o \
+ pep-dll.o
CFILES = ldctor.c ldemul.c ldexp.c ldfile.c ldlang.c \
ldmain.c ldmisc.c ldver.c ldwrite.c lexsup.c \
- mri.c ldcref.c pe-dll.c
+ mri.c ldcref.c pe-dll.c pep-dll.c
HFILES = ld.h ldctor.h ldemul.h ldexp.h ldfile.h \
ldlang.h ldlex.h ldmain.h ldmisc.h ldver.h \
- ldwrite.h mri.h deffile.h pe-dll.h elf-hints-local.h
+ ldwrite.h mri.h deffile.h pe-dll.h pep-dll.h elf-hints-local.h
GENERATED_CFILES = ldgram.c ldlex.c deffilep.c
GENERATED_HFILES = ldgram.h ldemul-list.h deffilep.h
ei386pe_posix.c: $(srcdir)/emulparams/i386pe_posix.sh \
$(srcdir)/emultempl/pe.em $(srcdir)/scripttempl/pe.sc ${GEN_DEPENDS}
${GENSCRIPTS} i386pe_posix "$(tdir_i386pe_posix)"
+ei386pep.c: $(srcdir)/emulparams/i386pep.sh \
+ $(srcdir)/emultempl/pep.em $(srcdir)/scripttempl/pep.sc ${GEN_DEPENDS}
+ ${GENSCRIPTS} i386pep "$(tdir_i386pe)"
elnk960.c: $(srcdir)/emulparams/lnk960.sh \
$(srcdir)/emultempl/lnk960.em $(srcdir)/scripttempl/i960.sc ${GEN_DEPENDS}
${GENSCRIPTS} lnk960 "$(tdir_lnk960)"
ld.h $(INCDIR)/bin-bugs.h ldexp.h ldlang.h ldwrite.h \
ldmisc.h ldgram.h ldmain.h ldfile.h ldemul.h $(INCDIR)/coff/internal.h \
$(BFDDIR)/libcoff.h deffile.h pe-dll.h
+pep-dll.o: pep-dll.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \
+ $(INCDIR)/symcat.h sysdep.h config.h $(INCDIR)/fopen-same.h \
+ $(INCDIR)/bfdlink.h $(INCDIR)/libiberty.h $(INCDIR)/safe-ctype.h \
+ ld.h $(INCDIR)/bin-bugs.h ldexp.h ldlang.h ldwrite.h \
+ ldmisc.h ldgram.h ldmain.h ldfile.h ldemul.h $(INCDIR)/coff/internal.h \
+ $(BFDDIR)/libcoff.h deffile.h pep-dll.h
ldgram.o: ldgram.c ../bfd/bfd.h $(INCDIR)/ansidecl.h \
$(INCDIR)/symcat.h sysdep.h config.h $(INCDIR)/fopen-same.h \
$(INCDIR)/bfdlink.h ld.h $(INCDIR)/bin-bugs.h ldexp.h \
-*- text -*-
+* Add support for x86_64 PE+ target.
+
* Add support for Score target.
* ELF: Add --dynamic-list option to specify a list of global symbols
test "$targ" != "$host" && LIB_PATH='${tooldir}/lib/w32api' ;;
i[3-7]86-*-mingw32*) targ_emul=i386pe ;
targ_extra_ofiles="deffilep.o pe-dll.o" ;;
+x86_64-*-mingw64*) targ_emul=i386pep ;
+ targ_extra_ofiles="deffilep.o pep-dll.o" ;;
i[3-7]86-*-interix*) targ_emul=i386pe_posix;
targ_extra_ofiles="deffilep.o pe-dll.o" ;;
i[3-7]86-*-beospe*) targ_emul=i386beos ;;
--- /dev/null
+ARCH="i386:x86-64"
+SCRIPT_NAME=pep
+OUTPUT_FORMAT="pei-x86-64"
+RELOCATEABLE_OUTPUT_FORMAT="pe-x86-64"
+TEMPLATE_NAME=pep
+ENTRY="_mainCRTStartup"
+SUBSYSTEM=PE_DEF_SUBSYSTEM
+INITIAL_SYMBOL_CHAR=\"_\"
+TARGET_PAGE_SIZE=0x1000
--- /dev/null
+# This shell script emits a C file. -*- C -*-
+# It does some substitutions.
+test -z "${ENTRY}" && ENTRY="_mainCRTStartup"
+if [ -z "$MACHINE" ]; then
+ OUTPUT_ARCH=${ARCH}
+else
+ OUTPUT_ARCH=${ARCH}:${MACHINE}
+fi
+rm -f e${EMULATION_NAME}.c
+(echo;echo;echo;echo;echo)>e${EMULATION_NAME}.c # there, now line numbers match ;-)
+cat >>e${EMULATION_NAME}.c <<EOF
+/* This file is part of GLD, the Gnu Linker.
+ Copyright 2006 Free Software Foundation, Inc.
+
+ 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. */
+
+/* For WINDOWS_XP64 and higher */
+/* Based on pe.em, but modified for 64 bit support. */
+
+#define TARGET_IS_${EMULATION_NAME}
+
+#define COFF_IMAGE_WITH_PE
+#define COFF_WITH_PE
+#define COFF_WITH_pex64
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "bfdlink.h"
+#include "getopt.h"
+#include "libiberty.h"
+#include "ld.h"
+#include "ldmain.h"
+#include "ldexp.h"
+#include "ldlang.h"
+#include "ldfile.h"
+#include "ldemul.h"
+#include <ldgram.h>
+#include "ldlex.h"
+#include "ldmisc.h"
+#include "ldctor.h"
+#include "coff/internal.h"
+
+/* FIXME: See bfd/peXXigen.c for why we include an architecture specific
+ header in generic PE code. */
+#include "coff/x86_64.h"
+#include "coff/pe.h"
+
+/* FIXME: This is a BFD internal header file, and we should not be
+ using it here. */
+#include "../bfd/libcoff.h"
+
+#undef AOUTSZ
+#define AOUTSZ PEPAOUTSZ
+#define PEAOUTHDR PEPAOUTHDR
+
+#include "deffile.h"
+#include "pep-dll.h"
+#include "safe-ctype.h"
+
+/* Permit the emulation parameters to override the default section
+ alignment by setting OVERRIDE_SECTION_ALIGNMENT. FIXME: This makes
+ it seem that include/coff/internal.h should not define
+ PE_DEF_SECTION_ALIGNMENT. */
+#if PE_DEF_SECTION_ALIGNMENT != ${OVERRIDE_SECTION_ALIGNMENT:-PE_DEF_SECTION_ALIGNMENT}
+#undef PE_DEF_SECTION_ALIGNMENT
+#define PE_DEF_SECTION_ALIGNMENT ${OVERRIDE_SECTION_ALIGNMENT}
+#endif
+
+#ifdef TARGET_IS_i386pep
+#define DLL_SUPPORT
+#endif
+
+#if defined(TARGET_IS_i386pep) || ! defined(DLL_SUPPORT)
+#define PE_DEF_SUBSYSTEM 3
+#else
+#undef NT_EXE_IMAGE_BASE
+#define NT_EXE_IMAGE_BASE 0x00010000
+#undef PE_DEF_SECTION_ALIGNMENT
+#define PE_DEF_SUBSYSTEM 2
+#undef PE_DEF_FILE_ALIGNMENT
+#define PE_DEF_FILE_ALIGNMENT 0x00000200
+#define PE_DEF_SECTION_ALIGNMENT 0x00000400
+#endif
+
+
+static struct internal_extra_pe_aouthdr pep;
+static int dll;
+static flagword real_flags = IMAGE_FILE_LARGE_ADDRESS_AWARE;
+static int support_old_code = 0;
+static lang_assignment_statement_type *image_base_statement = 0;
+
+#ifdef DLL_SUPPORT
+static int pep_enable_stdcall_fixup = -1; /* 0=disable 1=enable. */
+static char * pep_out_def_filename = NULL;
+static char * pep_implib_filename = NULL;
+static int pep_enable_auto_image_base = 0;
+static char * pep_dll_search_prefix = NULL;
+#endif
+
+extern const char *output_filename;
+
+static void
+gld_${EMULATION_NAME}_before_parse (void)
+{
+ ldfile_set_output_arch ("${OUTPUT_ARCH}", bfd_arch_`echo ${ARCH} | sed -e 's/:.*//'`);
+ output_filename = "${EXECUTABLE_NAME:-a.exe}";
+#ifdef DLL_SUPPORT
+ config.dynamic_link = TRUE;
+ config.has_shared = 1;
+ link_info.pei386_auto_import = -1;
+ link_info.pei386_runtime_pseudo_reloc = -1;
+
+#if (PE_DEF_SUBSYSTEM == 9) || (PE_DEF_SUBSYSTEM == 2)
+ lang_default_entry ("_WinMainCRTStartup");
+#else
+ lang_default_entry ("${ENTRY}");
+#endif
+#endif
+}
+\f
+/* PE format extra command line options. */
+
+/* Used for setting flags in the PE header. */
+enum options
+{
+ OPTION_BASE_FILE = 300 + 1,
+ OPTION_DLL,
+ OPTION_FILE_ALIGNMENT,
+ OPTION_IMAGE_BASE,
+ OPTION_MAJOR_IMAGE_VERSION,
+ OPTION_MAJOR_OS_VERSION,
+ OPTION_MAJOR_SUBSYSTEM_VERSION,
+ OPTION_MINOR_IMAGE_VERSION,
+ OPTION_MINOR_OS_VERSION,
+ OPTION_MINOR_SUBSYSTEM_VERSION,
+ OPTION_SECTION_ALIGNMENT,
+ OPTION_STACK,
+ OPTION_SUBSYSTEM,
+ OPTION_HEAP,
+ OPTION_SUPPORT_OLD_CODE,
+ OPTION_OUT_DEF,
+ OPTION_EXPORT_ALL,
+ OPTION_EXCLUDE_SYMBOLS,
+ OPTION_KILL_ATS,
+ OPTION_STDCALL_ALIASES,
+ OPTION_ENABLE_STDCALL_FIXUP,
+ OPTION_DISABLE_STDCALL_FIXUP,
+ OPTION_IMPLIB_FILENAME,
+ OPTION_WARN_DUPLICATE_EXPORTS,
+ OPTION_IMP_COMPAT,
+ OPTION_ENABLE_AUTO_IMAGE_BASE,
+ OPTION_DISABLE_AUTO_IMAGE_BASE,
+ OPTION_DLL_SEARCH_PREFIX,
+ OPTION_NO_DEFAULT_EXCLUDES,
+ OPTION_DLL_ENABLE_AUTO_IMPORT,
+ OPTION_DLL_DISABLE_AUTO_IMPORT,
+ OPTION_ENABLE_EXTRA_PE_DEBUG,
+ OPTION_EXCLUDE_LIBS,
+ OPTION_DLL_ENABLE_RUNTIME_PSEUDO_RELOC,
+ OPTION_DLL_DISABLE_RUNTIME_PSEUDO_RELOC
+};
+
+static void
+gld${EMULATION_NAME}_add_options
+ (int ns ATTRIBUTE_UNUSED,
+ char **shortopts ATTRIBUTE_UNUSED,
+ int nl,
+ struct option **longopts,
+ int nrl ATTRIBUTE_UNUSED,
+ struct option **really_longopts ATTRIBUTE_UNUSED)
+{
+ static const struct option xtra_long[] =
+ {
+ /* PE options */
+ {"base-file", required_argument, NULL, OPTION_BASE_FILE},
+ {"dll", no_argument, NULL, OPTION_DLL},
+ {"file-alignment", required_argument, NULL, OPTION_FILE_ALIGNMENT},
+ {"heap", required_argument, NULL, OPTION_HEAP},
+ {"image-base", required_argument, NULL, OPTION_IMAGE_BASE},
+ {"major-image-version", required_argument, NULL, OPTION_MAJOR_IMAGE_VERSION},
+ {"major-os-version", required_argument, NULL, OPTION_MAJOR_OS_VERSION},
+ {"major-subsystem-version", required_argument, NULL, OPTION_MAJOR_SUBSYSTEM_VERSION},
+ {"minor-image-version", required_argument, NULL, OPTION_MINOR_IMAGE_VERSION},
+ {"minor-os-version", required_argument, NULL, OPTION_MINOR_OS_VERSION},
+ {"minor-subsystem-version", required_argument, NULL, OPTION_MINOR_SUBSYSTEM_VERSION},
+ {"section-alignment", required_argument, NULL, OPTION_SECTION_ALIGNMENT},
+ {"stack", required_argument, NULL, OPTION_STACK},
+ {"subsystem", required_argument, NULL, OPTION_SUBSYSTEM},
+ {"support-old-code", no_argument, NULL, OPTION_SUPPORT_OLD_CODE},
+#ifdef DLL_SUPPORT
+ /* getopt allows abbreviations, so we do this to stop it
+ from treating -o as an abbreviation for this option. */
+ {"output-def", required_argument, NULL, OPTION_OUT_DEF},
+ {"output-def", required_argument, NULL, OPTION_OUT_DEF},
+ {"export-all-symbols", no_argument, NULL, OPTION_EXPORT_ALL},
+ {"exclude-symbols", required_argument, NULL, OPTION_EXCLUDE_SYMBOLS},
+ {"exclude-libs", required_argument, NULL, OPTION_EXCLUDE_LIBS},
+ {"kill-at", no_argument, NULL, OPTION_KILL_ATS},
+ {"add-stdcall-alias", no_argument, NULL, OPTION_STDCALL_ALIASES},
+ {"enable-stdcall-fixup", no_argument, NULL, OPTION_ENABLE_STDCALL_FIXUP},
+ {"disable-stdcall-fixup", no_argument, NULL, OPTION_DISABLE_STDCALL_FIXUP},
+ {"out-implib", required_argument, NULL, OPTION_IMPLIB_FILENAME},
+ {"warn-duplicate-exports", no_argument, NULL, OPTION_WARN_DUPLICATE_EXPORTS},
+ /* getopt() allows abbreviations, so we do this to stop it from
+ treating -c as an abbreviation for these --compat-implib. */
+ {"compat-implib", no_argument, NULL, OPTION_IMP_COMPAT},
+ {"compat-implib", no_argument, NULL, OPTION_IMP_COMPAT},
+ {"enable-auto-image-base", no_argument, NULL, OPTION_ENABLE_AUTO_IMAGE_BASE},
+ {"disable-auto-image-base", no_argument, NULL, OPTION_DISABLE_AUTO_IMAGE_BASE},
+ {"dll-search-prefix", required_argument, NULL, OPTION_DLL_SEARCH_PREFIX},
+ {"no-default-excludes", no_argument, NULL, OPTION_NO_DEFAULT_EXCLUDES},
+ {"enable-auto-import", no_argument, NULL, OPTION_DLL_ENABLE_AUTO_IMPORT},
+ {"disable-auto-import", no_argument, NULL, OPTION_DLL_DISABLE_AUTO_IMPORT},
+ {"enable-extra-pep-debug", no_argument, NULL, OPTION_ENABLE_EXTRA_PE_DEBUG},
+ {"enable-runtime-pseudo-reloc", no_argument, NULL, OPTION_DLL_ENABLE_RUNTIME_PSEUDO_RELOC},
+ {"disable-runtime-pseudo-reloc", no_argument, NULL, OPTION_DLL_DISABLE_RUNTIME_PSEUDO_RELOC},
+#endif
+ {NULL, no_argument, NULL, 0}
+ };
+
+ *longopts = xrealloc (*longopts, nl * sizeof (struct option) + sizeof (xtra_long));
+ memcpy (*longopts + nl, &xtra_long, sizeof (xtra_long));
+}
+
+/* PE/WIN32; added routines to get the subsystem type, heap and/or stack
+ parameters which may be input from the command line. */
+
+typedef struct
+{
+ void *ptr;
+ int size;
+ int value;
+ char *symbol;
+ int inited;
+} definfo;
+
+#define D(field,symbol,def) {&pep.field,sizeof(pep.field), def, symbol,0}
+
+static definfo init[] =
+{
+ /* imagebase must be first */
+#define IMAGEBASEOFF 0
+ D(ImageBase,"__image_base__", NT_EXE_IMAGE_BASE),
+#define DLLOFF 1
+ {&dll, sizeof(dll), 0, "__dll__", 0},
+#define MSIMAGEBASEOFF 2
+ D(ImageBase,"__ImageBase", NT_EXE_IMAGE_BASE),
+ D(SectionAlignment,"__section_alignment__", PE_DEF_SECTION_ALIGNMENT),
+ D(FileAlignment,"__file_alignment__", PE_DEF_FILE_ALIGNMENT),
+ D(MajorOperatingSystemVersion,"__major_os_version__", 4),
+ D(MinorOperatingSystemVersion,"__minor_os_version__", 0),
+ D(MajorImageVersion,"__major_image_version__", 0),
+ D(MinorImageVersion,"__minor_image_version__", 0),
+ D(MajorSubsystemVersion,"__major_subsystem_version__", 5),
+ D(MinorSubsystemVersion,"__minor_subsystem_version__", 2),
+ D(Subsystem,"__subsystem__", ${SUBSYSTEM}),
+ D(SizeOfStackReserve,"__size_of_stack_reserve__", 0x200000),
+ D(SizeOfStackCommit,"__size_of_stack_commit__", 0x1000),
+ D(SizeOfHeapReserve,"__size_of_heap_reserve__", 0x100000),
+ D(SizeOfHeapCommit,"__size_of_heap_commit__", 0x1000),
+ D(LoaderFlags,"__loader_flags__", 0x0),
+ { NULL, 0, 0, NULL, 0 }
+};
+
+
+static void
+gld_${EMULATION_NAME}_list_options (FILE *file)
+{
+ fprintf (file, _(" --base_file <basefile> Generate a base file for relocatable DLLs\n"));
+ fprintf (file, _(" --dll Set image base to the default for DLLs\n"));
+ fprintf (file, _(" --file-alignment <size> Set file alignment\n"));
+ fprintf (file, _(" --heap <size> Set initial size of the heap\n"));
+ fprintf (file, _(" --image-base <address> Set start address of the executable\n"));
+ fprintf (file, _(" --major-image-version <number> Set version number of the executable\n"));
+ fprintf (file, _(" --major-os-version <number> Set minimum required OS version\n"));
+ fprintf (file, _(" --major-subsystem-version <number> Set minimum required OS subsystem version\n"));
+ fprintf (file, _(" --minor-image-version <number> Set revision number of the executable\n"));
+ fprintf (file, _(" --minor-os-version <number> Set minimum required OS revision\n"));
+ fprintf (file, _(" --minor-subsystem-version <number> Set minimum required OS subsystem revision\n"));
+ fprintf (file, _(" --section-alignment <size> Set section alignment\n"));
+ fprintf (file, _(" --stack <size> Set size of the initial stack\n"));
+ fprintf (file, _(" --subsystem <name>[:<version>] Set required OS subsystem [& version]\n"));
+ fprintf (file, _(" --support-old-code Support interworking with old code\n"));
+#ifdef DLL_SUPPORT
+ fprintf (file, _(" --add-stdcall-alias Export symbols with and without @nn\n"));
+ fprintf (file, _(" --disable-stdcall-fixup Don't link _sym to _sym@nn\n"));
+ fprintf (file, _(" --enable-stdcall-fixup Link _sym to _sym@nn without warnings\n"));
+ fprintf (file, _(" --exclude-symbols sym,sym,... Exclude symbols from automatic export\n"));
+ fprintf (file, _(" --exclude-libs lib,lib,... Exclude libraries from automatic export\n"));
+ fprintf (file, _(" --export-all-symbols Automatically export all globals to DLL\n"));
+ fprintf (file, _(" --kill-at Remove @nn from exported symbols\n"));
+ fprintf (file, _(" --out-implib <file> Generate import library\n"));
+ fprintf (file, _(" --output-def <file> Generate a .DEF file for the built DLL\n"));
+ fprintf (file, _(" --warn-duplicate-exports Warn about duplicate exports.\n"));
+ fprintf (file, _(" --compat-implib Create backward compatible import libs;\n\
+ create __imp_<SYMBOL> as well.\n"));
+ fprintf (file, _(" --enable-auto-image-base Automatically choose image base for DLLs\n\
+ unless user specifies one\n"));
+ fprintf (file, _(" --disable-auto-image-base Do not auto-choose image base. (default)\n"));
+ fprintf (file, _(" --dll-search-prefix=<string> When linking dynamically to a dll without\n\
+ an importlib, use <string><basename>.dll\n\
+ in preference to lib<basename>.dll \n"));
+ fprintf (file, _(" --enable-auto-import Do sophistcated linking of _sym to\n\
+ __imp_sym for DATA references\n"));
+ fprintf (file, _(" --disable-auto-import Do not auto-import DATA items from DLLs\n"));
+ fprintf (file, _(" --enable-runtime-pseudo-reloc Work around auto-import limitations by\n\
+ adding pseudo-relocations resolved at\n\
+ runtime.\n"));
+ fprintf (file, _(" --disable-runtime-pseudo-reloc Do not add runtime pseudo-relocations for\n\
+ auto-imported DATA.\n"));
+ fprintf (file, _(" --enable-extra-pep-debug Enable verbose debug output when building\n\
+ or linking to DLLs (esp. auto-import)\n"));
+#endif
+}
+
+
+static void
+set_pep_name (char *name, long val)
+{
+ int i;
+
+ /* Find the name and set it. */
+ for (i = 0; init[i].ptr; i++)
+ {
+ if (strcmp (name, init[i].symbol) == 0)
+ {
+ init[i].value = val;
+ init[i].inited = 1;
+ if (strcmp (name,"__image_base__") == 0)
+ set_pep_name ("__ImageBase", val);
+ return;
+ }
+ }
+ abort ();
+}
+
+
+static void
+set_pep_subsystem (void)
+{
+ const char *sver;
+ const char *entry;
+ const char *initial_symbol_char;
+ char *end;
+ int len;
+ int i;
+ int subsystem;
+ unsigned long temp_subsystem;
+ static const struct
+ {
+ const char *name;
+ const int value;
+ const char *entry;
+ }
+ v[] =
+ {
+ { "native", 1, "NtProcessStartup" },
+ { "windows", 2, "WinMainCRTStartup" },
+ { "console", 3, "mainCRTStartup" },
+ { "posix", 7, "__PosixProcessStartup"},
+ { "wince", 9, "_WinMainCRTStartup" },
+ { "xbox", 14, "mainCRTStartup" },
+ { NULL, 0, NULL }
+ };
+ /* Entry point name for arbitrary subsystem numbers. */
+ static const char default_entry[] = "mainCRTStartup";
+
+ /* Check for the presence of a version number. */
+ sver = strchr (optarg, ':');
+ if (sver == NULL)
+ len = strlen (optarg);
+ else
+ {
+ len = sver - optarg;
+ set_pep_name ("__major_subsystem_version__",
+ strtoul (sver + 1, &end, 0));
+ if (*end == '.')
+ set_pep_name ("__minor_subsystem_version__",
+ strtoul (end + 1, &end, 0));
+ if (*end != '\0')
+ einfo (_("%P: warning: bad version number in -subsystem option\n"));
+ }
+
+ /* Check for numeric subsystem. */
+ temp_subsystem = strtoul (optarg, & end, 0);
+ if ((*end == ':' || *end == '\0') && (temp_subsystem < 65536))
+ {
+ /* Search list for a numeric match to use its entry point. */
+ for (i = 0; v[i].name; i++)
+ if (v[i].value == (int) temp_subsystem)
+ break;
+
+ /* If no match, use the default. */
+ if (v[i].name != NULL)
+ entry = v[i].entry;
+ else
+ entry = default_entry;
+
+ /* Use this subsystem. */
+ subsystem = (int) temp_subsystem;
+ }
+ else
+ {
+ /* Search for subsystem by name. */
+ for (i = 0; v[i].name; i++)
+ if (strncmp (optarg, v[i].name, len) == 0
+ && v[i].name[len] == '\0')
+ break;
+
+ if (v[i].name == NULL)
+ {
+ einfo (_("%P%F: invalid subsystem type %s\n"), optarg);
+ return;
+ }
+
+ entry = v[i].entry;
+ subsystem = v[i].value;
+ }
+
+ set_pep_name ("__subsystem__", subsystem);
+
+ initial_symbol_char = ${INITIAL_SYMBOL_CHAR};
+ if (*initial_symbol_char != '\0')
+ {
+ char *alc_entry;
+
+ /* lang_default_entry expects its argument to be permanently
+ allocated, so we don't free this string. */
+ alc_entry = xmalloc (strlen (initial_symbol_char)
+ + strlen (entry)
+ + 1);
+ strcpy (alc_entry, initial_symbol_char);
+ strcat (alc_entry, entry);
+ entry = alc_entry;
+ }
+
+ lang_default_entry (entry);
+
+ return;
+}
+
+
+static void
+set_pep_value (char *name)
+{
+ char *end;
+
+ set_pep_name (name, strtoul (optarg, &end, 0));
+
+ if (end == optarg)
+ einfo (_("%P%F: invalid hex number for PE parameter '%s'\n"), optarg);
+
+ optarg = end;
+}
+
+
+static void
+set_pep_stack_heap (char *resname, char *comname)
+{
+ set_pep_value (resname);
+
+ if (*optarg == ',')
+ {
+ optarg++;
+ set_pep_value (comname);
+ }
+ else if (*optarg)
+ einfo (_("%P%F: strange hex info for PE parameter '%s'\n"), optarg);
+}
+
+
+static bfd_boolean
+gld${EMULATION_NAME}_handle_option (int optc)
+{
+ switch (optc)
+ {
+ default:
+ return FALSE;
+
+ case OPTION_BASE_FILE:
+ link_info.base_file = fopen (optarg, FOPEN_WB);
+ if (link_info.base_file == NULL)
+ {
+ /* xgettext:c-format */
+ fprintf (stderr, _("%s: Can't open base file %s\n"),
+ program_name, optarg);
+ xexit (1);
+ }
+ break;
+
+ /* PE options. */
+ case OPTION_HEAP:
+ set_pep_stack_heap ("__size_of_heap_reserve__", "__size_of_heap_commit__");
+ break;
+ case OPTION_STACK:
+ set_pep_stack_heap ("__size_of_stack_reserve__", "__size_of_stack_commit__");
+ break;
+ case OPTION_SUBSYSTEM:
+ set_pep_subsystem ();
+ break;
+ case OPTION_MAJOR_OS_VERSION:
+ set_pep_value ("__major_os_version__");
+ break;
+ case OPTION_MINOR_OS_VERSION:
+ set_pep_value ("__minor_os_version__");
+ break;
+ case OPTION_MAJOR_SUBSYSTEM_VERSION:
+ set_pep_value ("__major_subsystem_version__");
+ break;
+ case OPTION_MINOR_SUBSYSTEM_VERSION:
+ set_pep_value ("__minor_subsystem_version__");
+ break;
+ case OPTION_MAJOR_IMAGE_VERSION:
+ set_pep_value ("__major_image_version__");
+ break;
+ case OPTION_MINOR_IMAGE_VERSION:
+ set_pep_value ("__minor_image_version__");
+ break;
+ case OPTION_FILE_ALIGNMENT:
+ set_pep_value ("__file_alignment__");
+ break;
+ case OPTION_SECTION_ALIGNMENT:
+ set_pep_value ("__section_alignment__");
+ break;
+ case OPTION_DLL:
+ set_pep_name ("__dll__", 1);
+ break;
+ case OPTION_IMAGE_BASE:
+ set_pep_value ("__image_base__");
+ break;
+ case OPTION_SUPPORT_OLD_CODE:
+ support_old_code = 1;
+ break;
+#ifdef DLL_SUPPORT
+ case OPTION_OUT_DEF:
+ pep_out_def_filename = xstrdup (optarg);
+ break;
+ case OPTION_EXPORT_ALL:
+ pep_dll_export_everything = 1;
+ break;
+ case OPTION_EXCLUDE_SYMBOLS:
+ pep_dll_add_excludes (optarg, 0);
+ break;
+ case OPTION_EXCLUDE_LIBS:
+ pep_dll_add_excludes (optarg, 1);
+ break;
+ case OPTION_KILL_ATS:
+ pep_dll_kill_ats = 1;
+ break;
+ case OPTION_STDCALL_ALIASES:
+ pep_dll_stdcall_aliases = 1;
+ break;
+ case OPTION_ENABLE_STDCALL_FIXUP:
+ pep_enable_stdcall_fixup = 1;
+ break;
+ case OPTION_DISABLE_STDCALL_FIXUP:
+ pep_enable_stdcall_fixup = 0;
+ break;
+ case OPTION_IMPLIB_FILENAME:
+ pep_implib_filename = xstrdup (optarg);
+ break;
+ case OPTION_WARN_DUPLICATE_EXPORTS:
+ pep_dll_warn_dup_exports = 1;
+ break;
+ case OPTION_IMP_COMPAT:
+ pep_dll_compat_implib = 1;
+ break;
+ case OPTION_ENABLE_AUTO_IMAGE_BASE:
+ pep_enable_auto_image_base = 1;
+ break;
+ case OPTION_DISABLE_AUTO_IMAGE_BASE:
+ pep_enable_auto_image_base = 0;
+ break;
+ case OPTION_DLL_SEARCH_PREFIX:
+ pep_dll_search_prefix = xstrdup (optarg);
+ break;
+ case OPTION_NO_DEFAULT_EXCLUDES:
+ pep_dll_do_default_excludes = 0;
+ break;
+ case OPTION_DLL_ENABLE_AUTO_IMPORT:
+ link_info.pei386_auto_import = 1;
+ break;
+ case OPTION_DLL_DISABLE_AUTO_IMPORT:
+ link_info.pei386_auto_import = 0;
+ break;
+ case OPTION_DLL_ENABLE_RUNTIME_PSEUDO_RELOC:
+ link_info.pei386_runtime_pseudo_reloc = 1;
+ break;
+ case OPTION_DLL_DISABLE_RUNTIME_PSEUDO_RELOC:
+ link_info.pei386_runtime_pseudo_reloc = 0;
+ break;
+ case OPTION_ENABLE_EXTRA_PE_DEBUG:
+ pep_dll_extra_pe_debug = 1;
+ break;
+#endif
+ }
+ return TRUE;
+}
+\f
+
+#ifdef DLL_SUPPORT
+static unsigned long
+strhash (const char *str)
+{
+ const unsigned char *s;
+ unsigned long hash;
+ unsigned int c;
+ unsigned int len;
+
+ hash = 0;
+ len = 0;
+ s = (const unsigned char *) str;
+ while ((c = *s++) != '\0')
+ {
+ hash += c + (c << 17);
+ hash ^= hash >> 2;
+ ++len;
+ }
+ hash += len + (len << 17);
+ hash ^= hash >> 2;
+
+ return hash;
+}
+
+/* Use the output file to create a image base for relocatable DLLs. */
+
+static unsigned long
+compute_dll_image_base (const char *ofile)
+{
+ unsigned long hash = strhash (ofile);
+ return 0x61300000 + ((hash << 16) & 0x0FFC0000);
+}
+#endif
+
+/* Assign values to the special symbols before the linker script is
+ read. */
+
+static void
+gld_${EMULATION_NAME}_set_symbols (void)
+{
+ /* Run through and invent symbols for all the
+ names and insert the defaults. */
+ int j;
+ lang_statement_list_type *save;
+
+ if (!init[IMAGEBASEOFF].inited)
+ {
+ if (link_info.relocatable)
+ init[IMAGEBASEOFF].value = 0;
+ else if (init[DLLOFF].value || (link_info.shared && !link_info.pie))
+#ifdef DLL_SUPPORT
+ init[IMAGEBASEOFF].value = (pep_enable_auto_image_base) ?
+ compute_dll_image_base (output_filename) : NT_DLL_IMAGE_BASE;
+#else
+ init[IMAGEBASEOFF].value = NT_DLL_IMAGE_BASE;
+#endif
+ else
+ init[IMAGEBASEOFF].value = NT_EXE_IMAGE_BASE;
+ init[MSIMAGEBASEOFF].value = init[IMAGEBASEOFF].value;
+ }
+
+ /* Don't do any symbol assignments if this is a relocatable link. */
+ if (link_info.relocatable)
+ return;
+
+ /* Glue the assignments into the abs section. */
+ save = stat_ptr;
+
+ stat_ptr = &(abs_output_section->children);
+
+ for (j = 0; init[j].ptr; j++)
+ {
+ long val = init[j].value;
+ lang_assignment_statement_type *rv;
+ rv = lang_add_assignment (exp_assop ('=', init[j].symbol,
+ exp_intop (val)));
+ if (init[j].size == sizeof (short))
+ *(short *) init[j].ptr = val;
+ else if (init[j].size == sizeof (int))
+ *(int *) init[j].ptr = val;
+ else if (init[j].size == sizeof (long))
+ *(long *) init[j].ptr = val;
+ /* This might be a long long or other special type. */
+ else if (init[j].size == sizeof (bfd_vma))
+ *(bfd_vma *) init[j].ptr = val;
+ else abort ();
+ if (j == IMAGEBASEOFF)
+ image_base_statement = rv;
+ }
+ /* Restore the pointer. */
+ stat_ptr = save;
+
+ if (pep.FileAlignment > pep.SectionAlignment)
+ {
+ einfo (_("%P: warning, file alignment > section alignment.\n"));
+ }
+}
+
+/* This is called after the linker script and the command line options
+ have been read. */
+
+static void
+gld_${EMULATION_NAME}_after_parse (void)
+{
+ /* The Windows libraries are designed for the linker to treat the
+ entry point as an undefined symbol. Otherwise, the .obj that
+ defines mainCRTStartup is brought in because it is the first
+ encountered in libc.lib and it has other symbols in it which will
+ be pulled in by the link process. To avoid this, we act as
+ though the user specified -u with the entry point symbol.
+
+ This function is called after the linker script and command line
+ options have been read, so at this point we know the right entry
+ point. This function is called before the input files are
+ opened, so registering the symbol as undefined will make a
+ difference. */
+
+ if (! link_info.relocatable && entry_symbol.name != NULL)
+ ldlang_add_undef (entry_symbol.name);
+}
+
+/* pep-dll.c directly accesses pep_data_import_dll,
+ so it must be defined outside of #ifdef DLL_SUPPORT.
+ Note - this variable is deliberately not initialised.
+ This allows it to be treated as a common varaible, and only
+ exist in one incarnation in a multiple target enabled linker. */
+char * pep_data_import_dll;
+
+#ifdef DLL_SUPPORT
+static struct bfd_link_hash_entry *pep_undef_found_sym;
+
+static bfd_boolean
+pep_undef_cdecl_match (struct bfd_link_hash_entry *h, void *inf)
+{
+ int sl;
+ char *string = inf;
+
+ sl = strlen (string);
+ if (h->type == bfd_link_hash_defined
+ && strncmp (h->root.string, string, sl) == 0
+ && h->root.string[sl] == '@')
+ {
+ pep_undef_found_sym = h;
+ return FALSE;
+ }
+ return TRUE;
+}
+
+static void
+pep_fixup_stdcalls (void)
+{
+ static int gave_warning_message = 0;
+ struct bfd_link_hash_entry *undef, *sym;
+
+ if (pep_dll_extra_pe_debug)
+ printf ("%s\n", __FUNCTION__);
+
+ for (undef = link_info.hash->undefs; undef; undef=undef->u.undef.next)
+ if (undef->type == bfd_link_hash_undefined)
+ {
+ char* at = strchr (undef->root.string, '@');
+ int lead_at = (*undef->root.string == '@');
+ /* For now, don't try to fixup fastcall symbols. */
+
+ if (at && !lead_at)
+ {
+ /* The symbol is a stdcall symbol, so let's look for a
+ cdecl symbol with the same name and resolve to that. */
+ char *cname = xstrdup (undef->root.string /* + lead_at */);
+ at = strchr (cname, '@');
+ *at = 0;
+ sym = bfd_link_hash_lookup (link_info.hash, cname, 0, 0, 1);
+
+ if (sym && sym->type == bfd_link_hash_defined)
+ {
+ undef->type = bfd_link_hash_defined;
+ undef->u.def.value = sym->u.def.value;
+ undef->u.def.section = sym->u.def.section;
+
+ if (pep_enable_stdcall_fixup == -1)
+ {
+ einfo (_("Warning: resolving %s by linking to %s\n"),
+ undef->root.string, cname);
+ if (! gave_warning_message)
+ {
+ gave_warning_message = 1;
+ einfo (_("Use --enable-stdcall-fixup to disable these warnings\n"));
+ einfo (_("Use --disable-stdcall-fixup to disable these fixups\n"));
+ }
+ }
+ }
+ }
+ else
+ {
+ /* The symbol is a cdecl symbol, so we look for stdcall
+ symbols - which means scanning the whole symbol table. */
+ pep_undef_found_sym = 0;
+ bfd_link_hash_traverse (link_info.hash, pep_undef_cdecl_match,
+ (char *) undef->root.string);
+ sym = pep_undef_found_sym;
+ if (sym)
+ {
+ undef->type = bfd_link_hash_defined;
+ undef->u.def.value = sym->u.def.value;
+ undef->u.def.section = sym->u.def.section;
+
+ if (pep_enable_stdcall_fixup == -1)
+ {
+ einfo (_("Warning: resolving %s by linking to %s\n"),
+ undef->root.string, sym->root.string);
+ if (! gave_warning_message)
+ {
+ gave_warning_message = 1;
+ einfo (_("Use --enable-stdcall-fixup to disable these warnings\n"));
+ einfo (_("Use --disable-stdcall-fixup to disable these fixups\n"));
+ }
+ }
+ }
+ }
+ }
+}
+
+static int
+make_import_fixup (arelent *rel, asection *s)
+{
+ struct bfd_symbol *sym = *rel->sym_ptr_ptr;
+ char addend[4];
+
+ if (pep_dll_extra_pe_debug)
+ printf ("arelent: %s@%#lx: add=%li\n", sym->name,
+ (long) rel->address, (long) rel->addend);
+
+ if (! bfd_get_section_contents (s->owner, s, addend, rel->address, sizeof (addend)))
+ einfo (_("%C: Cannot get section contents - auto-import exception\n"),
+ s->owner, s, rel->address);
+
+ pep_create_import_fixup (rel, s, bfd_get_32 (s->owner, addend));
+
+ return 1;
+}
+
+static void
+pep_find_data_imports (void)
+{
+ struct bfd_link_hash_entry *undef, *sym;
+
+ if (link_info.pei386_auto_import == 0)
+ return;
+
+ for (undef = link_info.hash->undefs; undef; undef=undef->u.undef.next)
+ {
+ if (undef->type == bfd_link_hash_undefined)
+ {
+ /* C++ symbols are *long*. */
+ char buf[4096];
+
+ if (pep_dll_extra_pe_debug)
+ printf ("%s:%s\n", __FUNCTION__, undef->root.string);
+
+ sprintf (buf, "__imp_%s", undef->root.string);
+
+ sym = bfd_link_hash_lookup (link_info.hash, buf, 0, 0, 1);
+
+ if (sym && sym->type == bfd_link_hash_defined)
+ {
+ bfd *b = sym->u.def.section->owner;
+ asymbol **symbols;
+ int nsyms, symsize, i;
+
+ if (link_info.pei386_auto_import == -1)
+ info_msg (_("Info: resolving %s by linking to %s (auto-import)\n"),
+ undef->root.string, buf);
+
+ symsize = bfd_get_symtab_upper_bound (b);
+ symbols = xmalloc (symsize);
+ nsyms = bfd_canonicalize_symtab (b, symbols);
+
+ for (i = 0; i < nsyms; i++)
+ {
+ if (! CONST_STRNEQ (symbols[i]->name, "__head_"))
+ continue;
+
+ if (pep_dll_extra_pe_debug)
+ printf ("->%s\n", symbols[i]->name);
+
+ pep_data_import_dll = (char*) (symbols[i]->name +
+ sizeof ("__head_") - 1);
+ break;
+ }
+
+ pep_walk_relocs_of_symbol (&link_info, undef->root.string,
+ make_import_fixup);
+
+ /* Let's differentiate it somehow from defined. */
+ undef->type = bfd_link_hash_defweak;
+ /* We replace original name with __imp_ prefixed, this
+ 1) may trash memory 2) leads to duplicate symbol generation.
+ Still, IMHO it's better than having name poluted. */
+ undef->root.string = sym->root.string;
+ undef->u.def.value = sym->u.def.value;
+ undef->u.def.section = sym->u.def.section;
+ }
+ }
+ }
+}
+
+static bfd_boolean
+pr_sym (struct bfd_hash_entry *h, void *inf ATTRIBUTE_UNUSED)
+{
+ if (pep_dll_extra_pe_debug)
+ printf ("+%s\n", h->string);
+
+ return TRUE;
+}
+#endif /* DLL_SUPPORT */
+
+
+static void
+gld_${EMULATION_NAME}_after_open (void)
+{
+#ifdef DLL_SUPPORT
+ if (pep_dll_extra_pe_debug)
+ {
+ bfd *a;
+ struct bfd_link_hash_entry *sym;
+
+ printf ("%s()\n", __FUNCTION__);
+
+ for (sym = link_info.hash->undefs; sym; sym=sym->u.undef.next)
+ printf ("-%s\n", sym->root.string);
+ bfd_hash_traverse (&link_info.hash->table, pr_sym, NULL);
+
+ for (a = link_info.input_bfds; a; a = a->link_next)
+ printf ("*%s\n",a->filename);
+ }
+#endif
+
+ /* Pass the wacky PE command line options into the output bfd.
+ FIXME: This should be done via a function, rather than by
+ including an internal BFD header. */
+
+ if (coff_data (output_bfd) == NULL || coff_data (output_bfd)->pe == 0)
+ einfo (_("%F%P: cannot perform PE operations on non PE output file '%B'.\n"), output_bfd);
+
+ pe_data (output_bfd)->pe_opthdr = pep;
+ pe_data (output_bfd)->dll = init[DLLOFF].value;
+ pe_data (output_bfd)->real_flags |= real_flags;
+
+#ifdef DLL_SUPPORT
+ if (pep_enable_stdcall_fixup) /* -1=warn or 1=disable */
+ pep_fixup_stdcalls ();
+
+ pep_process_import_defs (output_bfd, & link_info);
+
+ pep_find_data_imports ();
+
+#ifndef TARGET_IS_i386pep
+ if (link_info.shared)
+#else
+ if (!link_info.relocatable)
+#endif
+ pep_dll_build_sections (output_bfd, &link_info);
+
+#ifndef TARGET_IS_i386pep
+ else
+ pep_exe_build_sections (output_bfd, &link_info);
+#endif
+#endif /* DLL_SUPPORT */
+
+ {
+ /* This next chunk of code tries to detect the case where you have
+ two import libraries for the same DLL (specifically,
+ symbolically linking libm.a and libc.a in cygwin to
+ libcygwin.a). In those cases, it's possible for function
+ thunks from the second implib to be used but without the
+ head/tail objects, causing an improper import table. We detect
+ those cases and rename the "other" import libraries to match
+ the one the head/tail come from, so that the linker will sort
+ things nicely and produce a valid import table. */
+
+ LANG_FOR_EACH_INPUT_STATEMENT (is)
+ {
+ if (is->the_bfd->my_archive)
+ {
+ int idata2 = 0, reloc_count=0, is_imp = 0;
+ asection *sec;
+
+ /* See if this is an import library thunk. */
+ for (sec = is->the_bfd->sections; sec; sec = sec->next)
+ {
+ if (strcmp (sec->name, ".idata\$2") == 0)
+ idata2 = 1;
+ if (CONST_STRNEQ (sec->name, ".idata\$"))
+ is_imp = 1;
+ reloc_count += sec->reloc_count;
+ }
+
+ if (is_imp && !idata2 && reloc_count)
+ {
+ /* It is, look for the reference to head and see if it's
+ from our own library. */
+ for (sec = is->the_bfd->sections; sec; sec = sec->next)
+ {
+ int i;
+ long symsize;
+ long relsize;
+ asymbol **symbols;
+ arelent **relocs;
+ int nrelocs;
+
+ symsize = bfd_get_symtab_upper_bound (is->the_bfd);
+ if (symsize < 1)
+ break;
+ relsize = bfd_get_reloc_upper_bound (is->the_bfd, sec);
+ if (relsize < 1)
+ break;
+
+ symbols = xmalloc (symsize);
+ symsize = bfd_canonicalize_symtab (is->the_bfd, symbols);
+ if (symsize < 0)
+ {
+ einfo ("%X%P: unable to process symbols: %E");
+ return;
+ }
+
+ relocs = xmalloc ((size_t) relsize);
+ nrelocs = bfd_canonicalize_reloc (is->the_bfd, sec,
+ relocs, symbols);
+ if (nrelocs < 0)
+ {
+ free (relocs);
+ einfo ("%X%P: unable to process relocs: %E");
+ return;
+ }
+
+ for (i = 0; i < nrelocs; i++)
+ {
+ struct bfd_symbol *s;
+ struct bfd_link_hash_entry * blhe;
+ char *other_bfd_filename;
+ char *n;
+
+ s = (relocs[i]->sym_ptr_ptr)[0];
+
+ if (s->flags & BSF_LOCAL)
+ continue;
+
+ /* Thunk section with reloc to another bfd. */
+ blhe = bfd_link_hash_lookup (link_info.hash,
+ s->name,
+ FALSE, FALSE, TRUE);
+
+ if (blhe == NULL
+ || blhe->type != bfd_link_hash_defined)
+ continue;
+
+ other_bfd_filename
+ = blhe->u.def.section->owner->my_archive
+ ? bfd_get_filename (blhe->u.def.section->owner->my_archive)
+ : bfd_get_filename (blhe->u.def.section->owner);
+
+ if (strcmp (bfd_get_filename (is->the_bfd->my_archive),
+ other_bfd_filename) == 0)
+ continue;
+
+ /* Rename this implib to match the other one. */
+ n = xmalloc (strlen (other_bfd_filename) + 1);
+ strcpy (n, other_bfd_filename);
+ is->the_bfd->my_archive->filename = n;
+ }
+
+ free (relocs);
+ /* Note - we do not free the symbols,
+ they are now cached in the BFD. */
+ }
+ }
+ }
+ }
+ }
+
+ {
+ int is_ms_arch = 0;
+ bfd *cur_arch = 0;
+ lang_input_statement_type *is2;
+ lang_input_statement_type *is3;
+
+ /* Careful - this is a shell script. Watch those dollar signs! */
+ /* Microsoft import libraries have every member named the same,
+ and not in the right order for us to link them correctly. We
+ must detect these and rename the members so that they'll link
+ correctly. There are three types of objects: the head, the
+ thunks, and the sentinel(s). The head is easy; it's the one
+ with idata2. We assume that the sentinels won't have relocs,
+ and the thunks will. It's easier than checking the symbol
+ table for external references. */
+ LANG_FOR_EACH_INPUT_STATEMENT (is)
+ {
+ if (is->the_bfd->my_archive)
+ {
+ char *pnt;
+ bfd *arch = is->the_bfd->my_archive;
+
+ if (cur_arch != arch)
+ {
+ cur_arch = arch;
+ is_ms_arch = 1;
+
+ for (is3 = is;
+ is3 && is3->the_bfd->my_archive == arch;
+ is3 = (lang_input_statement_type *) is3->next)
+ {
+ /* A MS dynamic import library can also contain static
+ members, so look for the first element with a .dll
+ extension, and use that for the remainder of the
+ comparisons. */
+ pnt = strrchr (is3->the_bfd->filename, '.');
+ if (pnt != NULL && strcmp (pnt, ".dll") == 0)
+ break;
+ }
+
+ if (is3 == NULL)
+ is_ms_arch = 0;
+ else
+ {
+ /* OK, found one. Now look to see if the remaining
+ (dynamic import) members use the same name. */
+ for (is2 = is;
+ is2 && is2->the_bfd->my_archive == arch;
+ is2 = (lang_input_statement_type *) is2->next)
+ {
+ /* Skip static members, ie anything with a .obj
+ extension. */
+ pnt = strrchr (is2->the_bfd->filename, '.');
+ if (pnt != NULL && strcmp (pnt, ".obj") == 0)
+ continue;
+
+ if (strcmp (is3->the_bfd->filename,
+ is2->the_bfd->filename))
+ {
+ is_ms_arch = 0;
+ break;
+ }
+ }
+ }
+ }
+
+ /* This fragment might have come from an .obj file in a Microsoft
+ import, and not an actual import record. If this is the case,
+ then leave the filename alone. */
+ pnt = strrchr (is->the_bfd->filename, '.');
+
+ if (is_ms_arch && (strcmp (pnt, ".dll") == 0))
+ {
+ int idata2 = 0, reloc_count=0;
+ asection *sec;
+ char *new_name, seq;
+
+ for (sec = is->the_bfd->sections; sec; sec = sec->next)
+ {
+ if (strcmp (sec->name, ".idata\$2") == 0)
+ idata2 = 1;
+ reloc_count += sec->reloc_count;
+ }
+
+ if (idata2) /* .idata2 is the TOC */
+ seq = 'a';
+ else if (reloc_count > 0) /* thunks */
+ seq = 'b';
+ else /* sentinel */
+ seq = 'c';
+
+ new_name = xmalloc (strlen (is->the_bfd->filename) + 3);
+ sprintf (new_name, "%s.%c", is->the_bfd->filename, seq);
+ is->the_bfd->filename = new_name;
+
+ new_name = xmalloc (strlen (is->filename) + 3);
+ sprintf (new_name, "%s.%c", is->filename, seq);
+ is->filename = new_name;
+ }
+ }
+ }
+ }
+}
+\f
+static void
+gld_${EMULATION_NAME}_before_allocation (void)
+{
+ before_allocation_default ();
+}
+\f
+#ifdef DLL_SUPPORT
+/* This is called when an input file isn't recognized as a BFD. We
+ check here for .DEF files and pull them in automatically. */
+
+static int
+saw_option (char *option)
+{
+ int i;
+
+ for (i = 0; init[i].ptr; i++)
+ if (strcmp (init[i].symbol, option) == 0)
+ return init[i].inited;
+ return 0;
+}
+#endif /* DLL_SUPPORT */
+
+static bfd_boolean
+gld_${EMULATION_NAME}_unrecognized_file (lang_input_statement_type *entry ATTRIBUTE_UNUSED)
+{
+#ifdef DLL_SUPPORT
+ const char *ext = entry->filename + strlen (entry->filename) - 4;
+
+ if (strcmp (ext, ".def") == 0 || strcmp (ext, ".DEF") == 0)
+ {
+ pep_def_file = def_file_parse (entry->filename, pep_def_file);
+
+ if (pep_def_file)
+ {
+ int i, buflen=0, len;
+ char *buf;
+
+ for (i = 0; i < pep_def_file->num_exports; i++)
+ {
+ len = strlen (pep_def_file->exports[i].internal_name);
+ if (buflen < len + 2)
+ buflen = len + 2;
+ }
+
+ buf = xmalloc (buflen);
+
+ for (i = 0; i < pep_def_file->num_exports; i++)
+ {
+ struct bfd_link_hash_entry *h;
+
+ sprintf (buf, "_%s", pep_def_file->exports[i].internal_name);
+
+ h = bfd_link_hash_lookup (link_info.hash, buf, TRUE, TRUE, TRUE);
+ if (h == (struct bfd_link_hash_entry *) NULL)
+ einfo (_("%P%F: bfd_link_hash_lookup failed: %E\n"));
+ if (h->type == bfd_link_hash_new)
+ {
+ h->type = bfd_link_hash_undefined;
+ h->u.undef.abfd = NULL;
+ bfd_link_add_undef (link_info.hash, h);
+ }
+ }
+ free (buf);
+
+ /* def_file_print (stdout, pep_def_file); */
+ if (pep_def_file->is_dll == 1)
+ link_info.shared = 1;
+
+ if (pep_def_file->base_address != (bfd_vma)(-1))
+ {
+ pep.ImageBase =
+ pe_data (output_bfd)->pe_opthdr.ImageBase =
+ init[IMAGEBASEOFF].value = pep_def_file->base_address;
+ init[IMAGEBASEOFF].inited = 1;
+ if (image_base_statement)
+ image_base_statement->exp =
+ exp_assop ('=', "__image_base__", exp_intop (pep.ImageBase));
+ }
+
+ if (pep_def_file->stack_reserve != -1
+ && ! saw_option ("__size_of_stack_reserve__"))
+ {
+ pep.SizeOfStackReserve = pep_def_file->stack_reserve;
+ if (pep_def_file->stack_commit != -1)
+ pep.SizeOfStackCommit = pep_def_file->stack_commit;
+ }
+ if (pep_def_file->heap_reserve != -1
+ && ! saw_option ("__size_of_heap_reserve__"))
+ {
+ pep.SizeOfHeapReserve = pep_def_file->heap_reserve;
+ if (pep_def_file->heap_commit != -1)
+ pep.SizeOfHeapCommit = pep_def_file->heap_commit;
+ }
+ return TRUE;
+ }
+ }
+#endif
+ return FALSE;
+}
+
+static bfd_boolean
+gld_${EMULATION_NAME}_recognized_file (lang_input_statement_type *entry ATTRIBUTE_UNUSED)
+{
+#ifdef DLL_SUPPORT
+#ifdef TARGET_IS_i386pep
+ pep_dll_id_target ("pei-x86-64");
+#endif
+ if (bfd_get_format (entry->the_bfd) == bfd_object)
+ {
+ char fbuf[LD_PATHMAX + 1];
+ const char *ext;
+
+ if (REALPATH (entry->filename, fbuf) == NULL)
+ strncpy (fbuf, entry->filename, sizeof (fbuf));
+
+ ext = fbuf + strlen (fbuf) - 4;
+
+ if (strcmp (ext, ".dll") == 0 || strcmp (ext, ".DLL") == 0)
+ return pep_implied_import_dll (fbuf);
+ }
+#endif
+ return FALSE;
+}
+
+static void
+gld_${EMULATION_NAME}_finish (void)
+{
+ finish_default ();
+
+#ifdef DLL_SUPPORT
+ if (link_info.shared
+ || (!link_info.relocatable && pep_def_file->num_exports != 0))
+ {
+ pep_dll_fill_sections (output_bfd, &link_info);
+ if (pep_implib_filename)
+ pep_dll_generate_implib (pep_def_file, pep_implib_filename);
+ }
+
+ if (pep_out_def_filename)
+ pep_dll_generate_def_file (pep_out_def_filename);
+#endif /* DLL_SUPPORT */
+
+ /* I don't know where .idata gets set as code, but it shouldn't be. */
+ {
+ asection *asec = bfd_get_section_by_name (output_bfd, ".idata");
+
+ if (asec)
+ {
+ asec->flags &= ~SEC_CODE;
+ asec->flags |= SEC_DATA;
+ }
+ }
+}
+
+\f
+/* Place an orphan section.
+
+ We use this to put sections in a reasonable place in the file, and
+ to ensure that they are aligned as required.
+
+ We handle grouped sections here as well. A section named .foo$nn
+ goes into the output section .foo. All grouped sections are sorted
+ by name.
+
+ Grouped sections for the default sections are handled by the
+ default linker script using wildcards, and are sorted by
+ sort_sections. */
+
+static bfd_boolean
+gld_${EMULATION_NAME}_place_orphan (asection *s)
+{
+ const char *secname;
+ const char *orig_secname;
+ char *dollar = NULL;
+ lang_output_section_statement_type *os;
+ lang_statement_list_type add_child;
+
+ secname = bfd_get_section_name (s->owner, s);
+
+ /* Look through the script to see where to place this section. */
+ orig_secname = secname;
+ if (!link_info.relocatable
+ && (dollar = strchr (secname, '$')) != NULL)
+ {
+ size_t len = dollar - orig_secname;
+ char *newname = xmalloc (len + 1);
+ memcpy (newname, orig_secname, len);
+ newname[len] = '\0';
+ secname = newname;
+ }
+
+ os = lang_output_section_find (secname);
+
+ lang_list_init (&add_child);
+
+ if (os != NULL
+ && (os->bfd_section == NULL
+ || os->bfd_section->flags == 0
+ || ((s->flags ^ os->bfd_section->flags)
+ & (SEC_LOAD | SEC_ALLOC)) == 0))
+ {
+ /* We already have an output section statement with this
+ name, and its bfd section, if any, has compatible flags.
+ If the section already exists but does not have any flags set,
+ then it has been created by the linker, probably as a result of
+ a --section-start command line switch. */
+ lang_add_section (&add_child, s, os);
+ }
+ else
+ {
+ static struct orphan_save hold[] =
+ {
+ { ".text",
+ SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_CODE,
+ 0, 0, 0, 0 },
+ { ".rdata",
+ SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_DATA,
+ 0, 0, 0, 0 },
+ { ".data",
+ SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_DATA,
+ 0, 0, 0, 0 },
+ { ".bss",
+ SEC_ALLOC,
+ 0, 0, 0, 0 }
+ };
+ enum orphan_save_index
+ {
+ orphan_text = 0,
+ orphan_rodata,
+ orphan_data,
+ orphan_bss
+ };
+ static int orphan_init_done = 0;
+ struct orphan_save *place;
+ lang_output_section_statement_type *after;
+ etree_type *address;
+
+ if (!orphan_init_done)
+ {
+ struct orphan_save *ho;
+ for (ho = hold; ho < hold + sizeof (hold) / sizeof (hold[0]); ++ho)
+ if (ho->name != NULL)
+ {
+ ho->os = lang_output_section_find (ho->name);
+ if (ho->os != NULL && ho->os->flags == 0)
+ ho->os->flags = ho->flags;
+ }
+ orphan_init_done = 1;
+ }
+
+ /* Try to put the new output section in a reasonable place based
+ on the section name and section flags. */
+
+ place = NULL;
+ if ((s->flags & SEC_ALLOC) == 0)
+ ;
+ else if ((s->flags & (SEC_LOAD | SEC_HAS_CONTENTS)) == 0)
+ place = &hold[orphan_bss];
+ else if ((s->flags & SEC_READONLY) == 0)
+ place = &hold[orphan_data];
+ else if ((s->flags & SEC_CODE) == 0)
+ place = &hold[orphan_rodata];
+ else
+ place = &hold[orphan_text];
+
+ after = NULL;
+ if (place != NULL)
+ {
+ if (place->os == NULL)
+ place->os = lang_output_section_find (place->name);
+ after = place->os;
+ if (after == NULL)
+ after = lang_output_section_find_by_flags (s, &place->os, NULL);
+ if (after == NULL)
+ /* *ABS* is always the first output section statement. */
+ after = (&lang_output_section_statement.head
+ ->output_section_statement);
+ }
+
+ /* Choose a unique name for the section. This will be needed if the
+ same section name appears in the input file with different
+ loadable or allocatable characteristics. */
+ if (bfd_get_section_by_name (output_bfd, secname) != NULL)
+ {
+ static int count = 1;
+ secname = bfd_get_unique_section_name (output_bfd, secname, &count);
+ if (secname == NULL)
+ einfo ("%F%P: place_orphan failed: %E\n");
+ }
+
+ /* All sections in an executable must be aligned to a page boundary. */
+ address = exp_unop (ALIGN_K, exp_nameop (NAME, "__section_alignment__"));
+ os = lang_insert_orphan (s, secname, after, place, address, &add_child);
+ }
+
+ {
+ lang_statement_union_type **pl = &os->children.head;
+
+ if (dollar != NULL)
+ {
+ bfd_boolean found_dollar;
+
+ /* The section name has a '$'. Sort it with the other '$'
+ sections. */
+ found_dollar = FALSE;
+ for ( ; *pl != NULL; pl = &(*pl)->header.next)
+ {
+ lang_input_section_type *ls;
+ const char *lname;
+
+ if ((*pl)->header.type != lang_input_section_enum)
+ continue;
+
+ ls = &(*pl)->input_section;
+
+ lname = bfd_get_section_name (ls->section->owner, ls->section);
+ if (strchr (lname, '$') == NULL)
+ {
+ if (found_dollar)
+ break;
+ }
+ else
+ {
+ found_dollar = TRUE;
+ if (strcmp (orig_secname, lname) < 0)
+ break;
+ }
+ }
+ }
+
+ if (add_child.head != NULL)
+ {
+ add_child.head->header.next = *pl;
+ *pl = add_child.head;
+ }
+ }
+
+ return TRUE;
+}
+
+static bfd_boolean
+gld_${EMULATION_NAME}_open_dynamic_archive
+ (const char *arch ATTRIBUTE_UNUSED,
+ search_dirs_type *search,
+ lang_input_statement_type *entry)
+{
+ static const struct
+ {
+ const char * format;
+ bfd_boolean use_prefix;
+ }
+ libname_fmt [] =
+ {
+ /* Preferred explicit import library for dll's. */
+ { "lib%s.dll.a", FALSE },
+ /* Alternate explicit import library for dll's. */
+ { "%s.dll.a", FALSE },
+ /* "libfoo.a" could be either an import lib or a static lib.
+ For backwards compatibility, libfoo.a needs to precede
+ libfoo.dll and foo.dll in the search. */
+ { "lib%s.a", FALSE },
+ /* The 'native' spelling of an import lib name is "foo.lib". */
+ { "%s.lib", FALSE },
+#ifdef DLL_SUPPORT
+ /* Try "<prefix>foo.dll" (preferred dll name, if specified). */
+ { "%s%s.dll", TRUE },
+#endif
+ /* Try "libfoo.dll" (default preferred dll name). */
+ { "lib%s.dll", FALSE },
+ /* Finally try 'native' dll name "foo.dll". */
+ { "%s.dll", FALSE },
+ /* Note: If adding more formats to this table, make sure to check to
+ see if their length is longer than libname_fmt[0].format, and if
+ so, update the call to xmalloc() below. */
+ { NULL, FALSE }
+ };
+ static unsigned int format_max_len = 0;
+ const char * filename;
+ char * full_string;
+ char * base_string;
+ unsigned int i;
+
+
+ if (! entry->is_archive)
+ return FALSE;
+
+ filename = entry->filename;
+
+ if (format_max_len == 0)
+ /* We need to allow space in the memory that we are going to allocate
+ for the characters in the format string. Since the format array is
+ static we only need to calculate this information once. In theory
+ this value could also be computed statically, but this introduces
+ the possibility for a discrepancy and hence a possible memory
+ corruption. The lengths we compute here will be too long because
+ they will include any formating characters (%s) in the strings, but
+ this will not matter. */
+ for (i = 0; libname_fmt[i].format; i++)
+ if (format_max_len < strlen (libname_fmt[i].format))
+ format_max_len = strlen (libname_fmt[i].format);
+
+ full_string = xmalloc (strlen (search->name)
+ + strlen (filename)
+ + format_max_len
+#ifdef DLL_SUPPORT
+ + (pep_dll_search_prefix
+ ? strlen (pep_dll_search_prefix) : 0)
+#endif
+ /* Allow for the terminating NUL and for the path
+ separator character that is inserted between
+ search->name and the start of the format string. */
+ + 2);
+
+ sprintf (full_string, "%s/", search->name);
+ base_string = full_string + strlen (full_string);
+
+ for (i = 0; libname_fmt[i].format; i++)
+ {
+#ifdef DLL_SUPPORT
+ if (libname_fmt[i].use_prefix)
+ {
+ if (!pep_dll_search_prefix)
+ continue;
+ sprintf (base_string, libname_fmt[i].format, pep_dll_search_prefix, filename);
+ }
+ else
+#endif
+ sprintf (base_string, libname_fmt[i].format, filename);
+
+ if (ldfile_try_open_bfd (full_string, entry))
+ break;
+ }
+
+ if (!libname_fmt[i].format)
+ {
+ free (full_string);
+ return FALSE;
+ }
+
+ entry->filename = full_string;
+
+ return TRUE;
+}
+
+static int
+gld_${EMULATION_NAME}_find_potential_libraries
+ (char *name, lang_input_statement_type *entry)
+{
+ return ldfile_open_file_search (name, entry, "", ".lib");
+}
+\f
+static char *
+gld_${EMULATION_NAME}_get_script (int *isfile)
+EOF
+# Scripts compiled in.
+# sed commands to quote an ld script as a C string.
+sc="-f stringify.sed"
+
+cat >>e${EMULATION_NAME}.c <<EOF
+{
+ *isfile = 0;
+
+ if (link_info.relocatable && config.build_constructors)
+ return
+EOF
+sed $sc ldscripts/${EMULATION_NAME}.xu >> e${EMULATION_NAME}.c
+echo ' ; else if (link_info.relocatable) return' >> e${EMULATION_NAME}.c
+sed $sc ldscripts/${EMULATION_NAME}.xr >> e${EMULATION_NAME}.c
+echo ' ; else if (!config.text_read_only) return' >> e${EMULATION_NAME}.c
+sed $sc ldscripts/${EMULATION_NAME}.xbn >> e${EMULATION_NAME}.c
+echo ' ; else if (!config.magic_demand_paged) return' >> e${EMULATION_NAME}.c
+sed $sc ldscripts/${EMULATION_NAME}.xn >> e${EMULATION_NAME}.c
+echo ' ; else return' >> e${EMULATION_NAME}.c
+sed $sc ldscripts/${EMULATION_NAME}.x >> e${EMULATION_NAME}.c
+echo '; }' >> e${EMULATION_NAME}.c
+
+cat >>e${EMULATION_NAME}.c <<EOF
+
+
+struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation =
+{
+ gld_${EMULATION_NAME}_before_parse,
+ syslib_default,
+ hll_default,
+ gld_${EMULATION_NAME}_after_parse,
+ gld_${EMULATION_NAME}_after_open,
+ after_allocation_default,
+ set_output_arch_default,
+ ldemul_default_target,
+ gld_${EMULATION_NAME}_before_allocation,
+ gld_${EMULATION_NAME}_get_script,
+ "${EMULATION_NAME}",
+ "${OUTPUT_FORMAT}",
+ gld_${EMULATION_NAME}_finish,
+ NULL, /* Create output section statements. */
+ gld_${EMULATION_NAME}_open_dynamic_archive,
+ gld_${EMULATION_NAME}_place_orphan,
+ gld_${EMULATION_NAME}_set_symbols,
+ NULL, /* parse_args */
+ gld${EMULATION_NAME}_add_options,
+ gld${EMULATION_NAME}_handle_option,
+ gld_${EMULATION_NAME}_unrecognized_file,
+ gld_${EMULATION_NAME}_list_options,
+ gld_${EMULATION_NAME}_recognized_file,
+ gld_${EMULATION_NAME}_find_potential_libraries,
+ NULL /* new_vers_pattern. */
+};
+EOF
#include "coff/internal.h"
#include "../bfd/libcoff.h"
#include "deffile.h"
+
+#ifdef pe_use_x86_64
+
+#define PE_IDATA4_SIZE 8
+#define PE_IDATA5_SIZE 8
+#include "pep-dll.h"
+#undef AOUTSZ
+#define AOUTSZ PEPAOUTSZ
+#define PEAOUTHDR PEPAOUTHDR
+
+#else
+
#include "pe-dll.h"
+#endif
+
+#ifndef PE_IDATA4_SIZE
+#define PE_IDATA4_SIZE 4
+#endif
+
+#ifndef PE_IDATA5_SIZE
+#define PE_IDATA5_SIZE 4
+#endif
+
/* This file turns a regular Windows PE image into a DLL. Because of
the complexity of this operation, it has been broken down into a
number of separate modules which are all called by the main function
normally only called once, so static variables are used to reduce
the number of parameters and return values required.
- See also: ld/emultempl/pe.em. */
+ See also: ld/emultempl/pe.em and ld/emultempl/pep.em. */
/* Auto-import feature by Paul Sokolovsky
not, prohibiting that (detecting violation) would require more work on
behalf of loader than not doing it.
- See also: ld/emultempl/pe.em. */
+ See also: ld/emultempl/pe.em and ld/emultempl/pep.em. */
static void add_bfd_to_link (bfd *, const char *, struct bfd_link_info *);
static pe_details_type pe_detail_list[] =
{
{
+#ifdef pe_use_x86_64
+ "pei-x86-64",
+ "pe-x86-64",
+ 3 /* R_IMAGEBASE */,
+#else
"pei-i386",
"pe-i386",
7 /* R_IMAGEBASE */,
+#endif
PE_ARCH_i386,
bfd_arch_i386,
TRUE,
it is too restrictive. Instead we have
a target specific list to use: */
afptr = pe_details->autofilter_symbollist;
+
while (afptr->name)
{
if (strcmp (n, afptr->name) == 0)
switch BITS_AND_SHIFT (relocs[i]->howto->bitsize,
relocs[i]->howto->rightshift)
{
+#ifdef pe_use_x86_64
+ case BITS_AND_SHIFT (64, 0):
+ reloc_data[total_relocs].type = 10;
+ total_relocs++;
+ break;
+#endif
case BITS_AND_SHIFT (32, 0):
reloc_data[total_relocs].type = 3;
total_relocs++;
quick_reloc (abfd, 16, BFD_RELOC_RVA, 1);
save_relocs (id2);
- bfd_set_section_size (abfd, id5, 4);
- d5 = xmalloc (4);
+ bfd_set_section_size (abfd, id5, PE_IDATA5_SIZE);
+ d5 = xmalloc (PE_IDATA5_SIZE);
id5->contents = d5;
- memset (d5, 0, 4);
+ memset (d5, 0, PE_IDATA5_SIZE);
- bfd_set_section_size (abfd, id4, 4);
- d4 = xmalloc (4);
+ bfd_set_section_size (abfd, id4, PE_IDATA4_SIZE);
+ d4 = xmalloc (PE_IDATA4_SIZE);
id4->contents = d4;
- memset (d4, 0, 4);
+ memset (d4, 0, PE_IDATA4_SIZE);
bfd_set_symtab (abfd, symtab, symptr);
bfd_set_section_contents (abfd, id2, d2, 0, 20);
- bfd_set_section_contents (abfd, id5, d5, 0, 4);
- bfd_set_section_contents (abfd, id4, d4, 0, 4);
+ bfd_set_section_contents (abfd, id5, d5, 0, PE_IDATA5_SIZE);
+ bfd_set_section_contents (abfd, id4, d4, 0, PE_IDATA4_SIZE);
bfd_make_readable (abfd);
return abfd;
/* .section .idata$4
.long 0
+ [.long 0] for PE+
.section .idata$5
.long 0
+ [.long 0] for PE+
.section idata$7
.global __my_dll_iname
__my_dll_iname:
id7 = quick_section (abfd, ".idata$7", SEC_HAS_CONTENTS, 2);
quick_symbol (abfd, U (""), dll_symname, "_iname", id7, BSF_GLOBAL, 0);
- bfd_set_section_size (abfd, id4, 4);
- d4 = xmalloc (4);
+ bfd_set_section_size (abfd, id4, PE_IDATA4_SIZE);
+ d4 = xmalloc (PE_IDATA4_SIZE);
id4->contents = d4;
- memset (d4, 0, 4);
+ memset (d4, 0, PE_IDATA4_SIZE);
- bfd_set_section_size (abfd, id5, 4);
- d5 = xmalloc (4);
+ bfd_set_section_size (abfd, id5, PE_IDATA5_SIZE);
+ d5 = xmalloc (PE_IDATA5_SIZE);
id5->contents = d5;
- memset (d5, 0, 4);
+ memset (d5, 0, PE_IDATA5_SIZE);
len = strlen (dll_filename) + 1;
if (len & 1)
bfd_set_symtab (abfd, symtab, symptr);
- bfd_set_section_contents (abfd, id4, d4, 0, 4);
- bfd_set_section_contents (abfd, id5, d5, 0, 4);
+ bfd_set_section_contents (abfd, id4, d4, 0, PE_IDATA4_SIZE);
+ bfd_set_section_contents (abfd, id5, d5, 0, PE_IDATA5_SIZE);
bfd_set_section_contents (abfd, id7, d7, 0, len);
bfd_make_readable (abfd);
quick_reloc (abfd, 0, BFD_RELOC_RVA, 5);
save_relocs (id7);
- bfd_set_section_size (abfd, id5, 4);
- d5 = xmalloc (4);
+ bfd_set_section_size (abfd, id5, PE_IDATA5_SIZE);
+ d5 = xmalloc (PE_IDATA5_SIZE);
id5->contents = d5;
- memset (d5, 0, 4);
+ memset (d5, 0, PE_IDATA5_SIZE);
if (exp->flag_noname)
{
d5[0] = exp->ordinal;
d5[1] = exp->ordinal >> 8;
- d5[3] = 0x80;
+ d5[PE_IDATA5_SIZE - 1] = 0x80;
}
else
{
save_relocs (id5);
}
- bfd_set_section_size (abfd, id4, 4);
- d4 = xmalloc (4);
+ bfd_set_section_size (abfd, id4, PE_IDATA4_SIZE);
+ d4 = xmalloc (PE_IDATA4_SIZE);
id4->contents = d4;
- memset (d4, 0, 4);
+ memset (d4, 0, PE_IDATA4_SIZE);
if (exp->flag_noname)
{
d4[0] = exp->ordinal;
d4[1] = exp->ordinal >> 8;
- d4[3] = 0x80;
+ d4[PE_IDATA4_SIZE - 1] = 0x80;
}
else
{
bfd_set_section_contents (abfd, tx, td, 0, jmp_byte_count);
bfd_set_section_contents (abfd, id7, d7, 0, 4);
- bfd_set_section_contents (abfd, id5, d5, 0, 4);
- bfd_set_section_contents (abfd, id4, d4, 0, 4);
+ bfd_set_section_contents (abfd, id5, d5, 0, PE_IDATA5_SIZE);
+ bfd_set_section_contents (abfd, id4, d4, 0, PE_IDATA4_SIZE);
if (!exp->flag_noname)
bfd_set_section_contents (abfd, id6, d6, 0, len);
quick_symbol (abfd, U ("_nm_thnk_"), import, "", id4, BSF_GLOBAL, 0);
quick_symbol (abfd, U ("_nm_"), import, "", UNDSEC, BSF_GLOBAL, 0);
- bfd_set_section_size (abfd, id4, 8);
- d4 = xmalloc (4);
+ bfd_set_section_size (abfd, id4, PE_IDATA4_SIZE);
+ d4 = xmalloc (PE_IDATA4_SIZE);
id4->contents = d4;
- memset (d4, 0, 8);
+ memset (d4, 0, PE_IDATA4_SIZE);
quick_reloc (abfd, 0, BFD_RELOC_RVA, 2);
save_relocs (id4);
bfd_set_symtab (abfd, symtab, symptr);
- bfd_set_section_contents (abfd, id4, d4, 0, 8);
+ bfd_set_section_contents (abfd, id4, d4, 0, PE_IDATA4_SIZE);
bfd_make_readable (abfd);
return abfd;
current_sec, /* sym->section, */
rel->address, NULL, TRUE, FALSE, &bh);
- if (0)
- {
- struct coff_link_hash_entry *myh;
-
- myh = (struct coff_link_hash_entry *) bh;
- printf ("type:%d\n", myh->type);
- printf ("%s\n", myh->root.u.def.section->name);
- }
-
return fixup_name;
}
/* Get pe_header, optional header and numbers of export entries. */
pe_header_offset = pe_get32 (dll, 0x3c);
opthdr_ofs = pe_header_offset + 4 + 20;
+#ifdef pe_use_x86_64
+ num_entries = pe_get32 (dll, opthdr_ofs + 92 + 4 * 4); /* & NumberOfRvaAndSizes. */
+#else
num_entries = pe_get32 (dll, opthdr_ofs + 92);
+#endif
if (num_entries < 1) /* No exports. */
return FALSE;
+#ifdef pe_use_x86_64
+ export_rva = pe_get32 (dll, opthdr_ofs + 96 + 4 * 4);
+ export_size = pe_get32 (dll, opthdr_ofs + 100 + 4 * 4);
+#else
export_rva = pe_get32 (dll, opthdr_ofs + 96);
export_size = pe_get32 (dll, opthdr_ofs + 100);
+#endif
+
nsections = pe_get16 (dll, pe_header_offset + 4 + 2);
secptr = (pe_header_offset + 4 + 20 +
pe_get16 (dll, pe_header_offset + 4 + 16));
--- /dev/null
+/* Routines to help build PEPI-format DLLs (Win64 etc)
+ Copyright 2006 Free Software Foundation, Inc.
+
+ This file is part of BFD, the Binary File Descriptor library.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
+
+ Written by Kai Tietz, OneVision Software GmbH&CoKg. */
+
+#define COFF_IMAGE_WITH_PE
+#define COFF_WITH_PE
+#define COFF_WITH_pex64
+
+/* Local defined globals. */
+#define pe_def_file pep_def_file
+#define pe_details pep_details
+#define pe_dll_compat_implib pep_dll_compat_implib
+#define pe_dll_extra_pe_debug pep_dll_extra_pe_debug
+#define pe_dll_export_everything pep_dll_export_everything
+#define pe_dll_do_default_excludes pep_dll_do_default_excludes
+#define pe_dll_kill_ats pep_dll_kill_ats
+#define pe_dll_stdcall_aliases pep_dll_stdcall_aliases
+#define pe_dll_warn_dup_exports pep_dll_warn_dup_exports
+
+/* External globals. */
+#define pe_data_import_dll pep_data_import_dll
+
+/* Unique global name for functions to avoid double defined symbols. */
+#define pe_create_import_fixup pep_create_import_fixup
+#define pe_dll_generate_def_file pep_dll_generate_def_file
+#define pe_process_import_defs pep_process_import_defs
+#define pe_dll_id_target pep_dll_id_target
+#define pe_implied_import_dll pep_implied_import_dll
+#define pe_dll_build_sections pep_dll_build_sections
+#define pe_exe_build_sections pep_exe_build_sections
+#define pe_dll_fill_sections pep_dll_fill_sections
+#define pe_exe_fill_sections pep_exe_fill_sections
+#define pe_dll_generate_implib pep_dll_generate_implib
+#define pe_dll_add_excludes pep_dll_add_excludes
+#define pe_walk_relocs_of_symbol pep_walk_relocs_of_symbol
+
+/* Uses x86_64 PE+. */
+#define pe_use_x86_64
+
+#include "pe-dll.c"
--- /dev/null
+/* pep-dll.h: Header file for routines used to build Windows DLLs.
+ Copyright 2006 Free Software Foundation, Inc.
+
+ This file is part of BFD, the Binary File Descriptor library.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
+
+ Written by Kai Tietz, OneVision Software GmbH&CoKg. */
+
+#ifndef PEP_DLL_H
+#define PEP_DLL_H
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "bfdlink.h"
+#include "deffile.h"
+
+extern def_file * pep_def_file;
+extern int pep_dll_export_everything;
+extern int pep_dll_do_default_excludes;
+extern int pep_dll_kill_ats;
+extern int pep_dll_stdcall_aliases;
+extern int pep_dll_warn_dup_exports;
+extern int pep_dll_compat_implib;
+extern int pep_dll_extra_pe_debug;
+
+extern void pep_dll_id_target (const char *);
+extern void pep_dll_add_excludes (const char *, const int);
+extern void pep_dll_generate_def_file (const char *);
+extern void pep_dll_generate_implib (def_file *, const char *);
+extern void pep_process_import_defs (bfd *, struct bfd_link_info *);
+extern bfd_boolean pep_implied_import_dll (const char *);
+extern void pep_dll_build_sections (bfd *, struct bfd_link_info *);
+extern void pep_exe_build_sections (bfd *, struct bfd_link_info *);
+extern void pep_dll_fill_sections (bfd *, struct bfd_link_info *);
+extern void pep_exe_fill_sections (bfd *, struct bfd_link_info *);
+extern void pep_walk_relocs_of_symbol
+ (struct bfd_link_info *, const char *, int (*) (arelent *, asection *));
+extern void pep_create_import_fixup (arelent * rel, asection *, int);
+
+#endif /* PEP_DLL_H */
mri.h
pe-dll.c
pe-dll.h
+pep-dll.c
+pep-dll.h
--- /dev/null
+# Linker script for PE.
+
+if test -z "${RELOCATEABLE_OUTPUT_FORMAT}"; then
+ RELOCATEABLE_OUTPUT_FORMAT=${OUTPUT_FORMAT}
+fi
+
+# We can't easily and portably get an unquoted $ in a shell
+# substitution, so we do this instead.
+# Sorting of the .foo$* sections is required by the definition of
+# grouped sections in PE.
+# Sorting of the file names in R_IDATA is required by the
+# current implementation of dlltool (this could probably be changed to
+# use grouped sections instead).
+if test "${RELOCATING}"; then
+ R_TEXT='*(SORT(.text$*))'
+ R_DATA='*(SORT(.data$*))'
+ R_RDATA='*(SORT(.rdata$*))'
+ R_IDATA='
+ SORT(*)(.idata$2)
+ SORT(*)(.idata$3)
+ /* These zeroes mark the end of the import list. */
+ LONG (0); LONG (0); LONG (0); LONG (0); LONG (0);
+ SORT(*)(.idata$4)
+ SORT(*)(.idata$5)
+ SORT(*)(.idata$6)
+ SORT(*)(.idata$7)'
+ R_CRT_XC='*(SORT(.CRT$XC*)) /* C initialization */'
+ R_CRT_XI='*(SORT(.CRT$XI*)) /* C++ initialization */'
+ R_CRT_XL='*(SORT(.CRT$XL*)) /* TLS callbacks */'
+ R_CRT_XP='*(SORT(.CRT$XP*)) /* Pre-termination */'
+ R_CRT_XT='*(SORT(.CRT$XT*)) /* Termination */'
+ R_TLS='
+ *(.tls)
+ *(.tls$)
+ *(SORT(.tls$*))'
+ R_RSRC='*(SORT(.rsrc$*))'
+else
+ R_TEXT=
+ R_DATA=
+ R_RDATA=
+ R_IDATA=
+ R_CRT=
+ R_RSRC=
+fi
+
+cat <<EOF
+${RELOCATING+OUTPUT_FORMAT(${OUTPUT_FORMAT})}
+${RELOCATING-OUTPUT_FORMAT(${RELOCATEABLE_OUTPUT_FORMAT})}
+${OUTPUT_ARCH+OUTPUT_ARCH(${OUTPUT_ARCH})}
+
+${LIB_SEARCH_DIRS}
+
+SECTIONS
+{
+ ${RELOCATING+/* Make the virtual address and file offset synced if the alignment is}
+ ${RELOCATING+ lower than the target page size. */}
+ ${RELOCATING+. = SIZEOF_HEADERS;}
+ ${RELOCATING+. = ALIGN(__section_alignment__);}
+ .text ${RELOCATING+ __image_base__ + ( __section_alignment__ < ${TARGET_PAGE_SIZE} ? . : __section_alignment__ )} :
+ {
+ ${RELOCATING+ *(.init)}
+ *(.text)
+ ${R_TEXT}
+ *(.glue_7t)
+ *(.glue_7)
+ ${CONSTRUCTING+ ___CTOR_LIST__ = .; __CTOR_LIST__ = . ;
+ LONG (-1);*(.ctors); *(.ctor); *(SORT(.ctors.*)); LONG (0); }
+ ${CONSTRUCTING+ ___DTOR_LIST__ = .; __DTOR_LIST__ = . ;
+ LONG (-1); *(.dtors); *(.dtor); *(SORT(.dtors.*)); LONG (0); }
+ ${RELOCATING+ *(.fini)}
+ /* ??? Why is .gcc_exc here? */
+ ${RELOCATING+ *(.gcc_exc)}
+ ${RELOCATING+PROVIDE (etext = .);}
+ *(.gcc_except_table)
+ }
+
+ /* The Cygwin32 library uses a section to avoid copying certain data
+ on fork. This used to be named ".data$nocopy". The linker used
+ to include this between __data_start__ and __data_end__, but that
+ breaks building the cygwin32 dll. Instead, we name the section
+ ".data_cygwin_nocopy" and explictly include it after __data_end__. */
+
+ .data ${RELOCATING+BLOCK(__section_alignment__)} :
+ {
+ ${RELOCATING+__data_start__ = . ;}
+ *(.data)
+ *(.data2)
+ ${R_DATA}
+ *(.jcr)
+ ${RELOCATING+__data_end__ = . ;}
+ ${RELOCATING+*(.data_cygwin_nocopy)}
+ }
+
+ .rdata ${RELOCATING+BLOCK(__section_alignment__)} :
+ {
+ *(.rdata)
+ ${R_RDATA}
+ *(.eh_frame)
+ ${RELOCATING+___RUNTIME_PSEUDO_RELOC_LIST__ = .;}
+ ${RELOCATING+__RUNTIME_PSEUDO_RELOC_LIST__ = .;}
+ *(.rdata_runtime_pseudo_reloc)
+ ${RELOCATING+___RUNTIME_PSEUDO_RELOC_LIST_END__ = .;}
+ ${RELOCATING+__RUNTIME_PSEUDO_RELOC_LIST_END__ = .;}
+ }
+
+ .pdata ${RELOCATING+BLOCK(__section_alignment__)} :
+ {
+ *(.pdata)
+ }
+
+ .bss ${RELOCATING+BLOCK(__section_alignment__)} :
+ {
+ ${RELOCATING+__bss_start__ = . ;}
+ *(.bss)
+ *(COMMON)
+ ${RELOCATING+__bss_end__ = . ;}
+ }
+
+ .edata ${RELOCATING+BLOCK(__section_alignment__)} :
+ {
+ *(.edata)
+ }
+
+ /DISCARD/ :
+ {
+ *(.debug\$S)
+ *(.debug\$T)
+ *(.debug\$F)
+ *(.drectve)
+ }
+
+ .idata ${RELOCATING+BLOCK(__section_alignment__)} :
+ {
+ /* This cannot currently be handled with grouped sections.
+ See pep.em:sort_sections. */
+ ${R_IDATA}
+ }
+ .CRT ${RELOCATING+BLOCK(__section_alignment__)} :
+ {
+ ${RELOCATING+___crt_xc_start__ = . ;}
+ ${R_CRT_XC}
+ ${RELOCATING+___crt_xc_end__ = . ;}
+ ${RELOCATING+___crt_xi_start__ = . ;}
+ ${R_CRT_XI}
+ ${RELOCATING+___crt_xi_end__ = . ;}
+ ${RELOCATING+___crt_xl_start__ = . ;}
+ ${R_CRT_XL}
+ /* ___crt_xl_end__ is defined in the TLS Directory support code */
+ ${RELOCATING+___crt_xp_start__ = . ;}
+ ${R_CRT_XP}
+ ${RELOCATING+___crt_xp_end__ = . ;}
+ ${RELOCATING+___crt_xt_start__ = . ;}
+ ${R_CRT_XT}
+ ${RELOCATING+___crt_xt_end__ = . ;}
+ }
+
+ .tls ${RELOCATING+BLOCK(__section_alignment__)} :
+ {
+ ${RELOCATING+___tls_start__ = . ;}
+ ${R_TLS}
+ ${RELOCATING+___tls_end__ = . ;}
+ }
+
+ .endjunk ${RELOCATING+BLOCK(__section_alignment__)} :
+ {
+ /* end is deprecated, don't use it */
+ ${RELOCATING+PROVIDE (end = .);}
+ ${RELOCATING+PROVIDE ( _end = .);}
+ ${RELOCATING+ __end__ = .;}
+ }
+
+ .rsrc ${RELOCATING+BLOCK(__section_alignment__)} :
+ {
+ *(.rsrc)
+ ${R_RSRC}
+ }
+
+ .reloc ${RELOCATING+BLOCK(__section_alignment__)} :
+ {
+ *(.reloc)
+ }
+
+ .stab ${RELOCATING+BLOCK(__section_alignment__)} ${RELOCATING+(NOLOAD)} :
+ {
+ *(.stab)
+ }
+
+ .stabstr ${RELOCATING+BLOCK(__section_alignment__)} ${RELOCATING+(NOLOAD)} :
+ {
+ *(.stabstr)
+ }
+
+ /* DWARF debug sections.
+ Symbols in the DWARF debugging sections are relative to the beginning
+ of the section. Unlike other targets that fake this by putting the
+ section VMA at 0, the PE format will not allow it. */
+
+ /* DWARF 1.1 and DWARF 2. */
+ .debug_aranges ${RELOCATING+BLOCK(__section_alignment__)} ${RELOCATING+(NOLOAD)} :
+ {
+ *(.debug_aranges)
+ }
+
+ .debug_pubnames ${RELOCATING+BLOCK(__section_alignment__)} ${RELOCATING+(NOLOAD)} :
+ {
+ *(.debug_pubnames)
+ }
+
+ /* DWARF 2. */
+ .debug_info ${RELOCATING+BLOCK(__section_alignment__)} ${RELOCATING+(NOLOAD)} :
+ {
+ *(.debug_info) *(.gnu.linkonce.wi.*)
+ }
+
+ .debug_abbrev ${RELOCATING+BLOCK(__section_alignment__)} ${RELOCATING+(NOLOAD)} :
+ {
+ *(.debug_abbrev)
+ }
+
+ .debug_line ${RELOCATING+BLOCK(__section_alignment__)} ${RELOCATING+(NOLOAD)} :
+ {
+ *(.debug_line)
+ }
+
+ .debug_frame ${RELOCATING+BLOCK(__section_alignment__)} ${RELOCATING+(NOLOAD)} :
+ {
+ *(.debug_frame)
+ }
+
+ .debug_str ${RELOCATING+BLOCK(__section_alignment__)} ${RELOCATING+(NOLOAD)} :
+ {
+ *(.debug_str)
+ }
+
+ .debug_loc ${RELOCATING+BLOCK(__section_alignment__)} ${RELOCATING+(NOLOAD)} :
+ {
+ *(.debug_loc)
+ }
+
+ .debug_macinfo ${RELOCATING+BLOCK(__section_alignment__)} ${RELOCATING+(NOLOAD)} :
+ {
+ *(.debug_macinfo)
+ }
+
+ /* SGI/MIPS DWARF 2 extensions. */
+ .debug_weaknames ${RELOCATING+BLOCK(__section_alignment__)} ${RELOCATING+(NOLOAD)} :
+ {
+ *(.debug_weaknames)
+ }
+
+ .debug_funcnames ${RELOCATING+BLOCK(__section_alignment__)} ${RELOCATING+(NOLOAD)} :
+ {
+ *(.debug_funcnames)
+ }
+
+ .debug_typenames ${RELOCATING+BLOCK(__section_alignment__)} ${RELOCATING+(NOLOAD)} :
+ {
+ *(.debug_typenames)
+ }
+
+ .debug_varnames ${RELOCATING+BLOCK(__section_alignment__)} ${RELOCATING+(NOLOAD)} :
+ {
+ *(.debug_varnames)
+ }
+
+ /* DWARF 3. */
+ .debug_ranges ${RELOCATING+BLOCK(__section_alignment__)} ${RELOCATING+(NOLOAD)} :
+ {
+ *(.debug_ranges)
+ }
+}
+EOF
+2006-09-20 Kai Tietz <Kai.Tietz@onevision.com>
+
+ * bootstrap/bootstrap.exp: Fix x86_64-mingw32 target test.
+ * ld-fastcall/fastcall.exp: Likewise.
+ * ld-scripts/align.exp: Likewise.
+ * ld-scripts/align2a.d: Likewise.
+ * ld-scripts/defined.exp: Likewise.
+ * ld-scripts/provide.exp: Likewise.
+ * ld-scripts/script.exp: Likewise.
+ * ld-scripts/weak.exp: Likewise.
+ * lib/ld-lib.exp: Detect target as pecoff file format.
+
2006-09-18 Thiemo Seufer <ths@networkno.de>
Maciej W. Rozycki <macro@mips.com>
# Expect script for LD Bootstrap Tests
-# Copyright 1993, 1994, 1995, 1996, 1997, 1998, 2000, 2001, 2002, 2004
+# Copyright 1993, 1994, 1995, 1996, 1997, 1998, 2000, 2001, 2002, 2004, 2006
# Free Software Foundation, Inc.
#
# This file is free software; you can redistribute it and/or modify
|| [istarget "*-*-wince"]
|| [istarget "*-*-cygwin*"]
|| [istarget "*-*-winnt*"]
- || [istarget "*-*-mingw32*"]
+ || [istarget "*-*-mingw*"]
|| [istarget "*-*-interix*"]
|| [istarget "*-*-beospe*"]
|| [istarget "*-*-netbsdpe*"]} {
# Test that the linker can handle fastcall symbols correctly.
-# Copyright 2002 Free Software Foundation, Inc.
+# Copyright 2002, 2006 Free Software Foundation, Inc.
#
# This file is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
set testname "ld (fastcall symbols)"
-if {![istarget "i*86-*-*"]} {
+if {![istarget "i*86-*-*"] && ![istarget "x86_64-*-mingw64*"] } {
return
}
if { !([istarget "i*86-*-*pe*"] && ![istarget "i*86-*-opensd*"]) \
&& ![istarget "i*86-*-cygwin*"] \
- && ![istarget "i*86-*-mingw32*"] } {
+ && ![istarget "i*86-*-mingw*"] } {
return
}
# Test ALIGN in a linker script.
# By Nathan Sidwell, CodeSourcery LLC
-# Copyright 2004, 2005
+# Copyright 2004, 2005, 2006
# Free Software Foundation, Inc.
#
# This file is free software; you can redistribute it and/or modify
return
}
-# Doesn't work on PECOFF, appears to be a genuine bug
-if [is_pecoff_format] {
+# Doesn't work on PECOFF, appears to be a genuine bug.
+# mingw64 targets need to set the image base to 0 to avoid auto image-basing.
+global LDFLAGS
+set saved_LDFLAGS "$LDFLAGS"
+if [istarget "*-*-mingw64*"] then {
+ set LDFLAGS "$LDFLAGS --image-base 0"
+} else {
+ if [is_pecoff_format] {
global target_triplet
setup_xfail $target_triplet
+ }
}
-if ![ld_simple_link $ld tmpdir/align "-T $srcdir/$subdir/align.t tmpdir/align.o"] {
+if ![ld_simple_link $ld tmpdir/align "$LDFLAGS -T $srcdir/$subdir/align.t tmpdir/align.o"] {
fail $testname
} else {
pass $testname
run_dump_test align2b
}
run_dump_test align2c
+set LDFLAGS "$saved_LDFLAGS"
Sections:
Idx +Name +Size +VMA +LMA +File +off +Algn
- +0 +\.text +[^ ]* +0+ +0+ .*
- +CONTENTS, +ALLOC, +LOAD,.* CODE
- +1 +\.data +[^ ]* +0+10 +0+10 .*
- +CONTENTS, +ALLOC, +LOAD, +DATA
+[ ]+0 +\.text +[^ ]* +0+ +0+ .*
+[ ]+CONTENTS, +ALLOC, +LOAD,.* CODE
+[ ]+1 +\.data +[^ ]* +0+10 +0+10 .*
+[ ]+CONTENTS, +ALLOC, +LOAD, +DATA
#pass
# Test DEFINED in a linker script.
# By Ian Lance Taylor, Cygnus Support.
-# Copyright 2001, 2003
+# Copyright 2001, 2003. 2006
# Free Software Foundation, Inc.
#
# This file is free software; you can redistribute it and/or modify
return
}
-if ![ld_simple_link $ld tmpdir/def "-T $srcdir/$subdir/defined.t tmpdir/def.o"] {
+global LDFLAGS
+set saved_LDFLAGS "$LDFLAGS"
+if [istarget "*-*-mingw64*"] then {
+ set LDFLAGS "$LDFLAGS --image-base 0"
+}
+
+if ![ld_simple_link $ld tmpdir/def "$LDFLAGS -T $srcdir/$subdir/defined.t tmpdir/def.o"] {
fail $testname
} else {
if ![ld_nm $nm "" tmpdir/def] {
set prms_id 0
run_dump_test "defined2"
run_dump_test "defined3"
+set LDFLAGS "$saved_LDFLAGS"
# Test PROVIDE in a linker script.
# By Nathan Sidwell, CodeSourcery LLC
-# Copyright 2004
+# Copyright 2004, 2006
# Free Software Foundation, Inc.
#
# This file is free software; you can redistribute it and/or modify
return
}
+global LDFLAGS
+set saved_LDFLAGS "$LDFLAGS"
+if [istarget "*-*-mingw64*"] then {
+ set LDFLAGS "$LDFLAGS --image-base 0"
+}
+
run_dump_test provide-1
run_dump_test provide-2
setup_xfail *-*-*
run_dump_test provide-3
+
+set LDFLAGS "$saved_LDFLAGS"
# Test basic linker script functionality
# By Ian Lance Taylor, Cygnus Support
-# Copyright 1999, 2000, 2001, 2002, 2004
+# Copyright 1999, 2000, 2001, 2002, 2004, 2006
# Free Software Foundation, Inc.
#
# This file is free software; you can redistribute it and/or modify
set flags ""
if {[istarget "*-*-pe*"] \
|| [istarget "*-*-cygwin*"] \
- || [istarget "*-*-mingw32*"] \
+ || [istarget "*-*-mingw*"] \
|| [istarget "*-*-winnt*"] \
|| [istarget "*-*-nt"] \
|| [istarget "*-*-interix*"] } then {
} else {
check_script
}
-
-
# Test weak symbols.
# By Ian Lance Taylor, Cygnus Solutions.
-# Copyright 1999, 2000, 2002, 2004
+# Copyright 1999, 2000, 2002, 2004, 2006
# Free Software Foundation, Inc.
#
# This file is free software; you can redistribute it and/or modify
# Weak symbols are broken for non-i386 PE targets.
if {! [istarget i?86-*-*]} {
setup_xfail *-*-pe*
+ setup_xfail *-*-mingw64*
}
# hppa64 and or32 are incredibly broken
return
}
+global LDFLAGS
+set saved_LDFLAGS "$LDFLAGS"
+if [istarget "*-*-mingw64*"] then {
+ set LDFLAGS "$LDFLAGS --image-base 0"
+}
+
set weak_regexp_big \
".*Contents of section .text:.*1000 00001008 0000200c 12121212 34343434.*Contents of section .data:.*2000 00001008 0000200c 56565656 78787878.*"
} else {
if {[which $objdump] == 0} then {
unresolved $testname
+ set LDFLAGS "$saved_LDFLAGS"
return
}
fail $testname
}
}
+
+set LDFLAGS "$saved_LDFLAGS"