* Makefile.am (ALL_MACHINES): Add cpu-iq2000.lo.
authorStan Cox <scox@redhat.com>
Fri, 3 Jan 2003 21:12:28 +0000 (21:12 +0000)
committerStan Cox <scox@redhat.com>
Fri, 3 Jan 2003 21:12:28 +0000 (21:12 +0000)
(ALL_MACHINES_CFILES): Add cpu-iq2000.c.
(BFD32_BACKENDS): Add elf32-iq2000.lo.
(BFD32_BACKENDS_CFILES): Add elf32-iq2000.c.
(cpu-iq2000.lo): New target.
* Makefile.in: Regenerate.
* config.bfd: Handle iq2000-*-elf.
* archures.c (bfd_architecture): Add bfd_{arch,mach}_iq2000.
(bfd_archures_list): Add bfd_iq2000_arch.
* configure.in: Handle bfd_elf32_iq2000_vec.
* configure: Regenerate.
* reloc.c: Add BFD_RELOC_IQ2000_OFFSET_16, BFD_RELOC_IQ2000_OFFSET_21,
and BFD_RELOC_IQ2000_UHI16.
* targets.c (bfd_elf32_iq2000_vec): Declare.
(bfd_target_vector): Add bfd_elf32_iq2000_vec.
* elf.c (prep_headers): Set e_machine to EM_IQ2000.
* cpu-iq2000.c: New file.
* elf32-iq2000.c: Likewise.
* libbfd.h: Regenerate.
* bfd-in2.h: Likewise.

13 files changed:
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-iq2000.c [new file with mode: 0644]
bfd/elf32-iq2000.c [new file with mode: 0644]
bfd/libbfd.h
bfd/reloc.c
bfd/targets.c

index 9c6674430a5f0adb32703675f1a5c98fab56f3a1..7a35fd2d5e780f817946520249ac12d4109918c8 100644 (file)
@@ -1,3 +1,27 @@
+2002-01-02  Ben Elliston  <bje@redhat.com>
+           Jeff Johnston  <jjohnstn@redhat.com>
+
+       * Makefile.am (ALL_MACHINES): Add cpu-iq2000.lo.
+       (ALL_MACHINES_CFILES): Add cpu-iq2000.c.
+       (BFD32_BACKENDS): Add elf32-iq2000.lo.
+       (BFD32_BACKENDS_CFILES): Add elf32-iq2000.c.
+       (cpu-iq2000.lo): New target.
+       * Makefile.in: Regenerate.
+       * config.bfd: Handle iq2000-*-elf.
+       * archures.c (bfd_architecture): Add bfd_{arch,mach}_iq2000.
+       (bfd_archures_list): Add bfd_iq2000_arch.
+       * configure.in: Handle bfd_elf32_iq2000_vec.
+       * configure: Regenerate.
+       * reloc.c: Add BFD_RELOC_IQ2000_OFFSET_16, BFD_RELOC_IQ2000_OFFSET_21, 
+       and BFD_RELOC_IQ2000_UHI16.
+       * targets.c (bfd_elf32_iq2000_vec): Declare.
+       (bfd_target_vector): Add bfd_elf32_iq2000_vec.
+       * elf.c (prep_headers): Set e_machine to EM_IQ2000.
+       * cpu-iq2000.c: New file.
+       * elf32-iq2000.c: Likewise.
+       * libbfd.h: Regenerate.
+       * bfd-in2.h: Likewise.
+
 2003-01-02  Richard Sandiford  <rsandifo@redhat.com>
 
        * elfxx-mips.c: Include libiberty.h.
index 70de9e52f996427898368d226be5c4978b6fffcb..23ccb2a286c46e59dd3200afea128d99f71653d1 100644 (file)
@@ -70,6 +70,7 @@ ALL_MACHINES = \
        cpu-i860.lo \
        cpu-i960.lo \
        cpu-ip2k.lo \
+       cpu-iq2000.lo \
        cpu-m32r.lo \
        cpu-m68hc11.lo \
        cpu-m68hc12.lo \
@@ -123,6 +124,7 @@ ALL_MACHINES_CFILES = \
        cpu-i860.c \
        cpu-i960.c \
        cpu-ip2k.c \
+       cpu-iq2000.c \
        cpu-m32r.c \
        cpu-m68hc11.c \
        cpu-m68hc12.c \
@@ -223,6 +225,7 @@ BFD32_BACKENDS = \
        elf32-i960.lo \
        elf32-ia64.lo \
        elf32-ip2k.lo \
+       elf32-iq2000.lo \
        elf32-m32r.lo \
        elf32-m68hc11.lo \
        elf32-m68hc12.lo \
@@ -381,6 +384,7 @@ BFD32_BACKENDS_CFILES = \
        elf32-i860.c \
        elf32-i960.c \
        elf32-ip2k.c \
+       elf32-iq2000.c \
        elf32-m32r.c \
        elf32-m68k.c \
        elf32-m68hc11.c \
@@ -921,6 +925,7 @@ cpu-i386.lo: cpu-i386.c $(INCDIR)/filenames.h
 cpu-i860.lo: cpu-i860.c $(INCDIR)/filenames.h
 cpu-i960.lo: cpu-i960.c $(INCDIR)/filenames.h
 cpu-ip2k.lo: cpu-ip2k.c $(INCDIR)/filenames.h
+cpu-iq2000.lo: cpu-iq2000.c $(INCDIR)/filenames.h
 cpu-m32r.lo: cpu-m32r.c $(INCDIR)/filenames.h
 cpu-m68hc11.lo: cpu-m68hc11.c $(INCDIR)/filenames.h
 cpu-m68hc12.lo: cpu-m68hc12.c $(INCDIR)/filenames.h
@@ -1175,6 +1180,10 @@ elf32-ip2k.lo: elf32-ip2k.c $(INCDIR)/filenames.h elf-bfd.h \
   $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
   $(INCDIR)/bfdlink.h $(INCDIR)/elf/ip2k.h $(INCDIR)/elf/reloc-macros.h \
   elf32-target.h
