bfd/
authorRichard Sandiford <rdsandiford@googlemail.com>
Thu, 18 Dec 2003 10:23:10 +0000 (10:23 +0000)
committerRichard Sandiford <rdsandiford@googlemail.com>
Thu, 18 Dec 2003 10:23:10 +0000 (10:23 +0000)
* elf32-mips.c (elf_mips_howto_table_rel): Replace all uses of
mips_elf_generic_reloc with _bfd_mips_elf_generic_reloc.  Use
_bfd_mips_elf_hi16_reloc for R_MIPS_HI16 and R_MIPS_GNU_REL_HI16,
_bfd_mips_elf_lo16_reloc for R_MIPS_LO16 and R_MIPS_GNU_REL_LO16,
and _bfd_mips_elf_got16_reloc for R_MIPS_GOT16.  Change rightshift
to 16 for R_MIPS_HI16 and R_MIPS_GNU_REL_HI16.
(mips_elf_generic_reloc, struct mips_hi16, mips_elf_hi16_reloc)
(mips_elf_lo16_reloc, mips_elf_got16_reloc): Delete.
(_bfd_mips_elf32_gprel16_reloc): Remove special case.
(mips_elf_gprel32_reloc, mips32_64bit_reloc): Likewise.

* elf64-mips.c (mips_elf64_howto_table_rel): Replace all uses of
mips_elf_generic_reloc with _bfd_mips_elf_generic_reloc.  Use
_bfd_mips_elf_hi16_reloc for R_MIPS_HI16, _bfd_mips_elf_lo16_reloc
for R_MIPS_LO16 and _bfd_mips_elf_got16_reloc for R_MIPS_GOT16.
Change R_MIPS_HI16's rightshift to 16.
(mips_elf64_howto_table_rela): Replace all uses of
mips_elf_generic_reloc with _bfd_mips_elf_generic_reloc.
Use _bfd_mips_elf_generic_reloc for R_MIPS_GOT16 as well.
(mips_elf64_hi16_reloc, mips_elf64_got16_reloc): Delete.
(mips_elf64_shift6_reloc): Remove special case.  Use
_bfd_mips_elf_generic_reloc instead of returning bfd_reloc_continue.

* elfn32-mips.c (prev_reloc_section): Delete.
(prev_reloc_address, prev_reloc_addend): Delete.
(elf_mips_howto_table_rel, elf_mips_howto_table_rela): As for
elf64-mips.c
(GET_RELOC_ADDEND, SET_RELOC_ADDEND): Delete.
(mips_elf_generic_reloc, struct mips_hi16, mips_elf_hi16_reloc)
(mips_elf_lo16_reloc, mips_elf_got16_reloc): Delete.
(mips_elf_gprel16_reloc): Delete use of GET_RELOC_ADDEND.
(mips_elf_literal_reloc, mips_elf_gprel32_reloc): Likewise.
(mips16_jump_reloc, mips16_gprel_reloc): Likewise.
(mips_elf_shift6_reloc): Likewise.  Delete use of SET_RELOC_ADDEND.

* elfxx-mips.c (_bfd_mips_elf_gprel16_with_gp): Use
_bfd_relocate_contents to install an in-place addend.
(mips_hi16): New structure.
(mips_hi16_list): Moved from elf32-mips.c.
(_bfd_mips_elf_hi16_reloc, _bfd_mips_elf_got16_reloc): New functions.
(_bfd_mips_elf_lo16_reloc, _bfd_mips_elf_generic_reloc): New functions.
(mips_elf_calculate_relocation): Assume addend is unshifted.
(_bfd_mips_elf_relocate_section): Don't apply the howto rightshift
on top of the usual high-part shift.  Don't shift the addend right
before calling mips_elf_calculate_relocation.

* elfxx-mips.h (_bfd_mips_elf_hi16_reloc): Declare.
(_bfd_mips_elf_got16_reloc, _bfd_mips_elf_lo16_reloc): Declare.
(_bfd_mips_elf_generic_reloc): Declare.

gas/
* config/tc-mips.c (mips_need_elf_addend_fixup): Delete.
(md_apply_fix3): Remove bfd_install_relocation workarounds.
(tc_gen_reloc): Likewise. Factor handling of pc-relative relocations
and treat fx_addnumber as relative to the relocation address.

gas/testsuite/
* gas/mips/mips16-jalx.d: Use -mabi=o64.
* gas/mips/mips16.d: Likewise.
* gas/mips/elf-rel17.[sd]: New test.
* gas/mips/mips.exp: Run it.

14 files changed:
bfd/ChangeLog
bfd/elf32-mips.c
bfd/elf64-mips.c
bfd/elfn32-mips.c
bfd/elfxx-mips.c
bfd/elfxx-mips.h
gas/ChangeLog
gas/config/tc-mips.c
gas/testsuite/ChangeLog
gas/testsuite/gas/mips/elf-rel17.d [new file with mode: 0644]
gas/testsuite/gas/mips/elf-rel17.s [new file with mode: 0644]
gas/testsuite/gas/mips/mips.exp
gas/testsuite/gas/mips/mips16-jalx.d
gas/testsuite/gas/mips/mips16.d

index 4b354be..d818058 100644 (file)
@@ -1,3 +1,55 @@
+2003-12-18  Richard Sandiford  <rsandifo@redhat.com>
+
+       * elf32-mips.c (elf_mips_howto_table_rel): Replace all uses of
+       mips_elf_generic_reloc with _bfd_mips_elf_generic_reloc.  Use
+       _bfd_mips_elf_hi16_reloc for R_MIPS_HI16 and R_MIPS_GNU_REL_HI16,
+       _bfd_mips_elf_lo16_reloc for R_MIPS_LO16 and R_MIPS_GNU_REL_LO16,
+       and _bfd_mips_elf_got16_reloc for R_MIPS_GOT16.  Change rightshift
+       to 16 for R_MIPS_HI16 and R_MIPS_GNU_REL_HI16.
+       (mips_elf_generic_reloc, struct mips_hi16, mips_elf_hi16_reloc)
+       (mips_elf_lo16_reloc, mips_elf_got16_reloc): Delete.
+       (_bfd_mips_elf32_gprel16_reloc): Remove special case.
+       (mips_elf_gprel32_reloc, mips32_64bit_reloc): Likewise.
+
+       * elf64-mips.c (mips_elf64_howto_table_rel): Replace all uses of
+       mips_elf_generic_reloc with _bfd_mips_elf_generic_reloc.  Use
+       _bfd_mips_elf_hi16_reloc for R_MIPS_HI16, _bfd_mips_elf_lo16_reloc
+       for R_MIPS_LO16 and _bfd_mips_elf_got16_reloc for R_MIPS_GOT16.
+       Change R_MIPS_HI16's rightshift to 16.
+       (mips_elf64_howto_table_rela): Replace all uses of
+       mips_elf_generic_reloc with _bfd_mips_elf_generic_reloc.
+       Use _bfd_mips_elf_generic_reloc for R_MIPS_GOT16 as well.
+       (mips_elf64_hi16_reloc, mips_elf64_got16_reloc): Delete.
+       (mips_elf64_shift6_reloc): Remove special case.  Use
+       _bfd_mips_elf_generic_reloc instead of returning bfd_reloc_continue.
+
+       * elfn32-mips.c (prev_reloc_section): Delete.
+       (prev_reloc_address, prev_reloc_addend): Delete.
+       (elf_mips_howto_table_rel, elf_mips_howto_table_rela): As for
+       elf64-mips.c
+       (GET_RELOC_ADDEND, SET_RELOC_ADDEND): Delete.
+       (mips_elf_generic_reloc, struct mips_hi16, mips_elf_hi16_reloc)
+       (mips_elf_lo16_reloc, mips_elf_got16_reloc): Delete.
+       (mips_elf_gprel16_reloc): Delete use of GET_RELOC_ADDEND.
+       (mips_elf_literal_reloc, mips_elf_gprel32_reloc): Likewise.
+       (mips16_jump_reloc, mips16_gprel_reloc): Likewise.
+       (mips_elf_shift6_reloc): Likewise.  Delete use of SET_RELOC_ADDEND.
+
+       * elfxx-mips.c (_bfd_mips_elf_gprel16_with_gp): Use
+       _bfd_relocate_contents to install an in-place addend.
+       (mips_hi16): New structure.
+       (mips_hi16_list): Moved from elf32-mips.c.
+       (_bfd_mips_elf_hi16_reloc, _bfd_mips_elf_got16_reloc): New functions.
+       (_bfd_mips_elf_lo16_reloc, _bfd_mips_elf_generic_reloc): New functions.
+       (mips_elf_calculate_relocation): Assume addend is unshifted.
+       (_bfd_mips_elf_relocate_section): Don't apply the howto rightshift
+       on top of the usual high-part shift.  Don't shift the addend right
+       before calling mips_elf_calculate_relocation.
+
+       * elfxx-mips.h (_bfd_mips_elf_hi16_reloc): Declare.
+       (_bfd_mips_elf_got16_reloc, _bfd_mips_elf_lo16_reloc): Declare.
+       (_bfd_mips_elf_generic_reloc): Declare.
+
 2003-12-16  Eric Youngdale  <eric@mkssoftware.com>
            Nick Clifton  <nickc@redhat.com>
 
index 299c395..27b1c4b 100644 (file)
@@ -47,14 +47,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 #define ECOFF_SIGNED_32
 #include "ecoffswap.h"
 
