2010-01-13 Tristan Gingold <gingold@adacore.com>
authorTristan Gingold <gingold@adacore.com>
Wed, 13 Jan 2010 11:49:36 +0000 (11:49 +0000)
committerTristan Gingold <gingold@adacore.com>
Wed, 13 Jan 2010 11:49:36 +0000 (11:49 +0000)
* config.bfd: Remove duplicated target vector for i386-*-darwin.
Appends new arch instead of overriding.
Use mach_o_x86_64_vec for x86_64-*-darwin.
* configure.in: Add mach_o_x86_64_vec.
* configure: Regenerate.
* targets.c: Declare mach_o_x86_64_vec, add it to _bfd_target_vector.
* Makefile.am (BFD64_BACKENDS): Add mach-o-x86-64.lo
(BFD64_BACKENDS_CFILES): Add mach-o-x86-64.c
* Makefile.in: Regenerate.
* mach-o-x86-64.c: New file.

bfd/ChangeLog
bfd/Makefile.am
bfd/Makefile.in
bfd/config.bfd
bfd/configure
bfd/configure.in
bfd/mach-o-x86-64.c [new file with mode: 0644]
bfd/targets.c

index b70e9347358eff904ea19515d14edd78b9a33f9c..06bbc5b7e82c7b55ceff04f740252f6958a23af3 100644 (file)
@@ -1,3 +1,16 @@
+2010-01-13  Tristan Gingold  <gingold@adacore.com>
+
+       * config.bfd: Remove duplicated target vector for i386-*-darwin.
+       Appends new arch instead of overriding.
+       Use mach_o_x86_64_vec for x86_64-*-darwin.
+       * configure.in: Add mach_o_x86_64_vec.
+       * configure: Regenerate.
+       * targets.c: Declare mach_o_x86_64_vec, add it to _bfd_target_vector.
+       * Makefile.am (BFD64_BACKENDS): Add mach-o-x86-64.lo
+       (BFD64_BACKENDS_CFILES): Add mach-o-x86-64.c
+       * Makefile.in: Regenerate.
+       * mach-o-x86-64.c: New file.
+
 2010-01-13  Tristan Gingold  <gingold@adacore.com>
 
        * reloc.c: Add MACH_O_X86_64 relocations.
index b569f84d82b867e26e07e9e70b4e2d2c08744474..03aa24b7b154697ec6d0827cae89c3344612009f 100644 (file)
@@ -609,6 +609,7 @@ BFD64_BACKENDS = \
        elf64-x86-64.lo \
        elf64.lo \
        elfn32-mips.lo \
+       mach-o-x86-64.lo \
        mmo.lo \
        nlm32-alpha.lo \
        nlm64.lo \
@@ -639,6 +640,7 @@ BFD64_BACKENDS_CFILES = \
        elf64-x86-64.c \
        elf64.c \
        elfn32-mips.c \
+       mach-o-x86-64.c \
        mmo.c \
        nlm32-alpha.c \
        nlm64.c \
index 2196478d7433d22dbde923d25c6d096600cfa4b4..639817d794d082fab9480647f2453e8a71503514 100644 (file)
@@ -907,6 +907,7 @@ BFD64_BACKENDS = \
        elf64-x86-64.lo \
        elf64.lo \
        elfn32-mips.lo \
+       mach-o-x86-64.lo \
        mmo.lo \
        nlm32-alpha.lo \
        nlm64.lo \
@@ -937,6 +938,7 @@ BFD64_BACKENDS_CFILES = \
        elf64-x86-64.c \
        elf64.c \
        elfn32-mips.c \
+       mach-o-x86-64.c \
        mmo.c \
        nlm32-alpha.c \
        nlm64.c \
@@ -1413,6 +1415,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/m88kmach3.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/m88kopenbsd.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mach-o-i386.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mach-o-x86-64.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mach-o.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/merge.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mipsbsd.Plo@am__quote@
index c331a97e3956979a498790fba055b3d01e3d4530..9290b8307fc29e61ba88d80cb375d4c28fc6e642 100644 (file)
@@ -543,8 +543,8 @@ case "${targ}" in
     ;;
   i[3-7]86-*-darwin* | i[3-7]86-*-macos10* | i[3-7]86-*-rhapsody*)
     targ_defvec=mach_o_i386_vec
