MIPS/BFD: Fold the handling of input MIPS ABI flags together
[deliverable/binutils-gdb.git] / bfd / elfxx-mips.c
index 06e815823da7622ef39c6fb06053d2429e95ec5c..89d4409b097ed1b014bea0b637aa67da3aeb2afc 100644 (file)
@@ -1,5 +1,5 @@
 /* MIPS-specific support for ELF
-   Copyright (C) 1993-2015 Free Software Foundation, Inc.
+   Copyright (C) 1993-2016 Free Software Foundation, Inc.
 
    Most of the information added by Ian Lance Taylor, Cygnus Support,
    <ian@cygnus.com>.
@@ -911,10 +911,7 @@ static bfd *reldyn_sorting_bfd;
   ((ABI_64_P (abfd)                                                    \
     ? 0xdf998010                               /* ld t9,0x8010(gp) */  \
     : 0x8f998010))                             /* lw t9,0x8010(gp) */
-#define STUB_MOVE(abfd)                                                        \
-   ((ABI_64_P (abfd)                                                   \
-     ? 0x03e0782d                              /* daddu t7,ra */       \
-     : 0x03e07821))                            /* addu t7,ra */
+#define STUB_MOVE 0x03e07825                   /* or t7,ra,zero */
 #define STUB_LUI(VAL) (0x3c180000 + (VAL))     /* lui t8,VAL */
 #define STUB_JALR 0x0320f809                   /* jalr t9,ra */
 #define STUB_ORI(VAL) (0x37180000 + (VAL))     /* ori t8,t8,VAL */
@@ -930,10 +927,7 @@ static bfd *reldyn_sorting_bfd;
    ? 0xdf3c8010                                        /* ld t9,0x8010(gp) */  \
    : 0xff3c8010)                               /* lw t9,0x8010(gp) */
 #define STUB_MOVE_MICROMIPS 0x0dff             /* move t7,ra */
-#define STUB_MOVE32_MICROMIPS(abfd)                                    \
-   (ABI_64_P (abfd)                                                    \
-    ? 0x581f7950                               /* daddu t7,ra,zero */  \
-    : 0x001f7950)                              /* addu t7,ra,zero */
+#define STUB_MOVE32_MICROMIPS 0x001f7a90       /* or t7,ra,zero */
 #define STUB_LUI_MICROMIPS(VAL)                                                \
    (0x41b80000 + (VAL))                                /* lui t8,VAL */
 #define STUB_JALR_MICROMIPS 0x45d9             /* jalr t9 */
@@ -1030,7 +1024,7 @@ static const bfd_vma mips_o32_exec_plt0_entry[] =
   0x8f990000,  /* lw $25, %lo(&GOTPLT[0])($28)                         */
   0x279c0000,  /* addiu $28, $28, %lo(&GOTPLT[0])                      */
   0x031cc023,  /* subu $24, $24, $28                                   */
-  0x03e07821,  /* move $15, $31        # 32-bit move (addu)            */
+  0x03e07825,  /* or t7, ra, zero                                      */
   0x0018c082,  /* srl $24, $24, 2                                      */
   0x0320f809,  /* jalr $25                                             */
   0x2718fffe   /* subu $24, $24, 2                                     */
@@ -1044,7 +1038,7 @@ static const bfd_vma mips_n32_exec_plt0_entry[] =
   0x8dd90000,  /* lw $25, %lo(&GOTPLT[0])($14)                         */
   0x25ce0000,  /* addiu $14, $14, %lo(&GOTPLT[0])                      */
   0x030ec023,  /* subu $24, $24, $14                                   */
-  0x03e07821,  /* move $15, $31        # 32-bit move (addu)            */
+  0x03e07825,  /* or t7, ra, zero                                      */
   0x0018c082,  /* srl $24, $24, 2                                      */
   0x0320f809,  /* jalr $25                                             */
   0x2718fffe   /* subu $24, $24, 2                                     */
@@ -1058,7 +1052,7 @@ static const bfd_vma mips_n64_exec_plt0_entry[] =
   0xddd90000,  /* ld $25, %lo(&GOTPLT[0])($14)                         */
   0x25ce0000,  /* addiu $14, $14, %lo(&GOTPLT[0])                      */
   0x030ec023,  /* subu $24, $24, $14                                   */
-  0x03e0782d,  /* move $15, $31        # 64-bit move (daddu)           */
+  0x03e07825,  /* or t7, ra, zero                                      */
   0x0018c0c2,  /* srl $24, $24, 3                                      */
   0x0320f809,  /* jalr $25                                             */
   0x2718fffe   /* subu $24, $24, 2                                     */
@@ -1091,7 +1085,7 @@ static const bfd_vma micromips_insn32_o32_exec_plt0_entry[] =
   0xff3c, 0x0000,      /* lw $25, %lo(&GOTPLT[0])($28)                 */
   0x339c, 0x0000,      /* addiu $28, $28, %lo(&GOTPLT[0])              */
   0x0398, 0xc1d0,      /* subu $24, $24, $28                           */
-  0x001f, 0x7950,      /* move $15, $31                                */
+  0x001f, 0x7a90,      /* or $15, $31, zero                            */
   0x0318, 0x1040,      /* srl $24, $24, 2                              */
   0x03f9, 0x0f3c,      /* jalr $25                                     */
   0x3318, 0xfffe       /* subu $24, $24, 2                             */
@@ -1713,6 +1707,7 @@ mips_elf_check_mips16_stubs (struct bfd_link_info *info,
       h->fn_stub->flags &= ~SEC_RELOC;
       h->fn_stub->reloc_count = 0;
       h->fn_stub->flags |= SEC_EXCLUDE;
+      h->fn_stub->output_section = bfd_abs_section_ptr;
     }
 
   if (h->call_stub != NULL
@@ -1725,6 +1720,7 @@ mips_elf_check_mips16_stubs (struct bfd_link_info *info,
       h->call_stub->flags &= ~SEC_RELOC;
       h->call_stub->reloc_count = 0;
       h->call_stub->flags |= SEC_EXCLUDE;
+      h->call_stub->output_section = bfd_abs_section_ptr;
     }
 
   if (h->call_fp_stub != NULL
@@ -1737,6 +1733,7 @@ mips_elf_check_mips16_stubs (struct bfd_link_info *info,
       h->call_fp_stub->flags &= ~SEC_RELOC;
       h->call_fp_stub->reloc_count = 0;
       h->call_fp_stub->flags |= SEC_EXCLUDE;
+      h->call_fp_stub->output_section = bfd_abs_section_ptr;
     }
 }
 
@@ -1975,7 +1972,7 @@ mips_elf_check_symbols (struct mips_elf_link_hash_entry *h, void *data)
   struct mips_htab_traverse_info *hti;
 
   hti = (struct mips_htab_traverse_info *) data;
-  if (!hti->info->relocatable)
+  if (!bfd_link_relocatable (hti->info))
     mips_elf_check_mips16_stubs (hti->info, h);
 
   if (mips_elf_local_pic_function_p (h))
@@ -1990,7 +1987,7 @@ mips_elf_check_symbols (struct mips_elf_link_hash_entry *h, void *data)
         being PIC.  If we're creating a non-relocatable object with
         non-PIC branches and jumps to H, make sure that H has an la25
         stub.  */
-      if (hti->info->relocatable)
+      if (bfd_link_relocatable (hti->info))
        {
          if (!PIC_OBJECT_P (hti->output_bfd))
            h->root.other = ELF_ST_SET_MIPS_PIC (h->root.other);
@@ -2162,18 +2159,6 @@ got_page_reloc_p (unsigned int r_type)
   return r_type == R_MIPS_GOT_PAGE || r_type == R_MICROMIPS_GOT_PAGE;
 }
 
-static inline bfd_boolean
-got_ofst_reloc_p (unsigned int r_type)
-{
-  return r_type == R_MIPS_GOT_OFST || r_type == R_MICROMIPS_GOT_OFST;
-}
-
-static inline bfd_boolean
-got_hi16_reloc_p (unsigned int r_type)
-{
-  return r_type == R_MIPS_GOT_HI16 || r_type == R_MICROMIPS_GOT_HI16;
-}
-
 static inline bfd_boolean
 got_lo16_reloc_p (unsigned int r_type)
 {
@@ -3225,11 +3210,11 @@ mips_tls_got_relocs (struct bfd_link_info *info, unsigned char tls_type,
   bfd_boolean need_relocs = FALSE;
   bfd_boolean dyn = elf_hash_table (info)->dynamic_sections_created;
 
-  if (h && WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared, h)
-      && (!info->shared || !SYMBOL_REFERENCES_LOCAL (info, h)))
+  if (h && WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, bfd_link_pic (info), h)
+      && (!bfd_link_pic (info) || !SYMBOL_REFERENCES_LOCAL (info, h)))
     indx = h->dynindx;
 
-  if ((info->shared || indx != 0)
+  if ((bfd_link_pic (info) || indx != 0)
       && (h == NULL
          || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
          || h->root.type != bfd_link_hash_undefweak))
@@ -3247,7 +3232,7 @@ mips_tls_got_relocs (struct bfd_link_info *info, unsigned char tls_type,
       return 1;
 
     case GOT_TLS_LDM:
-      return info->shared ? 1 : 0;
+      return bfd_link_pic (info) ? 1 : 0;
 
     default:
       return 0;
@@ -3331,15 +3316,17 @@ mips_elf_initialize_tls_slots (bfd *abfd, struct bfd_link_info *info,
     {
       bfd_boolean dyn = elf_hash_table (info)->dynamic_sections_created;
 
-      if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared, &h->root)
-         && (!info->shared || !SYMBOL_REFERENCES_LOCAL (info, &h->root)))
+      if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, bfd_link_pic (info),
+                                          &h->root)
+         && (!bfd_link_pic (info)
+             || !SYMBOL_REFERENCES_LOCAL (info, &h->root)))
        indx = h->root.dynindx;
     }
 
   if (entry->tls_initialized)
     return;
 
