* elf32-mips.c (_bfd_mips_elf_relocate_section): Formatting.
[binutils-gdb.git] / bfd / elf32-mips.c
index 70e9dc9e4dfea4662512806b46e8ef9c3a47a78d..9e8e0d3dfb3512f0620299431b21c663a90c495a 100644 (file)
@@ -76,6 +76,10 @@ struct mips_elf_link_hash_entry
      this symbol.  */
   unsigned int possibly_dynamic_relocs;
 
+  /* If the R_MIPS_32, R_MIPS_REL32, or R_MIPS_64 reloc is against
+     a readonly section.  */
+  boolean readonly_reloc;
+
   /* The index of the first dynamic relocation (in the .rel.dyn
      section) against this symbol.  */
   unsigned int min_dyn_reloc_index;
@@ -128,7 +132,7 @@ static boolean mips_elf_create_procedure_table
   PARAMS ((PTR, bfd *, struct bfd_link_info *, asection *,
           struct ecoff_debug_info *));
 static INLINE int elf_mips_isa PARAMS ((flagword));
-static INLINE int elf_mips_mach PARAMS ((flagword));
+static INLINE unsigned long elf_mips_mach PARAMS ((flagword));
 static INLINE char* elf_mips_abi_name PARAMS ((bfd *));
 static boolean mips_elf_is_local_label_name
   PARAMS ((bfd *, const char *));
@@ -206,6 +210,21 @@ static boolean mips_elf_stub_section_p
   PARAMS ((bfd *, asection *));
 static int sort_dynamic_relocs
   PARAMS ((const void *, const void *));
+static void _bfd_mips_elf_hide_symbol
+  PARAMS ((struct bfd_link_info *, struct elf_link_hash_entry *));
+static void _bfd_mips_elf_copy_indirect_symbol
+  PARAMS ((struct elf_link_hash_entry *,
+          struct elf_link_hash_entry *));
+static boolean _bfd_elf32_mips_grok_prstatus
+  PARAMS ((bfd *, Elf_Internal_Note *));
+static boolean _bfd_elf32_mips_grok_psinfo
+  PARAMS ((bfd *, Elf_Internal_Note *));
+static boolean _bfd_elf32_mips_discard_info
+  PARAMS ((bfd *, struct elf_reloc_cookie *, struct bfd_link_info *));
+static boolean _bfd_elf32_mips_ignore_discarded_relocs
+  PARAMS ((asection *));
+static boolean _bfd_elf32_mips_write_section
+  PARAMS ((bfd *, asection *, bfd_byte *));
 
 extern const bfd_target bfd_elf32_tradbigmips_vec;
 extern const bfd_target bfd_elf32_tradlittlemips_vec;
@@ -249,8 +268,10 @@ static bfd *reldyn_sorting_bfd;
     (abfd->xvec == &bfd_elf32_tradlittlemips_vec)) ? ict_none : \
   ((ABI_N32_P (abfd) || ABI_64_P (abfd)) ? ict_irix6 : ict_irix5))
 #endif
-/* Whether we are trying to be compatible with IRIX at all.  */
 
+#define NEWABI_P(abfd) (ABI_N32_P(abfd) || ABI_64_P(abfd))
+
+/* Whether we are trying to be compatible with IRIX at all.  */
 #define SGI_COMPAT(abfd) \
   (IRIX_COMPAT (abfd) != ict_none)
 
@@ -303,15 +324,15 @@ static bfd *reldyn_sorting_bfd;
 
 /* Add a dynamic symbol table-entry.  */
 #ifdef BFD64
-#define MIPS_ELF_ADD_DYNAMIC_ENTRY(info, tag, val) \
-  (ABI_64_P (elf_hash_table (info)->dynobj)       \
-   ? bfd_elf64_add_dynamic_entry (info, tag, val)  \
-   : bfd_elf32_add_dynamic_entry (info, tag, val))
+#define MIPS_ELF_ADD_DYNAMIC_ENTRY(info, tag, val)                     \
+  (ABI_64_P (elf_hash_table (info)->dynobj)                            \
+   ? bfd_elf64_add_dynamic_entry (info, (bfd_vma) tag, (bfd_vma) val)  \
+   : bfd_elf32_add_dynamic_entry (info, (bfd_vma) tag, (bfd_vma) val))
 #else
-#define MIPS_ELF_ADD_DYNAMIC_ENTRY(info, tag, val) \
-  (ABI_64_P (elf_hash_table (info)->dynobj)       \
-   ? (abort (), false)                             \
-   : bfd_elf32_add_dynamic_entry (info, tag, val))
+#define MIPS_ELF_ADD_DYNAMIC_ENTRY(info, tag, val)                     \
+  (ABI_64_P (elf_hash_table (info)->dynobj)                            \
+   ? (boolean) (abort (), false)                                       \
+   : bfd_elf32_add_dynamic_entry (info, (bfd_vma) tag, (bfd_vma) val))
 #endif
 
 /* The number of local .got entries we reserve.  */
@@ -471,13 +492,13 @@ static void bfd_elf32_swap_compact_rel_out
 static void bfd_elf32_swap_crinfo_out
   PARAMS ((bfd *, const Elf32_crinfo *, Elf32_External_crinfo *));
 
-#define USE_REL        1               /* MIPS uses REL relocations instead of RELA */
-
 /* In case we're on a 32-bit machine, construct a 64-bit "-1" value
    from smaller values.  Start with zero, widen, *then* decrement.  */
 #define MINUS_ONE      (((bfd_vma)0) - 1)
 
-static reloc_howto_type elf_mips_howto_table[] =
+/* The relocation table used for SHT_REL sections.  */
+
+static reloc_howto_type elf_mips_howto_table_rel[] =
 {
   /* No relocation.  */
   HOWTO (R_MIPS_NONE,          /* type */
@@ -497,16 +518,16 @@ static reloc_howto_type elf_mips_howto_table[] =
   /* 16 bit relocation.  */
   HOWTO (R_MIPS_16,            /* type */
         0,                     /* rightshift */
-        1,                     /* size (0 = byte, 1 = short, 2 = long) */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
         16,                    /* bitsize */
         false,                 /* pc_relative */
         0,                     /* bitpos */
-        complain_overflow_bitfield, /* complain_on_overflow */
+        complain_overflow_signed, /* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
         "R_MIPS_16",           /* name */
         true,                  /* partial_inplace */
-        0xffff,                /* src_mask */
-        0xffff,                /* dst_mask */
+        0x0000ffff,            /* src_mask */
+        0x0000ffff,            /* dst_mask */
         false),                /* pcrel_offset */
 
   /* 32 bit relocation.  */
@@ -516,7 +537,7 @@ static reloc_howto_type elf_mips_howto_table[] =
         32,                    /* bitsize */
         false,                 /* pc_relative */
         0,                     /* bitpos */
-        complain_overflow_bitfield, /* complain_on_overflow */
+        complain_overflow_dont, /* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
         "R_MIPS_32",           /* name */
         true,                  /* partial_inplace */
@@ -531,7 +552,7 @@ static reloc_howto_type elf_mips_howto_table[] =
         32,                    /* bitsize */
         false,                 /* pc_relative */
         0,                     /* bitpos */
-        complain_overflow_bitfield, /* complain_on_overflow */
+        complain_overflow_dont, /* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
         "R_MIPS_REL32",        /* name */
         true,                  /* partial_inplace */
@@ -553,8 +574,8 @@ static reloc_howto_type elf_mips_howto_table[] =
         bfd_elf_generic_reloc, /* special_function */
         "R_MIPS_26",           /* name */
         true,                  /* partial_inplace */
-        0x3ffffff,             /* src_mask */
-        0x3ffffff,             /* dst_mask */
+        0x03ffffff,            /* src_mask */
+        0x03ffffff,            /* dst_mask */
         false),                /* pcrel_offset */
 
   /* High 16 bits of symbol value.  */
@@ -568,8 +589,8 @@ static reloc_howto_type elf_mips_howto_table[] =
         _bfd_mips_elf_hi16_reloc,      /* special_function */
         "R_MIPS_HI16",         /* name */
         true,                  /* partial_inplace */
-        0xffff,                /* src_mask */
-        0xffff,                /* dst_mask */
+        0x0000ffff,            /* src_mask */
+        0x0000ffff,            /* dst_mask */
         false),                /* pcrel_offset */
 
   /* Low 16 bits of symbol value.  */
@@ -583,8 +604,8 @@ static reloc_howto_type elf_mips_howto_table[] =
         _bfd_mips_elf_lo16_reloc,      /* special_function */
         "R_MIPS_LO16",         /* name */
         true,                  /* partial_inplace */
-        0xffff,                /* src_mask */
-        0xffff,                /* dst_mask */
+        0x0000ffff,            /* src_mask */
+        0x0000ffff,            /* dst_mask */
         false),                /* pcrel_offset */
 
   /* GP relative reference.  */
@@ -598,8 +619,8 @@ static reloc_howto_type elf_mips_howto_table[] =
         _bfd_mips_elf_gprel16_reloc, /* special_function */
         "R_MIPS_GPREL16",      /* name */
         true,                  /* partial_inplace */
-        0xffff,                /* src_mask */
-        0xffff,                /* dst_mask */
+        0x0000ffff,            /* src_mask */
+        0x0000ffff,            /* dst_mask */
         false),                /* pcrel_offset */
 
   /* Reference to literal section.  */
@@ -613,8 +634,8 @@ static reloc_howto_type elf_mips_howto_table[] =
         _bfd_mips_elf_gprel16_reloc, /* special_function */
         "R_MIPS_LITERAL",      /* name */
         true,                  /* partial_inplace */
-        0xffff,                /* src_mask */
-        0xffff,                /* dst_mask */
+        0x0000ffff,            /* src_mask */
+        0x0000ffff,            /* dst_mask */
         false),                /* pcrel_offset */
 
   /* Reference to global offset table.  */
@@ -627,9 +648,9 @@ static reloc_howto_type elf_mips_howto_table[] =
         complain_overflow_signed, /* complain_on_overflow */
         _bfd_mips_elf_got16_reloc,     /* special_function */
         "R_MIPS_GOT16",        /* name */
-        false,                 /* partial_inplace */
-        0xffff,                /* src_mask */
-        0xffff,                /* dst_mask */
+        true,                  /* partial_inplace */
+        0x0000ffff,            /* src_mask */
+        0x0000ffff,            /* dst_mask */
         false),                /* pcrel_offset */
 
   /* 16 bit PC relative reference.  */
@@ -643,8 +664,8 @@ static reloc_howto_type elf_mips_howto_table[] =
         bfd_elf_generic_reloc, /* special_function */
         "R_MIPS_PC16",         /* name */
         true,                  /* partial_inplace */
-        0xffff,                /* src_mask */
-        0xffff,                /* dst_mask */
+        0x0000ffff,            /* src_mask */
+        0x0000ffff,            /* dst_mask */
         true),                 /* pcrel_offset */
 
   /* 16 bit call through global offset table.  */
@@ -657,9 +678,9 @@ static reloc_howto_type elf_mips_howto_table[] =
         complain_overflow_signed, /* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
         "R_MIPS_CALL16",       /* name */
-        false,                 /* partial_inplace */
-        0xffff,                /* src_mask */
-        0xffff,                /* dst_mask */
+        true,                  /* partial_inplace */
+        0x0000ffff,            /* src_mask */
+        0x0000ffff,            /* dst_mask */
         false),                /* pcrel_offset */
 
   /* 32 bit GP relative reference.  */
@@ -669,7 +690,7 @@ static reloc_howto_type elf_mips_howto_table[] =
         32,                    /* bitsize */
         false,                 /* pc_relative */
         0,                     /* bitpos */
-        complain_overflow_bitfield, /* complain_on_overflow */
+        complain_overflow_dont, /* complain_on_overflow */
         _bfd_mips_elf_gprel32_reloc, /* special_function */
         "R_MIPS_GPREL32",      /* name */
         true,                  /* partial_inplace */
@@ -677,11 +698,11 @@ static reloc_howto_type elf_mips_howto_table[] =
         0xffffffff,            /* dst_mask */
         false),                /* pcrel_offset */
 
