Change sources over to using GPLv3
[deliverable/binutils-gdb.git] / bfd / elfxx-mips.c
index 1bccb331de937eb8f59027da37c9e101dfe1d357..1345b3a3103d769fe6b56019b7fb731586c99ae8 100644 (file)
@@ -13,7 +13,7 @@
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
+   the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
 
    This program is distributed in the hope that it will be useful,
    (at your option) any later version.
 
    This program is distributed in the hope that it will be useful,
@@ -23,7 +23,9 @@
 
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
 
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
-   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
+   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+   MA 02110-1301, USA.  */
+
 
 /* This file handles functionality common to the different MIPS ABI's.  */
 
 
 /* This file handles functionality common to the different MIPS ABI's.  */
 
@@ -4092,8 +4094,7 @@ mips_elf_calculate_relocation (bfd *abfd, bfd *input_bfd,
   /* 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->relocatable
   /* 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->relocatable
-          && h != NULL
-          && ((h->call_stub != NULL || h->call_fp_stub != NULL)
+          && ((h != NULL && (h->call_stub != NULL || h->call_fp_stub != NULL))
               || (local_p
                   && elf_tdata (input_bfd)->local_call_stubs != NULL
                   && elf_tdata (input_bfd)->local_call_stubs[r_symndx] != NULL))
               || (local_p
                   && elf_tdata (input_bfd)->local_call_stubs != NULL
                   && elf_tdata (input_bfd)->local_call_stubs[r_symndx] != NULL))
@@ -4356,6 +4357,8 @@ mips_elf_calculate_relocation (bfd *abfd, bfd *input_bfd,
       break;
 
     case R_MIPS_TLS_DTPREL_LO16:
       break;
 
     case R_MIPS_TLS_DTPREL_LO16:
+    case R_MIPS_TLS_DTPREL32:
+    case R_MIPS_TLS_DTPREL64:
       value = (symbol + addend - dtprel_base (info)) & howto->dst_mask;
       break;
 
       value = (symbol + addend - dtprel_base (info)) & howto->dst_mask;
       break;
 
@@ -10961,6 +10964,112 @@ mips_32bit_flags_p (flagword flags)
 }
 
 
 }
 
 
+/* Merge object attributes from IBFD into OBFD.  Raise an error if
+   there are conflicting attributes.  */
+static bfd_boolean
+mips_elf_merge_obj_attributes (bfd *ibfd, bfd *obfd)
+{
+  obj_attribute *in_attr;
+  obj_attribute *out_attr;
+
+  if (!elf_known_obj_attributes_proc (obfd)[0].i)
+    {
+      /* This is the first object.  Copy the attributes.  */
+      _bfd_elf_copy_obj_attributes (ibfd, obfd);
+
+      /* Use the Tag_null value to indicate the attributes have been
+        initialized.  */
+      elf_known_obj_attributes_proc (obfd)[0].i = 1;
+
+      return TRUE;
+    }
+
+  /* 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 > 3)
+       _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 > 3)
+       _bfd_error_handler
+         (_("Warning: %B uses unknown floating point ABI %d"), obfd,
+          out_attr[Tag_GNU_MIPS_ABI_FP].i);
+      else
+       switch (out_attr[Tag_GNU_MIPS_ABI_FP].i)
+         {
+         case 1:
+           switch (in_attr[Tag_GNU_MIPS_ABI_FP].i)
+             {
+             case 2:
+               _bfd_error_handler
+                 (_("Warning: %B uses -msingle-float, %B uses -mdouble-float"),
+                  obfd, ibfd);
+
+             case 3:
+               _bfd_error_handler
+                 (_("Warning: %B uses hard float, %B uses soft float"),
+                  obfd, ibfd);
+               break;
+
+             default:
+               abort ();
+             }
+           break;
+
+         case 2:
+           switch (in_attr[Tag_GNU_MIPS_ABI_FP].i)
+             {
+             case 1:
+               _bfd_error_handler
+                 (_("Warning: %B uses -msingle-float, %B uses -mdouble-float"),
+                  ibfd, obfd);
+
+             case 3:
+               _bfd_error_handler
+                 (_("Warning: %B uses hard float, %B uses soft float"),
+                  obfd, ibfd);
+               break;
+
+             default:
+               abort ();
+             }
+           break;
+
+         case 3:
+           switch (in_attr[Tag_GNU_MIPS_ABI_FP].i)
+             {
+             case 1:
+             case 2:
+               _bfd_error_handler
+                 (_("Warning: %B uses hard float, %B uses soft float"),
+                  ibfd, obfd);
+               break;
+
+             default:
+               abort ();
+             }
+           break;
+
+         default:
+           abort ();
+         }
+    }
+
+  /* Merge Tag_compatibility attributes and any common GNU ones.  */
+  _bfd_elf_merge_object_attributes (ibfd, obfd);
+
+  return TRUE;
+}
+
 /* Merge backend specific data from an object file to the output
    object file when linking.  */
 
 /* Merge backend specific data from an object file to the output
    object file when linking.  */
 
@@ -10994,6 +11103,9 @@ _bfd_mips_elf_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
       return FALSE;
     }
 
       return FALSE;
     }
 
+  if (!mips_elf_merge_obj_attributes (ibfd, obfd))
+    return FALSE;
+
   new_flags = elf_elfheader (ibfd)->e_flags;
   elf_elfheader (obfd)->e_flags |= new_flags & EF_MIPS_NOREORDER;
   old_flags = elf_elfheader (obfd)->e_flags;
   new_flags = elf_elfheader (ibfd)->e_flags;
   elf_elfheader (obfd)->e_flags |= new_flags & EF_MIPS_NOREORDER;
   old_flags = elf_elfheader (obfd)->e_flags;
This page took 0.028179 seconds and 4 git commands to generate.