* Makefile.am (ALL_MACHINES): Add ms1 support.
authorAldy Hernandez <aldyh@redhat.com>
Tue, 7 Jun 2005 21:07:32 +0000 (21:07 +0000)
committerAldy Hernandez <aldyh@redhat.com>
Tue, 7 Jun 2005 21:07:32 +0000 (21:07 +0000)
(ALL_MACHINES_CFILES): Same.
(BFD32_BACKENDS): Same.
(BFD32_BACKENDS_CFILES): Same.

* Makefile.in: Regenerate.

* archures.c (bfd_architecture): Add ms1 entries.
Externalize bfd_ms1_arch.
(bfd_archures_list): Add bfd_ms1_arch.

* bfd-in2.h: Regenerate.

* cpu-ms1.c: New file.

* elf32-ms1.c: New file.

* targets.c: Define extern of bfd_elf32_ms1_vec.
Add bfd_elf32_ms1_vec to _bfd_target_vector.

* configure.in: Add bfd_elf32_ms1_vec case.

* configure: Regenerate.

* config.bfd: Add ms1-*-elf to table.

bfd/ChangeLog
bfd/Makefile.am
bfd/Makefile.in
bfd/archures.c
bfd/bfd-in2.h
bfd/config.bfd
bfd/configure
bfd/configure.in
bfd/cpu-ms1.c [new file with mode: 0644]
bfd/elf32-ms1.c [new file with mode: 0644]
bfd/targets.c

index 360736185dc78bb909a4209524cd13429add379a..3f4898e1ce4c183b04ffd6f48a24b2df5c1e333e 100644 (file)
@@ -1,3 +1,33 @@
+2005-06-07  Aldy Hernandez  <aldyh@redhat.com>
+           Michael Snyder  <msnyder@redhat.com>
+           Stan Cox  <scox@redhat.com>
+
+       * Makefile.am (ALL_MACHINES): Add ms1 support.
+       (ALL_MACHINES_CFILES): Same.
+       (BFD32_BACKENDS): Same.
+       (BFD32_BACKENDS_CFILES): Same.
+
+       * Makefile.in: Regenerate.
+
+       * archures.c (bfd_architecture): Add ms1 entries.
+       Externalize bfd_ms1_arch.
+       (bfd_archures_list): Add bfd_ms1_arch.
+
+       * bfd-in2.h: Regenerate.
+
+       * cpu-ms1.c: New file.
+
+       * elf32-ms1.c: New file.
+
+       * targets.c: Define extern of bfd_elf32_ms1_vec.
+       Add bfd_elf32_ms1_vec to _bfd_target_vector.
+
+       * configure.in: Add bfd_elf32_ms1_vec case.
+
+       * configure: Regenerate.
+
+       * config.bfd: Add ms1-*-elf to table.
+
 2005-06-07  Zack Weinberg  <zack@codesourcery.com>
 
        * coff-i386.c: Change md_apply_fix3 to md_apply_fix in comment.
index e25cb9c49b746f398064021ca973a3c4a7e706b7..46455738942eaced92a2a9d63c873e34e6dd798c 100644 (file)
@@ -88,6 +88,7 @@ ALL_MACHINES = \
        cpu-mcore.lo \
        cpu-mips.lo \
        cpu-mmix.lo \
+       cpu-ms1.lo \
        cpu-msp430.lo \
        cpu-or32.lo \
        cpu-ns32k.lo \
@@ -146,6 +147,7 @@ ALL_MACHINES_CFILES = \
        cpu-mcore.c \
        cpu-mips.c \
        cpu-mmix.c \
+       cpu-ms1.c \
        cpu-msp430.c \
        cpu-or32.c \
        cpu-ns32k.c \
@@ -251,6 +253,7 @@ BFD32_BACKENDS = \
        elf32-mcore.lo \
        elfxx-mips.lo \
        elf32-mips.lo \
+       elf32-ms1.lo \
        elf32-msp430.lo \
        elf32-openrisc.lo \
        elf32-or32.lo \
@@ -421,6 +424,7 @@ BFD32_BACKENDS_CFILES = \
        elf32-mcore.c \
        elfxx-mips.c \
        elf32-mips.c \
+       elf32-ms1.c \
        elf32-msp430.c \
        elf32-openrisc.c \
        elf32-or32.c \
@@ -1333,6 +1337,10 @@ elf32-mips.lo: elf32-mips.c $(INCDIR)/filenames.h $(INCDIR)/hashtab.h \
   $(INCDIR)/coff/symconst.h $(INCDIR)/coff/internal.h \
   $(INCDIR)/coff/ecoff.h $(INCDIR)/coff/mips.h $(INCDIR)/coff/external.h \
   ecoffswap.h elf32-target.h