-    /* The remaining relocs are defined on Irix 5, although they are
-       not defined by the ABI.  */
-    EMPTY_HOWTO (13),
-    EMPTY_HOWTO (14),
-    EMPTY_HOWTO (15),
+  /* The remaining relocs are defined on Irix 5, although they are
+     not defined by the ABI.  */
+  EMPTY_HOWTO (13),
+  EMPTY_HOWTO (14),
+  EMPTY_HOWTO (15),
 
   /* A 5 bit shift field.  */
   HOWTO (R_MIPS_SHIFT5,                /* type */
@@ -722,7 +743,7 @@ static reloc_howto_type elf_mips_howto_table[] =
         64,                    /* bitsize */
         false,                 /* pc_relative */
         0,                     /* bitpos */
-        complain_overflow_bitfield, /* complain_on_overflow */
+        complain_overflow_dont, /* complain_on_overflow */
         mips32_64bit_reloc,    /* special_function */
         "R_MIPS_64",           /* name */
         true,                  /* partial_inplace */
@@ -737,7 +758,7 @@ static reloc_howto_type elf_mips_howto_table[] =
         16,                    /* bitsize */
         false,                 /* pc_relative */
         0,                     /* bitpos */
-        complain_overflow_bitfield, /* complain_on_overflow */
+        complain_overflow_signed, /* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
         "R_MIPS_GOT_DISP",     /* name */
         true,                  /* partial_inplace */
@@ -752,7 +773,7 @@ static reloc_howto_type elf_mips_howto_table[] =
         16,                    /* bitsize */
         false,                 /* pc_relative */
         0,                     /* bitpos */
-        complain_overflow_bitfield, /* complain_on_overflow */
+        complain_overflow_signed, /* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
         "R_MIPS_GOT_PAGE",     /* name */
         true,                  /* partial_inplace */
@@ -767,7 +788,7 @@ static reloc_howto_type elf_mips_howto_table[] =
         16,                    /* bitsize */
         false,                 /* pc_relative */
         0,                     /* bitpos */
-        complain_overflow_bitfield, /* complain_on_overflow */
+        complain_overflow_signed, /* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
         "R_MIPS_GOT_OFST",     /* name */
         true,                  /* partial_inplace */
@@ -808,23 +829,520 @@ static reloc_howto_type elf_mips_howto_table[] =
   /* 64 bit subtraction.  Used in the N32 ABI.  */
   HOWTO (R_MIPS_SUB,           /* type */
         0,                     /* rightshift */
-        4,                     /* size (0 = byte, 1 = short, 2 = long) */
-        64,                    /* bitsize */
+        4,                     /* size (0 = byte, 1 = short, 2 = long) */
+        64,                    /* bitsize */
+        false,                 /* pc_relative */
+        0,                     /* bitpos */
+        complain_overflow_dont, /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_MIPS_SUB",          /* name */
+        true,                  /* partial_inplace */
+        MINUS_ONE,             /* src_mask */
+        MINUS_ONE,             /* dst_mask */
+        false),                /* pcrel_offset */
+
+  /* Used to cause the linker to insert and delete instructions?  */
+  EMPTY_HOWTO (R_MIPS_INSERT_A),
+  EMPTY_HOWTO (R_MIPS_INSERT_B),
+  EMPTY_HOWTO (R_MIPS_DELETE),
+
+  /* Get the higher value of a 64 bit addend.  */
+  HOWTO (R_MIPS_HIGHER,                /* type */
+        0,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        16,                    /* bitsize */
+        false,                 /* pc_relative */
+        0,                     /* bitpos */
+        complain_overflow_dont, /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_MIPS_HIGHER",       /* name */
+        true,                  /* partial_inplace */
+        0x0000ffff,            /* src_mask */
+        0x0000ffff,            /* dst_mask */
+        false),                /* pcrel_offset */
+
+  /* Get the highest value of a 64 bit addend.  */
+  HOWTO (R_MIPS_HIGHEST,       /* type */
+        0,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        16,                    /* bitsize */
+        false,                 /* pc_relative */
+        0,                     /* bitpos */
+        complain_overflow_dont, /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_MIPS_HIGHEST",      /* name */
+        true,                  /* partial_inplace */
+        0x0000ffff,            /* src_mask */
+        0x0000ffff,            /* dst_mask */
+        false),                /* pcrel_offset */
+
+  /* High 16 bits of displacement in global offset table.  */
+  HOWTO (R_MIPS_CALL_HI16,     /* type */
+        0,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        16,                    /* bitsize */
+        false,                 /* pc_relative */
+        0,                     /* bitpos */
+        complain_overflow_dont, /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_MIPS_CALL_HI16",    /* name */
+        true,                  /* partial_inplace */
+        0x0000ffff,            /* src_mask */
+        0x0000ffff,            /* dst_mask */
+        false),                /* pcrel_offset */
+
+  /* Low 16 bits of displacement in global offset table.  */
+  HOWTO (R_MIPS_CALL_LO16,     /* type */
+        0,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        16,                    /* bitsize */
+        false,                 /* pc_relative */
+        0,                     /* bitpos */
+        complain_overflow_dont, /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_MIPS_CALL_LO16",    /* name */
+        true,                  /* partial_inplace */
+        0x0000ffff,            /* src_mask */
+        0x0000ffff,            /* dst_mask */
+        false),                /* pcrel_offset */
+
+  /* Section displacement.  */
+  HOWTO (R_MIPS_SCN_DISP,       /* type */
+        0,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        32,                    /* bitsize */
+        false,                 /* pc_relative */
+        0,                     /* bitpos */
+        complain_overflow_dont, /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_MIPS_SCN_DISP",     /* name */
+        true,                  /* partial_inplace */
+        0xffffffff,            /* src_mask */
+        0xffffffff,            /* dst_mask */
+        false),                /* pcrel_offset */
+
+  EMPTY_HOWTO (R_MIPS_REL16),
+  EMPTY_HOWTO (R_MIPS_ADD_IMMEDIATE),
+  EMPTY_HOWTO (R_MIPS_PJUMP),
+  EMPTY_HOWTO (R_MIPS_RELGOT),
+
+  /* Protected jump conversion.  This is an optimization hint.  No
+     relocation is required for correctness.  */
+  HOWTO (R_MIPS_JALR,          /* type */
+        0,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        32,                    /* bitsize */
+        false,                 /* pc_relative */
+        0,                     /* bitpos */
+        complain_overflow_dont, /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_MIPS_JALR",         /* name */
+        false,                 /* partial_inplace */
+        0x00000000,            /* src_mask */
+        0x00000000,            /* dst_mask */
+        false),                /* pcrel_offset */
+};
+
+/* The relocation table used for SHT_RELA sections.  */
+
+static reloc_howto_type elf_mips_howto_table_rela[] =
+{
+  /* No relocation.  */
+  HOWTO (R_MIPS_NONE,          /* type */
+        0,                     /* rightshift */
+        0,                     /* size (0 = byte, 1 = short, 2 = long) */
+        0,                     /* bitsize */
+        false,                 /* pc_relative */
+        0,                     /* bitpos */
+        complain_overflow_dont, /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_MIPS_NONE",         /* name */
+        false,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0,                     /* dst_mask */
+        false),                /* pcrel_offset */
+
+  /* 16 bit relocation.  */
+  HOWTO (R_MIPS_16,            /* type */
+        0,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        16,                    /* bitsize */
+        false,                 /* pc_relative */
+        0,                     /* bitpos */
+        complain_overflow_signed, /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_MIPS_16",           /* name */
+        false,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0x0000,                /* dst_mask */
+        false),                /* pcrel_offset */
+
+  /* 32 bit relocation.  */
+  HOWTO (R_MIPS_32,            /* type */
+        0,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        32,                    /* bitsize */
+        false,                 /* pc_relative */
+        0,                     /* bitpos */
+        complain_overflow_dont, /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_MIPS_32",           /* name */
+        false,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0xffffffff,            /* dst_mask */
+        false),                /* pcrel_offset */
+
+  /* 32 bit symbol relative relocation.  */
+  HOWTO (R_MIPS_REL32,         /* type */
+        0,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        32,                    /* bitsize */
+        false,                 /* pc_relative */
+        0,                     /* bitpos */
+        complain_overflow_dont, /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_MIPS_REL32",        /* name */
+        false,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0xffffffff,            /* dst_mask */
+        false),                /* pcrel_offset */
+
+  /* 26 bit jump address.  */
+  HOWTO (R_MIPS_26,            /* type */
+        2,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        26,                    /* bitsize */
+        false,                 /* pc_relative */
+        0,                     /* bitpos */
+        complain_overflow_dont, /* complain_on_overflow */
+                               /* This needs complex overflow
+                                  detection, because the upper 36
+                                  bits must match the PC + 4.  */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_MIPS_26",           /* name */
+        false,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0x03ffffff,            /* dst_mask */
+        false),                /* pcrel_offset */
+
+  /* R_MIPS_HI16 and R_MIPS_LO16 are unsupported for 64 bit REL.  */
+  /* High 16 bits of symbol value.  */
+  HOWTO (R_MIPS_HI16,          /* type */
+        0,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        16,                    /* bitsize */
+        false,                 /* pc_relative */
+        0,                     /* bitpos */
+        complain_overflow_dont, /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_MIPS_HI16",         /* name */
+        false,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0x0000ffff,            /* dst_mask */
+        false),                /* pcrel_offset */
+
+  /* Low 16 bits of symbol value.  */
+  HOWTO (R_MIPS_LO16,          /* type */
+        0,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        16,                    /* bitsize */
+        false,                 /* pc_relative */
+        0,                     /* bitpos */
+        complain_overflow_dont, /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_MIPS_LO16",         /* name */
+        false,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0x0000ffff,            /* dst_mask */
+        false),                /* pcrel_offset */
+
+  /* GP relative reference.  */
+  HOWTO (R_MIPS_GPREL16,       /* type */
+        0,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        16,                    /* bitsize */
+        false,                 /* pc_relative */
+        0,                     /* bitpos */
+        complain_overflow_signed, /* complain_on_overflow */
+        _bfd_mips_elf_gprel16_reloc, /* special_function */
+        "R_MIPS_GPREL16",      /* name */
+        false,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0x0000ffff,            /* dst_mask */
+        false),                /* pcrel_offset */
+
+  /* Reference to literal section.  */
+  HOWTO (R_MIPS_LITERAL,       /* type */
+        0,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        16,                    /* bitsize */
+        false,                 /* pc_relative */
+        0,                     /* bitpos */
+        complain_overflow_signed, /* complain_on_overflow */
+        _bfd_mips_elf_gprel16_reloc, /* special_function */
+        "R_MIPS_LITERAL",      /* name */
+        false,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0x0000ffff,            /* dst_mask */
+        false),                /* pcrel_offset */
+
+  /* Reference to global offset table.  */
+  /* FIXME: This is not handled correctly.  */
+  HOWTO (R_MIPS_GOT16,         /* type */
+        0,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        16,                    /* bitsize */
+        false,                 /* pc_relative */
+        0,                     /* bitpos */
+        complain_overflow_signed, /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_MIPS_GOT16",        /* name */
+        false,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0x0000ffff,            /* dst_mask */
+        false),                /* pcrel_offset */
+
+  /* 16 bit PC relative reference.  */
+  HOWTO (R_MIPS_PC16,          /* type */
+        0,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        16,                    /* bitsize */
+        true,                  /* pc_relative */
+        0,                     /* bitpos */
+        complain_overflow_signed, /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_MIPS_PC16",         /* name */
+        false,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0x0000ffff,            /* dst_mask */
+        true),                 /* pcrel_offset */
+
+  /* 16 bit call through global offset table.  */
+  /* FIXME: This is not handled correctly.  */
+  HOWTO (R_MIPS_CALL16,                /* type */
+        0,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        16,                    /* bitsize */
+        false,                 /* pc_relative */
+        0,                     /* bitpos */
+        complain_overflow_signed, /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_MIPS_CALL16",       /* name */
+        false,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0x0000ffff,            /* dst_mask */
+        false),                /* pcrel_offset */
+
+  /* 32 bit GP relative reference.  */
+  HOWTO (R_MIPS_GPREL32,       /* type */
+        0,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        32,                    /* bitsize */
+        false,                 /* pc_relative */
+        0,                     /* bitpos */
+        complain_overflow_dont, /* complain_on_overflow */
+        _bfd_mips_elf_gprel32_reloc, /* special_function */
+        "R_MIPS_GPREL32",      /* name */
+        false,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0xffffffff,            /* dst_mask */
+        false),                /* pcrel_offset */
+
+  EMPTY_HOWTO (13),
+  EMPTY_HOWTO (14),
+  EMPTY_HOWTO (15),
+
+  /* A 5 bit shift field.  */
+  HOWTO (R_MIPS_SHIFT5,                /* type */
+        0,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        5,                     /* bitsize */
+        false,                 /* pc_relative */
+        6,                     /* bitpos */
+        complain_overflow_bitfield, /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_MIPS_SHIFT5",       /* name */
+        false,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0x000007c0,            /* dst_mask */
+        false),                /* pcrel_offset */
+
+  /* A 6 bit shift field.  */
+  /* FIXME: Not handled correctly.  */
+  HOWTO (R_MIPS_SHIFT6,                /* type */
+        0,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        6,                     /* bitsize */
+        false,                 /* pc_relative */
+        6,                     /* bitpos */
+        complain_overflow_bitfield, /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_MIPS_SHIFT6",       /* name */
+        false,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0x000007c4,            /* dst_mask */
+        false),                /* pcrel_offset */
+
+  /* 64 bit relocation.  */
+  HOWTO (R_MIPS_64,            /* type */
+        0,                     /* rightshift */
+        4,                     /* size (0 = byte, 1 = short, 2 = long) */
+        64,                    /* bitsize */
+        false,                 /* pc_relative */
+        0,                     /* bitpos */
+        complain_overflow_dont, /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_MIPS_64",           /* name */
+        false,                 /* partial_inplace */
+        0,                     /* src_mask */
+        MINUS_ONE,             /* dst_mask */
+        false),                /* pcrel_offset */
+
+  /* Displacement in the global offset table.  */
+  /* FIXME: Not handled correctly.  */
+  HOWTO (R_MIPS_GOT_DISP,      /* type */
+        0,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        16,                    /* bitsize */
+        false,                 /* pc_relative */
+        0,                     /* bitpos */
+        complain_overflow_signed, /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_MIPS_GOT_DISP",     /* name */
+        false,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0x0000ffff,            /* dst_mask */
+        false),                /* pcrel_offset */
+
+  /* Displacement to page pointer in the global offset table.  */
+  /* FIXME: Not handled correctly.  */
+  HOWTO (R_MIPS_GOT_PAGE,      /* type */
+        0,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        16,                    /* bitsize */
+        false,                 /* pc_relative */
+        0,                     /* bitpos */
+        complain_overflow_signed, /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_MIPS_GOT_PAGE",     /* name */
+        false,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0x0000ffff,            /* dst_mask */
+        false),                /* pcrel_offset */
+
+  /* Offset from page pointer in the global offset table.  */
+  /* FIXME: Not handled correctly.  */
+  HOWTO (R_MIPS_GOT_OFST,      /* type */
+        0,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        16,                    /* bitsize */
+        false,                 /* pc_relative */
+        0,                     /* bitpos */
+        complain_overflow_signed, /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_MIPS_GOT_OFST",     /* name */
+        false,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0x0000ffff,            /* dst_mask */
+        false),                /* pcrel_offset */
+
+  /* High 16 bits of displacement in global offset table.  */
+  /* FIXME: Not handled correctly.  */
+  HOWTO (R_MIPS_GOT_HI16,      /* type */
+        0,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        16,                    /* bitsize */
+        false,                 /* pc_relative */
+        0,                     /* bitpos */
+        complain_overflow_dont, /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_MIPS_GOT_HI16",     /* name */
+        false,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0x0000ffff,            /* dst_mask */
+        false),                /* pcrel_offset */
+
+  /* Low 16 bits of displacement in global offset table.  */
+  /* FIXME: Not handled correctly.  */
+  HOWTO (R_MIPS_GOT_LO16,      /* type */
+        0,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        16,                    /* bitsize */
+        false,                 /* pc_relative */
+        0,                     /* bitpos */
+        complain_overflow_dont, /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_MIPS_GOT_LO16",     /* name */
+        false,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0x0000ffff,            /* dst_mask */
+        false),                /* pcrel_offset */
+
+  /* 64 bit substraction.  */
+  /* FIXME: Not handled correctly.  */
+  HOWTO (R_MIPS_SUB,           /* type */
+        0,                     /* rightshift */
+        4,                     /* size (0 = byte, 1 = short, 2 = long) */
+        64,                    /* bitsize */
+        false,                 /* pc_relative */
+        0,                     /* bitpos */
+        complain_overflow_dont, /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_MIPS_SUB",          /* name */
+        false,                 /* partial_inplace */
+        0,                     /* src_mask */
+        MINUS_ONE,             /* dst_mask */
+        false),                /* pcrel_offset */
+
+  /* Insert the addend as an instruction.  */
+  /* FIXME: Not handled correctly.  */
+  HOWTO (R_MIPS_INSERT_A,      /* type */
+        0,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        32,                    /* bitsize */
+        false,                 /* pc_relative */
+        0,                     /* bitpos */
+        complain_overflow_dont, /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_MIPS_INSERT_A",     /* name */
+        false,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0xffffffff,            /* dst_mask */
+        false),                /* pcrel_offset */
+
+  /* Insert the addend as an instruction, and change all relocations
+     to refer to the old instruction at the address.  */
+  /* FIXME: Not handled correctly.  */
+  HOWTO (R_MIPS_INSERT_B,      /* type */
+        0,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        32,                    /* bitsize */
+        false,                 /* pc_relative */
+        0,                     /* bitpos */
+        complain_overflow_dont, /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_MIPS_INSERT_B",     /* name */
+        false,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0xffffffff,            /* dst_mask */
+        false),                /* pcrel_offset */
+
+  /* Delete a 32 bit instruction.  */
+  /* FIXME: Not handled correctly.  */
+  HOWTO (R_MIPS_DELETE,                /* type */
+        0,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        32,                    /* bitsize */
         false,                 /* pc_relative */
         0,                     /* bitpos */
-        complain_overflow_bitfield, /* complain_on_overflow */
+        complain_overflow_dont, /* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
-        "R_MIPS_SUB",          /* name */
-        true,                  /* partial_inplace */
-        MINUS_ONE,             /* src_mask */
-        MINUS_ONE,             /* dst_mask */
+        "R_MIPS_DELETE",       /* name */
+        false,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0xffffffff,            /* dst_mask */
         false),                /* pcrel_offset */
 
-  /* Used to cause the linker to insert and delete instructions?  */
-  EMPTY_HOWTO (R_MIPS_INSERT_A),
-  EMPTY_HOWTO (R_MIPS_INSERT_B),
-  EMPTY_HOWTO (R_MIPS_DELETE),
-
   /* Get the higher value of a 64 bit addend.  */
   HOWTO (R_MIPS_HIGHER,                /* type */
         0,                     /* rightshift */
@@ -833,11 +1351,11 @@ static reloc_howto_type elf_mips_howto_table[] =
         false,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont, /* complain_on_overflow */
-        bfd_elf_generic_reloc, /* special_function */
+        bfd_elf_generic_reloc, /* special_function */
         "R_MIPS_HIGHER",       /* name */
-        true,                  /* partial_inplace */
+        false,                 /* partial_inplace */
         0,                     /* src_mask */
-        0xffff,                /* dst_mask */
+        0x0000ffff,            /* dst_mask */
         false),                /* pcrel_offset */
 
   /* Get the highest value of a 64 bit addend.  */
@@ -848,14 +1366,15 @@ static reloc_howto_type elf_mips_howto_table[] =
         false,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont, /* complain_on_overflow */
-        bfd_elf_generic_reloc, /* special_function */
+        bfd_elf_generic_reloc, /* special_function */
         "R_MIPS_HIGHEST",      /* name */
-        true,                  /* partial_inplace */
+        false,                 /* partial_inplace */
         0,                     /* src_mask */
-        0xffff,                /* dst_mask */
+        0x0000ffff,            /* dst_mask */
         false),                /* pcrel_offset */
 
   /* High 16 bits of displacement in global offset table.  */
