Microblaze: Add support for handling TLS symbol suffixes and generating
[deliverable/binutils-gdb.git] / bfd / elfxx-mips.c
index 9fef8efe464c7a92eacd64589ebd4a0ae6ee33d0..403627340503e633ea12bec3aa9e5f4bf1848d80 100644 (file)
@@ -306,12 +306,12 @@ struct mips_elf_la25_stub {
 #define LA25_LUI(VAL) (0x3c190000 | (VAL))     /* lui t9,VAL */
 #define LA25_J(VAL) (0x08000000 | (((VAL) >> 2) & 0x3ffffff)) /* j VAL */
 #define LA25_ADDIU(VAL) (0x27390000 | (VAL))   /* addiu t9,t9,VAL */
-#define LA25_LUI_MICROMIPS_1(VAL) (0x41b9)     /* lui t9,VAL */
-#define LA25_LUI_MICROMIPS_2(VAL) (VAL)
-#define LA25_J_MICROMIPS_1(VAL) (0xd400 | (((VAL) >> 17) & 0x3ff)) /* j VAL */
-#define LA25_J_MICROMIPS_2(VAL) ((VAL) >> 1)
-#define LA25_ADDIU_MICROMIPS_1(VAL) (0x3339)   /* addiu t9,t9,VAL */
-#define LA25_ADDIU_MICROMIPS_2(VAL) (VAL)
+#define LA25_LUI_MICROMIPS(VAL)                                                \
+  (0x41b90000 | (VAL))                         /* lui t9,VAL */
+#define LA25_J_MICROMIPS(VAL)                                          \
+  (0xd4000000 | (((VAL) >> 1) & 0x3ffffff))    /* j VAL */
+#define LA25_ADDIU_MICROMIPS(VAL)                                      \
+  (0x33390000 | (VAL))                         /* addiu t9,t9,VAL */
 
 /* This structure is passed to mips_elf_sort_hash_table_f when sorting
    the dynamic symbols.  */
@@ -432,8 +432,8 @@ struct mips_elf_link_hash_table
   /* The size of the .compact_rel section (if SGI_COMPAT).  */
   bfd_size_type compact_rel_size;
 
-  /* This flag indicates that the value of DT_MIPS_RLD_MAP dynamic
-     entry is set to the address of __rld_obj_head as in IRIX5.  */
+  /* This flag indicates that the value of DT_MIPS_RLD_MAP dynamic entry
+     is set to the address of __rld_obj_head as in IRIX5 and IRIX6.  */
   bfd_boolean use_rld_obj_head;
 
   /* The  __rld_map or __rld_obj_head symbol. */
@@ -515,6 +515,22 @@ struct mips_htab_traverse_info
   bfd_boolean error;
 };
 
+/* MIPS ELF private object data.  */
+
+struct mips_elf_obj_tdata
+{
+  /* Generic ELF private object data.  */
+  struct elf_obj_tdata root;
+
+  /* Input BFD providing Tag_GNU_MIPS_ABI_FP attribute for output.  */
+  bfd *abi_fp_bfd;
+};
+
+/* Get MIPS ELF private object data from BFD's tdata.  */
+
+#define mips_elf_tdata(bfd) \
+  ((struct mips_elf_obj_tdata *) (bfd)->tdata.any)
+
 #define TLS_RELOC_P(r_type) \
   (r_type == R_MIPS_TLS_DTPMOD32               \
    || r_type == R_MIPS_TLS_DTPMOD64            \
@@ -1013,6 +1029,23 @@ static const bfd_vma mips_vxworks_shared_plt_entry[] =
   0x24180000   /* li t8, <pltindex>    */
 };
 \f
