* bfd-in.h (bfd_get_section_limit): Define.
[deliverable/binutils-gdb.git] / bfd / elfxx-mips.c
index bede3e61293a05110410d9d1d4b51e3ded510dd7..b81927373d4cd41e884768cab06cc9adb2a06c7d 100644 (file)
@@ -1,6 +1,6 @@
 /* MIPS-specific support for ELF
    Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-   2003 Free Software Foundation, Inc.
+   2003, 2004 Free Software Foundation, Inc.
 
    Most of the information added by Ian Lance Taylor, Cygnus Support,
    <ian@cygnus.com>.
@@ -188,10 +188,6 @@ struct mips_elf_link_hash_entry
      a readonly section.  */
   bfd_boolean readonly_reloc;
 
-  /* The index of the first dynamic relocation (in the .rel.dyn
-     section) against this symbol.  */
-  unsigned int min_dyn_reloc_index;
-
   /* We must not create a stub for a symbol that has relocations
      related to taking the function's address, i.e. any but
      R_MIPS_CALL*16 ones -- see "MIPS ABI Supplement, 3rd Edition",
@@ -374,123 +370,135 @@ typedef struct runtime_pdr {
 #define rpdNil ((pRPDR) 0)
 \f
 static struct bfd_hash_entry *mips_elf_link_hash_newfunc
-  PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *));
+  (struct bfd_hash_entry *, struct bfd_hash_table *, const char *);
 static void ecoff_swap_rpdr_out
-  PARAMS ((bfd *, const RPDR *, struct rpdr_ext *));
+  (bfd *, const RPDR *, struct rpdr_ext *);
 static bfd_boolean mips_elf_create_procedure_table
-  PARAMS ((PTR, bfd *, struct bfd_link_info *, asection *,
-          struct ecoff_debug_info *));
+  (void *, bfd *, struct bfd_link_info *, asection *,
+   struct ecoff_debug_info *);
 static bfd_boolean mips_elf_check_mips16_stubs
-  PARAMS ((struct mips_elf_link_hash_entry *, PTR));
+  (struct mips_elf_link_hash_entry *, void *);
 static void bfd_mips_elf32_swap_gptab_in
-  PARAMS ((bfd *, const Elf32_External_gptab *, Elf32_gptab *));
+  (bfd *, const Elf32_External_gptab *, Elf32_gptab *);
 static void bfd_mips_elf32_swap_gptab_out
-  PARAMS ((bfd *, const Elf32_gptab *, Elf32_External_gptab *));
+  (bfd *, const Elf32_gptab *, Elf32_External_gptab *);
 static void bfd_elf32_swap_compact_rel_out
-  PARAMS ((bfd *, const Elf32_compact_rel *, Elf32_External_compact_rel *));
+  (bfd *, const Elf32_compact_rel *, Elf32_External_compact_rel *);
 static void bfd_elf32_swap_crinfo_out
-  PARAMS ((bfd *, const Elf32_crinfo *, Elf32_External_crinfo *));
-#if 0
-static void bfd_mips_elf_swap_msym_in
-  PARAMS ((bfd *, const Elf32_External_Msym *, Elf32_Internal_Msym *));
-#endif
-static void bfd_mips_elf_swap_msym_out
-  PARAMS ((bfd *, const Elf32_Internal_Msym *, Elf32_External_Msym *));
+  (bfd *, const Elf32_crinfo *, Elf32_External_crinfo *);
 static int sort_dynamic_relocs
-  PARAMS ((const void *, const void *));
+  (const void *, const void *);
 static int sort_dynamic_relocs_64
-  PARAMS ((const void *, const void *));
+  (const void *, const void *);
 static bfd_boolean mips_elf_output_extsym
-  PARAMS ((struct mips_elf_link_hash_entry *, PTR));
-static int gptab_compare PARAMS ((const void *, const void *));
-static asection * mips_elf_rel_dyn_section PARAMS ((bfd *, bfd_boolean));
-static asection * mips_elf_got_section PARAMS ((bfd *, bfd_boolean));
+  (struct mips_elf_link_hash_entry *, void *);
+static int gptab_compare
+  (const void *, const void *);
+static asection *mips_elf_rel_dyn_section
+  (bfd *, bfd_boolean);
+static asection *mips_elf_got_section
+  (bfd *, bfd_boolean);
 static struct mips_got_info *mips_elf_got_info
-  PARAMS ((bfd *, asection **));
-static long mips_elf_get_global_gotsym_index PARAMS ((bfd *abfd));
+  (bfd *, asection **);
 static bfd_vma mips_elf_local_got_index
-  PARAMS ((bfd *, bfd *, struct bfd_link_info *, bfd_vma));
+  (bfd *, bfd *, struct bfd_link_info *, bfd_vma);
 static bfd_vma mips_elf_global_got_index
-  PARAMS ((bfd *, bfd *, struct elf_link_hash_entry *));
+  (bfd *, bfd *, struct elf_link_hash_entry *);
 static bfd_vma mips_elf_got_page
-  PARAMS ((bfd *, bfd *, struct bfd_link_info *, bfd_vma, bfd_vma *));
+  (bfd *, bfd *, struct bfd_link_info *, bfd_vma, bfd_vma *);
 static bfd_vma mips_elf_got16_entry
-  PARAMS ((bfd *, bfd *, struct bfd_link_info *, bfd_vma, bfd_boolean));
+  (bfd *, bfd *, struct bfd_link_info *, bfd_vma, bfd_boolean);
 static bfd_vma mips_elf_got_offset_from_index
-  PARAMS ((bfd *, bfd *, bfd *, bfd_vma));
+  (bfd *, bfd *, bfd *, bfd_vma);
 static struct mips_got_entry *mips_elf_create_local_got_entry
-  PARAMS ((bfd *, bfd *, struct mips_got_info *, asection *, bfd_vma));
+  (bfd *, bfd *, struct mips_got_info *, asection *, bfd_vma);
 static bfd_boolean mips_elf_sort_hash_table
-  PARAMS ((struct bfd_link_info *, unsigned long));
+  (struct bfd_link_info *, unsigned long);
 static bfd_boolean mips_elf_sort_hash_table_f
-  PARAMS ((struct mips_elf_link_hash_entry *, PTR));
+  (struct mips_elf_link_hash_entry *, void *);
 static bfd_boolean mips_elf_record_local_got_symbol
-  PARAMS ((bfd *, long, bfd_vma, struct mips_got_info *));
+  (bfd *, long, bfd_vma, struct mips_got_info *);
 static bfd_boolean mips_elf_record_global_got_symbol
-  PARAMS ((struct elf_link_hash_entry *, bfd *, struct bfd_link_info *,
-          struct mips_got_info *));
+  (struct elf_link_hash_entry *, bfd *, struct bfd_link_info *,
+   struct mips_got_info *);
 static const Elf_Internal_Rela *mips_elf_next_relocation
-  PARAMS ((bfd *, unsigned int, const Elf_Internal_Rela *,
-          const Elf_Internal_Rela *));
+  (bfd *, unsigned int, const Elf_Internal_Rela *, const Elf_Internal_Rela *);
 static bfd_boolean mips_elf_local_relocation_p
-  PARAMS ((bfd *, const Elf_Internal_Rela *, asection **, bfd_boolean));
-static bfd_vma mips_elf_sign_extend PARAMS ((bfd_vma, int));
-static bfd_boolean mips_elf_overflow_p PARAMS ((bfd_vma, int));
-static bfd_vma mips_elf_high PARAMS ((bfd_vma));
-static bfd_vma mips_elf_higher PARAMS ((bfd_vma));
-static bfd_vma mips_elf_highest PARAMS ((bfd_vma));
+  (bfd *, const Elf_Internal_Rela *, asection **, bfd_boolean);
+static bfd_boolean mips_elf_overflow_p
+  (bfd_vma, int);
+static bfd_vma mips_elf_high
+  (bfd_vma);
+static bfd_vma mips_elf_higher
+  (bfd_vma);
+static bfd_vma mips_elf_highest
+  (bfd_vma);
 static bfd_boolean mips_elf_create_compact_rel_section
-  PARAMS ((bfd *, struct bfd_link_info *));
+  (bfd *, struct bfd_link_info *);
 static bfd_boolean mips_elf_create_got_section
-  PARAMS ((bfd *, struct bfd_link_info *, bfd_boolean));
-static asection *mips_elf_create_msym_section
-  PARAMS ((bfd *));
+  (bfd *, struct bfd_link_info *, bfd_boolean);
 static bfd_reloc_status_type mips_elf_calculate_relocation
-  PARAMS ((bfd *, bfd *, asection *, struct bfd_link_info *,
-          const Elf_Internal_Rela *, bfd_vma, reloc_howto_type *,
-          Elf_Internal_Sym *, asection **, bfd_vma *, const char **,
-          bfd_boolean *, bfd_boolean));
+  (bfd *, bfd *, asection *, struct bfd_link_info *,
+   const Elf_Internal_Rela *, bfd_vma, reloc_howto_type *,
+   Elf_Internal_Sym *, asection **, bfd_vma *, const char **,
+   bfd_boolean *, bfd_boolean);
 static bfd_vma mips_elf_obtain_contents
-  PARAMS ((reloc_howto_type *, const Elf_Internal_Rela *, bfd *, bfd_byte *));
+  (reloc_howto_type *, const Elf_Internal_Rela *, bfd *, bfd_byte *);
 static bfd_boolean mips_elf_perform_relocation
-  PARAMS ((struct bfd_link_info *, reloc_howto_type *,
-          const Elf_Internal_Rela *, bfd_vma, bfd *, asection *, bfd_byte *,
-          bfd_boolean));
+  (struct bfd_link_info *, reloc_howto_type *, const Elf_Internal_Rela *,
+   bfd_vma, bfd *, asection *, bfd_byte *, bfd_boolean);
 static bfd_boolean mips_elf_stub_section_p
-  PARAMS ((bfd *, asection *));
+  (bfd *, asection *);
 static void mips_elf_allocate_dynamic_relocations
-  PARAMS ((bfd *, unsigned int));
+  (bfd *, unsigned int);
 static bfd_boolean mips_elf_create_dynamic_relocation
-  PARAMS ((bfd *, struct bfd_link_info *, const Elf_Internal_Rela *,
-          struct mips_elf_link_hash_entry *, asection *,
-          bfd_vma, bfd_vma *, asection *));
-static void mips_set_isa_flags PARAMS ((bfd *));
-static INLINE char* elf_mips_abi_name PARAMS ((bfd *));
+  (bfd *, struct bfd_link_info *, const Elf_Internal_Rela *,
+   struct mips_elf_link_hash_entry *, asection *, bfd_vma,
+   bfd_vma *, asection *);
+static void mips_set_isa_flags
+  (bfd *);
+static INLINE char *elf_mips_abi_name
+  (bfd *);
 static void mips_elf_irix6_finish_dynamic_symbol
-  PARAMS ((bfd *, const char *, Elf_Internal_Sym *));
-static bfd_boolean mips_mach_extends_p PARAMS ((unsigned long, unsigned long));
-static bfd_boolean mips_32bit_flags_p PARAMS ((flagword));
-static INLINE hashval_t mips_elf_hash_bfd_vma PARAMS ((bfd_vma));
-static hashval_t mips_elf_got_entry_hash PARAMS ((const PTR));
-static int mips_elf_got_entry_eq PARAMS ((const PTR, const PTR));
+  (bfd *, const char *, Elf_Internal_Sym *);
+static bfd_boolean mips_mach_extends_p
+  (unsigned long, unsigned long);
+static bfd_boolean mips_32bit_flags_p
+  (flagword);
+static INLINE hashval_t mips_elf_hash_bfd_vma
+  (bfd_vma);
+static hashval_t mips_elf_got_entry_hash
+  (const void *);
+static int mips_elf_got_entry_eq
+  (const void *, const void *);
 
 static bfd_boolean mips_elf_multi_got
-  PARAMS ((bfd *, struct bfd_link_info *, struct mips_got_info *,
-          asection *, bfd_size_type));
-static hashval_t mips_elf_multi_got_entry_hash PARAMS ((const PTR));
-static int mips_elf_multi_got_entry_eq PARAMS ((const PTR, const PTR));
-static hashval_t mips_elf_bfd2got_entry_hash PARAMS ((const PTR));
-static int mips_elf_bfd2got_entry_eq PARAMS ((const PTR, const PTR));
-static int mips_elf_make_got_per_bfd PARAMS ((void **, void *));
-static int mips_elf_merge_gots PARAMS ((void **, void *));
-static int mips_elf_set_global_got_offset PARAMS ((void**, void *));
-static int mips_elf_resolve_final_got_entry PARAMS ((void**, void *));
+  (bfd *, struct bfd_link_info *, struct mips_got_info *,
+   asection *, bfd_size_type);
+static hashval_t mips_elf_multi_got_entry_hash
+  (const void *);
+static int mips_elf_multi_got_entry_eq
+  (const void *, const void *);
+static hashval_t mips_elf_bfd2got_entry_hash
+  (const void *);
+static int mips_elf_bfd2got_entry_eq
+  (const void *, const void *);
+static int mips_elf_make_got_per_bfd
+  (void **, void *);
+static int mips_elf_merge_gots
+  (void **, void *);
+static int mips_elf_set_global_got_offset
+  (void **, void *);
+static int mips_elf_set_no_stub
+  (void **, void *);
+static int mips_elf_resolve_final_got_entry
+  (void **, void *);
 static void mips_elf_resolve_final_got_entries
-  PARAMS ((struct mips_got_info *));
+  (struct mips_got_info *);
 static bfd_vma mips_elf_adjust_gp
-  PARAMS ((bfd *, struct mips_got_info *, bfd *));
+  (bfd *, struct mips_got_info *, bfd *);
 static struct mips_got_info *mips_elf_got_for_ibfd
-  PARAMS ((struct mips_got_info *, bfd *));
+  (struct mips_got_info *, bfd *);
 
 /* This will be used when we sort the dynamic relocation records.  */
 static bfd *reldyn_sorting_bfd;
@@ -517,11 +525,10 @@ static bfd *reldyn_sorting_bfd;
 
 /* The name of the options section.  */
 #define MIPS_ELF_OPTIONS_SECTION_NAME(abfd) \
-  (ABI_64_P (abfd) ? ".MIPS.options" : ".options")
+  (NEWABI_P (abfd) ? ".MIPS.options" : ".options")
 
 /* The name of the stub section.  */
-#define MIPS_ELF_STUB_SECTION_NAME(abfd) \
-  (ABI_64_P (abfd) ? ".MIPS.stubs" : ".stub")
+#define MIPS_ELF_STUB_SECTION_NAME(abfd) ".MIPS.stubs"
 
 /* The size of an external REL relocation.  */
 #define MIPS_ELF_REL_SIZE(abfd) \
@@ -554,17 +561,8 @@ static bfd *reldyn_sorting_bfd;
    : bfd_put_32 (abfd, val, ptr))
 
 /* 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, (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, (bfd_vma) tag, (bfd_vma) val))
-#endif
+#define MIPS_ELF_ADD_DYNAMIC_ENTRY(info, tag, val)     \
+  _bfd_elf_add_dynamic_entry (info, tag, val)
 
 #define MIPS_ELF_RTYPE_TO_HOWTO(abfd, rtype, rela)                     \
   (get_elf_backend_data (abfd)->elf_backend_mips_rtype_to_howto (rtype, rela))
@@ -589,6 +587,7 @@ static bfd *reldyn_sorting_bfd;
 /* 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)
+#define MINUS_TWO      (((bfd_vma)0) - 2)
 
 /* The number of local .got entries we reserve.  */
 #define MIPS_RESERVED_GOTNO (2)
@@ -600,17 +599,20 @@ static bfd *reldyn_sorting_bfd;
    offsets from $gp.  */
 #define MIPS_ELF_GOT_MAX_SIZE(abfd) (ELF_MIPS_GP_OFFSET(abfd) + 0x7fff)
 
-/* Instructions which appear in a stub.  For some reason the stub is
-   slightly different on an SGI system.  */
+/* Instructions which appear in a stub.  */
 #define STUB_LW(abfd)                                          \
   ((ABI_64_P (abfd)                                            \
     ? 0xdf998010               /* ld t9,0x8010(gp) */          \
     : 0x8f998010))              /* lw t9,0x8010(gp) */
 #define STUB_MOVE(abfd)                                         \
-  (SGI_COMPAT (abfd) ? 0x03e07825 : 0x03e07821)         /* move t7,ra */
-#define STUB_JALR 0x0320f809                           /* jal t9 */
+   ((ABI_64_P (abfd)                                           \
+     ? 0x03e0782d              /* daddu t7,ra */               \
+     : 0x03e07821))            /* addu t7,ra */
+#define STUB_JALR 0x0320f809   /* jalr t9,ra */
 #define STUB_LI16(abfd)                                         \
-  (SGI_COMPAT (abfd) ? 0x34180000 : 0x24180000)         /* ori t8,zero,0 */
+  ((ABI_64_P (abfd)                                            \
+   ? 0x64180000                        /* daddiu t8,zero,0 */          \
+   : 0x24180000))              /* addiu t8,zero,0 */
 #define MIPS_FUNCTION_STUB_SIZE (16)
 
 /* The name of the dynamic interpreter.  This is put in the .interp
@@ -690,7 +692,7 @@ static bfd *reldyn_sorting_bfd;
 #define mips_elf_link_hash_traverse(table, func, info)                 \
   (elf_link_hash_traverse                                              \
    (&(table)->root,                                                    \
-    (bfd_boolean (*) PARAMS ((struct elf_link_hash_entry *, PTR))) (func), \
+    (bfd_boolean (*) (struct elf_link_hash_entry *, void *)) (func),   \
     (info)))
 
 /* Get the MIPS ELF linker hash table from a link_info structure.  */
@@ -701,28 +703,24 @@ static bfd *reldyn_sorting_bfd;
 /* Create an entry in a MIPS ELF linker hash table.  */
 
 static struct bfd_hash_entry *