+elf32-iq2000.lo: elf32-iq2000.c $(INCDIR)/filenames.h elf-bfd.h \
+  $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+  $(INCDIR)/bfdlink.h $(INCDIR)/elf/iq2000.h $(INCDIR)/elf/reloc-macros.h \
+  elf32-target.h
 elf32-m32r.lo: elf32-m32r.c $(INCDIR)/filenames.h elf-bfd.h \
   $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
   $(INCDIR)/bfdlink.h $(INCDIR)/elf/m32r.h $(INCDIR)/elf/reloc-macros.h \
index efcbd81864454085515cb233aa6ff2e808b13093..dc981a4385dc221b82b64049032de023758d8061 100644 (file)
@@ -195,6 +195,7 @@ ALL_MACHINES = \
        cpu-i860.lo \
        cpu-i960.lo \
        cpu-ip2k.lo \
+       cpu-iq2000.lo \
        cpu-m32r.lo \
        cpu-m68hc11.lo \
        cpu-m68hc12.lo \
@@ -249,6 +250,7 @@ ALL_MACHINES_CFILES = \
        cpu-i860.c \
        cpu-i960.c \
        cpu-ip2k.c \
+       cpu-iq2000.c \
        cpu-m32r.c \
        cpu-m68hc11.c \
        cpu-m68hc12.c \
@@ -350,6 +352,7 @@ BFD32_BACKENDS = \
        elf32-i960.lo \
        elf32-ia64.lo \
        elf32-ip2k.lo \
+       elf32-iq2000.lo \
        elf32-m32r.lo \
        elf32-m68hc11.lo \
        elf32-m68hc12.lo \
@@ -509,6 +512,7 @@ BFD32_BACKENDS_CFILES = \
        elf32-i860.c \
        elf32-i960.c \
        elf32-ip2k.c \
+       elf32-iq2000.c \
        elf32-m32r.c \
        elf32-m68k.c \
        elf32-m68hc11.c \
@@ -1454,6 +1458,7 @@ cpu-i386.lo: cpu-i386.c $(INCDIR)/filenames.h
 cpu-i860.lo: cpu-i860.c $(INCDIR)/filenames.h
 cpu-i960.lo: cpu-i960.c $(INCDIR)/filenames.h
 cpu-ip2k.lo: cpu-ip2k.c $(INCDIR)/filenames.h
+cpu-iq2000.lo: cpu-iq2000.c $(INCDIR)/filenames.h
 cpu-m32r.lo: cpu-m32r.c $(INCDIR)/filenames.h
 cpu-m68hc11.lo: cpu-m68hc11.c $(INCDIR)/filenames.h
 cpu-m68hc12.lo: cpu-m68hc12.c $(INCDIR)/filenames.h
@@ -1708,6 +1713,10 @@ elf32-ip2k.lo: elf32-ip2k.c $(INCDIR)/filenames.h elf-bfd.h \
   $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
   $(INCDIR)/bfdlink.h $(INCDIR)/elf/ip2k.h $(INCDIR)/elf/reloc-macros.h \
   elf32-target.h
+elf32-iq2000.lo: elf32-iq2000.c $(INCDIR)/filenames.h elf-bfd.h \
+  $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+  $(INCDIR)/bfdlink.h $(INCDIR)/elf/iq2000.h $(INCDIR)/elf/reloc-macros.h \
+  elf32-target.h
 elf32-m32r.lo: elf32-m32r.c $(INCDIR)/filenames.h elf-bfd.h \
   $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
   $(INCDIR)/bfdlink.h $(INCDIR)/elf/m32r.h $(INCDIR)/elf/reloc-macros.h \
index 4c93cda6aa095f4332053855cee2d21603db3958..f8814442a712d61fd895ee471ed0b7c81d1d000d 100644 (file)
@@ -1,6 +1,6 @@
 /* BFD library support routines for architectures.
    Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-   2000, 2001, 2002
+   2000, 2001, 2002, 2003
    Free Software Foundation, Inc.
    Hacked by John Gilmore and Steve Chamberlain of Cygnus Support.
 
@@ -272,6 +272,9 @@ DESCRIPTION
 .  bfd_arch_ip2k,      {* Ubicom IP2K microcontrollers. *}
 .#define bfd_mach_ip2022       1
 .#define bfd_mach_ip2022ext    2
+. bfd_arch_iq2000,     {* Vitesse IQ2000.  *}
+.#define bfd_mach_iq2000        1
+.#define bfd_mach_iq10          2
 .  bfd_arch_pj,
 .  bfd_arch_avr,       {* Atmel AVR microcontrollers.  *}
 .#define bfd_mach_avr1         1
@@ -360,6 +363,7 @@ extern const bfd_arch_info_type bfd_i860_arch;
 extern const bfd_arch_info_type bfd_i960_arch;
 extern const bfd_arch_info_type bfd_ia64_arch;
 extern const bfd_arch_info_type bfd_ip2k_arch;
+extern const bfd_arch_info_type bfd_iq2000_arch;
 extern const bfd_arch_info_type bfd_m32r_arch;
 extern const bfd_arch_info_type bfd_m68hc11_arch;
 extern const bfd_arch_info_type bfd_m68hc12_arch;
@@ -418,6 +422,7 @@ static const bfd_arch_info_type * const bfd_archures_list[] =
     &bfd_i960_arch,
     &bfd_ia64_arch,
     &bfd_ip2k_arch,
+    &bfd_iq2000_arch,
     &bfd_m32r_arch,
     &bfd_m68hc11_arch,
     &bfd_m68hc12_arch,
index cdcf7ae76221939031329b16880349e0d91637c5..f679fccaa7d082edfade3c0bacd20ecd88de9fe2 100644 (file)
@@ -1699,6 +1699,9 @@ enum bfd_architecture
   bfd_arch_ip2k,      /* Ubicom IP2K microcontrollers. */
 #define bfd_mach_ip2022        1
 #define bfd_mach_ip2022ext     2
+ bfd_arch_iq2000,     /* Vitesse IQ2000.  */
+#define bfd_mach_iq2000        1
+#define bfd_mach_iq10          2
   bfd_arch_pj,
   bfd_arch_avr,       /* Atmel AVR microcontrollers.  */
 #define bfd_mach_avr1          1
