aboutsummaryrefslogtreecommitdiff
path: root/bfd/elfxx-mips.c
diff options
context:
space:
mode:
Diffstat (limited to 'bfd/elfxx-mips.c')
-rw-r--r--bfd/elfxx-mips.c161
1 files changed, 124 insertions, 37 deletions
diff --git a/bfd/elfxx-mips.c b/bfd/elfxx-mips.c
index 7b66c8a..168973e 100644
--- a/bfd/elfxx-mips.c
+++ b/bfd/elfxx-mips.c
@@ -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 \
@@ -1115,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)
{
@@ -13749,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)
{
@@ -13764,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:
@@ -13789,24 +13809,30 @@ mips_elf_merge_obj_attributes (bfd *ibfd, bfd *obfd)
{
case 2:
_bfd_error_handler
- (_("Warning: %B uses -mdouble-float, %B uses -msingle-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 -mdouble-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;
@@ -13815,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"),
- obfd, ibfd);
+ (_("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 -msingle-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;
@@ -13843,12 +13875,17 @@ mips_elf_merge_obj_attributes (bfd *ibfd, bfd *obfd)
case 2:
case 4:
_bfd_error_handler
- (_("Warning: %B uses soft float, %B uses hard float"),
- obfd, ibfd);
+ (_("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;
@@ -13857,29 +13894,79 @@ mips_elf_merge_obj_attributes (bfd *ibfd, bfd *obfd)
{
case 1:
_bfd_error_handler
- (_("Warning: %B uses -mips32r2 -mfp64, %B uses -mdouble-float"),
- obfd, ibfd);
+ (_("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 -mips32r2 -mfp64, %B uses -msingle-float"),
- obfd, ibfd);
+ (_("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;
}
}