-mips_elf_link_hash_newfunc (entry, table, string)
-     struct bfd_hash_entry *entry;
-     struct bfd_hash_table *table;
-     const char *string;
+mips_elf_link_hash_newfunc (struct bfd_hash_entry *entry,
+                           struct bfd_hash_table *table, const char *string)
 {
   struct mips_elf_link_hash_entry *ret =
     (struct mips_elf_link_hash_entry *) entry;
 
   /* Allocate the structure if it has not already been allocated by a
      subclass.  */
-  if (ret == (struct mips_elf_link_hash_entry *) NULL)
-    ret = ((struct mips_elf_link_hash_entry *)
-          bfd_hash_allocate (table,
-                             sizeof (struct mips_elf_link_hash_entry)));
-  if (ret == (struct mips_elf_link_hash_entry *) NULL)
+  if (ret == NULL)
+    ret = bfd_hash_allocate (table, sizeof (struct mips_elf_link_hash_entry));
+  if (ret == NULL)
     return (struct bfd_hash_entry *) ret;
 
   /* Call the allocation method of the superclass.  */
   ret = ((struct mips_elf_link_hash_entry *)
         _bfd_elf_link_hash_newfunc ((struct bfd_hash_entry *) ret,
                                     table, string));
-  if (ret != (struct mips_elf_link_hash_entry *) NULL)
+  if (ret != NULL)
     {
       /* Set local fields.  */
       memset (&ret->esym, 0, sizeof (EXTR));
@@ -731,7 +729,6 @@ mips_elf_link_hash_newfunc (entry, table, string)
       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;
       ret->need_fn_stub = FALSE;
@@ -744,17 +741,15 @@ mips_elf_link_hash_newfunc (entry, table, string)
 }
 
 bfd_boolean
-_bfd_mips_elf_new_section_hook (abfd, sec)
-     bfd *abfd;
-     asection *sec;
+_bfd_mips_elf_new_section_hook (bfd *abfd, asection *sec)
 {
   struct _mips_elf_section_data *sdata;
   bfd_size_type amt = sizeof (*sdata);
 
-  sdata = (struct _mips_elf_section_data *) bfd_zalloc (abfd, amt);
+  sdata = bfd_zalloc (abfd, amt);
   if (sdata == NULL)
     return FALSE;
-  sec->used_by_bfd = (PTR) sdata;
+  sec->used_by_bfd = sdata;
 
   return _bfd_elf_new_section_hook (abfd, sec);
 }
@@ -763,23 +758,21 @@ _bfd_mips_elf_new_section_hook (abfd, sec)
    ecoff_debug_info structure.  */
 
 bfd_boolean
-_bfd_mips_elf_read_ecoff_info (abfd, section, debug)
-     bfd *abfd;
-     asection *section;
-     struct ecoff_debug_info *debug;
+_bfd_mips_elf_read_ecoff_info (bfd *abfd, asection *section,
+                              struct ecoff_debug_info *debug)
 {
   HDRR *symhdr;
   const struct ecoff_debug_swap *swap;
-  char *ext_hdr = NULL;
+  char *ext_hdr;
 
   swap = get_elf_backend_data (abfd)->elf_backend_ecoff_debug_swap;
   memset (debug, 0, sizeof (*debug));
 
-  ext_hdr = (char *) bfd_malloc (swap->external_hdr_size);
+  ext_hdr = bfd_malloc (swap->external_hdr_size);
   if (ext_hdr == NULL && swap->external_hdr_size != 0)
     goto error_return;
 
-  if (! bfd_get_section_contents (abfd, section, ext_hdr, (file_ptr) 0,
+  if (! bfd_get_section_contents (abfd, section, ext_hdr, 0,
                                  swap->external_hdr_size))
     goto error_return;
 
@@ -794,30 +787,29 @@ _bfd_mips_elf_read_ecoff_info (abfd, section, debug)
   else                                                                 \
     {                                                                  \
       bfd_size_type amt = (bfd_size_type) size * symhdr->count;                \
-      debug->ptr = (type) bfd_malloc (amt);                            \
+      debug->ptr = bfd_malloc (amt);                                   \
       if (debug->ptr == NULL)                                          \
        goto error_return;                                              \
-      if (bfd_seek (abfd, (file_ptr) symhdr->offset, SEEK_SET) != 0    \
+      if (bfd_seek (abfd, symhdr->offset, SEEK_SET) != 0               \
          || bfd_bread (debug->ptr, amt, abfd) != amt)                  \
        goto error_return;                                              \
     }
 
   READ (line, cbLineOffset, cbLine, sizeof (unsigned char), unsigned char *);
-  READ (external_dnr, cbDnOffset, idnMax, swap->external_dnr_size, PTR);
-  READ (external_pdr, cbPdOffset, ipdMax, swap->external_pdr_size, PTR);
-  READ (external_sym, cbSymOffset, isymMax, swap->external_sym_size, PTR);
-  READ (external_opt, cbOptOffset, ioptMax, swap->external_opt_size, PTR);
+  READ (external_dnr, cbDnOffset, idnMax, swap->external_dnr_size, void *);
+  READ (external_pdr, cbPdOffset, ipdMax, swap->external_pdr_size, void *);
+  READ (external_sym, cbSymOffset, isymMax, swap->external_sym_size, void *);
+  READ (external_opt, cbOptOffset, ioptMax, swap->external_opt_size, void *);
   READ (external_aux, cbAuxOffset, iauxMax, sizeof (union aux_ext),
        union aux_ext *);
   READ (ss, cbSsOffset, issMax, sizeof (char), char *);
   READ (ssext, cbSsExtOffset, issExtMax, sizeof (char), char *);
-  READ (external_fdr, cbFdOffset, ifdMax, swap->external_fdr_size, PTR);
-  READ (external_rfd, cbRfdOffset, crfd, swap->external_rfd_size, PTR);
-  READ (external_ext, cbExtOffset, iextMax, swap->external_ext_size, PTR);
+  READ (external_fdr, cbFdOffset, ifdMax, swap->external_fdr_size, void *);
+  READ (external_rfd, cbRfdOffset, crfd, swap->external_rfd_size, void *);
+  READ (external_ext, cbExtOffset, iextMax, swap->external_ext_size, void *);
 #undef READ
 
   debug->fdr = NULL;
-  debug->adjust = NULL;
 
   return TRUE;
 
@@ -852,10 +844,7 @@ _bfd_mips_elf_read_ecoff_info (abfd, section, debug)
 /* Swap RPDR (runtime procedure table entry) for output.  */
 
 static void
-ecoff_swap_rpdr_out (abfd, in, ex)
-     bfd *abfd;
-     const RPDR *in;
-     struct rpdr_ext *ex;
+ecoff_swap_rpdr_out (bfd *abfd, const RPDR *in, struct rpdr_ext *ex)
 {
   H_PUT_S32 (abfd, in->adr, ex->p_adr);
   H_PUT_32 (abfd, in->regmask, ex->p_regmask);
@@ -876,18 +865,15 @@ ecoff_swap_rpdr_out (abfd, in, ex)
 /* Create a runtime procedure table from the .mdebug section.  */
 
 static bfd_boolean
-mips_elf_create_procedure_table (handle, abfd, info, s, debug)
-     PTR handle;
-     bfd *abfd;
-     struct bfd_link_info *info;
-     asection *s;
-     struct ecoff_debug_info *debug;
+mips_elf_create_procedure_table (void *handle, bfd *abfd,
+                                struct bfd_link_info *info, asection *s,
+                                struct ecoff_debug_info *debug)
 {
   const struct ecoff_debug_swap *swap;
   HDRR *hdr = &debug->symbolic_header;
   RPDR *rpdr, *rp;
   struct rpdr_ext *erp;
-  PTR rtproc;
+  void *rtproc;
   struct pdr_ext *epdr;
   struct sym_ext *esym;
   char *ss, **sv;
@@ -914,44 +900,44 @@ mips_elf_create_procedure_table (handle, abfd, info, s, debug)
     {
       size = swap->external_pdr_size;
 
-      epdr = (struct pdr_ext *) bfd_malloc (size * count);
+      epdr = bfd_malloc (size * count);
       if (epdr == NULL)
        goto error_return;
 
-      if (! _bfd_ecoff_get_accumulated_pdr (handle, (PTR) epdr))
+      if (! _bfd_ecoff_get_accumulated_pdr (handle, (bfd_byte *) epdr))
        goto error_return;
 
       size = sizeof (RPDR);
-      rp = rpdr = (RPDR *) bfd_malloc (size * count);
+      rp = rpdr = bfd_malloc (size * count);
       if (rpdr == NULL)
        goto error_return;
 
       size = sizeof (char *);
-      sv = (char **) bfd_malloc (size * count);
+      sv = bfd_malloc (size * count);
       if (sv == NULL)
        goto error_return;
 
       count = hdr->isymMax;
       size = swap->external_sym_size;
-      esym = (struct sym_ext *) bfd_malloc (size * count);
+      esym = bfd_malloc (size * count);
       if (esym == NULL)
        goto error_return;
 
-      if (! _bfd_ecoff_get_accumulated_sym (handle, (PTR) esym))
+      if (! _bfd_ecoff_get_accumulated_sym (handle, (bfd_byte *) esym))
        goto error_return;
 
       count = hdr->issMax;
-      ss = (char *) bfd_malloc (count);
+      ss = bfd_malloc (count);
       if (ss == NULL)
        goto error_return;
-      if (! _bfd_ecoff_get_accumulated_ss (handle, (PTR) ss))
+      if (! _bfd_ecoff_get_accumulated_ss (handle, ss))
        goto error_return;
 
       count = hdr->ipdMax;
       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);
+         (*swap->swap_pdr_in) (abfd, epdr + i, &pdr);
+         (*swap->swap_sym_in) (abfd, &esym[pdr.isym], &sym);
          rp->adr = sym.value;
          rp->regmask = pdr.regmask;
          rp->regoffset = pdr.regoffset;
@@ -968,7 +954,7 @@ mips_elf_create_procedure_table (handle, abfd, info, s, debug)
 
   size = sizeof (struct rpdr_ext) * (count + 2) + sindex;
   size = BFD_ALIGN (size, 16);
-  rtproc = (PTR) bfd_alloc (abfd, size);
+  rtproc = bfd_alloc (abfd, size);
   if (rtproc == NULL)
     {
       mips_elf_hash_table (info)->procedure_count = 0;
@@ -977,7 +963,7 @@ mips_elf_create_procedure_table (handle, abfd, info, s, debug)
 
   mips_elf_hash_table (info)->procedure_count = count + 2;
 
-  erp = (struct rpdr_ext *) rtproc;
+  erp = rtproc;
   memset (erp, 0, sizeof (struct rpdr_ext));
   erp++;
   str = (char *) rtproc + sizeof (struct rpdr_ext) * (count + 2);
@@ -992,12 +978,12 @@ mips_elf_create_procedure_table (handle, abfd, info, s, debug)
   H_PUT_S32 (abfd, -1, (erp + count)->p_adr);
 
   /* Set the size and contents of .rtproc section.  */
-  s->_raw_size = size;
-  s->contents = (bfd_byte *) rtproc;
+  s->size = size;
+  s->contents = rtproc;
 
   /* Skip this section later on (I don't think this currently
      matters, but someday it might).  */
-  s->link_order_head = (struct bfd_link_order *) NULL;
+  s->link_order_head = NULL;
 
   if (epdr != NULL)
     free (epdr);
@@ -1030,9 +1016,8 @@ mips_elf_create_procedure_table (handle, abfd, info, s, debug)
    discard them.  */
 
 static bfd_boolean
-mips_elf_check_mips16_stubs (h, data)
-     struct mips_elf_link_hash_entry *h;
-     PTR data ATTRIBUTE_UNUSED;
+mips_elf_check_mips16_stubs (struct mips_elf_link_hash_entry *h,
+                            void *data ATTRIBUTE_UNUSED)
 {
   if (h->root.root.type == bfd_link_hash_warning)
     h = (struct mips_elf_link_hash_entry *) h->root.root.u.i.link;
@@ -1043,8 +1028,7 @@ mips_elf_check_mips16_stubs (h, data)
       /* We don't need the fn_stub; the only references to this symbol
          are 16 bit calls.  Clobber the size to 0 to prevent it from
          being included in the link.  */
-      h->fn_stub->_raw_size = 0;
-      h->fn_stub->_cooked_size = 0;
+      h->fn_stub->size = 0;
       h->fn_stub->flags &= ~SEC_RELOC;
       h->fn_stub->reloc_count = 0;
       h->fn_stub->flags |= SEC_EXCLUDE;
@@ -1056,8 +1040,7 @@ mips_elf_check_mips16_stubs (h, data)
       /* We don't need the call_stub; this is a 16 bit function, so
          calls from other 16 bit functions are OK.  Clobber the size
          to 0 to prevent it from being included in the link.  */
-      h->call_stub->_raw_size = 0;
-      h->call_stub->_cooked_size = 0;
+      h->call_stub->size = 0;
       h->call_stub->flags &= ~SEC_RELOC;
       h->call_stub->reloc_count = 0;
       h->call_stub->flags |= SEC_EXCLUDE;
@@ -1069,8 +1052,7 @@ mips_elf_check_mips16_stubs (h, data)
       /* We don't need the call_stub; this is a 16 bit function, so
          calls from other 16 bit functions are OK.  Clobber the size
          to 0 to prevent it from being included in the link.  */
-      h->call_fp_stub->_raw_size = 0;
-      h->call_fp_stub->_cooked_size = 0;
+      h->call_fp_stub->size = 0;
       h->call_fp_stub->flags &= ~SEC_RELOC;
       h->call_fp_stub->reloc_count = 0;
       h->call_fp_stub->flags |= SEC_EXCLUDE;
@@ -1080,19 +1062,13 @@ mips_elf_check_mips16_stubs (h, data)
 }
 \f
 bfd_reloc_status_type
-_bfd_mips_elf_gprel16_with_gp (abfd, symbol, reloc_entry, input_section,
-                              relocateable, data, gp)
-     bfd *abfd;
-     asymbol *symbol;
-     arelent *reloc_entry;
-     asection *input_section;
-     bfd_boolean relocateable;
-     PTR data;
-     bfd_vma gp;
+_bfd_mips_elf_gprel16_with_gp (bfd *abfd, asymbol *symbol,
+                              arelent *reloc_entry, asection *input_section,
+                              bfd_boolean relocatable, void *data, bfd_vma gp)
 {
   bfd_vma relocation;
-  unsigned long insn;
-  unsigned long val;
+  bfd_signed_vma val;
+  bfd_reloc_status_type status;
 
   if (bfd_is_com_section (symbol->section))
     relocation = 0;
@@ -1102,39 +1078,225 @@ _bfd_mips_elf_gprel16_with_gp (abfd, symbol, reloc_entry, input_section,
   relocation += symbol->section->output_section->vma;
   relocation += symbol->section->output_offset;
 
-  if (reloc_entry->address > input_section->_cooked_size)
+  if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
     return bfd_reloc_outofrange;
 
-  insn = bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address);
-
   /* Set val to the offset into the section or symbol.  */
-  if (reloc_entry->howto->src_mask == 0)
-    {
-      /* This case occurs with the 64-bit MIPS ELF ABI.  */
-      val = reloc_entry->addend;
-    }
-  else
-    {
-      val = ((insn & 0xffff) + reloc_entry->addend) & 0xffff;
-      if (val & 0x8000)
-       val -= 0x10000;
-    }
+  val = reloc_entry->addend;
+
+  _bfd_mips_elf_sign_extend (val, 16);
 
   /* Adjust val for the final section location and GP value.  If we
-     are producing relocateable output, we don't want to do this for
+     are producing relocatable output, we don't want to do this for
      an external symbol.  */
-  if (! relocateable
+  if (! relocatable
       || (symbol->flags & BSF_SECTION_SYM) != 0)
     val += relocation - gp;
 
-  insn = (insn & ~0xffff) | (val & 0xffff);
-  bfd_put_32 (abfd, insn, (bfd_byte *) data + reloc_entry->address);
+  if (reloc_entry->howto->partial_inplace)
+    {
+      status = _bfd_relocate_contents (reloc_entry->howto, abfd, val,
+                                      (bfd_byte *) data
+                                      + reloc_entry->address);
+      if (status != bfd_reloc_ok)
+       return status;
+    }
+  else
+    reloc_entry->addend = val;
 
-  if (relocateable)
+  if (relocatable)
     reloc_entry->address += input_section->output_offset;
 
-  else if ((long) val >= 0x8000 || (long) val < -0x8000)
-    return bfd_reloc_overflow;
+  return bfd_reloc_ok;
+}
+
+/* Used to store a REL high-part relocation such as R_MIPS_HI16 or
+   R_MIPS_GOT16.  REL is the relocation, INPUT_SECTION is the section
+   that contains the relocation field and DATA points to the start of
+   INPUT_SECTION.  */
+
+struct mips_hi16
+{
+  struct mips_hi16 *next;
+  bfd_byte *data;
+  asection *input_section;
+  arelent rel;
+};
+
+/* FIXME: This should not be a static variable.  */
+
+static struct mips_hi16 *mips_hi16_list;
+
+/* A howto special_function for REL *HI16 relocations.  We can only
+   calculate the correct value once we've seen the partnering
+   *LO16 relocation, so just save the information for later.
+
+   The ABI requires that the *LO16 immediately follow the *HI16.
+   However, as a GNU extension, we permit an arbitrary number of
+   *HI16s to be associated with a single *LO16.  This significantly
+   simplies the relocation handling in gcc.  */
+
+bfd_reloc_status_type
+_bfd_mips_elf_hi16_reloc (bfd *abfd ATTRIBUTE_UNUSED, arelent *reloc_entry,
+                         asymbol *symbol ATTRIBUTE_UNUSED, void *data,
+                         asection *input_section, bfd *output_bfd,
+                         char **error_message ATTRIBUTE_UNUSED)
+{
+  struct mips_hi16 *n;
+
+  if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
+    return bfd_reloc_outofrange;
+
+  n = bfd_malloc (sizeof *n);
+  if (n == NULL)
+    return bfd_reloc_outofrange;
+
+  n->next = mips_hi16_list;
+  n->data = data;
+  n->input_section = input_section;
+  n->rel = *reloc_entry;
+  mips_hi16_list = n;
+
+  if (output_bfd != NULL)
+    reloc_entry->address += input_section->output_offset;
+
+  return bfd_reloc_ok;
+}
+
+/* A howto special_function for REL R_MIPS_GOT16 relocations.  This is just
+   like any other 16-bit relocation when applied to global symbols, but is
+   treated in the same as R_MIPS_HI16 when applied to local symbols.  */
+
+bfd_reloc_status_type
+_bfd_mips_elf_got16_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
+                          void *data, asection *input_section,
+                          bfd *output_bfd, char **error_message)
+{
+  if ((symbol->flags & (BSF_GLOBAL | BSF_WEAK)) != 0
+      || bfd_is_und_section (bfd_get_section (symbol))
+      || bfd_is_com_section (bfd_get_section (symbol)))
+    /* The relocation is against a global symbol.  */
+    return _bfd_mips_elf_generic_reloc (abfd, reloc_entry, symbol, data,
+                                       input_section, output_bfd,
+                                       error_message);
+
+  return _bfd_mips_elf_hi16_reloc (abfd, reloc_entry, symbol, data,
+                                  input_section, output_bfd, error_message);
+}
+
+/* A howto special_function for REL *LO16 relocations.  The *LO16 itself
+   is a straightforward 16 bit inplace relocation, but we must deal with
+   any partnering high-part relocations as well.  */
+
+bfd_reloc_status_type
+_bfd_mips_elf_lo16_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
+                         void *data, asection *input_section,
+                         bfd *output_bfd, char **error_message)
+{
+  bfd_vma vallo;
+
+  if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
+    return bfd_reloc_outofrange;
+
+  vallo = bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address);
+  while (mips_hi16_list != NULL)
+    {
+      bfd_reloc_status_type ret;
+      struct mips_hi16 *hi;
+
+      hi = mips_hi16_list;
+
+      /* R_MIPS_GOT16 relocations are something of a special case.  We
+        want to install the addend in the same way as for a R_MIPS_HI16
+        relocation (with a rightshift of 16).  However, since GOT16
+        relocations can also be used with global symbols, their howto
+        has a rightshift of 0.  */
+      if (hi->rel.howto->type == R_MIPS_GOT16)
+       hi->rel.howto = MIPS_ELF_RTYPE_TO_HOWTO (abfd, R_MIPS_HI16, FALSE);
+
+      /* VALLO is a signed 16-bit number.  Bias it by 0x8000 so that any
+        carry or borrow will induce a change of +1 or -1 in the high part.  */
+      hi->rel.addend += (vallo + 0x8000) & 0xffff;
+
+      ret = _bfd_mips_elf_generic_reloc (abfd, &hi->rel, symbol, hi->data,
+                                        hi->input_section, output_bfd,
+                                        error_message);
+      if (ret != bfd_reloc_ok)
+       return ret;
+
+      mips_hi16_list = hi->next;
+      free (hi);
+    }
+
+  return _bfd_mips_elf_generic_reloc (abfd, reloc_entry, symbol, data,
+                                     input_section, output_bfd,
+                                     error_message);
+}
+
+/* A generic howto special_function.  This calculates and installs the
+   relocation itself, thus avoiding the oft-discussed problems in
+   bfd_perform_relocation and bfd_install_relocation.  */
+
+bfd_reloc_status_type
+_bfd_mips_elf_generic_reloc (bfd *abfd ATTRIBUTE_UNUSED, arelent *reloc_entry,
+                            asymbol *symbol, void *data ATTRIBUTE_UNUSED,
+                            asection *input_section, bfd *output_bfd,
+                            char **error_message ATTRIBUTE_UNUSED)
+{
+  bfd_signed_vma val;
+  bfd_reloc_status_type status;
+  bfd_boolean relocatable;
+
+  relocatable = (output_bfd != NULL);
+
+  if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
+    return bfd_reloc_outofrange;
+
+  /* Build up the field adjustment in VAL.  */
+  val = 0;
+  if (!relocatable || (symbol->flags & BSF_SECTION_SYM) != 0)
+    {
+      /* Either we're calculating the final field value or we have a
+        relocation against a section symbol.  Add in the section's
+        offset or address.  */
+      val += symbol->section->output_section->vma;
+      val += symbol->section->output_offset;
+    }
+
+  if (!relocatable)
+    {
+      /* We're calculating the final field value.  Add in the symbol's value
+        and, if pc-relative, subtract the address of the field itself.  */
+      val += symbol->value;
+      if (reloc_entry->howto->pc_relative)
+       {
+         val -= input_section->output_section->vma;
+         val -= input_section->output_offset;
+         val -= reloc_entry->address;
+       }
+    }
+
+  /* VAL is now the final adjustment.  If we're keeping this relocation
+     in the output file, and if the relocation uses a separate addend,
+     we just need to add VAL to that addend.  Otherwise we need to add
+     VAL to the relocation field itself.  */
+  if (relocatable && !reloc_entry->howto->partial_inplace)
+    reloc_entry->addend += val;
+  else
+    {
+      /* Add in the separate addend, if any.  */
+      val += reloc_entry->addend;
+
+      /* Add VAL to the relocation field.  */
+      status = _bfd_relocate_contents (reloc_entry->howto, abfd, val,
+                                      (bfd_byte *) data
+                                      + reloc_entry->address);
+      if (status != bfd_reloc_ok)
+       return status;
+    }
+
+  if (relocatable)
+    reloc_entry->address += input_section->output_offset;
 
   return bfd_reloc_ok;
 }
@@ -1143,30 +1305,24 @@ _bfd_mips_elf_gprel16_with_gp (abfd, symbol, reloc_entry, input_section,
    on the equivalence of the two elements of the union.  */
 
 static void
-bfd_mips_elf32_swap_gptab_in (abfd, ex, in)
-     bfd *abfd;
-     const Elf32_External_gptab *ex;
-     Elf32_gptab *in;
+bfd_mips_elf32_swap_gptab_in (bfd *abfd, const Elf32_External_gptab *ex,
+                             Elf32_gptab *in)
 {
   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
-bfd_mips_elf32_swap_gptab_out (abfd, in, ex)
-     bfd *abfd;
-     const Elf32_gptab *in;
-     Elf32_External_gptab *ex;
+bfd_mips_elf32_swap_gptab_out (bfd *abfd, const Elf32_gptab *in,
+                              Elf32_External_gptab *ex)
 {
   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
-bfd_elf32_swap_compact_rel_out (abfd, in, ex)
-     bfd *abfd;
-     const Elf32_compact_rel *in;
-     Elf32_External_compact_rel *ex;
+bfd_elf32_swap_compact_rel_out (bfd *abfd, const Elf32_compact_rel *in,
+                               Elf32_External_compact_rel *ex)
 {
   H_PUT_32 (abfd, in->id1, ex->id1);
   H_PUT_32 (abfd, in->num, ex->num);
@@ -1177,10 +1333,8 @@ bfd_elf32_swap_compact_rel_out (abfd, in, ex)
 }
 
 static void
-bfd_elf32_swap_crinfo_out (abfd, in, ex)
-     bfd *abfd;
-     const Elf32_crinfo *in;
-     Elf32_External_crinfo *ex;
+bfd_elf32_swap_crinfo_out (bfd *abfd, const Elf32_crinfo *in,
+                          Elf32_External_crinfo *ex)
 {
   unsigned long l;
 
@@ -1192,41 +1346,14 @@ bfd_elf32_swap_crinfo_out (abfd, in, ex)
   H_PUT_32 (abfd, in->konst, ex->konst);
   H_PUT_32 (abfd, in->vaddr, ex->vaddr);
 }
-
-#if 0
-/* Swap in an MSYM entry.  */
-
-static void
-bfd_mips_elf_swap_msym_in (abfd, ex, in)
-     bfd *abfd;
-     const Elf32_External_Msym *ex;
-     Elf32_Internal_Msym *in;
-{
-  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.  */
-
-static void
-bfd_mips_elf_swap_msym_out (abfd, in, ex)
-     bfd *abfd;
-     const Elf32_Internal_Msym *in;
-     Elf32_External_Msym *ex;
-{
-  H_PUT_32 (abfd, in->ms_hash_value, ex->ms_hash_value);
-  H_PUT_32 (abfd, in->ms_info, ex->ms_info);
-}
 \f
 /* A .reginfo section holds a single Elf32_RegInfo structure.  These
    routines swap this structure in and out.  They are used outside of
    BFD, so they are globally visible.  */
 
 void
-bfd_mips_elf32_swap_reginfo_in (abfd, ex, in)
-     bfd *abfd;
-     const Elf32_External_RegInfo *ex;
-     Elf32_RegInfo *in;
+bfd_mips_elf32_swap_reginfo_in (bfd *abfd, const Elf32_External_RegInfo *ex,
+                               Elf32_RegInfo *in)
 {
   in->ri_gprmask = H_GET_32 (abfd, ex->ri_gprmask);
   in->ri_cprmask[0] = H_GET_32 (abfd, ex->ri_cprmask[0]);
@@ -1237,10 +1364,8 @@ bfd_mips_elf32_swap_reginfo_in (abfd, ex, in)
 }
 
 void
-bfd_mips_elf32_swap_reginfo_out (abfd, in, ex)
-     bfd *abfd;
-     const Elf32_RegInfo *in;
-     Elf32_External_RegInfo *ex;
+bfd_mips_elf32_swap_reginfo_out (bfd *abfd, const Elf32_RegInfo *in,
+                                Elf32_External_RegInfo *ex)
 {
   H_PUT_32 (abfd, in->ri_gprmask, ex->ri_gprmask);
   H_PUT_32 (abfd, in->ri_cprmask[0], ex->ri_cprmask[0]);
@@ -1257,10 +1382,8 @@ bfd_mips_elf32_swap_reginfo_out (abfd, in, ex)
    without worrying about whether the 64 bit ABI has been included.  */
 
 void
-bfd_mips_elf64_swap_reginfo_in (abfd, ex, in)
-     bfd *abfd;
-     const Elf64_External_RegInfo *ex;
-     Elf64_Internal_RegInfo *in;
+bfd_mips_elf64_swap_reginfo_in (bfd *abfd, const Elf64_External_RegInfo *ex,
+                               Elf64_Internal_RegInfo *in)
 {
   in->ri_gprmask = H_GET_32 (abfd, ex->ri_gprmask);
   in->ri_pad = H_GET_32 (abfd, ex->ri_pad);
@@ -1272,10 +1395,8 @@ bfd_mips_elf64_swap_reginfo_in (abfd, ex, in)
 }
 
 void
-bfd_mips_elf64_swap_reginfo_out (abfd, in, ex)
-     bfd *abfd;
-     const Elf64_Internal_RegInfo *in;
-     Elf64_External_RegInfo *ex;
+bfd_mips_elf64_swap_reginfo_out (bfd *abfd, const Elf64_Internal_RegInfo *in,
+                                Elf64_External_RegInfo *ex)
 {
   H_PUT_32 (abfd, in->ri_gprmask, ex->ri_gprmask);
   H_PUT_32 (abfd, in->ri_pad, ex->ri_pad);
@@ -1289,10 +1410,8 @@ bfd_mips_elf64_swap_reginfo_out (abfd, in, ex)
 /* Swap in an options header.  */
 
 void
-bfd_mips_elf_swap_options_in (abfd, ex, in)
-     bfd *abfd;
-     const Elf_External_Options *ex;
-     Elf_Internal_Options *in;
+bfd_mips_elf_swap_options_in (bfd *abfd, const Elf_External_Options *ex,
+                             Elf_Internal_Options *in)
 {
   in->kind = H_GET_8 (abfd, ex->kind);
   in->size = H_GET_8 (abfd, ex->size);
@@ -1303,10 +1422,8 @@ bfd_mips_elf_swap_options_in (abfd, ex, in)
 /* Swap out an options header.  */
 
 void
-bfd_mips_elf_swap_options_out (abfd, in, ex)
-     bfd *abfd;
-     const Elf_Internal_Options *in;
-     Elf_External_Options *ex;
+bfd_mips_elf_swap_options_out (bfd *abfd, const Elf_Internal_Options *in,
+                              Elf_External_Options *ex)
 {
   H_PUT_8 (abfd, in->kind, ex->kind);
   H_PUT_8 (abfd, in->size, ex->size);
@@ -1318,9 +1435,7 @@ bfd_mips_elf_swap_options_out (abfd, in, ex)
    entries by increasing r_symndx value.  */
 
 static int
-sort_dynamic_relocs (arg1, arg2)
-     const PTR arg1;
-     const PTR arg2;
+sort_dynamic_relocs (const void *arg1, const void *arg2)
 {
   Elf_Internal_Rela int_reloc1;
   Elf_Internal_Rela int_reloc2;
@@ -1334,9 +1449,7 @@ sort_dynamic_relocs (arg1, arg2)
 /* Like sort_dynamic_relocs, but used for elf64 relocations.  */
 
 static int
-sort_dynamic_relocs_64 (arg1, arg2)
-     const PTR arg1;
-     const PTR arg2;
+sort_dynamic_relocs_64 (const void *arg1, const void *arg2)
 {
   Elf_Internal_Rela int_reloc1[3];
   Elf_Internal_Rela int_reloc2[3];
@@ -1366,11 +1479,9 @@ sort_dynamic_relocs_64 (arg1, arg2)
    when generating a final executable.  */
 
 static bfd_boolean
-mips_elf_output_extsym (h, data)
-     struct mips_elf_link_hash_entry *h;
-     PTR data;
+mips_elf_output_extsym (struct mips_elf_link_hash_entry *h, void *data)
 {
-  struct extsym_info *einfo = (struct extsym_info *) data;
+  struct extsym_info *einfo = data;
   bfd_boolean strip;
   asection *sec, *output_section;
 
@@ -1548,12 +1659,10 @@ mips_elf_output_extsym (h, data)
 /* A comparison routine used to sort .gptab entries.  */
 
 static int
-gptab_compare (p1, p2)
-     const PTR p1;
-     const PTR p2;
+gptab_compare (const void *p1, const void *p2)
 {
-  const Elf32_gptab *a1 = (const Elf32_gptab *) p1;
-  const Elf32_gptab *a2 = (const Elf32_gptab *) p2;
+  const Elf32_gptab *a1 = p1;
+  const Elf32_gptab *a2 = p2;
 
   return a1->gt_entry.gt_g_value - a2->gt_entry.gt_g_value;
 }
@@ -1564,8 +1673,7 @@ gptab_compare (p1, p2)
    hash number.  */
 
 static INLINE hashval_t
-mips_elf_hash_bfd_vma (addr)
-     bfd_vma addr;
+mips_elf_hash_bfd_vma (bfd_vma addr)
 {
 #ifdef BFD64
   return addr + (addr >> 32);
@@ -1579,8 +1687,7 @@ mips_elf_hash_bfd_vma (addr)
    union members.  */
 
 static hashval_t
-mips_elf_got_entry_hash (entry_)
-     const PTR entry_;
+mips_elf_got_entry_hash (const void *entry_)
 {
   const struct mips_got_entry *entry = (struct mips_got_entry *)entry_;
 
@@ -1592,9 +1699,7 @@ mips_elf_got_entry_hash (entry_)
 }
 
 static int
-mips_elf_got_entry_eq (entry1, entry2)
-     const PTR entry1;
-     const PTR entry2;
+mips_elf_got_entry_eq (const void *entry1, const void *entry2)
 {
   const struct mips_got_entry *e1 = (struct mips_got_entry *)entry1;
   const struct mips_got_entry *e2 = (struct mips_got_entry *)entry2;
@@ -1611,8 +1716,7 @@ mips_elf_got_entry_eq (entry1, entry2)
    accordingly.  */
 
 static hashval_t
-mips_elf_multi_got_entry_hash (entry_)
-     const PTR entry_;
+mips_elf_multi_got_entry_hash (const void *entry_)
 {
   const struct mips_got_entry *entry = (struct mips_got_entry *)entry_;
 
@@ -1626,9 +1730,7 @@ mips_elf_multi_got_entry_hash (entry_)
 }
 
 static int
-mips_elf_multi_got_entry_eq (entry1, entry2)
-     const PTR entry1;
-     const PTR entry2;
+mips_elf_multi_got_entry_eq (const void *entry1, const void *entry2)
 {
   const struct mips_got_entry *e1 = (struct mips_got_entry *)entry1;
   const struct mips_got_entry *e2 = (struct mips_got_entry *)entry2;
@@ -1643,9 +1745,7 @@ mips_elf_multi_got_entry_eq (entry1, entry2)
 /* Returns the dynamic relocation section for DYNOBJ.  */
 
 static asection *
-mips_elf_rel_dyn_section (dynobj, create_p)
-     bfd *dynobj;
-     bfd_boolean create_p;
+mips_elf_rel_dyn_section (bfd *dynobj, bfd_boolean create_p)
 {
   static const char dname[] = ".rel.dyn";
   asection *sreloc;
@@ -1663,7 +1763,7 @@ mips_elf_rel_dyn_section (dynobj, create_p)
                                       | SEC_LINKER_CREATED
                                       | SEC_READONLY))
          || ! bfd_set_section_alignment (dynobj, sreloc,
-                                         4))
+                                         MIPS_ELF_LOG_FILE_ALIGN (dynobj)))
        return NULL;
     }
   return sreloc;
@@ -1672,9 +1772,7 @@ mips_elf_rel_dyn_section (dynobj, create_p)
 /* Returns the GOT section for ABFD.  */
 
 static asection *
-mips_elf_got_section (abfd, maybe_excluded)
-     bfd *abfd;
-     bfd_boolean maybe_excluded;
+mips_elf_got_section (bfd *abfd, bfd_boolean maybe_excluded)
 {
   asection *sgot = bfd_get_section_by_name (abfd, ".got");
   if (sgot == NULL
@@ -1688,9 +1786,7 @@ mips_elf_got_section (abfd, maybe_excluded)
    section.  */
 
 static struct mips_got_info *
-mips_elf_got_info (abfd, sgotp)
-     bfd *abfd;
-     asection **sgotp;
+mips_elf_got_info (bfd *abfd, asection **sgotp)
 {
   asection *sgot;
   struct mips_got_info *g;
@@ -1707,38 +1803,13 @@ mips_elf_got_info (abfd, sgotp)
   return g;
 }
 
-/* Obtain the lowest dynamic index of a symbol that was assigned a
-   global GOT entry.  */
-static long
-mips_elf_get_global_gotsym_index (abfd)
-     bfd *abfd;
-{
-  asection *sgot;
-  struct mips_got_info *g;
-
-  if (abfd == NULL)
-    return 0;
-
-  sgot = mips_elf_got_section (abfd, TRUE);
-  if (sgot == NULL || mips_elf_section_data (sgot) == NULL)
-    return 0;
-
-  g = mips_elf_section_data (sgot)->u.got_info;
-  if (g == NULL || g->global_gotsym == NULL)
-    return 0;
-
-  return g->global_gotsym->dynindx;
-}
-
 /* Returns the GOT offset at which the indicated address can be found.
    If there is not yet a GOT entry for this value, create one.  Returns
    -1 if no satisfactory GOT offset can be found.  */
 
 static bfd_vma
-mips_elf_local_got_index (abfd, ibfd, info, value)
-     bfd *abfd, *ibfd;
-     struct bfd_link_info *info;
-     bfd_vma value;
+mips_elf_local_got_index (bfd *abfd, bfd *ibfd, struct bfd_link_info *info,
+                         bfd_vma value)
 {
   asection *sgot;
   struct mips_got_info *g;
@@ -1756,9 +1827,7 @@ mips_elf_local_got_index (abfd, ibfd, info, value)
 /* Returns the GOT index for the global symbol indicated by H.  */
 
 static bfd_vma
-mips_elf_global_got_index (abfd, ibfd, h)
-     bfd *abfd, *ibfd;
-     struct elf_link_hash_entry *h;
+mips_elf_global_got_index (bfd *abfd, bfd *ibfd, struct elf_link_hash_entry *h)
 {
   bfd_vma index;
   asection *sgot;
@@ -1779,7 +1848,7 @@ mips_elf_global_got_index (abfd, ibfd, h)
          e.symndx = -1;
          e.d.h = (struct mips_elf_link_hash_entry *)h;
 
-         p = (struct mips_got_entry *) htab_find (g->got_entries, &e);
+         p = htab_find (g->got_entries, &e);
 
          BFD_ASSERT (p->gotidx > 0);
          return p->gotidx;
@@ -1796,7 +1865,7 @@ mips_elf_global_got_index (abfd, ibfd, h)
   BFD_ASSERT (h->dynindx >= global_got_dynindx);
   index = ((h->dynindx - global_got_dynindx + g->local_gotno)
           * MIPS_ELF_GOT_SIZE (abfd));
-  BFD_ASSERT (index < sgot->_raw_size);
+  BFD_ASSERT (index < sgot->size);
 
   return index;
 }
@@ -1808,11 +1877,8 @@ mips_elf_global_got_index (abfd, ibfd, h)
    OFFSETP, if it is non-NULL.  */
 
 static bfd_vma
-mips_elf_got_page (abfd, ibfd, info, value, offsetp)
-     bfd *abfd, *ibfd;
-     struct bfd_link_info *info;
-     bfd_vma value;
-     bfd_vma *offsetp;
+mips_elf_got_page (bfd *abfd, bfd *ibfd, struct bfd_link_info *info,
+                  bfd_vma value, bfd_vma *offsetp)
 {
   asection *sgot;
   struct mips_got_info *g;
@@ -1840,11 +1906,8 @@ mips_elf_got_page (abfd, ibfd, info, value, offsetp)
    for value.  Return the index into the GOT for this entry.  */
 
 static bfd_vma
-mips_elf_got16_entry (abfd, ibfd, info, value, external)
-     bfd *abfd, *ibfd;
-     struct bfd_link_info *info;
-     bfd_vma value;
-     bfd_boolean external;
+mips_elf_got16_entry (bfd *abfd, bfd *ibfd, struct bfd_link_info *info,
+                     bfd_vma value, bfd_boolean external)
 {
   asection *sgot;
   struct mips_got_info *g;
@@ -1872,11 +1935,8 @@ mips_elf_got16_entry (abfd, ibfd, info, value, external)
    in the GOT.  */
 
 static bfd_vma
-mips_elf_got_offset_from_index (dynobj, output_bfd, input_bfd, index)
-     bfd *dynobj;
-     bfd *output_bfd;
-     bfd *input_bfd;
-     bfd_vma index;
+mips_elf_got_offset_from_index (bfd *dynobj, bfd *output_bfd,
+                               bfd *input_bfd, bfd_vma index)
 {
   asection *sgot;
   bfd_vma gp;
@@ -1893,11 +1953,9 @@ mips_elf_got_offset_from_index (dynobj, output_bfd, input_bfd, index)
    or -1 if it could not be created.  */
 
 static struct mips_got_entry *
-mips_elf_create_local_got_entry (abfd, ibfd, gg, sgot, value)
-     bfd *abfd, *ibfd;
-     struct mips_got_info *gg;
-     asection *sgot;
-     bfd_vma value;
+mips_elf_create_local_got_entry (bfd *abfd, bfd *ibfd,
+                                struct mips_got_info *gg,
+                                asection *sgot, bfd_vma value)
 {
   struct mips_got_entry entry, **loc;
   struct mips_got_info *g;
@@ -1951,9 +2009,7 @@ mips_elf_create_local_got_entry (abfd, ibfd, gg, sgot, value)
    section symbols are added and the count is higher.  */
 
 static bfd_boolean
-mips_elf_sort_hash_table (info, max_local)
-     struct bfd_link_info *info;
-     unsigned long max_local;
+mips_elf_sort_hash_table (struct bfd_link_info *info, unsigned long max_local)
 {
   struct mips_elf_hash_sort_data hsd;
   struct mips_got_info *g;
@@ -1998,12 +2054,9 @@ mips_elf_sort_hash_table (info, max_local)
    index.  */
 
 static bfd_boolean
-mips_elf_sort_hash_table_f (h, data)
-     struct mips_elf_link_hash_entry *h;
-     PTR data;
+mips_elf_sort_hash_table_f (struct mips_elf_link_hash_entry *h, void *data)
 {
-  struct mips_elf_hash_sort_data *hsd
-    = (struct mips_elf_hash_sort_data *) data;
+  struct mips_elf_hash_sort_data *hsd = data;
 
   if (h->root.root.type == bfd_link_hash_warning)
     h = (struct mips_elf_link_hash_entry *) h->root.root.u.i.link;
@@ -2039,11 +2092,9 @@ mips_elf_sort_hash_table_f (h, data)
    posterity.  */
 
 static bfd_boolean
-mips_elf_record_global_got_symbol (h, abfd, info, g)
-     struct elf_link_hash_entry *h;
-     bfd *abfd;
-     struct bfd_link_info *info;
-     struct mips_got_info *g;
+mips_elf_record_global_got_symbol (struct elf_link_hash_entry *h,
+                                  bfd *abfd, struct bfd_link_info *info,
+                                  struct mips_got_info *g)
 {
   struct mips_got_entry entry, **loc;
 
@@ -2058,7 +2109,7 @@ mips_elf_record_global_got_symbol (h, abfd, info, g)
          _bfd_mips_elf_hide_symbol (info, h, TRUE);
          break;
        }
-      if (!bfd_elf32_link_record_dynamic_symbol (info, h))
+      if (!bfd_elf_link_record_dynamic_symbol (info, h))
        return FALSE;
     }
 
@@ -2097,11 +2148,8 @@ mips_elf_record_global_got_symbol (h, abfd, info, g)
    SYMNDX in input bfd ABDF, plus ADDEND.  */
 
 static bfd_boolean
-mips_elf_record_local_got_symbol (abfd, symndx, addend, g)
-     bfd *abfd;
-     long symndx;
-     bfd_vma addend;
-     struct mips_got_info *g;
+mips_elf_record_local_got_symbol (bfd *abfd, long symndx, bfd_vma addend,
+                                 struct mips_got_info *g)
 {
   struct mips_got_entry entry, **loc;
 
@@ -2129,8 +2177,7 @@ mips_elf_record_local_got_symbol (abfd, symndx, addend, g)
 /* Compute the hash value of the bfd in a bfd2got hash entry.  */
 
 static hashval_t
-mips_elf_bfd2got_entry_hash (entry_)
-     const PTR entry_;
+mips_elf_bfd2got_entry_hash (const void *entry_)
 {
   const struct mips_elf_bfd2got_hash *entry
     = (struct mips_elf_bfd2got_hash *)entry_;
@@ -2141,9 +2188,7 @@ mips_elf_bfd2got_entry_hash (entry_)
 /* Check whether two hash entries have the same bfd.  */
 
 static int
-mips_elf_bfd2got_entry_eq (entry1, entry2)
-     const PTR entry1;
-     const PTR entry2;
+mips_elf_bfd2got_entry_eq (const void *entry1, const void *entry2)
 {
   const struct mips_elf_bfd2got_hash *e1
     = (const struct mips_elf_bfd2got_hash *)entry1;
@@ -2157,9 +2202,7 @@ mips_elf_bfd2got_entry_eq (entry1, entry2)
    be the master GOT data.  */
 
 static struct mips_got_info *
-mips_elf_got_for_ibfd (g, ibfd)
-     struct mips_got_info *g;
-     bfd *ibfd;
+mips_elf_got_for_ibfd (struct mips_got_info *g, bfd *ibfd)
 {
   struct mips_elf_bfd2got_hash e, *p;
 
@@ -2167,7 +2210,7 @@ mips_elf_got_for_ibfd (g, ibfd)
     return g;
 
   e.bfd = ibfd;
-  p = (struct mips_elf_bfd2got_hash *) htab_find (g->bfd2got, &e);
+  p = htab_find (g->bfd2got, &e);
   return p ? p->g : NULL;
 }
 
@@ -2176,9 +2219,7 @@ mips_elf_got_for_ibfd (g, ibfd)
    bfd requires.  */
 
 static int
-mips_elf_make_got_per_bfd (entryp, p)
-     void **entryp;
-     void *p;
+mips_elf_make_got_per_bfd (void **entryp, void *p)
 {
   struct mips_got_entry *entry = (struct mips_got_entry *)*entryp;
   struct mips_elf_got_per_bfd_arg *arg = (struct mips_elf_got_per_bfd_arg *)p;
@@ -2222,8 +2263,7 @@ mips_elf_make_got_per_bfd (entryp, p)
       g->local_gotno = 0;
       g->assigned_gotno = -1;
       g->got_entries = htab_try_create (1, mips_elf_multi_got_entry_hash,
-                                       mips_elf_multi_got_entry_eq,
-                                       (htab_del) NULL);
+                                       mips_elf_multi_got_entry_eq, NULL);
       if (g->got_entries == NULL)
        {
          arg->obfd = 0;
@@ -2257,9 +2297,7 @@ mips_elf_make_got_per_bfd (entryp, p)
    and then make make the new got current.  */
 
 static int
-mips_elf_merge_gots (bfd2got_, p)
-     void **bfd2got_;
-     void *p;
+mips_elf_merge_gots (void **bfd2got_, void *p)
 {
   struct mips_elf_bfd2got_hash *bfd2got
     = (struct mips_elf_bfd2got_hash *)*bfd2got_;
@@ -2298,7 +2336,7 @@ mips_elf_merge_gots (bfd2got_, p)
         got entries, since they're all in the master got_entries hash
         table anyway.  */
 
-      BFD_ASSERT (old_lcount + lcount == arg->primary->local_gotno);
+      BFD_ASSERT (old_lcount + lcount >= arg->primary->local_gotno);
       BFD_ASSERT (old_gcount + gcount >= arg->primary->global_gotno);
 
       arg->primary_count = arg->primary->local_gotno
@@ -2322,7 +2360,7 @@ mips_elf_merge_gots (bfd2got_, p)
 
       htab_delete (g->got_entries);
 
-      BFD_ASSERT (old_lcount + lcount == arg->current->local_gotno);
+      BFD_ASSERT (old_lcount + lcount >= arg->current->local_gotno);
       BFD_ASSERT (old_gcount + gcount >= arg->current->global_gotno);
 
       arg->current_count = arg->current->local_gotno
@@ -2353,12 +2391,10 @@ mips_elf_merge_gots (bfd2got_, p)
    first available global GOT entry in G.  VALUE must contain the size
    of a GOT entry in bytes.  For each global GOT entry that requires a
    dynamic relocation, NEEDED_RELOCS is incremented, and the symbol is
-   marked as not elligible for lazy resolution through a function
+   marked as not eligible for lazy resolution through a function
    stub.  */
 static int
-mips_elf_set_global_got_offset (entryp, p)
-     void **entryp;
-     void *p;
+mips_elf_set_global_got_offset (void **entryp, void *p)
 {
   struct mips_got_entry *entry = (struct mips_got_entry *)*entryp;
   struct mips_elf_set_global_got_offset_arg *arg
@@ -2373,10 +2409,6 @@ mips_elf_set_global_got_offset (entryp, p)
          BFD_ASSERT (g->global_gotsym == NULL);
 
          entry->gotidx = arg->value * (long) g->assigned_gotno++;
-         /* We can't do lazy update of GOT entries for
-            non-primary GOTs since the PLT entries don't use the
-            right offsets, so punt at it for now.  */
-         entry->d.h->no_fn_stub = TRUE;
          if (arg->info->shared
              || (elf_hash_table (arg->info)->dynamic_sections_created
                  && ((entry->d.h->root.elf_link_hash_flags
@@ -2392,6 +2424,21 @@ mips_elf_set_global_got_offset (entryp, p)
   return 1;
 }
 
+/* Mark any global symbols referenced in the GOT we are iterating over
+   as inelligible for lazy resolution stubs.  */
+static int
+mips_elf_set_no_stub (void **entryp, void *p ATTRIBUTE_UNUSED)
+{
+  struct mips_got_entry *entry = (struct mips_got_entry *)*entryp;
+
+  if (entry->abfd != NULL
+      && entry->symndx == -1
+      && entry->d.h->root.dynindx != -1)
+    entry->d.h->no_fn_stub = TRUE;
+
+  return 1;
+}
+
 /* Follow indirect and warning hash entries so that each got entry
    points to the final symbol definition.  P must point to a pointer
    to the hash table we're traversing.  Since this traversal may
@@ -2399,9 +2446,7 @@ mips_elf_set_global_got_offset (entryp, p)
    we've made a potentially-destructive change to the hash table, so
    the traversal must be restarted.  */
 static int
-mips_elf_resolve_final_got_entry (entryp, p)
-     void **entryp;
-     void *p;
+mips_elf_resolve_final_got_entry (void **entryp, void *p)
 {
   struct mips_got_entry *entry = (struct mips_got_entry *)*entryp;
   htab_t got_entries = *(htab_t *)p;
@@ -2443,8 +2488,7 @@ mips_elf_resolve_final_got_entry (entryp, p)
 /* Turn indirect got entries in a got_entries table into their final
    locations.  */
 static void
-mips_elf_resolve_final_got_entries (g)
-     struct mips_got_info *g;
+mips_elf_resolve_final_got_entries (struct mips_got_info *g)
 {
   htab_t got_entries;
 
@@ -2462,10 +2506,7 @@ mips_elf_resolve_final_got_entries (g)
 /* Return the offset of an input bfd IBFD's GOT from the beginning of
    the primary GOT.  */
 static bfd_vma
-mips_elf_adjust_gp (abfd, g, ibfd)
-     bfd *abfd;
-     struct mips_got_info *g;
-     bfd *ibfd;
+mips_elf_adjust_gp (bfd *abfd, struct mips_got_info *g, bfd *ibfd)
 {
   if (g->bfd2got == NULL)
     return 0;
@@ -2485,12 +2526,9 @@ mips_elf_adjust_gp (abfd, g, ibfd)
    a sequence of GOTs, each one 16-bit addressable.  */
 
 static bfd_boolean
-mips_elf_multi_got (abfd, info, g, got, pages)
-     bfd *abfd;
-     struct bfd_link_info *info;
-     struct mips_got_info *g;
-     asection *got;
-     bfd_size_type pages;
+mips_elf_multi_got (bfd *abfd, struct bfd_link_info *info,
+                   struct mips_got_info *g, asection *got,
+                   bfd_size_type pages)
 {
   struct mips_elf_got_per_bfd_arg got_per_bfd_arg;
   struct mips_elf_set_global_got_offset_arg set_got_offset_arg;
@@ -2498,8 +2536,7 @@ mips_elf_multi_got (abfd, info, g, got, pages)
   unsigned int assign;
 
   g->bfd2got = htab_try_create (1, mips_elf_bfd2got_entry_hash,
-                               mips_elf_bfd2got_entry_eq,
-                               (htab_del) NULL);
+                               mips_elf_bfd2got_entry_eq, NULL);
   if (g->bfd2got == NULL)
     return FALSE;
 
@@ -2544,7 +2581,7 @@ mips_elf_multi_got (abfd, info, g, got, pages)
       g->next->assigned_gotno = 0;
       g->next->got_entries = htab_try_create (1, mips_elf_multi_got_entry_hash,
                                              mips_elf_multi_got_entry_eq,
-                                             (htab_del) NULL);
+                                             NULL);
       if (g->next->got_entries == NULL)
        return FALSE;
       g->next->bfd2got = NULL;
@@ -2659,10 +2696,15 @@ mips_elf_multi_got (abfd, info, g, got, pages)
       g->next = gg->next;
       gg->next = g;
       g = gn;
+
+      /* Mark global symbols in every non-primary GOT as ineligible for
+        stubs.  */
+      if (g)
+       htab_traverse (g->got_entries, mips_elf_set_no_stub, NULL);
     }
   while (g);
 
-  got->_raw_size = (gg->next->local_gotno
+  got->size = (gg->next->local_gotno
                    + gg->next->global_gotno) * MIPS_ELF_GOT_SIZE (abfd);
 
   return TRUE;
@@ -2673,18 +2715,10 @@ mips_elf_multi_got (abfd, info, g, got, pages)
    RELOCATION.  RELEND is one-past-the-end of the relocation table.  */
 
 static const Elf_Internal_Rela *
-mips_elf_next_relocation (abfd, r_type, relocation, relend)
-     bfd *abfd ATTRIBUTE_UNUSED;
-     unsigned int r_type;
-     const Elf_Internal_Rela *relocation;
-     const Elf_Internal_Rela *relend;
-{
-  /* According to the MIPS ELF ABI, the R_MIPS_LO16 relocation must be
-     immediately following.  However, for the IRIX6 ABI, the next
-     relocation may be a composed relocation consisting of several
-     relocations for the same address.  In that case, the R_MIPS_LO16
-     relocation may occur as one of these.  We permit a similar
-     extension in general, as that is useful for GCC.  */
+mips_elf_next_relocation (bfd *abfd ATTRIBUTE_UNUSED, unsigned int r_type,
+                         const Elf_Internal_Rela *relocation,
+                         const Elf_Internal_Rela *relend)
+{
   while (relocation < relend)
     {
       if (ELF_R_TYPE (abfd, relocation->r_info) == r_type)
@@ -2701,12 +2735,10 @@ mips_elf_next_relocation (abfd, r_type, relocation, relend)
 /* Return whether a relocation is against a local symbol.  */
 
 static bfd_boolean
-mips_elf_local_relocation_p (input_bfd, relocation, local_sections,
-                            check_forced)
-     bfd *input_bfd;
-     const Elf_Internal_Rela *relocation;
-     asection **local_sections;
-     bfd_boolean check_forced;
+mips_elf_local_relocation_p (bfd *input_bfd,
+                            const Elf_Internal_Rela *relocation,
+                            asection **local_sections,
+                            bfd_boolean check_forced)
 {
   unsigned long r_symndx;
   Elf_Internal_Shdr *symtab_hdr;
@@ -2741,10 +2773,8 @@ mips_elf_local_relocation_p (input_bfd, relocation, local_sections,
 \f
 /* Sign-extend VALUE, which has the indicated number of BITS.  */
 
-static bfd_vma
-mips_elf_sign_extend (value, bits)
-     bfd_vma value;
-     int bits;
+bfd_vma
+_bfd_mips_elf_sign_extend (bfd_vma value, int bits)
 {
   if (value & ((bfd_vma) 1 << (bits - 1)))
     /* VALUE is negative.  */
@@ -2754,13 +2784,11 @@ mips_elf_sign_extend (value, bits)
 }
 
 /* Return non-zero if the indicated VALUE has overflowed the maximum
-   range expressable by a signed number with the indicated number of
+   range expressible by a signed number with the indicated number of
    BITS.  */
 
 static bfd_boolean
-mips_elf_overflow_p (value, bits)
-     bfd_vma value;
-     int bits;
+mips_elf_overflow_p (bfd_vma value, int bits)
 {
   bfd_signed_vma svalue = (bfd_signed_vma) value;
 
@@ -2778,8 +2806,7 @@ mips_elf_overflow_p (value, bits)
 /* Calculate the %high function.  */
 
 static bfd_vma
-mips_elf_high (value)
-     bfd_vma value;
+mips_elf_high (bfd_vma value)
 {
   return ((value + (bfd_vma) 0x8000) >> 16) & 0xffff;
 }
@@ -2787,37 +2814,34 @@ mips_elf_high (value)
 /* Calculate the %higher function.  */
 
 static bfd_vma
-mips_elf_higher (value)
-     bfd_vma value ATTRIBUTE_UNUSED;
+mips_elf_higher (bfd_vma value ATTRIBUTE_UNUSED)
 {
 #ifdef BFD64
   return ((value + (bfd_vma) 0x80008000) >> 32) & 0xffff;
 #else
   abort ();
-  return (bfd_vma) -1;
+  return MINUS_ONE;
 #endif
 }
 
 /* Calculate the %highest function.  */
 
 static bfd_vma
-mips_elf_highest (value)
-     bfd_vma value ATTRIBUTE_UNUSED;
+mips_elf_highest (bfd_vma value ATTRIBUTE_UNUSED)
 {
 #ifdef BFD64
   return ((value + (((bfd_vma) 0x8000 << 32) | 0x80008000)) >> 48) & 0xffff;
 #else
   abort ();
-  return (bfd_vma) -1;
+  return MINUS_ONE;
 #endif
 }
 \f
 /* Create the .compact_rel section.  */
 
 static bfd_boolean
-mips_elf_create_compact_rel_section (abfd, info)
-     bfd *abfd;
-     struct bfd_link_info *info ATTRIBUTE_UNUSED;
+mips_elf_create_compact_rel_section
+  (bfd *abfd, struct bfd_link_info *info ATTRIBUTE_UNUSED)
 {
   flagword flags;
   register asection *s;
@@ -2834,7 +2858,7 @@ mips_elf_create_compact_rel_section (abfd, info)
                                          MIPS_ELF_LOG_FILE_ALIGN (abfd)))
        return FALSE;
 
-      s->_raw_size = sizeof (Elf32_External_compact_rel);
+      s->size = sizeof (Elf32_External_compact_rel);
     }
 
   return TRUE;
@@ -2843,10 +2867,8 @@ mips_elf_create_compact_rel_section (abfd, info)
 /* Create the .got section to hold the global offset table.  */
 
 static bfd_boolean
-mips_elf_create_got_section (abfd, info, maybe_exclude)
-     bfd *abfd;
-     struct bfd_link_info *info;
-     bfd_boolean maybe_exclude;
+mips_elf_create_got_section (bfd *abfd, struct bfd_link_info *info,
+                            bfd_boolean maybe_exclude)
 {
   flagword flags;
   register asection *s;
@@ -2870,6 +2892,8 @@ mips_elf_create_got_section (abfd, info, maybe_exclude)
   if (maybe_exclude)
     flags |= SEC_EXCLUDE;
 
+  /* We have to use an alignment of 2**4 here because this is hardcoded
+     in the function stub generation and in the linker script.  */
   s = bfd_make_section (abfd, ".got");
   if (s == NULL
       || ! bfd_set_section_flags (abfd, s, flags)
@@ -2882,8 +2906,7 @@ mips_elf_create_got_section (abfd, info, maybe_exclude)
   bh = NULL;
   if (! (_bfd_generic_link_add_one_symbol
         (info, abfd, "_GLOBAL_OFFSET_TABLE_", BSF_GLOBAL, s,
-         (bfd_vma) 0, (const char *) NULL, FALSE,
-         get_elf_backend_data (abfd)->collect, &bh)))
+         0, NULL, FALSE, get_elf_backend_data (abfd)->collect, &bh)))
     return FALSE;
 
   h = (struct elf_link_hash_entry *) bh;
@@ -2892,21 +2915,21 @@ mips_elf_create_got_section (abfd, info, maybe_exclude)
   h->type = STT_OBJECT;
 
   if (info->shared
-      && ! bfd_elf32_link_record_dynamic_symbol (info, h))
+      && ! bfd_elf_link_record_dynamic_symbol (info, h))
     return FALSE;
 
   amt = sizeof (struct mips_got_info);
-  g = (struct mips_got_info *) bfd_alloc (abfd, amt);
+  g = bfd_alloc (abfd, amt);
   if (g == NULL)
     return FALSE;
   g->global_gotsym = NULL;
+  g->global_gotno = 0;
   g->local_gotno = MIPS_RESERVED_GOTNO;
   g->assigned_gotno = MIPS_RESERVED_GOTNO;
   g->bfd2got = NULL;
   g->next = NULL;
   g->got_entries = htab_try_create (1, mips_elf_got_entry_hash,
-                                   mips_elf_got_entry_eq,
-                                   (htab_del) NULL);
+                                   mips_elf_got_entry_eq, NULL);
   if (g->got_entries == NULL)
     return FALSE;
   mips_elf_section_data (s)->u.got_info = g;
@@ -2915,34 +2938,6 @@ mips_elf_create_got_section (abfd, info, maybe_exclude)
 
   return TRUE;
 }
-
-/* Returns the .msym section for ABFD, creating it if it does not
-   already exist.  Returns NULL to indicate error.  */
-
-static asection *
-mips_elf_create_msym_section (abfd)
-     bfd *abfd;
-{
-  asection *s;
-
-  s = bfd_get_section_by_name (abfd, ".msym");
-  if (!s)
-    {
-      s = bfd_make_section (abfd, ".msym");
-      if (!s
-         || !bfd_set_section_flags (abfd, s,
-                                    SEC_ALLOC
-                                    | SEC_LOAD
-                                    | SEC_HAS_CONTENTS
-                                    | SEC_LINKER_CREATED
-                                    | SEC_READONLY)
-         || !bfd_set_section_alignment (abfd, s,
-                                        MIPS_ELF_LOG_FILE_ALIGN (abfd)))
-       return NULL;
-    }
-
-  return s;
-}
 \f
 /* Calculate the value produced by the RELOCATION (which comes from
    the INPUT_BFD).  The ADDEND is the addend to use for this
@@ -2958,23 +2953,15 @@ mips_elf_create_msym_section (abfd)
    overflow occurs, and bfd_reloc_ok to indicate success.  */
 
 static bfd_reloc_status_type
-mips_elf_calculate_relocation (abfd, input_bfd, input_section, info,
-                              relocation, addend, howto, local_syms,
-                              local_sections, valuep, namep,
-                              require_jalxp, save_addend)
-     bfd *abfd;
-     bfd *input_bfd;
-     asection *input_section;
-     struct bfd_link_info *info;
-     const Elf_Internal_Rela *relocation;
-     bfd_vma addend;
-     reloc_howto_type *howto;
-     Elf_Internal_Sym *local_syms;
-     asection **local_sections;
-     bfd_vma *valuep;
-     const char **namep;
-     bfd_boolean *require_jalxp;
-     bfd_boolean save_addend;
+mips_elf_calculate_relocation (bfd *abfd, bfd *input_bfd,
+                              asection *input_section,
+                              struct bfd_link_info *info,
+                              const Elf_Internal_Rela *relocation,
+                              bfd_vma addend, reloc_howto_type *howto,
+                              Elf_Internal_Sym *local_syms,
+                              asection **local_sections, bfd_vma *valuep,
+                              const char **namep, bfd_boolean *require_jalxp,
+                              bfd_boolean save_addend)
 {
   /* The eventual value we will return.  */
   bfd_vma value;
@@ -3072,6 +3059,8 @@ mips_elf_calculate_relocation (abfd, input_bfd, input_section, info,
     }
   else
     {
+      /* ??? Could we use RELOC_FOR_GLOBAL_SYMBOL here ?  */
+
       /* For global symbols we look up the symbol in the hash-table.  */
       h = ((struct mips_elf_link_hash_entry *)
           elf_sym_hashes (input_bfd) [r_symndx - extsymoff]);
@@ -3085,7 +3074,7 @@ mips_elf_calculate_relocation (abfd, input_bfd, input_section, info,
 
       /* See if this is the special _gp_disp symbol.  Note that such a
         symbol must always be a global symbol.  */
-      if (strcmp (h->root.root.root.string, "_gp_disp") == 0
+      if (strcmp (*namep, "_gp_disp") == 0
          && ! NEWABI_P (input_bfd))
        {
          /* Relocations against _gp_disp are permitted only with
@@ -3117,12 +3106,11 @@ mips_elf_calculate_relocation (abfd, input_bfd, input_section, info,
           and check to see if they exist by looking at their
           addresses.  */
        symbol = 0;
-      else if (info->shared
-              && !info->no_undefined
+      else if (info->unresolved_syms_in_objects == RM_IGNORE
               && ELF_ST_VISIBILITY (h->root.other) == STV_DEFAULT)
        symbol = 0;
-      else if (strcmp (h->root.root.root.string, "_DYNAMIC_LINK") == 0 ||
-              strcmp (h->root.root.root.string, "_DYNAMIC_LINKING") == 0)
+      else if (strcmp (*namep, "_DYNAMIC_LINK") == 0 ||
+              strcmp (*namep, "_DYNAMIC_LINKING") == 0)
        {
          /* If this is a dynamic link, we should have created a
             _DYNAMIC_LINK symbol or _DYNAMIC_LINKING(for normal mips) symbol
@@ -3139,8 +3127,8 @@ mips_elf_calculate_relocation (abfd, input_bfd, input_section, info,
          if (! ((*info->callbacks->undefined_symbol)
                 (info, h->root.root.root.string, input_bfd,
                  input_section, relocation->r_offset,
-                 (!info->shared || info->no_undefined
-                  || ELF_ST_VISIBILITY (h->root.other)))))
+                 (info->unresolved_syms_in_objects == RM_GENERATE_ERROR)
+                  || ELF_ST_VISIBILITY (h->root.other))))
            return bfd_reloc_undefined;
          symbol = 0;
        }
@@ -3151,7 +3139,7 @@ mips_elf_calculate_relocation (abfd, input_bfd, input_section, info,
   /* If this is a 32- or 64-bit call to a 16-bit function with a stub, we
      need to redirect the call to the stub, unless we're already *in*
      a stub.  */
-  if (r_type != R_MIPS16_26 && !info->relocateable
+  if (r_type != R_MIPS16_26 && !info->relocatable
       && ((h != NULL && h->fn_stub != NULL)
          || (local_p && elf_tdata (input_bfd)->local_stubs != NULL
              && elf_tdata (input_bfd)->local_stubs[r_symndx] != NULL))
@@ -3172,7 +3160,7 @@ mips_elf_calculate_relocation (abfd, input_bfd, input_section, info,
     }
   /* If this is a 16-bit call to a 32- or 64-bit function with a stub, we
      need to redirect the call to the stub.  */
-  else if (r_type == R_MIPS16_26 && !info->relocateable
+  else if (r_type == R_MIPS16_26 && !info->relocatable
           && h != NULL
           && (h->call_stub != NULL || h->call_fp_stub != NULL)
           && !target_is_16_bit_code_p)
@@ -3202,13 +3190,13 @@ mips_elf_calculate_relocation (abfd, input_bfd, input_section, info,
       else
        sec = h->call_fp_stub;
 
-      BFD_ASSERT (sec->_raw_size > 0);
+      BFD_ASSERT (sec->size > 0);
       symbol = sec->output_section->vma + sec->output_offset;
     }
 
   /* Calls from 16-bit code to 32-bit code and vice versa require the
      special jalx instruction.  */
-  *require_jalxp = (!info->relocateable
+  *require_jalxp = (!info->relocatable
                     && (((r_type == R_MIPS16_26) && !target_is_16_bit_code_p)
                         || ((r_type == R_MIPS_26) && target_is_16_bit_code_p)));
 
@@ -3221,12 +3209,9 @@ mips_elf_calculate_relocation (abfd, input_bfd, input_section, info,
     {
     case R_MIPS_GOT_PAGE:
     case R_MIPS_GOT_OFST:
-      /* If this symbol got a global GOT entry, we have to decay
-        GOT_PAGE/GOT_OFST to GOT_DISP/addend.  */
-      local_p = local_p || ! h
-       || (h->root.dynindx
-           < mips_elf_get_global_gotsym_index (elf_hash_table (info)
-                                               ->dynobj));
+      /* We need to decay to GOT_DISP/addend if the symbol doesn't
+        bind locally.  */
+      local_p = local_p || _bfd_elf_symbol_refs_local_p (&h->root, info, 1);
       if (local_p || r_type == R_MIPS_GOT_OFST)
        break;
       /* Fall through.  */
@@ -3305,7 +3290,7 @@ mips_elf_calculate_relocation (abfd, input_bfd, input_section, info,
       return bfd_reloc_continue;
 
     case R_MIPS_16:
-      value = symbol + mips_elf_sign_extend (addend, 16);
+      value = symbol + _bfd_mips_elf_sign_extend (addend, 16);
       overflowed_p = mips_elf_overflow_p (value, 16);
       break;
 
@@ -3349,28 +3334,16 @@ mips_elf_calculate_relocation (abfd, input_bfd, input_section, info,
       break;
 
     case R_MIPS_PC32:
-    case R_MIPS_PC64:
-    case R_MIPS_GNU_REL_LO16:
       value = symbol + addend - p;
       value &= howto->dst_mask;
       break;
 
     case R_MIPS_GNU_REL16_S2:
-      value = symbol + mips_elf_sign_extend (addend << 2, 18) - p;
+      value = symbol + _bfd_mips_elf_sign_extend (addend, 18) - p;
       overflowed_p = mips_elf_overflow_p (value, 18);
       value = (value >> 2) & howto->dst_mask;
       break;
 
-    case R_MIPS_GNU_REL_HI16:
-      /* Instead of subtracting 'p' here, we should be subtracting the
-        equivalent value for the LO part of the reloc, since the value
-        here is relative to that address.  Because that's not easy to do,
-        we adjust 'addend' in _bfd_mips_elf_relocate_section().  See also
-        the comment there for more information.  */
-      value = mips_elf_high (addend + symbol - p);
-      value &= howto->dst_mask;
-      break;
-
     case R_MIPS16_26:
       /* The calculation for R_MIPS16_26 is just the same as for an
         R_MIPS_26.  It's only the storage of the relocated field into
@@ -3379,9 +3352,9 @@ mips_elf_calculate_relocation (abfd, input_bfd, input_section, info,
         R_MIPS_26 case here.  */
     case R_MIPS_26:
       if (local_p)
-       value = (((addend << 2) | ((p + 4) & 0xf0000000)) + symbol) >> 2;
+       value = ((addend | ((p + 4) & 0xf0000000)) + symbol) >> 2;
       else
-       value = (mips_elf_sign_extend (addend << 2, 28) + symbol) >> 2;
+       value = (_bfd_mips_elf_sign_extend (addend, 28) + symbol) >> 2;
       value &= howto->dst_mask;
       break;
 
@@ -3441,7 +3414,7 @@ mips_elf_calculate_relocation (abfd, input_bfd, input_section, info,
         instruction.  If the addend was separate, leave it alone,
         otherwise we may lose significant bits.  */
       if (howto->partial_inplace)
-       addend = mips_elf_sign_extend (addend, 16);
+       addend = _bfd_mips_elf_sign_extend (addend, 16);
       value = symbol + addend - gp;
       /* If the symbol was local, any earlier relocatable links will
         have adjusted its addend with the gp offset, so compensate
@@ -3490,7 +3463,7 @@ mips_elf_calculate_relocation (abfd, input_bfd, input_section, info,
       break;
 
     case R_MIPS_PC16:
-      value = mips_elf_sign_extend (addend, 16) + symbol - p;
+      value = _bfd_mips_elf_sign_extend (addend, 16) + symbol - p;
       overflowed_p = mips_elf_overflow_p (value, 16);
       break;
 
@@ -3575,11 +3548,9 @@ mips_elf_calculate_relocation (abfd, input_bfd, input_section, info,
 /* Obtain the field relocated by RELOCATION.  */
 
 static bfd_vma
-mips_elf_obtain_contents (howto, relocation, input_bfd, contents)
-     reloc_howto_type *howto;
-     const Elf_Internal_Rela *relocation;
-     bfd *input_bfd;
-     bfd_byte *contents;
+mips_elf_obtain_contents (reloc_howto_type *howto,
+                         const Elf_Internal_Rela *relocation,
+                         bfd *input_bfd, bfd_byte *contents)
 {
   bfd_vma x;
   bfd_byte *location = contents + relocation->r_offset;
@@ -3607,16 +3578,12 @@ mips_elf_obtain_contents (howto, relocation, input_bfd, contents)
    Returns FALSE if anything goes wrong.  */
 
 static bfd_boolean
-mips_elf_perform_relocation (info, howto, relocation, value, input_bfd,
-                            input_section, contents, require_jalx)
-     struct bfd_link_info *info;
-     reloc_howto_type *howto;
-     const Elf_Internal_Rela *relocation;
-     bfd_vma value;
-     bfd *input_bfd;
-     asection *input_section;
-     bfd_byte *contents;
-     bfd_boolean require_jalx;
+mips_elf_perform_relocation (struct bfd_link_info *info,
+                            reloc_howto_type *howto,
+                            const Elf_Internal_Rela *relocation,
+                            bfd_vma value, bfd *input_bfd,
+                            asection *input_section, bfd_byte *contents,
+                            bfd_boolean require_jalx)
 {
   bfd_vma x;
   bfd_byte *location;
@@ -3650,7 +3617,7 @@ mips_elf_perform_relocation (info, howto, relocation, value, input_bfd,
         JALX is the 5-bit value 00011.  X is 0 for jal, 1 for jalx.
         Note that the immediate value in the first word is swapped.
 
-        When producing a relocateable object file, R_MIPS16_26 is
+        When producing a relocatable object file, R_MIPS16_26 is
         handled mostly like R_MIPS_26.  In particular, the addend is
         stored as a straight 26-bit value in a 32-bit instruction.
         (gas makes life simpler for itself by never adjusting a
@@ -3688,13 +3655,13 @@ mips_elf_perform_relocation (info, howto, relocation, value, input_bfd,
         where targ26-16 is sub1 followed by sub2 (i.e., the addend field A is
         ((sub1 << 16) | sub2)).
 
-        When producing a relocateable object file, the calculation is
+        When producing a relocatable object file, the calculation is
         (((A < 2) | ((P + 4) & 0xf0000000) + S) >> 2)
         When producing a fully linked file, the calculation is
         let R = (((A < 2) | ((P + 4) & 0xf0000000) + S) >> 2)
         ((R & 0x1f0000) << 5) | ((R & 0x3e00000) >> 5) | (R & 0xffff)  */
 
-      if (!info->relocateable)
+      if (!info->relocatable)
        /* Shuffle the bits according to the formula above.  */
        value = (((value & 0x1f0000) << 5)
                 | ((value & 0x3e00000) >> 5)
@@ -3778,9 +3745,7 @@ mips_elf_perform_relocation (info, howto, relocation, value, input_bfd,
 /* Returns TRUE if SECTION is a MIPS16 stub section.  */
 
 static bfd_boolean
-mips_elf_stub_section_p (abfd, section)
-     bfd *abfd ATTRIBUTE_UNUSED;
-     asection *section;
+mips_elf_stub_section_p (bfd *abfd ATTRIBUTE_UNUSED, asection *section)
 {
   const char *name = bfd_get_section_name (abfd, section);
 
@@ -3792,22 +3757,20 @@ mips_elf_stub_section_p (abfd, section)
 /* Add room for N relocations to the .rel.dyn section in ABFD.  */
 
 static void
-mips_elf_allocate_dynamic_relocations (abfd, n)
-     bfd *abfd;
-     unsigned int n;
+mips_elf_allocate_dynamic_relocations (bfd *abfd, unsigned int n)
 {
   asection *s;
 
   s = mips_elf_rel_dyn_section (abfd, FALSE);
   BFD_ASSERT (s != NULL);
 
-  if (s->_raw_size == 0)
+  if (s->size == 0)
     {
       /* Make room for a null element.  */
-      s->_raw_size += MIPS_ELF_REL_SIZE (abfd);
+      s->size += MIPS_ELF_REL_SIZE (abfd);
       ++s->reloc_count;
     }
-  s->_raw_size += n * MIPS_ELF_REL_SIZE (abfd);
+  s->size += n * MIPS_ELF_REL_SIZE (abfd);
 }
 
 /* Create a rel.dyn relocation for the dynamic linker to resolve.  REL
@@ -3816,16 +3779,12 @@ mips_elf_allocate_dynamic_relocations (abfd, n)
    caller should store the result in place of the original addend.  */
 
 static bfd_boolean
-mips_elf_create_dynamic_relocation (output_bfd, info, rel, h, sec,
-                                   symbol, addendp, input_section)
-     bfd *output_bfd;
-     struct bfd_link_info *info;
-     const Elf_Internal_Rela *rel;
-     struct mips_elf_link_hash_entry *h;
-     asection *sec;
-     bfd_vma symbol;
-     bfd_vma *addendp;
-     asection *input_section;
+mips_elf_create_dynamic_relocation (bfd *output_bfd,
+                                   struct bfd_link_info *info,
+                                   const Elf_Internal_Rela *rel,
+                                   struct mips_elf_link_hash_entry *h,
+                                   asection *sec, bfd_vma symbol,
+                                   bfd_vma *addendp, asection *input_section)
 {
   Elf_Internal_Rela outrel[3];
   bfd_boolean skip;
@@ -3839,7 +3798,7 @@ mips_elf_create_dynamic_relocation (output_bfd, info, rel, h, sec,
   BFD_ASSERT (sreloc != NULL);
   BFD_ASSERT (sreloc->contents != NULL);
   BFD_ASSERT (sreloc->reloc_count * MIPS_ELF_REL_SIZE (output_bfd)
-             < sreloc->_raw_size);
+             < sreloc->size);
 
   skip = FALSE;
   outrel[0].r_offset =
@@ -3853,7 +3812,7 @@ mips_elf_create_dynamic_relocation (output_bfd, info, rel, h, sec,
   /* 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)->sec_info_type != ELF_INFO_TYPE_STABS)
+  if (input_section->sec_info_type != ELF_INFO_TYPE_STABS)
     {
       outrel[1].r_offset = rel[1].r_offset;
       outrel[2].r_offset = rel[2].r_offset;
@@ -3868,14 +3827,22 @@ mips_elf_create_dynamic_relocation (output_bfd, info, rel, h, sec,
       outrel[2].r_offset = outrel[0].r_offset;
       /* If we didn't need the relocation at all, this value will be
         -1.  */
-      if (outrel[0].r_offset == (bfd_vma) -1)
+      if (outrel[0].r_offset == MINUS_ONE)
        skip = TRUE;
     }
 #endif
 
-  if (outrel[0].r_offset == (bfd_vma) -1
-      || outrel[0].r_offset == (bfd_vma) -2)
+  if (outrel[0].r_offset == MINUS_ONE)
+    /* The relocation field has been deleted.  */
     skip = TRUE;
+  else if (outrel[0].r_offset == MINUS_TWO)
+    {
+      /* The relocation field has been converted into a relative value of
+        some sort.  Functions like _bfd_elf_write_section_eh_frame expect
+        the field to be fully relocated, so add in the symbol's value.  */
+      skip = TRUE;
+      *addendp += symbol;
+    }
 
   /* 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
@@ -3885,18 +3852,27 @@ mips_elf_create_dynamic_relocation (output_bfd, info, rel, h, sec,
   else
     {
       long indx;
+      bfd_boolean defined_p;
 
       /* We must now calculate the dynamic symbol table index to use
         in the relocation.  */
       if (h != NULL
          && (! info->symbolic || (h->root.elf_link_hash_flags
-                                  & ELF_LINK_HASH_DEF_REGULAR) == 0))
-       {
-         indx = h->root.dynindx;
+                                  & ELF_LINK_HASH_DEF_REGULAR) == 0)
          /* h->root.dynindx may be -1 if this symbol was marked to
             become local.  */
-         if (indx == -1)
-           indx = 0;
+         && h->root.dynindx != -1)
+       {
+         indx = h->root.dynindx;
+         if (SGI_COMPAT (output_bfd))
+           defined_p = ((h->root.elf_link_hash_flags
+                         & ELF_LINK_HASH_DEF_REGULAR) != 0);
+         else
+           /* ??? glibc's ld.so just adds the final GOT entry to the
+              relocation field.  It therefore treats relocs against
+              defined symbols in the same way as relocs against
+              undefined symbols.  */
+           defined_p = FALSE;
        }
       else
        {
@@ -3925,14 +3901,20 @@ mips_elf_create_dynamic_relocation (output_bfd, info, rel, h, sec,
             section-relative relocations.  It's not like they're
             useful, after all.  This should be a bit more efficient
             as well.  */
-         indx = 0;
+         /* ??? Although this behavior is compatible with glibc's ld.so,
+            the ABI says that relocations against STN_UNDEF should have
+            a symbol value of 0.  Irix rld honors this, so relocations
+            against STN_UNDEF have no effect.  */
+         if (!SGI_COMPAT (output_bfd))
+           indx = 0;
+         defined_p = TRUE;
        }
 
       /* If the relocation was previously an absolute relocation and
         this symbol will not be referred to by the relocation, we must
         adjust it by the value we give it in the dynamic symbol table.
         Otherwise leave the job up to the dynamic linker.  */
-      if (!indx && r_type != R_MIPS_REL32)
+      if (defined_p && r_type != R_MIPS_REL32)
        *addendp += symbol;
 
       /* The relocation is always an REL32 relocation because we don't
@@ -3951,12 +3933,11 @@ mips_elf_create_dynamic_relocation (output_bfd, info, rel, h, sec,
         invocation if ABI_64_P, and here we should generate an
         additional relocation record with R_MIPS_64 by itself for a
         NULL symbol before this relocation record.  */
-      outrel[1].r_info = ELF_R_INFO (output_bfd, (unsigned long) 0,
+      outrel[1].r_info = ELF_R_INFO (output_bfd, 0,
                                     ABI_64_P (output_bfd)
                                     ? R_MIPS_64
                                     : R_MIPS_NONE);
-      outrel[2].r_info = ELF_R_INFO (output_bfd, (unsigned long) 0,
-                                    R_MIPS_NONE);
+      outrel[2].r_info = ELF_R_INFO (output_bfd, 0, R_MIPS_NONE);
 
       /* Adjust the output offset of the relocation to reference the
         correct location in the output file.  */
@@ -3983,13 +3964,6 @@ mips_elf_create_dynamic_relocation (output_bfd, info, rel, h, sec,
       (output_bfd, &outrel[0],
        (sreloc->contents + sreloc->reloc_count * sizeof (Elf32_External_Rel)));
 
-  /* Record the index of the first relocation referencing H.  This
-     information is later emitted in the .msym section.  */
-  if (h != NULL
-      && (h->min_dyn_reloc_index == 0
-         || sreloc->reloc_count < h->min_dyn_reloc_index))
-    h->min_dyn_reloc_index = sreloc->reloc_count;
-
   /* We've now added another relocation.  */
   ++sreloc->reloc_count;
 
@@ -4034,8 +4008,7 @@ mips_elf_create_dynamic_relocation (output_bfd, info, rel, h, sec,
 /* Return the MACH for a MIPS e_flags value.  */
 
 unsigned long
-_bfd_elf_mips_mach (flags)
-     flagword flags;
+_bfd_elf_mips_mach (flagword flags)
 {
   switch (flags & EF_MIPS_MACH)
     {
@@ -4101,6 +4074,10 @@ _bfd_elf_mips_mach (flags)
        case E_MIPS_ARCH_32R2:
          return bfd_mach_mipsisa32r2;
          break;
+
+       case E_MIPS_ARCH_64R2:
+         return bfd_mach_mipsisa64r2;
+         break;
        }
     }
 
@@ -4110,8 +4087,7 @@ _bfd_elf_mips_mach (flags)
 /* Return printable name for ABI.  */
 
 static INLINE char *
-elf_mips_abi_name (abfd)
-     bfd *abfd;
+elf_mips_abi_name (bfd *abfd)
 {
   flagword flags;
 
@@ -4158,9 +4134,7 @@ static asymbol *mips_elf_acom_symbol_ptr;
    This is used for both the 32-bit and the 64-bit ABI.  */
 
 void
-_bfd_mips_elf_symbol_processing (abfd, asym)
-     bfd *abfd;
-     asymbol *asym;
+_bfd_mips_elf_symbol_processing (bfd *abfd, asymbol *asym)
 {
   elf_symbol_type *elfsym;
 
@@ -4230,15 +4204,33 @@ _bfd_mips_elf_symbol_processing (abfd, asym)
     }
 }
 \f
+/* There appears to be a bug in the MIPSpro linker that causes GOT_DISP
+   relocations against two unnamed section symbols to resolve to the
+   same address.  For example, if we have code like:
+
+       lw      $4,%got_disp(.data)($gp)
+       lw      $25,%got_disp(.text)($gp)
+       jalr    $25
+
+   then the linker will resolve both relocations to .data and the program
+   will jump there rather than to .text.
+
+   We can work around this problem by giving names to local section symbols.
+   This is also what the MIPSpro tools do.  */
+
+bfd_boolean
+_bfd_mips_elf_name_local_section_symbols (bfd *abfd)
+{
+  return SGI_COMPAT (abfd);
+}
+\f
 /* Work over a section just before writing it out.  This routine is
    used by both the 32-bit and the 64-bit ABI.  FIXME: We recognize
    sections that need the SHF_MIPS_GPREL flag by name; there has to be
    a better way.  */
 
 bfd_boolean
-_bfd_mips_elf_section_processing (abfd, hdr)
-     bfd *abfd;
-     Elf_Internal_Shdr *hdr;
+_bfd_mips_elf_section_processing (bfd *abfd, Elf_Internal_Shdr *hdr)
 {
   if (hdr->sh_type == SHT_MIPS_REGINFO
       && hdr->sh_size > 0)
@@ -4253,7 +4245,7 @@ _bfd_mips_elf_section_processing (abfd, hdr)
                    SEEK_SET) != 0)
        return FALSE;
       H_PUT_32 (abfd, elf_gp (abfd), buf);
-      if (bfd_bwrite (buf, (bfd_size_type) 4, abfd) != 4)
+      if (bfd_bwrite (buf, 4, abfd) != 4)
        return FALSE;
     }
 
@@ -4292,7 +4284,7 @@ _bfd_mips_elf_section_processing (abfd, hdr)
                             SEEK_SET) != 0)
                return FALSE;
              H_PUT_64 (abfd, elf_gp (abfd), buf);
-             if (bfd_bwrite (buf, (bfd_size_type) 8, abfd) != 8)
+             if (bfd_bwrite (buf, 8, abfd) != 8)
                return FALSE;
            }
          else if (intopt.kind == ODK_REGINFO)
@@ -4307,7 +4299,7 @@ _bfd_mips_elf_section_processing (abfd, hdr)
                            SEEK_SET) != 0)
                return FALSE;
              H_PUT_32 (abfd, elf_gp (abfd), buf);
-             if (bfd_bwrite (buf, (bfd_size_type) 4, abfd) != 4)
+             if (bfd_bwrite (buf, 4, abfd) != 4)
                return FALSE;
            }
          l += intopt.size;
@@ -4364,10 +4356,8 @@ _bfd_mips_elf_section_processing (abfd, hdr)
    how to.  */
 
 bfd_boolean
-_bfd_mips_elf_section_from_shdr (abfd, hdr, name)
-     bfd *abfd;
-     Elf_Internal_Shdr *hdr;
-     const char *name;
+_bfd_mips_elf_section_from_shdr (bfd *abfd, Elf_Internal_Shdr *hdr,
+                                const char *name)
 {
   flagword flags = 0;
 
@@ -4462,9 +4452,8 @@ _bfd_mips_elf_section_from_shdr (abfd, hdr, name)
       Elf32_External_RegInfo ext;
       Elf32_RegInfo s;
 
-      if (! bfd_get_section_contents (abfd, hdr->bfd_section, (PTR) &ext,
-                                     (file_ptr) 0,
-                                     (bfd_size_type) sizeof ext))
+      if (! bfd_get_section_contents (abfd, hdr->bfd_section,
+                                     &ext, 0, sizeof ext))
        return FALSE;
       bfd_mips_elf32_swap_reginfo_in (abfd, &ext, &s);
       elf_gp (abfd) = s.ri_gp_value;
@@ -4478,11 +4467,11 @@ _bfd_mips_elf_section_from_shdr (abfd, hdr, name)
     {
       bfd_byte *contents, *l, *lend;
 
-      contents = (bfd_byte *) bfd_malloc (hdr->sh_size);
+      contents = bfd_malloc (hdr->sh_size);
       if (contents == NULL)
        return FALSE;
       if (! bfd_get_section_contents (abfd, hdr->bfd_section, contents,
-                                     (file_ptr) 0, hdr->sh_size))
+                                     0, hdr->sh_size))
        {
          free (contents);
          return FALSE;
@@ -4530,10 +4519,7 @@ _bfd_mips_elf_section_from_shdr (abfd, hdr, name)
    used by both the 32-bit and the 64-bit ABI.  */
 
 bfd_boolean
-_bfd_mips_elf_fake_sections (abfd, hdr, sec)
-     bfd *abfd;
-     Elf_Internal_Shdr *hdr;
-     asection *sec;
+_bfd_mips_elf_fake_sections (bfd *abfd, Elf_Internal_Shdr *hdr, asection *sec)
 {
   register const char *name;
 
@@ -4542,7 +4528,7 @@ _bfd_mips_elf_fake_sections (abfd, hdr, sec)
   if (strcmp (name, ".liblist") == 0)
     {
       hdr->sh_type = SHT_MIPS_LIBLIST;
-      hdr->sh_info = sec->_raw_size / sizeof (Elf32_Lib);
+      hdr->sh_info = sec->size / sizeof (Elf32_Lib);
       /* The sh_link field is set in final_write_processing.  */
     }
   else if (strcmp (name, ".conflict") == 0)
@@ -4639,30 +4625,11 @@ _bfd_mips_elf_fake_sections (abfd, hdr, sec)
       hdr->sh_entsize = 8;
     }
 
-  /* The generic elf_fake_sections will set up REL_HDR using the
-     default kind of relocations.  But, we may actually need both
-     kinds of relocations, so we set up the second header here.
-
-     This is not necessary for the O32 ABI since that only uses Elf32_Rel
-     relocations (cf. System V ABI, MIPS RISC Processor Supplement,
-     3rd Edition, p. 4-17).  It breaks the IRIX 5/6 32-bit ld, since one
-     of the resulting empty .rela.<section> sections starts with
-     sh_offset == object size, and ld doesn't allow that.  While the check
-     is arguably bogus for empty or SHT_NOBITS sections, it can easily be
-     avoided by not emitting those useless sections in the first place.  */
-  if (! SGI_COMPAT (abfd) && ! NEWABI_P(abfd)
-      && (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, amt);
-      if (!esd->rel_hdr2)
-       return FALSE;
-      _bfd_elf_init_reloc_shdr (abfd, esd->rel_hdr2, sec, !sec->use_rela_p);
-    }
+  /* The generic elf_fake_sections will set up REL_HDR using the default
+   kind of relocations.  We used to set up a second header for the
+   non-default kind of relocations here, but only NewABI would use
+   these, and the IRIX ld doesn't like resulting empty RELA sections.
+   Thus we create those header only on demand now.  */
 
   return TRUE;
 }
@@ -4674,10 +4641,8 @@ _bfd_mips_elf_fake_sections (abfd, hdr, sec)
    the .scommon section.  */
 
 bfd_boolean
-_bfd_mips_elf_section_from_bfd_section (abfd, sec, retval)
-     bfd *abfd ATTRIBUTE_UNUSED;
-     asection *sec;
-     int *retval;
+_bfd_mips_elf_section_from_bfd_section (bfd *abfd ATTRIBUTE_UNUSED,
+                                       asection *sec, int *retval)
 {
   if (strcmp (bfd_get_section_name (abfd, sec), ".scommon") == 0)
     {
@@ -4696,14 +4661,10 @@ _bfd_mips_elf_section_from_bfd_section (abfd, sec, retval)
    file.  We must handle the special MIPS section numbers here.  */
 
 bfd_boolean
-_bfd_mips_elf_add_symbol_hook (abfd, info, sym, namep, flagsp, secp, valp)
-     bfd *abfd;
-     struct bfd_link_info *info;
-     const Elf_Internal_Sym *sym;
-     const char **namep;
-     flagword *flagsp ATTRIBUTE_UNUSED;
-     asection **secp;
-     bfd_vma *valp;
+_bfd_mips_elf_add_symbol_hook (bfd *abfd, struct bfd_link_info *info,
+                              Elf_Internal_Sym *sym, const char **namep,
+                              flagword *flagsp ATTRIBUTE_UNUSED,
+                              asection **secp, bfd_vma *valp)
 {
   if (SGI_COMPAT (abfd)
       && (abfd->flags & DYNAMIC) != 0
@@ -4825,8 +4786,7 @@ _bfd_mips_elf_add_symbol_hook (abfd, info, sym, namep, flagsp, secp, valp)
       /* Mark __rld_obj_head as dynamic.  */
       bh = NULL;
       if (! (_bfd_generic_link_add_one_symbol
-            (info, abfd, *namep, BSF_GLOBAL, *secp,
-             (bfd_vma) *valp, (const char *) NULL, FALSE,
+            (info, abfd, *namep, BSF_GLOBAL, *secp, *valp, NULL, FALSE,
              get_elf_backend_data (abfd)->collect, &bh)))
        return FALSE;
 
@@ -4835,7 +4795,7 @@ _bfd_mips_elf_add_symbol_hook (abfd, info, sym, namep, flagsp, secp, valp)
       h->elf_link_hash_flags |= ELF_LINK_HASH_DEF_REGULAR;
       h->type = STT_OBJECT;
 
-      if (! bfd_elf32_link_record_dynamic_symbol (info, h))
+      if (! bfd_elf_link_record_dynamic_symbol (info, h))
        return FALSE;
 
       mips_elf_hash_table (info)->use_rld_obj_head = TRUE;
@@ -4855,12 +4815,10 @@ _bfd_mips_elf_add_symbol_hook (abfd, info, sym, namep, flagsp, secp, valp)
    also where we undo the increment of the value for a mips16 symbol.  */
 
 bfd_boolean
-_bfd_mips_elf_link_output_symbol_hook (abfd, info, name, sym, input_sec)
-     bfd *abfd ATTRIBUTE_UNUSED;
-     struct bfd_link_info *info ATTRIBUTE_UNUSED;
-     const char *name ATTRIBUTE_UNUSED;
-     Elf_Internal_Sym *sym;
-     asection *input_sec;
+_bfd_mips_elf_link_output_symbol_hook
+  (struct bfd_link_info *info ATTRIBUTE_UNUSED,
+   const char *name ATTRIBUTE_UNUSED, Elf_Internal_Sym *sym,
+   asection *input_sec, struct elf_link_hash_entry *h ATTRIBUTE_UNUSED)
 {
   /* If we see a common symbol, which implies a relocatable link, then
      if a symbol was small common in an input file, mark it as small
@@ -4869,9 +4827,8 @@ _bfd_mips_elf_link_output_symbol_hook (abfd, info, name, sym, input_sec)
       && strcmp (input_sec->name, ".scommon") == 0)
     sym->st_shndx = SHN_MIPS_SCOMMON;
 
-  if (sym->st_other == STO_MIPS16
-      && (sym->st_value & 1) != 0)
-    --sym->st_value;
+  if (sym->st_other == STO_MIPS16)
+    sym->st_value &= ~1;
 
   return TRUE;
 }
@@ -4881,9 +4838,7 @@ _bfd_mips_elf_link_output_symbol_hook (abfd, info, name, sym, input_sec)
 /* Create dynamic sections when linking against a dynamic object.  */
 
 bfd_boolean
-_bfd_mips_elf_create_dynamic_sections (abfd, info)
-     bfd *abfd;
-     struct bfd_link_info *info;
+_bfd_mips_elf_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info)
 {
   struct elf_link_hash_entry *h;
   struct bfd_link_hash_entry *bh;
@@ -4909,13 +4864,6 @@ _bfd_mips_elf_create_dynamic_sections (abfd, info)
   if (! mips_elf_rel_dyn_section (elf_hash_table (info)->dynobj, TRUE))
     return FALSE;
 
-  /* Create the .msym section on IRIX6.  It is used by the dynamic
-     linker to speed up dynamic relocations, and to avoid computing
-     the ELF hash for symbols.  */
-  if (IRIX_COMPAT (abfd) == ict_irix6
-      && !mips_elf_create_msym_section (abfd))
-    return FALSE;
-
   /* Create .stub section.  */
   if (bfd_get_section_by_name (abfd,
                               MIPS_ELF_STUB_SECTION_NAME (abfd)) == NULL)
@@ -4950,9 +4898,8 @@ _bfd_mips_elf_create_dynamic_sections (abfd, info)
        {
          bh = NULL;
          if (! (_bfd_generic_link_add_one_symbol
-                (info, abfd, *namep, BSF_GLOBAL, bfd_und_section_ptr,
-                 (bfd_vma) 0, (const char *) NULL, FALSE,
-                 get_elf_backend_data (abfd)->collect, &bh)))
+                (info, abfd, *namep, BSF_GLOBAL, bfd_und_section_ptr, 0,
+                 NULL, FALSE, get_elf_backend_data (abfd)->collect, &bh)))
            return FALSE;
 
          h = (struct elf_link_hash_entry *) bh;
@@ -4960,7 +4907,7 @@ _bfd_mips_elf_create_dynamic_sections (abfd, info)
          h->elf_link_hash_flags |= ELF_LINK_HASH_DEF_REGULAR;
          h->type = STT_SECTION;
 
-         if (! bfd_elf32_link_record_dynamic_symbol (info, h))
+         if (! bfd_elf_link_record_dynamic_symbol (info, h))
            return FALSE;
        }
 
@@ -4974,19 +4921,19 @@ _bfd_mips_elf_create_dynamic_sections (abfd, info)
       /* Change alignments of some sections.  */
       s = bfd_get_section_by_name (abfd, ".hash");
       if (s != NULL)
-       bfd_set_section_alignment (abfd, s, 4);
+       bfd_set_section_alignment (abfd, s, MIPS_ELF_LOG_FILE_ALIGN (abfd));
       s = bfd_get_section_by_name (abfd, ".dynsym");
       if (s != NULL)
-       bfd_set_section_alignment (abfd, s, 4);
+       bfd_set_section_alignment (abfd, s, MIPS_ELF_LOG_FILE_ALIGN (abfd));
       s = bfd_get_section_by_name (abfd, ".dynstr");
       if (s != NULL)
-       bfd_set_section_alignment (abfd, s, 4);
+       bfd_set_section_alignment (abfd, s, MIPS_ELF_LOG_FILE_ALIGN (abfd));
       s = bfd_get_section_by_name (abfd, ".reginfo");
       if (s != NULL)
-       bfd_set_section_alignment (abfd, s, 4);
+       bfd_set_section_alignment (abfd, s, MIPS_ELF_LOG_FILE_ALIGN (abfd));
       s = bfd_get_section_by_name (abfd, ".dynamic");
       if (s != NULL)
-       bfd_set_section_alignment (abfd, s, 4);
+       bfd_set_section_alignment (abfd, s, MIPS_ELF_LOG_FILE_ALIGN (abfd));
     }
 
   if (!info->shared)
@@ -4996,9 +4943,8 @@ _bfd_mips_elf_create_dynamic_sections (abfd, info)
       name = SGI_COMPAT (abfd) ? "_DYNAMIC_LINK" : "_DYNAMIC_LINKING";
       bh = NULL;
       if (!(_bfd_generic_link_add_one_symbol
-           (info, abfd, name, BSF_GLOBAL, bfd_abs_section_ptr,
-            (bfd_vma) 0, (const char *) NULL, FALSE,
-            get_elf_backend_data (abfd)->collect, &bh)))
+           (info, abfd, name, BSF_GLOBAL, bfd_abs_section_ptr, 0,
+            NULL, FALSE, get_elf_backend_data (abfd)->collect, &bh)))
        return FALSE;
 
       h = (struct elf_link_hash_entry *) bh;
@@ -5006,7 +4952,7 @@ _bfd_mips_elf_create_dynamic_sections (abfd, info)
       h->elf_link_hash_flags |= ELF_LINK_HASH_DEF_REGULAR;
       h->type = STT_SECTION;
 
-      if (! bfd_elf32_link_record_dynamic_symbol (info, h))
+      if (! bfd_elf_link_record_dynamic_symbol (info, h))
        return FALSE;
 
       if (! mips_elf_hash_table (info)->use_rld_obj_head)
@@ -5021,8 +4967,7 @@ _bfd_mips_elf_create_dynamic_sections (abfd, info)
          name = SGI_COMPAT (abfd) ? "__rld_map" : "__RLD_MAP";
          bh = NULL;
          if (!(_bfd_generic_link_add_one_symbol
-               (info, abfd, name, BSF_GLOBAL, s,
-                (bfd_vma) 0, (const char *) NULL, FALSE,
+               (info, abfd, name, BSF_GLOBAL, s, 0, NULL, FALSE,
                 get_elf_backend_data (abfd)->collect, &bh)))
            return FALSE;
 
@@ -5031,7 +4976,7 @@ _bfd_mips_elf_create_dynamic_sections (abfd, info)
          h->elf_link_hash_flags |= ELF_LINK_HASH_DEF_REGULAR;
          h->type = STT_OBJECT;
 
-         if (! bfd_elf32_link_record_dynamic_symbol (info, h))
+         if (! bfd_elf_link_record_dynamic_symbol (info, h))
            return FALSE;
        }
     }
@@ -5043,11 +4988,8 @@ _bfd_mips_elf_create_dynamic_sections (abfd, info)
    allocate space in the global offset table.  */
 
 bfd_boolean
-_bfd_mips_elf_check_relocs (abfd, info, sec, relocs)
-     bfd *abfd;
-     struct bfd_link_info *info;
-     asection *sec;
-     const Elf_Internal_Rela *relocs;
+_bfd_mips_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
+                           asection *sec, const Elf_Internal_Rela *relocs)
 {
   const char *name;
   bfd *dynobj;
@@ -5059,9 +5001,9 @@ _bfd_mips_elf_check_relocs (abfd, info, sec, relocs)
   const Elf_Internal_Rela *rel_end;
   asection *sgot;
   asection *sreloc;
-  struct elf_backend_data *bed;
+  const struct elf_backend_data *bed;
 
-  if (info->relocateable)
+  if (info->relocatable)
     return TRUE;
 
   dynobj = elf_hash_table (info)->dynobj;
@@ -5106,8 +5048,7 @@ _bfd_mips_elf_check_relocs (abfd, info, sec, relocs)
                continue;
 
              sec_relocs
-               = _bfd_elf_link_read_relocs (abfd, o, (PTR) NULL,
-                                            (Elf_Internal_Rela *) NULL,
+               = _bfd_elf_link_read_relocs (abfd, o, NULL, NULL,
                                             info->keep_memory);
              if (sec_relocs == NULL)
                return FALSE;
@@ -5149,7 +5090,7 @@ _bfd_mips_elf_check_relocs (abfd, info, sec, relocs)
              else
                symcount = symtab_hdr->sh_info;
              amt = symcount * sizeof (asection *);
-             n = (asection **) bfd_zalloc (abfd, amt);
+             n = bfd_zalloc (abfd, amt);
              if (n == NULL)
                return FALSE;
              elf_tdata (abfd)->local_stubs = n;
@@ -5354,7 +5295,7 @@ _bfd_mips_elf_check_relocs (abfd, info, sec, relocs)
 
              /* We need a stub, not a plt entry for the undefined
                 function.  But we record it as if it needs plt.  See
-                elf_adjust_dynamic_symbol in elflink.h.  */
+                _bfd_elf_adjust_dynamic_symbol.  */
              h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT;
              h->type = STT_FUNC;
            }
@@ -5375,25 +5316,10 @@ _bfd_mips_elf_check_relocs (abfd, info, sec, relocs)
                hmips = (struct mips_elf_link_hash_entry *)
                  hmips->root.root.u.i.link;
 
-             if ((hmips->root.root.type == bfd_link_hash_defined
-                  || hmips->root.root.type == bfd_link_hash_defweak)
-                 && hmips->root.root.u.def.section
+             if ((hmips->root.elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR)
                  && ! (info->shared && ! info->symbolic
                        && ! (hmips->root.elf_link_hash_flags
-                             & ELF_LINK_FORCED_LOCAL))
-                 /* If we've encountered any other relocation
-                    referencing the symbol, we'll have marked it as
-                    dynamic, and, even though we might be able to get
-                    rid of the GOT entry should we know for sure all
-                    previous relocations were GOT_PAGE ones, at this
-                    point we can't tell, so just keep using the
-                    symbol as dynamic.  This is very important in the
-                    multi-got case, since we don't decide whether to
-                    decay GOT_PAGE to GOT_DISP on a per-GOT basis: if
-                    the symbol is dynamic, we'll need a GOT entry for
-                    every GOT in which the symbol is referenced with
-                    a GOT_PAGE relocation.  */
-                 && hmips->root.dynindx == -1)
+                             & ELF_LINK_FORCED_LOCAL)))
                break;
            }
          /* Fall through.  */
@@ -5481,14 +5407,14 @@ _bfd_mips_elf_check_relocs (abfd, info, sec, relocs)
          /* This relocation describes the C++ object vtable hierarchy.
             Reconstruct it for later use during GC.  */
        case R_MIPS_GNU_VTINHERIT:
-         if (!_bfd_elf32_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
+         if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
            return FALSE;
          break;
 
          /* This relocation describes which C++ vtable entries are actually
             used.  Record for later use during GC.  */
        case R_MIPS_GNU_VTENTRY:
-         if (!_bfd_elf32_gc_record_vtentry (abfd, sec, h, rel->r_offset))
+         if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_offset))
            return FALSE;
          break;
 
@@ -5512,6 +5438,7 @@ _bfd_mips_elf_check_relocs (abfd, info, sec, relocs)
        case R_MIPS_CALL16:
        case R_MIPS_CALL_HI16:
        case R_MIPS_CALL_LO16:
+       case R_MIPS_JALR:
          break;
        }
 
@@ -5538,17 +5465,14 @@ _bfd_mips_elf_check_relocs (abfd, info, sec, relocs)
 }
 \f
 bfd_boolean
-_bfd_mips_relax_section (abfd, sec, link_info, again)
-     bfd *abfd;
-     asection *sec;
-     struct bfd_link_info *link_info;
-     bfd_boolean *again;
+_bfd_mips_relax_section (bfd *abfd, asection *sec,
+                        struct bfd_link_info *link_info,
+                        bfd_boolean *again)
 {
   Elf_Internal_Rela *internal_relocs;
   Elf_Internal_Rela *irel, *irelend;
   Elf_Internal_Shdr *symtab_hdr;
   bfd_byte *contents = NULL;
-  bfd_byte *free_contents = NULL;
   size_t extsymoff;
   bfd_boolean changed_contents = FALSE;
   bfd_vma sec_start = sec->output_section->vma + sec->output_offset;
@@ -5557,11 +5481,10 @@ _bfd_mips_relax_section (abfd, sec, link_info, again)
   /* We are not currently changing any sizes, so only one pass.  */
   *again = FALSE;
 
-  if (link_info->relocateable)
+  if (link_info->relocatable)
     return TRUE;
 
-  internal_relocs = _bfd_elf_link_read_relocs (abfd, sec, (PTR) NULL,
-                                              (Elf_Internal_Rela *) NULL,
+  internal_relocs = _bfd_elf_link_read_relocs (abfd, sec, NULL, NULL,
                                               link_info->keep_memory);
   if (internal_relocs == NULL)
     return TRUE;
@@ -5670,13 +5593,7 @@ _bfd_mips_relax_section (abfd, sec, link_info, again)
            contents = elf_section_data (sec)->this_hdr.contents;
          else
            {
-             contents = (bfd_byte *) bfd_malloc (sec->_raw_size);
-             if (contents == NULL)
-               goto relax_return;
-
-             free_contents = contents;
-             if (! bfd_get_section_contents (abfd, sec, contents,
-                                             (file_ptr) 0, sec->_raw_size))
+             if (!bfd_malloc_and_get_section (abfd, sec, &contents))
                goto relax_return;
            }
        }
@@ -5711,8 +5628,9 @@ _bfd_mips_relax_section (abfd, sec, link_info, again)
   return TRUE;
 
  relax_return:
-  if (free_contents != NULL)
-    free (free_contents);
+  if (contents != NULL
+      && elf_section_data (sec)->this_hdr.contents != contents)
+    free (contents);
   return FALSE;
 }
 \f
@@ -5723,9 +5641,8 @@ _bfd_mips_relax_section (abfd, sec, link_info, again)
    understand.  */
 
 bfd_boolean
-_bfd_mips_elf_adjust_dynamic_symbol (info, h)
-     struct bfd_link_info *info;
-     struct elf_link_hash_entry *h;
+_bfd_mips_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
+                                    struct elf_link_hash_entry *h)
 {
   bfd *dynobj;
   struct mips_elf_link_hash_entry *hmips;
@@ -5748,7 +5665,7 @@ _bfd_mips_elf_adjust_dynamic_symbol (info, h)
      any R_MIPS_32 or R_MIPS_REL32 relocs against it into the output
      file.  */
   hmips = (struct mips_elf_link_hash_entry *) h;
-  if (! info->relocateable
+  if (! info->relocatable
       && hmips->possibly_dynamic_relocs != 0
       && (h->root.type == bfd_link_hash_defweak
          || (h->elf_link_hash_flags
@@ -5781,13 +5698,13 @@ _bfd_mips_elf_adjust_dynamic_symbol (info, h)
          BFD_ASSERT (s != NULL);
 
          h->root.u.def.section = s;
-         h->root.u.def.value = s->_raw_size;
+         h->root.u.def.value = s->size;
 
          /* XXX Write this stub address somewhere.  */
-         h->plt.offset = s->_raw_size;
+         h->plt.offset = s->size;
 
          /* Make room for this stub code.  */
-         s->_raw_size += MIPS_FUNCTION_STUB_SIZE;
+         s->size += MIPS_FUNCTION_STUB_SIZE;
 
          /* The last half word of the stub will be filled with the index
             of this symbol in .dynsym section.  */
@@ -5826,9 +5743,8 @@ _bfd_mips_elf_adjust_dynamic_symbol (info, h)
    check for any mips16 stub sections that we can discard.  */
 
 bfd_boolean
-_bfd_mips_elf_always_size_sections (output_bfd, info)
-     bfd *output_bfd;
-     struct bfd_link_info *info;
+_bfd_mips_elf_always_size_sections (bfd *output_bfd,
+                                   struct bfd_link_info *info)
 {
   asection *ri;
 
@@ -5843,14 +5759,12 @@ _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,
-                         (bfd_size_type) sizeof (Elf32_External_RegInfo));
+    bfd_set_section_size (output_bfd, ri, sizeof (Elf32_External_RegInfo));
 
-  if (! (info->relocateable
+  if (! (info->relocatable
         || ! mips_elf_hash_table (info)->mips16_stubs_seen))
     mips_elf_link_hash_traverse (mips_elf_hash_table (info),
-                                mips_elf_check_mips16_stubs,
-                                (PTR) NULL);
+                                mips_elf_check_mips16_stubs, NULL);
 
   dynobj = elf_hash_table (info)->dynobj;
   if (dynobj == NULL)
@@ -5874,7 +5788,7 @@ _bfd_mips_elf_always_size_sections (output_bfd, info)
        {
          if ((subsection->flags & SEC_ALLOC) == 0)
            continue;
-         loadable_size += ((subsection->_raw_size + 0xf)
+         loadable_size += ((subsection->size + 0xf)
                            &~ (bfd_size_type) 0xf);
        }
     }
@@ -5904,12 +5818,12 @@ _bfd_mips_elf_always_size_sections (output_bfd, info)
   local_gotno = (loadable_size >> 16) + 5;
 
   g->local_gotno += local_gotno;
-  s->_raw_size += g->local_gotno * MIPS_ELF_GOT_SIZE (output_bfd);
+  s->size += g->local_gotno * MIPS_ELF_GOT_SIZE (output_bfd);
 
   g->global_gotno = i;
-  s->_raw_size += i * MIPS_ELF_GOT_SIZE (output_bfd);
+  s->size += i * MIPS_ELF_GOT_SIZE (output_bfd);
 
-  if (s->_raw_size > MIPS_ELF_GOT_MAX_SIZE (output_bfd)
+  if (s->size > MIPS_ELF_GOT_MAX_SIZE (output_bfd)
       && ! mips_elf_multi_got (output_bfd, info, g, s, local_gotno))
     return FALSE;
 
@@ -5919,9 +5833,8 @@ _bfd_mips_elf_always_size_sections (output_bfd, info)
 /* Set the sizes of the dynamic sections.  */
 
 bfd_boolean
-_bfd_mips_elf_size_dynamic_sections (output_bfd, info)
-     bfd *output_bfd;
-     struct bfd_link_info *info;
+_bfd_mips_elf_size_dynamic_sections (bfd *output_bfd,
+                                    struct bfd_link_info *info)
 {
   bfd *dynobj;
   asection *s;
@@ -5933,11 +5846,11 @@ _bfd_mips_elf_size_dynamic_sections (output_bfd, info)
   if (elf_hash_table (info)->dynamic_sections_created)
     {
       /* Set the contents of the .interp section to the interpreter.  */
-      if (! info->shared)
+      if (info->executable)
        {
          s = bfd_get_section_by_name (dynobj, ".interp");
          BFD_ASSERT (s != NULL);
-         s->_raw_size
+         s->size
            = strlen (ELF_DYNAMIC_INTERPRETER (output_bfd)) + 1;
          s->contents
            = (bfd_byte *) ELF_DYNAMIC_INTERPRETER (output_bfd);
@@ -5964,7 +5877,7 @@ _bfd_mips_elf_size_dynamic_sections (output_bfd, info)
 
       if (strncmp (name, ".rel", 4) == 0)
        {
-         if (s->_raw_size == 0)
+         if (s->size == 0)
            {
              /* We only strip the section if the output section name
                  has the same name.  Otherwise, there might be several
@@ -6064,7 +5977,7 @@ _bfd_mips_elf_size_dynamic_sections (output_bfd, info)
        {
          /* IRIX rld assumes that the function stub isn't at the end
             of .text section. So put a dummy. XXX  */
-         s->_raw_size += MIPS_FUNCTION_STUB_SIZE;
+         s->size += MIPS_FUNCTION_STUB_SIZE;
        }
       else if (! info->shared
               && ! mips_elf_hash_table (info)->use_rld_obj_head
@@ -6072,15 +5985,11 @@ _bfd_mips_elf_size_dynamic_sections (output_bfd, info)
        {
          /* We add a room for __rld_map. It will be filled in by the
             rtld to contain a pointer to the _r_debug structure.  */
-         s->_raw_size += 4;
+         s->size += 4;
        }
       else if (SGI_COMPAT (output_bfd)
               && strncmp (name, ".compact_rel", 12) == 0)
-       s->_raw_size += mips_elf_hash_table (info)->compact_rel_size;
-      else if (strcmp (name, ".msym") == 0)
-       s->_raw_size = (sizeof (Elf32_External_Msym)
-                       * (elf_hash_table (info)->dynsymcount
-                          + bfd_count_sections (output_bfd)));
+       s->size += mips_elf_hash_table (info)->compact_rel_size;
       else if (strncmp (name, ".init", 5) != 0)
        {
          /* It's not one of our sections, so don't allocate space.  */
@@ -6094,8 +6003,8 @@ _bfd_mips_elf_size_dynamic_sections (output_bfd, info)
        }
 
       /* Allocate memory for the section contents.  */
-      s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->_raw_size);
-      if (s->contents == NULL && s->_raw_size != 0)
+      s->contents = bfd_zalloc (dynobj, s->size);
+      if (s->contents == NULL && s->size != 0)
        {
          bfd_set_error (bfd_error_no_memory);
          return FALSE;
@@ -6155,30 +6064,6 @@ _bfd_mips_elf_size_dynamic_sections (output_bfd, info)
            return FALSE;
        }
 
-      if (SGI_COMPAT (output_bfd))
-       {
-         if (!MIPS_ELF_ADD_DYNAMIC_ENTRY (info, DT_MIPS_CONFLICTNO, 0))
-           return FALSE;
-       }
-
-      if (SGI_COMPAT (output_bfd))
-       {
-         if (!MIPS_ELF_ADD_DYNAMIC_ENTRY (info, DT_MIPS_LIBLISTNO, 0))
-           return FALSE;
-       }
-
-      if (bfd_get_section_by_name (dynobj, ".conflict") != NULL)
-       {
-         if (! MIPS_ELF_ADD_DYNAMIC_ENTRY (info, DT_MIPS_CONFLICT, 0))
-           return FALSE;
-
-         s = bfd_get_section_by_name (dynobj, ".liblist");
-         BFD_ASSERT (s != NULL);
-
-         if (! MIPS_ELF_ADD_DYNAMIC_ENTRY (info, DT_MIPS_LIBLIST, 0))
-           return FALSE;
-       }
-
       if (! MIPS_ELF_ADD_DYNAMIC_ENTRY (info, DT_MIPS_RLD_VERSION, 0))
        return FALSE;
 
@@ -6225,10 +6110,6 @@ _bfd_mips_elf_size_dynamic_sections (output_bfd, info)
              (dynobj, MIPS_ELF_OPTIONS_SECTION_NAME (dynobj)))
          && !MIPS_ELF_ADD_DYNAMIC_ENTRY (info, DT_MIPS_OPTIONS, 0))
        return FALSE;
-
-      if (bfd_get_section_by_name (dynobj, ".msym")
-         && !MIPS_ELF_ADD_DYNAMIC_ENTRY (info, DT_MIPS_MSYM, 0))
-       return FALSE;
     }
 
   return TRUE;
@@ -6237,22 +6118,17 @@ _bfd_mips_elf_size_dynamic_sections (output_bfd, info)
 /* Relocate a MIPS ELF section.  */
 
 bfd_boolean
-_bfd_mips_elf_relocate_section (output_bfd, info, input_bfd, input_section,
-                               contents, relocs, local_syms, local_sections)
-     bfd *output_bfd;
-     struct bfd_link_info *info;
-     bfd *input_bfd;
-     asection *input_section;
-     bfd_byte *contents;
-     Elf_Internal_Rela *relocs;
-     Elf_Internal_Sym *local_syms;
-     asection **local_sections;
+_bfd_mips_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
+                               bfd *input_bfd, asection *input_section,
+                               bfd_byte *contents, Elf_Internal_Rela *relocs,
+                               Elf_Internal_Sym *local_syms,
+                               asection **local_sections)
 {
   Elf_Internal_Rela *rel;
   const Elf_Internal_Rela *relend;
   bfd_vma addend = 0;
   bfd_boolean use_saved_addend_p = FALSE;
-  struct elf_backend_data *bed;
+  const struct elf_backend_data *bed;
 
   bed = get_elf_backend_data (output_bfd);
   relend = relocs + input_section->reloc_count * bed->s->int_rels_per_ext_rel;
@@ -6266,7 +6142,7 @@ _bfd_mips_elf_relocate_section (output_bfd, info, input_bfd, input_section,
          REL relocation.  */
       bfd_boolean rela_relocation_p = TRUE;
       unsigned int r_type = ELF_R_TYPE (output_bfd, rel->r_info);
-      const char * msg = (const char *) NULL;
+      const char *msg;
 
       /* Find the relocation howto for this relocation.  */
       if (r_type == R_MIPS_64 && ! NEWABI_P (input_bfd))
@@ -6315,13 +6191,11 @@ _bfd_mips_elf_relocate_section (output_bfd, info, input_bfd, input_section,
              addend = mips_elf_obtain_contents (howto, rel, input_bfd,
                                                 contents);
              addend &= howto->src_mask;
-             addend <<= howto->rightshift;
 
              /* For some kinds of relocations, the ADDEND is a
                 combination of the addend stored in two different
                 relocations.   */
              if (r_type == R_MIPS_HI16
-                 || r_type == R_MIPS_GNU_REL_HI16
                  || (r_type == R_MIPS_GOT16
                      && mips_elf_local_relocation_p (input_bfd, rel,
                                                      local_sections, FALSE)))
@@ -6329,7 +6203,6 @@ _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;
-                 unsigned int lo;
 
                  /* The combined value is the sum of the HI16 addend,
                     left-shifted by sixteen bits, and the LO16
@@ -6337,38 +6210,35 @@ _bfd_mips_elf_relocate_section (output_bfd, info, input_bfd, input_section,
                     a `lui' of the HI16 value, and then an `addiu' of
                     the LO16 value.)
 
-                    Scan ahead to find a matching LO16 relocation.  */
-                 if (r_type == R_MIPS_GNU_REL_HI16)
-                   lo = R_MIPS_GNU_REL_LO16;
-                 else
-                   lo = R_MIPS_LO16;
-                 lo16_relocation = mips_elf_next_relocation (input_bfd, lo,
+                    Scan ahead to find a matching LO16 relocation.
+
+                    According to the MIPS ELF ABI, the R_MIPS_LO16
+                    relocation must be immediately following.
+                    However, for the IRIX6 ABI, the next relocation
+                    may be a composed relocation consisting of
+                    several relocations for the same address.  In
+                    that case, the R_MIPS_LO16 relocation may occur
+                    as one of these.  We permit a similar extension
+                    in general, as that is useful for GCC.  */
+                 lo16_relocation = mips_elf_next_relocation (input_bfd,
+                                                             R_MIPS_LO16,
                                                              rel, relend);
                  if (lo16_relocation == NULL)
                    return FALSE;
 
                  /* Obtain the addend kept there.  */
-                 lo16_howto = MIPS_ELF_RTYPE_TO_HOWTO (input_bfd, lo, FALSE);
+                 lo16_howto = MIPS_ELF_RTYPE_TO_HOWTO (input_bfd,
+                                                       R_MIPS_LO16, FALSE);
                  l = mips_elf_obtain_contents (lo16_howto, lo16_relocation,
                                                input_bfd, contents);
                  l &= lo16_howto->src_mask;
                  l <<= lo16_howto->rightshift;
-                 l = mips_elf_sign_extend (l, 16);
+                 l = _bfd_mips_elf_sign_extend (l, 16);
 
                  addend <<= 16;
 
                  /* Compute the combined addend.  */
                  addend += l;
-
-                 /* If PC-relative, subtract the difference between the
-                    address of the LO part of the reloc and the address of
-                    the HI part.  The relocation is relative to the LO
-                    part, but mips_elf_calculate_relocation() doesn't
-                    know its address or the difference from the HI part, so
-                    we subtract that difference here.  See also the
-                    comment in mips_elf_calculate_relocation().  */
-                 if (r_type == R_MIPS_GNU_REL_HI16)
-                   addend -= (lo16_relocation->r_offset - rel->r_offset);
                }
              else if (r_type == R_MIPS16_GPREL)
                {
@@ -6379,12 +6249,14 @@ _bfd_mips_elf_relocate_section (output_bfd, info, input_bfd, input_section,
                            | ((addend & 0x7e00000) >> 16)
                            | (addend & 0x1f));
                }
+             else
+               addend <<= howto->rightshift;
            }
          else
            addend = rel->r_addend;
        }
 
-      if (info->relocateable)
+      if (info->relocatable)
        {
          Elf_Internal_Sym *sym;
          unsigned long r_symndx;
@@ -6398,7 +6270,7 @@ _bfd_mips_elf_relocate_section (output_bfd, info, input_bfd, input_section,
             they're against a section symbol, in which case we need
             to adjust by the section offset, or unless they're GP
             relative in which case we need to adjust by the amount
-            that we're adjusting GP in this relocateable object.  */
+            that we're adjusting GP in this relocatable object.  */
 
          if (! mips_elf_local_relocation_p (input_bfd, rel, local_sections,
                                             FALSE))
@@ -6418,33 +6290,24 @@ _bfd_mips_elf_relocate_section (output_bfd, info, input_bfd, input_section,
            /* Adjust the addend appropriately.  */
            addend += local_sections[r_symndx]->output_offset;
 
-         if (howto->partial_inplace)
+         if (rela_relocation_p)
+           /* If this is a RELA relocation, just update the addend.  */
+           rel->r_addend = addend;
+         else
            {
-             /* If the relocation is for a R_MIPS_HI16 or R_MIPS_GOT16,
-                then we only want to write out the high-order 16 bits.
-                The subsequent R_MIPS_LO16 will handle the low-order bits.
-              */
-             if (r_type == R_MIPS_HI16 || r_type == R_MIPS_GOT16
-                 || r_type == R_MIPS_GNU_REL_HI16)
+             if (r_type == R_MIPS_HI16
+                 || r_type == R_MIPS_GOT16)
                addend = mips_elf_high (addend);
              else if (r_type == R_MIPS_HIGHER)
                addend = mips_elf_higher (addend);
              else if (r_type == R_MIPS_HIGHEST)
                addend = mips_elf_highest (addend);
-           }
+             else
+               addend >>= howto->rightshift;
 
-         if (rela_relocation_p)
-           /* If this is a RELA relocation, just update the addend.
-              We have to cast away constness for REL.  */
-           rel->r_addend = addend;
-         else
-           {
-             /* Otherwise, we have to write the value back out.  Note
-                that we use the source mask, rather than the
-                destination mask because the place to which we are
-                writing will be source of the addend in the final
-                link.  */
-             addend >>= howto->rightshift;
+             /* We use the source mask, rather than the destination
+                mask because the place to which we are writing will be
+                source of the addend in the final link.  */
              addend &= howto->src_mask;
 
              if (r_type == R_MIPS_64 && ! NEWABI_P (output_bfd))
@@ -6508,8 +6371,6 @@ _bfd_mips_elf_relocate_section (output_bfd, info, input_bfd, input_section,
       else
        use_saved_addend_p = FALSE;
 
-      addend >>= howto->rightshift;
-
       /* Figure out what value we are supposed to relocate.  */
       switch (mips_elf_calculate_relocation (output_bfd, input_bfd,
                                             input_section, info, rel,
@@ -6544,7 +6405,7 @@ _bfd_mips_elf_relocate_section (output_bfd, info, input_bfd, input_section,
            {
              BFD_ASSERT (name != NULL);
              if (! ((*info->callbacks->reloc_overflow)
-                    (info, name, howto->name, (bfd_vma) 0,
+                    (info, name, howto->name, 0,
                      input_bfd, input_section, rel->r_offset)))
                return FALSE;
            }
@@ -6625,10 +6486,8 @@ _bfd_mips_elf_relocate_section (output_bfd, info, input_bfd, input_section,
    adjust it appropriately now.  */
 
 static void
-mips_elf_irix6_finish_dynamic_symbol (abfd, name, sym)
-     bfd *abfd ATTRIBUTE_UNUSED;
-     const char *name;
-     Elf_Internal_Sym *sym;
+mips_elf_irix6_finish_dynamic_symbol (bfd *abfd ATTRIBUTE_UNUSED,
+                                     const char *name, Elf_Internal_Sym *sym)
 {
   /* The linker script takes care of providing names and values for
      these, but we must place them into the right sections.  */
@@ -6661,6 +6520,7 @@ mips_elf_irix6_finish_dynamic_symbol (abfd, name, sym)
          /* All of these symbols are given type STT_SECTION by the
             IRIX6 linker.  */
          sym->st_info = ELF_ST_INFO (STB_GLOBAL, STT_SECTION);
+         sym->st_other = STO_PROTECTED;
 
          /* The IRIX linker puts these symbols in special sections.  */
          if (i == 0)
@@ -6676,25 +6536,19 @@ mips_elf_irix6_finish_dynamic_symbol (abfd, name, sym)
    dynamic sections here.  */
 
 bfd_boolean
-_bfd_mips_elf_finish_dynamic_symbol (output_bfd, info, h, sym)
-     bfd *output_bfd;
-     struct bfd_link_info *info;
-     struct elf_link_hash_entry *h;
-     Elf_Internal_Sym *sym;
+_bfd_mips_elf_finish_dynamic_symbol (bfd *output_bfd,
+                                    struct bfd_link_info *info,
+                                    struct elf_link_hash_entry *h,
+                                    Elf_Internal_Sym *sym)
 {
   bfd *dynobj;
-  bfd_vma gval;
   asection *sgot;
-  asection *smsym;
   struct mips_got_info *g, *gg;
   const char *name;
-  struct mips_elf_link_hash_entry *mh;
 
   dynobj = elf_hash_table (info)->dynobj;
-  gval = sym->st_value;
-  mh = (struct mips_elf_link_hash_entry *) h;
 
-  if (h->plt.offset != (bfd_vma) -1)
+  if (h->plt.offset != MINUS_ONE)
     {
       asection *s;
       bfd_byte stub[MIPS_FUNCTION_STUB_SIZE];
@@ -6717,7 +6571,7 @@ _bfd_mips_elf_finish_dynamic_symbol (output_bfd, info, h, sym)
       bfd_put_32 (output_bfd, STUB_JALR, stub + 8);
       bfd_put_32 (output_bfd, STUB_LI16 (output_bfd) + h->dynindx, stub + 12);
 
-      BFD_ASSERT (h->plt.offset <= s->_raw_size);
+      BFD_ASSERT (h->plt.offset <= s->size);
       memcpy (s->contents + h->plt.offset, stub, MIPS_FUNCTION_STUB_SIZE);
 
       /* Mark the symbol as undefined.  plt.offset != -1 occurs
@@ -6727,8 +6581,8 @@ _bfd_mips_elf_finish_dynamic_symbol (output_bfd, info, h, sym)
       /* The run-time linker uses the st_value field of the symbol
         to reset the global offset table entry for this external
         to its stub address when unlinking a shared object.  */
-      gval = s->output_section->vma + s->output_offset + h->plt.offset;
-      sym->st_value = gval;
+      sym->st_value = (s->output_section->vma + s->output_offset
+                      + h->plt.offset);
     }
 
   BFD_ASSERT (h->dynindx != -1
@@ -6748,22 +6602,7 @@ _bfd_mips_elf_finish_dynamic_symbol (output_bfd, info, h, sym)
       bfd_vma offset;
       bfd_vma value;
 
-      if (sym->st_value)
-       value = sym->st_value;
-      else
-       {
-         /* For an entity defined in a shared object, this will be
-            NULL.  (For functions in shared objects for
-            which we have created stubs, ST_VALUE will be non-NULL.
-            That's because such the functions are now no longer defined
-            in a shared object.)  */
-
-         if ((info->shared && h->root.type == bfd_link_hash_undefined)
-             || h->root.type == bfd_link_hash_undefweak)
-           value = 0;
-         else
-           value = h->root.u.def.value;
-       }
+      value = sym->st_value;
       offset = mips_elf_global_got_index (dynobj, output_bfd, h);
       MIPS_ELF_PUT_WORD (output_bfd, value, sgot->contents + offset);
     }
@@ -6771,10 +6610,8 @@ _bfd_mips_elf_finish_dynamic_symbol (output_bfd, info, h, sym)
   if (g->next && h->dynindx != -1)
     {
       struct mips_got_entry e, *p;
+      bfd_vma entry;
       bfd_vma offset;
-      bfd_vma value;
-      Elf_Internal_Rela rel[3];
-      bfd_vma addend = 0;
 
       gg = g;
 
@@ -6782,18 +6619,6 @@ _bfd_mips_elf_finish_dynamic_symbol (output_bfd, info, h, sym)
       e.symndx = -1;
       e.d.h = (struct mips_elf_link_hash_entry *)h;
 
-      if (info->shared
-         || h->root.type == bfd_link_hash_undefined
-         || h->root.type == bfd_link_hash_undefweak)
-       value = 0;
-      else if (sym->st_value)
-       value = sym->st_value;
-      else
-       value = h->root.u.def.value;
-
-      memset (rel, 0, sizeof (rel));
-      rel[0].r_info = ELF_R_INFO (output_bfd, 0, R_MIPS_REL32);
-
       for (g = g->next; g->next != gg; g = g->next)
        {
          if (g->got_entries
@@ -6801,41 +6626,41 @@ _bfd_mips_elf_finish_dynamic_symbol (output_bfd, info, h, sym)
                                                           &e)))
            {
              offset = p->gotidx;
-             rel[0].r_offset = rel[1].r_offset = rel[2].r_offset = offset;
-
-             MIPS_ELF_PUT_WORD (output_bfd, value, sgot->contents + offset);
-
-             if ((info->shared
-                  || (elf_hash_table (info)->dynamic_sections_created
-                      && p->d.h != NULL
-                      && ((p->d.h->root.elf_link_hash_flags
-                           & ELF_LINK_HASH_DEF_DYNAMIC) != 0)
-                      && ((p->d.h->root.elf_link_hash_flags
-                           & ELF_LINK_HASH_DEF_REGULAR) == 0)))
-                 && ! (mips_elf_create_dynamic_relocation
-                       (output_bfd, info, rel,
-                        e.d.h, NULL, value, &addend, sgot)))
-               return FALSE;
-             BFD_ASSERT (addend == 0);
+             if (info->shared
+                 || (elf_hash_table (info)->dynamic_sections_created
+                     && p->d.h != NULL
+                     && ((p->d.h->root.elf_link_hash_flags
+                          & ELF_LINK_HASH_DEF_DYNAMIC) != 0)
+                     && ((p->d.h->root.elf_link_hash_flags
+                          & ELF_LINK_HASH_DEF_REGULAR) == 0)))
+               {
+                 /* Create an R_MIPS_REL32 relocation for this entry.  Due to
+                    the various compatibility problems, it's easier to mock
+                    up an R_MIPS_32 or R_MIPS_64 relocation and leave
+                    mips_elf_create_dynamic_relocation to calculate the
+                    appropriate addend.  */
+                 Elf_Internal_Rela rel[3];
+
+                 memset (rel, 0, sizeof (rel));
+                 if (ABI_64_P (output_bfd))
+                   rel[0].r_info = ELF_R_INFO (output_bfd, 0, R_MIPS_64);
+                 else
+                   rel[0].r_info = ELF_R_INFO (output_bfd, 0, R_MIPS_32);
+                 rel[0].r_offset = rel[1].r_offset = rel[2].r_offset = offset;
+
+                 entry = 0;
+                 if (! (mips_elf_create_dynamic_relocation
+                        (output_bfd, info, rel,
+                         e.d.h, NULL, sym->st_value, &entry, sgot)))
+                   return FALSE;
+               }
+             else
+               entry = sym->st_value;
+             MIPS_ELF_PUT_WORD (output_bfd, entry, sgot->contents + offset);
            }
        }
     }
 
-  /* Create a .msym entry, if appropriate.  */
-  smsym = bfd_get_section_by_name (dynobj, ".msym");
-  if (smsym)
-    {
-      Elf32_Internal_Msym msym;
-
-      msym.ms_hash_value = bfd_elf_hash (h->root.root.string);
-      /* It is undocumented what the `1' indicates, but IRIX6 uses
-        this value.  */
-      msym.ms_info = ELF32_MS_INFO (mh->min_dyn_reloc_index, 1);
-      bfd_mips_elf_swap_msym_out
-       (dynobj, &msym,
-        ((Elf32_External_Msym *) smsym->contents) + h->dynindx);
-    }
-
   /* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute.  */
   name = h->root.root.string;
   if (strcmp (name, "_DYNAMIC") == 0
@@ -6893,7 +6718,7 @@ _bfd_mips_elf_finish_dynamic_symbol (output_bfd, info, h, sym)
          asection *s = bfd_get_section_by_name (dynobj, ".rld_map");
          BFD_ASSERT (s != NULL);
          sym->st_value = s->output_section->vma + s->output_offset;
-         bfd_put_32 (output_bfd, (bfd_vma) 0, s->contents);
+         bfd_put_32 (output_bfd, 0, s->contents);
          if (mips_elf_hash_table (info)->rld_value == 0)
            mips_elf_hash_table (info)->rld_value = sym->st_value;
        }
@@ -6910,9 +6735,8 @@ _bfd_mips_elf_finish_dynamic_symbol (output_bfd, info, h, sym)
     }
 
   /* If this is a mips16 symbol, force the value to be even.  */
-  if (sym->st_other == STO_MIPS16
-      && (sym->st_value & 1) != 0)
-    --sym->st_value;
+  if (sym->st_other == STO_MIPS16)
+    sym->st_value &= ~1;
 
   return TRUE;
 }
@@ -6920,9 +6744,8 @@ _bfd_mips_elf_finish_dynamic_symbol (output_bfd, info, h, sym)
 /* Finish up the dynamic sections.  */
 
 bfd_boolean
-_bfd_mips_elf_finish_dynamic_sections (output_bfd, info)
-     bfd *output_bfd;
-     struct bfd_link_info *info;
+_bfd_mips_elf_finish_dynamic_sections (bfd *output_bfd,
+                                      struct bfd_link_info *info)
 {
   bfd *dynobj;
   asection *sdyn;
@@ -6953,7 +6776,7 @@ _bfd_mips_elf_finish_dynamic_sections (output_bfd, info)
       BFD_ASSERT (g != NULL);
 
       for (b = sdyn->contents;
-          b < sdyn->contents + sdyn->_raw_size;
+          b < sdyn->contents + sdyn->size;
           b += MIPS_ELF_DYN_SIZE (dynobj))
        {
          Elf_Internal_Dyn dyn;
@@ -6984,13 +6807,6 @@ _bfd_mips_elf_finish_dynamic_sections (output_bfd, info)
 
            case DT_PLTGOT:
              name = ".got";
-             goto get_vma;
-           case DT_MIPS_CONFLICT:
-             name = ".conflict";
-             goto get_vma;
-           case DT_MIPS_LIBLIST:
-             name = ".liblist";
-           get_vma:
              s = bfd_get_section_by_name (output_bfd, name);
              BFD_ASSERT (s != NULL);
              dyn.d_un.d_ptr = s->vma;
@@ -7004,27 +6820,6 @@ _bfd_mips_elf_finish_dynamic_sections (output_bfd, info)
              dyn.d_un.d_val = RHF_NOTPOT; /* XXX */
              break;
 
-           case DT_MIPS_CONFLICTNO:
-             name = ".conflict";
-             elemsize = sizeof (Elf32_Conflict);
-             goto set_elemno;
-
-           case DT_MIPS_LIBLISTNO:
-             name = ".liblist";
-             elemsize = sizeof (Elf32_Lib);
-           set_elemno:
-             s = bfd_get_section_by_name (output_bfd, name);
-             if (s != NULL)
-               {
-                 if (s->_cooked_size != 0)
-                   dyn.d_un.d_val = s->_cooked_size / elemsize;
-                 else
-                   dyn.d_un.d_val = s->_raw_size / elemsize;
-               }
-             else
-               dyn.d_un.d_val = 0;
-             break;
-
            case DT_MIPS_TIME_STAMP:
              time ((time_t *) &dyn.d_un.d_val);
              break;
@@ -7072,10 +6867,7 @@ _bfd_mips_elf_finish_dynamic_sections (output_bfd, info)
              s = bfd_get_section_by_name (output_bfd, name);
              BFD_ASSERT (s != NULL);
 
-             if (s->_cooked_size != 0)
-               dyn.d_un.d_val = s->_cooked_size / elemsize;
-             else
-               dyn.d_un.d_val = s->_raw_size / elemsize;
+             dyn.d_un.d_val = s->size / elemsize;
              break;
 
            case DT_MIPS_HIPAGENO:
@@ -7092,9 +6884,16 @@ _bfd_mips_elf_finish_dynamic_sections (output_bfd, info)
              dyn.d_un.d_ptr = s->vma;
              break;
 
-           case DT_MIPS_MSYM:
-             s = (bfd_get_section_by_name (output_bfd, ".msym"));
-             dyn.d_un.d_ptr = s->vma;
+           case DT_RELSZ:
+             /* Reduce DT_RELSZ to account for any relocations we
+                decided not to make.  This is for the n64 irix rld,
+                which doesn't seem to apply any relocations if there
+                are trailing null entries.  */
+             s = mips_elf_rel_dyn_section (dynobj, FALSE);
+             dyn.d_un.d_val = (s->reloc_count
+                               * (ABI_64_P (output_bfd)
+                                  ? sizeof (Elf64_Mips_External_Rel)
+                                  : sizeof (Elf32_External_Rel)));
              break;
 
            default:
@@ -7111,10 +6910,10 @@ _bfd_mips_elf_finish_dynamic_sections (output_bfd, info)
   /* The first entry of the global offset table will be filled at
      runtime. The second entry will be used by some runtime loaders.
      This isn't the case of IRIX rld.  */
-  if (sgot != NULL && sgot->_raw_size > 0)
+  if (sgot != NULL && sgot->size > 0)
     {
-      MIPS_ELF_PUT_WORD (output_bfd, (bfd_vma) 0, sgot->contents);
-      MIPS_ELF_PUT_WORD (output_bfd, (bfd_vma) 0x80000000,
+      MIPS_ELF_PUT_WORD (output_bfd, 0, sgot->contents);
+      MIPS_ELF_PUT_WORD (output_bfd, 0x80000000,
                         sgot->contents + MIPS_ELF_GOT_SIZE (output_bfd));
     }
 
@@ -7135,9 +6934,9 @@ _bfd_mips_elf_finish_dynamic_sections (output_bfd, info)
        {
          bfd_vma index = g->next->local_gotno + g->next->global_gotno;
 
-         MIPS_ELF_PUT_WORD (output_bfd, (bfd_vma) 0, sgot->contents
+         MIPS_ELF_PUT_WORD (output_bfd, 0, sgot->contents
                             + index++ * MIPS_ELF_GOT_SIZE (output_bfd));
-         MIPS_ELF_PUT_WORD (output_bfd, (bfd_vma) 0x80000000, sgot->contents
+         MIPS_ELF_PUT_WORD (output_bfd, 0x80000000, sgot->contents
                             + index++ * MIPS_ELF_GOT_SIZE (output_bfd));
 
          if (! info->shared)
@@ -7158,33 +6957,9 @@ _bfd_mips_elf_finish_dynamic_sections (output_bfd, info)
     }
 
   {
-    asection *smsym;
     asection *s;
     Elf32_compact_rel cpt;
 
-    /* ??? The section symbols for the output sections were set up in
-       _bfd_elf_final_link.  SGI sets the STT_NOTYPE attribute for these
-       symbols.  Should we do so?  */
-
-    smsym = bfd_get_section_by_name (dynobj, ".msym");
-    if (smsym != NULL)
-      {
-       Elf32_Internal_Msym msym;
-
-       msym.ms_hash_value = 0;
-       msym.ms_info = ELF32_MS_INFO (0, 1);
-
-       for (s = output_bfd->sections; s != NULL; s = s->next)
-         {
-           long dynindx = elf_section_data (s)->dynindx;
-
-           bfd_mips_elf_swap_msym_out
-             (output_bfd, &msym,
-              (((Elf32_External_Msym *) smsym->contents)
-               + dynindx));
-         }
-      }
-
     if (SGI_COMPAT (output_bfd))
       {
        /* Write .compact_rel section out.  */
@@ -7209,8 +6984,8 @@ _bfd_mips_elf_finish_dynamic_sections (output_bfd, info)
              {
                file_ptr dummy_offset;
 
-               BFD_ASSERT (s->_raw_size >= MIPS_FUNCTION_STUB_SIZE);
-               dummy_offset = s->_raw_size - MIPS_FUNCTION_STUB_SIZE;
+               BFD_ASSERT (s->size >= MIPS_FUNCTION_STUB_SIZE);
+               dummy_offset = s->size - MIPS_FUNCTION_STUB_SIZE;
                memset (s->contents + dummy_offset, 0,
                        MIPS_FUNCTION_STUB_SIZE);
              }
@@ -7222,17 +6997,15 @@ _bfd_mips_elf_finish_dynamic_sections (output_bfd, info)
     s = mips_elf_rel_dyn_section (dynobj, FALSE);
 
     if (s != NULL
-       && s->_raw_size > (bfd_vma)2 * MIPS_ELF_REL_SIZE (output_bfd))
+       && s->size > (bfd_vma)2 * MIPS_ELF_REL_SIZE (output_bfd))
       {
        reldyn_sorting_bfd = output_bfd;
 
        if (ABI_64_P (output_bfd))
-         qsort ((Elf64_External_Rel *) s->contents + 1,
-                (size_t) s->reloc_count - 1,
+         qsort ((Elf64_External_Rel *) s->contents + 1, s->reloc_count - 1,
                 sizeof (Elf64_Mips_External_Rel), sort_dynamic_relocs_64);
        else
-         qsort ((Elf32_External_Rel *) s->contents + 1,
-                (size_t) s->reloc_count - 1,
+         qsort ((Elf32_External_Rel *) s->contents + 1, s->reloc_count - 1,
                 sizeof (Elf32_External_Rel), sort_dynamic_relocs);
       }
   }
@@ -7244,8 +7017,7 @@ _bfd_mips_elf_finish_dynamic_sections (output_bfd, info)
 /* Set ABFD's EF_MIPS_ARCH and EF_MIPS_MACH flags.  */
 
 static void
-mips_set_isa_flags (abfd)
-     bfd *abfd;
+mips_set_isa_flags (bfd *abfd)
 {
   flagword val;
 
@@ -7300,6 +7072,7 @@ mips_set_isa_flags (abfd)
       break;
 
     case bfd_mach_mips5000:
+    case bfd_mach_mips7000:
     case bfd_mach_mips8000:
     case bfd_mach_mips10000:
     case bfd_mach_mips12000:
@@ -7325,6 +7098,10 @@ mips_set_isa_flags (abfd)
     case bfd_mach_mipsisa32r2:
       val = E_MIPS_ARCH_32R2;
       break;
+
+    case bfd_mach_mipsisa64r2:
+      val = E_MIPS_ARCH_64R2;
+      break;
     }
   elf_elfheader (abfd)->e_flags &= ~(EF_MIPS_ARCH | EF_MIPS_MACH);
   elf_elfheader (abfd)->e_flags |= val;
@@ -7337,9 +7114,8 @@ mips_set_isa_flags (abfd)
    number.  This is used by both the 32-bit and the 64-bit ABI.  */
 
 void
-_bfd_mips_elf_final_write_processing (abfd, linker)
-     bfd *abfd;
-     bfd_boolean linker ATTRIBUTE_UNUSED;
+_bfd_mips_elf_final_write_processing (bfd *abfd,
+                                     bfd_boolean linker ATTRIBUTE_UNUSED)
 {
   unsigned int i;
   Elf_Internal_Shdr **hdrpp;
@@ -7425,8 +7201,7 @@ _bfd_mips_elf_final_write_processing (abfd, linker)
    segments.  */
 
 int
-_bfd_mips_elf_additional_program_headers (abfd)
-     bfd *abfd;
+_bfd_mips_elf_additional_program_headers (bfd *abfd)
 {
   asection *s;
   int ret = 0;
@@ -7454,8 +7229,8 @@ _bfd_mips_elf_additional_program_headers (abfd)
 /* Modify the segment map for an IRIX5 executable.  */
 
 bfd_boolean
-_bfd_mips_elf_modify_segment_map (abfd)
-     bfd *abfd;
+_bfd_mips_elf_modify_segment_map (bfd *abfd,
+                                 struct bfd_link_info *info ATTRIBUTE_UNUSED)
 {
   asection *s;
   struct elf_segment_map *m, **pm;
@@ -7472,7 +7247,7 @@ _bfd_mips_elf_modify_segment_map (abfd)
       if (m == NULL)
        {
          amt = sizeof *m;
-         m = (struct elf_segment_map *) bfd_zalloc (abfd, amt);
+         m = bfd_zalloc (abfd, amt);
          if (m == NULL)
            return FALSE;
 
@@ -7494,7 +7269,7 @@ _bfd_mips_elf_modify_segment_map (abfd)
 
   /* For IRIX 6, we don't have .mdebug sections, nor does anything but
      .dynamic end up in PT_DYNAMIC.  However, we do have to insert a
-     PT_OPTIONS segment immediately following the program header
+     PT_MIPS_OPTIONS segment immediately following the program header
      table.  */
   if (NEWABI_P (abfd)
       /* On non-IRIX6 new abi, we'll have already created a segment
@@ -7511,15 +7286,11 @@ _bfd_mips_elf_modify_segment_map (abfd)
        {
          struct elf_segment_map *options_segment;
 
-         /* Usually, there's a program header table.  But, sometimes
-            there's not (like when running the `ld' testsuite).  So,
-            if there's no program header table, we just put the
-            options segment at the end.  */
-         for (pm = &elf_tdata (abfd)->segment_map;
-              *pm != NULL;
-              pm = &(*pm)->next)
-           if ((*pm)->p_type == PT_PHDR)
-             break;
+         pm = &elf_tdata (abfd)->segment_map;
+         while (*pm != NULL
+                && ((*pm)->p_type == PT_PHDR
+                    || (*pm)->p_type == PT_INTERP))
+           pm = &(*pm)->next;
 
          amt = sizeof (struct elf_segment_map);
          options_segment = bfd_zalloc (abfd, amt);
@@ -7548,7 +7319,7 @@ _bfd_mips_elf_modify_segment_map (abfd)
              if (m == NULL)
                {
                  amt = sizeof *m;
-                 m = (struct elf_segment_map *) bfd_zalloc (abfd, amt);
+                 m = bfd_zalloc (abfd, amt);
                  if (m == NULL)
                    return FALSE;
 
@@ -7610,7 +7381,7 @@ _bfd_mips_elf_modify_segment_map (abfd)
          unsigned int i, c;
          struct elf_segment_map *n;
 
-         low = 0xffffffff;
+         low = ~(bfd_vma) 0;
          high = 0;
          for (i = 0; i < sizeof sec_names / sizeof sec_names[0]; i++)
            {
@@ -7621,9 +7392,7 @@ _bfd_mips_elf_modify_segment_map (abfd)
 
                  if (low > s->vma)
                    low = s->vma;
-                 sz = s->_cooked_size;
-                 if (sz == 0)
-                   sz = s->_raw_size;
+                 sz = s->size;
                  if (high < s->vma + sz)
                    high = s->vma + sz;
                }
@@ -7633,13 +7402,11 @@ _bfd_mips_elf_modify_segment_map (abfd)
          for (s = abfd->sections; s != NULL; s = s->next)
            if ((s->flags & SEC_LOAD) != 0
                && s->vma >= low
-               && ((s->vma
-                    + (s->_cooked_size !=
-                       0 ? s->_cooked_size : s->_raw_size)) <= high))
+               && s->vma + s->size <= high)
              ++c;
 
          amt = sizeof *n + (bfd_size_type) (c - 1) * sizeof (asection *);
-         n = (struct elf_segment_map *) bfd_zalloc (abfd, amt);
+         n = bfd_zalloc (abfd, amt);
          if (n == NULL)
            return FALSE;
          *n = *m;
@@ -7650,9 +7417,7 @@ _bfd_mips_elf_modify_segment_map (abfd)
            {
              if ((s->flags & SEC_LOAD) != 0
                  && s->vma >= low
-                 && ((s->vma
-                      + (s->_cooked_size != 0 ?
-                         s->_cooked_size : s->_raw_size)) <= high))
+                 && s->vma + s->size <= high)
                {
                  n->sections[i] = s;
                  ++i;
@@ -7670,12 +7435,11 @@ _bfd_mips_elf_modify_segment_map (abfd)
    relocation.  */
 
 asection *
-_bfd_mips_elf_gc_mark_hook (sec, info, rel, h, sym)
-     asection *sec;
-     struct bfd_link_info *info ATTRIBUTE_UNUSED;
-     Elf_Internal_Rela *rel;
-     struct elf_link_hash_entry *h;
-     Elf_Internal_Sym *sym;
+_bfd_mips_elf_gc_mark_hook (asection *sec,
+                           struct bfd_link_info *info ATTRIBUTE_UNUSED,
+                           Elf_Internal_Rela *rel,
+                           struct elf_link_hash_entry *h,
+                           Elf_Internal_Sym *sym)
 {
   /* ??? Do mips16 stub sections need to be handled special?  */
 
@@ -7711,11 +7475,10 @@ _bfd_mips_elf_gc_mark_hook (sec, info, rel, h, sym)
 /* Update the got entry reference counts for the section being removed.  */
 
 bfd_boolean
-_bfd_mips_elf_gc_sweep_hook (abfd, info, sec, relocs)
-     bfd *abfd ATTRIBUTE_UNUSED;
-     struct bfd_link_info *info ATTRIBUTE_UNUSED;
-     asection *sec ATTRIBUTE_UNUSED;
-     const Elf_Internal_Rela *relocs ATTRIBUTE_UNUSED;
+_bfd_mips_elf_gc_sweep_hook (bfd *abfd ATTRIBUTE_UNUSED,
+                            struct bfd_link_info *info ATTRIBUTE_UNUSED,
+                            asection *sec ATTRIBUTE_UNUSED,
+                            const Elf_Internal_Rela *relocs ATTRIBUTE_UNUSED)
 {
 #if 0
   Elf_Internal_Shdr *symtab_hdr;
@@ -7761,9 +7524,9 @@ _bfd_mips_elf_gc_sweep_hook (abfd, info, sec, relocs)
    _bfd_elf_link_hash_copy_indirect copy the flags for us.  */
 
 void
-_bfd_mips_elf_copy_indirect_symbol (bed, dir, ind)
-     struct elf_backend_data *bed;
-     struct elf_link_hash_entry *dir, *ind;
+_bfd_mips_elf_copy_indirect_symbol (const struct elf_backend_data *bed,
+                                   struct elf_link_hash_entry *dir,
+                                   struct elf_link_hash_entry *ind)
 {
   struct mips_elf_link_hash_entry *dirmips, *indmips;
 
@@ -7777,19 +7540,14 @@ _bfd_mips_elf_copy_indirect_symbol (bed, dir, 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))
-    dirmips->min_dyn_reloc_index = indmips->min_dyn_reloc_index;
   if (indmips->no_fn_stub)
     dirmips->no_fn_stub = TRUE;
 }
 
 void
-_bfd_mips_elf_hide_symbol (info, entry, force_local)
-     struct bfd_link_info *info;
-     struct elf_link_hash_entry *entry;
-     bfd_boolean force_local;
+_bfd_mips_elf_hide_symbol (struct bfd_link_info *info,
+                          struct elf_link_hash_entry *entry,
+                          bfd_boolean force_local)
 {
   bfd *dynobj;
   asection *got;
@@ -7799,10 +7557,10 @@ _bfd_mips_elf_hide_symbol (info, entry, force_local)
   h = (struct mips_elf_link_hash_entry *) entry;
   if (h->forced_local)
     return;
-  h->forced_local = TRUE;
+  h->forced_local = force_local;
 
   dynobj = elf_hash_table (info)->dynobj;
-  if (dynobj != NULL)
+  if (dynobj != NULL && force_local)
     {
       got = mips_elf_got_section (dynobj, FALSE);
       g = mips_elf_section_data (got)->u.got_info;
@@ -7861,10 +7619,8 @@ _bfd_mips_elf_hide_symbol (info, entry, force_local)
 #define PDR_SIZE 32
 
 bfd_boolean
-_bfd_mips_elf_discard_info (abfd, cookie, info)
-     bfd *abfd;
-     struct elf_reloc_cookie *cookie;
-     struct bfd_link_info *info;
+_bfd_mips_elf_discard_info (bfd *abfd, struct elf_reloc_cookie *cookie,
+                           struct bfd_link_info *info)
 {
   asection *o;
   bfd_boolean ret = FALSE;
@@ -7874,20 +7630,19 @@ _bfd_mips_elf_discard_info (abfd, cookie, info)
   o = bfd_get_section_by_name (abfd, ".pdr");
   if (! o)
     return FALSE;
-  if (o->_raw_size == 0)
+  if (o->size == 0)
     return FALSE;
-  if (o->_raw_size % PDR_SIZE != 0)
+  if (o->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);
+  tdata = bfd_zmalloc (o->size / PDR_SIZE);
   if (! tdata)
     return FALSE;
 
-  cookie->rels = _bfd_elf_link_read_relocs (abfd, o, (PTR) NULL,
-                                           (Elf_Internal_Rela *) NULL,
+  cookie->rels = _bfd_elf_link_read_relocs (abfd, o, NULL, NULL,
                                            info->keep_memory);
   if (!cookie->rels)
     {
@@ -7898,9 +7653,9 @@ _bfd_mips_elf_discard_info (abfd, cookie, info)
   cookie->rel = cookie->rels;
   cookie->relend = cookie->rels + o->reloc_count;
 
-  for (i = 0, skip = 0; i < o->_raw_size; i ++)
+  for (i = 0, skip = 0; i < o->size / PDR_SIZE; i ++)
     {
-      if (MNAME(abfd,_bfd_elf,reloc_symbol_deleted_p) (i * PDR_SIZE, cookie))
+      if (bfd_elf_reloc_symbol_deleted_p (i * PDR_SIZE, cookie))
        {
          tdata[i] = 1;
          skip ++;
@@ -7910,7 +7665,7 @@ _bfd_mips_elf_discard_info (abfd, cookie, info)
   if (skip != 0)
     {
       mips_elf_section_data (o)->u.tdata = tdata;
-      o->_cooked_size = o->_raw_size - skip * PDR_SIZE;
+      o->size -= skip * PDR_SIZE;
       ret = TRUE;
     }
   else
@@ -7923,8 +7678,7 @@ _bfd_mips_elf_discard_info (abfd, cookie, info)
 }
 
 bfd_boolean
-_bfd_mips_elf_ignore_discarded_relocs (sec)
-     asection *sec;
+_bfd_mips_elf_ignore_discarded_relocs (asection *sec)
 {
   if (strcmp (sec->name, ".pdr") == 0)
     return TRUE;
@@ -7932,10 +7686,8 @@ _bfd_mips_elf_ignore_discarded_relocs (sec)
 }
 
 bfd_boolean
-_bfd_mips_elf_write_section (output_bfd, sec, contents)
-     bfd *output_bfd;
-     asection *sec;
-     bfd_byte *contents;
+_bfd_mips_elf_write_section (bfd *output_bfd, asection *sec,
+                            bfd_byte *contents)
 {
   bfd_byte *to, *from, *end;
   int i;
@@ -7947,7 +7699,7 @@ _bfd_mips_elf_write_section (output_bfd, sec, contents)
     return FALSE;
 
   to = contents;
-  end = contents + sec->_raw_size;
+  end = contents + sec->size;
   for (from = contents, i = 0;
        from < end;
        from += PDR_SIZE, i++)
@@ -7959,8 +7711,7 @@ _bfd_mips_elf_write_section (output_bfd, sec, contents)
       to += PDR_SIZE;
     }
   bfd_set_section_contents (output_bfd, sec->output_section, contents,
-                           (file_ptr) sec->output_offset,
-                           sec->_cooked_size);
+                           sec->output_offset, sec->size);
   return TRUE;
 }
 \f
@@ -7974,15 +7725,11 @@ struct mips_elf_find_line
 };
 
 bfd_boolean
-_bfd_mips_elf_find_nearest_line (abfd, section, symbols, offset, filename_ptr,
-                                functionname_ptr, line_ptr)
-     bfd *abfd;
-     asection *section;
-     asymbol **symbols;
-     bfd_vma offset;
-     const char **filename_ptr;
-     const char **functionname_ptr;
-     unsigned int *line_ptr;
+_bfd_mips_elf_find_nearest_line (bfd *abfd, asection *section,
+                                asymbol **symbols, bfd_vma offset,
+                                const char **filename_ptr,
+                                const char **functionname_ptr,
+                                unsigned int *line_ptr)
 {
   asection *msec;
 
@@ -7993,8 +7740,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,
-                                    (unsigned) (ABI_64_P (abfd) ? 8 : 0),
+                                    line_ptr, ABI_64_P (abfd) ? 8 : 0,
                                     &elf_tdata (abfd)->dwarf2_find_line_info))
     return TRUE;
 
@@ -8022,7 +7768,7 @@ _bfd_mips_elf_find_nearest_line (abfd, section, symbols, offset, filename_ptr,
          struct fdr *fdr_ptr;
          bfd_size_type amt = sizeof (struct mips_elf_find_line);
 
-         fi = (struct mips_elf_find_line *) bfd_zalloc (abfd, amt);
+         fi = bfd_zalloc (abfd, amt);
          if (fi == NULL)
            {
              msec->flags = origflags;
@@ -8037,7 +7783,7 @@ _bfd_mips_elf_find_nearest_line (abfd, section, symbols, offset, filename_ptr,
 
          /* Swap in the FDR information.  */
          amt = fi->d.symbolic_header.ifdMax * sizeof (struct fdr);
-         fi->d.fdr = (struct fdr *) bfd_alloc (abfd, amt);
+         fi->d.fdr = bfd_alloc (abfd, amt);
          if (fi->d.fdr == NULL)
            {
              msec->flags = origflags;
@@ -8049,7 +7795,7 @@ _bfd_mips_elf_find_nearest_line (abfd, section, symbols, offset, filename_ptr,
          fraw_end = (fraw_src
                      + fi->d.symbolic_header.ifdMax * external_fdr_size);
          for (; fraw_src < fraw_end; fraw_src += external_fdr_size, fdr_ptr++)
-           (*swap->swap_fdr_in) (abfd, (PTR) fraw_src, fdr_ptr);
+           (*swap->swap_fdr_in) (abfd, fraw_src, fdr_ptr);
 
          elf_tdata (abfd)->find_line_info = fi;
 
@@ -8084,12 +7830,9 @@ _bfd_mips_elf_find_nearest_line (abfd, section, symbols, offset, filename_ptr,
    GP value in the section_processing routine.  */
 
 bfd_boolean
-_bfd_mips_elf_set_section_contents (abfd, section, location, offset, count)
-     bfd *abfd;
-     sec_ptr section;
-     PTR location;
-     file_ptr offset;
-     bfd_size_type count;
+_bfd_mips_elf_set_section_contents (bfd *abfd, sec_ptr section,
+                                   const void *location,
+                                   file_ptr offset, bfd_size_type count)
 {
   if (strcmp (section->name, MIPS_ELF_OPTIONS_SECTION_NAME (abfd)) == 0)
     {
@@ -8098,26 +7841,20 @@ _bfd_mips_elf_set_section_contents (abfd, section, location, offset, count)
       if (elf_section_data (section) == NULL)
        {
          bfd_size_type amt = sizeof (struct bfd_elf_section_data);
-         section->used_by_bfd = (PTR) bfd_zalloc (abfd, amt);
+         section->used_by_bfd = bfd_zalloc (abfd, amt);
          if (elf_section_data (section) == NULL)
            return FALSE;
        }
       c = mips_elf_section_data (section)->u.tdata;
       if (c == NULL)
        {
-         bfd_size_type size;
-
-         if (section->_cooked_size != 0)
-           size = section->_cooked_size;
-         else
-           size = section->_raw_size;
-         c = (bfd_byte *) bfd_zalloc (abfd, size);
+         c = bfd_zalloc (abfd, section->size);
          if (c == NULL)
            return FALSE;
          mips_elf_section_data (section)->u.tdata = c;
        }
 
-      memcpy (c + offset, location, (size_t) count);
+      memcpy (c + offset, location, count);
     }
 
   return _bfd_elf_set_section_contents (abfd, section, location, offset,
@@ -8128,18 +7865,18 @@ _bfd_mips_elf_set_section_contents (abfd, section, location, offset, count)
    MIPS relocations need to be handled specially.  Sigh.  */
 
 bfd_byte *
-_bfd_elf_mips_get_relocated_section_contents (abfd, link_info, link_order,
-                                             data, relocateable, symbols)
-     bfd *abfd;
-     struct bfd_link_info *link_info;
-     struct bfd_link_order *link_order;
-     bfd_byte *data;
-     bfd_boolean relocateable;
-     asymbol **symbols;
+_bfd_elf_mips_get_relocated_section_contents
+  (bfd *abfd,
+   struct bfd_link_info *link_info,
+   struct bfd_link_order *link_order,
+   bfd_byte *data,
+   bfd_boolean relocatable,
+   asymbol **symbols)
 {
   /* Get enough memory to hold the stuff */
   bfd *input_bfd = link_order->u.indirect.section->owner;
   asection *input_section = link_order->u.indirect.section;
+  bfd_size_type sz;
 
   long reloc_size = bfd_get_reloc_upper_bound (input_bfd, input_section);
   arelent **reloc_vector = NULL;
@@ -8148,22 +7885,15 @@ _bfd_elf_mips_get_relocated_section_contents (abfd, link_info, link_order,
   if (reloc_size < 0)
     goto error_return;
 
-  reloc_vector = (arelent **) bfd_malloc ((bfd_size_type) reloc_size);
+  reloc_vector = bfd_malloc (reloc_size);
   if (reloc_vector == NULL && reloc_size != 0)
     goto error_return;
 
   /* read in the section */
-  if (!bfd_get_section_contents (input_bfd,
-                                input_section,
-                                (PTR) data,
-                                (file_ptr) 0,
-                                input_section->_raw_size))
+  sz = input_section->rawsize ? input_section->rawsize : input_section->size;
+  if (!bfd_get_section_contents (input_bfd, input_section, data, 0, sz))
     goto error_return;
 
-  /* We're not relaxing the section, so just copy the size info */
-  input_section->_cooked_size = input_section->_raw_size;
-  input_section->reloc_done = TRUE;
-
   reloc_count = bfd_canonicalize_reloc (input_bfd,
                                        input_section,
                                        reloc_vector,
@@ -8219,10 +7949,9 @@ _bfd_elf_mips_get_relocated_section_contents (abfd, link_info, link_order,
          gp_found = 0;
       }
       /* end mips */
-      for (parent = reloc_vector; *parent != (arelent *) NULL;
-          parent++)
+      for (parent = reloc_vector; *parent != NULL; parent++)
        {
-         char *error_message = (char *) NULL;
+         char *error_message = NULL;
          bfd_reloc_status_type r;
 
          /* Specific to MIPS: Deal with relocation types that require
@@ -8242,21 +7971,18 @@ _bfd_elf_mips_get_relocated_section_contents (abfd, link_info, link_order,
            {
              /* bypass special_function call */
              r = _bfd_mips_elf_gprel16_with_gp (input_bfd, sym, *parent,
-                                                input_section, relocateable,
-                                                (PTR) data, gp);
+                                                input_section, relocatable,
+                                                data, gp);
              goto skip_bfd_perform_relocation;
            }
          /* end mips specific stuff */
 
-         r = bfd_perform_relocation (input_bfd,
-                                     *parent,
-                                     (PTR) data,
-                                     input_section,
-                                     relocateable ? abfd : (bfd *) NULL,
+         r = bfd_perform_relocation (input_bfd, *parent, data, input_section,
+                                     relocatable ? abfd : NULL,
                                      &error_message);
        skip_bfd_perform_relocation:
 
-         if (relocateable)
+         if (relocatable)
            {
              asection *os = input_section->output_section;
 
@@ -8277,7 +8003,7 @@ _bfd_elf_mips_get_relocated_section_contents (abfd, link_info, link_order,
                    goto error_return;
                  break;
                case bfd_reloc_dangerous:
-                 BFD_ASSERT (error_message != (char *) NULL);
+                 BFD_ASSERT (error_message != NULL);
                  if (!((*link_info->callbacks->reloc_dangerous)
                        (link_info, error_message, input_bfd, input_section,
                         (*parent)->address)))
@@ -8312,14 +8038,13 @@ error_return:
 /* Create a MIPS ELF linker hash table.  */
 
 struct bfd_link_hash_table *
-_bfd_mips_elf_link_hash_table_create (abfd)
-     bfd *abfd;
+_bfd_mips_elf_link_hash_table_create (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_malloc (amt);
-  if (ret == (struct mips_elf_link_hash_table *) NULL)
+  ret = bfd_malloc (amt);
+  if (ret == NULL)
     return NULL;
 
   if (! _bfd_elf_link_hash_table_init (&ret->root, abfd,
@@ -8348,9 +8073,7 @@ _bfd_mips_elf_link_hash_table_create (abfd)
    sections together, not write them all out sequentially.  */
 
 bfd_boolean
-_bfd_mips_elf_final_link (abfd, info)
-     bfd *abfd;
-     struct bfd_link_info *info;
+_bfd_mips_elf_final_link (bfd *abfd, struct bfd_link_info *info)
 {
   asection **secpp;
   asection *o;
@@ -8362,7 +8085,7 @@ _bfd_mips_elf_final_link (abfd, info)
   const struct ecoff_debug_swap *swap
     = get_elf_backend_data (abfd)->elf_backend_ecoff_debug_swap;
   HDRR *symhdr = &debug.symbolic_header;
-  PTR mdebug_handle = NULL;
+  void *mdebug_handle = NULL;
   asection *s;
   EXTR esym;
   unsigned int i;
@@ -8458,17 +8181,16 @@ _bfd_mips_elf_final_link (abfd, info)
       struct bfd_link_hash_entry *h;
 
       h = bfd_link_hash_lookup (info->hash, "_gp", FALSE, FALSE, TRUE);
-      if (h != (struct bfd_link_hash_entry *) NULL
-         && h->type == bfd_link_hash_defined)
+      if (h != NULL && h->type == bfd_link_hash_defined)
        elf_gp (abfd) = (h->u.def.value
                         + h->u.def.section->output_section->vma
                         + h->u.def.section->output_offset);
-      else if (info->relocateable)
+      else if (info->relocatable)
        {
          bfd_vma lo = MINUS_ONE;
 
          /* Find the GP-relative section with the lowest offset.  */
-         for (o = abfd->sections; o != (asection *) NULL; o = o->next)
+         for (o = abfd->sections; o != NULL; o = o->next)
            if (o->vma < lo
                && (elf_section_data (o)->this_hdr.sh_flags & SHF_MIPS_GPREL))
              lo = o->vma;
@@ -8490,7 +8212,7 @@ _bfd_mips_elf_final_link (abfd, info)
   mdebug_sec = NULL;
   gptab_data_sec = NULL;
   gptab_bss_sec = NULL;
-  for (o = abfd->sections; o != (asection *) NULL; o = o->next)
+  for (o = abfd->sections; o != NULL; o = o->next)
     {
       if (strcmp (o->name, ".reginfo") == 0)
        {
@@ -8499,9 +8221,7 @@ _bfd_mips_elf_final_link (abfd, info)
          /* We have found the .reginfo section in the output file.
             Look through all the link_orders comprising it and merge
             the information together.  */
-         for (p = o->link_order_head;
-              p != (struct bfd_link_order *) NULL;
-              p = p->next)
+         for (p = o->link_order_head; p != NULL; p = p->next)
            {
              asection *input_section;
              bfd *input_bfd;
@@ -8518,15 +8238,8 @@ _bfd_mips_elf_final_link (abfd, info)
              input_section = p->u.indirect.section;
              input_bfd = input_section->owner;
 
-             /* The linker emulation code has probably clobbered the
-                 size to be zero bytes.  */
-             if (input_section->_raw_size == 0)
-               input_section->_raw_size = sizeof (Elf32_External_RegInfo);
-
              if (! bfd_get_section_contents (input_bfd, input_section,
-                                             (PTR) &ext,
-                                             (file_ptr) 0,
-                                             (bfd_size_type) sizeof ext))
+                                             &ext, 0, sizeof ext))
                return FALSE;
 
              bfd_mips_elf32_swap_reginfo_in (input_bfd, &ext, &sub);
@@ -8547,11 +8260,11 @@ _bfd_mips_elf_final_link (abfd, info)
            }
 
          /* Size has been set in _bfd_mips_elf_always_size_sections.  */
-         BFD_ASSERT(o->_raw_size == sizeof (Elf32_External_RegInfo));
+         BFD_ASSERT(o->size == sizeof (Elf32_External_RegInfo));
 
          /* Skip this section later on (I don't think this currently
             matters, but someday it might).  */
-         o->link_order_head = (struct bfd_link_order *) NULL;
+         o->link_order_head = NULL;
 
          reginfo_sec = o;
        }
@@ -8595,7 +8308,7 @@ _bfd_mips_elf_final_link (abfd, info)
          debug.external_ext = debug.external_ext_end = NULL;
 
          mdebug_handle = bfd_ecoff_debug_init (abfd, &debug, swap, info);
-         if (mdebug_handle == (PTR) NULL)
+         if (mdebug_handle == NULL)
            return FALSE;
 
          esym.jmptbl = 0;
@@ -8615,7 +8328,7 @@ _bfd_mips_elf_final_link (abfd, info)
              if (s != NULL)
                {
                  esym.asym.value = s->vma;
-                 last = s->vma + s->_raw_size;
+                 last = s->vma + s->size;
                }
              else
                esym.asym.value = last;
@@ -8624,9 +8337,7 @@ _bfd_mips_elf_final_link (abfd, info)
                return FALSE;
            }
 
-         for (p = o->link_order_head;
-              p != (struct bfd_link_order *) NULL;
-              p = p->next)
+         for (p = o->link_order_head; p != NULL; p = p->next)
            {
              asection *input_section;
              bfd *input_bfd;
@@ -8658,7 +8369,7 @@ _bfd_mips_elf_final_link (abfd, info)
              input_swap = (get_elf_backend_data (input_bfd)
                            ->elf_backend_ecoff_debug_swap);
 
-             BFD_ASSERT (p->size == input_section->_raw_size);
+             BFD_ASSERT (p->size == input_section->size);
 
              /* The ECOFF linking code expects that we have already
                 read in the debugging information and set up an
@@ -8688,7 +8399,7 @@ _bfd_mips_elf_final_link (abfd, info)
                  const char *name;
                  struct mips_elf_link_hash_entry *h;
 
-                 (*input_swap->swap_ext_in) (input_bfd, (PTR) eraw_src, &ext);
+                 (*input_swap->swap_ext_in) (input_bfd, eraw_src, &ext);
                  if (ext.asym.sc == scNil
                      || ext.asym.sc == scUndefined
                      || ext.asym.sc == scSUndefined)
@@ -8757,17 +8468,16 @@ _bfd_mips_elf_final_link (abfd, info)
          einfo.swap = swap;
          einfo.failed = FALSE;
          mips_elf_link_hash_traverse (mips_elf_hash_table (info),
-                                      mips_elf_output_extsym,
-                                      (PTR) &einfo);
+                                      mips_elf_output_extsym, &einfo);
          if (einfo.failed)
            return FALSE;
 
          /* Set the size of the .mdebug section.  */
-         o->_raw_size = bfd_ecoff_debug_size (abfd, &debug, swap);
+         o->size = bfd_ecoff_debug_size (abfd, &debug, swap);
 
          /* Skip this section later on (I don't think this currently
             matters, but someday it might).  */
-         o->link_order_head = (struct bfd_link_order *) NULL;
+         o->link_order_head = NULL;
 
          mdebug_sec = o;
        }
@@ -8784,11 +8494,9 @@ _bfd_mips_elf_final_link (abfd, info)
             information describing how the small data area would
             change depending upon the -G switch.  These sections
             not used in executables files.  */
-         if (! info->relocateable)
+         if (! info->relocatable)
            {
-             for (p = o->link_order_head;
-                  p != (struct bfd_link_order *) NULL;
-                  p = p->next)
+             for (p = o->link_order_head; p != NULL; p = p->next)
                {
                  asection *input_section;
 
@@ -8808,7 +8516,7 @@ _bfd_mips_elf_final_link (abfd, info)
 
              /* Skip this section later on (I don't think this
                 currently matters, but someday it might).  */
-             o->link_order_head = (struct bfd_link_order *) NULL;
+             o->link_order_head = NULL;
 
              /* Really remove the section.  */
              for (secpp = &abfd->sections;
@@ -8855,16 +8563,14 @@ _bfd_mips_elf_final_link (abfd, info)
          /* Set up the first entry.  */
          c = 1;
          amt = c * sizeof (Elf32_gptab);
-         tab = (Elf32_gptab *) bfd_malloc (amt);
+         tab = bfd_malloc (amt);
          if (tab == NULL)
            return FALSE;
          tab[0].gt_header.gt_current_g_value = elf_gp_size (abfd);
          tab[0].gt_header.gt_unused = 0;
 
          /* Combine the input sections.  */
-         for (p = o->link_order_head;
-              p != (struct bfd_link_order *) NULL;
-              p = p->next)
+         for (p = o->link_order_head; p != NULL; p = p->next)
            {
              asection *input_section;
              bfd *input_bfd;
@@ -8885,7 +8591,7 @@ _bfd_mips_elf_final_link (abfd, info)
              /* Combine the gptab entries for this input section one
                 by one.  We know that the input gptab entries are
                 sorted by ascending -G value.  */
-             size = bfd_section_size (input_bfd, input_section);
+             size = input_section->size;
              last = 0;
              for (gpentry = sizeof (Elf32_External_gptab);
                   gpentry < size;
@@ -8899,9 +8605,8 @@ _bfd_mips_elf_final_link (abfd, info)
                  unsigned int look;
 
                  if (! (bfd_get_section_contents
-                        (input_bfd, input_section, (PTR) &ext_gptab,
-                         (file_ptr) gpentry,
-                         (bfd_size_type) sizeof (Elf32_External_gptab))))
+                        (input_bfd, input_section, &ext_gptab, gpentry,
+                         sizeof (Elf32_External_gptab))))
                    {
                      free (tab);
                      return FALSE;
@@ -8929,7 +8634,7 @@ _bfd_mips_elf_final_link (abfd, info)
 
                      /* We need a new table entry.  */
                      amt = (bfd_size_type) (c + 1) * sizeof (Elf32_gptab);
-                     new_tab = (Elf32_gptab *) bfd_realloc ((PTR) tab, amt);
+                     new_tab = bfd_realloc (tab, amt);
                      if (new_tab == NULL)
                        {
                          free (tab);
@@ -8972,7 +8677,7 @@ _bfd_mips_elf_final_link (abfd, info)
 
          /* Swap out the table.  */
          amt = (bfd_size_type) c * sizeof (Elf32_External_gptab);
-         ext_tab = (Elf32_External_gptab *) bfd_alloc (abfd, amt);
+         ext_tab = bfd_alloc (abfd, amt);
          if (ext_tab == NULL)
            {
              free (tab);
@@ -8983,33 +8688,31 @@ _bfd_mips_elf_final_link (abfd, info)
            bfd_mips_elf32_swap_gptab_out (abfd, tab + j, ext_tab + j);
          free (tab);
 
-         o->_raw_size = c * sizeof (Elf32_External_gptab);
+         o->size = c * sizeof (Elf32_External_gptab);
          o->contents = (bfd_byte *) ext_tab;
 
          /* Skip this section later on (I don't think this currently
             matters, but someday it might).  */
-         o->link_order_head = (struct bfd_link_order *) NULL;
+         o->link_order_head = NULL;
        }
     }
 
   /* Invoke the regular ELF backend linker to do all the work.  */
-  if (!MNAME(abfd,bfd_elf,bfd_final_link) (abfd, info))
+  if (!bfd_elf_final_link (abfd, info))
     return FALSE;
 
   /* Now write out the computed sections.  */
 
-  if (reginfo_sec != (asection *) NULL)
+  if (reginfo_sec != NULL)
     {
       Elf32_External_RegInfo ext;
 
       bfd_mips_elf32_swap_reginfo_out (abfd, &reginfo, &ext);
-      if (! bfd_set_section_contents (abfd, reginfo_sec, (PTR) &ext,
-                                     (file_ptr) 0,
-                                     (bfd_size_type) sizeof ext))
+      if (! bfd_set_section_contents (abfd, reginfo_sec, &ext, 0, sizeof ext))
        return FALSE;
     }
 
-  if (mdebug_sec != (asection *) NULL)
+  if (mdebug_sec != NULL)
     {
       BFD_ASSERT (abfd->output_has_begun);
       if (! bfd_ecoff_write_accumulated_debug (mdebug_handle, abfd, &debug,
@@ -9020,21 +8723,19 @@ _bfd_mips_elf_final_link (abfd, info)
       bfd_ecoff_debug_free (mdebug_handle, abfd, &debug, swap, info);
     }
 
-  if (gptab_data_sec != (asection *) NULL)
+  if (gptab_data_sec != NULL)
     {
       if (! bfd_set_section_contents (abfd, gptab_data_sec,
                                      gptab_data_sec->contents,
-                                     (file_ptr) 0,
-                                     gptab_data_sec->_raw_size))
+                                     0, gptab_data_sec->size))
        return FALSE;
     }
 
-  if (gptab_bss_sec != (asection *) NULL)
+  if (gptab_bss_sec != NULL)
     {
       if (! bfd_set_section_contents (abfd, gptab_bss_sec,
                                      gptab_bss_sec->contents,
-                                     (file_ptr) 0,
-                                     gptab_bss_sec->_raw_size))
+                                     0, gptab_bss_sec->size))
        return FALSE;
     }
 
@@ -9045,8 +8746,7 @@ _bfd_mips_elf_final_link (abfd, info)
        {
          if (! bfd_set_section_contents (abfd, rtproc_sec,
                                          rtproc_sec->contents,
-                                         (file_ptr) 0,
-                                         rtproc_sec->_raw_size))
+                                         0, rtproc_sec->size))
            return FALSE;
        }
     }
@@ -9066,6 +8766,7 @@ struct mips_mach_extension {
 
 static const struct mips_mach_extension mips_mach_extensions[] = {
   /* MIPS64 extensions.  */
+  { bfd_mach_mipsisa64r2, bfd_mach_mipsisa64 },
   { bfd_mach_mips_sb1, bfd_mach_mipsisa64 },
 
   /* MIPS V extensions.  */
@@ -9086,6 +8787,7 @@ static const struct mips_mach_extension mips_mach_extensions[] = {
   { bfd_mach_mips5, bfd_mach_mips8000 },
   { bfd_mach_mips10000, bfd_mach_mips8000 },
   { bfd_mach_mips5000, bfd_mach_mips8000 },
+  { bfd_mach_mips7000, bfd_mach_mips8000 },
 
   /* VR4100 extensions.  */
   { bfd_mach_mips4120, bfd_mach_mips4100 },
@@ -9116,8 +8818,7 @@ static const struct mips_mach_extension mips_mach_extensions[] = {
 /* Return true if bfd machine EXTENSION is an extension of machine BASE.  */
 
 static bfd_boolean
-mips_mach_extends_p (base, extension)
-     unsigned long base, extension;
+mips_mach_extends_p (unsigned long base, unsigned long extension)
 {
   size_t i;
 
@@ -9132,8 +8833,7 @@ mips_mach_extends_p (base, extension)
 /* Return true if the given ELF header flags describe a 32-bit binary.  */
 
 static bfd_boolean
-mips_32bit_flags_p (flags)
-     flagword flags;
+mips_32bit_flags_p (flagword flags)
 {
   return ((flags & EF_MIPS_32BITMODE) != 0
          || (flags & EF_MIPS_ABI) == E_MIPS_ABI_O32
@@ -9149,9 +8849,7 @@ mips_32bit_flags_p (flags)
    object file when linking.  */
 
 bfd_boolean
-_bfd_mips_elf_merge_private_bfd_data (ibfd, obfd)
-     bfd *ibfd;
-     bfd *obfd;
+_bfd_mips_elf_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
 {
   flagword old_flags;
   flagword new_flags;
@@ -9212,6 +8910,11 @@ _bfd_mips_elf_merge_private_bfd_data (ibfd, obfd)
   new_flags &= ~EF_MIPS_XGOT;
   old_flags &= ~EF_MIPS_XGOT;
 
+  /* MIPSpro generates ucode info in n64 objects.  Again, we should
+     just be able to ignore this.  */
+  new_flags &= ~EF_MIPS_UCODE;
+  old_flags &= ~EF_MIPS_UCODE;
+
   if (new_flags == old_flags)
     return TRUE;
 
@@ -9224,10 +8927,10 @@ _bfd_mips_elf_merge_private_bfd_data (ibfd, obfd)
          which are automatically generated by gas.  */
       if (strcmp (sec->name, ".reginfo")
          && strcmp (sec->name, ".mdebug")
-         && ((!strcmp (sec->name, ".text")
-              || !strcmp (sec->name, ".data")
-              || !strcmp (sec->name, ".bss"))
-             && sec->_raw_size != 0))
+         && (sec->size != 0
+             || (strcmp (sec->name, ".text")
+                 && strcmp (sec->name, ".data")
+                 && strcmp (sec->name, ".bss"))))
        {
          null_input_bfd = FALSE;
          break;
@@ -9351,9 +9054,7 @@ _bfd_mips_elf_merge_private_bfd_data (ibfd, obfd)
 /* Function to keep MIPS specific file flags like as EF_MIPS_PIC.  */
 
 bfd_boolean
-_bfd_mips_elf_set_private_flags (abfd, flags)
-     bfd *abfd;
-     flagword flags;
+_bfd_mips_elf_set_private_flags (bfd *abfd, flagword flags)
 {
   BFD_ASSERT (!elf_flags_init (abfd)
              || elf_elfheader (abfd)->e_flags == flags);
@@ -9364,11 +9065,9 @@ _bfd_mips_elf_set_private_flags (abfd, flags)
 }
 
 bfd_boolean
-_bfd_mips_elf_print_private_bfd_data (abfd, ptr)
-     bfd *abfd;
-     PTR ptr;
+_bfd_mips_elf_print_private_bfd_data (bfd *abfd, void *ptr)
 {
-  FILE *file = (FILE *) ptr;
+  FILE *file = ptr;
 
   BFD_ASSERT (abfd != NULL && ptr != NULL);
 
@@ -9411,6 +9110,8 @@ _bfd_mips_elf_print_private_bfd_data (abfd, ptr)
     fprintf (file, _(" [mips64]"));
   else if ((elf_elfheader (abfd)->e_flags & EF_MIPS_ARCH) == E_MIPS_ARCH_32R2)
     fprintf (file, _(" [mips32r2]"));
+  else if ((elf_elfheader (abfd)->e_flags & EF_MIPS_ARCH) == E_MIPS_ARCH_64R2)
+    fprintf (file, _(" [mips64r2]"));
   else
     fprintf (file, _(" [unknown ISA]"));
 
@@ -9429,3 +9130,14 @@ _bfd_mips_elf_print_private_bfd_data (abfd, ptr)
 
   return TRUE;
 }
+
+struct bfd_elf_special_section const _bfd_mips_elf_special_sections[]=
+{
+  { ".sdata",  6, -2, SHT_PROGBITS,   SHF_ALLOC + SHF_WRITE + SHF_MIPS_GPREL },
+  { ".sbss",   5, -2, SHT_NOBITS,     SHF_ALLOC + SHF_WRITE + SHF_MIPS_GPREL },
+  { ".lit4",   5,  0, SHT_PROGBITS,   SHF_ALLOC + SHF_WRITE + SHF_MIPS_GPREL },
+  { ".lit8",   5,  0, SHT_PROGBITS,   SHF_ALLOC + SHF_WRITE + SHF_MIPS_GPREL },
+  { ".ucode",  6,  0, SHT_MIPS_UCODE, 0 },
+  { ".mdebug", 7,  0, SHT_MIPS_DEBUG, 0 },
+  { NULL,      0,  0, 0,              0 }
+};
This page took 0.085311 seconds and 4 git commands to generate.