@@ -3268,6 +3271,11 @@ to follow the 16K memory bank of 68HC12 (seen as mapped in the window).  */
   BFD_RELOC_MSP430_16,
   BFD_RELOC_MSP430_16_PCREL_BYTE,
   BFD_RELOC_MSP430_16_BYTE,
+
+/* IQ2000 Relocations.  */
+  BFD_RELOC_IQ2000_OFFSET_16,
+  BFD_RELOC_IQ2000_OFFSET_21,
+  BFD_RELOC_IQ2000_UHI16,
   BFD_RELOC_UNUSED };
 typedef enum bfd_reloc_code_real bfd_reloc_code_real_type;
 reloc_howto_type *
index 4379b6f547bc3622ab2cdbfec843c6c6b496296c..ec364a0387397d58c02d1e997252c22d623cc732 100644 (file)
@@ -553,6 +553,10 @@ case "${targ}" in
     targ_defvec=bfd_elf32_ip2k_vec
     ;;
 
+  iq2000-*-elf)
+    targ_defvec=bfd_elf32_iq2000_vec
+    ;;
+
   m32r-*-*)
     targ_defvec=bfd_elf32_m32r_vec
     ;;
index 6d68944b2e0d087769827eae68b8c2f04c11e24c..f41ac1d3cfaad4ac299d9ca1cd4517ed56699147 100755 (executable)
@@ -6094,6 +6094,7 @@ do
     bfd_elf32_ia64_big_vec)    tb="$tb elf32-ia64.lo elf32.lo $elf" ;;
     bfd_elf32_ia64_hpux_big_vec) tb="$tb elf32-ia64.lo elf32.lo $elf";;
     bfd_elf32_ip2k_vec)                tb="$tb elf32-ip2k.lo elf32.lo $elf" ;;
+    bfd_elf32_iq2000_vec)       tb="$tb elf32-iq2000.lo elf32.lo $elf" ;;
     bfd_elf32_little_generic_vec) tb="$tb elf32-gen.lo elf32.lo $elf" ;;
     bfd_elf32_littlearc_vec)   tb="$tb elf32-arc.lo elf32.lo $elf" ;;
     bfd_elf32_littlearm_oabi_vec) tb="$tb elfarm-oabi.lo elf32.lo $elf" ;;
index e641e7361a71c0a0261500001327254eb99cb01d..82dc090428f85681d278ec67340949330746447c 100644 (file)
@@ -590,6 +590,7 @@ do
     bfd_elf32_ia64_big_vec)    tb="$tb elf32-ia64.lo elf32.lo $elf" ;;
     bfd_elf32_ia64_hpux_big_vec) tb="$tb elf32-ia64.lo elf32.lo $elf";;
     bfd_elf32_ip2k_vec)                tb="$tb elf32-ip2k.lo elf32.lo $elf" ;;
+    bfd_elf32_iq2000_vec)       tb="$tb elf32-iq2000.lo elf32.lo $elf" ;;
     bfd_elf32_little_generic_vec) tb="$tb elf32-gen.lo elf32.lo $elf" ;;
     bfd_elf32_littlearc_vec)   tb="$tb elf32-arc.lo elf32.lo $elf" ;;
     bfd_elf32_littlearm_oabi_vec) tb="$tb elfarm-oabi.lo elf32.lo $elf" ;;