-    targ_selvecs="mach_o_i386_vec mach_o_le_vec mach_o_be_vec mach_o_fat_vec pef_vec pef_xlib_vec sym_vec"
-    targ_archs="bfd_i386_arch bfd_powerpc_arch bfd_rs6000_arch"
+    targ_selvecs="mach_o_le_vec mach_o_be_vec mach_o_fat_vec pef_vec pef_xlib_vec sym_vec"
+    targ_archs="$targ_archs bfd_powerpc_arch bfd_rs6000_arch"
     ;;
  i[3-7]86-sequent-bsd*)
     targ_defvec=i386dynix_vec
@@ -605,9 +605,9 @@ case "${targ}" in
     ;;
 #ifdef BFD64
   x86_64-*-darwin*)
-    targ_defvec=mach_o_le_vec
+    targ_defvec=mach_o_x86_64_vec
     targ_selvecs="mach_o_i386_vec mach_o_le_vec mach_o_be_vec mach_o_fat_vec pef_vec pef_xlib_vec sym_vec"
-    targ_archs="bfd_i386_arch bfd_powerpc_arch bfd_rs6000_arch"
+    targ_archs="$targ_archs bfd_powerpc_arch bfd_rs6000_arch"
     want64=true
     ;;
   x86_64-*-dicos*)
@@ -1153,7 +1153,7 @@ case "${targ}" in
   powerpc-*-darwin* | powerpc-*-macos10* | powerpc-*-rhapsody*)
     targ_defvec=mach_o_be_vec
     targ_selvecs="mach_o_be_vec mach_o_le_vec mach_o_fat_vec pef_vec pef_xlib_vec sym_vec"
-    targ_archs="bfd_powerpc_arch bfd_rs6000_arch bfd_i386_arch"
+    targ_archs="$targ_archs bfd_i386_arch"
     ;;
   powerpc-*-macos*)
     targ_defvec=pmac_xcoff_vec
index 0626f09b51874dc20280b4487b460147062d410e..5ee3ffd448112fcc08ab589a24d0a89f48684b17 100755 (executable)
@@ -15198,6 +15198,7 @@ do
     mach_o_le_vec)              tb="$tb mach-o.lo" ;;
     mach_o_fat_vec)             tb="$tb mach-o.lo" ;;
     mach_o_i386_vec)            tb="$tb mach-o-i386.lo" ;;
+    mach_o_x86_64_vec)          tb="$tb mach-o-x86-64.lo" ;;
     mcore_pe_big_vec)          tb="$tb pe-mcore.lo peigen.lo cofflink.lo" ;;
     mcore_pe_little_vec)       tb="$tb pe-mcore.lo peigen.lo cofflink.lo" ;;
     mcore_pei_big_vec)         tb="$tb pei-mcore.lo peigen.lo cofflink.lo" ;;
index 3713d5669ed62709bb2e6ee498a0d604b4788b12..b246afc95ae59c6dd6094ba38037873354860c41 100644 (file)
@@ -857,6 +857,7 @@ do
     mach_o_le_vec)              tb="$tb mach-o.lo" ;;
     mach_o_fat_vec)             tb="$tb mach-o.lo" ;;
     mach_o_i386_vec)            tb="$tb mach-o-i386.lo" ;;
+    mach_o_x86_64_vec)          tb="$tb mach-o-x86-64.lo" ;;
     mcore_pe_big_vec)          tb="$tb pe-mcore.lo peigen.lo cofflink.lo" ;;
     mcore_pe_little_vec)       tb="$tb pe-mcore.lo peigen.lo cofflink.lo" ;;
     mcore_pei_big_vec)         tb="$tb pei-mcore.lo peigen.lo cofflink.lo" ;;