+  /* FIXME: Not handled correctly.  */
   HOWTO (R_MIPS_CALL_HI16,     /* type */
         0,                     /* rightshift */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
@@ -865,12 +1384,13 @@ static reloc_howto_type elf_mips_howto_table[] =
         complain_overflow_dont, /* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
         "R_MIPS_CALL_HI16",    /* name */
-        true,                  /* partial_inplace */
-        0x0000ffff,            /* src_mask */
+        false,                 /* partial_inplace */
+        0,                     /* src_mask */
         0x0000ffff,            /* dst_mask */
         false),                /* pcrel_offset */
 
   /* Low 16 bits of displacement in global offset table.  */
+  /* FIXME: Not handled correctly.  */
   HOWTO (R_MIPS_CALL_LO16,     /* type */
         0,                     /* rightshift */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
@@ -880,13 +1400,14 @@ static reloc_howto_type elf_mips_howto_table[] =
         complain_overflow_dont, /* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
         "R_MIPS_CALL_LO16",    /* name */
-        true,                  /* partial_inplace */
-        0x0000ffff,            /* src_mask */
+        false,                 /* partial_inplace */
+        0,                     /* src_mask */
         0x0000ffff,            /* dst_mask */
         false),                /* pcrel_offset */
 
-  /* Section displacement.  */
-  HOWTO (R_MIPS_SCN_DISP,       /* type */
+  /* Section displacement, used by an associated event location section.  */
+  /* FIXME: Not handled correctly.  */
+  HOWTO (R_MIPS_SCN_DISP,      /* type */
         0,                     /* rightshift */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
         32,                    /* bitsize */
@@ -894,31 +1415,60 @@ static reloc_howto_type elf_mips_howto_table[] =
         0,                     /* bitpos */
         complain_overflow_dont, /* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
-        "R_MIPS_SCN_DISP",     /* name */
+        "R_MIPS_SCN_DISP",     /* name */
         false,                 /* partial_inplace */
-        0xffffffff,            /* src_mask */
+        0,                     /* src_mask */
         0xffffffff,            /* dst_mask */
         false),                /* pcrel_offset */
 
-  EMPTY_HOWTO (R_MIPS_REL16),
+  HOWTO (R_MIPS_REL16,         /* type */
+        0,                     /* rightshift */
+        1,                     /* size (0 = byte, 1 = short, 2 = long) */
+        16,                    /* bitsize */
+        false,                 /* pc_relative */
+        0,                     /* bitpos */
+        complain_overflow_signed, /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_MIPS_REL16",        /* name */
+        false,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0xffff,                /* dst_mask */
+        false),                /* pcrel_offset */
+
+  /* These two are obsolete.  */
   EMPTY_HOWTO (R_MIPS_ADD_IMMEDIATE),
   EMPTY_HOWTO (R_MIPS_PJUMP),
-  EMPTY_HOWTO (R_MIPS_RELGOT),
+
+  /* Similiar to R_MIPS_REL32, but used for relocations in a GOT section.
+     It must be used for multigot GOT's (and only there).  */
+  HOWTO (R_MIPS_RELGOT,                /* type */
+        0,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        32,                    /* bitsize */
+        false,                 /* pc_relative */
+        0,                     /* bitpos */
+        complain_overflow_dont, /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_MIPS_RELGOT",       /* name */
+        false,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0xffffffff,            /* dst_mask */
+        false),                /* pcrel_offset */
 
   /* Protected jump conversion.  This is an optimization hint.  No
      relocation is required for correctness.  */
   HOWTO (R_MIPS_JALR,          /* type */
         0,                     /* rightshift */
-        0,                     /* size (0 = byte, 1 = short, 2 = long) */
-        0,                     /* bitsize */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        32,                    /* bitsize */
         false,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont, /* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
         "R_MIPS_JALR",         /* name */
         false,                 /* partial_inplace */
-        0x00000000,            /* src_mask */
-        0x00000000,            /* dst_mask */
+        0,                     /* src_mask */
+        0xffffffff,            /* dst_mask */
         false),                /* pcrel_offset */
 };
 