diff --git a/bfd/cpu-iq2000.c b/bfd/cpu-iq2000.c
new file mode 100644 (file)
index 0000000..fd6d230
--- /dev/null
@@ -0,0 +1,57 @@
+/* BFD support for the Vitesse IQ2000 processor.
+   Copyright (C) 2003 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"
+
+static const bfd_arch_info_type arch_info_struct[] =
+{
+  32,                          /* bits per word */
+  32,                          /* bits per address */
+  8,                           /* bits per byte */
+  bfd_arch_iq2000,             /* architecture */
+  bfd_mach_iq10,               /* machine */
+  "iq2000",                    /* architecture name */
+  "iq10",                      /* printable name */
+  3,                           /* 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_iq2000_arch =
+{
+  32,                          /* bits per word */
+  32,                          /* bits per address */
+  8,                           /* bits per byte */
+  bfd_arch_iq2000,             /* architecture */
+  bfd_mach_iq2000,             /* machine */
+  "iq2000",                    /* architecture name */
+  "iq2000",                    /* printable name */
+  3,                           /* 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-iq2000.c b/bfd/elf32-iq2000.c
new file mode 100644 (file)
index 0000000..c4261bf
--- /dev/null
@@ -0,0 +1,974 @@
+/* IQ2000-specific support for 32-bit ELF.
+   Copyright (C) 2003 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/iq2000.h"
+
+/* Forward declarations.  */
+
+/* Private relocation functions.  */
+static bfd_reloc_status_type iq2000_elf_relocate_hi16         PARAMS ((bfd *, Elf_Internal_Rela *, bfd_byte *, bfd_vma));
+static reloc_howto_type *    iq2000_reloc_type_lookup         PARAMS ((bfd *, bfd_reloc_code_real_type));
+static void                 iq2000_info_to_howto_rela         PARAMS ((bfd *, arelent *, Elf_Internal_Rela *));
+static bfd_boolean          iq2000_elf_relocate_section       PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *, Elf_Internal_Rela *, Elf_Internal_Sym *, asection **));
+static bfd_reloc_status_type iq2000_final_link_relocate               PARAMS ((reloc_howto_type *, bfd *, asection *, bfd_byte *, Elf_Internal_Rela *, bfd_vma));
+static bfd_boolean          iq2000_elf_gc_sweep_hook          PARAMS ((bfd *, struct bfd_link_info *, asection *, const Elf_Internal_Rela *));
+static asection *           iq2000_elf_gc_mark_hook           PARAMS ((asection *sec, struct bfd_link_info *, Elf_Internal_Rela *, struct elf_link_hash_entry *, Elf_Internal_Sym *));
+static reloc_howto_type *    iq2000_reloc_type_lookup         PARAMS ((bfd *, bfd_reloc_code_real_type));
+static int                  elf32_iq2000_machine              PARAMS ((bfd *));
+static bfd_boolean          iq2000_elf_object_p               PARAMS ((bfd *));
+static bfd_boolean          iq2000_elf_set_private_flags      PARAMS ((bfd *, flagword));
+static bfd_boolean          iq2000_elf_copy_private_bfd_data  PARAMS ((bfd *, bfd *));
+static bfd_boolean          iq2000_elf_merge_private_bfd_data PARAMS ((bfd *, bfd *));
+static bfd_boolean          iq2000_elf_print_private_bfd_data PARAMS ((bfd *, PTR));
+static bfd_boolean          iq2000_elf_check_relocs           PARAMS ((bfd *, struct bfd_link_info *, asection *, const Elf_Internal_Rela *));
+static bfd_reloc_status_type iq2000_elf_howto_hi16_reloc       PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
+
+\f
+static reloc_howto_type iq2000_elf_howto_table [] =
+{
+  /* This reloc does nothing.  */
+
+  HOWTO (R_IQ2000_NONE,                     /* type */
+        0,                          /* rightshift */
+        2,                          /* size (0 = byte, 1 = short, 2 = long) */
+        32,                         /* bitsize */
+        FALSE,                      /* pc_relative */
+        0,                          /* bitpos */
+        complain_overflow_bitfield, /* complain_on_overflow */
+        bfd_elf_generic_reloc,      /* special_function */
+        "R_IQ2000_NONE",            /* name */
+        FALSE,                      /* partial_inplace */
+        0,                          /* src_mask */
+        0,                          /* dst_mask */
+        FALSE),                     /* pcrel_offset */
+
+  /* A 16 bit absolute relocation.  */
+  HOWTO (R_IQ2000_16,               /* type */
+        0,                          /* rightshift */
+        1,                          /* size (0 = byte, 1 = short, 2 = long) */
+        16,                         /* bitsize */
+        FALSE,                      /* pc_relative */
+        0,                          /* bitpos */
+        complain_overflow_bitfield, /* complain_on_overflow */
+        bfd_elf_generic_reloc,      /* special_function */
+        "R_IQ2000_16",              /* name */
+        FALSE,                      /* partial_inplace */
+        0x0000,                     /* src_mask */
+        0xffff,                     /* dst_mask */
+        FALSE),                     /* pcrel_offset */
+
+  /* A 32 bit absolute relocation.  */
+  HOWTO (R_IQ2000_32,               /* type */
+        0,                          /* rightshift */
+        2,                          /* size (0 = byte, 1 = short, 2 = long) */
+        31,                         /* bitsize */
+        FALSE,                      /* pc_relative */
+        0,                          /* bitpos */
+        complain_overflow_bitfield, /* complain_on_overflow */
+        bfd_elf_generic_reloc,      /* special_function */
+        "R_IQ2000_32",              /* name */
+        FALSE,                      /* partial_inplace */
+        0x00000000,                 /* src_mask */
+        0x7fffffff,                 /* dst_mask */
+        FALSE),                     /* pcrel_offset */
+
+  /* 26 bit branch address.  */
+  HOWTO (R_IQ2000_26,          /* type */
+        2,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        26,                    /* bitsize */
+        FALSE,                 /* pc_relative */
+        0,                     /* bitpos */
+        complain_overflow_dont, /* complain_on_overflow */
+                               /* This needs complex overflow
+                                  detection, because the upper four
+                                  bits must match the PC.  */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_IQ2000_26",         /* name */
+        FALSE,                 /* partial_inplace */
+        0x00000000,            /* src_mask */
+        0x03ffffff,            /* dst_mask */
+        FALSE),                /* pcrel_offset */
+
+  /* 16 bit PC relative reference.  */
+  HOWTO (R_IQ2000_PC16,                /* type */
+        2,                     /* 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_IQ2000_PC16",       /* name */
+        FALSE,                 /* partial_inplace */
+        0x0000,                /* src_mask */
+        0xffff,                /* dst_mask */
+        TRUE),                 /* pcrel_offset */
+
+  /* high 16 bits of symbol value.  */
+  HOWTO (R_IQ2000_HI16,                /* type */
+        16,                    /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        15,                    /* bitsize */
+        FALSE,                 /* pc_relative */
+        0,                     /* bitpos */
+        complain_overflow_dont, /* complain_on_overflow */
+        iq2000_elf_howto_hi16_reloc,   /* special_function */
+        "R_IQ2000_HI16",       /* name */
+        FALSE,                 /* partial_inplace */
+        0x0000,                /* src_mask */
+        0x7fff,                /* dst_mask */
+        FALSE),                /* pcrel_offset */
+
+  /* Low 16 bits of symbol value.  */
+  HOWTO (R_IQ2000_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_IQ2000_LO16",       /* name */
+        FALSE,                 /* partial_inplace */
+        0x0000,                /* src_mask */
+        0xffff,                /* dst_mask */
+        FALSE),                /* pcrel_offset */
+
+  /* 16-bit jump offset.  */
+  HOWTO (R_IQ2000_OFFSET_16,   /* type */
+        2,                     /* 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_IQ2000_OFFSET_16",  /* name */
+        FALSE,                 /* partial_inplace */
+        0x0000,                /* src_mask */
+        0xffff,                /* dst_mask */
+        FALSE),                /* pcrel_offset */
+
+  /* 21-bit jump offset.  */
+  HOWTO (R_IQ2000_OFFSET_21,   /* type */
+        2,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        21,                    /* bitsize */
+        FALSE,                 /* pc_relative */
+        0,                     /* bitpos */
+        complain_overflow_dont, /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_IQ2000_OFFSET_21",  /* name */
+        FALSE,                 /* partial_inplace */
+        0x000000,              /* src_mask */
+        0x1fffff,              /* dst_mask */
+        FALSE),                /* pcrel_offset */
+
+  /* unsigned high 16 bits of value.  */
+  HOWTO (R_IQ2000_OFFSET_21,   /* type */
+        16,                    /* 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_IQ2000_UHI16",      /* name */
+        FALSE,                 /* partial_inplace */
+        0x0000,                /* src_mask */
+        0x7fff,                /* dst_mask */
+        FALSE),                /* pcrel_offset */
+
+  /* A 32 bit absolute debug relocation.  */
+  HOWTO (R_IQ2000_32_DEBUG,         /* type */
+        0,                          /* rightshift */
+        2,                          /* size (0 = byte, 1 = short, 2 = long) */
+        32,                         /* bitsize */
+        FALSE,                      /* pc_relative */
+        0,                          /* bitpos */
+        complain_overflow_bitfield, /* complain_on_overflow */
+        bfd_elf_generic_reloc,      /* special_function */
+        "R_IQ2000_32",              /* name */
+        FALSE,                      /* partial_inplace */
+        0x00000000,                 /* src_mask */
+        0xffffffff,                 /* dst_mask */
+        FALSE),                     /* pcrel_offset */
+
+};
+
+/* GNU extension to record C++ vtable hierarchy.  */
+static reloc_howto_type iq2000_elf_vtinherit_howto =
+  HOWTO (R_IQ2000_GNU_VTINHERIT,    /* type */
+        0,                        /* rightshift */
+        2,                        /* size (0 = byte, 1 = short, 2 = long) */
+        0,                        /* bitsize */
+        FALSE,                    /* pc_relative */
+        0,                        /* bitpos */
+        complain_overflow_dont,   /* complain_on_overflow */
+        NULL,                     /* special_function */
+        "R_IQ2000_GNU_VTINHERIT",  /* name */
+        FALSE,                    /* partial_inplace */
+        0,                        /* src_mask */
+        0,                        /* dst_mask */
+        FALSE);                   /* pcrel_offset */
+
+/* GNU extension to record C++ vtable member usage.  */
+static reloc_howto_type iq2000_elf_vtentry_howto =
+  HOWTO (R_IQ2000_GNU_VTENTRY,    /* type */
+        0,                        /* rightshift */
+        2,                        /* size (0 = byte, 1 = short, 2 = long) */
+        0,                        /* bitsize */
+        FALSE,                    /* pc_relative */
+        0,                        /* bitpos */
+        complain_overflow_dont,   /* complain_on_overflow */
+        NULL,                     /* special_function */
+        "R_IQ2000_GNU_VTENTRY",    /* name */
+        FALSE,                    /* partial_inplace */
+        0,                        /* src_mask */
+        0,                        /* dst_mask */
+        FALSE);                   /* pcrel_offset */
+
+\f
+/* Map BFD reloc types to IQ2000 ELF reloc types.  */
+
+struct iq2000_reloc_map
+{
+  bfd_reloc_code_real_type bfd_reloc_val;
+  unsigned int iq2000_reloc_val;
+};
+
+static const struct iq2000_reloc_map iq2000_reloc_map [] =
+{
+  { BFD_RELOC_NONE,           R_IQ2000_NONE },
+  { BFD_RELOC_16,             R_IQ2000_16 },
+  { BFD_RELOC_32,             R_IQ2000_32 },
+  { BFD_RELOC_MIPS_JMP,               R_IQ2000_26 },
+  { BFD_RELOC_16_PCREL_S2,     R_IQ2000_PC16 },
+  { BFD_RELOC_HI16,           R_IQ2000_HI16 },
+  { BFD_RELOC_LO16,           R_IQ2000_LO16 },
+  { BFD_RELOC_IQ2000_OFFSET_16,R_IQ2000_OFFSET_16 },
+  { BFD_RELOC_IQ2000_OFFSET_21,R_IQ2000_OFFSET_21 },
+  { BFD_RELOC_IQ2000_UHI16,    R_IQ2000_UHI16 },
+  { BFD_RELOC_VTABLE_INHERIT,  R_IQ2000_GNU_VTINHERIT },
+  { BFD_RELOC_VTABLE_ENTRY,    R_IQ2000_GNU_VTENTRY },
+};
+
+static bfd_reloc_status_type
+iq2000_elf_howto_hi16_reloc (abfd,
+                    reloc_entry,
+                    symbol,
+                    data,
+                    input_section,
+                    output_bfd,
+                    error_message)
+     bfd *abfd ATTRIBUTE_UNUSED;
+     arelent *reloc_entry;
+     asymbol *symbol;
+     PTR data;
+     asection *input_section;
+     bfd *output_bfd;
+     char **error_message ATTRIBUTE_UNUSED;
+{
+  bfd_reloc_status_type ret;
+  bfd_vma relocation;
+
+  /* If we're relocating, and this an external symbol, we don't want
+     to change anything.  */
+  if (output_bfd != (bfd *) NULL
+      && (symbol->flags & BSF_SECTION_SYM) == 0
+      && reloc_entry->addend == 0)
+    {
+      reloc_entry->address += input_section->output_offset;
+      return bfd_reloc_ok;
+    }
+
+  if (bfd_is_com_section (symbol->section))
+    relocation = 0;
+  else
+    relocation = symbol->value;
+
+  relocation += symbol->section->output_section->vma;
+  relocation += symbol->section->output_offset;
+  relocation += reloc_entry->addend;
+
+  /* if %lo will have sign-extension, compensate by add 0x10000 to hi portion */
+  if (relocation & 0x8000)
+    reloc_entry->addend += 0x10000;
+
+  /* Now do the reloc in the usual way.         */
+  ret = bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data,
+                               input_section, output_bfd, error_message);
+
+  /* put it back the way it was */
+  if (relocation & 0x8000)
+    reloc_entry->addend -= 0x10000;
+
+  return ret;
+}
+
+static bfd_reloc_status_type
+iq2000_elf_relocate_hi16 (input_bfd, relhi, contents, value)
+     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 &= 0x7fffffff; /* mask off top-bit which is Harvard mask bit */
+
+  /* if top-bit of %lo value is on, this means that %lo will
+     sign-propagate and so we compensate by adding 1 to %hi value */
+  if (value & 0x8000)
+    value += 0x10000;
+
+  value >>= 16; 
+  insn = ((insn & ~0xFFFF) | value);
+
+  bfd_put_32 (input_bfd, insn, contents + relhi->r_offset);
+  return bfd_reloc_ok;
+}
+
+static reloc_howto_type *
+iq2000_reloc_type_lookup (abfd, code)
+     bfd * abfd ATTRIBUTE_UNUSED;
+     bfd_reloc_code_real_type code;
+{
+  /* Note that the iq2000_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/iq2000.h.  */
+
+  switch (code)
+    {
+    case BFD_RELOC_NONE:
+      return &iq2000_elf_howto_table[ (int) R_IQ2000_NONE];
+    case BFD_RELOC_16:
+      return &iq2000_elf_howto_table[ (int) R_IQ2000_16];
+    case BFD_RELOC_32:
+      return &iq2000_elf_howto_table[ (int) R_IQ2000_32];
+    case BFD_RELOC_MIPS_JMP:
+      return &iq2000_elf_howto_table[ (int) R_IQ2000_26];
+    case BFD_RELOC_IQ2000_OFFSET_16:
+      return &iq2000_elf_howto_table[ (int) R_IQ2000_OFFSET_16];
+    case BFD_RELOC_IQ2000_OFFSET_21:
+      return &iq2000_elf_howto_table[ (int) R_IQ2000_OFFSET_21];
+    case BFD_RELOC_16_PCREL_S2:
+      return &iq2000_elf_howto_table[ (int) R_IQ2000_PC16];
+    case BFD_RELOC_HI16:
+      return &iq2000_elf_howto_table[ (int) R_IQ2000_HI16];
+    case BFD_RELOC_IQ2000_UHI16:
+      return &iq2000_elf_howto_table[ (int) R_IQ2000_UHI16];
+    case BFD_RELOC_LO16:
+      return &iq2000_elf_howto_table[ (int) R_IQ2000_LO16];
+    case BFD_RELOC_VTABLE_INHERIT:
+      return &iq2000_elf_vtinherit_howto;
+    case BFD_RELOC_VTABLE_ENTRY:
+      return &iq2000_elf_vtentry_howto;
+    default:
+      /* Pacify gcc -Wall.  */
+      return NULL;
+    }
+  return NULL;
+}
+
+\f
+/* Perform a single relocation.         By default we use the standard BFD
+   routines.  */
+
+static bfd_reloc_status_type
+iq2000_final_link_relocate (howto, input_bfd, input_section, contents, rel, relocation)
+     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);
+}
+\f
+/* Set the howto pointer for a IQ2000 ELF reloc.  */
+
+static void
+iq2000_info_to_howto_rela (abfd, cache_ptr, dst)
+     bfd * abfd ATTRIBUTE_UNUSED;
+     arelent * cache_ptr;
+     Elf_Internal_Rela * dst;
+{
+  unsigned int r_type;
+
+  r_type = ELF32_R_TYPE (dst->r_info);
+  switch (r_type)
+    {
+    case R_IQ2000_GNU_VTINHERIT:
+      cache_ptr->howto = & iq2000_elf_vtinherit_howto;
+      break;
+
+    case R_IQ2000_GNU_VTENTRY:
+      cache_ptr->howto = & iq2000_elf_vtentry_howto;
+      break;
+
+    default:
+      cache_ptr->howto = & iq2000_elf_howto_table [r_type];
+      break;
+    }
+}
+
+/* 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
+iq2000_elf_check_relocs (abfd, info, sec, 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, **sym_hashes_end;
+  Elf_Internal_Rela *rel;
+  Elf_Internal_Rela *rel_end;
+  
+  if (info->relocateable)
+    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];
+      
+      switch (ELF32_R_TYPE (rel->r_info))
+       {
+         /* This relocation describes the C++ object vtable hierarchy.
+            Reconstruct it for later use during GC.  */
+       case R_IQ2000_GNU_VTINHERIT:
+         if (!_bfd_elf32_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
+           return FALSE;
+         break;
+         
+         /* This relocation describes which C++ vtable entries are actually
+            used.  Record for later use during GC.  */
+       case R_IQ2000_GNU_VTENTRY:
+         if (!_bfd_elf32_gc_record_vtentry (abfd, sec, h, rel->r_addend))
+           return FALSE;
+         break;
+
+       case R_IQ2000_32:
+         /* For debug section, change to special harvard-aware relocations */
+         if (memcmp (sec->name, ".debug", 6) == 0
+             || memcmp (sec->name, ".stab", 5) == 0
+             || memcmp (sec->name, ".eh_frame", 9) == 0)
+           rel->r_info = ELF32_R_INFO (ELF32_R_SYM (rel->r_info), R_IQ2000_32_DEBUG);
+         break;
+       }
+    }
+  return TRUE;
+}
+
+\f
+/* Relocate a IQ2000 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 relocateable
+   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 relocateable 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
+iq2000_elf_relocate_section (output_bfd, info, input_bfd, input_section,
+                          contents, relocs, local_syms, local_sections)
+     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);
+      
+      if (   r_type == R_IQ2000_GNU_VTINHERIT
+         || r_type == R_IQ2000_GNU_VTENTRY)
+       continue;
+      
+      r_symndx = ELF32_R_SYM (rel->r_info);
+
+      /* This is a final link. */
+      howto  = iq2000_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 = (sec->output_section->vma
+                       + sec->output_offset
+                       + sym->st_value);
+         
+         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;
+#ifdef DEBUG
+         fprintf (stderr, "local: sec: %s, sym: %s (%d), value: %x + %x + %x addend %x\n",
+                  sec->name, name, sym->st_name,
+                  sec->output_section->vma, sec->output_offset,
+                  sym->st_value, rel->r_addend);
+#endif
+       }
+      else
+       {
+         h = sym_hashes [r_symndx];
+         
+         while (h->root.type == bfd_link_hash_indirect
+                || h->root.type == bfd_link_hash_warning)
+           h = (struct elf_link_hash_entry *) h->root.u.i.link;
+
+         name = h->root.root.string;
+         
+         if (h->root.type == bfd_link_hash_defined
+             || h->root.type == bfd_link_hash_defweak)
+           {
+             sec = h->root.u.def.section;
+             relocation = (h->root.u.def.value
+                           + sec->output_section->vma
+                           + sec->output_offset);
+#ifdef DEBUG
+             fprintf (stderr,
+                      "defined: sec: %s, name: %s, value: %x + %x + %x gives: %x\n",
+                      sec->name, name, h->root.u.def.value,
+                      sec->output_section->vma, sec->output_offset, relocation);
+#endif
+           }
+         else if (h->root.type == bfd_link_hash_undefweak)
+           {
+#ifdef DEBUG
+             fprintf (stderr, "undefined: sec: %s, name: %s\n",
+                      sec->name, name);
+#endif
+             relocation = 0;
+           }
+         else
+           {
+             if (! ((*info->callbacks->undefined_symbol)
+                    (info, h->root.root.string, input_bfd,
+                     input_section, rel->r_offset,
+                    (!info->shared || info->no_undefined))))
+               return FALSE;
+#ifdef DEBUG
+             fprintf (stderr, "unknown: name: %s\n", name);
+#endif
+             relocation = 0;
+           }
+       }
+
+      switch (r_type)
+       {
+       case R_IQ2000_HI16:
+         r = iq2000_elf_relocate_hi16 (input_bfd, rel, contents, relocation);
+         break;
+
+       case R_IQ2000_PC16:
+         rel->r_addend -= 4;
+         /* Fall through.  */
+
+       default:
+         r = iq2000_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, 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_notsupported:
+             msg = _("internal error: unsupported relocation 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;
+}
+\f
+
+/* Update the got entry reference counts for the section being
+   removed.  */
+
+static bfd_boolean
+iq2000_elf_gc_sweep_hook (abfd, info, sec, relocs)
+     bfd *                    abfd ATTRIBUTE_UNUSED;
+     struct bfd_link_info *    info ATTRIBUTE_UNUSED;
+     asection *                       sec ATTRIBUTE_UNUSED;
+     const Elf_Internal_Rela * relocs ATTRIBUTE_UNUSED;
+{
+  return TRUE;
+}
+
+/* Return the section that should be marked against GC for a given
+   relocation. */
+
+static asection *
+iq2000_elf_gc_mark_hook (sec, info, rel, h, sym)
+     asection *                          sec;
+     struct bfd_link_info *      info ATTRIBUTE_UNUSED;
+     Elf_Internal_Rela *         rel;
+     struct elf_link_hash_entry * h;
+     Elf_Internal_Sym *                  sym;
+{
+  if (h != NULL)
+    {
+      switch (ELF32_R_TYPE (rel->r_info))
+       {
+       case R_IQ2000_GNU_VTINHERIT:
+       case R_IQ2000_GNU_VTENTRY:
+         break;
+         
+       default:
+         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
+    return bfd_section_from_elf_index (sec->owner, sym->st_shndx);
+
+  return NULL;
+}
+
+\f
+/* Return the MACH for an e_flags value.  */
+
+static int
+elf32_iq2000_machine (abfd)
+     bfd *abfd;
+{
+  switch (elf_elfheader (abfd)->e_flags & EF_IQ2000_CPU_MASK)
+    {
+    case EF_IQ2000_CPU_IQ2000: return bfd_mach_iq2000;
+    case EF_IQ2000_CPU_IQ10:  return bfd_mach_iq10;
+    }
+
+  return bfd_mach_iq2000;
+}
+
+\f
+/* Function to set the ELF flag bits.  */
+
+static bfd_boolean
+iq2000_elf_set_private_flags (abfd, flags)
+     bfd *abfd;
+     flagword flags;
+{
+  elf_elfheader (abfd)->e_flags = flags;
+  elf_flags_init (abfd) = TRUE;
+  return TRUE;
+}
+
+/* Copy backend specific data from one object module to another.  */
+
+static bfd_boolean
+iq2000_elf_copy_private_bfd_data (ibfd, obfd)
+     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
+iq2000_elf_merge_private_bfd_data (ibfd, obfd)
+     bfd *ibfd;
+     bfd *obfd;
+{
+  flagword old_flags, old_partial;
+  flagword new_flags, new_partial;
+  bfd_boolean error = FALSE;
+  char new_opt[80];
+  char old_opt[80];
+
+  new_opt[0] = old_opt[0] = '\0';
+  new_flags = elf_elfheader (ibfd)->e_flags;
+  old_flags = elf_elfheader (obfd)->e_flags;
+
+#ifdef DEBUG
+  (*_bfd_error_handler) ("old_flags = 0x%.8lx, new_flags = 0x%.8lx, init = %s, filename = %s",
+                        old_flags, new_flags, elf_flags_init (obfd) ? "yes" : "no",
+                        bfd_get_filename (ibfd));
+#endif
+
+  if (!elf_flags_init (obfd))
+    {
+      /* First call, no flags set.  */
+      elf_flags_init (obfd) = TRUE;
+      elf_elfheader (obfd)->e_flags = new_flags;
+    }
+
+  else if (new_flags == old_flags)
+    /* Compatible flags are ok.         */
+    ;
+
+  else         /* Possibly incompatible flags.  */
+    {
+      /* Warn if different cpu is used (allow a specific cpu to override
+        the generic cpu).  */
+      new_partial = (new_flags & EF_IQ2000_CPU_MASK);
+      old_partial = (old_flags & EF_IQ2000_CPU_MASK);
+      if (new_partial == old_partial)
+       ;
+
+      else
+       {
+         switch (new_partial)
+           {
+           default:              strcat (new_opt, " -m2000");  break;
+           case EF_IQ2000_CPU_IQ2000:  strcat (new_opt, " -m2000");  break;
+           case EF_IQ2000_CPU_IQ10:  strcat (new_opt, " -m10");  break;
+           }
+
+         switch (old_partial)
+           {
+           default:              strcat (old_opt, " -m2000");  break;
+           case EF_IQ2000_CPU_IQ2000:  strcat (old_opt, " -m2000");  break;
+           case EF_IQ2000_CPU_IQ10:  strcat (old_opt, " -m10");  break;
+           }
+       }
+      
+      /* Print out any mismatches from above.  */
+      if (new_opt[0])
+       {
+         error = TRUE;
+         (*_bfd_error_handler)
+           (_("%s: compiled with %s and linked with modules compiled with %s"),
+            bfd_get_filename (ibfd), new_opt, old_opt);
+       }
+
+      new_flags &= ~ EF_IQ2000_ALL_FLAGS;
+      old_flags &= ~ EF_IQ2000_ALL_FLAGS;
+
+      /* Warn about any other mismatches.  */
+      if (new_flags != old_flags)
+       {
+         error = TRUE;
+         (*_bfd_error_handler)
+           (_("%s: uses different e_flags (0x%lx) fields than previous modules (0x%lx)"),
+            bfd_get_filename (ibfd), (long)new_flags, (long)old_flags);
+       }
+    }
+
+  if (error)
+    bfd_set_error (bfd_error_bad_value);
+
+  return !error;
+}
+
+\f
+static bfd_boolean
+iq2000_elf_print_private_bfd_data (abfd, ptr)
+     bfd *abfd;
+     PTR 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_IQ2000_CPU_MASK)
+    {
+    default:                                                   break;
+    case EF_IQ2000_CPU_IQ2000: fprintf (file, " -m2000");      break;
+    case EF_IQ2000_CPU_IQ10:  fprintf (file, " -m10"); break;
+    }
+
+  fputc ('\n', file);
+}
+
+static
+bfd_boolean
+iq2000_elf_object_p (abfd)
+     bfd *abfd;
+{
+  /* Irix 5 and 6 is broken.  Object file symbol tables are not always
+     sorted correctly such that local symbols precede global symbols,
+     and the sh_info field in the symbol table is not always right.  */
+  elf_bad_symtab (abfd) = TRUE;
+
+  bfd_default_set_arch_mach (abfd, bfd_arch_iq2000,
+                            elf32_iq2000_machine (abfd));
+  return TRUE;
+}
+
+\f
+#define ELF_ARCH               bfd_arch_iq2000
+#define ELF_MACHINE_CODE       EM_IQ2000
+#define ELF_MAXPAGESIZE                0x1000
+
+#define TARGET_BIG_SYM         bfd_elf32_iq2000_vec
+#define TARGET_BIG_NAME                "elf32-iq2000"
+
+#define elf_info_to_howto_rel                  NULL
+#define elf_info_to_howto                      iq2000_info_to_howto_rela
+#define elf_backend_relocate_section           iq2000_elf_relocate_section
+#define elf_backend_gc_mark_hook               iq2000_elf_gc_mark_hook
+#define elf_backend_gc_sweep_hook              iq2000_elf_gc_sweep_hook
+#define elf_backend_check_relocs               iq2000_elf_check_relocs
+#define elf_backend_object_p                   iq2000_elf_object_p
+#define elf_backend_rela_normal                        1
+
+#define elf_backend_can_gc_sections            1
+
+#define bfd_elf32_bfd_reloc_type_lookup                iq2000_reloc_type_lookup
+#define bfd_elf32_bfd_set_private_flags                iq2000_elf_set_private_flags
+#define bfd_elf32_bfd_copy_private_bfd_data    iq2000_elf_copy_private_bfd_data
+#define bfd_elf32_bfd_merge_private_bfd_data   iq2000_elf_merge_private_bfd_data
+#define bfd_elf32_bfd_print_private_bfd_data   iq2000_elf_print_private_bfd_data
+
+#include "elf32-target.h"
index 3a3a8a03c500c3501b4e9096a865cf7c49ee5cc0..98f06a8bfff5e141a9637d917f4a674316cdea86 100644 (file)
@@ -1378,6 +1378,9 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
   "BFD_RELOC_MSP430_16",
   "BFD_RELOC_MSP430_16_PCREL_BYTE",
   "BFD_RELOC_MSP430_16_BYTE",
+  "BFD_RELOC_IQ2000_OFFSET_16",
+  "BFD_RELOC_IQ2000_OFFSET_21",
+  "BFD_RELOC_IQ2000_UHI16",
  "@@overflow: BFD_RELOC_UNUSED@@",
 };
 #endif
