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,
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. */
/* 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))
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;
}
+/* 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. */
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;