+elf32-ms1.lo: elf32-ms1.c elf-bfd.h $(INCDIR)/elf/common.h \
+  $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h \
+  $(INCDIR)/elf/ms1.h $(INCDIR)/elf/reloc-macros.h \
+  elf32-target.h
 elf32-msp430.lo: elf32-msp430.c $(INCDIR)/filenames.h \
   $(INCDIR)/libiberty.h $(INCDIR)/hashtab.h elf-bfd.h \
   $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
index 9a749eaead5336c4a89646179b75498eb40862b9..98825c582e8f430c7fd91dfb6b2e5bd455363d58 100644 (file)
@@ -325,6 +325,7 @@ ALL_MACHINES = \
        cpu-mcore.lo \
        cpu-mips.lo \
        cpu-mmix.lo \
+       cpu-ms1.lo \
        cpu-msp430.lo \
        cpu-or32.lo \
        cpu-ns32k.lo \
@@ -383,6 +384,7 @@ ALL_MACHINES_CFILES = \
        cpu-mcore.c \
        cpu-mips.c \
        cpu-mmix.c \
+       cpu-ms1.c \
        cpu-msp430.c \
        cpu-or32.c \
        cpu-ns32k.c \
@@ -489,6 +491,7 @@ BFD32_BACKENDS = \
        elf32-mcore.lo \
        elfxx-mips.lo \
        elf32-mips.lo \
+       elf32-ms1.lo \
        elf32-msp430.lo \
        elf32-openrisc.lo \
        elf32-or32.lo \
@@ -659,6 +662,7 @@ BFD32_BACKENDS_CFILES = \
        elf32-mcore.c \
        elfxx-mips.c \
        elf32-mips.c \
+       elf32-ms1.c \
        elf32-msp430.c \
        elf32-openrisc.c \
        elf32-or32.c \
@@ -1900,6 +1904,10 @@ elf32-mips.lo: elf32-mips.c $(INCDIR)/filenames.h $(INCDIR)/hashtab.h \
   $(INCDIR)/coff/symconst.h $(INCDIR)/coff/internal.h \
   $(INCDIR)/coff/ecoff.h $(INCDIR)/coff/mips.h $(INCDIR)/coff/external.h \
   ecoffswap.h elf32-target.h
+elf32-ms1.lo: elf32-ms1.c elf-bfd.h $(INCDIR)/elf/common.h \
+  $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h \
+  $(INCDIR)/elf/ms1.h $(INCDIR)/elf/reloc-macros.h \
+  elf32-target.h
 elf32-msp430.lo: elf32-msp430.c $(INCDIR)/filenames.h \
   $(INCDIR)/libiberty.h $(INCDIR)/hashtab.h elf-bfd.h \
   $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
index 0e589343d43ecebe4ae82c7b29032a378a09453d..e84ccde64a6e3a226aea446993a513b1146d6e2e 100644 (file)
@@ -316,6 +316,9 @@ DESCRIPTION
 . bfd_arch_iq2000,     {* Vitesse IQ2000.  *}
 .#define bfd_mach_iq2000        1
 .#define bfd_mach_iq10          2
+.  bfd_arch_ms1,
+.#define bfd_mach_ms1           1
+.#define bfd_mach_mrisc2        2
 .  bfd_arch_pj,
 .  bfd_arch_avr,       {* Atmel AVR microcontrollers.  *}
 .#define bfd_mach_avr1         1
@@ -453,6 +456,7 @@ extern const bfd_arch_info_type bfd_w65_arch;
 extern const bfd_arch_info_type bfd_xstormy16_arch;
 extern const bfd_arch_info_type bfd_xtensa_arch;
 extern const bfd_arch_info_type bfd_z8k_arch;
+extern const bfd_arch_info_type bfd_ms1_arch;
 
 static const bfd_arch_info_type * const bfd_archures_list[] =
   {
@@ -493,6 +497,7 @@ static const bfd_arch_info_type * const bfd_archures_list[] =
     &bfd_mmix_arch,
     &bfd_mn10200_arch,
     &bfd_mn10300_arch,
+    &bfd_ms1_arch,
     &bfd_msp430_arch,
     &bfd_ns32k_arch,
     &bfd_openrisc_arch,
index 93d86688cca89727f1523ef0edb62ec5edf1bf9a..ec1944091d72e93f824d62d3ffde0b7d6e7c1b68 100644 (file)
@@ -1851,6 +1851,9 @@ enum bfd_architecture
  bfd_arch_iq2000,     /* Vitesse IQ2000.  */
 #define bfd_mach_iq2000        1
 #define bfd_mach_iq10          2
+  bfd_arch_ms1,
+#define bfd_mach_ms1           1
+#define bfd_mach_mrisc2        2
   bfd_arch_pj,
   bfd_arch_avr,       /* Atmel AVR microcontrollers.  */
 #define bfd_mach_avr1          1
index 9bec56db5591e4863d06b277e0d9f5764d40994c..29cd6143aa736a8f37ec744208d8866240875389 100644 (file)
@@ -920,6 +920,10 @@ case "${targ}" in
     targ_underscore=yes
     ;;
 
+  ms1-*-elf)
+    targ_defvec=bfd_elf32_ms1_vec
+    ;;
+
   msp430-*-*)
     targ_defvec=bfd_elf32_msp430_vec
     ;;