diff --git a/bfd/mach-o-x86-64.c b/bfd/mach-o-x86-64.c
new file mode 100644 (file)
index 0000000..005315d
--- /dev/null
@@ -0,0 +1,280 @@
+/* Intel x86-64 Mach-O support for BFD.
+   Copyright 2010
+   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 3 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.  */
+
+#include "sysdep.h"
+#include "mach-o.h"
+#include "bfd.h"
+#include "libbfd.h"
+#include "libiberty.h"
+
+#define bfd_mach_o_object_p bfd_mach_o_x86_64_object_p
+#define bfd_mach_o_core_p bfd_mach_o_x86_64_core_p
+#define bfd_mach_o_mkobject bfd_mach_o_x86_64_mkobject
+
+static const bfd_target *
+bfd_mach_o_x86_64_object_p (bfd *abfd)
+{
+  return bfd_mach_o_header_p (abfd, 0, BFD_MACH_O_CPU_TYPE_X86_64);
+}
+
+static const bfd_target *
+bfd_mach_o_x86_64_core_p (bfd *abfd)
+{
+  return bfd_mach_o_header_p (abfd,
+                              BFD_MACH_O_MH_CORE, BFD_MACH_O_CPU_TYPE_X86_64);
+}
+
+static bfd_boolean
+bfd_mach_o_x86_64_mkobject (bfd *abfd)
+{
+  bfd_mach_o_data_struct *mdata;
+
+  if (!bfd_mach_o_mkobject_init (abfd))
+    return FALSE;
+
+  mdata = bfd_mach_o_get_data (abfd);
+  mdata->header.magic = BFD_MACH_O_MH_MAGIC;
+  mdata->header.cputype = BFD_MACH_O_CPU_TYPE_X86_64;
+  mdata->header.cpusubtype = BFD_MACH_O_CPU_SUBTYPE_X86_ALL;
+  mdata->header.byteorder = BFD_ENDIAN_LITTLE;
+  mdata->header.version = 1;
+
+  return TRUE;
+}
+
+/* In case we're on a 32-bit machine, construct a 64-bit "-1" value.  */
+#define MINUS_ONE (~ (bfd_vma) 0)
+
+static reloc_howto_type x86_64_howto_table[]=
+{
+  /* 0 */
+  HOWTO(BFD_RELOC_64, 0, 4, 64, FALSE, 0,
+       complain_overflow_bitfield,
+       NULL, "64",
+       FALSE, MINUS_ONE, MINUS_ONE, FALSE),
+  HOWTO(BFD_RELOC_32, 0, 2, 32, FALSE, 0,
+       complain_overflow_bitfield,
+       NULL, "32",
+       FALSE, 0xffffffff, 0xffffffff, FALSE),
+  HOWTO(BFD_RELOC_32_PCREL, 0, 2, 32, TRUE, 0,
+       complain_overflow_bitfield,
+       NULL, "DISP32",
+       FALSE, 0xffffffff, 0xffffffff, TRUE),
+  HOWTO(BFD_RELOC_MACH_O_X86_64_PCREL32_1, 0, 2, 32, TRUE, 0,
+       complain_overflow_bitfield,
+       NULL, "DISP32_1",
+       FALSE, 0xffffffff, 0xffffffff, TRUE),
+  /* 4 */
+  HOWTO(BFD_RELOC_MACH_O_X86_64_PCREL32_2, 0, 2, 32, TRUE, 0,
+       complain_overflow_bitfield,
+       NULL, "DISP32_2",
+       FALSE, 0xffffffff, 0xffffffff, TRUE),
+  HOWTO(BFD_RELOC_MACH_O_X86_64_PCREL32_4, 0, 2, 32, TRUE, 0,
+       complain_overflow_bitfield,
+       NULL, "DISP32_4",
+       FALSE, 0xffffffff, 0xffffffff, TRUE),
+  HOWTO(BFD_RELOC_MACH_O_X86_64_BRANCH32, 0, 2, 32, TRUE, 0,
+       complain_overflow_bitfield,
+       NULL, "BRANCH32",
+       FALSE, 0xffffffff, 0xffffffff, TRUE),
+  HOWTO(BFD_RELOC_MACH_O_X86_64_GOT_LOAD, 0, 2, 32, TRUE, 0,
+       complain_overflow_bitfield,
+       NULL, "GOT_LOAD",
+       FALSE, 0xffffffff, 0xffffffff, TRUE),
+  /* 8 */
+  HOWTO(BFD_RELOC_MACH_O_X86_64_SUBTRACTOR32, 0, 2, 32, FALSE, 0,
+       complain_overflow_bitfield,
+       NULL, "SUBTRACTOR32",
+       FALSE, 0xffffffff, 0xffffffff, FALSE),
+  HOWTO(BFD_RELOC_MACH_O_X86_64_SUBTRACTOR64, 0, 4, 64, FALSE, 0,
+       complain_overflow_bitfield,
+       NULL, "SUBTRACTOR64",
+       FALSE, MINUS_ONE, MINUS_ONE, FALSE),
+  HOWTO(BFD_RELOC_MACH_O_X86_64_GOT, 0, 2, 32, TRUE, 0,
+       complain_overflow_bitfield,
+       NULL, "GOT",
+       FALSE, 0xffffffff, 0xffffffff, TRUE),
+  HOWTO(BFD_RELOC_MACH_O_X86_64_BRANCH8, 0, 0, 8, TRUE, 0,
+       complain_overflow_bitfield,
+       NULL, "BRANCH8",
+       FALSE, 0xff, 0xff, TRUE),
+};
+
+static bfd_boolean
+bfd_mach_o_x86_64_swap_reloc_in (arelent *res, bfd_mach_o_reloc_info *reloc)
+{
+  /* On x86-64, scattered relocs are not used.  */
+  if (reloc->r_scattered)
+    return FALSE;
+
+  switch (reloc->r_type)
+    {
+    case BFD_MACH_O_X86_64_RELOC_UNSIGNED:
+      if (reloc->r_pcrel)
+        return FALSE;
+      switch (reloc->r_length)
+        {
+        case 2:
+          res->howto = &x86_64_howto_table[1];
+          return TRUE;
+        case 3:
+          res->howto = &x86_64_howto_table[0];
+          return TRUE;
+        default:
+          return FALSE;
+        }
+    case BFD_MACH_O_X86_64_RELOC_SIGNED:
+      if (reloc->r_length == 2 && reloc->r_pcrel)
+        {
+          res->howto = &x86_64_howto_table[2];
+          return TRUE;
+        }
+      break;
+    case BFD_MACH_O_X86_64_RELOC_BRANCH:
+      if (!reloc->r_pcrel)
+        return FALSE;
+      switch (reloc->r_length)
+        {
+        case 2:
+          res->howto = &x86_64_howto_table[6];
+          return TRUE;
+        default:
+          return FALSE;
+        }
+      break;
+    case BFD_MACH_O_X86_64_RELOC_GOT_LOAD:
+      if (reloc->r_length == 2 && reloc->r_pcrel && reloc->r_extern)
+        {
+          res->howto = &x86_64_howto_table[7];
+          return TRUE;
+        }
+      break;
+    case BFD_MACH_O_X86_64_RELOC_GOT:
+      if (reloc->r_length == 2 && reloc->r_pcrel && reloc->r_extern)
+        {
+          res->howto = &x86_64_howto_table[10];
+          return TRUE;
+        }
+      break;
+    case BFD_MACH_O_X86_64_RELOC_SUBTRACTOR:
+      if (reloc->r_pcrel)
+        return FALSE;
+      switch (reloc->r_length)
+        {
+        case 2:
+          res->howto = &x86_64_howto_table[8];
+          return TRUE;
+        case 3:
+          res->howto = &x86_64_howto_table[9];
+          return TRUE;
+        default:
+          return FALSE;
+        }
+      break;
+    case BFD_MACH_O_X86_64_RELOC_SIGNED_1:
+      if (reloc->r_length == 2 && reloc->r_pcrel)
+        {
+          res->howto = &x86_64_howto_table[3];
+          return TRUE;
+        }
+      break;
+    case BFD_MACH_O_X86_64_RELOC_SIGNED_2:
+      if (reloc->r_length == 2 && reloc->r_pcrel)
+        {
+          res->howto = &x86_64_howto_table[4];
+          return TRUE;
+        }
+      break;
+    case BFD_MACH_O_X86_64_RELOC_SIGNED_4:
+      if (reloc->r_length == 2 && reloc->r_pcrel)
+        {
+          res->howto = &x86_64_howto_table[5];
+          return TRUE;
+        }
+      break;
+    default:
+      return FALSE;
+    }
+  return FALSE;
+}
+
+static bfd_boolean
+bfd_mach_o_x86_64_swap_reloc_out (arelent *rel, bfd_mach_o_reloc_info *rinfo)
+{
+  rinfo->r_address = rel->address;
+  switch (rel->howto->type)
+    {
+    case BFD_RELOC_64:
+      rinfo->r_scattered = 0;
+      rinfo->r_type = BFD_MACH_O_X86_64_RELOC_UNSIGNED;
+      rinfo->r_pcrel = 0;
+      rinfo->r_length = rel->howto->size; /* Correct in practice.  */
+      if ((*rel->sym_ptr_ptr)->flags & BSF_SECTION_SYM)
+        {
+          rinfo->r_extern = 0;
+          rinfo->r_value = (*rel->sym_ptr_ptr)->section->target_index;
+        }
+      else
+        {
+          rinfo->r_extern = 1;
+          rinfo->r_value = (*rel->sym_ptr_ptr)->udata.i;
+        }
+      break;
+    default:
+      return FALSE;
+    }
+  return TRUE;
+}
+
+static reloc_howto_type *
+bfd_mach_o_x86_64_bfd_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+                                         bfd_reloc_code_real_type code)
+{
+  unsigned int i;
+
+  for (i = 0;
+       i < sizeof (x86_64_howto_table) / sizeof (*x86_64_howto_table);
+       i++)
+    if (code == x86_64_howto_table[i].type)
+      return &x86_64_howto_table[i];
+  return NULL;
+}
+
+static reloc_howto_type *
+bfd_mach_o_x86_64_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+                                         const char *name ATTRIBUTE_UNUSED)
+{
+  return NULL;
+}
+
+#define bfd_mach_o_swap_reloc_in bfd_mach_o_x86_64_swap_reloc_in
+#define bfd_mach_o_swap_reloc_out bfd_mach_o_x86_64_swap_reloc_out
+
+#define bfd_mach_o_bfd_reloc_type_lookup bfd_mach_o_x86_64_bfd_reloc_type_lookup
+#define bfd_mach_o_bfd_reloc_name_lookup bfd_mach_o_x86_64_bfd_reloc_name_lookup
+#define bfd_mach_o_print_thread NULL
+
+#define TARGET_NAME            mach_o_x86_64_vec
+#define TARGET_STRING          "mach-o-x86-64"
+#define TARGET_ARCHITECTURE    bfd_arch_i386
+#define TARGET_BIG_ENDIAN      0
+#define TARGET_ARCHIVE                 0
+#include "mach-o-target.c"
index d9811a8010954a12282ab8b9509f86f79f3887ac..ad22a29ded63e4e61c125fc24e1d104ce89b692b 100644 (file)
@@ -760,6 +760,7 @@ extern const bfd_target mach_o_be_vec;
 extern const bfd_target mach_o_le_vec;
 extern const bfd_target mach_o_fat_vec;
 extern const bfd_target mach_o_i386_vec;
+extern const bfd_target mach_o_x86_64_vec;
 extern const bfd_target maxqcoff_vec;
 extern const bfd_target mcore_pe_big_vec;
 extern const bfd_target mcore_pe_little_vec;
@@ -1134,6 +1135,9 @@ static const bfd_target * const _bfd_target_vector[] =
        &mach_o_le_vec,
        &mach_o_fat_vec,
        &mach_o_i386_vec,
+#ifdef BFD64
+       &mach_o_x86_64_vec,
+#endif
        &maxqcoff_vec,
        &mcore_pe_big_vec,
        &mcore_pe_little_vec,