@@ -1177,12 +1727,14 @@ _bfd_mips_elf_hi16_reloc (abfd,
   relocation += symbol->section->output_section->vma;
   relocation += symbol->section->output_offset;
   relocation += reloc_entry->addend;
+  if (reloc_entry->howto->pc_relative)
+    relocation -= reloc_entry->address;
 
   if (reloc_entry->address > input_section->_cooked_size)
     return bfd_reloc_outofrange;
 
   /* Save the information, and let LO16 do the actual relocation.  */
-  n = (struct mips_hi16 *) bfd_malloc (sizeof *n);
+  n = (struct mips_hi16 *) bfd_malloc ((bfd_size_type) sizeof *n);
   if (n == NULL)
     return bfd_reloc_outofrange;
   n->addr = (bfd_byte *) data + reloc_entry->address;
@@ -1250,8 +1802,8 @@ _bfd_mips_elf_lo16_reloc (abfd,
          if ((val & 0x8000) != 0)
            val += 0x10000;
 
-         insn = (insn & ~0xffff) | ((val >> 16) & 0xffff);
-         bfd_put_32 (abfd, insn, l->addr);
+         insn = (insn &~ (bfd_vma) 0xffff) | ((val >> 16) & 0xffff);
+         bfd_put_32 (abfd, (bfd_vma) insn, l->addr);
 
          if (strcmp (bfd_asymbol_name (symbol), "_gp_disp") == 0)
            {
@@ -1374,7 +1926,7 @@ mips_elf_assign_gp (output_bfd, pgp)
     {
       for (i = 0; i < count; i++, sym++)
        {
-         register CONST char *name;
+         register const char *name;
 
          name = bfd_asymbol_name (*sym);
          if (*name == '_' && strcmp (name, "_gp") == 0)
@@ -1658,7 +2210,7 @@ gprel32_with_gp (abfd, symbol, reloc_entry, input_section, relocateable, data,
       || (symbol->flags & BSF_SECTION_SYM) != 0)
     val += relocation - gp;
 
-  bfd_put_32 (abfd, val, (bfd_byte *) data + reloc_entry->address);
+  bfd_put_32 (abfd, (bfd_vma) val, (bfd_byte *) data + reloc_entry->address);
 
   if (relocateable)
     reloc_entry->address += input_section->output_offset;
@@ -1695,7 +2247,7 @@ mips32_64bit_reloc (abfd, reloc_entry, symbol, data, input_section,
   reloc32 = *reloc_entry;
   if (bfd_big_endian (abfd))
     reloc32.address += 4;
-  reloc32.howto = &elf_mips_howto_table[R_MIPS_32];
+  reloc32.howto = &elf_mips_howto_table_rel[R_MIPS_32];
   r = bfd_perform_relocation (abfd, &reloc32, data, input_section,
                              output_bfd, error_message);
 
@@ -1708,7 +2260,7 @@ mips32_64bit_reloc (abfd, reloc_entry, symbol, data, input_section,
   addr = reloc_entry->address;
   if (bfd_little_endian (abfd))
     addr += 4;
-  bfd_put_32 (abfd, val, (bfd_byte *) data + addr);
+  bfd_put_32 (abfd, (bfd_vma) val, (bfd_byte *) data + addr);
 
   return r;
 }
@@ -1802,9 +2354,9 @@ mips16_gprel_reloc (abfd, reloc_entry, symbol, data, input_section,
   /* Stuff the current addend back as a 32 bit value, do the usual
      relocation, and then clean up.  */
   bfd_put_32 (abfd,
-             (((extend & 0x1f) << 11)
-              | (extend & 0x7e0)
-              | (insn & 0x1f)),
+             (bfd_vma) (((extend & 0x1f) << 11)
+                        | (extend & 0x7e0)
+                        | (insn & 0x1f)),
              (bfd_byte *) data + reloc_entry->address);
 
   ret = gprel16_with_gp (abfd, symbol, reloc_entry, input_section,
@@ -1812,13 +2364,13 @@ mips16_gprel_reloc (abfd, reloc_entry, symbol, data, input_section,
 
   final = bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address);
   bfd_put_16 (abfd,
-             ((extend & 0xf800)
-              | ((final >> 11) & 0x1f)
-              | (final & 0x7e0)),
+             (bfd_vma) ((extend & 0xf800)
+                        | ((final >> 11) & 0x1f)
+                        | (final & 0x7e0)),
              (bfd_byte *) data + reloc_entry->address);
   bfd_put_16 (abfd,
-             ((insn & 0xffe0)
-              | (final & 0x1f)),
+             (bfd_vma) ((insn & 0xffe0)
+                        | (final & 0x1f)),
              (bfd_byte *) data + reloc_entry->address + 2);
 
   return ret;
@@ -1852,7 +2404,7 @@ elf_mips_isa (flags)
 
 /* Return the MACH for a MIPS e_flags value.  */
 
-static INLINE int
+static INLINE unsigned long
 elf_mips_mach (flags)
      flagword flags;
 {
@@ -1873,9 +2425,6 @@ elf_mips_mach (flags)
     case E_MIPS_MACH_4650:
       return bfd_mach_mips4650;
 
-    case E_MIPS_MACH_MIPS32_4K:
-      return bfd_mach_mips32_4k;
-
     case E_MIPS_MACH_SB1:
       return bfd_mach_mips_sb1;
 
@@ -1904,11 +2453,11 @@ elf_mips_mach (flags)
          break;
 
        case E_MIPS_ARCH_32:
-         return bfd_mach_mips32;
+         return bfd_mach_mipsisa32;
          break;
 
        case E_MIPS_ARCH_64:
-         return bfd_mach_mips64;
+         return bfd_mach_mipsisa64;
          break;
        }
     }
@@ -1924,16 +2473,16 @@ elf_mips_abi_name (abfd)
 {
   flagword flags;
 
-  if (ABI_N32_P (abfd))
-    return "N32";
-  else if (ABI_64_P (abfd))
-    return "64";
-
   flags = elf_elfheader (abfd)->e_flags;
   switch (flags & EF_MIPS_ABI)
     {
     case 0:
-      return "none";
+      if (ABI_N32_P (abfd))
+       return "N32";
+      else if (ABI_64_P (abfd))
+       return "64";
+      else
+       return "none";
     case E_MIPS_ABI_O32:
       return "O32";
     case E_MIPS_ABI_O64:
@@ -1954,7 +2503,7 @@ struct elf_reloc_map {
   enum elf_mips_reloc_type elf_reloc_val;
 };
 
-static CONST struct elf_reloc_map mips_reloc_map[] =
+static const struct elf_reloc_map mips_reloc_map[] =
 {
   { BFD_RELOC_NONE, R_MIPS_NONE, },
   { BFD_RELOC_16, R_MIPS_16 },
@@ -1963,12 +2512,12 @@ static CONST struct elf_reloc_map mips_reloc_map[] =
   { BFD_RELOC_MIPS_JMP, R_MIPS_26 },
   { BFD_RELOC_HI16_S, R_MIPS_HI16 },
   { BFD_RELOC_LO16, R_MIPS_LO16 },
-  { BFD_RELOC_MIPS_GPREL, R_MIPS_GPREL16 },
+  { BFD_RELOC_GPREL16, R_MIPS_GPREL16 },
   { BFD_RELOC_MIPS_LITERAL, R_MIPS_LITERAL },
   { BFD_RELOC_MIPS_GOT16, R_MIPS_GOT16 },
   { BFD_RELOC_16_PCREL, R_MIPS_PC16 },
   { BFD_RELOC_MIPS_CALL16, R_MIPS_CALL16 },
-  { BFD_RELOC_MIPS_GPREL32, R_MIPS_GPREL32 },
+  { BFD_RELOC_GPREL32, R_MIPS_GPREL32 },
   { BFD_RELOC_MIPS_GOT_HI16, R_MIPS_GOT_HI16 },
   { BFD_RELOC_MIPS_GOT_LO16, R_MIPS_GOT_LO16 },
   { BFD_RELOC_MIPS_CALL_HI16, R_MIPS_CALL_HI16 },
@@ -1991,7 +2540,7 @@ bfd_elf32_bfd_reloc_type_lookup (abfd, code)
   for (i = 0; i < sizeof (mips_reloc_map) / sizeof (struct elf_reloc_map); i++)
     {
       if (mips_reloc_map[i].bfd_reloc_val == code)
-       return &elf_mips_howto_table[(int) mips_reloc_map[i].elf_reloc_val];
+       return &elf_mips_howto_table_rel[(int) mips_reloc_map[i].elf_reloc_val];
     }
 
   switch (code)
@@ -2005,7 +2554,7 @@ bfd_elf32_bfd_reloc_type_lookup (abfd, code)
         Select the right relocation (R_MIPS_32 or R_MIPS_64) based on the
         size of addresses on this architecture.  */
       if (bfd_arch_bits_per_address (abfd) == 32)
-       return &elf_mips_howto_table[(int) R_MIPS_32];
+       return &elf_mips_howto_table_rel[(int) R_MIPS_32];
       else
        return &elf_mips_ctor64_howto;
 
@@ -2068,7 +2617,7 @@ mips_rtype_to_howto (r_type)
 
     default:
       BFD_ASSERT (r_type < (unsigned int) R_MIPS_max);
-      return &elf_mips_howto_table[r_type];
+      return &elf_mips_howto_table_rel[r_type];
       break;
     }
 }
@@ -2123,12 +2672,12 @@ bfd_mips_elf32_swap_reginfo_in (abfd, ex, in)
      const Elf32_External_RegInfo *ex;
      Elf32_RegInfo *in;
 {
-  in->ri_gprmask = bfd_h_get_32 (abfd, (bfd_byte *) ex->ri_gprmask);
-  in->ri_cprmask[0] = bfd_h_get_32 (abfd, (bfd_byte *) ex->ri_cprmask[0]);
-  in->ri_cprmask[1] = bfd_h_get_32 (abfd, (bfd_byte *) ex->ri_cprmask[1]);
-  in->ri_cprmask[2] = bfd_h_get_32 (abfd, (bfd_byte *) ex->ri_cprmask[2]);
-  in->ri_cprmask[3] = bfd_h_get_32 (abfd, (bfd_byte *) ex->ri_cprmask[3]);
-  in->ri_gp_value = bfd_h_get_32 (abfd, (bfd_byte *) ex->ri_gp_value);
+  in->ri_gprmask = H_GET_32 (abfd, ex->ri_gprmask);
+  in->ri_cprmask[0] = H_GET_32 (abfd, ex->ri_cprmask[0]);
+  in->ri_cprmask[1] = H_GET_32 (abfd, ex->ri_cprmask[1]);
+  in->ri_cprmask[2] = H_GET_32 (abfd, ex->ri_cprmask[2]);
+  in->ri_cprmask[3] = H_GET_32 (abfd, ex->ri_cprmask[3]);
+  in->ri_gp_value = H_GET_32 (abfd, ex->ri_gp_value);
 }
 
 void
@@ -2137,18 +2686,12 @@ bfd_mips_elf32_swap_reginfo_out (abfd, in, ex)
      const Elf32_RegInfo *in;
      Elf32_External_RegInfo *ex;
 {
-  bfd_h_put_32 (abfd, (bfd_vma) in->ri_gprmask,
-               (bfd_byte *) ex->ri_gprmask);
-  bfd_h_put_32 (abfd, (bfd_vma) in->ri_cprmask[0],
-               (bfd_byte *) ex->ri_cprmask[0]);
-  bfd_h_put_32 (abfd, (bfd_vma) in->ri_cprmask[1],
-               (bfd_byte *) ex->ri_cprmask[1]);
-  bfd_h_put_32 (abfd, (bfd_vma) in->ri_cprmask[2],
-               (bfd_byte *) ex->ri_cprmask[2]);
-  bfd_h_put_32 (abfd, (bfd_vma) in->ri_cprmask[3],
-               (bfd_byte *) ex->ri_cprmask[3]);
-  bfd_h_put_32 (abfd, (bfd_vma) in->ri_gp_value,
-               (bfd_byte *) ex->ri_gp_value);
+  H_PUT_32 (abfd, in->ri_gprmask, ex->ri_gprmask);
+  H_PUT_32 (abfd, in->ri_cprmask[0], ex->ri_cprmask[0]);
+  H_PUT_32 (abfd, in->ri_cprmask[1], ex->ri_cprmask[1]);
+  H_PUT_32 (abfd, in->ri_cprmask[2], ex->ri_cprmask[2]);
+  H_PUT_32 (abfd, in->ri_cprmask[3], ex->ri_cprmask[3]);
+  H_PUT_32 (abfd, in->ri_gp_value, ex->ri_gp_value);
 }
 
 /* In the 64 bit ABI, the .MIPS.options section holds register
@@ -2163,13 +2706,13 @@ bfd_mips_elf64_swap_reginfo_in (abfd, ex, in)
      const Elf64_External_RegInfo *ex;
      Elf64_Internal_RegInfo *in;
 {
-  in->ri_gprmask = bfd_h_get_32 (abfd, (bfd_byte *) ex->ri_gprmask);
-  in->ri_pad = bfd_h_get_32 (abfd, (bfd_byte *) ex->ri_pad);
-  in->ri_cprmask[0] = bfd_h_get_32 (abfd, (bfd_byte *) ex->ri_cprmask[0]);
-  in->ri_cprmask[1] = bfd_h_get_32 (abfd, (bfd_byte *) ex->ri_cprmask[1]);
-  in->ri_cprmask[2] = bfd_h_get_32 (abfd, (bfd_byte *) ex->ri_cprmask[2]);
-  in->ri_cprmask[3] = bfd_h_get_32 (abfd, (bfd_byte *) ex->ri_cprmask[3]);
-  in->ri_gp_value = bfd_h_get_64 (abfd, (bfd_byte *) ex->ri_gp_value);
+  in->ri_gprmask = H_GET_32 (abfd, ex->ri_gprmask);
+  in->ri_pad = H_GET_32 (abfd, ex->ri_pad);
+  in->ri_cprmask[0] = H_GET_32 (abfd, ex->ri_cprmask[0]);
+  in->ri_cprmask[1] = H_GET_32 (abfd, ex->ri_cprmask[1]);
+  in->ri_cprmask[2] = H_GET_32 (abfd, ex->ri_cprmask[2]);
+  in->ri_cprmask[3] = H_GET_32 (abfd, ex->ri_cprmask[3]);
+  in->ri_gp_value = H_GET_64 (abfd, ex->ri_gp_value);
 }
 
 void
@@ -2178,20 +2721,13 @@ bfd_mips_elf64_swap_reginfo_out (abfd, in, ex)
      const Elf64_Internal_RegInfo *in;
      Elf64_External_RegInfo *ex;
 {
-  bfd_h_put_32 (abfd, (bfd_vma) in->ri_gprmask,
-               (bfd_byte *) ex->ri_gprmask);
-  bfd_h_put_32 (abfd, (bfd_vma) in->ri_pad,
-               (bfd_byte *) ex->ri_pad);
-  bfd_h_put_32 (abfd, (bfd_vma) in->ri_cprmask[0],
-               (bfd_byte *) ex->ri_cprmask[0]);
-  bfd_h_put_32 (abfd, (bfd_vma) in->ri_cprmask[1],
-               (bfd_byte *) ex->ri_cprmask[1]);
-  bfd_h_put_32 (abfd, (bfd_vma) in->ri_cprmask[2],
-               (bfd_byte *) ex->ri_cprmask[2]);
-  bfd_h_put_32 (abfd, (bfd_vma) in->ri_cprmask[3],
-               (bfd_byte *) ex->ri_cprmask[3]);
-  bfd_h_put_64 (abfd, (bfd_vma) in->ri_gp_value,
-               (bfd_byte *) ex->ri_gp_value);
+  H_PUT_32 (abfd, in->ri_gprmask, ex->ri_gprmask);
+  H_PUT_32 (abfd, in->ri_pad, ex->ri_pad);
+  H_PUT_32 (abfd, in->ri_cprmask[0], ex->ri_cprmask[0]);
+  H_PUT_32 (abfd, in->ri_cprmask[1], ex->ri_cprmask[1]);
+  H_PUT_32 (abfd, in->ri_cprmask[2], ex->ri_cprmask[2]);
+  H_PUT_32 (abfd, in->ri_cprmask[3], ex->ri_cprmask[3]);
+  H_PUT_64 (abfd, in->ri_gp_value, ex->ri_gp_value);
 }
 
 /* Swap an entry in a .gptab section.  Note that these routines rely
@@ -2203,8 +2739,8 @@ bfd_mips_elf32_swap_gptab_in (abfd, ex, in)
      const Elf32_External_gptab *ex;
      Elf32_gptab *in;
 {
-  in->gt_entry.gt_g_value = bfd_h_get_32 (abfd, ex->gt_entry.gt_g_value);
-  in->gt_entry.gt_bytes = bfd_h_get_32 (abfd, ex->gt_entry.gt_bytes);
+  in->gt_entry.gt_g_value = H_GET_32 (abfd, ex->gt_entry.gt_g_value);
+  in->gt_entry.gt_bytes = H_GET_32 (abfd, ex->gt_entry.gt_bytes);
 }
 
 static void
@@ -2213,10 +2749,8 @@ bfd_mips_elf32_swap_gptab_out (abfd, in, ex)
      const Elf32_gptab *in;
      Elf32_External_gptab *ex;
 {
-  bfd_h_put_32 (abfd, (bfd_vma) in->gt_entry.gt_g_value,
-               ex->gt_entry.gt_g_value);
-  bfd_h_put_32 (abfd, (bfd_vma) in->gt_entry.gt_bytes,
-               ex->gt_entry.gt_bytes);
+  H_PUT_32 (abfd, in->gt_entry.gt_g_value, ex->gt_entry.gt_g_value);
+  H_PUT_32 (abfd, in->gt_entry.gt_bytes, ex->gt_entry.gt_bytes);
 }
 
 static void
@@ -2225,12 +2759,12 @@ bfd_elf32_swap_compact_rel_out (abfd, in, ex)
      const Elf32_compact_rel *in;
      Elf32_External_compact_rel *ex;
 {
-  bfd_h_put_32 (abfd, (bfd_vma) in->id1, ex->id1);
-  bfd_h_put_32 (abfd, (bfd_vma) in->num, ex->num);
-  bfd_h_put_32 (abfd, (bfd_vma) in->id2, ex->id2);
-  bfd_h_put_32 (abfd, (bfd_vma) in->offset, ex->offset);
-  bfd_h_put_32 (abfd, (bfd_vma) in->reserved0, ex->reserved0);
-  bfd_h_put_32 (abfd, (bfd_vma) in->reserved1, ex->reserved1);
+  H_PUT_32 (abfd, in->id1, ex->id1);
+  H_PUT_32 (abfd, in->num, ex->num);
+  H_PUT_32 (abfd, in->id2, ex->id2);
+  H_PUT_32 (abfd, in->offset, ex->offset);
+  H_PUT_32 (abfd, in->reserved0, ex->reserved0);
+  H_PUT_32 (abfd, in->reserved1, ex->reserved1);
 }
 
 static void
@@ -2245,9 +2779,9 @@ bfd_elf32_swap_crinfo_out (abfd, in, ex)
        | ((in->rtype & CRINFO_RTYPE) << CRINFO_RTYPE_SH)
        | ((in->dist2to & CRINFO_DIST2TO) << CRINFO_DIST2TO_SH)
        | ((in->relvaddr & CRINFO_RELVADDR) << CRINFO_RELVADDR_SH));
-  bfd_h_put_32 (abfd, (bfd_vma) l, ex->info);
-  bfd_h_put_32 (abfd, (bfd_vma) in->konst, ex->konst);
-  bfd_h_put_32 (abfd, (bfd_vma) in->vaddr, ex->vaddr);
+  H_PUT_32 (abfd, l, ex->info);
+  H_PUT_32 (abfd, in->konst, ex->konst);
+  H_PUT_32 (abfd, in->vaddr, ex->vaddr);
 }
 
 /* Swap in an options header.  */
@@ -2258,10 +2792,10 @@ bfd_mips_elf_swap_options_in (abfd, ex, in)
      const Elf_External_Options *ex;
      Elf_Internal_Options *in;
 {
-  in->kind = bfd_h_get_8 (abfd, ex->kind);
-  in->size = bfd_h_get_8 (abfd, ex->size);
-  in->section = bfd_h_get_16 (abfd, ex->section);
-  in->info = bfd_h_get_32 (abfd, ex->info);
+  in->kind = H_GET_8 (abfd, ex->kind);
+  in->size = H_GET_8 (abfd, ex->size);
+  in->section = H_GET_16 (abfd, ex->section);
+  in->info = H_GET_32 (abfd, ex->info);
 }
 
 /* Swap out an options header.  */
@@ -2272,10 +2806,10 @@ bfd_mips_elf_swap_options_out (abfd, in, ex)
      const Elf_Internal_Options *in;
      Elf_External_Options *ex;
 {
-  bfd_h_put_8 (abfd, in->kind, ex->kind);
-  bfd_h_put_8 (abfd, in->size, ex->size);
-  bfd_h_put_16 (abfd, in->section, ex->section);
-  bfd_h_put_32 (abfd, in->info, ex->info);
+  H_PUT_8 (abfd, in->kind, ex->kind);
+  H_PUT_8 (abfd, in->size, ex->size);
+  H_PUT_16 (abfd, in->section, ex->section);
+  H_PUT_32 (abfd, in->info, ex->info);
 }
 #if 0
 /* Swap in an MSYM entry.  */
@@ -2286,8 +2820,8 @@ bfd_mips_elf_swap_msym_in (abfd, ex, in)
      const Elf32_External_Msym *ex;
      Elf32_Internal_Msym *in;
 {
-  in->ms_hash_value = bfd_h_get_32 (abfd, ex->ms_hash_value);
-  in->ms_info = bfd_h_get_32 (abfd, ex->ms_info);
+  in->ms_hash_value = H_GET_32 (abfd, ex->ms_hash_value);
+  in->ms_info = H_GET_32 (abfd, ex->ms_info);
 }
 #endif
 /* Swap out an MSYM entry.  */
@@ -2298,8 +2832,8 @@ bfd_mips_elf_swap_msym_out (abfd, in, ex)
      const Elf32_Internal_Msym *in;
      Elf32_External_Msym *ex;
 {
-  bfd_h_put_32 (abfd, in->ms_hash_value, ex->ms_hash_value);
-  bfd_h_put_32 (abfd, in->ms_info, ex->ms_info);
+  H_PUT_32 (abfd, in->ms_hash_value, ex->ms_hash_value);
+  H_PUT_32 (abfd, in->ms_info, ex->ms_info);
 }
 \f
 /* Determine whether a symbol is global for the purposes of splitting
@@ -2313,12 +2847,12 @@ mips_elf_sym_is_global (abfd, sym)
      bfd *abfd ATTRIBUTE_UNUSED;
      asymbol *sym;
 {
-  if (SGI_COMPAT(abfd))
-    return (sym->flags & BSF_SECTION_SYM) == 0 ? true : false;
+  if (SGI_COMPAT (abfd))
+    return (sym->flags & BSF_SECTION_SYM) == 0;
   else
     return ((sym->flags & (BSF_GLOBAL | BSF_WEAK)) != 0
-            || bfd_is_und_section (bfd_get_section (sym))
-            || bfd_is_com_section (bfd_get_section (sym)));
+           || bfd_is_und_section (bfd_get_section (sym))
+           || bfd_is_com_section (bfd_get_section (sym)));
 }
 \f
 /* Set the right machine number for a MIPS ELF file.  This is used for
@@ -2328,10 +2862,11 @@ boolean
 _bfd_mips_elf_object_p (abfd)
      bfd *abfd;
 {
-  /* Irix 5 and 6 is broken.  Object file symbol tables are not always
+  /* Irix 5 and 6 are broken.  Object file symbol tables are not always
      sorted correctly such that local symbols precede global symbols,
      and the sh_info field in the symbol table is not always right.  */
-  elf_bad_symtab (abfd) = true;
+  if (SGI_COMPAT(abfd))
+    elf_bad_symtab (abfd) = true;
 
   bfd_default_set_arch_mach (abfd, bfd_arch_mips,
                             elf_mips_mach (elf_elfheader (abfd)->e_flags));
@@ -2370,6 +2905,8 @@ _bfd_mips_elf_final_write_processing (abfd, linker)
 
     case bfd_mach_mips4000:
     case bfd_mach_mips4300:
+    case bfd_mach_mips4400:
+    case bfd_mach_mips4600:
       val = E_MIPS_ARCH_3;
       break;
 
@@ -2389,29 +2926,27 @@ _bfd_mips_elf_final_write_processing (abfd, linker)
       val = E_MIPS_ARCH_3 | E_MIPS_MACH_4650;
       break;
 
+    case bfd_mach_mips5000:
     case bfd_mach_mips8000:
+    case bfd_mach_mips10000:
+    case bfd_mach_mips12000:
       val = E_MIPS_ARCH_4;
       break;
 
-    case bfd_mach_mips32:
-      val = E_MIPS_ARCH_32;
-      break;
-
-    case bfd_mach_mips32_4k:
-      val = E_MIPS_ARCH_32 | E_MIPS_MACH_MIPS32_4K;
-      break;
-
     case bfd_mach_mips5:
       val = E_MIPS_ARCH_5;
       break;
 
-    case bfd_mach_mips64:
-      val = E_MIPS_ARCH_64;
-      break;
-
     case bfd_mach_mips_sb1:
       val = E_MIPS_ARCH_64 | E_MIPS_MACH_SB1;
       break;
+
+    case bfd_mach_mipsisa32:
+      val = E_MIPS_ARCH_32;
+      break;
+
+    case bfd_mach_mipsisa64:
+      val = E_MIPS_ARCH_64;
     }
 
   elf_elfheader (abfd)->e_flags &= ~(EF_MIPS_ARCH | EF_MIPS_MACH);
@@ -2420,7 +2955,7 @@ _bfd_mips_elf_final_write_processing (abfd, linker)
   /* Set the sh_info field for .gptab sections and other appropriate
      info for each special section.  */
   for (i = 1, hdrpp = elf_elfsections (abfd) + 1;
-       i < elf_elfheader (abfd)->e_shnum;
+       i < elf_numsections (abfd);
        i++, hdrpp++)
     {
       switch ((*hdrpp)->sh_type)
@@ -2603,7 +3138,7 @@ _bfd_mips_elf_merge_private_bfd_data (ibfd, obfd)
       old_flags &= ~EF_MIPS_PIC;
       (*_bfd_error_handler)
        (_("%s: linking PIC files with non-PIC files"),
-        bfd_get_filename (ibfd));
+        bfd_archive_filename (ibfd));
       ok = false;
     }
 
@@ -2613,7 +3148,7 @@ _bfd_mips_elf_merge_private_bfd_data (ibfd, obfd)
       old_flags &= ~EF_MIPS_CPIC;
       (*_bfd_error_handler)
        (_("%s: linking abicalls files with non-abicalls files"),
-        bfd_get_filename (ibfd));
+        bfd_archive_filename (ibfd));
       ok = false;
     }
 
@@ -2642,7 +3177,7 @@ _bfd_mips_elf_merge_private_bfd_data (ibfd, obfd)
            {
              (*_bfd_error_handler)
               (_("%s: ISA mismatch (-mips%d) with previous modules (-mips%d)"),
-               bfd_get_filename (ibfd), new_isa, old_isa);
+               bfd_archive_filename (ibfd), new_isa, old_isa);
              ok = false;
            }
        }
@@ -2651,7 +3186,7 @@ _bfd_mips_elf_merge_private_bfd_data (ibfd, obfd)
        {
          (*_bfd_error_handler)
            (_("%s: ISA mismatch (%d) with previous modules (%d)"),
-            bfd_get_filename (ibfd),
+            bfd_archive_filename (ibfd),
             elf_mips_mach (new_flags),
             elf_mips_mach (old_flags));
          ok = false;
@@ -2674,7 +3209,7 @@ _bfd_mips_elf_merge_private_bfd_data (ibfd, obfd)
        {
          (*_bfd_error_handler)
            (_("%s: ABI mismatch: linking %s module with previous %s modules"),
-            bfd_get_filename (ibfd),
+            bfd_archive_filename (ibfd),
             elf_mips_abi_name (ibfd),
             elf_mips_abi_name (obfd));
          ok = false;
@@ -2688,7 +3223,7 @@ _bfd_mips_elf_merge_private_bfd_data (ibfd, obfd)
     {
       (*_bfd_error_handler)
        (_("%s: uses different e_flags (0x%lx) fields than previous modules (0x%lx)"),
-        bfd_get_filename (ibfd), (unsigned long) new_flags,
+        bfd_archive_filename (ibfd), (unsigned long) new_flags,
         (unsigned long) old_flags);
       ok = false;
     }
@@ -2868,7 +3403,8 @@ _bfd_mips_elf_section_from_shdr (abfd, hdr, name)
       Elf32_RegInfo s;
 
       if (! bfd_get_section_contents (abfd, hdr->bfd_section, (PTR) &ext,
-                                     (file_ptr) 0, sizeof ext))
+                                     (file_ptr) 0,
+                                     (bfd_size_type) sizeof ext))
        return false;
       bfd_mips_elf32_swap_reginfo_in (abfd, &ext, &s);
       elf_gp (abfd) = s.ri_gp_value;
@@ -3049,11 +3585,11 @@ _bfd_mips_elf_fake_sections (abfd, hdr, sec)
   if ((sec->flags & SEC_RELOC) != 0)
     {
       struct bfd_elf_section_data *esd;
+      bfd_size_type amt = sizeof (Elf_Internal_Shdr);
 
       esd = elf_section_data (sec);
       BFD_ASSERT (esd->rel_hdr2 == NULL);
-      esd->rel_hdr2
-       = (Elf_Internal_Shdr *) bfd_zalloc (abfd, sizeof (Elf_Internal_Shdr));
+      esd->rel_hdr2 = (Elf_Internal_Shdr *) bfd_zalloc (abfd, amt);
       if (!esd->rel_hdr2)
        return false;
       _bfd_elf_init_reloc_shdr (abfd, esd->rel_hdr2, sec,
@@ -3107,8 +3643,8 @@ _bfd_mips_elf_set_section_contents (abfd, section, location, offset, count)
 
       if (elf_section_data (section) == NULL)
        {
-         section->used_by_bfd =
-           (PTR) bfd_zalloc (abfd, sizeof (struct bfd_elf_section_data));
+         bfd_size_type amt = sizeof (struct bfd_elf_section_data);
+         section->used_by_bfd = (PTR) bfd_zalloc (abfd, amt);
          if (elf_section_data (section) == NULL)
            return false;
        }
@@ -3127,7 +3663,7 @@ _bfd_mips_elf_set_section_contents (abfd, section, location, offset, count)
          elf_section_data (section)->tdata = (PTR) c;
        }
 
-      memcpy (c + offset, location, count);
+      memcpy (c + offset, location, (size_t) count);
     }
 
   return _bfd_elf_set_section_contents (abfd, section, location, offset,
@@ -3154,10 +3690,10 @@ _bfd_mips_elf_section_processing (abfd, hdr)
 
       if (bfd_seek (abfd,
                    hdr->sh_offset + sizeof (Elf32_External_RegInfo) - 4,
-                   SEEK_SET) == -1)
+                   SEEK_SET) != 0)
        return false;
-      bfd_h_put_32 (abfd, (bfd_vma) elf_gp (abfd), buf);
-      if (bfd_write (buf, (bfd_size_type) 1, (bfd_size_type) 4, abfd) != 4)
+      H_PUT_32 (abfd, elf_gp (abfd), buf);
+      if (bfd_bwrite (buf, (bfd_size_type) 4, abfd) != 4)
        return false;
     }
 