-static bfd_reloc_status_type mips_elf_generic_reloc
-  (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
-static bfd_reloc_status_type mips_elf_hi16_reloc
-  (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
-static bfd_reloc_status_type mips_elf_lo16_reloc
-  (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
-static bfd_reloc_status_type mips_elf_got16_reloc
-  (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
 static bfd_reloc_status_type gprel32_with_gp
   (bfd *, asymbol *, arelent *, asection *, bfd_boolean, void *, bfd_vma);
 static bfd_reloc_status_type mips_elf_gprel32_reloc
@@ -120,7 +112,7 @@ static reloc_howto_type elf_mips_howto_table_rel[] =
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont, /* complain_on_overflow */
-        mips_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc, /* special_function */
         "R_MIPS_NONE",         /* name */
         FALSE,                 /* partial_inplace */
         0,                     /* src_mask */
@@ -135,7 +127,7 @@ static reloc_howto_type elf_mips_howto_table_rel[] =
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_signed, /* complain_on_overflow */
-        mips_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc, /* special_function */
         "R_MIPS_16",           /* name */
         TRUE,                  /* partial_inplace */
         0x0000ffff,            /* src_mask */
@@ -150,7 +142,7 @@ static reloc_howto_type elf_mips_howto_table_rel[] =
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont, /* complain_on_overflow */
-        mips_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc, /* special_function */
         "R_MIPS_32",           /* name */
         TRUE,                  /* partial_inplace */
         0xffffffff,            /* src_mask */
@@ -165,7 +157,7 @@ static reloc_howto_type elf_mips_howto_table_rel[] =
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont, /* complain_on_overflow */
-        mips_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc, /* special_function */
         "R_MIPS_REL32",        /* name */
         TRUE,                  /* partial_inplace */
         0xffffffff,            /* src_mask */
@@ -183,7 +175,7 @@ static reloc_howto_type elf_mips_howto_table_rel[] =
                                /* This needs complex overflow
                                   detection, because the upper four
                                   bits must match the PC + 4.  */
-        mips_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc, /* special_function */
         "R_MIPS_26",           /* name */
         TRUE,                  /* partial_inplace */
         0x03ffffff,            /* src_mask */
@@ -192,13 +184,13 @@ static reloc_howto_type elf_mips_howto_table_rel[] =
 
   /* High 16 bits of symbol value.  */
   HOWTO (R_MIPS_HI16,          /* type */
-        0,                     /* rightshift */
+        16,                    /* rightshift */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
         16,                    /* bitsize */
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont, /* complain_on_overflow */
-        mips_elf_hi16_reloc,   /* special_function */
+        _bfd_mips_elf_hi16_reloc, /* special_function */
         "R_MIPS_HI16",         /* name */
         TRUE,                  /* partial_inplace */
         0x0000ffff,            /* src_mask */
@@ -213,7 +205,7 @@ static reloc_howto_type elf_mips_howto_table_rel[] =
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont, /* complain_on_overflow */
-        mips_elf_lo16_reloc,   /* special_function */
+        _bfd_mips_elf_lo16_reloc, /* special_function */
         "R_MIPS_LO16",         /* name */
         TRUE,                  /* partial_inplace */
         0x0000ffff,            /* src_mask */
@@ -258,7 +250,7 @@ static reloc_howto_type elf_mips_howto_table_rel[] =
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_signed, /* complain_on_overflow */
-        mips_elf_got16_reloc,  /* special_function */
+        _bfd_mips_elf_got16_reloc, /* special_function */
         "R_MIPS_GOT16",        /* name */
         TRUE,                  /* partial_inplace */
         0x0000ffff,            /* src_mask */
@@ -273,7 +265,7 @@ static reloc_howto_type elf_mips_howto_table_rel[] =
         TRUE,                  /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_signed, /* complain_on_overflow */
-        mips_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc, /* special_function */
         "R_MIPS_PC16",         /* name */
         TRUE,                  /* partial_inplace */
         0x0000ffff,            /* src_mask */
@@ -288,7 +280,7 @@ static reloc_howto_type elf_mips_howto_table_rel[] =
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_signed, /* complain_on_overflow */
-        mips_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc, /* special_function */
         "R_MIPS_CALL16",       /* name */
         TRUE,                  /* partial_inplace */
         0x0000ffff,            /* src_mask */
@@ -324,7 +316,7 @@ static reloc_howto_type elf_mips_howto_table_rel[] =
         FALSE,                 /* pc_relative */
         6,                     /* bitpos */
         complain_overflow_bitfield, /* complain_on_overflow */
-        mips_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc, /* special_function */
         "R_MIPS_SHIFT5",       /* name */
         TRUE,                  /* partial_inplace */
         0x000007c0,            /* src_mask */
@@ -341,7 +333,7 @@ static reloc_howto_type elf_mips_howto_table_rel[] =
         FALSE,                 /* pc_relative */
         6,                     /* bitpos */
         complain_overflow_bitfield, /* complain_on_overflow */
-        mips_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc, /* special_function */
         "R_MIPS_SHIFT6",       /* name */
         TRUE,                  /* partial_inplace */
         0x000007c4,            /* src_mask */
@@ -371,7 +363,7 @@ static reloc_howto_type elf_mips_howto_table_rel[] =
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_signed, /* complain_on_overflow */
-        mips_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc, /* special_function */
         "R_MIPS_GOT_DISP",     /* name */
         TRUE,                  /* partial_inplace */
         0x0000ffff,            /* src_mask */
@@ -386,7 +378,7 @@ static reloc_howto_type elf_mips_howto_table_rel[] =
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_signed, /* complain_on_overflow */
-        mips_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc, /* special_function */
         "R_MIPS_GOT_PAGE",     /* name */
         TRUE,                  /* partial_inplace */
         0x0000ffff,            /* src_mask */
@@ -401,7 +393,7 @@ static reloc_howto_type elf_mips_howto_table_rel[] =
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_signed, /* complain_on_overflow */
-        mips_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc, /* special_function */
         "R_MIPS_GOT_OFST",     /* name */
         TRUE,                  /* partial_inplace */
         0x0000ffff,            /* src_mask */
@@ -416,7 +408,7 @@ static reloc_howto_type elf_mips_howto_table_rel[] =
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont, /* complain_on_overflow */
-        mips_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc, /* special_function */
         "R_MIPS_GOT_HI16",     /* name */
         TRUE,                  /* partial_inplace */
         0x0000ffff,            /* src_mask */
@@ -431,7 +423,7 @@ static reloc_howto_type elf_mips_howto_table_rel[] =
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont, /* complain_on_overflow */
-        mips_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc, /* special_function */
         "R_MIPS_GOT_LO16",     /* name */
         TRUE,                  /* partial_inplace */
         0x0000ffff,            /* src_mask */
@@ -446,7 +438,7 @@ static reloc_howto_type elf_mips_howto_table_rel[] =
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont, /* complain_on_overflow */
-        mips_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc, /* special_function */
         "R_MIPS_SUB",          /* name */
         TRUE,                  /* partial_inplace */
         MINUS_ONE,             /* src_mask */
@@ -466,7 +458,7 @@ static reloc_howto_type elf_mips_howto_table_rel[] =
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont, /* complain_on_overflow */
-        mips_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc, /* special_function */
         "R_MIPS_HIGHER",       /* name */
         TRUE,                  /* partial_inplace */
         0x0000ffff,            /* src_mask */
@@ -481,7 +473,7 @@ static reloc_howto_type elf_mips_howto_table_rel[] =
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont, /* complain_on_overflow */
-        mips_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc, /* special_function */
         "R_MIPS_HIGHEST",      /* name */
         TRUE,                  /* partial_inplace */
         0x0000ffff,            /* src_mask */
@@ -496,7 +488,7 @@ static reloc_howto_type elf_mips_howto_table_rel[] =
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont, /* complain_on_overflow */
-        mips_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc, /* special_function */
         "R_MIPS_CALL_HI16",    /* name */
         TRUE,                  /* partial_inplace */
         0x0000ffff,            /* src_mask */
@@ -511,7 +503,7 @@ static reloc_howto_type elf_mips_howto_table_rel[] =
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont, /* complain_on_overflow */
-        mips_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc, /* special_function */
         "R_MIPS_CALL_LO16",    /* name */
         TRUE,                  /* partial_inplace */
         0x0000ffff,            /* src_mask */
@@ -526,7 +518,7 @@ static reloc_howto_type elf_mips_howto_table_rel[] =
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont, /* complain_on_overflow */
-        mips_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc, /* special_function */
         "R_MIPS_SCN_DISP",     /* name */
         TRUE,                  /* partial_inplace */
         0xffffffff,            /* src_mask */
@@ -547,7 +539,7 @@ static reloc_howto_type elf_mips_howto_table_rel[] =
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont, /* complain_on_overflow */
-        mips_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc, /* special_function */
         "R_MIPS_JALR",         /* name */
         FALSE,                 /* partial_inplace */
         0x00000000,            /* src_mask */
@@ -611,13 +603,13 @@ static reloc_howto_type elf_mips16_gprel_howto =
 /* High 16 bits of symbol value, pc-relative.  */
 static reloc_howto_type elf_mips_gnu_rel_hi16 =
   HOWTO (R_MIPS_GNU_REL_HI16,  /* type */
-        0,                     /* rightshift */
+        16,                    /* rightshift */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
         16,                    /* bitsize */
         TRUE,                  /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont, /* complain_on_overflow */
-        mips_elf_hi16_reloc,   /* special_function */
+        _bfd_mips_elf_hi16_reloc, /* special_function */
         "R_MIPS_GNU_REL_HI16", /* name */
         TRUE,                  /* partial_inplace */
         0xffff,                /* src_mask */
@@ -633,7 +625,7 @@ static reloc_howto_type elf_mips_gnu_rel_lo16 =
         TRUE,                  /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont, /* complain_on_overflow */
-        mips_elf_lo16_reloc,   /* special_function */
+        _bfd_mips_elf_lo16_reloc, /* special_function */
         "R_MIPS_GNU_REL_LO16", /* name */
         TRUE,                  /* partial_inplace */
         0xffff,                /* src_mask */
@@ -649,7 +641,7 @@ static reloc_howto_type elf_mips_gnu_rel16_s2 =
         TRUE,                  /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_signed, /* complain_on_overflow */
-        mips_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc, /* special_function */
         "R_MIPS_GNU_REL16_S2", /* name */
         TRUE,                  /* partial_inplace */
         0xffff,                /* src_mask */
@@ -665,7 +657,7 @@ static reloc_howto_type elf_mips_gnu_pcrel64 =
         TRUE,                  /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_signed, /* complain_on_overflow */
-        mips_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc, /* special_function */
         "R_MIPS_PC64",         /* name */
         TRUE,                  /* partial_inplace */
         MINUS_ONE,             /* src_mask */
@@ -681,7 +673,7 @@ static reloc_howto_type elf_mips_gnu_pcrel32 =
         TRUE,                  /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_signed, /* complain_on_overflow */
-        mips_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc, /* special_function */
         "R_MIPS_PC32",         /* name */
         TRUE,                  /* partial_inplace */
         0xffffffff,            /* src_mask */
@@ -720,260 +712,6 @@ static reloc_howto_type elf_mips_gnu_vtentry_howto =
         0,                     /* dst_mask */
         FALSE);                /* pcrel_offset */
 
-/* We use this instead of bfd_elf_generic_reloc because the latter
-   gets the handling of zero addends wrong. */
-static bfd_reloc_status_type
-mips_elf_generic_reloc (bfd *abfd ATTRIBUTE_UNUSED, arelent *reloc_entry,
-                       asymbol *symbol, void *data ATTRIBUTE_UNUSED,
-                       asection *input_section, bfd *output_bfd,
-                       char **error_message ATTRIBUTE_UNUSED)
-{
-  /* If we're relocating, and this is an external symbol, we don't want
-     to change anything.  */
-  if (output_bfd != NULL
-      && (symbol->flags & BSF_SECTION_SYM) == 0
-      && (symbol->flags & BSF_LOCAL) != 0)
-    {
-      reloc_entry->address += input_section->output_offset;
-      return bfd_reloc_ok;
-    }
-
-  /* Just go on, nothing to see here.  */
-  return bfd_reloc_continue;
-}
-
-/* Do a R_MIPS_HI16 relocation.  This has to be done in combination
-   with a R_MIPS_LO16 reloc, because there is a carry from the LO16 to
-   the HI16.  Here we just save the information we need; we do the
-   actual relocation when we see the LO16.
-
-   MIPS ELF requires that the LO16 immediately follow the HI16.  As a
-   GNU extension, for non-pc-relative relocations, we permit an
-   arbitrary number of HI16 relocs to be associated with a single LO16
-   reloc.  This extension permits gcc to output the HI and LO relocs
-   itself.
-
-   This cannot be done for PC-relative relocations because both the HI16
-   and LO16 parts of the relocations must be done relative to the LO16
-   part, and there can be carry to or borrow from the HI16 part.  */
-
-struct mips_hi16
-{
-  struct mips_hi16 *next;
-  bfd_byte *addr;
-  bfd_vma addend;
-};
-
-/* FIXME: This should not be a static variable.  */
-
-static struct mips_hi16 *mips_hi16_list;
-
-static bfd_reloc_status_type
-mips_elf_hi16_reloc (bfd *abfd ATTRIBUTE_UNUSED, arelent *reloc_entry,
-                    asymbol *symbol, void *data, asection *input_section,
-                    bfd *output_bfd, char **error_message)
-{
-  bfd_reloc_status_type ret;
-  bfd_vma relocation;
-  struct mips_hi16 *n;
-
-  /* If we're relocating, and this is an external symbol, we don't want
-     to change anything.  */
-  if (output_bfd != NULL
-      && (symbol->flags & BSF_SECTION_SYM) == 0
-      && (symbol->flags & BSF_LOCAL) != 0)
-    {
-      reloc_entry->address += input_section->output_offset;
-      return bfd_reloc_ok;
-    }
-
-  ret = bfd_reloc_ok;
-
-  if (strcmp (bfd_asymbol_name (symbol), "_gp_disp") == 0)
-    {
-      bfd_boolean relocatable;
-      bfd_vma gp;
-
-      if (ret == bfd_reloc_undefined)
-       abort ();
-
-      if (output_bfd != NULL)
-       relocatable = TRUE;
-      else
-       {
-         relocatable = FALSE;
-         output_bfd = symbol->section->output_section->owner;
-       }
-
-      ret = mips_elf_final_gp (output_bfd, symbol, relocatable,
-                              error_message, &gp);
-      if (ret != bfd_reloc_ok)
-       return ret;
-
-      relocation = gp - reloc_entry->address;
-    }
-  else
-    {
-      if (bfd_is_und_section (symbol->section) && output_bfd == NULL)
-       ret = bfd_reloc_undefined;
-
-      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 (reloc_entry->address > input_section->_cooked_size)
-    return bfd_reloc_outofrange;
-
-  /* Save the information, and let LO16 do the actual relocation.  */
-  n = bfd_malloc (sizeof *n);
-  if (n == NULL)
-    return bfd_reloc_outofrange;
-  n->addr = (bfd_byte *) data + reloc_entry->address;
-  n->addend = relocation;
-  n->next = mips_hi16_list;
-  mips_hi16_list = n;
-
-  if (output_bfd != NULL)
-    reloc_entry->address += input_section->output_offset;
-
-  return ret;
-}
-
-/* Do a R_MIPS_LO16 relocation.  This is a straightforward 16 bit
-   inplace relocation; this function exists in order to do the
-   R_MIPS_HI16 relocation described above.  */
-
-static bfd_reloc_status_type
-mips_elf_lo16_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
-                    void *data, asection *input_section, bfd *output_bfd,
-                    char **error_message)
-{
-  arelent gp_disp_relent;
-
-  if (mips_hi16_list != NULL)
-    {
-      struct mips_hi16 *l;
-
-      l = mips_hi16_list;
-      while (l != NULL)
-       {
-         unsigned long insn;
-         unsigned long val;
-         unsigned long vallo;
-         struct mips_hi16 *next;
-
-         if (strcmp (bfd_asymbol_name (symbol), "_gp_disp") == 0)
-           {
-             gp_disp_relent = *reloc_entry;
-             reloc_entry = &gp_disp_relent;
-             reloc_entry->addend = l->addend;
-           }
-         else
-           {
-             /* Do the HI16 relocation.  Note that we actually don't need
-                to know anything about the LO16 itself, except where to
-                find the low 16 bits of the addend needed by the LO16.  */
-             insn = bfd_get_32 (abfd, l->addr);
-             vallo = bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address);
-             /* The low order 16 bits are always treated as a signed
-                value.  */
-             vallo = ((vallo & 0xffff) ^ 0x8000) - 0x8000;
-             val = ((insn & 0xffff) << 16) + vallo;
-             val += l->addend;
-
-             /* If PC-relative, we need to subtract out the address of the LO
-                half of the HI/LO.  (The actual relocation is relative
-                to that instruction.)  */
-             if (reloc_entry->howto->pc_relative)
-               val -= reloc_entry->address;
-
-             /* At this point, "val" has the value of the combined HI/LO
-                pair.  If the low order 16 bits (which will be used for
-                the LO16 insn) are negative, then we will need an
-                adjustment for the high order 16 bits.  */
-             val += 0x8000;
-             val = (val >> 16) & 0xffff;
-
-             insn &= ~ (bfd_vma) 0xffff;
-             insn |= val;
-             bfd_put_32 (abfd, insn, l->addr);
-           }
-
-         next = l->next;
-         free (l);
-         l = next;
-       }
-
-      mips_hi16_list = NULL;
-    }
-  else if (strcmp (bfd_asymbol_name (symbol), "_gp_disp") == 0)
-    {
-      bfd_reloc_status_type ret;
-      bfd_vma gp, relocation;
-
-      /* FIXME: Does this case ever occur?  */
-
-      ret = mips_elf_final_gp (output_bfd, symbol, TRUE, error_message, &gp);
-      if (ret != bfd_reloc_ok)
-       return ret;
-
-      relocation = gp - reloc_entry->address;
-      relocation += symbol->section->output_section->vma;
-      relocation += symbol->section->output_offset;
-      relocation += reloc_entry->addend;
-
-      if (reloc_entry->address > input_section->_cooked_size)
-       return bfd_reloc_outofrange;
-
-      gp_disp_relent = *reloc_entry;
-      reloc_entry = &gp_disp_relent;
-      reloc_entry->addend = relocation - 4;
-    }
-
-  /* Now do the LO16 reloc in the usual way.  */
-  return mips_elf_generic_reloc (abfd, reloc_entry, symbol, data,
-                                input_section, output_bfd, error_message);
-}
-
-/* Do a R_MIPS_GOT16 reloc.  This is a reloc against the global offset
-   table used for PIC code.  If the symbol is an external symbol, the
-   instruction is modified to contain the offset of the appropriate
-   entry in the global offset table.  If the symbol is a section
-   symbol, the next reloc is a R_MIPS_LO16 reloc.  The two 16 bit
-   addends are combined to form the real addend against the section
-   symbol; the GOT16 is modified to contain the offset of an entry in
-   the global offset table, and the LO16 is modified to offset it
-   appropriately.  Thus an offset larger than 16 bits requires a
-   modified value in the global offset table.
-
-   This implementation suffices for the assembler, but the linker does
-   not yet know how to create global offset tables.  */
-
-static bfd_reloc_status_type
-mips_elf_got16_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
-                     void *data, asection *input_section, bfd *output_bfd,
-                     char **error_message)
-{
-  /* If we're relocating, and this is an external symbol, we don't want
-     to change anything.  */
-  if (output_bfd != NULL
-      && (symbol->flags & BSF_SECTION_SYM) == 0
-      && (symbol->flags & BSF_LOCAL) != 0)
-    {
-      reloc_entry->address += input_section->output_offset;
-      return bfd_reloc_ok;
-    }
-
-  return mips_elf_hi16_reloc (abfd, reloc_entry, symbol, data,
-                             input_section, output_bfd, error_message);
-}
-
 /* Set the GP value for OUTPUT_BFD.  Returns FALSE if this is a
    dangerous relocation.  */
 
@@ -1078,16 +816,6 @@ _bfd_mips_elf32_gprel16_reloc (bfd *abfd, arelent *reloc_entry,
   bfd_reloc_status_type ret;
   bfd_vma gp;
 
-  /* If we're relocating, and this is an external symbol, we don't want
-     to change anything.  */
-  if (output_bfd != NULL
-      && (symbol->flags & BSF_SECTION_SYM) == 0
-      && (symbol->flags & BSF_LOCAL) != 0)
-    {
-      reloc_entry->address += input_section->output_offset;
-      return bfd_reloc_ok;
-    }
-
   if (output_bfd != NULL)
     relocatable = TRUE;
   else
@@ -1118,17 +846,6 @@ mips_elf_gprel32_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
   bfd_reloc_status_type ret;
   bfd_vma gp;
 
-  /* If we're relocating, and this is an external symbol, we don't want
-     to change anything.  */
-  if (output_bfd != NULL
-      && (symbol->flags & BSF_SECTION_SYM) == 0
-      && (symbol->flags & BSF_LOCAL) != 0)
-    {
-      *error_message = (char *)
-       _("32bits gp relative relocation occurs for an external symbol");
-      return bfd_reloc_outofrange;
-    }
-
   if (output_bfd != NULL)
     relocatable = TRUE;
   else
@@ -1194,20 +911,16 @@ gprel32_with_gp (bfd *abfd, asymbol *symbol, arelent *reloc_entry,
    sign extension.  */
 
 static bfd_reloc_status_type
-mips32_64bit_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
-                   void *data, asection *input_section, bfd *output_bfd,
-                   char **error_message)
+mips32_64bit_reloc (bfd *abfd, arelent *reloc_entry,
+                   asymbol *symbol ATTRIBUTE_UNUSED,
+                   void *data, asection *input_section,
+                   bfd *output_bfd, char **error_message)
 {
   bfd_reloc_status_type r;
   arelent reloc32;
   unsigned long val;
   bfd_size_type addr;
 
-  r = mips_elf_generic_reloc (abfd, reloc_entry, symbol, data,
-                             input_section, output_bfd, error_message);
-  if (r != bfd_reloc_continue)
-    return r;
-
   /* Do a normal 32 bit relocation on the lower 32 bits.  */
   reloc32 = *reloc_entry;
   if (bfd_big_endian (abfd))
index 998c5df..ca0ed6e 100644 (file)
@@ -104,8 +104,6 @@ static void mips_elf64_write_rel
   (bfd *, asection *, Elf_Internal_Shdr *, int *, void *);
 static void mips_elf64_write_rela
   (bfd *, asection *, Elf_Internal_Shdr *, int *, void *);
-static bfd_reloc_status_type mips_elf64_hi16_reloc
-  (bfd *, arelent *, asymbol *,        void *, asection *, bfd *, char **);
 static bfd_reloc_status_type mips_elf64_gprel16_reloc
   (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
 static bfd_reloc_status_type mips_elf64_literal_reloc
@@ -114,8 +112,6 @@ static bfd_reloc_status_type mips_elf64_gprel32_reloc
   (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
 static bfd_reloc_status_type mips_elf64_shift6_reloc
   (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
-static bfd_reloc_status_type mips_elf64_got16_reloc
-  (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
 static bfd_reloc_status_type mips16_jump_reloc
   (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
 static bfd_reloc_status_type mips16_gprel_reloc
@@ -155,7 +151,7 @@ static reloc_howto_type mips_elf64_howto_table_rel[] =
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont, /* complain_on_overflow */
-        bfd_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc,   /* special_function */
         "R_MIPS_NONE",         /* name */
         FALSE,                 /* partial_inplace */
         0,                     /* src_mask */
@@ -170,7 +166,7 @@ static reloc_howto_type mips_elf64_howto_table_rel[] =
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_signed, /* complain_on_overflow */
-        bfd_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc,   /* special_function */
         "R_MIPS_16",           /* name */
         TRUE,                  /* partial_inplace */
         0x0000ffff,            /* src_mask */
@@ -185,7 +181,7 @@ static reloc_howto_type mips_elf64_howto_table_rel[] =
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont, /* complain_on_overflow */
-        bfd_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc,   /* special_function */
         "R_MIPS_32",           /* name */
         TRUE,                  /* partial_inplace */
         0xffffffff,            /* src_mask */
@@ -200,7 +196,7 @@ static reloc_howto_type mips_elf64_howto_table_rel[] =
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont, /* complain_on_overflow */
-        bfd_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc,   /* special_function */
         "R_MIPS_REL32",        /* name */
         TRUE,                  /* partial_inplace */
         0xffffffff,            /* src_mask */
@@ -218,7 +214,7 @@ static reloc_howto_type mips_elf64_howto_table_rel[] =
                                /* This needs complex overflow
                                   detection, because the upper 36
                                   bits must match the PC + 4.  */
-        bfd_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc,   /* special_function */
         "R_MIPS_26",           /* name */
         TRUE,                  /* partial_inplace */
         0x03ffffff,            /* src_mask */
@@ -230,13 +226,13 @@ static reloc_howto_type mips_elf64_howto_table_rel[] =
 
   /* High 16 bits of symbol value.  */
   HOWTO (R_MIPS_HI16,          /* type */
-        0,                     /* rightshift */
+        16,                    /* rightshift */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
         16,                    /* bitsize */
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont, /* complain_on_overflow */
-        mips_elf64_hi16_reloc, /* special_function */
+        _bfd_mips_elf_hi16_reloc, /* special_function */
         "R_MIPS_HI16",         /* name */
         TRUE,                  /* partial_inplace */
         0x0000ffff,            /* src_mask */
@@ -251,7 +247,7 @@ static reloc_howto_type mips_elf64_howto_table_rel[] =
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont, /* complain_on_overflow */
-        bfd_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_lo16_reloc, /* special_function */
         "R_MIPS_LO16",         /* name */
         TRUE,                  /* partial_inplace */
         0x0000ffff,            /* src_mask */
@@ -296,7 +292,7 @@ static reloc_howto_type mips_elf64_howto_table_rel[] =
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_signed, /* complain_on_overflow */
-        mips_elf64_got16_reloc, /* special_function */
+        _bfd_mips_elf_got16_reloc, /* special_function */
         "R_MIPS_GOT16",        /* name */
         TRUE,                  /* partial_inplace */
         0x0000ffff,            /* src_mask */
@@ -311,7 +307,7 @@ static reloc_howto_type mips_elf64_howto_table_rel[] =
         TRUE,                  /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_signed, /* complain_on_overflow */
-        bfd_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc,   /* special_function */
         "R_MIPS_PC16",         /* name */
         TRUE,                  /* partial_inplace */
         0x0000ffff,            /* src_mask */
@@ -326,7 +322,7 @@ static reloc_howto_type mips_elf64_howto_table_rel[] =
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_signed, /* complain_on_overflow */
-        bfd_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc,   /* special_function */
         "R_MIPS_CALL16",       /* name */
         TRUE,                  /* partial_inplace */
         0x0000ffff,            /* src_mask */
@@ -360,7 +356,7 @@ static reloc_howto_type mips_elf64_howto_table_rel[] =
         FALSE,                 /* pc_relative */
         6,                     /* bitpos */
         complain_overflow_bitfield, /* complain_on_overflow */
-        bfd_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc,   /* special_function */
         "R_MIPS_SHIFT5",       /* name */
         TRUE,                  /* partial_inplace */
         0x000007c0,            /* src_mask */
@@ -390,7 +386,7 @@ static reloc_howto_type mips_elf64_howto_table_rel[] =
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont, /* complain_on_overflow */
-        bfd_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc,   /* special_function */
         "R_MIPS_64",           /* name */
         TRUE,                  /* partial_inplace */
         MINUS_ONE,             /* src_mask */
@@ -405,7 +401,7 @@ static reloc_howto_type mips_elf64_howto_table_rel[] =
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_signed, /* complain_on_overflow */
-        bfd_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc,   /* special_function */
         "R_MIPS_GOT_DISP",     /* name */
         TRUE,                  /* partial_inplace */
         0x0000ffff,            /* src_mask */
@@ -420,7 +416,7 @@ static reloc_howto_type mips_elf64_howto_table_rel[] =
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_signed, /* complain_on_overflow */
-        bfd_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc,   /* special_function */
         "R_MIPS_GOT_PAGE",     /* name */
         TRUE,                  /* partial_inplace */
         0x0000ffff,            /* src_mask */
@@ -435,7 +431,7 @@ static reloc_howto_type mips_elf64_howto_table_rel[] =
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_signed, /* complain_on_overflow */
-        bfd_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc,   /* special_function */
         "R_MIPS_GOT_OFST",     /* name */
         TRUE,                  /* partial_inplace */
         0x0000ffff,            /* src_mask */
@@ -450,7 +446,7 @@ static reloc_howto_type mips_elf64_howto_table_rel[] =
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont, /* complain_on_overflow */
-        bfd_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc,   /* special_function */
         "R_MIPS_GOT_HI16",     /* name */
         TRUE,                  /* partial_inplace */
         0x0000ffff,            /* src_mask */
@@ -465,7 +461,7 @@ static reloc_howto_type mips_elf64_howto_table_rel[] =
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont, /* complain_on_overflow */
-        bfd_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc,   /* special_function */
         "R_MIPS_GOT_LO16",     /* name */
         TRUE,                  /* partial_inplace */
         0x0000ffff,            /* src_mask */
@@ -480,7 +476,7 @@ static reloc_howto_type mips_elf64_howto_table_rel[] =
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont, /* complain_on_overflow */
-        bfd_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc,   /* special_function */
         "R_MIPS_SUB",          /* name */
         TRUE,                  /* partial_inplace */
         MINUS_ONE,             /* src_mask */
@@ -496,7 +492,7 @@ static reloc_howto_type mips_elf64_howto_table_rel[] =
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont, /* complain_on_overflow */
-        bfd_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc,   /* special_function */
         "R_MIPS_INSERT_A",     /* name */
         TRUE,                  /* partial_inplace */
         0xffffffff,            /* src_mask */
@@ -513,7 +509,7 @@ static reloc_howto_type mips_elf64_howto_table_rel[] =
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont, /* complain_on_overflow */
-        bfd_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc,   /* special_function */
         "R_MIPS_INSERT_B",     /* name */
         TRUE,                  /* partial_inplace */
         0xffffffff,            /* src_mask */
@@ -529,7 +525,7 @@ static reloc_howto_type mips_elf64_howto_table_rel[] =
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont, /* complain_on_overflow */
-        bfd_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc,   /* special_function */
         "R_MIPS_DELETE",       /* name */
         TRUE,                  /* partial_inplace */
         0xffffffff,            /* src_mask */
@@ -553,7 +549,7 @@ static reloc_howto_type mips_elf64_howto_table_rel[] =
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont, /* complain_on_overflow */
-        bfd_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc,   /* special_function */
         "R_MIPS_CALL_HI16",    /* name */
         TRUE,                  /* partial_inplace */
         0x0000ffff,            /* src_mask */
@@ -568,7 +564,7 @@ static reloc_howto_type mips_elf64_howto_table_rel[] =
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont, /* complain_on_overflow */
-        bfd_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc,   /* special_function */
         "R_MIPS_CALL_LO16",    /* name */
         TRUE,                  /* partial_inplace */
         0x0000ffff,            /* src_mask */
@@ -583,7 +579,7 @@ static reloc_howto_type mips_elf64_howto_table_rel[] =
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont, /* complain_on_overflow */
-        bfd_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc,   /* special_function */
         "R_MIPS_SCN_DISP",     /* name */
         TRUE,                  /* partial_inplace */
         0xffffffff,            /* src_mask */
@@ -597,7 +593,7 @@ static reloc_howto_type mips_elf64_howto_table_rel[] =
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_signed, /* complain_on_overflow */
-        bfd_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc,   /* special_function */
         "R_MIPS_REL16",        /* name */
         TRUE,                  /* partial_inplace */
         0xffff,                /* src_mask */
@@ -617,7 +613,7 @@ static reloc_howto_type mips_elf64_howto_table_rel[] =
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont, /* complain_on_overflow */
-        bfd_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc,   /* special_function */
         "R_MIPS_RELGOT",       /* name */
         TRUE,                  /* partial_inplace */
         0xffffffff,            /* src_mask */
@@ -633,7 +629,7 @@ static reloc_howto_type mips_elf64_howto_table_rel[] =
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont, /* complain_on_overflow */
-        bfd_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc,   /* special_function */
         "R_MIPS_JALR",         /* name */
         FALSE,                 /* partial_inplace */
         0,                     /* src_mask */
@@ -653,7 +649,7 @@ static reloc_howto_type mips_elf64_howto_table_rela[] =
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont, /* complain_on_overflow */
-        bfd_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc,   /* special_function */
         "R_MIPS_NONE",         /* name */
         FALSE,                 /* partial_inplace */
         0,                     /* src_mask */
@@ -668,7 +664,7 @@ static reloc_howto_type mips_elf64_howto_table_rela[] =
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_signed, /* complain_on_overflow */
-        bfd_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc,   /* special_function */
         "R_MIPS_16",           /* name */
         FALSE,                 /* partial_inplace */
         0,                     /* src_mask */
@@ -683,7 +679,7 @@ static reloc_howto_type mips_elf64_howto_table_rela[] =
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont, /* complain_on_overflow */
-        bfd_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc,   /* special_function */
         "R_MIPS_32",           /* name */
         FALSE,                 /* partial_inplace */
         0,                     /* src_mask */
@@ -698,7 +694,7 @@ static reloc_howto_type mips_elf64_howto_table_rela[] =
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont, /* complain_on_overflow */
-        bfd_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc,   /* special_function */
         "R_MIPS_REL32",        /* name */
         FALSE,                 /* partial_inplace */
         0,                     /* src_mask */
@@ -716,7 +712,7 @@ static reloc_howto_type mips_elf64_howto_table_rela[] =
                                /* This needs complex overflow
                                   detection, because the upper 36
                                   bits must match the PC + 4.  */
-        bfd_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc,   /* special_function */
         "R_MIPS_26",           /* name */
         FALSE,                 /* partial_inplace */
         0,                     /* src_mask */
@@ -731,7 +727,7 @@ static reloc_howto_type mips_elf64_howto_table_rela[] =
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont, /* complain_on_overflow */
-        bfd_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc,   /* special_function */
         "R_MIPS_HI16",         /* name */
         FALSE,                 /* partial_inplace */
         0,                     /* src_mask */
@@ -746,7 +742,7 @@ static reloc_howto_type mips_elf64_howto_table_rela[] =
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont, /* complain_on_overflow */
-        bfd_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc,   /* special_function */
         "R_MIPS_LO16",         /* name */
         FALSE,                 /* partial_inplace */
         0,                     /* src_mask */
@@ -791,7 +787,7 @@ static reloc_howto_type mips_elf64_howto_table_rela[] =
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_signed, /* complain_on_overflow */
-        mips_elf64_got16_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc, /* special_function */
         "R_MIPS_GOT16",        /* name */
         FALSE,                 /* partial_inplace */
         0,                     /* src_mask */
@@ -806,7 +802,7 @@ static reloc_howto_type mips_elf64_howto_table_rela[] =
         TRUE,                  /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_signed, /* complain_on_overflow */
-        bfd_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc,   /* special_function */
         "R_MIPS_PC16",         /* name */
         FALSE,                 /* partial_inplace */
         0,                     /* src_mask */
@@ -821,7 +817,7 @@ static reloc_howto_type mips_elf64_howto_table_rela[] =
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_signed, /* complain_on_overflow */
-        bfd_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc,   /* special_function */
         "R_MIPS_CALL16",       /* name */
         FALSE,                 /* partial_inplace */
         0,                     /* src_mask */
@@ -855,7 +851,7 @@ static reloc_howto_type mips_elf64_howto_table_rela[] =
         FALSE,                 /* pc_relative */
         6,                     /* bitpos */
         complain_overflow_bitfield, /* complain_on_overflow */
-        bfd_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc,   /* special_function */
         "R_MIPS_SHIFT5",       /* name */
         FALSE,                 /* partial_inplace */
         0,                     /* src_mask */
@@ -885,7 +881,7 @@ static reloc_howto_type mips_elf64_howto_table_rela[] =
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont, /* complain_on_overflow */
-        bfd_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc,   /* special_function */
         "R_MIPS_64",           /* name */
         FALSE,                 /* partial_inplace */
         0,                     /* src_mask */
@@ -900,7 +896,7 @@ static reloc_howto_type mips_elf64_howto_table_rela[] =
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_signed, /* complain_on_overflow */
-        bfd_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc,   /* special_function */
         "R_MIPS_GOT_DISP",     /* name */
         FALSE,                 /* partial_inplace */
         0,                     /* src_mask */
@@ -915,7 +911,7 @@ static reloc_howto_type mips_elf64_howto_table_rela[] =
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_signed, /* complain_on_overflow */
-        bfd_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc,   /* special_function */
         "R_MIPS_GOT_PAGE",     /* name */
         FALSE,                 /* partial_inplace */
         0,                     /* src_mask */
@@ -930,7 +926,7 @@ static reloc_howto_type mips_elf64_howto_table_rela[] =
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_signed, /* complain_on_overflow */
-        bfd_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc,   /* special_function */
         "R_MIPS_GOT_OFST",     /* name */
         FALSE,                 /* partial_inplace */
         0,                     /* src_mask */
@@ -945,7 +941,7 @@ static reloc_howto_type mips_elf64_howto_table_rela[] =
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont, /* complain_on_overflow */
-        bfd_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc,   /* special_function */
         "R_MIPS_GOT_HI16",     /* name */
         FALSE,                 /* partial_inplace */
         0,                     /* src_mask */
@@ -960,7 +956,7 @@ static reloc_howto_type mips_elf64_howto_table_rela[] =
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont, /* complain_on_overflow */
-        bfd_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc,   /* special_function */
         "R_MIPS_GOT_LO16",     /* name */
         FALSE,                 /* partial_inplace */
         0,                     /* src_mask */
@@ -975,7 +971,7 @@ static reloc_howto_type mips_elf64_howto_table_rela[] =
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont, /* complain_on_overflow */
-        bfd_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc,   /* special_function */
         "R_MIPS_SUB",          /* name */
         FALSE,                 /* partial_inplace */
         0,                     /* src_mask */
@@ -991,7 +987,7 @@ static reloc_howto_type mips_elf64_howto_table_rela[] =
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont, /* complain_on_overflow */
-        bfd_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc,   /* special_function */
         "R_MIPS_INSERT_A",     /* name */
         FALSE,                 /* partial_inplace */
         0,                     /* src_mask */
@@ -1008,7 +1004,7 @@ static reloc_howto_type mips_elf64_howto_table_rela[] =
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont, /* complain_on_overflow */
-        bfd_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc,   /* special_function */
         "R_MIPS_INSERT_B",     /* name */
         FALSE,                 /* partial_inplace */
         0,                     /* src_mask */
@@ -1024,7 +1020,7 @@ static reloc_howto_type mips_elf64_howto_table_rela[] =
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont, /* complain_on_overflow */
-        bfd_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc,   /* special_function */
         "R_MIPS_DELETE",       /* name */
         FALSE,                 /* partial_inplace */
         0,                     /* src_mask */
@@ -1039,7 +1035,7 @@ static reloc_howto_type mips_elf64_howto_table_rela[] =
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont, /* complain_on_overflow */
-        bfd_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc, /* special_function */
         "R_MIPS_HIGHER",       /* name */
         FALSE,                 /* partial_inplace */
         0,                     /* src_mask */
@@ -1054,7 +1050,7 @@ static reloc_howto_type mips_elf64_howto_table_rela[] =
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont, /* complain_on_overflow */
-        bfd_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc, /* special_function */
         "R_MIPS_HIGHEST",      /* name */
         FALSE,                 /* partial_inplace */
         0,                     /* src_mask */
@@ -1069,7 +1065,7 @@ static reloc_howto_type mips_elf64_howto_table_rela[] =
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont, /* complain_on_overflow */
-        bfd_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc,   /* special_function */
         "R_MIPS_CALL_HI16",    /* name */
         FALSE,                 /* partial_inplace */
         0,                     /* src_mask */
@@ -1084,7 +1080,7 @@ static reloc_howto_type mips_elf64_howto_table_rela[] =
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont, /* complain_on_overflow */
-        bfd_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc,   /* special_function */
         "R_MIPS_CALL_LO16",    /* name */
         FALSE,                 /* partial_inplace */
         0,                     /* src_mask */
@@ -1099,7 +1095,7 @@ static reloc_howto_type mips_elf64_howto_table_rela[] =
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont, /* complain_on_overflow */
-        bfd_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc,   /* special_function */
         "R_MIPS_SCN_DISP",     /* name */
         FALSE,                 /* partial_inplace */
         0,                     /* src_mask */
@@ -1113,7 +1109,7 @@ static reloc_howto_type mips_elf64_howto_table_rela[] =
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_signed, /* complain_on_overflow */
-        bfd_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc,   /* special_function */
         "R_MIPS_REL16",        /* name */
         FALSE,                 /* partial_inplace */
         0,                     /* src_mask */
@@ -1133,7 +1129,7 @@ static reloc_howto_type mips_elf64_howto_table_rela[] =
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont, /* complain_on_overflow */
-        bfd_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc,   /* special_function */
         "R_MIPS_RELGOT",       /* name */
         FALSE,                 /* partial_inplace */
         0,                     /* src_mask */
@@ -1149,7 +1145,7 @@ static reloc_howto_type mips_elf64_howto_table_rela[] =
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont, /* complain_on_overflow */
-        bfd_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc,   /* special_function */
         "R_MIPS_JALR",         /* name */
         FALSE,                 /* partial_inplace */
         0,                     /* src_mask */
@@ -1233,7 +1229,7 @@ static reloc_howto_type elf_mips_gnu_rel16_s2 =
         TRUE,                  /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_signed, /* complain_on_overflow */
-        bfd_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc,   /* special_function */
         "R_MIPS_GNU_REL16_S2", /* name */
         TRUE,                  /* partial_inplace */
         0x0000ffff,            /* src_mask */
@@ -1249,7 +1245,7 @@ static reloc_howto_type elf_mips_gnu_rela16_s2 =
         TRUE,                  /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_signed, /* complain_on_overflow */
-        bfd_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc,   /* special_function */
         "R_MIPS_GNU_REL16_S2", /* name */
         FALSE,                 /* partial_inplace */
         0,                     /* src_mask */
@@ -1411,66 +1407,6 @@ mips_elf64_be_swap_reloca_out (bfd *abfd, const Elf_Internal_Rela *src,
                              (Elf64_Mips_External_Rela *) dst);
 }
 \f
-/* Do a R_MIPS_HI16 relocation.  */
-
-static bfd_reloc_status_type
-mips_elf64_hi16_reloc (bfd *abfd ATTRIBUTE_UNUSED, arelent *reloc_entry,
-                      asymbol *symbol, void *data ATTRIBUTE_UNUSED,
-                      asection *input_section, bfd *output_bfd,
-                      char **error_message ATTRIBUTE_UNUSED)
-{
-  /* If we're relocating, and this is an external symbol, we don't
-     want to change anything.  */
-  if (output_bfd != NULL
-      && (symbol->flags & BSF_SECTION_SYM) == 0
-      && (symbol->flags & BSF_LOCAL) != 0)
-    {
-      reloc_entry->address += input_section->output_offset;
-      return bfd_reloc_ok;
-    }
-
-  if (reloc_entry->howto->partial_inplace)
-    {
-      if (((reloc_entry->addend & 0xffff) + 0x8000) & ~0xffff)
-       reloc_entry->addend += 0x8000;
-    }
-
-  return bfd_reloc_continue;
-}
-
-/* Do a R_MIPS_GOT16 reloc.  This is a reloc against the global offset
-   table used for PIC code.  If the symbol is an external symbol, the
-   instruction is modified to contain the offset of the appropriate
-   entry in the global offset table.  If the symbol is a section
-   symbol, the next reloc is a R_MIPS_LO16 reloc.  The two 16 bit
-   addends are combined to form the real addend against the section
-   symbol; the GOT16 is modified to contain the offset of an entry in
-   the global offset table, and the LO16 is modified to offset it
-   appropriately.  Thus an offset larger than 16 bits requires a
-   modified value in the global offset table.
-
-   This implementation suffices for the assembler, but the linker does
-   not yet know how to create global offset tables.  */
-
-static bfd_reloc_status_type
-mips_elf64_got16_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
-                       void *data, asection *input_section, bfd *output_bfd,
-                       char **error_message)
-{
-  /* If we're relocating, and this is a local symbol, we can handle it
-     just like an R_MIPS_HI16.  */
-  if (output_bfd != NULL
-      && ((symbol->flags & BSF_SECTION_SYM) != 0
-         || (symbol->flags & BSF_LOCAL) == 0))
-    return mips_elf64_hi16_reloc (abfd, reloc_entry, symbol, data,
-                                 input_section, output_bfd, error_message);
-
-
-  /* Otherwise we try to handle it as R_MIPS_GOT_DISP.  */
-  return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data,
-                               input_section, output_bfd, error_message);
-}
-
 /* Set the GP value for OUTPUT_BFD.  Returns FALSE if this is a
    dangerous relocation.  */
 
@@ -1716,28 +1652,19 @@ mips_elf64_gprel32_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
    the rest is at bits 6-10. The bitpos already got right by the howto.  */
 
 static bfd_reloc_status_type
-mips_elf64_shift6_reloc (bfd *abfd ATTRIBUTE_UNUSED, arelent *reloc_entry,
-                        asymbol *symbol, void *data ATTRIBUTE_UNUSED,
-                        asection *input_section, bfd *output_bfd,
-                        char **error_message ATTRIBUTE_UNUSED)
+mips_elf64_shift6_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
+                        void *data, asection *input_section, bfd *output_bfd,
+                        char **error_message)
 {
-  /* If we're relocating, and this is an external symbol, we don't
-     want to change anything.  */
-  if (output_bfd != NULL
-      && (symbol->flags & BSF_SECTION_SYM) == 0
-      && (symbol->flags & BSF_LOCAL) != 0)
-    {
-      reloc_entry->address += input_section->output_offset;
-      return bfd_reloc_ok;
-    }
-
   if (reloc_entry->howto->partial_inplace)
     {
       reloc_entry->addend = ((reloc_entry->addend & 0x00007c0)
                             | (reloc_entry->addend & 0x00000800) >> 9);
     }
 
-  return bfd_reloc_continue;
+  return _bfd_mips_elf_generic_reloc (abfd, reloc_entry, symbol, data,
+                                     input_section, output_bfd,
+                                     error_message);
 }
 
 /* Handle a mips16 jump.  */
index 49cf898..2bfbf62 100644 (file)
@@ -47,14 +47,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 #define ECOFF_SIGNED_32
 #include "ecoffswap.h"
 
-static bfd_reloc_status_type mips_elf_generic_reloc
-  (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
-static bfd_reloc_status_type mips_elf_hi16_reloc
-  (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
-static bfd_reloc_status_type mips_elf_lo16_reloc
-  (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
-static bfd_reloc_status_type mips_elf_got16_reloc
-  (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
 static bfd_boolean mips_elf_assign_gp
   (bfd *, bfd_vma *);
 static bfd_reloc_status_type mips_elf_final_gp
@@ -95,10 +87,6 @@ static irix_compat_t elf_n32_mips_irix_compat
 extern const bfd_target bfd_elf32_nbigmips_vec;
 extern const bfd_target bfd_elf32_nlittlemips_vec;
 
-static asection *prev_reloc_section = NULL;
-static bfd_vma prev_reloc_address = -1;
-static bfd_vma prev_reloc_addend = 0;
-
 /* Nonzero if ABFD is using the N32 ABI.  */
 #define ABI_N32_P(abfd) \
   ((elf_elfheader (abfd)->e_flags & EF_MIPS_ABI2) != 0)
@@ -126,7 +114,7 @@ static reloc_howto_type elf_mips_howto_table_rel[] =
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont, /* complain_on_overflow */
-        mips_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc, /* special_function */
         "R_MIPS_NONE",         /* name */
         FALSE,                 /* partial_inplace */
         0,                     /* src_mask */
@@ -141,7 +129,7 @@ static reloc_howto_type elf_mips_howto_table_rel[] =
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_signed, /* complain_on_overflow */
-        mips_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc, /* special_function */
         "R_MIPS_16",           /* name */
         TRUE,                  /* partial_inplace */
         0x0000ffff,            /* src_mask */
@@ -156,7 +144,7 @@ static reloc_howto_type elf_mips_howto_table_rel[] =
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont, /* complain_on_overflow */
-        mips_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc, /* special_function */
         "R_MIPS_32",           /* name */
         TRUE,                  /* partial_inplace */
         0xffffffff,            /* src_mask */
@@ -171,7 +159,7 @@ static reloc_howto_type elf_mips_howto_table_rel[] =
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont, /* complain_on_overflow */
-        mips_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc, /* special_function */
         "R_MIPS_REL32",        /* name */
         TRUE,                  /* partial_inplace */
         0xffffffff,            /* src_mask */
@@ -189,7 +177,7 @@ static reloc_howto_type elf_mips_howto_table_rel[] =
                                /* This needs complex overflow
                                   detection, because the upper four
                                   bits must match the PC + 4.  */
-        mips_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc, /* special_function */
         "R_MIPS_26",           /* name */
         TRUE,                  /* partial_inplace */
         0x03ffffff,            /* src_mask */
@@ -201,13 +189,13 @@ static reloc_howto_type elf_mips_howto_table_rel[] =
 
   /* High 16 bits of symbol value.  */
   HOWTO (R_MIPS_HI16,          /* type */
-        0,                     /* rightshift */
+        16,                    /* rightshift */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
         16,                    /* bitsize */
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont, /* complain_on_overflow */
-        mips_elf_hi16_reloc,   /* special_function */
+        _bfd_mips_elf_hi16_reloc, /* special_function */
         "R_MIPS_HI16",         /* name */
         TRUE,                  /* partial_inplace */
         0x0000ffff,            /* src_mask */
@@ -222,7 +210,7 @@ static reloc_howto_type elf_mips_howto_table_rel[] =
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont, /* complain_on_overflow */
-        mips_elf_lo16_reloc,   /* special_function */
+        _bfd_mips_elf_lo16_reloc, /* special_function */
         "R_MIPS_LO16",         /* name */
         TRUE,                  /* partial_inplace */
         0x0000ffff,            /* src_mask */
@@ -267,7 +255,7 @@ static reloc_howto_type elf_mips_howto_table_rel[] =
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_signed, /* complain_on_overflow */
-        mips_elf_got16_reloc,  /* special_function */
+        _bfd_mips_elf_got16_reloc, /* special_function */
         "R_MIPS_GOT16",        /* name */
         TRUE,                  /* partial_inplace */
         0x0000ffff,            /* src_mask */
@@ -282,7 +270,7 @@ static reloc_howto_type elf_mips_howto_table_rel[] =
         TRUE,                  /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_signed, /* complain_on_overflow */
-        mips_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc, /* special_function */
         "R_MIPS_PC16",         /* name */
         TRUE,                  /* partial_inplace */
         0x0000ffff,            /* src_mask */
@@ -297,7 +285,7 @@ static reloc_howto_type elf_mips_howto_table_rel[] =
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_signed, /* complain_on_overflow */
-        mips_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc, /* special_function */
         "R_MIPS_CALL16",       /* name */
         TRUE,                  /* partial_inplace */
         0x0000ffff,            /* src_mask */
@@ -333,7 +321,7 @@ static reloc_howto_type elf_mips_howto_table_rel[] =
         FALSE,                 /* pc_relative */
         6,                     /* bitpos */
         complain_overflow_bitfield, /* complain_on_overflow */
-        mips_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc, /* special_function */
         "R_MIPS_SHIFT5",       /* name */
         TRUE,                  /* partial_inplace */
         0x000007c0,            /* src_mask */
@@ -363,7 +351,7 @@ static reloc_howto_type elf_mips_howto_table_rel[] =
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont, /* complain_on_overflow */
-        mips_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc, /* special_function */
         "R_MIPS_64",           /* name */
         TRUE,                  /* partial_inplace */
         MINUS_ONE,             /* src_mask */
@@ -378,7 +366,7 @@ static reloc_howto_type elf_mips_howto_table_rel[] =
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_signed, /* complain_on_overflow */
-        mips_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc, /* special_function */
         "R_MIPS_GOT_DISP",     /* name */
         TRUE,                  /* partial_inplace */
         0x0000ffff,            /* src_mask */
@@ -393,7 +381,7 @@ static reloc_howto_type elf_mips_howto_table_rel[] =
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_signed, /* complain_on_overflow */
-        mips_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc, /* special_function */
         "R_MIPS_GOT_PAGE",     /* name */
         TRUE,                  /* partial_inplace */
         0x0000ffff,            /* src_mask */
@@ -408,7 +396,7 @@ static reloc_howto_type elf_mips_howto_table_rel[] =
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_signed, /* complain_on_overflow */
-        mips_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc, /* special_function */
         "R_MIPS_GOT_OFST",     /* name */
         TRUE,                  /* partial_inplace */
         0x0000ffff,            /* src_mask */
@@ -423,7 +411,7 @@ static reloc_howto_type elf_mips_howto_table_rel[] =
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont, /* complain_on_overflow */
-        mips_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc, /* special_function */
         "R_MIPS_GOT_HI16",     /* name */
         TRUE,                  /* partial_inplace */
         0x0000ffff,            /* src_mask */
@@ -438,7 +426,7 @@ static reloc_howto_type elf_mips_howto_table_rel[] =
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont, /* complain_on_overflow */
-        mips_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc, /* special_function */
         "R_MIPS_GOT_LO16",     /* name */
         TRUE,                  /* partial_inplace */
         0x0000ffff,            /* src_mask */
@@ -453,7 +441,7 @@ static reloc_howto_type elf_mips_howto_table_rel[] =
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont, /* complain_on_overflow */
-        mips_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc, /* special_function */
         "R_MIPS_SUB",          /* name */
         TRUE,                  /* partial_inplace */
         MINUS_ONE,             /* src_mask */
@@ -469,7 +457,7 @@ static reloc_howto_type elf_mips_howto_table_rel[] =
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont, /* complain_on_overflow */
-        mips_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc, /* special_function */
         "R_MIPS_INSERT_A",     /* name */
         TRUE,                  /* partial_inplace */
         0xffffffff,            /* src_mask */
@@ -486,7 +474,7 @@ static reloc_howto_type elf_mips_howto_table_rel[] =
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont, /* complain_on_overflow */
-        mips_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc, /* special_function */
         "R_MIPS_INSERT_B",     /* name */
         TRUE,                  /* partial_inplace */
         0xffffffff,            /* src_mask */
@@ -502,7 +490,7 @@ static reloc_howto_type elf_mips_howto_table_rel[] =
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont, /* complain_on_overflow */
-        mips_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc, /* special_function */
         "R_MIPS_DELETE",       /* name */
         TRUE,                  /* partial_inplace */
         0xffffffff,            /* src_mask */
@@ -526,7 +514,7 @@ static reloc_howto_type elf_mips_howto_table_rel[] =
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont, /* complain_on_overflow */
-        mips_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc, /* special_function */
         "R_MIPS_CALL_HI16",    /* name */
         TRUE,                  /* partial_inplace */
         0x0000ffff,            /* src_mask */
@@ -541,7 +529,7 @@ static reloc_howto_type elf_mips_howto_table_rel[] =
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont, /* complain_on_overflow */
-        mips_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc, /* special_function */
         "R_MIPS_CALL_LO16",    /* name */
         TRUE,                  /* partial_inplace */
         0x0000ffff,            /* src_mask */
@@ -556,7 +544,7 @@ static reloc_howto_type elf_mips_howto_table_rel[] =
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont, /* complain_on_overflow */
-        mips_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc, /* special_function */
         "R_MIPS_SCN_DISP",     /* name */
         TRUE,                  /* partial_inplace */
         0xffffffff,            /* src_mask */
@@ -570,7 +558,7 @@ static reloc_howto_type elf_mips_howto_table_rel[] =
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_signed, /* complain_on_overflow */
-        mips_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc, /* special_function */
         "R_MIPS_REL16",        /* name */
         TRUE,                  /* partial_inplace */
         0xffff,                /* src_mask */
@@ -590,7 +578,7 @@ static reloc_howto_type elf_mips_howto_table_rel[] =
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont, /* complain_on_overflow */
-        mips_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc, /* special_function */
         "R_MIPS_RELGOT",       /* name */
         TRUE,                  /* partial_inplace */
         0xffffffff,            /* src_mask */
@@ -606,7 +594,7 @@ static reloc_howto_type elf_mips_howto_table_rel[] =
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont, /* complain_on_overflow */
-        mips_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc, /* special_function */
         "R_MIPS_JALR",         /* name */
         FALSE,                 /* partial_inplace */
         0x00000000,            /* src_mask */
@@ -626,7 +614,7 @@ static reloc_howto_type elf_mips_howto_table_rela[] =
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont, /* complain_on_overflow */
-        mips_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc, /* special_function */
         "R_MIPS_NONE",         /* name */
         FALSE,                 /* partial_inplace */
         0,                     /* src_mask */
@@ -641,7 +629,7 @@ static reloc_howto_type elf_mips_howto_table_rela[] =
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_signed, /* complain_on_overflow */
-        mips_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc, /* special_function */
         "R_MIPS_16",           /* name */
         FALSE,                 /* partial_inplace */
         0,                     /* src_mask */
@@ -656,7 +644,7 @@ static reloc_howto_type elf_mips_howto_table_rela[] =
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont, /* complain_on_overflow */
-        mips_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc, /* special_function */
         "R_MIPS_32",           /* name */
         FALSE,                 /* partial_inplace */
         0,                     /* src_mask */
@@ -671,7 +659,7 @@ static reloc_howto_type elf_mips_howto_table_rela[] =
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont, /* complain_on_overflow */
-        mips_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc, /* special_function */
         "R_MIPS_REL32",        /* name */
         FALSE,                 /* partial_inplace */
         0,                     /* src_mask */
@@ -689,7 +677,7 @@ static reloc_howto_type elf_mips_howto_table_rela[] =
                                /* This needs complex overflow
                                   detection, because the upper 36
                                   bits must match the PC + 4.  */
-        mips_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc, /* special_function */
         "R_MIPS_26",           /* name */
         FALSE,                 /* partial_inplace */
         0,                     /* src_mask */
@@ -704,7 +692,7 @@ static reloc_howto_type elf_mips_howto_table_rela[] =
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont, /* complain_on_overflow */
-        mips_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc, /* special_function */
         "R_MIPS_HI16",         /* name */
         FALSE,                 /* partial_inplace */
         0,                     /* src_mask */
@@ -719,7 +707,7 @@ static reloc_howto_type elf_mips_howto_table_rela[] =
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont, /* complain_on_overflow */
-        mips_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc, /* special_function */
         "R_MIPS_LO16",         /* name */
         FALSE,                 /* partial_inplace */
         0,                     /* src_mask */
@@ -764,7 +752,7 @@ static reloc_howto_type elf_mips_howto_table_rela[] =
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_signed, /* complain_on_overflow */
-        mips_elf_got16_reloc,  /* special_function */
+        _bfd_mips_elf_generic_reloc, /* special_function */
         "R_MIPS_GOT16",        /* name */
         FALSE,                 /* partial_inplace */
         0,                     /* src_mask */
@@ -779,7 +767,7 @@ static reloc_howto_type elf_mips_howto_table_rela[] =
         TRUE,                  /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_signed, /* complain_on_overflow */
-        mips_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc, /* special_function */
         "R_MIPS_PC16",         /* name */
         FALSE,                 /* partial_inplace */
         0,                     /* src_mask */
@@ -794,7 +782,7 @@ static reloc_howto_type elf_mips_howto_table_rela[] =
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_signed, /* complain_on_overflow */
-        mips_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc, /* special_function */
         "R_MIPS_CALL16",       /* name */
         FALSE,                 /* partial_inplace */
         0,                     /* src_mask */
@@ -828,7 +816,7 @@ static reloc_howto_type elf_mips_howto_table_rela[] =
         FALSE,                 /* pc_relative */
         6,                     /* bitpos */
         complain_overflow_bitfield, /* complain_on_overflow */
-        mips_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc, /* special_function */
         "R_MIPS_SHIFT5",       /* name */
         FALSE,                 /* partial_inplace */
         0,                     /* src_mask */
@@ -858,7 +846,7 @@ static reloc_howto_type elf_mips_howto_table_rela[] =
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont, /* complain_on_overflow */
-        mips_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc, /* special_function */
         "R_MIPS_64",           /* name */
         FALSE,                 /* partial_inplace */
         0,                     /* src_mask */
@@ -873,7 +861,7 @@ static reloc_howto_type elf_mips_howto_table_rela[] =
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_signed, /* complain_on_overflow */
-        mips_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc, /* special_function */
         "R_MIPS_GOT_DISP",     /* name */
         FALSE,                 /* partial_inplace */
         0,                     /* src_mask */
@@ -888,7 +876,7 @@ static reloc_howto_type elf_mips_howto_table_rela[] =
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_signed, /* complain_on_overflow */
-        mips_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc, /* special_function */
         "R_MIPS_GOT_PAGE",     /* name */
         FALSE,                 /* partial_inplace */
         0,                     /* src_mask */
@@ -903,7 +891,7 @@ static reloc_howto_type elf_mips_howto_table_rela[] =
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_signed, /* complain_on_overflow */
-        mips_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc, /* special_function */
         "R_MIPS_GOT_OFST",     /* name */
         FALSE,                 /* partial_inplace */
         0,                     /* src_mask */
@@ -918,7 +906,7 @@ static reloc_howto_type elf_mips_howto_table_rela[] =
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont, /* complain_on_overflow */
-        mips_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc, /* special_function */
         "R_MIPS_GOT_HI16",     /* name */
         FALSE,                 /* partial_inplace */
         0,                     /* src_mask */
@@ -933,7 +921,7 @@ static reloc_howto_type elf_mips_howto_table_rela[] =
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont, /* complain_on_overflow */
-        mips_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc, /* special_function */
         "R_MIPS_GOT_LO16",     /* name */
         FALSE,                 /* partial_inplace */
         0,                     /* src_mask */
@@ -948,7 +936,7 @@ static reloc_howto_type elf_mips_howto_table_rela[] =
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont, /* complain_on_overflow */
-        mips_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc, /* special_function */
         "R_MIPS_SUB",          /* name */
         FALSE,                 /* partial_inplace */
         0,                     /* src_mask */
@@ -964,7 +952,7 @@ static reloc_howto_type elf_mips_howto_table_rela[] =
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont, /* complain_on_overflow */
-        mips_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc, /* special_function */
         "R_MIPS_INSERT_A",     /* name */
         FALSE,                 /* partial_inplace */
         0,                     /* src_mask */
@@ -981,7 +969,7 @@ static reloc_howto_type elf_mips_howto_table_rela[] =
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont, /* complain_on_overflow */
-        mips_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc, /* special_function */
         "R_MIPS_INSERT_B",     /* name */
         FALSE,                 /* partial_inplace */
         0,                     /* src_mask */
@@ -997,7 +985,7 @@ static reloc_howto_type elf_mips_howto_table_rela[] =
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont, /* complain_on_overflow */
-        mips_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc, /* special_function */
         "R_MIPS_DELETE",       /* name */
         FALSE,                 /* partial_inplace */
         0,                     /* src_mask */
@@ -1012,7 +1000,7 @@ static reloc_howto_type elf_mips_howto_table_rela[] =
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont, /* complain_on_overflow */
-        mips_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc, /* special_function */
         "R_MIPS_HIGHER",       /* name */
         FALSE,                 /* partial_inplace */
         0,                     /* src_mask */
@@ -1027,7 +1015,7 @@ static reloc_howto_type elf_mips_howto_table_rela[] =
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont, /* complain_on_overflow */
-        mips_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc, /* special_function */
         "R_MIPS_HIGHEST",      /* name */
         FALSE,                 /* partial_inplace */
         0,                     /* src_mask */
@@ -1042,7 +1030,7 @@ static reloc_howto_type elf_mips_howto_table_rela[] =
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont, /* complain_on_overflow */
-        mips_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc, /* special_function */
         "R_MIPS_CALL_HI16",    /* name */
         FALSE,                 /* partial_inplace */
         0,                     /* src_mask */
@@ -1057,7 +1045,7 @@ static reloc_howto_type elf_mips_howto_table_rela[] =
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont, /* complain_on_overflow */
-        mips_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc, /* special_function */
         "R_MIPS_CALL_LO16",    /* name */
         FALSE,                 /* partial_inplace */
         0,                     /* src_mask */
@@ -1072,7 +1060,7 @@ static reloc_howto_type elf_mips_howto_table_rela[] =
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont, /* complain_on_overflow */
-        mips_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc, /* special_function */
         "R_MIPS_SCN_DISP",     /* name */
         FALSE,                 /* partial_inplace */
         0,                     /* src_mask */
@@ -1087,7 +1075,7 @@ static reloc_howto_type elf_mips_howto_table_rela[] =
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_signed, /* complain_on_overflow */
-        mips_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc, /* special_function */
         "R_MIPS_REL16",        /* name */
         FALSE,                 /* partial_inplace */
         0,                     /* src_mask */
@@ -1107,7 +1095,7 @@ static reloc_howto_type elf_mips_howto_table_rela[] =
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont, /* complain_on_overflow */
-        mips_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc, /* special_function */
         "R_MIPS_RELGOT",       /* name */
         FALSE,                 /* partial_inplace */
         0,                     /* src_mask */
@@ -1123,7 +1111,7 @@ static reloc_howto_type elf_mips_howto_table_rela[] =
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont, /* complain_on_overflow */
-        mips_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc, /* special_function */
         "R_MIPS_JALR",         /* name */
         FALSE,                 /* partial_inplace */
         0,                     /* src_mask */
@@ -1207,7 +1195,7 @@ static reloc_howto_type elf_mips_gnu_rel16_s2 =
         TRUE,                  /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_signed, /* complain_on_overflow */
-        mips_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc, /* special_function */
         "R_MIPS_GNU_REL16_S2", /* name */
         TRUE,                  /* partial_inplace */
         0x0000ffff,            /* src_mask */
@@ -1223,224 +1211,13 @@ static reloc_howto_type elf_mips_gnu_rela16_s2 =
         TRUE,                  /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_signed, /* complain_on_overflow */
-        mips_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc, /* special_function */
         "R_MIPS_GNU_REL16_S2", /* name */
         FALSE,                 /* partial_inplace */
         0,                     /* src_mask */
         0x0000ffff,            /* dst_mask */
         TRUE);                 /* pcrel_offset */
 \f
-/* This is derived from bfd_elf_generic_reloc.  NewABI allows us to have
-   several relocations against the same address.  The addend is derived
-   from the addends of preceding relocations.  If we don't need to
-   do something special,  we simply keep track of the addend.  */
-
-#define GET_RELOC_ADDEND(obfd, sym, entry, sec)                                \
-{                                                                      \
-  /* If we're relocating, and this is an external symbol, we don't     \
-     want to change anything.  */                                      \
-    if ((obfd) != NULL                                                 \
-       && ((sym)->flags & BSF_SECTION_SYM) == 0                        \
-       && (! (entry)->howto->partial_inplace                           \
-           || (entry)->addend == 0))                                   \
-      {                                                                        \
-        (entry)->address += (sec)->output_offset;                      \
-        return bfd_reloc_ok;                                           \
-      }                                                                        \
-                                                                       \
-    /* The addend of combined relocs is remembered and left for                \
-       subsequent relocs.  */                                          \
-    if (prev_reloc_address != (entry)->address                         \
-       || prev_reloc_section != (sec))                                 \
-      {                                                                        \
-       prev_reloc_section = (sec);                                     \
-        prev_reloc_address = (entry)->address;                         \
-        prev_reloc_addend = (entry)->addend;                           \
-      }                                                                        \
-    else                                                               \
-      (entry)->addend = prev_reloc_addend;                             \
-}
-
-#define SET_RELOC_ADDEND(entry)                                                \
-{                                                                      \
-  prev_reloc_addend = (entry)->addend;                                 \
-}
-
-static bfd_reloc_status_type
-mips_elf_generic_reloc (bfd *abfd ATTRIBUTE_UNUSED, arelent *reloc_entry,
-                       asymbol *symbol, void *data ATTRIBUTE_UNUSED,
-                       asection *input_section, bfd *output_bfd,
-                       char **error_message ATTRIBUTE_UNUSED)
-{
-  GET_RELOC_ADDEND (output_bfd, symbol, reloc_entry, input_section)
-
-  return bfd_reloc_continue;
-}
-\f
-/* Do a R_MIPS_HI16 relocation.  This has to be done in combination
-   with a R_MIPS_LO16 reloc, because there is a carry from the LO16 to
-   the HI16.  Here we just save the information we need; we do the
-   actual relocation when we see the LO16.
-
-   MIPS ELF requires that the LO16 immediately follow the HI16.  As a
-   GNU extension, for non-pc-relative relocations, we permit an
-   arbitrary number of HI16 relocs to be associated with a single LO16
-   reloc.  This extension permits gcc to output the HI and LO relocs
-   itself.
-
-   This cannot be done for PC-relative relocations because both the HI16
-   and LO16 parts of the relocations must be done relative to the LO16
-   part, and there can be carry to or borrow from the HI16 part.  */
-
-struct mips_hi16
-{
-  struct mips_hi16 *next;
-  bfd_byte *addr;
-  bfd_vma addend;
-};
-
-/* FIXME: This should not be a static variable.  */
-
-static struct mips_hi16 *mips_hi16_list;
-
-static bfd_reloc_status_type
-mips_elf_hi16_reloc (bfd *abfd ATTRIBUTE_UNUSED, arelent *reloc_entry,
-                    asymbol *symbol, void *data, asection *input_section,
-                    bfd *output_bfd, char **error_message ATTRIBUTE_UNUSED)
-{
-  bfd_reloc_status_type ret;
-  bfd_vma relocation;
-  struct mips_hi16 *n;
-
-  GET_RELOC_ADDEND (output_bfd, symbol, reloc_entry, input_section)
-
-  ret = bfd_reloc_ok;
-
-  if (bfd_is_und_section (symbol->section) && output_bfd == NULL)
-    ret = bfd_reloc_undefined;
-
-  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 (reloc_entry->address > input_section->_cooked_size)
-    return bfd_reloc_outofrange;
-
-  /* Save the information, and let LO16 do the actual relocation.  */
-  n = bfd_malloc (sizeof *n);
-  if (n == NULL)
-    return bfd_reloc_outofrange;
-  n->addr = (bfd_byte *) data + reloc_entry->address;
-  n->addend = relocation;
-  n->next = mips_hi16_list;
-  mips_hi16_list = n;
-
-  if (output_bfd != NULL)
-    reloc_entry->address += input_section->output_offset;
-
-  return ret;
-}
-
-/* Do a R_MIPS_LO16 relocation.  This is a straightforward 16 bit
-   inplace relocation; this function exists in order to do the
-   R_MIPS_HI16 relocation described above.  */
-
-static bfd_reloc_status_type
-mips_elf_lo16_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
-                    void *data, asection *input_section, bfd *output_bfd,
-                    char **error_message)
-{
-  if (mips_hi16_list != NULL)
-    {
-      struct mips_hi16 *l;
-
-      l = mips_hi16_list;
-      while (l != NULL)
-       {
-         unsigned long insn;
-         unsigned long val;
-         unsigned long vallo;
-         struct mips_hi16 *next;
-
-         /* Do the HI16 relocation.  Note that we actually don't need
-            to know anything about the LO16 itself, except where to
-            find the low 16 bits of the addend needed by the LO16.  */
-         insn = bfd_get_32 (abfd, l->addr);
-         vallo = bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address);
-
-         /* The low order 16 bits are always treated as a signed
-            value.  */
-         vallo = ((vallo & 0xffff) ^ 0x8000) - 0x8000;
-         val = ((insn & 0xffff) << 16) + vallo;
-         val += l->addend;
-
-         /* If PC-relative, we need to subtract out the address of the LO
-            half of the HI/LO.  (The actual relocation is relative
-            to that instruction.)  */
-         if (reloc_entry->howto->pc_relative)
-           val -= reloc_entry->address;
-
-         /* At this point, "val" has the value of the combined HI/LO
-            pair.  If the low order 16 bits (which will be used for
-            the LO16 insn) are negative, then we will need an
-            adjustment for the high order 16 bits.  */
-         val += 0x8000;
-         val = (val >> 16) & 0xffff;
-
-         insn &= ~ (bfd_vma) 0xffff;
-         insn |= val;
-         bfd_put_32 (abfd, insn, l->addr);
-
-         next = l->next;
-         free (l);
-         l = next;
-       }
-
-      mips_hi16_list = NULL;
-    }
-
-  /* Now do the LO16 reloc in the usual way.  */
-  return mips_elf_generic_reloc (abfd, reloc_entry, symbol, data,
-                                input_section, output_bfd, error_message);
-}
-
-/* Do a R_MIPS_GOT16 reloc.  This is a reloc against the global offset
-   table used for PIC code.  If the symbol is an external symbol, the
-   instruction is modified to contain the offset of the appropriate
-   entry in the global offset table.  If the symbol is a section
-   symbol, the next reloc is a R_MIPS_LO16 reloc.  The two 16 bit
-   addends are combined to form the real addend against the section
-   symbol; the GOT16 is modified to contain the offset of an entry in
-   the global offset table, and the LO16 is modified to offset it
-   appropriately.  Thus an offset larger than 16 bits requires a
-   modified value in the global offset table.
-
-   This implementation suffices for the assembler, but the linker does
-   not yet know how to create global offset tables.  */
-
-static bfd_reloc_status_type
-mips_elf_got16_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
-                     void *data, asection *input_section, bfd *output_bfd,
-                     char **error_message)
-{
-  /* If we're relocating, and this is a local symbol, we can handle it
-     just like an R_MIPS_HI16.  */
-  if (output_bfd != NULL
-      && ((symbol->flags & BSF_SECTION_SYM) != 0
-         || (symbol->flags & BSF_LOCAL) == 0))
-    return mips_elf_hi16_reloc (abfd, reloc_entry, symbol, data,
-                               input_section, output_bfd, error_message);
-
-  /* Otherwise we try to handle it as R_MIPS_GOT_DISP.  */
-  return mips_elf_generic_reloc (abfd, reloc_entry, symbol, data,
-                                input_section, output_bfd, error_message);
-}
-
 /* Set the GP value for OUTPUT_BFD.  Returns FALSE if this is a
    dangerous relocation.  */
 
@@ -1542,8 +1319,6 @@ mips_elf_gprel16_reloc (bfd *abfd ATTRIBUTE_UNUSED, arelent *reloc_entry,
   bfd_reloc_status_type ret;
   bfd_vma gp;
 
-  GET_RELOC_ADDEND (output_bfd, symbol, reloc_entry, input_section)
-
   if (output_bfd != NULL)
     relocatable = TRUE;
   else
@@ -1573,8 +1348,6 @@ mips_elf_literal_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
   bfd_reloc_status_type ret;
   bfd_vma gp;
 
-  GET_RELOC_ADDEND (output_bfd, symbol, reloc_entry, input_section)
-
   /* FIXME: The entries in the .lit8 and .lit4 sections should be merged.  */
   if (output_bfd != NULL)
     relocatable = TRUE;
@@ -1606,8 +1379,6 @@ mips_elf_gprel32_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
   bfd_reloc_status_type ret;
   bfd_vma gp;
 
-  GET_RELOC_ADDEND (output_bfd, symbol, reloc_entry, input_section)
-
   /* R_MIPS_GPREL32 relocations are defined for local symbols only.  */
   if (output_bfd != NULL
       && (symbol->flags & BSF_SECTION_SYM) == 0
@@ -1684,36 +1455,33 @@ gprel32_with_gp (bfd *abfd, asymbol *symbol, arelent *reloc_entry,
    the rest is at bits 6-10. The bitpos already got right by the howto.  */
 
 static bfd_reloc_status_type
-mips_elf_shift6_reloc (bfd *abfd ATTRIBUTE_UNUSED, arelent *reloc_entry,
-                      asymbol *symbol, void *data ATTRIBUTE_UNUSED,
-                      asection *input_section, bfd *output_bfd,
-                      char **error_message ATTRIBUTE_UNUSED)
+mips_elf_shift6_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
+                      void *data, asection *input_section, bfd *output_bfd,
+                      char **error_message)
 {
-  GET_RELOC_ADDEND (output_bfd, symbol, reloc_entry, input_section)
-
   if (reloc_entry->howto->partial_inplace)
     {
       reloc_entry->addend = ((reloc_entry->addend & 0x00007c0)
                             | (reloc_entry->addend & 0x00000800) >> 9);
     }
 
-  SET_RELOC_ADDEND (reloc_entry)
-
-  return bfd_reloc_continue;
+  return _bfd_mips_elf_generic_reloc (abfd, reloc_entry, symbol, data,
+                                     input_section, output_bfd,
+                                     error_message);
 }
 \f
 /* Handle a mips16 jump.  */
 
 static bfd_reloc_status_type
-mips16_jump_reloc (bfd *abfd ATTRIBUTE_UNUSED, arelent *reloc_entry,
-                  asymbol *symbol, void *data ATTRIBUTE_UNUSED,
-                  asection *input_section, bfd *output_bfd,
+mips16_jump_reloc (bfd *abfd ATTRIBUTE_UNUSED,
+                  arelent *reloc_entry ATTRIBUTE_UNUSED,
+                  asymbol *symbol ATTRIBUTE_UNUSED,
+                  void *data ATTRIBUTE_UNUSED,
+                  asection *input_section, bfd *output_bfd ATTRIBUTE_UNUSED,
                   char **error_message ATTRIBUTE_UNUSED)
 {
   static bfd_boolean warned = FALSE;
 
-  GET_RELOC_ADDEND (output_bfd, symbol, reloc_entry, input_section)
-
   /* FIXME.  */
   if (! warned)
     (*_bfd_error_handler)
@@ -1739,8 +1507,6 @@ mips16_gprel_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
   bfd_signed_vma val;
   bfd_vma relocation;
 
-  GET_RELOC_ADDEND (output_bfd, symbol, reloc_entry, input_section)
-
   if (output_bfd != NULL)
     relocatable = TRUE;
   else
@@ -1804,9 +1570,6 @@ mips16_gprel_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
 
   return bfd_reloc_ok;
 }
-
-#undef GET_RELOC_ADDEND
-#undef SET_RELOC_ADDEND
 \f
 /* A mapping from BFD reloc types to MIPS ELF reloc types.  */
 
index 1af0f98..7bcdb11 100644 (file)
@@ -1082,8 +1082,8 @@ _bfd_mips_elf_gprel16_with_gp (bfd *abfd, asymbol *symbol,
                               bfd_boolean relocatable, void *data, bfd_vma gp)
 {
   bfd_vma relocation;
-  unsigned long insn = 0;
   bfd_signed_vma val;
+  bfd_reloc_status_type status;
 
   if (bfd_is_com_section (symbol->section))
     relocation = 0;
@@ -1099,13 +1099,7 @@ _bfd_mips_elf_gprel16_with_gp (bfd *abfd, asymbol *symbol,
   /* Set val to the offset into the section or symbol.  */
   val = reloc_entry->addend;
 
-  if (reloc_entry->howto->partial_inplace)
-    {
-      insn = bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address);
-      val += insn & 0xffff;
-    }
-
-  _bfd_mips_elf_sign_extend(val, 16);
+  _bfd_mips_elf_sign_extend (val, 16);
 
   /* Adjust val for the final section location and GP value.  If we
      are producing relocatable output, we don't want to do this for
@@ -1116,16 +1110,215 @@ _bfd_mips_elf_gprel16_with_gp (bfd *abfd, asymbol *symbol,
 
   if (reloc_entry->howto->partial_inplace)
     {
-      insn = (insn & ~0xffff) | (val & 0xffff);
-      bfd_put_32 (abfd, insn, (bfd_byte *) data + reloc_entry->address);
+      status = _bfd_relocate_contents (reloc_entry->howto, abfd, val,
+                                      (bfd_byte *) data
+                                      + reloc_entry->address);
+      if (status != bfd_reloc_ok)
+       return status;
     }
   else
     reloc_entry->addend = val;
 
   if (relocatable)
     reloc_entry->address += input_section->output_offset;
-  else if (((val & ~0xffff) != ~0xffff) && ((val & ~0xffff) != 0))
-    return bfd_reloc_overflow;
+
+  return bfd_reloc_ok;
+}
+
+/* Used to store a REL high-part relocation such as R_MIPS_HI16 or
+   R_MIPS_GOT16.  REL is the relocation, INPUT_SECTION is the section
+   that contains the relocation field and DATA points to the start of
+   INPUT_SECTION.  */
+
+struct mips_hi16
+{
+  struct mips_hi16 *next;
+  bfd_byte *data;
+  asection *input_section;
+  arelent rel;
+};
+
+/* FIXME: This should not be a static variable.  */
+
+static struct mips_hi16 *mips_hi16_list;
+
+/* A howto special_function for REL *HI16 relocations.  We can only
+   calculate the correct value once we've seen the partnering
+   *LO16 relocation, so just save the information for later.
+
+   The ABI requires that the *LO16 immediately follow the *HI16.
+   However, as a GNU extension, we permit an arbitrary number of
+   *HI16s to be associated with a single *LO16.  This significantly
+   simplies the relocation handling in gcc.  */
+
+bfd_reloc_status_type
+_bfd_mips_elf_hi16_reloc (bfd *abfd ATTRIBUTE_UNUSED, arelent *reloc_entry,
+                         asymbol *symbol ATTRIBUTE_UNUSED, void *data,
+                         asection *input_section, bfd *output_bfd,
+                         char **error_message ATTRIBUTE_UNUSED)
+{
+  struct mips_hi16 *n;
+
+  if (reloc_entry->address > input_section->_cooked_size)
+    return bfd_reloc_outofrange;
+
+  n = bfd_malloc (sizeof *n);
+  if (n == NULL)
+    return bfd_reloc_outofrange;
+
+  n->next = mips_hi16_list;
+  n->data = data;
+  n->input_section = input_section;
+  n->rel = *reloc_entry;
+  mips_hi16_list = n;
+
+  if (output_bfd != NULL)
+    reloc_entry->address += input_section->output_offset;
+
+  return bfd_reloc_ok;
+}
+
+/* A howto special_function for REL R_MIPS_GOT16 relocations.  This is just
+   like any other 16-bit relocation when applied to global symbols, but is
+   treated in the same as R_MIPS_HI16 when applied to local symbols.  */
+
+bfd_reloc_status_type
+_bfd_mips_elf_got16_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
+                          void *data, asection *input_section,
+                          bfd *output_bfd, char **error_message)
+{
+  if ((symbol->flags & (BSF_GLOBAL | BSF_WEAK)) != 0
+      || bfd_is_und_section (bfd_get_section (symbol))
+      || bfd_is_com_section (bfd_get_section (symbol)))
+    /* The relocation is against a global symbol.  */
+    return _bfd_mips_elf_generic_reloc (abfd, reloc_entry, symbol, data,
+                                       input_section, output_bfd,
+                                       error_message);
+
+  return _bfd_mips_elf_hi16_reloc (abfd, reloc_entry, symbol, data,
+                                  input_section, output_bfd, error_message);
+}
+
+/* A howto special_function for REL *LO16 relocations.  The *LO16 itself
+   is a straightforward 16 bit inplace relocation, but we must deal with
+   any partnering high-part relocations as well.  */
+
+bfd_reloc_status_type
+_bfd_mips_elf_lo16_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
+                         void *data, asection *input_section,
+                         bfd *output_bfd, char **error_message)
+{
+  bfd_vma vallo;
+
+  if (reloc_entry->address > input_section->_cooked_size)
+    return bfd_reloc_outofrange;
+
+  vallo = bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address);
+  while (mips_hi16_list != NULL)
+    {
+      bfd_reloc_status_type ret;
+      struct mips_hi16 *hi;
+
+      hi = mips_hi16_list;
+
+      /* R_MIPS_GOT16 relocations are something of a special case.  We
+        want to install the addend in the same way as for a R_MIPS_HI16
+        relocation (with a rightshift of 16).  However, since GOT16
+        relocations can also be used with global symbols, their howto
+        has a rightshift of 0.  */
+      if (hi->rel.howto->type == R_MIPS_GOT16)
+       hi->rel.howto = MIPS_ELF_RTYPE_TO_HOWTO (abfd, R_MIPS_HI16, FALSE);
+
+      /* VALLO is a signed 16-bit number.  Bias it by 0x8000 so that any
+        carry or borrow will induce a change of +1 or -1 in the high part.  */
+      hi->rel.addend += (vallo + 0x8000) & 0xffff;
+
+      /* R_MIPS_GNU_REL_HI16 relocations are relative to the address of the
+        lo16 relocation, not their own address.  If we're calculating the
+        final value, and hence subtracting the "PC", subtract the offset
+        of the lo16 relocation from here.  */
+      if (output_bfd == NULL && hi->rel.howto->type == R_MIPS_GNU_REL_HI16)
+       hi->rel.addend -= reloc_entry->address - hi->rel.address;
+
+      ret = _bfd_mips_elf_generic_reloc (abfd, &hi->rel, symbol, hi->data,
+                                        hi->input_section, output_bfd,
+                                        error_message);
+      if (ret != bfd_reloc_ok)
+       return ret;
+
+      mips_hi16_list = hi->next;
+      free (hi);
+    }
+
+  return _bfd_mips_elf_generic_reloc (abfd, reloc_entry, symbol, data,
+                                     input_section, output_bfd,
+                                     error_message);
+}
+
+/* A generic howto special_function.  This calculates and installs the
+   relocation itself, thus avoiding the oft-discussed problems in
+   bfd_perform_relocation and bfd_install_relocation.  */
+
+bfd_reloc_status_type
+_bfd_mips_elf_generic_reloc (bfd *abfd ATTRIBUTE_UNUSED, arelent *reloc_entry,
+                            asymbol *symbol, void *data ATTRIBUTE_UNUSED,
+                            asection *input_section, bfd *output_bfd,
+                            char **error_message ATTRIBUTE_UNUSED)
+{
+  bfd_signed_vma val;
+  bfd_reloc_status_type status;
+  bfd_boolean relocatable;
+
+  relocatable = (output_bfd != NULL);
+
+  if (reloc_entry->address > input_section->_cooked_size)
+    return bfd_reloc_outofrange;
+
+  /* Build up the field adjustment in VAL.  */
+  val = 0;
+  if (!relocatable || (symbol->flags & BSF_SECTION_SYM) != 0)
+    {
+      /* Either we're calculating the final field value or we have a
+        relocation against a section symbol.  Add in the section's
+        offset or address.  */
+      val += symbol->section->output_section->vma;
+      val += symbol->section->output_offset;
+    }
+
+  if (!relocatable)
+    {
+      /* We're calculating the final field value.  Add in the symbol's value
+        and, if pc-relative, subtract the address of the field itself.  */
+      val += symbol->value;
+      if (reloc_entry->howto->pc_relative)
+       {
+         val -= input_section->output_section->vma;
+         val -= input_section->output_offset;
+         val -= reloc_entry->address;
+       }
+    }
+
+  /* VAL is now the final adjustment.  If we're keeping this relocation
+     in the output file, and if the relocation uses a separate addend,
+     we just need to add VAL to that addend.  Otherwise we need to add
+     VAL to the relocation field itself.  */
+  if (relocatable && !reloc_entry->howto->partial_inplace)
+    reloc_entry->addend += val;
+  else
+    {
+      /* Add in the separate addend, if any.  */
+      val += reloc_entry->addend;
+
+      /* Add VAL to the relocation field.  */
+      status = _bfd_relocate_contents (reloc_entry->howto, abfd, val,
+                                      (bfd_byte *) data
+                                      + reloc_entry->address);
+      if (status != bfd_reloc_ok)
+       return status;
+    }
+
+  if (relocatable)
+    reloc_entry->address += input_section->output_offset;
 
   return bfd_reloc_ok;
 }
@@ -3203,7 +3396,7 @@ mips_elf_calculate_relocation (bfd *abfd, bfd *input_bfd,
       break;
 
     case R_MIPS_GNU_REL16_S2:
-      value = symbol + _bfd_mips_elf_sign_extend (addend << 2, 18) - p;
+      value = symbol + _bfd_mips_elf_sign_extend (addend, 18) - p;
       overflowed_p = mips_elf_overflow_p (value, 18);
       value = (value >> 2) & howto->dst_mask;
       break;
@@ -3226,9 +3419,9 @@ mips_elf_calculate_relocation (bfd *abfd, bfd *input_bfd,
         R_MIPS_26 case here.  */
     case R_MIPS_26:
       if (local_p)
-       value = (((addend << 2) | ((p + 4) & 0xf0000000)) + symbol) >> 2;
+       value = ((addend | ((p + 4) & 0xf0000000)) + symbol) >> 2;
       else
-       value = (_bfd_mips_elf_sign_extend (addend << 2, 28) + symbol) >> 2;
+       value = (_bfd_mips_elf_sign_extend (addend, 28) + symbol) >> 2;
       value &= howto->dst_mask;
       break;
 
@@ -6067,7 +6260,6 @@ _bfd_mips_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
              addend = mips_elf_obtain_contents (howto, rel, input_bfd,
                                                 contents);
              addend &= howto->src_mask;
-             addend <<= howto->rightshift;
 
              /* For some kinds of relocations, the ADDEND is a
                 combination of the addend stored in two different
@@ -6131,6 +6323,8 @@ _bfd_mips_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
                            | ((addend & 0x7e00000) >> 16)
                            | (addend & 0x1f));
                }
+             else
+               addend <<= howto->rightshift;
            }
          else
            addend = rel->r_addend;
@@ -6170,33 +6364,25 @@ _bfd_mips_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
            /* Adjust the addend appropriately.  */
            addend += local_sections[r_symndx]->output_offset;
 
-         if (howto->partial_inplace)
+         if (rela_relocation_p)
+           /* If this is a RELA relocation, just update the addend.  */
+           rel->r_addend = addend;
+         else
            {
-             /* If the relocation is for a R_MIPS_HI16 or R_MIPS_GOT16,
-                then we only want to write out the high-order 16 bits.
-                The subsequent R_MIPS_LO16 will handle the low-order bits.
-              */
-             if (r_type == R_MIPS_HI16 || r_type == R_MIPS_GOT16
+             if (r_type == R_MIPS_HI16
+                 || r_type == R_MIPS_GOT16
                  || r_type == R_MIPS_GNU_REL_HI16)
                addend = mips_elf_high (addend);
              else if (r_type == R_MIPS_HIGHER)
                addend = mips_elf_higher (addend);
              else if (r_type == R_MIPS_HIGHEST)
                addend = mips_elf_highest (addend);
-           }
+             else
+               addend >>= howto->rightshift;
 
-         if (rela_relocation_p)
-           /* If this is a RELA relocation, just update the addend.
-              We have to cast away constness for REL.  */
-           rel->r_addend = addend;
-         else
-           {
-             /* Otherwise, we have to write the value back out.  Note
-                that we use the source mask, rather than the
-                destination mask because the place to which we are
-                writing will be source of the addend in the final
-                link.  */
-             addend >>= howto->rightshift;
+             /* We use the source mask, rather than the destination
+                mask because the place to which we are writing will be
+                source of the addend in the final link.  */
              addend &= howto->src_mask;
 
              if (r_type == R_MIPS_64 && ! NEWABI_P (output_bfd))
@@ -6260,8 +6446,6 @@ _bfd_mips_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
       else
        use_saved_addend_p = FALSE;
 
-      addend >>= howto->rightshift;
-
       /* Figure out what value we are supposed to relocate.  */
       switch (mips_elf_calculate_relocation (output_bfd, input_bfd,
                                             input_section, info, rel,
index aef4e7b..d3787e9 100644 (file)
@@ -103,6 +103,14 @@ extern bfd_reloc_status_type _bfd_mips_elf_gprel16_with_gp
   (bfd *, asymbol *, arelent *, asection *, bfd_boolean, void *, bfd_vma);
 extern bfd_reloc_status_type _bfd_mips_elf32_gprel16_reloc
   (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
+extern bfd_reloc_status_type _bfd_mips_elf_hi16_reloc
+  (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
+extern bfd_reloc_status_type _bfd_mips_elf_got16_reloc
+  (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
+extern bfd_reloc_status_type _bfd_mips_elf_lo16_reloc
+  (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
+extern bfd_reloc_status_type _bfd_mips_elf_generic_reloc
+  (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
 extern unsigned long _bfd_elf_mips_mach
   (flagword);
 extern bfd_boolean _bfd_mips_relax_section
index aec39cc..95408f6 100644 (file)
@@ -1,5 +1,12 @@
 2003-12-18  Richard Sandiford  <rsandifo@redhat.com>
 
+       * config/tc-mips.c (mips_need_elf_addend_fixup): Delete.
+       (md_apply_fix3): Remove bfd_install_relocation workarounds.
+       (tc_gen_reloc): Likewise. Factor handling of pc-relative relocations
+       and treat fx_addnumber as relative to the relocation address.
+
+2003-12-18  Richard Sandiford  <rsandifo@redhat.com>
+
        * config/tc-mips.c (s_change_section): When parsing the MIPS-specific
        .section syntax, map SHT_MIPS_DWARF to SHT_PROGBITS.
 
index e6997ca..eb5be49 100644 (file)
@@ -11339,31 +11339,6 @@ mips_validate_fix (struct fix *fixP, asection *seg)
   return 1;
 }
 
-#ifdef OBJ_ELF
-static int
-mips_need_elf_addend_fixup (fixS *fixP)
-{
-  if (S_GET_OTHER (fixP->fx_addsy) == STO_MIPS16)
-    return 1;
-  if (mips_pic == EMBEDDED_PIC
-      && S_IS_WEAK (fixP->fx_addsy))
-    return 1;
-  if (mips_pic != EMBEDDED_PIC
-      && (S_IS_WEAK (fixP->fx_addsy)
-         || S_IS_EXTERNAL (fixP->fx_addsy))
-      && !S_IS_COMMON (fixP->fx_addsy))
-    return 1;
-  if (((bfd_get_section_flags (stdoutput,
-                              S_GET_SEGMENT (fixP->fx_addsy))
-       & (SEC_LINK_ONCE | SEC_MERGE)) != 0)
-      || !strncmp (segment_name (S_GET_SEGMENT (fixP->fx_addsy)),
-                  ".gnu.linkonce",
-                  sizeof (".gnu.linkonce") - 1))
-    return 1;
-  return 0;
-}
-#endif
-
 /* Apply a fixup to the object file.  */
 
 void
@@ -11389,61 +11364,6 @@ md_apply_fix3 (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
 
   buf = (bfd_byte *) (fixP->fx_frag->fr_literal + fixP->fx_where);
 
-  /* If we aren't adjusting this fixup to be against the section
-     symbol, we need to adjust the value.  */
-#ifdef OBJ_ELF
-  if (fixP->fx_addsy != NULL && OUTPUT_FLAVOR == bfd_target_elf_flavour)
-    {
-      if (mips_need_elf_addend_fixup (fixP)
-         && howto->partial_inplace
-         && fixP->fx_r_type != BFD_RELOC_GPREL16
-         && fixP->fx_r_type != BFD_RELOC_GPREL32
-         && fixP->fx_r_type != BFD_RELOC_MIPS16_GPREL)
-       {
-         /* In this case, the bfd_install_relocation routine will
-            incorrectly add the symbol value back in.  We just want
-            the addend to appear in the object file.
-
-            The condition above used to include
-            "&& (! fixP->fx_pcrel || howto->pcrel_offset)".
-
-            However, howto can't be trusted here, because we
-            might change the reloc type in tc_gen_reloc.  We can
-            check howto->partial_inplace because that conversion
-            happens to preserve howto->partial_inplace; but it
-            does not preserve howto->pcrel_offset.  I've just
-            eliminated the check, because all MIPS PC-relative
-            relocations are marked howto->pcrel_offset.
-
-            howto->pcrel_offset was originally added for
-            R_MIPS_PC16, which is generated for code like
-
-                   globl g1 .text
-                   .text
-                   .space 20
-            g1:
-            x:
-                   bal g1
-          */
-         *valP -= S_GET_VALUE (fixP->fx_addsy);
-       }
-
-      /* This code was generated using trial and error and so is
-        fragile and not trustworthy.  If you change it, you should
-        rerun the elf-rel, elf-rel2, and empic testcases and ensure
-        they still pass.  */
-      if (fixP->fx_pcrel)
-       {
-         *valP += fixP->fx_frag->fr_address + fixP->fx_where;
-
-         /* BFD's REL handling, for MIPS, is _very_ weird.
-            This gives the right results, but it can't possibly
-            be the way things are supposed to work.  */
-         *valP += fixP->fx_frag->fr_address + fixP->fx_where;
-       }
-    }
-#endif
-
   /* We are not done if this is a composite relocation to set up gp.  */
   if (fixP->fx_addsy == NULL && ! fixP->fx_pcrel
       && !(fixP->fx_r_type == BFD_RELOC_MIPS_SUB
@@ -13406,52 +13326,49 @@ tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixp)
        as_fatal (_("Double check fx_r_type in tc-mips.c:tc_gen_reloc"));
       fixp->fx_r_type = BFD_RELOC_GPREL32;
     }
-  else if (fixp->fx_r_type == BFD_RELOC_PCREL_LO16)
+  else if (fixp->fx_pcrel)
     {
-      if (OUTPUT_FLAVOR == bfd_target_elf_flavour)
-       reloc->addend = fixp->fx_addnumber;
+      bfd_vma pcrel_address;
+
+      /* Set PCREL_ADDRESS to this relocation's "PC".  The PC for high
+        high-part relocs is the address of the low-part reloc.  */
+      if (fixp->fx_r_type == BFD_RELOC_PCREL_HI16_S)
+       {
+         assert (fixp->fx_next != NULL
+                 && fixp->fx_next->fx_r_type == BFD_RELOC_PCREL_LO16);
+         pcrel_address = (fixp->fx_next->fx_where
+                          + fixp->fx_next->fx_frag->fr_address);
+       }
       else
+       pcrel_address = reloc->address;
+
+      if (OUTPUT_FLAVOR == bfd_target_elf_flavour)
+       {
+         /* At this point, fx_addnumber is "symbol offset - pcrel_address".
+            Relocations want only the symbol offset.  */
+         reloc->addend = fixp->fx_addnumber + pcrel_address;
+       }
+      else if (fixp->fx_r_type == BFD_RELOC_PCREL_LO16
+              || fixp->fx_r_type == BFD_RELOC_PCREL_HI16_S)
        {
-         /* We use a special addend for an internal RELLO reloc.  */
+         /* We use a special addend for an internal RELLO or RELHI reloc.  */
          if (symbol_section_p (fixp->fx_addsy))
-           reloc->addend = reloc->address - S_GET_VALUE (fixp->fx_subsy);
+           reloc->addend = pcrel_address - S_GET_VALUE (fixp->fx_subsy);
          else
-           reloc->addend = fixp->fx_addnumber + reloc->address;
+           reloc->addend = fixp->fx_addnumber + pcrel_address;
        }
-    }
-  else if (fixp->fx_r_type == BFD_RELOC_PCREL_HI16_S)
-    {
-      assert (fixp->fx_next != NULL
-             && fixp->fx_next->fx_r_type == BFD_RELOC_PCREL_LO16);
-
-      /* The reloc is relative to the RELLO; adjust the addend
-        accordingly.  */
-      if (OUTPUT_FLAVOR == bfd_target_elf_flavour)
-       reloc->addend = fixp->fx_next->fx_addnumber;
       else
        {
-         /* We use a special addend for an internal RELHI reloc.  */
-         if (symbol_section_p (fixp->fx_addsy))
-           reloc->addend = (fixp->fx_next->fx_frag->fr_address
-                            + fixp->fx_next->fx_where
-                            - S_GET_VALUE (fixp->fx_subsy));
+         if (OUTPUT_FLAVOR != bfd_target_aout_flavour)
+           /* A gruesome hack which is a result of the gruesome gas reloc
+              handling.  */
+           reloc->addend = pcrel_address;
          else
-           reloc->addend = (fixp->fx_addnumber
-                            + fixp->fx_next->fx_frag->fr_address
-                            + fixp->fx_next->fx_where);
+           reloc->addend = -pcrel_address;
        }
     }
-  else if (fixp->fx_pcrel == 0 || OUTPUT_FLAVOR == bfd_target_elf_flavour)
-    reloc->addend = fixp->fx_addnumber;
   else
-    {
-      if (OUTPUT_FLAVOR != bfd_target_aout_flavour)
-       /* A gruesome hack which is a result of the gruesome gas reloc
-          handling.  */
-       reloc->addend = reloc->address;
-      else
-       reloc->addend = -reloc->address;
-    }
+    reloc->addend = fixp->fx_addnumber;
 
   /* If this is a variant frag, we may need to adjust the existing
      reloc and generate a new one.  */
@@ -13500,8 +13417,7 @@ tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixp)
       reloc2->address = (reloc->address
                         + (RELAX_RELOC2 (fixp->fx_frag->fr_subtype)
                            - RELAX_RELOC1 (fixp->fx_frag->fr_subtype)));
-      reloc2->addend = fixp->fx_addnumber - S_GET_VALUE (fixp->fx_addsy)
-       + fixp->fx_frag->tc_frag_data.tc_fr_offset;
+      reloc2->addend = reloc->addend;
       reloc2->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_LO16);
       assert (reloc2->howto != NULL);
 
index b606043..829fb75 100644 (file)
@@ -1,3 +1,10 @@
+2003-12-18  Richard Sandiford  <rsandifo@redhat.com>
+
+       * gas/mips/mips16-jalx.d: Use -mabi=o64.
+       * gas/mips/mips16.d: Likewise.
+       * gas/mips/elf-rel17.[sd]: New test.
+       * gas/mips/mips.exp: Run it.
+
 2003-12-17  Nick Clifton  <nickc@redhat.com>
 
        * gas/m32r/error.exp: Add parallel.s
diff --git a/gas/testsuite/gas/mips/elf-rel17.d b/gas/testsuite/gas/mips/elf-rel17.d
new file mode 100644 (file)
index 0000000..8774ae2
--- /dev/null
@@ -0,0 +1,13 @@
+#objdump: -dr
+#as: -mabi=32
+
+.*:     file format .*
+
+Disassembly of section \.text:
+
+00000000 <.*>:
+.*:    3c040000        lui     a0,0x0
+                       .*: R_MIPS_HI16 x
+.*:    24840000        addiu   a0,a0,0
+                       .*: R_MIPS_LO16 x
+       \.\.\.
diff --git a/gas/testsuite/gas/mips/elf-rel17.s b/gas/testsuite/gas/mips/elf-rel17.s
new file mode 100644 (file)
index 0000000..44ec0fa
--- /dev/null
@@ -0,0 +1,3 @@
+       la      $4,x
+       .space  16
+       .comm   x,12
index fa8a9a9..2d515a9 100644 (file)
@@ -670,6 +670,7 @@ if { [istarget mips*-*-*] } then {
            run_dump_test "elf-rel-got-n64"
            run_dump_test "elf-rel-xgot-n64"
        }
+       run_dump_test "elf-rel17"
 
        run_dump_test "${tmips}${el}empic"
        run_dump_test "empic2"
index eeec2cb..8af1066 100644 (file)
@@ -1,5 +1,5 @@
 #objdump: -dr -mmips:4000 -mmips:16
-#as: -mips3 -mtune=r4000 -mips16
+#as: -mips3 -mtune=r4000 -mips16 -mabi=o64
 #name: mips16 jalx
 .*:     file format .*
 Disassembly of section .text:
index 1550529..7169d69 100644 (file)
@@ -1,5 +1,5 @@
 #objdump: -dr -mmips:4000
-#as: -mips3 -mtune=r4000
+#as: -mips3 -mtune=r4000 -mabi=o64
 #name: mips16
 
 # Test the mips16 instruction set.