index 65bc1bb159004187c27653fb7024fb1c10a4c04b..02804af20ecceead264d0d3993a5746475669036 100755 (executable)
@@ -13015,6 +13015,7 @@ do
     bfd_elf32_mcore_little_vec)        tb="$tb elf32-mcore.lo elf32.lo $elf" ;;
     bfd_elf32_mn10200_vec)     tb="$tb elf-m10200.lo elf32.lo $elf" ;;
     bfd_elf32_mn10300_vec)     tb="$tb elf-m10300.lo elf32.lo $elf" ;;
+    bfd_elf32_ms1_vec)          tb="$tb elf32-ms1.lo elf32.lo $elf" ;;
     bfd_elf32_msp430_vec)      tb="$tb elf32-msp430.lo elf32.lo $elf" ;;
     bfd_elf32_nbigmips_vec)    tb="$tb elfn32-mips.lo elfxx-mips.lo elf32.lo $elf ecofflink.lo"; target_size=64 ;;
     bfd_elf32_nlittlemips_vec) tb="$tb elfn32-mips.lo elfxx-mips.lo elf32.lo $elf ecofflink.lo"; target_size=64 ;;
index be917485a5d2ea128a5da8fcd94ec7ecc5d97c35..225d875838d918b719888650dc32cb2b66c32ac8 100644 (file)
@@ -636,6 +636,7 @@ do
     bfd_elf32_mcore_little_vec)        tb="$tb elf32-mcore.lo elf32.lo $elf" ;;
     bfd_elf32_mn10200_vec)     tb="$tb elf-m10200.lo elf32.lo $elf" ;;
     bfd_elf32_mn10300_vec)     tb="$tb elf-m10300.lo elf32.lo $elf" ;;
+    bfd_elf32_ms1_vec)          tb="$tb elf32-ms1.lo elf32.lo $elf" ;;
     bfd_elf32_msp430_vec)      tb="$tb elf32-msp430.lo elf32.lo $elf" ;;
     bfd_elf32_nbigmips_vec)    tb="$tb elfn32-mips.lo elfxx-mips.lo elf32.lo $elf ecofflink.lo"; target_size=64 ;;
     bfd_elf32_nlittlemips_vec) tb="$tb elfn32-mips.lo elfxx-mips.lo elf32.lo $elf ecofflink.lo"; target_size=64 ;;