@@ -3193,10 +3729,10 @@ _bfd_mips_elf_section_processing (abfd, hdr)
                             + (l - contents)
                             + sizeof (Elf_External_Options)
                             + (sizeof (Elf64_External_RegInfo) - 8)),
-                            SEEK_SET) == -1)
+                            SEEK_SET) != 0)
                return false;
-             bfd_h_put_64 (abfd, elf_gp (abfd), buf);
-             if (bfd_write (buf, 1, 8, abfd) != 8)
+             H_PUT_64 (abfd, elf_gp (abfd), buf);
+             if (bfd_bwrite (buf, (bfd_size_type) 8, abfd) != 8)
                return false;
            }
          else if (intopt.kind == ODK_REGINFO)
@@ -3208,10 +3744,10 @@ _bfd_mips_elf_section_processing (abfd, hdr)
                             + (l - contents)
                             + sizeof (Elf_External_Options)
                             + (sizeof (Elf32_External_RegInfo) - 4)),
-                           SEEK_SET) == -1)
+                           SEEK_SET) != 0)
                return false;
-             bfd_h_put_32 (abfd, elf_gp (abfd), buf);
-             if (bfd_write (buf, 1, 4, abfd) != 4)
+             H_PUT_32 (abfd, elf_gp (abfd), buf);
+             if (bfd_bwrite (buf, (bfd_size_type) 4, abfd) != 4)
                return false;
            }
          l += intopt.size;