-  if ((info->shared || indx != 0)
+  if ((bfd_link_pic (info) || indx != 0)
       && (h == NULL
          || ELF_ST_VISIBILITY (h->root.other) == STV_DEFAULT
          || h->root.type != bfd_link_hash_undefweak))
@@ -3414,7 +3401,7 @@ mips_elf_initialize_tls_slots (bfd *abfd, struct bfd_link_info *info,
                         sgot->contents + got_offset
                         + MIPS_ELF_GOT_SIZE (abfd));
 
-      if (!info->shared)
+      if (!bfd_link_pic (info))
        MIPS_ELF_PUT_WORD (abfd, 1,
                           sgot->contents + got_offset);
       else
@@ -3775,7 +3762,8 @@ count_section_dynsyms (bfd *output_bfd, struct bfd_link_info *info)
   bfd_size_type count;
 
   count = 0;
-  if (info->shared || elf_hash_table (info)->is_relocatable_executable)
+  if (bfd_link_pic (info)
+      || elf_hash_table (info)->is_relocatable_executable)
     {
       asection *p;
       const struct elf_backend_data *bed;
@@ -4414,7 +4402,7 @@ mips_use_local_got_p (struct bfd_link_info *info,
   /* If this is an executable that must provide a definition of the symbol,
      either though PLTs or copy relocations, then that address should go in
      the local rather than global GOT.  */
-  if (info->executable && h->has_static_relocs)
+  if (bfd_link_executable (info) && h->has_static_relocs)
     return TRUE;
 
   return FALSE;
@@ -4722,7 +4710,7 @@ mips_elf_set_global_gotidx (void **entryp, void *data)
        }
       arg->g->assigned_low_gotno += 1;
 
-      if (arg->info->shared
+      if (bfd_link_pic (arg->info)
          || (elf_hash_table (arg->info)->dynamic_sections_created
              && entry->d.h->root.def_dynamic
              && !entry->d.h->root.def_regular))
@@ -4929,7 +4917,7 @@ mips_elf_multi_got (bfd *abfd, struct bfd_link_info *info,
       BFD_ASSERT (g->assigned_low_gotno == g->local_gotno + g->global_gotno);
       g->assigned_low_gotno = save_assign;
 
-      if (info->shared)
+      if (bfd_link_pic (info))
        {
          g->relocs += g->local_gotno - g->assigned_low_gotno;
          BFD_ASSERT (g->assigned_low_gotno == g->next->local_gotno
@@ -5132,7 +5120,7 @@ mips_elf_create_got_section (bfd *abfd, struct bfd_link_info *info)
   h->other = (h->other & ~ELF_ST_VISIBILITY (-1)) | STV_HIDDEN;
   elf_hash_table (info)->hgot = h;
 
-  if (info->shared
+  if (bfd_link_pic (info)
       && ! bfd_elf_link_record_dynamic_symbol (info, h))
     return FALSE;
 
@@ -5161,7 +5149,7 @@ static bfd_boolean
 is_gott_symbol (struct bfd_link_info *info, struct elf_link_hash_entry *h)
 {
   return (mips_elf_hash_table (info)->is_vxworks
-         && info->shared
+         && bfd_link_pic (info)
          && (strcmp (h->root.root.string, "__GOTT_BASE__") == 0
              || strcmp (h->root.root.string, "__GOTT_INDEX__") == 0));
 }
@@ -5401,7 +5389,7 @@ mips_elf_calculate_relocation (bfd *abfd, bfd *input_bfd,
             Otherwise, we should define the symbol with a value of 0.
             FIXME: It should probably get into the symbol table
             somehow as well.  */
-         BFD_ASSERT (! info->shared);
+         BFD_ASSERT (! bfd_link_pic (info));
          BFD_ASSERT (bfd_get_section_by_name (abfd, ".dynamic") == NULL);
          symbol = 0;
        }
@@ -5443,7 +5431,7 @@ mips_elf_calculate_relocation (bfd *abfd, bfd *input_bfd,
 
      (c) the section allows direct references to MIPS16 functions.  */
   if (r_type != R_MIPS16_26
-      && !info->relocatable
+      && !bfd_link_relocatable (info)
       && ((h != NULL
           && h->fn_stub != NULL
           && (r_type != R_MIPS16_CALL16 || h->need_fn_stub))
@@ -5485,7 +5473,7 @@ mips_elf_calculate_relocation (bfd *abfd, bfd *input_bfd,
      to a standard MIPS function, we need to redirect the call to the stub.
      Note that we specifically exclude R_MIPS16_CALL16 from this behavior;
      indirect calls should use an indirect stub instead.  */
-  else if (r_type == R_MIPS16_26 && !info->relocatable
+  else if (r_type == R_MIPS16_26 && !bfd_link_relocatable (info)
           && ((h != NULL && (h->call_stub != NULL || h->call_fp_stub != NULL))
               || (local_p
                   && mips_elf_tdata (input_bfd)->local_call_stubs != NULL
@@ -5538,7 +5526,7 @@ mips_elf_calculate_relocation (bfd *abfd, bfd *input_bfd,
      to point to the standard PLT entry, so redirect to the compressed
      one.  */
   else if ((r_type == R_MIPS16_26 || r_type == R_MICROMIPS_26_S1)
-          && !info->relocatable
+          && !bfd_link_relocatable (info)
           && h != NULL
           && h->use_plt_entry
           && h->root.plt.plist->comp_offset != MINUS_ONE
@@ -5573,7 +5561,7 @@ mips_elf_calculate_relocation (bfd *abfd, bfd *input_bfd,
      because the assembly writer may have "known" that any definition of the
      symbol would be 16-bit code, and that direct jumps were therefore
      acceptable.  */
-  *cross_mode_jump_p = (!info->relocatable
+  *cross_mode_jump_p = (!bfd_link_relocatable (info)
                        && !(h && h->root.root.type == bfd_link_hash_undefweak)
                        && ((r_type == R_MIPS16_26 && !target_is_16_bit_code_p)
                            || (r_type == R_MICROMIPS_26_S1
@@ -5724,7 +5712,7 @@ mips_elf_calculate_relocation (bfd *abfd, bfd *input_bfd,
     case R_MIPS_32:
     case R_MIPS_REL32:
     case R_MIPS_64:
-      if ((info->shared
+      if ((bfd_link_pic (info)
           || (htab->root.dynamic_sections_created
               && h != NULL
               && h->root.def_dynamic
@@ -6285,7 +6273,7 @@ mips_elf_perform_relocation (struct bfd_link_info *info,
 
   /* Try converting JAL to BAL and J(AL)R to B(AL), if the target is in
      range.  */
-  if (!info->relocatable
+  if (!bfd_link_relocatable (info)
       && !cross_mode_jump_p
       && ((JAL_TO_BAL_P (input_bfd)
           && r_type == R_MIPS_26
@@ -6324,7 +6312,7 @@ mips_elf_perform_relocation (struct bfd_link_info *info,
   if (size != 0)
     bfd_put (8 * size, input_bfd, x, location);
 
-  _bfd_mips_elf_reloc_shuffle (input_bfd, r_type, !info->relocatable,
+  _bfd_mips_elf_reloc_shuffle (input_bfd, r_type, !bfd_link_relocatable (info),
                               location);
 
   return TRUE;
@@ -7454,7 +7442,7 @@ _bfd_mips_elf_add_symbol_hook (bfd *abfd, struct bfd_link_info *info,
          elf_text_symbol->section = elf_text_section;
        }
       /* This code used to do *secp = bfd_und_section_ptr if
-         info->shared.  I don't know why, and that doesn't make sense,
+         bfd_link_pic (info).  I don't know why, and that doesn't make sense,
          so I took it out.  */
       *secp = mips_elf_tdata (abfd)->elf_text_section;
       break;
@@ -7495,7 +7483,7 @@ _bfd_mips_elf_add_symbol_hook (bfd *abfd, struct bfd_link_info *info,
          elf_data_symbol->section = elf_data_section;
        }
       /* This code used to do *secp = bfd_und_section_ptr if
-         info->shared.  I don't know why, and that doesn't make sense,
+         bfd_link_pic (info).  I don't know why, and that doesn't make sense,
          so I took it out.  */
       *secp = mips_elf_tdata (abfd)->elf_data_section;
       break;
@@ -7506,7 +7494,7 @@ _bfd_mips_elf_add_symbol_hook (bfd *abfd, struct bfd_link_info *info,
     }
 
   if (SGI_COMPAT (abfd)
-      && ! info->shared
+      && ! bfd_link_pic (info)
       && info->output_bfd->xvec == abfd->xvec
       && strcmp (*namep, "__rld_obj_head") == 0)
     {
@@ -7614,7 +7602,7 @@ _bfd_mips_elf_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info)
   htab->sstubs = s;
 
   if (!mips_elf_hash_table (info)->use_rld_obj_head
-      && info->executable
+      && bfd_link_executable (info)
       && bfd_get_linker_section (abfd, ".rld_map") == NULL)
     {
       s = bfd_make_section_anyway_with_flags (abfd, ".rld_map",
@@ -7678,7 +7666,7 @@ _bfd_mips_elf_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info)
        (void) bfd_set_section_alignment (abfd, s, MIPS_ELF_LOG_FILE_ALIGN (abfd));
     }
 
-  if (info->executable)
+  if (bfd_link_executable (info))
     {
       const char *name;
 
@@ -7740,7 +7728,7 @@ _bfd_mips_elf_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info)
   else
     htab->srelplt = bfd_get_linker_section (abfd, ".rel.plt");
   if (!htab->sdynbss
-      || (htab->is_vxworks && !htab->srelbss && !info->shared)
+      || (htab->is_vxworks && !htab->srelbss && !bfd_link_pic (info))
       || !htab->srelplt
       || !htab->splt)
     abort ();
@@ -7918,7 +7906,7 @@ _bfd_mips_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
   bfd_vma addend;
   reloc_howto_type *howto;
 
-  if (info->relocatable)
+  if (bfd_link_relocatable (info))
     return TRUE;
 
   htab = mips_elf_hash_table (info);
@@ -8274,7 +8262,7 @@ _bfd_mips_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
            elf_hash_table (info)->dynobj = dynobj = abfd;
          if (!mips_elf_create_got_section (dynobj, info))
            return FALSE;
-         if (htab->is_vxworks && !info->shared)
+         if (htab->is_vxworks && !bfd_link_pic (info))
            {
              (*_bfd_error_handler)
                (_("%B: GOT reloc at 0x%lx not expected in executables"),
@@ -8317,7 +8305,7 @@ _bfd_mips_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
             one or using copy relocations or PLT entries.  It is
             usually better to do the former, unless the relocation is
             against a read-only section.  */
-         if ((info->shared
+         if ((bfd_link_pic (info)
               || (h != NULL
                   && !htab->is_vxworks
                   && strcmp (h->root.root.string, "__gnu_local_gp") != 0
@@ -8482,7 +8470,7 @@ _bfd_mips_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
 
                  /* This symbol is definitely not overridable.  */
                  if (hmips->root.def_regular
-                     && ! (info->shared && ! info->symbolic
+                     && ! (bfd_link_pic (info) && ! info->symbolic
                            && ! hmips->root.forced_local))
                    h = NULL;
                }
@@ -8501,7 +8489,7 @@ _bfd_mips_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
        case R_MIPS_TLS_GOTTPREL:
        case R_MIPS16_TLS_GOTTPREL:
        case R_MICROMIPS_TLS_GOTTPREL:
-         if (info->shared)
+         if (bfd_link_pic (info))
            info->flags |= DF_STATIC_TLS;
          /* Fall through */
 
@@ -8549,7 +8537,7 @@ _bfd_mips_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
                  if (sreloc == NULL)
                    return FALSE;
                }
-             if (info->shared && h == NULL)
+             if (bfd_link_pic (info) && h == NULL)
                {
                  /* When creating a shared object, we must copy these
                     reloc types into the output file as R_MIPS_REL32
@@ -8663,7 +8651,7 @@ _bfd_mips_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
         not PIC, but we can create dynamic relocations and the result
         will be fine.  Also do not refuse R_MIPS_LO16, which can be
         combined with R_MIPS_GOT16.  */
-      if (info->shared)
+      if (bfd_link_pic (info))
        {
          switch (r_type)
            {
@@ -8727,7 +8715,7 @@ _bfd_mips_relax_section (bfd *abfd, asection *sec,
   /* We are not currently changing any sizes, so only one pass.  */
   *again = FALSE;
 
-  if (link_info->relocatable)
+  if (bfd_link_relocatable (link_info))
     return TRUE;
 
   internal_relocs = _bfd_elf_link_read_relocs (abfd, sec, NULL, NULL,
@@ -8773,7 +8761,7 @@ _bfd_mips_relax_section (bfd *abfd, asection *sec,
          if (! ((h->root.root.type == bfd_link_hash_defined
                  || h->root.root.type == bfd_link_hash_defweak)
                 && h->root.root.u.def.section)
-             || (link_info->shared && ! link_info->symbolic
+             || (bfd_link_pic (link_info) && ! link_info->symbolic
                  && !h->root.forced_local))
            continue;
 
@@ -8889,7 +8877,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
 
   /* VxWorks executables are handled elsewhere; we only need to
      allocate relocations in shared objects.  */
-  if (htab->is_vxworks && !info->shared)
+  if (htab->is_vxworks && !bfd_link_pic (info))
     return TRUE;
 
   /* Ignore indirect symbols.  All relocations against such symbols
@@ -8900,11 +8888,11 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
   /* If this symbol is defined in a dynamic object, or we are creating
      a shared library, we will need to copy any R_MIPS_32 or
      R_MIPS_REL32 relocs against it into the output file.  */
-  if (! info->relocatable
+  if (! bfd_link_relocatable (info)
       && hmips->possibly_dynamic_relocs != 0
       && (h->root.type == bfd_link_hash_defweak
          || (!h->def_regular && !ELF_COMMON_DEF_P (h))
-         || info->shared))
+         || bfd_link_pic (info)))
     {
       bfd_boolean do_copy = TRUE;
 
@@ -9058,11 +9046,11 @@ _bfd_mips_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
 
          /* On VxWorks, also allocate room for the header's
             .rela.plt.unloaded entries.  */
-         if (htab->is_vxworks && !info->shared)
+         if (htab->is_vxworks && !bfd_link_pic (info))
            htab->srelplt2->size += 2 * sizeof (Elf32_External_Rela);
 
          /* Now work out the sizes of individual PLT entries.  */
-         if (htab->is_vxworks && info->shared)
+         if (htab->is_vxworks && bfd_link_pic (info))
            htab->plt_mips_entry_size
              = 4 * ARRAY_SIZE (mips_vxworks_shared_plt_entry);
          else if (htab->is_vxworks)
@@ -9146,7 +9134,7 @@ _bfd_mips_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
 
       /* If the output file has no definition of the symbol, set the
         symbol's value to the address of the stub.  */
-      if (!info->shared && !h->def_regular)
+      if (!bfd_link_pic (info) && !h->def_regular)
        hmips->use_plt_entry = TRUE;
 
       /* Make room for the R_MIPS_JUMP_SLOT relocation.  */
@@ -9155,7 +9143,7 @@ _bfd_mips_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
                              : MIPS_ELF_REL_SIZE (dynobj));
 
       /* Make room for the .rela.plt.unloaded relocations.  */
-      if (htab->is_vxworks && !info->shared)
+      if (htab->is_vxworks && !bfd_link_pic (info))
        htab->srelplt2->size += 3 * sizeof (Elf32_External_Rela);
 
       /* All relocations against this symbol that could have been made
@@ -9189,7 +9177,7 @@ _bfd_mips_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
 
   /* We're now relying on copy relocations.  Complain if we have
      some that we can't convert.  */
-  if (!htab->use_plts_and_copy_relocs || info->shared)
+  if (!htab->use_plts_and_copy_relocs || bfd_link_pic (info))
     {
       (*_bfd_error_handler) (_("non-dynamic relocations refer to "
                               "dynamic symbol %s"),
@@ -9370,7 +9358,7 @@ mips_elf_lay_out_got (bfd *output_bfd, struct bfd_link_info *info)
                  == g->global_gotno + g->local_gotno + g->tls_gotno);
 
       /* Each VxWorks GOT entry needs an explicit relocation.  */
-      if (htab->is_vxworks && info->shared)
+      if (htab->is_vxworks && bfd_link_pic (info))
        g->relocs += g->global_gotno + g->local_gotno - htab->reserved_gotno;
 
       /* Allocate room for the TLS relocations.  */
@@ -9582,7 +9570,7 @@ _bfd_mips_elf_size_dynamic_sections (bfd *output_bfd,
   if (elf_hash_table (info)->dynamic_sections_created)
     {
       /* Set the contents of the .interp section to the interpreter.  */
-      if (info->executable)
+      if (bfd_link_executable (info) && !info->nointerp)
        {
          s = bfd_get_linker_section (dynobj, ".interp");
          BFD_ASSERT (s != NULL);
@@ -9617,7 +9605,7 @@ _bfd_mips_elf_size_dynamic_sections (bfd *output_bfd,
          BFD_ASSERT (htab->sgotplt->size == 0);
          BFD_ASSERT (htab->splt->size == 0);
 
-         if (htab->is_vxworks && info->shared)
+         if (htab->is_vxworks && bfd_link_pic (info))
            size = 4 * ARRAY_SIZE (mips_vxworks_shared_plt0_entry);
          else if (htab->is_vxworks)
            size = 4 * ARRAY_SIZE (mips_vxworks_exec_plt0_entry);
@@ -9719,7 +9707,7 @@ _bfd_mips_elf_size_dynamic_sections (bfd *output_bfd,
              info->combreloc = 0;
            }
        }
-      else if (info->executable
+      else if (bfd_link_executable (info)
               && ! mips_elf_hash_table (info)->use_rld_obj_head
               && CONST_STRNEQ (name, ".rld_map"))
        {
@@ -9778,17 +9766,17 @@ _bfd_mips_elf_size_dynamic_sections (bfd *output_bfd,
         DT_MIPS_RLD_MAP entry.  This must come first because glibc
         only fills in DT_MIPS_RLD_MAP (not DT_DEBUG) and some tools
         may only look at the first one they see.  */
-      if (!info->shared
+      if (!bfd_link_pic (info)
          && !MIPS_ELF_ADD_DYNAMIC_ENTRY (info, DT_MIPS_RLD_MAP, 0))
        return FALSE;
 
-      if (info->executable
+      if (bfd_link_executable (info)
          && !MIPS_ELF_ADD_DYNAMIC_ENTRY (info, DT_MIPS_RLD_MAP_REL, 0))
        return FALSE;
 
       /* The DT_DEBUG entry may be filled in by the dynamic linker and
         used by the debugger.  */
-      if (info->executable
+      if (bfd_link_executable (info)
          && !SGI_COMPAT (output_bfd)
          && !MIPS_ELF_ADD_DYNAMIC_ENTRY (info, DT_DEBUG, 0))
        return FALSE;
@@ -9924,7 +9912,7 @@ mips_elf_adjust_addend (bfd *output_bfd, struct bfd_link_info *info,
       sym = local_syms + r_symndx;
 
       /* Adjust REL's addend to account for section merging.  */
-      if (!info->relocatable)
+      if (!bfd_link_relocatable (info))
        {
          sec = local_sections[r_symndx];
          _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
@@ -10115,7 +10103,7 @@ _bfd_mips_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
                                  local_syms, local_sections, rel);
        }
 
-      if (info->relocatable)
+      if (bfd_link_relocatable (info))
        {
          if (r_type == R_MIPS_64 && ! NEWABI_P (output_bfd)
              && bfd_big_endian (input_bfd))
@@ -10714,8 +10702,7 @@ _bfd_mips_elf_finish_dynamic_symbol (bfd *output_bfd,
          if (htab->insn32)
            {
              bfd_put_micromips_32 (output_bfd,
-                                   STUB_MOVE32_MICROMIPS (output_bfd),
-                                   stub + idx);
+                                   STUB_MOVE32_MICROMIPS, stub + idx);
              idx += 4;
            }
          else
@@ -10765,7 +10752,7 @@ _bfd_mips_elf_finish_dynamic_symbol (bfd *output_bfd,
          idx = 0;
          bfd_put_32 (output_bfd, STUB_LW (output_bfd), stub + idx);
          idx += 4;
-         bfd_put_32 (output_bfd, STUB_MOVE (output_bfd), stub + idx);
+         bfd_put_32 (output_bfd, STUB_MOVE, stub + idx);
          idx += 4;
          if (stub_size == stub_big_size)
            {
@@ -10859,7 +10846,7 @@ _bfd_mips_elf_finish_dynamic_symbol (bfd *output_bfd,
            {
              offset = p->gotidx;
              BFD_ASSERT (offset > 0 && offset < htab->sgot->size);
-             if (info->shared
+             if (bfd_link_pic (info)
                  || (elf_hash_table (info)->dynamic_sections_created
                      && p->d.h != NULL
                      && p->d.h->root.def_dynamic
@@ -11035,7 +11022,7 @@ _bfd_mips_vxworks_finish_dynamic_symbol (bfd *output_bfd,
       /* Find out where the .plt entry should go.  */
       loc = htab->splt->contents + plt_offset;
 
-      if (info->shared)
+      if (bfd_link_pic (info))
        {
          plt_entry = mips_vxworks_shared_plt_entry;
          bfd_put_32 (output_bfd, plt_entry[0] | branch_offset, loc);
@@ -11650,7 +11637,7 @@ _bfd_mips_elf_finish_dynamic_sections (bfd *output_bfd,
                             sgot->contents
                             + got_index++ * MIPS_ELF_GOT_SIZE (output_bfd));
 
-         if (! info->shared)
+         if (! bfd_link_pic (info))
            continue;
 
          for (; got_index < g->local_gotno; got_index++)
@@ -11786,14 +11773,14 @@ _bfd_mips_elf_finish_dynamic_sections (bfd *output_bfd,
     {
       if (htab->is_vxworks)
        {
-         if (info->shared)
+         if (bfd_link_pic (info))
            mips_vxworks_finish_shared_plt (output_bfd, info);
          else
            mips_vxworks_finish_exec_plt (output_bfd, info);
        }
       else
        {
-         BFD_ASSERT (!info->shared);
+         BFD_ASSERT (!bfd_link_pic (info));
          if (!mips_finish_exec_plt (output_bfd, info))
            return FALSE;
        }
@@ -12398,7 +12385,7 @@ _bfd_mips_elf_gc_sweep_hook (bfd *abfd ATTRIBUTE_UNUSED,
   unsigned long r_symndx;
   struct elf_link_hash_entry *h;
 
-  if (info->relocatable)
+  if (bfd_link_relocatable (info))
     return TRUE;
 
   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
@@ -13224,8 +13211,8 @@ static const struct opcode_descriptor addiupc_insn =
 #define MOVE16_RS_FIELD(r) (((r) & 0x1f)     )
 
 static const struct opcode_descriptor move_insns_32[] = {
-  { /* "move", "d,s",          */ 0x00000150, 0xffe007ff }, /* addu d,s,$0 */
   { /* "move", "d,s",          */ 0x00000290, 0xffe007ff }, /* or   d,s,$0 */
+  { /* "move", "d,s",          */ 0x00000150, 0xffe007ff }, /* addu d,s,$0 */
   { 0, 0 }  /* End marker for find_match().  */
 };
 
@@ -13412,7 +13399,7 @@ _bfd_mips_elf_relax_section (bfd *abfd, asection *sec,
      this section does not have relocs, or if this is not a
      code section.  */
 
-  if (link_info->relocatable
+  if (bfd_link_relocatable (link_info)
       || (sec->flags & SEC_RELOC) == 0
       || sec->reloc_count == 0
       || (sec->flags & SEC_CODE) == 0)
@@ -13925,6 +13912,140 @@ _bfd_mips_elf_insn32 (struct bfd_link_info *info, bfd_boolean on)
   mips_elf_hash_table (info)->insn32 = on;
 }
 \f
+/* Structure for saying that BFD machine EXTENSION extends BASE.  */
+
+struct mips_mach_extension
+{
+  unsigned long extension, base;
+};
+
+
+/* An array describing how BFD machines relate to one another.  The entries
+   are ordered topologically with MIPS I extensions listed last.  */
+
+static const struct mips_mach_extension mips_mach_extensions[] =
+{
+  /* MIPS64r2 extensions.  */
+  { bfd_mach_mips_octeon3, bfd_mach_mips_octeon2 },
+  { bfd_mach_mips_octeon2, bfd_mach_mips_octeonp },
+  { bfd_mach_mips_octeonp, bfd_mach_mips_octeon },
+  { bfd_mach_mips_octeon, bfd_mach_mipsisa64r2 },
+  { bfd_mach_mips_loongson_3a, bfd_mach_mipsisa64r2 },
+
+  /* MIPS64 extensions.  */
+  { bfd_mach_mipsisa64r2, bfd_mach_mipsisa64 },
+  { bfd_mach_mips_sb1, bfd_mach_mipsisa64 },
+  { bfd_mach_mips_xlr, bfd_mach_mipsisa64 },
+
+  /* MIPS V extensions.  */
+  { bfd_mach_mipsisa64, bfd_mach_mips5 },
+
+  /* R10000 extensions.  */
+  { bfd_mach_mips12000, bfd_mach_mips10000 },
+  { bfd_mach_mips14000, bfd_mach_mips10000 },
+  { bfd_mach_mips16000, bfd_mach_mips10000 },
+
+  /* R5000 extensions.  Note: the vr5500 ISA is an extension of the core
+     vr5400 ISA, but doesn't include the multimedia stuff.  It seems
+     better to allow vr5400 and vr5500 code to be merged anyway, since
+     many libraries will just use the core ISA.  Perhaps we could add
+     some sort of ASE flag if this ever proves a problem.  */
+  { bfd_mach_mips5500, bfd_mach_mips5400 },
+  { bfd_mach_mips5400, bfd_mach_mips5000 },
+
+  /* MIPS IV 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 },
+  { bfd_mach_mips9000, bfd_mach_mips8000 },
+
+  /* VR4100 extensions.  */
+  { bfd_mach_mips4120, bfd_mach_mips4100 },
+  { bfd_mach_mips4111, bfd_mach_mips4100 },
+
+  /* MIPS III extensions.  */
+  { bfd_mach_mips_loongson_2e, bfd_mach_mips4000 },
+  { bfd_mach_mips_loongson_2f, bfd_mach_mips4000 },
+  { bfd_mach_mips8000, bfd_mach_mips4000 },
+  { bfd_mach_mips4650, bfd_mach_mips4000 },
+  { bfd_mach_mips4600, bfd_mach_mips4000 },
+  { bfd_mach_mips4400, bfd_mach_mips4000 },
+  { bfd_mach_mips4300, bfd_mach_mips4000 },
+  { bfd_mach_mips4100, bfd_mach_mips4000 },
+  { bfd_mach_mips4010, bfd_mach_mips4000 },
+  { bfd_mach_mips5900, bfd_mach_mips4000 },
+
+  /* MIPS32 extensions.  */
+  { bfd_mach_mipsisa32r2, bfd_mach_mipsisa32 },
+
+  /* MIPS II extensions.  */
+  { bfd_mach_mips4000, bfd_mach_mips6000 },
+  { bfd_mach_mipsisa32, bfd_mach_mips6000 },
+
+  /* MIPS I extensions.  */
+  { bfd_mach_mips6000, bfd_mach_mips3000 },
+  { bfd_mach_mips3900, bfd_mach_mips3000 }
+};
+
+/* Return true if bfd machine EXTENSION is an extension of machine BASE.  */
+
+static bfd_boolean
+mips_mach_extends_p (unsigned long base, unsigned long extension)
+{
+  size_t i;
+
+  if (extension == base)
+    return TRUE;
+
+  if (base == bfd_mach_mipsisa32
+      && mips_mach_extends_p (bfd_mach_mipsisa64, extension))
+    return TRUE;
+
+  if (base == bfd_mach_mipsisa32r2
+      && mips_mach_extends_p (bfd_mach_mipsisa64r2, extension))
+    return TRUE;
+
+  for (i = 0; i < ARRAY_SIZE (mips_mach_extensions); i++)
+    if (extension == mips_mach_extensions[i].extension)
+      {
+       extension = mips_mach_extensions[i].base;
+       if (extension == base)
+         return TRUE;
+      }
+
+  return FALSE;
+}
+
+/* Return the BFD mach for each .MIPS.abiflags ISA Extension.  */
+
+static unsigned long
+bfd_mips_isa_ext_mach (unsigned int isa_ext)
+{
+  switch (isa_ext)
+    {
+    case AFL_EXT_3900:        return bfd_mach_mips3900;
+    case AFL_EXT_4010:        return bfd_mach_mips4010;
+    case AFL_EXT_4100:        return bfd_mach_mips4100;
+    case AFL_EXT_4111:        return bfd_mach_mips4111;
+    case AFL_EXT_4120:        return bfd_mach_mips4120;
+    case AFL_EXT_4650:        return bfd_mach_mips4650;
+    case AFL_EXT_5400:        return bfd_mach_mips5400;
+    case AFL_EXT_5500:        return bfd_mach_mips5500;
+    case AFL_EXT_5900:        return bfd_mach_mips5900;
+    case AFL_EXT_10000:       return bfd_mach_mips10000;
+    case AFL_EXT_LOONGSON_2E: return bfd_mach_mips_loongson_2e;
+    case AFL_EXT_LOONGSON_2F: return bfd_mach_mips_loongson_2f;
+    case AFL_EXT_LOONGSON_3A: return bfd_mach_mips_loongson_3a;
+    case AFL_EXT_SB1:         return bfd_mach_mips_sb1;
+    case AFL_EXT_OCTEON:      return bfd_mach_mips_octeon;
+    case AFL_EXT_OCTEONP:     return bfd_mach_mips_octeonp;
+    case AFL_EXT_OCTEON2:     return bfd_mach_mips_octeon2;
+    case AFL_EXT_XLR:         return bfd_mach_mips_xlr;
+    default:                  return bfd_mach_mips3000;
+    }
+}
+
 /* Return the .MIPS.abiflags value representing each ISA Extension.  */
 
 unsigned int
@@ -13932,110 +14053,71 @@ bfd_mips_isa_ext (bfd *abfd)
 {
   switch (bfd_get_mach (abfd))
     {
-    case bfd_mach_mips3900:
-      return AFL_EXT_3900;
-    case bfd_mach_mips4010:
-      return AFL_EXT_4010;
-    case bfd_mach_mips4100:
-      return AFL_EXT_4100;
-    case bfd_mach_mips4111:
-      return AFL_EXT_4111;
-    case bfd_mach_mips4120:
-      return AFL_EXT_4120;
-    case bfd_mach_mips4650:
-      return AFL_EXT_4650;
-    case bfd_mach_mips5400:
-      return AFL_EXT_5400;
-    case bfd_mach_mips5500:
-      return AFL_EXT_5500;
-    case bfd_mach_mips5900:
-      return AFL_EXT_5900;
-    case bfd_mach_mips10000:
-      return AFL_EXT_10000;
-    case bfd_mach_mips_loongson_2e:
-      return AFL_EXT_LOONGSON_2E;
-    case bfd_mach_mips_loongson_2f:
-      return AFL_EXT_LOONGSON_2F;
-    case bfd_mach_mips_loongson_3a:
-      return AFL_EXT_LOONGSON_3A;
-    case bfd_mach_mips_sb1:
-      return AFL_EXT_SB1;
-    case bfd_mach_mips_octeon:
-      return AFL_EXT_OCTEON;
-    case bfd_mach_mips_octeonp:
-      return AFL_EXT_OCTEONP;
-    case bfd_mach_mips_octeon3:
-      return AFL_EXT_OCTEON3;
-    case bfd_mach_mips_octeon2:
-      return AFL_EXT_OCTEON2;
-    case bfd_mach_mips_xlr:
-      return AFL_EXT_XLR;
-    }
-  return 0;
-}
+    case bfd_mach_mips3900:         return AFL_EXT_3900;
+    case bfd_mach_mips4010:         return AFL_EXT_4010;
+    case bfd_mach_mips4100:         return AFL_EXT_4100;
+    case bfd_mach_mips4111:         return AFL_EXT_4111;
+    case bfd_mach_mips4120:         return AFL_EXT_4120;
+    case bfd_mach_mips4650:         return AFL_EXT_4650;
+    case bfd_mach_mips5400:         return AFL_EXT_5400;
+    case bfd_mach_mips5500:         return AFL_EXT_5500;
+    case bfd_mach_mips5900:         return AFL_EXT_5900;
+    case bfd_mach_mips10000:        return AFL_EXT_10000;
+    case bfd_mach_mips_loongson_2e: return AFL_EXT_LOONGSON_2E;
+    case bfd_mach_mips_loongson_2f: return AFL_EXT_LOONGSON_2F;
+    case bfd_mach_mips_loongson_3a: return AFL_EXT_LOONGSON_3A;
+    case bfd_mach_mips_sb1:         return AFL_EXT_SB1;
+    case bfd_mach_mips_octeon:      return AFL_EXT_OCTEON;
+    case bfd_mach_mips_octeonp:     return AFL_EXT_OCTEONP;
+    case bfd_mach_mips_octeon3:     return AFL_EXT_OCTEON3;
+    case bfd_mach_mips_octeon2:     return AFL_EXT_OCTEON2;
+    case bfd_mach_mips_xlr:         return AFL_EXT_XLR;
+    default:                        return 0;
+    }
+}
+
+/* Encode ISA level and revision as a single value.  */
+#define LEVEL_REV(LEV,REV) ((LEV) << 3 | (REV))
+
+/* Decode a single value into level and revision.  */
+#define ISA_LEVEL(LEVREV)  ((LEVREV) >> 3)
+#define ISA_REV(LEVREV)    ((LEVREV) & 0x7)
 
 /* Update the isa_level, isa_rev, isa_ext fields of abiflags.  */
 
 static void
 update_mips_abiflags_isa (bfd *abfd, Elf_Internal_ABIFlags_v0 *abiflags)
 {
+  int new_isa = 0;
   switch (elf_elfheader (abfd)->e_flags & EF_MIPS_ARCH)
     {
-    case E_MIPS_ARCH_1:
-      abiflags->isa_level = 1;
-      abiflags->isa_rev = 0;
-      break;
-    case E_MIPS_ARCH_2:
-      abiflags->isa_level = 2;
-      abiflags->isa_rev = 0;
-      break;
-    case E_MIPS_ARCH_3:
-      abiflags->isa_level = 3;
-      abiflags->isa_rev = 0;
-      break;
-    case E_MIPS_ARCH_4:
-      abiflags->isa_level = 4;
-      abiflags->isa_rev = 0;
-      break;
-    case E_MIPS_ARCH_5:
-      abiflags->isa_level = 5;
-      abiflags->isa_rev = 0;
-      break;
-    case E_MIPS_ARCH_32:
-      abiflags->isa_level = 32;
-      abiflags->isa_rev = 1;
-      break;
-    case E_MIPS_ARCH_32R2:
-      abiflags->isa_level = 32;
-      /* Handle MIPS32r3 and MIPS32r5 which do not have a header flag.  */
-      if (abiflags->isa_rev < 2)
-       abiflags->isa_rev = 2;
-      break;
-    case E_MIPS_ARCH_32R6:
-      abiflags->isa_level = 32;
-      abiflags->isa_rev = 6;
-      break;
-    case E_MIPS_ARCH_64:
-      abiflags->isa_level = 64;
-      abiflags->isa_rev = 1;
-      break;
-    case E_MIPS_ARCH_64R2:
-      /* Handle MIPS64r3 and MIPS64r5 which do not have a header flag.  */
-      abiflags->isa_level = 64;
-      if (abiflags->isa_rev < 2)
-       abiflags->isa_rev = 2;
-      break;
-    case E_MIPS_ARCH_64R6:
-      abiflags->isa_level = 64;
-      abiflags->isa_rev = 6;
-      break;
+    case E_MIPS_ARCH_1:    new_isa = LEVEL_REV (1, 0); break;
+    case E_MIPS_ARCH_2:    new_isa = LEVEL_REV (2, 0); break;
+    case E_MIPS_ARCH_3:    new_isa = LEVEL_REV (3, 0); break;
+    case E_MIPS_ARCH_4:    new_isa = LEVEL_REV (4, 0); break;
+    case E_MIPS_ARCH_5:    new_isa = LEVEL_REV (5, 0); break;
+    case E_MIPS_ARCH_32:   new_isa = LEVEL_REV (32, 1); break;
+    case E_MIPS_ARCH_32R2: new_isa = LEVEL_REV (32, 2); break;
+    case E_MIPS_ARCH_32R6: new_isa = LEVEL_REV (32, 6); break;
+    case E_MIPS_ARCH_64:   new_isa = LEVEL_REV (64, 1); break;
+    case E_MIPS_ARCH_64R2: new_isa = LEVEL_REV (64, 2); break;
+    case E_MIPS_ARCH_64R6: new_isa = LEVEL_REV (64, 6); break;
     default:
       (*_bfd_error_handler)
        (_("%B: Unknown architecture %s"),
         abfd, bfd_printable_name (abfd));
     }
 
-  abiflags->isa_ext = bfd_mips_isa_ext (abfd);
+  if (new_isa > LEVEL_REV (abiflags->isa_level, abiflags->isa_rev))
+    {
+      abiflags->isa_level = ISA_LEVEL (new_isa);
+      abiflags->isa_rev = ISA_REV (new_isa);
+    }
+
+  /* Update the isa_ext if ABFD describes a further extension.  */
+  if (mips_mach_extends_p (bfd_mips_isa_ext_mach (abiflags->isa_ext),
+                          bfd_get_mach (abfd)))
+    abiflags->isa_ext = bfd_mips_isa_ext (abfd);
 }
 
 /* Return true if the given ELF header flags describe a 32-bit binary.  */
@@ -14169,7 +14251,7 @@ _bfd_mips_elf_final_link (bfd *abfd, struct bfd_link_info *info)
        elf_gp (abfd) = (h->u.def.section->output_section->vma
                         + h->u.def.section->output_offset
                         + h->u.def.value);
-      else if (info->relocatable)
+      else if (bfd_link_relocatable (info))
        {
          bfd_vma lo = MINUS_ONE;
 
@@ -14455,7 +14537,7 @@ _bfd_mips_elf_final_link (bfd *abfd, struct bfd_link_info *info)
              input_section->flags &= ~SEC_HAS_CONTENTS;
            }
 
-         if (SGI_COMPAT (abfd) && info->shared)
+         if (SGI_COMPAT (abfd) && bfd_link_pic (info))
            {
              /* Create .rtproc section.  */
              rtproc_sec = bfd_get_linker_section (abfd, ".rtproc");
@@ -14511,7 +14593,7 @@ _bfd_mips_elf_final_link (bfd *abfd, struct bfd_link_info *info)
             information describing how the small data area would
             change depending upon the -G switch.  These sections
             not used in executables files.  */
-         if (! info->relocatable)
+         if (! bfd_link_relocatable (info))
            {
              for (p = o->map_head.link_order; p != NULL; p = p->next)
                {
@@ -14785,113 +14867,6 @@ _bfd_mips_elf_final_link (bfd *abfd, struct bfd_link_info *info)
   return TRUE;
 }
 \f
-/* Structure for saying that BFD machine EXTENSION extends BASE.  */
-
-struct mips_mach_extension
-{
-  unsigned long extension, base;
-};
-
-
-/* An array describing how BFD machines relate to one another.  The entries
-   are ordered topologically with MIPS I extensions listed last.  */
-
-static const struct mips_mach_extension mips_mach_extensions[] =
-{
-  /* MIPS64r2 extensions.  */
-  { bfd_mach_mips_octeon3, bfd_mach_mips_octeon2 },
-  { bfd_mach_mips_octeon2, bfd_mach_mips_octeonp },
-  { bfd_mach_mips_octeonp, bfd_mach_mips_octeon },
-  { bfd_mach_mips_octeon, bfd_mach_mipsisa64r2 },
-  { bfd_mach_mips_loongson_3a, bfd_mach_mipsisa64r2 },
-
-  /* MIPS64 extensions.  */
-  { bfd_mach_mipsisa64r2, bfd_mach_mipsisa64 },
-  { bfd_mach_mips_sb1, bfd_mach_mipsisa64 },
-  { bfd_mach_mips_xlr, bfd_mach_mipsisa64 },
-
-  /* MIPS V extensions.  */
-  { bfd_mach_mipsisa64, bfd_mach_mips5 },
-
-  /* R10000 extensions.  */
-  { bfd_mach_mips12000, bfd_mach_mips10000 },
-  { bfd_mach_mips14000, bfd_mach_mips10000 },
-  { bfd_mach_mips16000, bfd_mach_mips10000 },
-
-  /* R5000 extensions.  Note: the vr5500 ISA is an extension of the core
-     vr5400 ISA, but doesn't include the multimedia stuff.  It seems
-     better to allow vr5400 and vr5500 code to be merged anyway, since
-     many libraries will just use the core ISA.  Perhaps we could add
-     some sort of ASE flag if this ever proves a problem.  */
-  { bfd_mach_mips5500, bfd_mach_mips5400 },
-  { bfd_mach_mips5400, bfd_mach_mips5000 },
-
-  /* MIPS IV 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 },
-  { bfd_mach_mips9000, bfd_mach_mips8000 },
-
-  /* VR4100 extensions.  */
-  { bfd_mach_mips4120, bfd_mach_mips4100 },
-  { bfd_mach_mips4111, bfd_mach_mips4100 },
-
-  /* MIPS III extensions.  */
-  { bfd_mach_mips_loongson_2e, bfd_mach_mips4000 },
-  { bfd_mach_mips_loongson_2f, bfd_mach_mips4000 },
-  { bfd_mach_mips8000, bfd_mach_mips4000 },
-  { bfd_mach_mips4650, bfd_mach_mips4000 },
-  { bfd_mach_mips4600, bfd_mach_mips4000 },
-  { bfd_mach_mips4400, bfd_mach_mips4000 },
-  { bfd_mach_mips4300, bfd_mach_mips4000 },
-  { bfd_mach_mips4100, bfd_mach_mips4000 },
-  { bfd_mach_mips4010, bfd_mach_mips4000 },
-  { bfd_mach_mips5900, bfd_mach_mips4000 },
-
-  /* MIPS32 extensions.  */
-  { bfd_mach_mipsisa32r2, bfd_mach_mipsisa32 },
-
-  /* MIPS II extensions.  */
-  { bfd_mach_mips4000, bfd_mach_mips6000 },
-  { bfd_mach_mipsisa32, bfd_mach_mips6000 },
-
-  /* MIPS I extensions.  */
-  { bfd_mach_mips6000, bfd_mach_mips3000 },
-  { bfd_mach_mips3900, bfd_mach_mips3000 }
-};
-
-
-/* Return true if bfd machine EXTENSION is an extension of machine BASE.  */
-
-static bfd_boolean
-mips_mach_extends_p (unsigned long base, unsigned long extension)
-{
-  size_t i;
-
-  if (extension == base)
-    return TRUE;
-
-  if (base == bfd_mach_mipsisa32
-      && mips_mach_extends_p (bfd_mach_mipsisa64, extension))
-    return TRUE;
-
-  if (base == bfd_mach_mipsisa32r2
-      && mips_mach_extends_p (bfd_mach_mipsisa64r2, extension))
-    return TRUE;
-
-  for (i = 0; i < ARRAY_SIZE (mips_mach_extensions); i++)
-    if (extension == mips_mach_extensions[i].extension)
-      {
-       extension = mips_mach_extensions[i].base;
-       if (extension == base)
-         return TRUE;
-      }
-
-  return FALSE;
-}
-
-
 /* Merge object attributes from IBFD into OBFD.  Raise an error if
    there are conflicting attributes.  */
 static bfd_boolean
@@ -15049,6 +15024,8 @@ mips_elf_merge_obj_attributes (bfd *ibfd, bfd *obfd)
 bfd_boolean
 _bfd_mips_elf_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
 {
+  struct mips_elf_obj_tdata *out_tdata;
+  struct mips_elf_obj_tdata *in_tdata;
   flagword old_flags;
   flagword new_flags;
   bfd_boolean ok;
@@ -15068,6 +15045,9 @@ _bfd_mips_elf_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
   if (!is_mips_elf (ibfd) || !is_mips_elf (obfd))
     return TRUE;
 
+  in_tdata = mips_elf_tdata (ibfd);
+  out_tdata = mips_elf_tdata (obfd);
+
   if (strcmp (bfd_get_target (ibfd), bfd_get_target (obfd)) != 0)
     {
       (*_bfd_error_handler)
@@ -15076,22 +15056,9 @@ _bfd_mips_elf_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
       return FALSE;
     }
 
-  /* Set up the FP ABI attribute from the abiflags if it is not already
-     set.  */
-  if (mips_elf_tdata (ibfd)->abiflags_valid)
-    {
-      obj_attribute *in_attr = elf_known_obj_attributes (ibfd)[OBJ_ATTR_GNU];
-      if (in_attr[Tag_GNU_MIPS_ABI_FP].i == Val_GNU_MIPS_ABI_FP_ANY)
-        in_attr[Tag_GNU_MIPS_ABI_FP].i =
-         mips_elf_tdata (ibfd)->abiflags.fp_abi;
-    }
-
-  if (!mips_elf_merge_obj_attributes (ibfd, obfd))
-    return FALSE;
-
-  /* Check to see if the input BFD actually contains any sections.
-     If not, its flags may not have been initialised either, but it cannot
-     actually cause any incompatibility.  */
+  /* Check to see if the input BFD actually contains any sections.  If not,
+     then it has no attributes, and its flags may not have been initialized
+     either, but it cannot actually cause any incompatibility.  */
   for (sec = ibfd->sections; sec != NULL; sec = sec->next)
     {
       /* Ignore synthetic sections and empty .text, .data and .bss sections
@@ -15114,39 +15081,43 @@ _bfd_mips_elf_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
     return TRUE;
 
   /* Populate abiflags using existing information.  */
-  if (!mips_elf_tdata (ibfd)->abiflags_valid)
+  if (in_tdata->abiflags_valid)
     {
-      infer_mips_abiflags (ibfd, &mips_elf_tdata (ibfd)->abiflags);
-      mips_elf_tdata (ibfd)->abiflags_valid = TRUE;
-    }
-  else
-    {
-      Elf_Internal_ABIFlags_v0 abiflags;
+      obj_attribute *in_attr = elf_known_obj_attributes (ibfd)[OBJ_ATTR_GNU];
       Elf_Internal_ABIFlags_v0 in_abiflags;
+      Elf_Internal_ABIFlags_v0 abiflags;
+
+      /* Set up the FP ABI attribute from the abiflags if it is not already
+         set.  */
+      if (in_attr[Tag_GNU_MIPS_ABI_FP].i == Val_GNU_MIPS_ABI_FP_ANY)
+        in_attr[Tag_GNU_MIPS_ABI_FP].i = in_tdata->abiflags.fp_abi;
+
       infer_mips_abiflags (ibfd, &abiflags);
-      in_abiflags = mips_elf_tdata (ibfd)->abiflags;
+      in_abiflags = in_tdata->abiflags;
 
       /* It is not possible to infer the correct ISA revision
          for R3 or R5 so drop down to R2 for the checks.  */
       if (in_abiflags.isa_rev == 3 || in_abiflags.isa_rev == 5)
        in_abiflags.isa_rev = 2;
 
-      if (in_abiflags.isa_level != abiflags.isa_level
-         || in_abiflags.isa_rev != abiflags.isa_rev
-         || in_abiflags.isa_ext != abiflags.isa_ext)
+      if (LEVEL_REV (in_abiflags.isa_level, in_abiflags.isa_rev)
+         < LEVEL_REV (abiflags.isa_level, abiflags.isa_rev))
        (*_bfd_error_handler)
          (_("%B: warning: Inconsistent ISA between e_flags and "
             ".MIPS.abiflags"), ibfd);
       if (abiflags.fp_abi != Val_GNU_MIPS_ABI_FP_ANY
          && in_abiflags.fp_abi != abiflags.fp_abi)
        (*_bfd_error_handler)
-         (_("%B: warning: Inconsistent FP ABI between e_flags and "
+         (_("%B: warning: Inconsistent FP ABI between .gnu.attributes and "
             ".MIPS.abiflags"), ibfd);
       if ((in_abiflags.ases & abiflags.ases) != abiflags.ases)
        (*_bfd_error_handler)
          (_("%B: warning: Inconsistent ASEs between e_flags and "
             ".MIPS.abiflags"), ibfd);
-      if (in_abiflags.isa_ext != abiflags.isa_ext)
+      /* The isa_ext is allowed to be an extension of what can be inferred
+        from e_flags.  */
+      if (!mips_mach_extends_p (bfd_mips_isa_ext_mach (abiflags.isa_ext),
+                               bfd_mips_isa_ext_mach (in_abiflags.isa_ext)))
        (*_bfd_error_handler)
          (_("%B: warning: Inconsistent ISA extensions between e_flags and "
             ".MIPS.abiflags"), ibfd);
@@ -15156,12 +15127,20 @@ _bfd_mips_elf_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
             ".MIPS.abiflags (0x%lx)"), ibfd,
           (unsigned long) in_abiflags.flags2);
     }
+  else
+    {
+      infer_mips_abiflags (ibfd, &in_tdata->abiflags);
+      in_tdata->abiflags_valid = TRUE;
+    }
+
+  if (!mips_elf_merge_obj_attributes (ibfd, obfd))
+    return FALSE;
 
-  if (!mips_elf_tdata (obfd)->abiflags_valid)
+  if (!out_tdata->abiflags_valid)
     {
       /* Copy input abiflags if output abiflags are not already valid.  */
-      mips_elf_tdata (obfd)->abiflags = mips_elf_tdata (ibfd)->abiflags;
-      mips_elf_tdata (obfd)->abiflags_valid = TRUE;
+      out_tdata->abiflags = in_tdata->abiflags;
+      out_tdata->abiflags_valid = TRUE;
     }
 
   if (! elf_flags_init (obfd))
@@ -15181,7 +15160,7 @@ _bfd_mips_elf_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
            return FALSE;
 
          /* Update the ABI flags isa_level, isa_rev and isa_ext fields.  */
-         update_mips_abiflags_isa (obfd, &mips_elf_tdata (obfd)->abiflags);
+         update_mips_abiflags_isa (obfd, &out_tdata->abiflags);
        }
 
       return TRUE;
@@ -15189,27 +15168,23 @@ _bfd_mips_elf_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
 
   /* Update the output abiflags fp_abi using the computed fp_abi.  */
   out_attr = elf_known_obj_attributes (obfd)[OBJ_ATTR_GNU];
-  mips_elf_tdata (obfd)->abiflags.fp_abi = out_attr[Tag_GNU_MIPS_ABI_FP].i;
+  out_tdata->abiflags.fp_abi = out_attr[Tag_GNU_MIPS_ABI_FP].i;
 
 #define max(a,b) ((a) > (b) ? (a) : (b))
   /* Merge abiflags.  */
-  mips_elf_tdata (obfd)->abiflags.isa_rev
-    = max (mips_elf_tdata (obfd)->abiflags.isa_rev,
-          mips_elf_tdata (ibfd)->abiflags.isa_rev);
-  mips_elf_tdata (obfd)->abiflags.gpr_size
-    = max (mips_elf_tdata (obfd)->abiflags.gpr_size,
-          mips_elf_tdata (ibfd)->abiflags.gpr_size);
-  mips_elf_tdata (obfd)->abiflags.cpr1_size
-    = max (mips_elf_tdata (obfd)->abiflags.cpr1_size,
-          mips_elf_tdata (ibfd)->abiflags.cpr1_size);
-  mips_elf_tdata (obfd)->abiflags.cpr2_size
-    = max (mips_elf_tdata (obfd)->abiflags.cpr2_size,
-          mips_elf_tdata (ibfd)->abiflags.cpr2_size);
+  out_tdata->abiflags.isa_level = max (out_tdata->abiflags.isa_level,
+                                      in_tdata->abiflags.isa_level);
+  out_tdata->abiflags.isa_rev = max (out_tdata->abiflags.isa_rev,
+                                    in_tdata->abiflags.isa_rev);
+  out_tdata->abiflags.gpr_size = max (out_tdata->abiflags.gpr_size,
+                                     in_tdata->abiflags.gpr_size);
+  out_tdata->abiflags.cpr1_size = max (out_tdata->abiflags.cpr1_size,
+                                      in_tdata->abiflags.cpr1_size);
+  out_tdata->abiflags.cpr2_size = max (out_tdata->abiflags.cpr2_size,
+                                      in_tdata->abiflags.cpr2_size);
 #undef max
-  mips_elf_tdata (obfd)->abiflags.ases
-    |= mips_elf_tdata (ibfd)->abiflags.ases;
-  mips_elf_tdata (obfd)->abiflags.flags1
-    |= mips_elf_tdata (ibfd)->abiflags.flags1;
+  out_tdata->abiflags.ases |= in_tdata->abiflags.ases;
+  out_tdata->abiflags.flags1 |= in_tdata->abiflags.flags1;
 
   new_flags = elf_elfheader (ibfd)->e_flags;
   elf_elfheader (obfd)->e_flags |= new_flags & EF_MIPS_NOREORDER;
@@ -15278,7 +15253,7 @@ _bfd_mips_elf_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
            |= new_flags & (EF_MIPS_ARCH | EF_MIPS_MACH | EF_MIPS_32BITMODE);
 
          /* Update the ABI flags isa_level, isa_rev, isa_ext fields.  */
-         update_mips_abiflags_isa (obfd, &mips_elf_tdata (obfd)->abiflags);
+         update_mips_abiflags_isa (obfd, &out_tdata->abiflags);
 
          /* Copy across the ABI flags if OBFD doesn't use them
             and if that was what caused us to treat IBFD as 32-bit.  */
This page took 0.043655 seconds and 4 git commands to generate.