+/* microMIPS 32-bit opcode helper installer.  */
+
+static void
+bfd_put_micromips_32 (const bfd *abfd, bfd_vma opcode, bfd_byte *ptr)
+{
+  bfd_put_16 (abfd, (opcode >> 16) & 0xffff, ptr);
+  bfd_put_16 (abfd,  opcode        & 0xffff, ptr + 2);
+}
+
+/* microMIPS 32-bit opcode helper retriever.  */
+
+static bfd_vma
+bfd_get_micromips_32 (const bfd *abfd, const bfd_byte *ptr)
+{
+  return (bfd_get_16 (abfd, ptr) << 16) | bfd_get_16 (abfd, ptr + 2);
+}
+\f
 /* Look up an entry in a MIPS ELF linker hash table.  */
 
 #define mips_elf_link_hash_lookup(table, string, create, copy, follow) \
@@ -1098,6 +1131,15 @@ mips_elf_link_hash_newfunc (struct bfd_hash_entry *entry,
   return (struct bfd_hash_entry *) ret;
 }
 
+/* Allocate MIPS ELF private object data.  */
+
+bfd_boolean
+_bfd_mips_elf_mkobject (bfd *abfd)
+{
+  return bfd_elf_allocate_object (abfd, sizeof (struct mips_elf_obj_tdata),
+                                 MIPS_ELF_DATA);
+}
+
 bfd_boolean
 _bfd_mips_elf_new_section_hook (bfd *abfd, asection *sec)
 {
@@ -5343,7 +5385,10 @@ mips_elf_calculate_relocation (bfd *abfd, bfd *input_bfd,
                                && (target_is_16_bit_code_p
                                    || target_is_micromips_code_p))));
 
-  local_p = h == NULL || SYMBOL_REFERENCES_LOCAL (info, &h->root);
+  local_p = (h == NULL
+            || (h->got_only_for_calls
+                ? SYMBOL_CALLS_LOCAL (info, &h->root)
+                : SYMBOL_REFERENCES_LOCAL (info, &h->root)));
 
   gp0 = _bfd_get_gp_value (input_bfd);
   gp = _bfd_get_gp_value (abfd);
@@ -5930,11 +5975,12 @@ mips_elf_perform_relocation (struct bfd_link_info *info,
          jalx_opcode = 0x1d;
        }
 