@@ -3390,6 +3926,7 @@ _bfd_mips_elf_modify_segment_map (abfd)
 {
   asection *s;
   struct elf_segment_map *m, **pm;
+  bfd_size_type amt;
 
   /* If there is a .reginfo section, we need a PT_MIPS_REGINFO
      segment.  */
@@ -3401,7 +3938,8 @@ _bfd_mips_elf_modify_segment_map (abfd)
          break;
       if (m == NULL)
        {
-         m = (struct elf_segment_map *) bfd_zalloc (abfd, sizeof *m);
+         amt = sizeof *m;
+         m = (struct elf_segment_map *) bfd_zalloc (abfd, amt);
          if (m == NULL)
            return false;
 
@@ -3427,8 +3965,6 @@ _bfd_mips_elf_modify_segment_map (abfd)
      table.  */
   if (IRIX_COMPAT (abfd) == ict_irix6)
     {
-      asection *s;
-
       for (s = abfd->sections; s; s = s->next)
        if (elf_section_data (s)->this_hdr.sh_type == SHT_MIPS_OPTIONS)
          break;
@@ -3447,8 +3983,8 @@ _bfd_mips_elf_modify_segment_map (abfd)
            if ((*pm)->p_type == PT_PHDR)
              break;
 
-         options_segment = bfd_zalloc (abfd,
-                                       sizeof (struct elf_segment_map));
+         amt = sizeof (struct elf_segment_map);
+         options_segment = bfd_zalloc (abfd, amt);
          options_segment->next = *pm;
          options_segment->p_type = PT_MIPS_OPTIONS;
          options_segment->p_flags = PF_R;
@@ -3473,7 +4009,8 @@ _bfd_mips_elf_modify_segment_map (abfd)
                  break;
              if (m == NULL)
                {
-                 m = (struct elf_segment_map *) bfd_zalloc (abfd, sizeof *m);
+                 amt = sizeof *m;
+                 m = (struct elf_segment_map *) bfd_zalloc (abfd, amt);
                  if (m == NULL)
                    return false;
 
@@ -3512,7 +4049,7 @@ _bfd_mips_elf_modify_segment_map (abfd)
        if ((*pm)->p_type == PT_DYNAMIC)
          break;
       m = *pm;
-      if (IRIX_COMPAT (abfd) == ict_none)
+      if (m != NULL && IRIX_COMPAT (abfd) == ict_none)
        {
          /* For a normal mips executable the permissions for the PT_DYNAMIC
             segment are read, write and execute. We do that here since
@@ -3563,8 +4100,8 @@ _bfd_mips_elf_modify_segment_map (abfd)
                        0 ? s->_cooked_size : s->_raw_size)) <= high))
              ++c;
 
-         n = ((struct elf_segment_map *)
-              bfd_zalloc (abfd, sizeof *n + (c - 1) * sizeof (asection *)));
+         amt = sizeof *n + (bfd_size_type) (c - 1) * sizeof (asection *);
+         n = (struct elf_segment_map *) bfd_zalloc (abfd, amt);
          if (n == NULL)
            return false;
          *n = *m;
@@ -3621,20 +4158,20 @@ ecoff_swap_rpdr_out (abfd, in, ex)
      const RPDR *in;
      struct rpdr_ext *ex;
 {
-  /* ecoff_put_off was defined in ecoffswap.h.  */
-  ecoff_put_off (abfd, in->adr, (bfd_byte *) ex->p_adr);
-  bfd_h_put_32 (abfd, in->regmask, (bfd_byte *) ex->p_regmask);
-  bfd_h_put_32 (abfd, in->regoffset, (bfd_byte *) ex->p_regoffset);
-  bfd_h_put_32 (abfd, in->fregmask, (bfd_byte *) ex->p_fregmask);
-  bfd_h_put_32 (abfd, in->fregoffset, (bfd_byte *) ex->p_fregoffset);
-  bfd_h_put_32 (abfd, in->frameoffset, (bfd_byte *) ex->p_frameoffset);
-
-  bfd_h_put_16 (abfd, in->framereg, (bfd_byte *) ex->p_framereg);
-  bfd_h_put_16 (abfd, in->pcreg, (bfd_byte *) ex->p_pcreg);
-
-  bfd_h_put_32 (abfd, in->irpss, (bfd_byte *) ex->p_irpss);
+  /* ECOFF_PUT_OFF was defined in ecoffswap.h.  */
+  ECOFF_PUT_OFF (abfd, in->adr, ex->p_adr);
+  H_PUT_32 (abfd, in->regmask, ex->p_regmask);
+  H_PUT_32 (abfd, in->regoffset, ex->p_regoffset);
+  H_PUT_32 (abfd, in->fregmask, ex->p_fregmask);
+  H_PUT_32 (abfd, in->fregoffset, ex->p_fregoffset);
+  H_PUT_32 (abfd, in->frameoffset, ex->p_frameoffset);
+
+  H_PUT_16 (abfd, in->framereg, ex->p_framereg);
+  H_PUT_16 (abfd, in->pcreg, ex->p_pcreg);
+
+  H_PUT_32 (abfd, in->irpss, ex->p_irpss);
 #if 0 /* FIXME */
-  ecoff_put_off (abfd, in->exception_info, (bfd_byte *) ex->p_exception_info);
+  ECOFF_PUT_OFF (abfd, in->exception_info, ex->p_exception_info);
 #endif
 }
 \f
@@ -3654,7 +4191,7 @@ _bfd_mips_elf_read_ecoff_info (abfd, section, debug)
   swap = get_elf_backend_data (abfd)->elf_backend_ecoff_debug_swap;
   memset (debug, 0, sizeof (*debug));
 
-  ext_hdr = (char *) bfd_malloc ((size_t) swap->external_hdr_size);
+  ext_hdr = (char *) bfd_malloc (swap->external_hdr_size);
   if (ext_hdr == NULL && swap->external_hdr_size != 0)
     goto error_return;
 
@@ -3673,12 +4210,12 @@ _bfd_mips_elf_read_ecoff_info (abfd, section, debug)
     debug->ptr = NULL;                                                 \
   else                                                                 \
     {                                                                  \
-      debug->ptr = (type) bfd_malloc ((size_t) (size * symhdr->count));        \
+      bfd_size_type amt = (bfd_size_type) size * symhdr->count;                \
+      debug->ptr = (type) bfd_malloc (amt);                            \
       if (debug->ptr == NULL)                                          \
        goto error_return;                                              \
       if (bfd_seek (abfd, (file_ptr) symhdr->offset, SEEK_SET) != 0    \
-         || (bfd_read (debug->ptr, size, symhdr->count,                \
-                       abfd) != size * symhdr->count))                 \
+         || bfd_bread (debug->ptr, amt, abfd) != amt)                  \
        goto error_return;                                              \
     }
 
@@ -3774,7 +4311,7 @@ _bfd_mips_elf_find_nearest_line (abfd, section, symbols, offset, filename_ptr,
   if (_bfd_dwarf2_find_nearest_line (abfd, section, symbols, offset,
                                     filename_ptr, functionname_ptr,
                                     line_ptr,
-                                    ABI_64_P (abfd) ? 8 : 0,
+                                    (unsigned) (ABI_64_P (abfd) ? 8 : 0),
                                     &elf_tdata (abfd)->dwarf2_find_line_info))
     return true;
 
@@ -3800,9 +4337,9 @@ _bfd_mips_elf_find_nearest_line (abfd, section, symbols, offset, filename_ptr,
          char *fraw_src;
          char *fraw_end;
          struct fdr *fdr_ptr;
+         bfd_size_type amt = sizeof (struct mips_elf_find_line);
 
-         fi = ((struct mips_elf_find_line *)
-               bfd_zalloc (abfd, sizeof (struct mips_elf_find_line)));
+         fi = (struct mips_elf_find_line *) bfd_zalloc (abfd, amt);
          if (fi == NULL)
            {
              msec->flags = origflags;
@@ -3816,10 +4353,8 @@ _bfd_mips_elf_find_nearest_line (abfd, section, symbols, offset, filename_ptr,
            }
 
          /* Swap in the FDR information.  */
-         fi->d.fdr = ((struct fdr *)
-                      bfd_alloc (abfd,
-                                 (fi->d.symbolic_header.ifdMax *
-                                  sizeof (struct fdr))));
+         amt = fi->d.symbolic_header.ifdMax * sizeof (struct fdr);
+         fi->d.fdr = (struct fdr *) bfd_alloc (abfd, amt);
          if (fi->d.fdr == NULL)
            {
              msec->flags = origflags;
@@ -3977,6 +4512,7 @@ mips_elf_link_hash_newfunc (entry, table, string)
         not been set.  -1 means there is no associated ifd.  */
       ret->esym.ifd = -2;
       ret->possibly_dynamic_relocs = 0;
+      ret->readonly_reloc = false;
       ret->min_dyn_reloc_index = 0;
       ret->no_fn_stub = false;
       ret->fn_stub = NULL;
@@ -3988,14 +4524,16 @@ mips_elf_link_hash_newfunc (entry, table, string)
   return (struct bfd_hash_entry *) ret;
 }
 
-void
-_bfd_mips_elf_hide_symbol (info, h)
+static void
+_bfd_mips_elf_hide_symbol (info, entry)
      struct bfd_link_info *info;
-     struct mips_elf_link_hash_entry *h;
+     struct elf_link_hash_entry *entry;
 {
   bfd *dynobj;
   asection *got;
   struct mips_got_info *g;
+  struct mips_elf_link_hash_entry *h;
+  h = (struct mips_elf_link_hash_entry *) entry;
   dynobj = elf_hash_table (info)->dynobj;
   got = bfd_get_section_by_name (dynobj, ".got");
   g = (struct mips_got_info *) elf_section_data (got)->tdata;
@@ -4017,9 +4555,9 @@ _bfd_mips_elf_link_hash_table_create (abfd)
      bfd *abfd;
 {
   struct mips_elf_link_hash_table *ret;
+  bfd_size_type amt = sizeof (struct mips_elf_link_hash_table);
 
-  ret = ((struct mips_elf_link_hash_table *)
-        bfd_alloc (abfd, sizeof (struct mips_elf_link_hash_table)));
+  ret = (struct mips_elf_link_hash_table *) bfd_alloc (abfd, amt);
   if (ret == (struct mips_elf_link_hash_table *) NULL)
     return NULL;
 
@@ -4087,12 +4625,14 @@ _bfd_mips_elf_add_symbol_hook (abfd, info, sym, namep, flagsp, secp, valp)
        {
          asymbol *elf_text_symbol;
          asection *elf_text_section;
+         bfd_size_type amt = sizeof (asection);
 
-         elf_text_section = bfd_zalloc (abfd, sizeof (asection));
+         elf_text_section = bfd_zalloc (abfd, amt);
          if (elf_text_section == NULL)
            return false;
 
-         elf_text_symbol = bfd_zalloc (abfd, sizeof (asymbol));
+         amt = sizeof (asymbol);
+         elf_text_symbol = bfd_zalloc (abfd, amt);
          if (elf_text_symbol == NULL)
            return false;
 
@@ -4126,12 +4666,14 @@ _bfd_mips_elf_add_symbol_hook (abfd, info, sym, namep, flagsp, secp, valp)
        {
          asymbol *elf_data_symbol;
          asection *elf_data_section;
+         bfd_size_type amt = sizeof (asection);
 
-         elf_data_section = bfd_zalloc (abfd, sizeof (asection));
+         elf_data_section = bfd_zalloc (abfd, amt);
          if (elf_data_section == NULL)
            return false;
 
-         elf_data_symbol = bfd_zalloc (abfd, sizeof (asymbol));
+         amt = sizeof (asymbol);
+         elf_data_symbol = bfd_zalloc (abfd, amt);
          if (elf_data_symbol == NULL)
            return false;
 
@@ -4417,7 +4959,8 @@ mips_elf_create_procedure_table (handle, abfd, info, s, debug)
   struct sym_ext *esym;
   char *ss, **sv;
   char *str;
-  unsigned long size, count;
+  bfd_size_type size;
+  bfd_size_type count;
   unsigned long sindex;
   unsigned long i;
   PDR pdr;
@@ -4450,7 +4993,8 @@ mips_elf_create_procedure_table (handle, abfd, info, s, debug)
       if (rpdr == NULL)
        goto error_return;
 
-      sv = (char **) bfd_malloc (sizeof (char *) * count);
+      size = sizeof (char *);
+      sv = (char **) bfd_malloc (size * count);
       if (sv == NULL)
        goto error_return;
 
@@ -4471,7 +5015,7 @@ mips_elf_create_procedure_table (handle, abfd, info, s, debug)
        goto error_return;
 
       count = hdr->ipdMax;
-      for (i = 0; i < count; i++, rp++)
+      for (i = 0; i < (unsigned long) count; i++, rp++)
        {
          (*swap->swap_pdr_in) (abfd, (PTR) (epdr + i), &pdr);
          (*swap->swap_sym_in) (abfd, (PTR) &esym[pdr.isym], &sym);
@@ -4512,7 +5056,7 @@ mips_elf_create_procedure_table (handle, abfd, info, s, debug)
       strcpy (str, sv[i]);
       str += strlen (sv[i]) + 1;
     }
-  ecoff_put_off (abfd, (bfd_vma) -1, (bfd_byte *) (erp + count)->p_adr);
+  ECOFF_PUT_OFF (abfd, -1, (erp + count)->p_adr);
 
   /* Set the size and contents of .rtproc section.  */
   s->_raw_size = size;
@@ -4584,9 +5128,10 @@ _bfd_mips_elf_final_link (abfd, info)
   PTR mdebug_handle = NULL;
   asection *s;
   EXTR esym;
-  bfd_vma last;
   unsigned int i;
-  static const char * const name[] =
+  bfd_size_type amt;
+
+  static const char * const secname[] =
   {
     ".text", ".init", ".fini", ".data",
     ".rodata", ".sdata", ".sbss", ".bss"
@@ -4735,7 +5280,7 @@ _bfd_mips_elf_final_link (abfd, info)
              if (! bfd_get_section_contents (input_bfd, input_section,
                                              (PTR) &ext,
                                              (file_ptr) 0,
-                                             sizeof ext))
+                                             (bfd_size_type) sizeof ext))
                return false;
 
              bfd_mips_elf32_swap_reginfo_in (input_bfd, &ext, &sub);
@@ -4768,6 +5313,7 @@ _bfd_mips_elf_final_link (abfd, info)
       if (strcmp (o->name, ".mdebug") == 0)
        {
          struct extsym_info einfo;
+         bfd_vma last;
 
          /* We have found the .mdebug section in the output file.
             Look through all the link_orders comprising it and merge
@@ -4816,10 +5362,10 @@ _bfd_mips_elf_final_link (abfd, info)
          esym.asym.reserved = 0;
          esym.asym.index = indexNil;
          last = 0;
-         for (i = 0; i < 8; i++)
+         for (i = 0; i < sizeof (secname) / sizeof (secname[0]); i++)
            {
              esym.asym.sc = sc[i];
-             s = bfd_get_section_by_name (abfd, name[i]);
+             s = bfd_get_section_by_name (abfd, secname[i]);
              if (s != NULL)
                {
                  esym.asym.value = s->vma;
@@ -4828,7 +5374,7 @@ _bfd_mips_elf_final_link (abfd, info)
              else
                esym.asym.value = last;
              if (!bfd_ecoff_debug_one_external (abfd, &debug, swap,
-                                                name[i], &esym))
+                                                secname[i], &esym))
                return false;
            }
 
@@ -4985,7 +5531,7 @@ _bfd_mips_elf_final_link (abfd, info)
          unsigned int c;
          Elf32_gptab *tab;
          Elf32_External_gptab *ext_tab;
-         unsigned int i;
+         unsigned int j;
 
          /* The .gptab.sdata and .gptab.sbss sections hold
             information describing how the small data area would
@@ -4993,8 +5539,6 @@ _bfd_mips_elf_final_link (abfd, info)
             not used in executables files.  */
          if (! info->relocateable)
            {
-             asection **secpp;
-
              for (p = o->link_order_head;
                   p != (struct bfd_link_order *) NULL;
                   p = p->next)
@@ -5063,7 +5607,8 @@ _bfd_mips_elf_final_link (abfd, info)
 
          /* Set up the first entry.  */
          c = 1;
-         tab = (Elf32_gptab *) bfd_malloc (c * sizeof (Elf32_gptab));
+         amt = c * sizeof (Elf32_gptab);
+         tab = (Elf32_gptab *) bfd_malloc (amt);
          if (tab == NULL)
            return false;
          tab[0].gt_header.gt_current_g_value = elf_gp_size (abfd);
@@ -5108,7 +5653,8 @@ _bfd_mips_elf_final_link (abfd, info)
 
                  if (! (bfd_get_section_contents
                         (input_bfd, input_section, (PTR) &ext_gptab,
-                         gpentry, sizeof (Elf32_External_gptab))))
+                         (file_ptr) gpentry,
+                         (bfd_size_type) sizeof (Elf32_External_gptab))))
                    {
                      free (tab);
                      return false;
@@ -5135,9 +5681,8 @@ _bfd_mips_elf_final_link (abfd, info)
                      unsigned int max;
 
                      /* We need a new table entry.  */
-                     new_tab = ((Elf32_gptab *)
-                                bfd_realloc ((PTR) tab,
-                                             (c + 1) * sizeof (Elf32_gptab)));
+                     amt = (bfd_size_type) (c + 1) * sizeof (Elf32_gptab);
+                     new_tab = (Elf32_gptab *) bfd_realloc ((PTR) tab, amt);
                      if (new_tab == NULL)
                        {
                          free (tab);
@@ -5179,16 +5724,16 @@ _bfd_mips_elf_final_link (abfd, info)
            qsort (tab + 1, c - 1, sizeof (tab[0]), gptab_compare);
 
          /* Swap out the table.  */
-         ext_tab = ((Elf32_External_gptab *)
-                    bfd_alloc (abfd, c * sizeof (Elf32_External_gptab)));
+         amt = (bfd_size_type) c * sizeof (Elf32_External_gptab);
+         ext_tab = (Elf32_External_gptab *) bfd_alloc (abfd, amt);
          if (ext_tab == NULL)
            {
              free (tab);
              return false;
            }
 
-         for (i = 0; i < c; i++)
-           bfd_mips_elf32_swap_gptab_out (abfd, tab + i, ext_tab + i);
+         for (j = 0; j < c; j++)
+           bfd_mips_elf32_swap_gptab_out (abfd, tab + j, ext_tab + j);
          free (tab);
 
          o->_raw_size = c * sizeof (Elf32_External_gptab);
@@ -5222,7 +5767,7 @@ _bfd_mips_elf_final_link (abfd, info)
 
       bfd_mips_elf32_swap_reginfo_out (abfd, &reginfo, &ext);
       if (! bfd_set_section_contents (abfd, reginfo_sec, (PTR) &ext,
-                                     (file_ptr) 0, sizeof ext))
+                                     (file_ptr) 0, (bfd_size_type) sizeof ext))
        return false;
     }
 
@@ -5496,14 +6041,15 @@ mips_elf_record_global_got_symbol (h, info, g)
       && !bfd_elf32_link_record_dynamic_symbol (info, h))
     return false;
 
-  /* If we've already marked this entry as need GOT space, we don't
+  /* If we've already marked this entry as needing GOT space, we don't
      need to do it again.  */
-  if (h->got.offset != (bfd_vma) - 1)
+  if (h->got.offset != (bfd_vma) -1)
     return true;
 
   /* By setting this to a value other than -1, we are indicating that
-     there needs to be a GOT entry for H.  */
-  h->got.offset = 0;
+     there needs to be a GOT entry for H.  Avoid using zero, as the
+     generic ELF copy_indirect_symbol tests for <= 0.  */
+  h->got.offset = 1;
 
   return true;
 }
@@ -5541,7 +6087,7 @@ mips_elf_sort_hash_table_f (h, data)
   if (h->root.dynindx == -1)
     return true;
 
-  if (h->root.got.offset != 0)
+  if (h->root.got.offset != 1)
     h->root.dynindx = hsd->max_non_got_dynindx++;
   else
     {
@@ -5578,7 +6124,7 @@ mips_elf_sort_hash_table (info, max_local)
                               mips_elf_sort_hash_table_f,
                               &hsd);
 
-  /* There shoud have been enough room in the symbol table to
+  /* There should have been enough room in the symbol table to
      accomodate both the GOT and non-GOT symbols.  */
   BFD_ASSERT (hsd.max_non_got_dynindx <= hsd.min_got_dynindx);
 
@@ -5808,31 +6354,14 @@ mips_elf_create_dynamic_relocation (output_bfd, info, rel, h, sec,
                               MIPS_ELF_REL_DYN_SECTION_NAME (output_bfd));
   BFD_ASSERT (sreloc != NULL);
   BFD_ASSERT (sreloc->contents != NULL);
+  BFD_ASSERT (sreloc->reloc_count * MIPS_ELF_REL_SIZE (output_bfd)
+             < sreloc->_raw_size);
 
   skip = false;
-
-  /* We begin by assuming that the offset for the dynamic relocation
-     is the same as for the original relocation.  We'll adjust this
-     later to reflect the correct output offsets.  */
-  if (elf_section_data (input_section)->stab_info == NULL)
-    outrel.r_offset = rel->r_offset;
-  else
-    {
-      /* Except that in a stab section things are more complex.
-        Because we compress stab information, the offset given in the
-        relocation may not be the one we want; we must let the stabs
-        machinery tell us the offset.  */
-      outrel.r_offset
-       = (_bfd_stab_section_offset
-          (output_bfd, &elf_hash_table (info)->stab_info,
-           input_section,
-           &elf_section_data (input_section)->stab_info,
-           rel->r_offset));
-      /* If we didn't need the relocation at all, this value will be
-        -1.  */
-      if (outrel.r_offset == (bfd_vma) -1)
-       skip = true;
-    }
+  outrel.r_offset =
+    _bfd_elf_section_offset (output_bfd, info, input_section, rel->r_offset);
+  if (outrel.r_offset == (bfd_vma) -1)
+    skip = true;
 
   /* If we've decided to skip this relocation, just output an empty
      record.  Note that R_MIPS_NONE == 0, so that this call to memset
@@ -6134,7 +6663,9 @@ mips_elf_calculate_relocation (abfd,
           and check to see if they exist by looking at their
           addresses.  */
        symbol = 0;
-      else if (info->shared && !info->symbolic && !info->no_undefined
+      else if (info->shared
+              && (!info->symbolic || info->allow_shlib_undefined)
+              && !info->no_undefined
               && ELF_ST_VISIBILITY (h->root.other) == STV_DEFAULT)
        symbol = 0;
       else if (strcmp (h->root.root.root.string, "_DYNAMIC_LINK") == 0 ||
@@ -6308,8 +6839,11 @@ mips_elf_calculate_relocation (abfd,
       if ((info->shared
           || (elf_hash_table (info)->dynamic_sections_created
               && h != NULL
-              && ((h->root.elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC)
-                  != 0)))
+              && ((h->root.elf_link_hash_flags
+                   & ELF_LINK_HASH_DEF_DYNAMIC) != 0)
+              && ((h->root.elf_link_hash_flags
+                   & ELF_LINK_HASH_DEF_REGULAR) == 0)))
+         && r_symndx != 0
          && (input_section->flags & SEC_ALLOC) != 0)
        {
          /* If we're creating a shared library, or this relocation is
@@ -6464,8 +6998,8 @@ mips_elf_calculate_relocation (abfd,
 
     case R_MIPS_PC16:
       value = mips_elf_sign_extend (addend, 16) + symbol - p;
-      value = (bfd_vma) ((bfd_signed_vma) value / 4);
       overflowed_p = mips_elf_overflow_p (value, 16);
+      value = (bfd_vma) ((bfd_signed_vma) value / 4);
       break;
 
     case R_MIPS_GOT_HI16:
@@ -6552,7 +7086,7 @@ mips_elf_obtain_contents (howto, relocation, input_bfd, contents)
   bfd_byte *location = contents + relocation->r_offset;
 
   /* Obtain the bytes.  */
-  x = bfd_get (8 * bfd_get_reloc_size (howto), input_bfd, location);
+  x = bfd_get (((bfd_vma)(8 * bfd_get_reloc_size (howto))), input_bfd, location);
 
   if ((ELF32_R_TYPE (relocation->r_info) == R_MIPS16_26
        || ELF32_R_TYPE (relocation->r_info) == R_MIPS16_GPREL)
@@ -6721,7 +7255,7 @@ mips_elf_perform_relocation (info, howto, relocation, value,
        {
          (*_bfd_error_handler)
            (_("%s: %s+0x%lx: jump to stub routine which is not jal"),
-            bfd_get_filename (input_bfd),
+            bfd_archive_filename (input_bfd),
             input_section->name,
             (unsigned long) relocation->r_offset);
          bfd_set_error (bfd_error_bad_value);
@@ -6788,7 +7322,7 @@ _bfd_mips_elf_relocate_section (output_bfd, info, input_bfd, input_section,
       /* True if the relocation is a RELA relocation, rather than a
          REL relocation.  */
       boolean rela_relocation_p = true;
-      int r_type = ELF32_R_TYPE (rel->r_info);
+      unsigned int r_type = ELF32_R_TYPE (rel->r_info);
       const char * msg = (const char *) NULL;
 
       /* Find the relocation howto for this relocation.  */
@@ -6800,7 +7334,7 @@ _bfd_mips_elf_relocate_section (output_bfd, info, input_bfd, input_section,
             space.  Thus, when they use an R_MIPS_64 they mean what is
             usually meant by R_MIPS_32, with the exception that the
             stored value is sign-extended to 64 bits.  */
-         howto = elf_mips_howto_table + R_MIPS_32;
+         howto = elf_mips_howto_table_rel + R_MIPS_32;
 
          /* On big-endian systems, we need to lie about the position
             of the reloc.  */
@@ -6848,7 +7382,7 @@ _bfd_mips_elf_relocate_section (output_bfd, info, input_bfd, input_section,
                  bfd_vma l;
                  const Elf_Internal_Rela *lo16_relocation;
                  reloc_howto_type *lo16_howto;
-                 int lo;
+                 unsigned int lo;
 
                  /* The combined value is the sum of the HI16 addend,
                     left-shifted by sixteen bits, and the LO16
@@ -6971,7 +7505,11 @@ _bfd_mips_elf_relocate_section (output_bfd, info, input_bfd, input_section,
                  bfd_vma high_bits;
 
                  if (addend & ((bfd_vma) 1 << 31))
+#ifdef BFD64
                    sign_bits = ((bfd_vma) 1 << 32) - 1;
+#else
+                   sign_bits = -1;
+#endif
                  else
                    sign_bits = 0;
 
@@ -6997,7 +7535,7 @@ _bfd_mips_elf_relocate_section (output_bfd, info, input_bfd, input_section,
                }
 
              if (!mips_elf_perform_relocation (info, howto, rel, addend,
-                                               input_bfd,  input_section,
+                                               input_bfd, input_section,
                                                contents, false))
                return false;
            }
@@ -7093,7 +7631,11 @@ _bfd_mips_elf_relocate_section (output_bfd, info, input_bfd, input_section,
          bfd_vma high_bits;
 
          if (value & ((bfd_vma) 1 << 31))
+#ifdef BFD64
            sign_bits = ((bfd_vma) 1 << 32) - 1;
+#else
+           sign_bits = -1;
+#endif
          else
            sign_bits = 0;
 
@@ -7218,7 +7760,7 @@ _bfd_mips_elf_create_dynamic_sections (abfd, info)
     {
       s = bfd_make_section (abfd, ".rld_map");
       if (s == NULL
-         || ! bfd_set_section_flags (abfd, s, flags & ~SEC_READONLY)
+         || ! bfd_set_section_flags (abfd, s, flags &~ (flagword) SEC_READONLY)
          || ! bfd_set_section_alignment (abfd, s,
                                          MIPS_ELF_LOG_FILE_ALIGN (abfd)))
        return false;
@@ -7381,6 +7923,7 @@ mips_elf_create_got_section (abfd, info)
   register asection *s;
   struct elf_link_hash_entry *h;
   struct mips_got_info *g;
+  bfd_size_type amt;
 
   /* This function may be called more than once.  */
   if (mips_elf_got_section (abfd))
@@ -7416,8 +7959,8 @@ mips_elf_create_got_section (abfd, info)
   /* The first several global offset table entries are reserved.  */
   s->_raw_size = MIPS_RESERVED_GOTNO * MIPS_ELF_GOT_SIZE (abfd);
 
-  g = (struct mips_got_info *) bfd_alloc (abfd,
-                                         sizeof (struct mips_got_info));
+  amt = sizeof (struct mips_got_info);
+  g = (struct mips_got_info *) bfd_alloc (abfd, amt);
   if (g == NULL)
     return false;
   g->global_gotsym = NULL;
@@ -7425,8 +7968,8 @@ mips_elf_create_got_section (abfd, info)
   g->assigned_gotno = MIPS_RESERVED_GOTNO;
   if (elf_section_data (s) == NULL)
     {
-      s->used_by_bfd =
-       (PTR) bfd_zalloc (abfd, sizeof (struct bfd_elf_section_data));
+      amt = sizeof (struct bfd_elf_section_data);
+      s->used_by_bfd = (PTR) bfd_zalloc (abfd, amt);
       if (elf_section_data (s) == NULL)
        return false;
     }
@@ -7589,13 +8132,14 @@ _bfd_mips_elf_check_relocs (abfd, info, sec, relocs)
            {
              unsigned long symcount;
              asection **n;
+             bfd_size_type amt;
 
              if (elf_bad_symtab (abfd))
                symcount = NUM_SHDR_ENTRIES (symtab_hdr);
              else
                symcount = symtab_hdr->sh_info;
-             n = (asection **) bfd_zalloc (abfd,
-                                           symcount * sizeof (asection *));
+             amt = symcount * sizeof (asection *);
+             n = (asection **) bfd_zalloc (abfd, amt);
              if (n == NULL)
                return false;
              elf_tdata (abfd)->local_stubs = n;
@@ -7698,7 +8242,7 @@ _bfd_mips_elf_check_relocs (abfd, info, sec, relocs)
   for (rel = relocs; rel < rel_end; ++rel)
     {
       unsigned long r_symndx;
-      int r_type;
+      unsigned int r_type;
       struct elf_link_hash_entry *h;
 
       r_symndx = ELF32_R_SYM (rel->r_info);
@@ -7709,7 +8253,8 @@ _bfd_mips_elf_check_relocs (abfd, info, sec, relocs)
       else if (r_symndx >= extsymoff + NUM_SHDR_ENTRIES (symtab_hdr))
        {
          (*_bfd_error_handler)
-           (_("Malformed reloc detected for section %s"), name);
+           (_("%s: Malformed reloc detected for section %s"),
+            bfd_archive_filename (abfd), name);
          bfd_set_error (bfd_error_bad_value);
          return false;
        }
@@ -7787,7 +8332,7 @@ _bfd_mips_elf_check_relocs (abfd, info, sec, relocs)
            {
              (*_bfd_error_handler)
                (_("%s: CALL16 reloc at 0x%lx not against global symbol"),
-                bfd_get_filename (abfd), (unsigned long) rel->r_offset);
+                bfd_archive_filename (abfd), (unsigned long) rel->r_offset);
              bfd_set_error (bfd_error_bad_value);
              return false;
            }
@@ -7826,12 +8371,12 @@ _bfd_mips_elf_check_relocs (abfd, info, sec, relocs)
            {
              if (sreloc == NULL)
                {
-                 const char *name = MIPS_ELF_REL_DYN_SECTION_NAME (dynobj);
+                 const char *dname = MIPS_ELF_REL_DYN_SECTION_NAME (dynobj);
 
-                 sreloc = bfd_get_section_by_name (dynobj, name);
+                 sreloc = bfd_get_section_by_name (dynobj, dname);
                  if (sreloc == NULL)
                    {
-                     sreloc = bfd_make_section (dynobj, name);
+                     sreloc = bfd_make_section (dynobj, dname);
                      if (sreloc == NULL
                          || ! bfd_set_section_flags (dynobj, sreloc,
                                                      (SEC_ALLOC
@@ -7845,12 +8390,20 @@ _bfd_mips_elf_check_relocs (abfd, info, sec, relocs)
                        return false;
                    }
                }
+#define MIPS_READONLY_SECTION (SEC_ALLOC | SEC_LOAD | SEC_READONLY)
              if (info->shared)
-               /* When creating a shared object, we must copy these
-                  reloc types into the output file as R_MIPS_REL32
-                  relocs.  We make room for this reloc in the
-                  .rel.dyn reloc section.  */
-               mips_elf_allocate_dynamic_relocations (dynobj, 1);
+               {
+                 /* When creating a shared object, we must copy these
+                    reloc types into the output file as R_MIPS_REL32
+                    relocs.  We make room for this reloc in the
+                    .rel.dyn reloc section.  */
+                 mips_elf_allocate_dynamic_relocations (dynobj, 1);
+                 if ((sec->flags & MIPS_READONLY_SECTION)
+                     == MIPS_READONLY_SECTION)
+                   /* We tell the dynamic linker that there are
+                      relocations against the text segment.  */
+                   info->flags |= DF_TEXTREL;
+               }
              else
                {
                  struct mips_elf_link_hash_entry *hmips;
@@ -7859,6 +8412,11 @@ _bfd_mips_elf_check_relocs (abfd, info, sec, relocs)
                      defined in a dynamic object.  */
                  hmips = (struct mips_elf_link_hash_entry *) h;
                  ++hmips->possibly_dynamic_relocs;
+                 if ((sec->flags & MIPS_READONLY_SECTION)
+                     == MIPS_READONLY_SECTION)
+                   /* We need it to tell the dynamic linker if there
+                      are relocations against the text segment.  */
+                   hmips->readonly_reloc = true;
                }
 
              /* Even though we don't directly need a GOT entry for
@@ -7981,13 +8539,7 @@ _bfd_mips_elf_gc_mark_hook (abfd, info, rel, h, sym)
     }
   else
     {
-      if (!(elf_bad_symtab (abfd)
-           && ELF_ST_BIND (sym->st_info) != STB_LOCAL)
-         && ! ((sym->st_shndx <= 0 || sym->st_shndx >= SHN_LORESERVE)
-               && sym->st_shndx != SHN_COMMON))
-       {
-         return bfd_section_from_elf_index (abfd, sym->st_shndx);
-       }
+      return bfd_section_from_elf_index (abfd, sym->st_shndx);
     }
 
   return NULL;
@@ -8039,9 +8591,10 @@ _bfd_mips_elf_gc_sweep_hook (abfd, info, sec, relocs)
 
 /* Copy data from a MIPS ELF indirect symbol to its direct symbol,
    hiding the old indirect symbol.  Process additional relocation
-   information.  */
+   information.  Also called for weakdefs, in which case we just let
+   _bfd_elf_link_hash_copy_indirect copy the flags for us.  */
 
-void
+static void
 _bfd_mips_elf_copy_indirect_symbol (dir, ind)
      struct elf_link_hash_entry *dir, *ind;
 {
@@ -8049,9 +8602,14 @@ _bfd_mips_elf_copy_indirect_symbol (dir, ind)
 
   _bfd_elf_link_hash_copy_indirect (dir, ind);
 
+  if (ind->root.type != bfd_link_hash_indirect)
+    return;
+
   dirmips = (struct mips_elf_link_hash_entry *) dir;
   indmips = (struct mips_elf_link_hash_entry *) ind;
   dirmips->possibly_dynamic_relocs += indmips->possibly_dynamic_relocs;
+  if (indmips->readonly_reloc)
+    dirmips->readonly_reloc = true;
   if (dirmips->min_dyn_reloc_index == 0
       || (indmips->min_dyn_reloc_index != 0
          && indmips->min_dyn_reloc_index < dirmips->min_dyn_reloc_index))
@@ -8094,9 +8652,17 @@ _bfd_mips_elf_adjust_dynamic_symbol (info, h)
   hmips = (struct mips_elf_link_hash_entry *) h;
   if (! info->relocateable
       && hmips->possibly_dynamic_relocs != 0
-      && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0)
-    mips_elf_allocate_dynamic_relocations (dynobj,
-                                          hmips->possibly_dynamic_relocs);
+      && (h->root.type == bfd_link_hash_defweak
+         || (h->elf_link_hash_flags
+             & ELF_LINK_HASH_DEF_REGULAR) == 0))
+    {
+      mips_elf_allocate_dynamic_relocations (dynobj,
+                                            hmips->possibly_dynamic_relocs);
+      if (hmips->readonly_reloc)
+       /* We tell the dynamic linker that there are relocations
+          against the text segment.  */
+       info->flags |= DF_TEXTREL;
+    }
 
   /* For a function, create a stub, if allowed.  */
   if (! hmips->no_fn_stub
@@ -8174,7 +8740,8 @@ _bfd_mips_elf_always_size_sections (output_bfd, info)
   /* The .reginfo section has a fixed size.  */
   ri = bfd_get_section_by_name (output_bfd, ".reginfo");
   if (ri != NULL)
-    bfd_set_section_size (output_bfd, ri, sizeof (Elf32_External_RegInfo));
+    bfd_set_section_size (output_bfd, ri,
+                         (bfd_size_type) sizeof (Elf32_External_RegInfo));
 
   if (info->relocateable
       || ! mips_elf_hash_table (info)->mips16_stubs_seen)
@@ -8332,7 +8899,7 @@ _bfd_mips_elf_size_dynamic_sections (output_bfd, info)
          int i;
          bfd_size_type loadable_size = 0;
          bfd_size_type local_gotno;
-         struct _bfd *sub;
+         bfd *sub;
 
          BFD_ASSERT (elf_section_data (s) != NULL);
          g = (struct mips_got_info *) elf_section_data (s)->tdata;
@@ -8351,7 +8918,8 @@ _bfd_mips_elf_size_dynamic_sections (output_bfd, info)
                {
                  if ((subsection->flags & SEC_ALLOC) == 0)
                    continue;
-                 loadable_size += (subsection->_raw_size + 0xf) & ~0xf;
+                 loadable_size += ((subsection->_raw_size + 0xf)
+                                   &~ (bfd_size_type) 0xf);
                }
            }
          loadable_size += MIPS_FUNCTION_STUB_SIZE;
@@ -8456,11 +9024,14 @@ _bfd_mips_elf_size_dynamic_sections (output_bfd, info)
                return false;
            }
        }
+
       if (reltext && SGI_COMPAT (output_bfd))
+       info->flags |= DF_TEXTREL;
+
+      if ((info->flags & DF_TEXTREL) != 0)
        {
          if (! MIPS_ELF_ADD_DYNAMIC_ENTRY (info, DT_TEXTREL, 0))
            return false;
-         info->flags |= DF_TEXTREL;
        }
 
       if (! MIPS_ELF_ADD_DYNAMIC_ENTRY (info, DT_PLTGOT, 0))
@@ -8648,18 +9219,18 @@ _bfd_mips_elf_finish_dynamic_symbol (output_bfd, info, h, sym)
 
       /* Fill the stub.  */
       p = stub;
-      bfd_put_32 (output_bfd, STUB_LW (output_bfd), p);
+      bfd_put_32 (output_bfd, (bfd_vma) STUB_LW (output_bfd), p);
       p += 4;
-      bfd_put_32 (output_bfd, STUB_MOVE (output_bfd), p);
+      bfd_put_32 (output_bfd, (bfd_vma) STUB_MOVE (output_bfd), p);
       p += 4;
 
       /* FIXME: Can h->dynindex be more than 64K?  */
       if (h->dynindx & 0xffff0000)
        return false;
 
-      bfd_put_32 (output_bfd, STUB_JALR, p);
+      bfd_put_32 (output_bfd, (bfd_vma) STUB_JALR, p);
       p += 4;
-      bfd_put_32 (output_bfd, STUB_LI16 (output_bfd) + h->dynindx, p);
+      bfd_put_32 (output_bfd, (bfd_vma) STUB_LI16 (output_bfd) + h->dynindx, p);
 
       BFD_ASSERT (h->plt.offset <= s->_raw_size);
       memcpy (s->contents + h->plt.offset, stub, MIPS_FUNCTION_STUB_SIZE);
@@ -8870,7 +9441,7 @@ _bfd_mips_elf_finish_dynamic_sections (output_bfd, info)
            case DT_STRSZ:
              /* Rewrite DT_STRSZ.  */
              dyn.d_un.d_val =
-               _bfd_stringtab_size (elf_hash_table (info)->dynstr);
+               _bfd_elf_strtab_size (elf_hash_table (info)->dynstr);
              break;
 
            case DT_PLTGOT:
@@ -8933,7 +9504,7 @@ _bfd_mips_elf_finish_dynamic_sections (output_bfd, info)
            case DT_MIPS_BASE_ADDRESS:
              s = output_bfd->sections;
              BFD_ASSERT (s != NULL);
-             dyn.d_un.d_ptr = s->vma & ~(0xffff);
+             dyn.d_un.d_ptr = s->vma & ~(bfd_vma) 0xffff;
              break;
 
            case DT_MIPS_LOCAL_GOTNO:
@@ -9102,6 +9673,179 @@ _bfd_mips_elf_finish_dynamic_sections (output_bfd, info)
   return true;
 }
 \f
+/* Support for core dump NOTE sections */
+static boolean
+_bfd_elf32_mips_grok_prstatus (abfd, note)
+     bfd *abfd;
+     Elf_Internal_Note *note;
+{
+  int offset;
+  unsigned int raw_size;
+
+  switch (note->descsz)
+    {
+      default:
+       return false;
+
+      case 256:                /* Linux/MIPS */
+       /* pr_cursig */
+       elf_tdata (abfd)->core_signal = bfd_get_16 (abfd, note->descdata + 12);
+
+       /* pr_pid */
+       elf_tdata (abfd)->core_pid = bfd_get_32 (abfd, note->descdata + 24);
+
+       /* pr_reg */
+       offset = 72;
+       raw_size = 180;
+
+       break;
+    }
+
+  /* Make a ".reg/999" section.  */
+  return _bfd_elfcore_make_pseudosection (abfd, ".reg",
+                                         raw_size, note->descpos + offset);
+}
+
+static boolean
+_bfd_elf32_mips_grok_psinfo (abfd, note)
+     bfd *abfd;
+     Elf_Internal_Note *note;
+{
+  switch (note->descsz)
+    {
+      default:
+       return false;
+
+      case 128:                /* Linux/MIPS elf_prpsinfo */
+       elf_tdata (abfd)->core_program
+        = _bfd_elfcore_strndup (abfd, note->descdata + 32, 16);
+       elf_tdata (abfd)->core_command
+        = _bfd_elfcore_strndup (abfd, note->descdata + 48, 80);
+    }
+
+  /* Note that for some reason, a spurious space is tacked
+     onto the end of the args in some (at least one anyway)
+     implementations, so strip it off if it exists.  */
+
+  {
+    char *command = elf_tdata (abfd)->core_command;
+    int n = strlen (command);
+
+    if (0 < n && command[n - 1] == ' ')
+      command[n - 1] = '\0';
+  }
+
+  return true;
+}
+\f
+#define PDR_SIZE 32
+
+static boolean
+_bfd_elf32_mips_discard_info (abfd, cookie, info)
+     bfd *abfd;
+     struct elf_reloc_cookie *cookie;
+     struct bfd_link_info *info;
+{
+  asection *o;
+  struct elf_backend_data *bed = get_elf_backend_data (abfd);
+  boolean ret = false;
+  unsigned char *tdata;
+  size_t i, skip;
+
+  o = bfd_get_section_by_name (abfd, ".pdr");
+  if (! o)
+    return false;
+  if (o->_raw_size == 0)
+    return false;
+  if (o->_raw_size % PDR_SIZE != 0)
+    return false;
+  if (o->output_section != NULL
+      && bfd_is_abs_section (o->output_section))
+    return false;
+
+  tdata = bfd_zmalloc (o->_raw_size / PDR_SIZE);
+  if (! tdata)
+    return false;
+
+  cookie->rels = _bfd_elf32_link_read_relocs (abfd, o, (PTR) NULL,
+                                            (Elf_Internal_Rela *) NULL,
+                                             info->keep_memory);
+  if (!cookie->rels)
+    {
+      free (tdata);
+      return false;
+    }
+
+  cookie->rel = cookie->rels;
+  cookie->relend =
+    cookie->rels + o->reloc_count * bed->s->int_rels_per_ext_rel;
+      
+  for (i = 0, skip = 0; i < o->_raw_size; i ++)
+    {
+      if (_bfd_elf32_reloc_symbol_deleted_p (i * PDR_SIZE, cookie))
+       {
+         tdata[i] = 1;
+         skip ++;
+       }
+    }
+
+  if (skip != 0)
+    {
+      elf_section_data (o)->tdata = tdata;
+      o->_cooked_size = o->_raw_size - skip * PDR_SIZE;
+      ret = true;
+    }
+  else
+    free (tdata);
+
+  if (! info->keep_memory)
+    free (cookie->rels);
+
+  return ret;
+}
+
+static boolean
+_bfd_elf32_mips_ignore_discarded_relocs (sec)
+     asection *sec;
+{
+  if (strcmp (sec->name, ".pdr") == 0)
+    return true;
+  return false;
+}
+
+static boolean
+_bfd_elf32_mips_write_section (output_bfd, sec, contents)
+     bfd *output_bfd;
+     asection *sec;
+     bfd_byte *contents;
+{
+  bfd_byte *to, *from, *end;
+  int i;
+
+  if (strcmp (sec->name, ".pdr") != 0)
+    return false;
+
+  if (elf_section_data (sec)->tdata == NULL)
+    return false;
+
+  to = contents;
+  end = contents + sec->_raw_size;
+  for (from = contents, i = 0;
+       from < end;
+       from += PDR_SIZE, i++)
+    {
+      if (((unsigned char *)elf_section_data (sec)->tdata)[i] == 1)
+       continue;
+      if (to != from)
+       memcpy (to, from, PDR_SIZE);
+      to += PDR_SIZE;
+    }
+  bfd_set_section_contents (output_bfd, sec->output_section, contents,
+                           (file_ptr) sec->output_offset,
+                           sec->_cooked_size);
+  return true;
+}
+\f
 /* This is almost identical to bfd_generic_get_... except that some
    MIPS relocations need to be handled specially.  Sigh.  */
 
@@ -9126,7 +9870,7 @@ elf32_mips_get_relocated_section_contents (abfd, link_info, link_order, data,
   if (reloc_size < 0)
     goto error_return;
 
-  reloc_vector = (arelent **) bfd_malloc (reloc_size);
+  reloc_vector = (arelent **) bfd_malloc ((bfd_size_type) reloc_size);
   if (reloc_vector == NULL && reloc_size != 0)
     goto error_return;
 
@@ -9134,7 +9878,7 @@ elf32_mips_get_relocated_section_contents (abfd, link_info, link_order, data,
   if (!bfd_get_section_contents (input_bfd,
                                 input_section,
                                 (PTR) data,
-                                0,
+                                (file_ptr) 0,
                                 input_section->_raw_size))
     goto error_return;
 
@@ -9331,10 +10075,6 @@ static const struct ecoff_debug_swap mips_elf32_ecoff_debug_swap = {
   _bfd_mips_elf_read_ecoff_info
 };
 \f
-#define TARGET_LITTLE_SYM              bfd_elf32_littlemips_vec
-#define TARGET_LITTLE_NAME             "elf32-littlemips"
-#define TARGET_BIG_SYM                 bfd_elf32_bigmips_vec
-#define TARGET_BIG_NAME                        "elf32-bigmips"
 #define ELF_ARCH                       bfd_arch_mips
 #define ELF_MACHINE_CODE               EM_MIPS
 
@@ -9345,24 +10085,19 @@ static const struct ecoff_debug_swap mips_elf32_ecoff_debug_swap = {
 #define elf_backend_collect            true
 #define elf_backend_type_change_ok     true
 #define elf_backend_can_gc_sections    true
-#define elf_backend_sign_extend_vma    true
 #define elf_info_to_howto              mips_info_to_howto_rela
 #define elf_info_to_howto_rel          mips_info_to_howto_rel
 #define elf_backend_sym_is_global      mips_elf_sym_is_global
 #define elf_backend_object_p           _bfd_mips_elf_object_p
+#define elf_backend_symbol_processing  _bfd_mips_elf_symbol_processing
+#define elf_backend_section_processing _bfd_mips_elf_section_processing
 #define elf_backend_section_from_shdr  _bfd_mips_elf_section_from_shdr
 #define elf_backend_fake_sections      _bfd_mips_elf_fake_sections
 #define elf_backend_section_from_bfd_section \
                                        _bfd_mips_elf_section_from_bfd_section
-#define elf_backend_section_processing _bfd_mips_elf_section_processing
-#define elf_backend_symbol_processing  _bfd_mips_elf_symbol_processing
-#define elf_backend_additional_program_headers \
-                                       _bfd_mips_elf_additional_program_headers
-#define elf_backend_modify_segment_map _bfd_mips_elf_modify_segment_map
-#define elf_backend_final_write_processing \
-                                       _bfd_mips_elf_final_write_processing
-#define elf_backend_ecoff_debug_swap   &mips_elf32_ecoff_debug_swap
 #define elf_backend_add_symbol_hook    _bfd_mips_elf_add_symbol_hook
+#define elf_backend_link_output_symbol_hook \
+                                       _bfd_mips_elf_link_output_symbol_hook
 #define elf_backend_create_dynamic_sections \
                                        _bfd_mips_elf_create_dynamic_sections
 #define elf_backend_check_relocs       _bfd_mips_elf_check_relocs
@@ -9373,22 +10108,35 @@ static const struct ecoff_debug_swap mips_elf32_ecoff_debug_swap = {
 #define elf_backend_size_dynamic_sections \
                                        _bfd_mips_elf_size_dynamic_sections
 #define elf_backend_relocate_section   _bfd_mips_elf_relocate_section
-#define elf_backend_link_output_symbol_hook \
-                                       _bfd_mips_elf_link_output_symbol_hook
 #define elf_backend_finish_dynamic_symbol \
                                        _bfd_mips_elf_finish_dynamic_symbol
 #define elf_backend_finish_dynamic_sections \
                                        _bfd_mips_elf_finish_dynamic_sections
+#define elf_backend_final_write_processing \
+                                       _bfd_mips_elf_final_write_processing
+#define elf_backend_additional_program_headers \
+                                       _bfd_mips_elf_additional_program_headers
+#define elf_backend_modify_segment_map _bfd_mips_elf_modify_segment_map
 #define elf_backend_gc_mark_hook       _bfd_mips_elf_gc_mark_hook
 #define elf_backend_gc_sweep_hook      _bfd_mips_elf_gc_sweep_hook
-
-#define elf_backend_got_header_size    (4*MIPS_RESERVED_GOTNO)
-#define elf_backend_plt_header_size    0
-
 #define elf_backend_copy_indirect_symbol \
                                        _bfd_mips_elf_copy_indirect_symbol
-
 #define elf_backend_hide_symbol                _bfd_mips_elf_hide_symbol
+#define elf_backend_grok_prstatus      _bfd_elf32_mips_grok_prstatus
+#define elf_backend_grok_psinfo                _bfd_elf32_mips_grok_psinfo
+#define elf_backend_ecoff_debug_swap   &mips_elf32_ecoff_debug_swap
+
+#define elf_backend_got_header_size    (4 * MIPS_RESERVED_GOTNO)
+#define elf_backend_plt_header_size    0
+#define elf_backend_may_use_rel_p      1
+#define elf_backend_may_use_rela_p     0
+#define elf_backend_default_use_rela_p 0
+#define elf_backend_sign_extend_vma    true
+
+#define elf_backend_discard_info       _bfd_elf32_mips_discard_info
+#define elf_backend_ignore_discarded_relocs \
+                                       _bfd_elf32_mips_ignore_discarded_relocs
+#define elf_backend_write_section      _bfd_elf32_mips_write_section
 
 #define bfd_elf32_bfd_is_local_label_name \
                                        mips_elf_is_local_label_name
@@ -9404,11 +10152,17 @@ static const struct ecoff_debug_swap mips_elf32_ecoff_debug_swap = {
 #define bfd_elf32_bfd_set_private_flags        _bfd_mips_elf_set_private_flags
 #define bfd_elf32_bfd_print_private_bfd_data \
                                        _bfd_mips_elf_print_private_bfd_data
-#include "elf32-target.h"
 
-/* Support for traditional mips targets */
+/* Support for SGI-ish mips targets.  */
+#define TARGET_LITTLE_SYM              bfd_elf32_littlemips_vec
+#define TARGET_LITTLE_NAME             "elf32-littlemips"
+#define TARGET_BIG_SYM                 bfd_elf32_bigmips_vec
+#define TARGET_BIG_NAME                        "elf32-bigmips"
+
+#include "elf32-target.h"
 
-#define INCLUDED_TARGET_FILE            /* More a type of flag */
+/* Support for traditional mips targets.  */
+#define INCLUDED_TARGET_FILE            /* More a type of flag.  */
 
 #undef TARGET_LITTLE_SYM
 #undef TARGET_LITTLE_NAME