index ebf59aae9f5b05942720667506bf3832728eeeed..661ac4a396b3cc233b05eed3ec6d308e14ecc409 100644 (file)
@@ -1,6 +1,6 @@
 /* BFD support for handling relocation entries.
    Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-   2000, 2001, 2002
+   2000, 2001, 2002, 2003
    Free Software Foundation, Inc.
    Written by Cygnus Support.
 
@@ -3627,6 +3627,15 @@ ENUMX
 ENUMDOC
   msp430 specific relocation codes
 
+ENUM
+  BFD_RELOC_IQ2000_OFFSET_16
+ENUMX
+  BFD_RELOC_IQ2000_OFFSET_21
+ENUMX
+  BFD_RELOC_IQ2000_UHI16
+ENUMDOC
+  IQ2000 Relocations.
+
 ENDSENUM
   BFD_RELOC_UNUSED
 CODE_FRAGMENT
index bebd6a0a1b9f95a9a3190b531e770094c98ea9ed..c541c11ab5502d4408e8cbca1b248e545b613f3c 100644 (file)
@@ -1,6 +1,6 @@
 /* Generic target-file-type support for the BFD library.
    Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-   2000, 2001, 2002
+   2000, 2001, 2002, 2003
    Free Software Foundation, Inc.
    Written by Cygnus Support.
 
@@ -533,6 +533,7 @@ extern const bfd_target bfd_elf32_i960_vec;
 extern const bfd_target bfd_elf32_ia64_big_vec;
 extern const bfd_target bfd_elf32_ia64_hpux_big_vec;
 extern const bfd_target bfd_elf32_ip2k_vec;
+extern const bfd_target bfd_elf32_iq2000_vec;
 extern const bfd_target bfd_elf32_little_generic_vec;
 extern const bfd_target bfd_elf32_littlearc_vec;
 extern const bfd_target bfd_elf32_littlearm_oabi_vec;
@@ -820,6 +821,7 @@ static const bfd_target * const _bfd_target_vector[] = {
 #endif
        &bfd_elf32_ia64_hpux_big_vec,
        &bfd_elf32_ip2k_vec,
+       &bfd_elf32_iq2000_vec,
        &bfd_elf32_little_generic_vec,
        &bfd_elf32_littlearc_vec,
        &bfd_elf32_littlearm_oabi_vec,