-      /* If the opcode is not JAL or JALX, there's a problem.  */
+      /* If the opcode is not JAL or JALX, there's a problem.  We cannot
+         convert J or JALS to JALX.  */
       if (!ok)
        {
          (*_bfd_error_handler)
-           (_("%B: %A+0x%lx: Direct jumps between ISA modes are not allowed; consider recompiling with interlinking enabled."),
+           (_("%B: %A+0x%lx: Unsupported jump between ISA modes; consider recompiling with interlinking enabled."),
             input_bfd,
             input_section,
             (unsigned long) relocation->r_offset);
@@ -7247,7 +7293,7 @@ _bfd_mips_elf_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info)
     return FALSE;
   htab->sstubs = s;
 
-  if ((IRIX_COMPAT (abfd) == ict_irix5 || IRIX_COMPAT (abfd) == ict_none)
+  if (!mips_elf_hash_table (info)->use_rld_obj_head
       && !info->shared
       && bfd_get_linker_section (abfd, ".rld_map") == NULL)
     {
@@ -8522,7 +8568,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
   if (! info->relocatable
       && hmips->possibly_dynamic_relocs != 0
       && (h->root.type == bfd_link_hash_defweak
-         || !h->def_regular
+         || (!h->def_regular && !ELF_COMMON_DEF_P (h))
          || info->shared))
     {
       bfd_boolean do_copy = TRUE;
@@ -9172,8 +9218,8 @@ _bfd_mips_elf_size_dynamic_sections (bfd *output_bfd,
 
       /* SGI object has the equivalence of DT_DEBUG in the
         DT_MIPS_RLD_MAP entry.  This must come first because glibc
-        only fills in DT_MIPS_RLD_MAP (not DT_DEBUG) and GDB only
-        looks at the first one it sees.  */
+        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
          && !MIPS_ELF_ADD_DYNAMIC_ENTRY (info, DT_MIPS_RLD_MAP, 0))
        return FALSE;
@@ -9261,7 +9307,7 @@ _bfd_mips_elf_size_dynamic_sections (bfd *output_bfd,
 
          if (IRIX_COMPAT (dynobj) == ict_irix6
              && (bfd_get_section_by_name
-                 (dynobj, MIPS_ELF_OPTIONS_SECTION_NAME (dynobj)))
+                 (output_bfd, MIPS_ELF_OPTIONS_SECTION_NAME (dynobj)))
              && !MIPS_ELF_ADD_DYNAMIC_ENTRY (info, DT_MIPS_OPTIONS, 0))
            return FALSE;
        }
@@ -9776,14 +9822,12 @@ mips_elf_create_la25_stub (void **slot, void *data)
       loc += offset;
       if (ELF_ST_IS_MICROMIPS (stub->h->root.other))
        {
-         bfd_put_16 (hti->output_bfd, LA25_LUI_MICROMIPS_1 (target_high),
-                     loc);
-         bfd_put_16 (hti->output_bfd, LA25_LUI_MICROMIPS_2 (target_high),
-                     loc + 2);
-         bfd_put_16 (hti->output_bfd, LA25_ADDIU_MICROMIPS_1 (target_low),
-                     loc + 4);
-         bfd_put_16 (hti->output_bfd, LA25_ADDIU_MICROMIPS_2 (target_low),
-                     loc + 6);
+         bfd_put_micromips_32 (hti->output_bfd,
+                               LA25_LUI_MICROMIPS (target_high),
+                               loc);
+         bfd_put_micromips_32 (hti->output_bfd,
+                               LA25_ADDIU_MICROMIPS (target_low),
+                               loc + 4);
        }
       else
        {
@@ -9797,16 +9841,12 @@ mips_elf_create_la25_stub (void **slot, void *data)
       loc += offset;
       if (ELF_ST_IS_MICROMIPS (stub->h->root.other))
        {
-         bfd_put_16 (hti->output_bfd, LA25_LUI_MICROMIPS_1 (target_high),
-                     loc);
-         bfd_put_16 (hti->output_bfd, LA25_LUI_MICROMIPS_2 (target_high),
-                     loc + 2);
-         bfd_put_16 (hti->output_bfd, LA25_J_MICROMIPS_1 (target), loc + 4);
-         bfd_put_16 (hti->output_bfd, LA25_J_MICROMIPS_2 (target), loc + 6);
-         bfd_put_16 (hti->output_bfd, LA25_ADDIU_MICROMIPS_1 (target_low),
-                     loc + 8);
-         bfd_put_16 (hti->output_bfd, LA25_ADDIU_MICROMIPS_2 (target_low),
-                     loc + 10);
+         bfd_put_micromips_32 (hti->output_bfd,
+                               LA25_LUI_MICROMIPS (target_high), loc);
+         bfd_put_micromips_32 (hti->output_bfd,
+                               LA25_J_MICROMIPS (target), loc + 4);
+         bfd_put_micromips_32 (hti->output_bfd,
+                               LA25_ADDIU_MICROMIPS (target_low), loc + 8);
          bfd_put_32 (hti->output_bfd, 0, loc + 12);
        }
       else
@@ -10114,7 +10154,7 @@ _bfd_mips_elf_finish_dynamic_symbol (bfd *output_bfd,
 
   /* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute.  */
   name = h->root.root.string;
-  if (strcmp (name, "_DYNAMIC") == 0
+  if (h == elf_hash_table (info)->hdynamic
       || h == elf_hash_table (info)->hgot)
     sym->st_shndx = SHN_ABS;
   else if (strcmp (name, "_DYNAMIC_LINK") == 0
@@ -12339,7 +12379,7 @@ check_br32_dslot (bfd *abfd, bfd_byte *ptr)
   unsigned long opcode;
   int bdsize;
 
-  opcode = (bfd_get_16 (abfd, ptr) << 16) | bfd_get_16 (abfd, ptr + 2);
+  opcode = bfd_get_micromips_32 (abfd, ptr);
   if (find_match (opcode, ds_insns_32_bd32) >= 0)
     /* 32-bit branch/jump with a 32-bit delay slot.  */
     bdsize = 4;
@@ -12384,7 +12424,7 @@ check_br32 (bfd *abfd, bfd_byte *ptr, unsigned long reg)
 {
   unsigned long opcode;
 
-  opcode = (bfd_get_16 (abfd, ptr) << 16) | bfd_get_16 (abfd, ptr + 2);
+  opcode = bfd_get_micromips_32 (abfd, ptr);
   if (MATCH (opcode, j_insn_32)
                                                /* J  */
       || MATCH (opcode, bc_insn_32)
@@ -12416,9 +12456,7 @@ check_relocated_bzc (bfd *abfd, const bfd_byte *ptr, bfd_vma offset,
   const Elf_Internal_Rela *irel;
   unsigned long opcode;
 
-  opcode   = bfd_get_16 (abfd, ptr);
-  opcode <<= 16;
-  opcode  |= bfd_get_16 (abfd, ptr + 2);
+  opcode = bfd_get_micromips_32 (abfd, ptr);
   if (find_match (opcode, bzc_insns_32) < 0)
     return FALSE;
 
@@ -12576,8 +12614,7 @@ _bfd_mips_elf_relax_section (bfd *abfd, asection *sec,
       if (irel->r_offset + 4 > sec->size)
        continue;
 
-      opcode  = bfd_get_16 (abfd, ptr    ) << 16;
-      opcode |= bfd_get_16 (abfd, ptr + 2);
+      opcode = bfd_get_micromips_32 (abfd, ptr);
 
       /* This is the pc-relative distance from the instruction the
          relocation is applied to, to the symbol referred.  */
@@ -12659,8 +12696,7 @@ _bfd_mips_elf_relax_section (bfd *abfd, asection *sec,
              continue;
            }
 
-         nextopc  = bfd_get_16 (abfd, contents + irel[1].r_offset    ) << 16;
-         nextopc |= bfd_get_16 (abfd, contents + irel[1].r_offset + 2);
+         nextopc = bfd_get_micromips_32 (abfd, contents + irel[1].r_offset);
 
          /* Give up unless the same register is used with both
             relocations.  */
@@ -12701,10 +12737,8 @@ _bfd_mips_elf_relax_section (bfd *abfd, asection *sec,
              nextopc = (addiupc_insn.match
                         | ADDIUPC_REG_FIELD (OP32_TREG (nextopc)));
 
-             bfd_put_16 (abfd, (nextopc >> 16) & 0xffff,
-                         contents + irel[1].r_offset);
-             bfd_put_16 (abfd,  nextopc        & 0xffff,
-                         contents + irel[1].r_offset + 2);
+             bfd_put_micromips_32 (abfd, nextopc,
+                                   contents + irel[1].r_offset);
            }
 
          /* Can't do anything, give up, sigh...  */
@@ -12738,8 +12772,7 @@ _bfd_mips_elf_relax_section (bfd *abfd, asection *sec,
                    | BZC32_REG_FIELD (reg)
                    | (opcode & 0xffff));               /* Addend value.  */
 
-         bfd_put_16 (abfd, (opcode >> 16) & 0xffff, ptr);
-         bfd_put_16 (abfd,  opcode        & 0xffff, ptr + 2);
+         bfd_put_micromips_32 (abfd, opcode, ptr);
 
          /* Delete the 16-bit delay slot NOP: two bytes from
             irel->offset + 4.  */
@@ -12756,7 +12789,7 @@ _bfd_mips_elf_relax_section (bfd *abfd, asection *sec,
          /* Fix the relocation's type.  */
          irel->r_info = ELF32_R_INFO (r_symndx, R_MICROMIPS_PC10_S1);
 
-         /* Replace the the 32-bit opcode with a 16-bit opcode.  */
+         /* Replace the 32-bit opcode with a 16-bit opcode.  */
          bfd_put_16 (abfd,
                      (b_insn_16.match
                       | (opcode & 0x3ff)),             /* Addend value.  */
@@ -12783,7 +12816,7 @@ _bfd_mips_elf_relax_section (bfd *abfd, asection *sec,
          /* Fix the relocation's type.  */
          irel->r_info = ELF32_R_INFO (r_symndx, R_MICROMIPS_PC7_S1);
 
-         /* Replace the the 32-bit opcode with a 16-bit opcode.  */
+         /* Replace the 32-bit opcode with a 16-bit opcode.  */
          bfd_put_16 (abfd,
                      (bz_insns_16[fndopc].match
                       | BZ16_REG_FIELD (reg)
@@ -12804,8 +12837,7 @@ _bfd_mips_elf_relax_section (bfd *abfd, asection *sec,
          unsigned long n32opc;
          bfd_boolean relaxed = FALSE;
 
-         n32opc  = bfd_get_16 (abfd, ptr + 4) << 16;
-         n32opc |= bfd_get_16 (abfd, ptr + 6);
+         n32opc = bfd_get_micromips_32 (abfd, ptr + 4);
 
          if (MATCH (n32opc, nop_insn_32))
            {
@@ -12832,10 +12864,7 @@ _bfd_mips_elf_relax_section (bfd *abfd, asection *sec,
            {
              /* JAL with 32-bit delay slot that is changed to a JALS
                 with 16-bit delay slot.  */
-             bfd_put_16 (abfd, (jal_insn_32_bd16.match >> 16) & 0xffff,
-                         ptr);
-             bfd_put_16 (abfd,  jal_insn_32_bd16.match        & 0xffff,
-                         ptr + 2);
+             bfd_put_micromips_32 (abfd, jal_insn_32_bd16.match, ptr);
 
              /* Delete 2 bytes from irel->r_offset + 6.  */
              delcnt = 2;
@@ -13745,6 +13774,12 @@ mips_elf_merge_obj_attributes (bfd *ibfd, bfd *obfd)
 {
   obj_attribute *in_attr;
   obj_attribute *out_attr;
+  bfd *abi_fp_bfd;
+
+  abi_fp_bfd = mips_elf_tdata (obfd)->abi_fp_bfd;
+  in_attr = elf_known_obj_attributes (ibfd)[OBJ_ATTR_GNU];
+  if (!abi_fp_bfd && in_attr[Tag_GNU_MIPS_ABI_FP].i != 0)
+    mips_elf_tdata (obfd)->abi_fp_bfd = ibfd;
 
   if (!elf_known_obj_attributes_proc (obfd)[0].i)
     {
@@ -13760,24 +13795,13 @@ mips_elf_merge_obj_attributes (bfd *ibfd, bfd *obfd)
 
   /* Check for conflicting Tag_GNU_MIPS_ABI_FP attributes and merge
      non-conflicting ones.  */
-  in_attr = elf_known_obj_attributes (ibfd)[OBJ_ATTR_GNU];
   out_attr = elf_known_obj_attributes (obfd)[OBJ_ATTR_GNU];
   if (in_attr[Tag_GNU_MIPS_ABI_FP].i != out_attr[Tag_GNU_MIPS_ABI_FP].i)
     {
       out_attr[Tag_GNU_MIPS_ABI_FP].type = 1;
       if (out_attr[Tag_GNU_MIPS_ABI_FP].i == 0)
        out_attr[Tag_GNU_MIPS_ABI_FP].i = in_attr[Tag_GNU_MIPS_ABI_FP].i;
-      else if (in_attr[Tag_GNU_MIPS_ABI_FP].i == 0)
-       ;
-      else if (in_attr[Tag_GNU_MIPS_ABI_FP].i > 4)
-       _bfd_error_handler
-         (_("Warning: %B uses unknown floating point ABI %d"), ibfd,
-          in_attr[Tag_GNU_MIPS_ABI_FP].i);
-      else if (out_attr[Tag_GNU_MIPS_ABI_FP].i > 4)
-       _bfd_error_handler
-         (_("Warning: %B uses unknown floating point ABI %d"), obfd,
-          out_attr[Tag_GNU_MIPS_ABI_FP].i);
-      else
+      else if (in_attr[Tag_GNU_MIPS_ABI_FP].i != 0)
        switch (out_attr[Tag_GNU_MIPS_ABI_FP].i)
          {
          case 1:
@@ -13785,24 +13809,30 @@ mips_elf_merge_obj_attributes (bfd *ibfd, bfd *obfd)
              {
              case 2:
                _bfd_error_handler
-                 (_("Warning: %B uses -msingle-float, %B uses -mdouble-float"),
-                  obfd, ibfd);
+                 (_("Warning: %B uses %s (set by %B), %B uses %s"),
+                  obfd, abi_fp_bfd, ibfd, "-mdouble-float", "-msingle-float");
                break;
 
              case 3:
                _bfd_error_handler
-                 (_("Warning: %B uses hard float, %B uses soft float"),
-                  obfd, ibfd);
+                 (_("Warning: %B uses %s (set by %B), %B uses %s"),
+                  obfd, abi_fp_bfd, ibfd, "-mhard-float", "-msoft-float");
                break;
 
              case 4:
                _bfd_error_handler
-                 (_("Warning: %B uses -msingle-float, %B uses -mips32r2 -mfp64"),
-                  obfd, ibfd);
+                 (_("Warning: %B uses %s (set by %B), %B uses %s"),
+                  obfd, abi_fp_bfd, ibfd,
+                  "-mdouble-float", "-mips32r2 -mfp64");
                break;
 
              default:
-               abort ();
+               _bfd_error_handler
+                 (_("Warning: %B uses %s (set by %B), "
+                    "%B uses unknown floating point ABI %d"),
+                  obfd, abi_fp_bfd, ibfd,
+                  "-mdouble-float", in_attr[Tag_GNU_MIPS_ABI_FP].i);
+               break;
              }
            break;
 
@@ -13811,24 +13841,30 @@ mips_elf_merge_obj_attributes (bfd *ibfd, bfd *obfd)
              {
              case 1:
                _bfd_error_handler
-                 (_("Warning: %B uses -msingle-float, %B uses -mdouble-float"),
-                  ibfd, obfd);
+                 (_("Warning: %B uses %s (set by %B), %B uses %s"),
+                  obfd, abi_fp_bfd, ibfd, "-msingle-float", "-mdouble-float");
                break;
 
              case 3:
                _bfd_error_handler
-                 (_("Warning: %B uses hard float, %B uses soft float"),
-                  obfd, ibfd);
+                 (_("Warning: %B uses %s (set by %B), %B uses %s"),
+                  obfd, abi_fp_bfd, ibfd, "-mhard-float", "-msoft-float");
                break;
 
              case 4:
                _bfd_error_handler
-                 (_("Warning: %B uses -mdouble-float, %B uses -mips32r2 -mfp64"),
-                  obfd, ibfd);
+                 (_("Warning: %B uses %s (set by %B), %B uses %s"),
+                  obfd, abi_fp_bfd, ibfd,
+                  "-msingle-float", "-mips32r2 -mfp64");
                break;
 
              default:
-               abort ();
+               _bfd_error_handler
+                 (_("Warning: %B uses %s (set by %B), "
+                    "%B uses unknown floating point ABI %d"),
+                  obfd, abi_fp_bfd, ibfd,
+                  "-msingle-float", in_attr[Tag_GNU_MIPS_ABI_FP].i);
+               break;
              }
            break;
 
@@ -13839,12 +13875,17 @@ mips_elf_merge_obj_attributes (bfd *ibfd, bfd *obfd)
              case 2:
              case 4:
                _bfd_error_handler
-                 (_("Warning: %B uses hard float, %B uses soft float"),
-                  ibfd, obfd);
+                 (_("Warning: %B uses %s (set by %B), %B uses %s"),
+                  obfd, abi_fp_bfd, ibfd, "-msoft-float", "-mhard-float");
                break;
 
              default:
-               abort ();
+               _bfd_error_handler
+                 (_("Warning: %B uses %s (set by %B), "
+                    "%B uses unknown floating point ABI %d"),
+                  obfd, abi_fp_bfd, ibfd,
+                  "-msoft-float", in_attr[Tag_GNU_MIPS_ABI_FP].i);
+               break;
              }
            break;
 
@@ -13853,29 +13894,79 @@ mips_elf_merge_obj_attributes (bfd *ibfd, bfd *obfd)
              {
              case 1:
                _bfd_error_handler
-                 (_("Warning: %B uses -msingle-float, %B uses -mips32r2 -mfp64"),
-                  ibfd, obfd);
+                 (_("Warning: %B uses %s (set by %B), %B uses %s"),
+                  obfd, abi_fp_bfd, ibfd,
+                  "-mips32r2 -mfp64", "-mdouble-float");
                break;
 
              case 2:
                _bfd_error_handler
-                 (_("Warning: %B uses -mdouble-float, %B uses -mips32r2 -mfp64"),
-                  ibfd, obfd);
+                 (_("Warning: %B uses %s (set by %B), %B uses %s"),
+                  obfd, abi_fp_bfd, ibfd,
+                  "-mips32r2 -mfp64", "-msingle-float");
                break;
 
              case 3:
                _bfd_error_handler
-                 (_("Warning: %B uses hard float, %B uses soft float"),
-                  obfd, ibfd);
+                 (_("Warning: %B uses %s (set by %B), %B uses %s"),
+                  obfd, abi_fp_bfd, ibfd, "-mhard-float", "-msoft-float");
                break;
 
              default:
-               abort ();
+               _bfd_error_handler
+                 (_("Warning: %B uses %s (set by %B), "
+                    "%B uses unknown floating point ABI %d"),
+                  obfd, abi_fp_bfd, ibfd,
+                  "-mips32r2 -mfp64", in_attr[Tag_GNU_MIPS_ABI_FP].i);
+               break;
              }
            break;
 
          default:
-           abort ();
+           switch (in_attr[Tag_GNU_MIPS_ABI_FP].i)
+             {
+             case 1:
+               _bfd_error_handler
+                 (_("Warning: %B uses unknown floating point ABI %d "
+                    "(set by %B), %B uses %s"),
+                  obfd, abi_fp_bfd, ibfd,
+                  out_attr[Tag_GNU_MIPS_ABI_FP].i, "-mdouble-float");
+               break;
+
+             case 2:
+               _bfd_error_handler
+                 (_("Warning: %B uses unknown floating point ABI %d "
+                    "(set by %B), %B uses %s"),
+                  obfd, abi_fp_bfd, ibfd,
+                  out_attr[Tag_GNU_MIPS_ABI_FP].i, "-msingle-float");
+               break;
+
+             case 3:
+               _bfd_error_handler
+                 (_("Warning: %B uses unknown floating point ABI %d "
+                    "(set by %B), %B uses %s"),
+                  obfd, abi_fp_bfd, ibfd,
+                  out_attr[Tag_GNU_MIPS_ABI_FP].i, "-msoft-float");
+               break;
+
+             case 4:
+               _bfd_error_handler
+                 (_("Warning: %B uses unknown floating point ABI %d "
+                    "(set by %B), %B uses %s"),
+                  obfd, abi_fp_bfd, ibfd,
+                  out_attr[Tag_GNU_MIPS_ABI_FP].i, "-mips32r2 -mfp64");
+               break;
+
+             default:
+               _bfd_error_handler
+                 (_("Warning: %B uses unknown floating point ABI %d "
+                    "(set by %B), %B uses unknown floating point ABI %d"),
+                  obfd, abi_fp_bfd, ibfd,
+                  out_attr[Tag_GNU_MIPS_ABI_FP].i,
+                  in_attr[Tag_GNU_MIPS_ABI_FP].i);
+               break;
+             }
+           break;
          }
     }
 
This page took 0.033902 seconds and 4 git commands to generate.