diff --git a/bfd/cpu-ms1.c b/bfd/cpu-ms1.c
new file mode 100644 (file)
index 0000000..1a0a726
--- /dev/null
@@ -0,0 +1,57 @@
+/* BFD support for the Morpho Technologies MS1 processor.
+   Copyright (C) 2001, 2002, 2005 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+
+const bfd_arch_info_type arch_info_struct[] =
+{
+{
+  32,                          /* Bits per word - not really true.  */
+  32,                          /* Bits per address.  */
+  8,                           /* Bits per byte.  */
+  bfd_arch_ms1,                        /* Architecture.  */
+  bfd_mach_mrisc2,             /* Machine.  */
+  "ms1",                       /* Architecture name.  */
+  "ms1-003",                   /* Printable name.  */
+  1,                           /* Section align power.  */
+  FALSE,                       /* The default ?  */
+  bfd_default_compatible,      /* Architecture comparison fn.  */
+  bfd_default_scan,            /* String to architecture convert fn.  */
+  NULL                         /* Next in list.  */
+}
+};
+
+const bfd_arch_info_type bfd_ms1_arch =
+{
+  32,                          /* Bits per word - not really true.  */
+  32,                          /* Bits per address.  */
+  8,                           /* Bits per byte.  */
+  bfd_arch_ms1,                        /* Architecture.  */
+  bfd_mach_ms1,                        /* Machine.  */
+  "ms1",                       /* Architecture name.  */
+  "ms1",                       /* Printable name.  */
+  1,                           /* Section align power.  */
+  TRUE,                                /* The default ?  */
+  bfd_default_compatible,      /* Architecture comparison fn.  */
+  bfd_default_scan,            /* String to architecture convert fn.  */
+  &arch_info_struct[0]         /* Next in list.  */
+};
+
diff --git a/bfd/elf32-ms1.c b/bfd/elf32-ms1.c
new file mode 100644 (file)
index 0000000..3a04fd5
--- /dev/null
@@ -0,0 +1,633 @@
+/* Morpho Technologies MS1 specific support for 32-bit ELF
+   Copyright 2001, 2002, 2003, 2004, 2005
+   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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+#include "elf-bfd.h"
+#include "elf/ms1.h"
+
+/* Prototypes.  */
+static reloc_howto_type * ms1_reloc_type_lookup 
+  (bfd *, bfd_reloc_code_real_type);
+
+static void ms1_info_to_howto_rela
+  (bfd *, arelent *, Elf_Internal_Rela *);
+
+static bfd_reloc_status_type ms1_elf_relocate_hi16
+  (bfd *, Elf_Internal_Rela *, bfd_byte *, bfd_vma);
+
+static bfd_reloc_status_type ms1_final_link_relocate
+  (reloc_howto_type *, bfd *, asection *, bfd_byte *, 
+   Elf_Internal_Rela *, bfd_vma);
+
+static bfd_boolean ms1_elf_relocate_section
+  (bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *, 
+   Elf_Internal_Rela *, Elf_Internal_Sym *, asection **);
+
+/* Relocation tables.  */
+static reloc_howto_type ms1_elf_howto_table [] =
+{
+  /* This reloc does nothing.  */
+  HOWTO (R_MS1_NONE,           /* type */
+          0,                      /* rightshift */ 
+          2,                      /* size (0 = byte, 1 = short, 2 = long) */ 
+          32,                     /* bitsize */
+          FALSE,                  /* pc_relative */ 
+          0,                      /* bitpos */ 
+          complain_overflow_dont, /* complain_on_overflow */ 
+          bfd_elf_generic_reloc,  /* special_function */ 
+          "R_MS1_NONE",          /* name */ 
+          FALSE,                  /* partial_inplace */ 
+          0 ,                     /* src_mask */ 
+          0,                      /* dst_mask */ 
+          FALSE),                 /* pcrel_offset */
+
+  /* A 16 bit absolute relocation.  */
+  HOWTO (R_MS1_16,             /* type */
+          0,                      /* rightshift */ 
+          2,                      /* size (0 = byte, 1 = short, 2 = long) */ 
+          16,                     /* bitsize */
+          FALSE,                  /* pc_relative */ 
+          0,                      /* bitpos */ 
+          complain_overflow_dont, /* complain_on_overflow */ 
+          bfd_elf_generic_reloc,  /* special_function */ 
+          "R_MS1_16",            /* name */ 
+          FALSE,                  /* partial_inplace */ 
+          0 ,                     /* src_mask */ 
+          0xffff,                 /* dst_mask */ 
+          FALSE),                 /* pcrel_offset */
+
+  /* A 32 bit absolute relocation.  */
+  HOWTO (R_MS1_32,             /* type */
+          0,                      /* rightshift */ 
+          2,                      /* size (0 = byte, 1 = short, 2 = long) */ 
+          32,                     /* bitsize */
+          FALSE,                  /* pc_relative */ 
+          0,                      /* bitpos */ 
+          complain_overflow_dont, /* complain_on_overflow */ 
+          bfd_elf_generic_reloc,  /* special_function */ 
+          "R_MS1_32",            /* name */ 
+          FALSE,                  /* partial_inplace */ 
+          0 ,                     /* src_mask */ 
+          0xffffffff,             /* dst_mask */ 
+          FALSE),                 /* pcrel_offset */
+
+  /* A 32 bit pc-relative relocation.  */
+  HOWTO (R_MS1_32_PCREL,       /* type */
+          0,                      /* rightshift */ 
+          2,                      /* size (0 = byte, 1 = short, 2 = long) */ 
+          32,                     /* bitsize */
+          TRUE,                   /* pc_relative */ 
+          0,                      /* bitpos */ 
+          complain_overflow_dont, /* complain_on_overflow */ 
+          bfd_elf_generic_reloc,  /* special_function */ 
+          "R_MS1_32_PCREL",    /* name */ 
+          FALSE,                  /* partial_inplace */ 
+          0 ,                     /* src_mask */ 
+          0xffffffff,             /* dst_mask */ 
+          TRUE),                  /* pcrel_offset */
+
+  /* A 16 bit pc-relative relocation.  */
+  HOWTO (R_MS1_PC16,           /* type */
+          0,                      /* rightshift */ 
+          2,                      /* size (0 = byte, 1 = short, 2 = long) */ 
+          16,                     /* bitsize */
+          TRUE,                   /* pc_relative */ 
+          0,                      /* bitpos */ 
+          complain_overflow_signed, /* complain_on_overflow */ 
+          bfd_elf_generic_reloc,  /* special_function */ 
+          "R_MS1_PC16",          /* name */ 
+          FALSE,                  /* partial_inplace */ 
+          0,                      /* src_mask */ 
+          0xffff,                 /* dst_mask */ 
+          TRUE),                  /* pcrel_offset */
+
+  /* high 16 bits of symbol value.  */
+  HOWTO (R_MS1_HI16,          /* type */
+         0,                     /* rightshift */
+         2,                     /* size (0 = byte, 1 = short, 2 = long) */
+         16,                    /* bitsize */
+         FALSE,                 /* pc_relative */
+         0,                     /* bitpos */
+         complain_overflow_dont, /* complain_on_overflow */
+         bfd_elf_generic_reloc, /* special_function */
+         "R_MS1_HI16",        /* name */
+         FALSE,                  /* partial_inplace */
+         0xffff0000,            /* src_mask */
+         0xffff0000,            /* dst_mask */
+         FALSE),                /* pcrel_offset */
+
+  /* Low 16 bits of symbol value.  */
+  HOWTO (R_MS1_LO16,          /* type */
+         0,                     /* rightshift */
+         2,                     /* size (0 = byte, 1 = short, 2 = long) */
+         16,                    /* bitsize */
+         FALSE,                 /* pc_relative */
+         0,                     /* bitpos */
+         complain_overflow_dont, /* complain_on_overflow */
+         bfd_elf_generic_reloc, /* special_function */
+         "R_MS1_LO16",        /* name */
+         FALSE,                  /* partial_inplace */
+         0xffff,                /* src_mask */
+         0xffff,                /* dst_mask */
+         FALSE),                /* pcrel_offset */
+};
+
+/* Map BFD reloc types to MS1 ELF reloc types.  */
+
+static reloc_howto_type *
+ms1_reloc_type_lookup
+    (bfd *                    abfd ATTRIBUTE_UNUSED,
+     bfd_reloc_code_real_type code)
+{
+  /* Note that the ms1_elf_howto_table is indxed by the R_
+     constants.  Thus, the order that the howto records appear in the
+     table *must* match the order of the relocation types defined in
+     include/elf/ms1.h.  */
+
+  switch (code)
+    {
+    case BFD_RELOC_NONE:
+      return &ms1_elf_howto_table[ (int) R_MS1_NONE];
+    case BFD_RELOC_16:
+      return &ms1_elf_howto_table[ (int) R_MS1_16];
+    case BFD_RELOC_32:
+      return &ms1_elf_howto_table[ (int) R_MS1_32];
+    case BFD_RELOC_32_PCREL:
+      return &ms1_elf_howto_table[ (int) R_MS1_32_PCREL];
+    case BFD_RELOC_16_PCREL:
+      return &ms1_elf_howto_table[ (int) R_MS1_PC16];
+    case BFD_RELOC_HI16:
+      return &ms1_elf_howto_table[ (int) R_MS1_HI16];
+    case BFD_RELOC_LO16:
+      return &ms1_elf_howto_table[ (int) R_MS1_LO16];
+
+    default:
+      /* Pacify gcc -Wall.  */
+      return NULL;
+    }
+  return NULL;
+}
+
+bfd_reloc_status_type
+ms1_elf_relocate_hi16
+    (bfd *               input_bfd,
+     Elf_Internal_Rela * relhi,
+     bfd_byte *          contents,
+     bfd_vma             value)
+{
+  bfd_vma insn;
+
+  insn = bfd_get_32 (input_bfd, contents + relhi->r_offset);
+
+  value += relhi->r_addend;
+  value >>= 16;
+  insn = ((insn & ~0xFFFF) | value);
+
+  bfd_put_32 (input_bfd, insn, contents + relhi->r_offset);
+  return bfd_reloc_ok;
+}
+\f
+/* XXX: The following code is the result of a cut&paste.  This unfortunate
+   practice is very widespread in the various target back-end files.  */
+
+/* Set the howto pointer for a MS1 ELF reloc.  */
+
+static void
+ms1_info_to_howto_rela
+    (bfd *               abfd ATTRIBUTE_UNUSED,
+     arelent *           cache_ptr,
+     Elf_Internal_Rela * dst)
+{
+  unsigned int r_type;
+
+  r_type = ELF32_R_TYPE (dst->r_info);
+  cache_ptr->howto = & ms1_elf_howto_table [r_type];
+}
+
+/* Perform a single relocation.  By default we use the standard BFD
+   routines.  */
+
+static bfd_reloc_status_type
+ms1_final_link_relocate
+    (reloc_howto_type *  howto,
+     bfd *               input_bfd,
+     asection *          input_section,
+     bfd_byte *          contents,
+     Elf_Internal_Rela * rel,
+     bfd_vma             relocation)
+{
+  return _bfd_final_link_relocate (howto, input_bfd, input_section,
+                                  contents, rel->r_offset,
+                                  relocation, rel->r_addend);
+}
+
+/* Relocate a MS1 ELF section.
+   There is some attempt to make this function usable for many architectures,
+   both USE_REL and USE_RELA ['twould be nice if such a critter existed],
+   if only to serve as a learning tool.
+
+   The RELOCATE_SECTION function is called by the new ELF backend linker
+   to handle the relocations for a section.
+
+   The relocs are always passed as Rela structures; if the section
+   actually uses Rel structures, the r_addend field will always be
+   zero.
+
+   This function is responsible for adjusting the section contents as
+   necessary, and (if using Rela relocs and generating a relocatable
+   output file) adjusting the reloc addend as necessary.
+
+   This function does not have to worry about setting the reloc
+   address or the reloc symbol index.
+
+   LOCAL_SYMS is a pointer to the swapped in local symbols.
+
+   LOCAL_SECTIONS is an array giving the section in the input file
+   corresponding to the st_shndx field of each local symbol.
+
+   The global hash table entry for the global symbols can be found
+   via elf_sym_hashes (input_bfd).
+
+   When generating relocatable output, this function must handle
+   STB_LOCAL/STT_SECTION symbols specially.  The output symbol is
+   going to be the section symbol corresponding to the output
+   section, which means that the addend must be adjusted
+   accordingly.  */
+
+static bfd_boolean
+ms1_elf_relocate_section
+    (bfd *                   output_bfd ATTRIBUTE_UNUSED,
+     struct bfd_link_info *  info,
+     bfd *                   input_bfd,
+     asection *              input_section,
+     bfd_byte *              contents,
+     Elf_Internal_Rela *     relocs,
+     Elf_Internal_Sym *      local_syms,
+     asection **             local_sections)
+{
+  Elf_Internal_Shdr *           symtab_hdr;
+  struct elf_link_hash_entry ** sym_hashes;
+  Elf_Internal_Rela *           rel;
+  Elf_Internal_Rela *           relend;
+
+  symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
+  sym_hashes = elf_sym_hashes (input_bfd);
+  relend     = relocs + input_section->reloc_count;
+
+  for (rel = relocs; rel < relend; rel ++)
+    {
+      reloc_howto_type *           howto;
+      unsigned long                r_symndx;
+      Elf_Internal_Sym *           sym;
+      asection *                   sec;
+      struct elf_link_hash_entry * h;
+      bfd_vma                      relocation;
+      bfd_reloc_status_type        r;
+      const char *                 name = NULL;
+      int                          r_type;
+      
+      r_type = ELF32_R_TYPE (rel->r_info);
+
+      r_symndx = ELF32_R_SYM (rel->r_info);
+
+      /* This is a final link.  */
+      howto  = ms1_elf_howto_table + ELF32_R_TYPE (rel->r_info);
+      h      = NULL;
+      sym    = NULL;
+      sec    = NULL;
+      
+      if (r_symndx < symtab_hdr->sh_info)
+       {
+         sym = local_syms + r_symndx;
+         sec = local_sections [r_symndx];
+         relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
+         
+         name = bfd_elf_string_from_elf_section
+           (input_bfd, symtab_hdr->sh_link, sym->st_name);
+         name = (name == NULL) ? bfd_section_name (input_bfd, sec) : name;
+       }
+      else
+       {
+         bfd_boolean unresolved_reloc;
+         bfd_boolean warned;
+
+         RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
+                                  r_symndx, symtab_hdr, sym_hashes,
+                                  h, sec, relocation,
+                                  unresolved_reloc, warned);
+
+         name = h->root.root.string;
+       }
+
+
+      /* Finally, the sole MS1-specific part.  */
+      switch (r_type)
+        {
+        case R_MS1_HI16:
+          r = ms1_elf_relocate_hi16 (input_bfd, rel, contents, relocation);
+          break;
+       default:
+          r = ms1_final_link_relocate (howto, input_bfd, input_section,
+                                         contents, rel, relocation);
+          break;
+        }
+
+
+      if (r != bfd_reloc_ok)
+       {
+         const char * msg = (const char *) NULL;
+
+         switch (r)
+           {
+           case bfd_reloc_overflow:
+             r = info->callbacks->reloc_overflow
+               (info, (h ? &h->root : NULL), name, howto->name, (bfd_vma) 0,
+                input_bfd, input_section, rel->r_offset);
+             break;
+             
+           case bfd_reloc_undefined:
+             r = info->callbacks->undefined_symbol
+               (info, name, input_bfd, input_section, rel->r_offset, TRUE);
+             break;
+             
+           case bfd_reloc_outofrange:
+             msg = _("internal error: out of range error");
+             break;
+
+           case bfd_reloc_dangerous:
+             msg = _("internal error: dangerous relocation");
+             break;
+
+           default:
+             msg = _("internal error: unknown error");
+             break;
+           }
+
+         if (msg)
+           r = info->callbacks->warning
+             (info, msg, name, input_bfd, input_section, rel->r_offset);
+
+         if (! r)
+           return FALSE;
+       }
+    }
+
+  return TRUE;
+}
+
+/* Return the section that should be marked against GC for a given
+   relocation.  */
+
+static asection *
+ms1_elf_gc_mark_hook
+    (asection *                   sec,
+     struct bfd_link_info *       info ATTRIBUTE_UNUSED,
+     Elf_Internal_Rela *          rel ATTRIBUTE_UNUSED,
+     struct elf_link_hash_entry * h,
+     Elf_Internal_Sym *           sym)
+{
+  if (h != NULL)
+    {
+      switch (h->root.type)
+       {
+       case bfd_link_hash_defined:
+       case bfd_link_hash_defweak:
+         return h->root.u.def.section;
+
+       case bfd_link_hash_common:
+         return h->root.u.c.p->section;
+
+       default:
+         break;
+       }
+    }
+  else
+    {
+      if (!(elf_bad_symtab (sec->owner)
+           && ELF_ST_BIND (sym->st_info) != STB_LOCAL)
+         && ! ((sym->st_shndx <= 0 || sym->st_shndx >= SHN_LORESERVE)
+               && sym->st_shndx != SHN_COMMON))
+       return bfd_section_from_elf_index (sec->owner, sym->st_shndx);
+    }
+
+  return NULL;
+}
+
+/* Update the got entry reference counts for the section being
+   removed.  */
+
+static bfd_boolean
+ms1_elf_gc_sweep_hook
+    (bfd *                     abfd ATTRIBUTE_UNUSED,
+     struct bfd_link_info *    info ATTRIBUTE_UNUSED,
+     asection *                sec ATTRIBUTE_UNUSED,
+     const Elf_Internal_Rela * relocs ATTRIBUTE_UNUSED)
+{
+  return TRUE;
+}
+
+/* Look through the relocs for a section during the first phase.
+   Since we don't do .gots or .plts, we just need to consider the
+   virtual table relocs for gc.  */
+static bfd_boolean
+ms1_elf_check_relocs
+    (bfd *                     abfd,
+     struct bfd_link_info *    info,
+     asection *                sec,
+     const Elf_Internal_Rela * relocs)
+{
+  Elf_Internal_Shdr *           symtab_hdr;
+  struct elf_link_hash_entry ** sym_hashes;
+  struct elf_link_hash_entry ** sym_hashes_end;
+  const Elf_Internal_Rela *     rel;
+  const Elf_Internal_Rela *     rel_end;
+  
+  if (info->relocatable)
+    return TRUE;
+  
+  symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+  sym_hashes = elf_sym_hashes (abfd);
+  sym_hashes_end = sym_hashes + symtab_hdr->sh_size / sizeof (Elf32_External_Sym);
+  if (!elf_bad_symtab (abfd))
+    sym_hashes_end -= symtab_hdr->sh_info;
+  
+  rel_end = relocs + sec->reloc_count;
+  for (rel = relocs; rel < rel_end; rel++)
+    {
+      struct elf_link_hash_entry *h;
+      unsigned long r_symndx;
+      
+      r_symndx = ELF32_R_SYM (rel->r_info);
+      if (r_symndx < symtab_hdr->sh_info)
+        h = NULL;
+      else
+        h = sym_hashes[r_symndx - symtab_hdr->sh_info];
+    }
+
+  return TRUE;
+}
+
+/* Return the MACH for an e_flags value.  */
+
+static int
+elf32_ms1_machine (bfd *abfd)
+{
+  switch (elf_elfheader (abfd)->e_flags & EF_MS1_CPU_MASK)
+    {
+    case EF_MS1_CPU_MRISC:     return bfd_mach_ms1;
+    case EF_MS1_CPU_MRISC2:  return bfd_mach_mrisc2;
+    }
+
+  return bfd_mach_ms1;
+}
+
+static bfd_boolean
+ms1_elf_object_p (bfd * abfd)
+{
+  bfd_default_set_arch_mach (abfd, bfd_arch_ms1, elf32_ms1_machine (abfd));
+
+  return TRUE;
+}
+
+/* Function to set the ELF flag bits.  */
+
+static bfd_boolean
+ms1_elf_set_private_flags (bfd *    abfd,
+                          flagword flags)
+{
+  elf_elfheader (abfd)->e_flags = flags;
+  elf_flags_init (abfd) = TRUE;
+  return TRUE;
+}
+
+static bfd_boolean
+ms1_elf_copy_private_bfd_data (bfd * ibfd, bfd * obfd)
+{
+  if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
+      || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
+    return TRUE;
+  
+  BFD_ASSERT (!elf_flags_init (obfd)
+             || elf_elfheader (obfd)->e_flags == elf_elfheader (ibfd)->e_flags);
+
+  elf_elfheader (obfd)->e_flags = elf_elfheader (ibfd)->e_flags;
+  elf_flags_init (obfd) = TRUE;
+  return TRUE;
+}
+
+/* Merge backend specific data from an object file to the output
+   object file when linking.  */
+
+static bfd_boolean
+ms1_elf_merge_private_bfd_data (bfd * ibfd, bfd * obfd)
+{
+  flagword     old_flags, new_flags;
+  bfd_boolean  error = FALSE;
+  static bfd * last_ibfd = 0;
+
+  /* Check if we have the same endianess.  */
+  if (_bfd_generic_verify_endian_match (ibfd, obfd) == FALSE)
+    return FALSE;
+
+  /* If they're not both ms1, then merging is meaningless, so just
+     don't do it.  */
+  if (strcmp (ibfd->arch_info->arch_name, "ms1") != 0)
+    return TRUE;
+  if (strcmp (obfd->arch_info->arch_name, "ms1") != 0)
+    return TRUE;
+
+  new_flags = elf_elfheader (ibfd)->e_flags;
+  old_flags = elf_elfheader (obfd)->e_flags;
+
+#ifdef DEBUG
+  _bfd_error_handler ("%B: old_flags = 0x%.8lx, new_flags = 0x%.8lx, init = %s",
+                     ibfd, old_flags, new_flags, elf_flags_init (obfd) ? "yes" : "no");
+#endif
+
+  elf_flags_init (obfd) = TRUE;
+
+  if ((new_flags & EF_MS1_CPU_MASK) == EF_MS1_CPU_MRISC2)
+    {
+      elf_elfheader (obfd)->e_flags = new_flags;
+      last_ibfd = ibfd;
+      obfd->arch_info = ibfd->arch_info;
+    }
+
+  return !error;
+}
+
+static bfd_boolean
+ms1_elf_print_private_bfd_data (bfd * abfd, void * ptr)
+{
+  FILE *   file = (FILE *) ptr;
+  flagword flags;
+
+  BFD_ASSERT (abfd != NULL && ptr != NULL);
+  
+  /* Print normal ELF private data.  */
+  _bfd_elf_print_private_bfd_data (abfd, ptr);
+
+  flags = elf_elfheader (abfd)->e_flags;
+  fprintf (file, _("private flags = 0x%lx:"), (long)flags);
+
+  switch (flags & EF_MS1_CPU_MASK)
+    {
+    default:
+    case EF_MS1_CPU_MRISC:     fprintf (file, " ms1-16-002");  break;
+    case EF_MS1_CPU_MRISC2:  fprintf (file, " ms1-16-003");    break;
+    }
+
+  fputc ('\n', file);
+
+  return TRUE;
+}
+
+\f
+#define TARGET_BIG_SYM  bfd_elf32_ms1_vec
+#define TARGET_BIG_NAME  "elf32-ms1"
+
+#define ELF_ARCH        bfd_arch_ms1
+#define ELF_MACHINE_CODE EM_MS1
+#define ELF_MAXPAGESIZE  1 /* No pages on the MS1.  */
+
+#define elf_info_to_howto_rel                  NULL
+#define elf_info_to_howto                      ms1_info_to_howto_rela
+
+#define elf_backend_relocate_section           ms1_elf_relocate_section
+
+#define bfd_elf32_bfd_reloc_type_lookup                ms1_reloc_type_lookup
+
+#define elf_backend_gc_mark_hook               ms1_elf_gc_mark_hook
+#define elf_backend_gc_sweep_hook              ms1_elf_gc_sweep_hook
+#define elf_backend_check_relocs                ms1_elf_check_relocs
+#define elf_backend_object_p                   ms1_elf_object_p
+#define elf_backend_rela_normal                        1
+
+#define elf_backend_can_gc_sections            1
+
+#define bfd_elf32_bfd_set_private_flags                ms1_elf_set_private_flags
+#define bfd_elf32_bfd_copy_private_bfd_data    ms1_elf_copy_private_bfd_data
+#define bfd_elf32_bfd_merge_private_bfd_data   ms1_elf_merge_private_bfd_data
+#define bfd_elf32_bfd_print_private_bfd_data   ms1_elf_print_private_bfd_data
+
+#include "elf32-target.h"
index 3bfde1b02fdd0d0eaedafa75c23dd69aca3817ba..65eff4d5393fc93f6095bc52d7a51f08c02e715e 100644 (file)
@@ -790,6 +790,7 @@ extern const bfd_target sco5_core_vec;
 extern const bfd_target trad_core_vec;
 
 extern const bfd_target bfd_elf32_am33lin_vec;
+extern const bfd_target bfd_elf32_ms1_vec;
 static const bfd_target * const _bfd_target_vector[] = {
 
 #ifdef SELECT_VECS
@@ -1120,6 +1121,7 @@ static const bfd_target * const _bfd_target_vector[] = {
        &we32kcoff_vec,
        &z8kcoff_vec,
        &bfd_elf32_am33lin_vec,
+       &bfd_elf32_ms1_vec,
 #endif /* not SELECT_VECS */
 
 /* Always support S-records, for convenience.  */