Error for mismatched powerpc ABI tags

Alan Modra amodra@gmail.com
Thu Jul 5 00:50:00 GMT 2018


And report the two input files that are incompatible rather than
reporting that an input file is incompatible with the output.  I think
that's rather more useful.  Saying that a file is incompatible with
the output leaves a user wondering why the output file is that way,
and those users who eventually figure out it has something to do with
input files before the one reported don't know which input file.

Nick, I'd like this on the branch too please.

bfd/
	* elf-bfd.h (_bfd_elf_ppc_merge_fp_attributes): Update prototype.
	* elf32-ppc.c (_bfd_elf_ppc_merge_fp_attributes): Return error
	on mismatch.  Remove "warning: " from messages.  Track last bfd
	used to set tags.
	(ppc_elf_merge_obj_attributes): Likewise.  Handle status from
	_bfd_elf_ppc_merge_fp_attributes.
	* elf64-ppc.c (ppc64_elf_merge_private_bfd_data): Handle status
	from _bfd_elf_ppc_merge_fp_attributes.
ld/
	* testsuite/ld-powerpc/attr-gnu-4-12.d: Update expected output.
	* testsuite/ld-powerpc/attr-gnu-4-13.d: Likewise.
	* testsuite/ld-powerpc/attr-gnu-4-21.d: Likewise.
	* testsuite/ld-powerpc/attr-gnu-4-23.d: Likewise.
	* testsuite/ld-powerpc/attr-gnu-4-31.d: Likewise.
	* testsuite/ld-powerpc/attr-gnu-4-32.d: Likewise.
	* testsuite/ld-powerpc/attr-gnu-8-23.d: Likewise.
	* testsuite/ld-powerpc/attr-gnu-12-21.d: Likewise.

diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h
index 3ed16de89c..e8eac7bf01 100644
--- a/bfd/elf-bfd.h
+++ b/bfd/elf-bfd.h
@@ -2548,7 +2548,8 @@ extern unsigned int _bfd_elf_ppc_at_tprel_transform
 /* PowerPC elf_object_p tweak.  */
 extern bfd_boolean _bfd_elf_ppc_set_arch (bfd *);
 /* PowerPC .gnu.attributes handling common to both 32-bit and 64-bit.  */
-extern void _bfd_elf_ppc_merge_fp_attributes (bfd *, struct bfd_link_info *);
+extern bfd_boolean _bfd_elf_ppc_merge_fp_attributes
+  (bfd *, struct bfd_link_info *);
 
 /* Exported interface for writing elf corefile notes.  */
 extern char *elfcore_write_note
diff --git a/bfd/elf32-ppc.c b/bfd/elf32-ppc.c
index a97e127948..3024674007 100644
--- a/bfd/elf32-ppc.c
+++ b/bfd/elf32-ppc.c
@@ -4713,12 +4713,13 @@ ppc_elf_check_relocs (bfd *abfd,
 
 /* Warn for conflicting Tag_GNU_Power_ABI_FP attributes between IBFD
    and OBFD, and merge non-conflicting ones.  */
-void
+bfd_boolean
 _bfd_elf_ppc_merge_fp_attributes (bfd *ibfd, struct bfd_link_info *info)
 {
   bfd *obfd = info->output_bfd;
   obj_attribute *in_attr, *in_attrs;
   obj_attribute *out_attr, *out_attrs;
+  bfd_boolean ret = TRUE;
 
   in_attrs = elf_known_obj_attributes (ibfd)[OBJ_ATTR_GNU];
   out_attrs = elf_known_obj_attributes (obfd)[OBJ_ATTR_GNU];
@@ -4730,6 +4731,7 @@ _bfd_elf_ppc_merge_fp_attributes (bfd *ibfd, struct bfd_link_info *info)
     {
       int in_fp = in_attr->i & 3;
       int out_fp = out_attr->i & 3;
+      static bfd *last_fp, *last_ld;
 
       if (in_fp == 0)
 	;
@@ -4737,38 +4739,39 @@ _bfd_elf_ppc_merge_fp_attributes (bfd *ibfd, struct bfd_link_info *info)
 	{
 	  out_attr->type = ATTR_TYPE_FLAG_INT_VAL;
 	  out_attr->i ^= in_fp;
+	  last_fp = ibfd;
 	}
       else if (out_fp != 2 && in_fp == 2)
 	{
 	  _bfd_error_handler
 	    /* xgettext:c-format */
-	    (_("warning: %pB uses hard float, %pB uses soft float"),
-	     obfd, ibfd);
-	  out_attr->type = ATTR_TYPE_FLAG_INT_VAL | ATTR_TYPE_FLAG_ERROR;
+	    (_("%pB uses hard float, %pB uses soft float"),
+	     last_fp, ibfd);
+	  ret = FALSE;
 	}
       else if (out_fp == 2 && in_fp != 2)
 	{
 	  _bfd_error_handler
 	    /* xgettext:c-format */
-	    (_("warning: %pB uses hard float, %pB uses soft float"),
-	     ibfd, obfd);
-	  out_attr->type = ATTR_TYPE_FLAG_INT_VAL | ATTR_TYPE_FLAG_ERROR;
+	    (_("%pB uses hard float, %pB uses soft float"),
+	     ibfd, last_fp);
+	  ret = FALSE;
 	}
       else if (out_fp == 1 && in_fp == 3)
 	{
 	  _bfd_error_handler
 	    /* xgettext:c-format */
-	    (_("warning: %pB uses double-precision hard float, "
-	       "%pB uses single-precision hard float"), obfd, ibfd);
-	  out_attr->type = ATTR_TYPE_FLAG_INT_VAL | ATTR_TYPE_FLAG_ERROR;
+	    (_("%pB uses double-precision hard float, "
+	       "%pB uses single-precision hard float"), last_fp, ibfd);
+	  ret = FALSE;
 	}
       else if (out_fp == 3 && in_fp == 1)
 	{
 	  _bfd_error_handler
 	    /* xgettext:c-format */
-	    (_("warning: %pB uses double-precision hard float, "
-	       "%pB uses single-precision hard float"), ibfd, obfd);
-	  out_attr->type = ATTR_TYPE_FLAG_INT_VAL | ATTR_TYPE_FLAG_ERROR;
+	    (_("%pB uses double-precision hard float, "
+	       "%pB uses single-precision hard float"), ibfd, last_fp);
+	  ret = FALSE;
 	}
 
       in_fp = in_attr->i & 0xc;
@@ -4779,40 +4782,48 @@ _bfd_elf_ppc_merge_fp_attributes (bfd *ibfd, struct bfd_link_info *info)
 	{
 	  out_attr->type = ATTR_TYPE_FLAG_INT_VAL;
 	  out_attr->i ^= in_fp;
+	  last_ld = ibfd;
 	}
       else if (out_fp != 2 * 4 && in_fp == 2 * 4)
 	{
 	  _bfd_error_handler
 	    /* xgettext:c-format */
-	    (_("warning: %pB uses 64-bit long double, "
-	       "%pB uses 128-bit long double"), ibfd, obfd);
-	  out_attr->type = ATTR_TYPE_FLAG_INT_VAL | ATTR_TYPE_FLAG_ERROR;
+	    (_("%pB uses 64-bit long double, "
+	       "%pB uses 128-bit long double"), ibfd, last_ld);
+	  ret = FALSE;
 	}
       else if (in_fp != 2 * 4 && out_fp == 2 * 4)
 	{
 	  _bfd_error_handler
 	    /* xgettext:c-format */
-	    (_("warning: %pB uses 64-bit long double, "
-	       "%pB uses 128-bit long double"), obfd, ibfd);
-	  out_attr->type = ATTR_TYPE_FLAG_INT_VAL | ATTR_TYPE_FLAG_ERROR;
+	    (_("%pB uses 64-bit long double, "
+	       "%pB uses 128-bit long double"), last_ld, ibfd);
+	  ret = FALSE;
 	}
       else if (out_fp == 1 * 4 && in_fp == 3 * 4)
 	{
 	  _bfd_error_handler
 	    /* xgettext:c-format */
-	    (_("warning: %pB uses IBM long double, "
-	       "%pB uses IEEE long double"), obfd, ibfd);
-	  out_attr->type = ATTR_TYPE_FLAG_INT_VAL | ATTR_TYPE_FLAG_ERROR;
+	    (_("%pB uses IBM long double, "
+	       "%pB uses IEEE long double"), last_ld, ibfd);
+	  ret = FALSE;
 	}
       else if (out_fp == 3 * 4 && in_fp == 1 * 4)
 	{
 	  _bfd_error_handler
 	    /* xgettext:c-format */
-	    (_("warning: %pB uses IBM long double, "
-	       "%pB uses IEEE long double"), ibfd, obfd);
-	  out_attr->type = ATTR_TYPE_FLAG_INT_VAL | ATTR_TYPE_FLAG_ERROR;
+	    (_("%pB uses IBM long double, "
+	       "%pB uses IEEE long double"), ibfd, last_ld);
+	  ret = FALSE;
 	}
     }
+
+  if (!ret)
+    {
+      out_attr->type = ATTR_TYPE_FLAG_INT_VAL | ATTR_TYPE_FLAG_ERROR;
+      bfd_set_error (bfd_error_bad_value);
+    }
+  return ret;
 }
 
 /* Merge object attributes from IBFD into OBFD.  Warn if
@@ -4823,8 +4834,10 @@ ppc_elf_merge_obj_attributes (bfd *ibfd, struct bfd_link_info *info)
   bfd *obfd;
   obj_attribute *in_attr, *in_attrs;
   obj_attribute *out_attr, *out_attrs;
+  bfd_boolean ret;
 
-  _bfd_elf_ppc_merge_fp_attributes (ibfd, info);
+  if (!_bfd_elf_ppc_merge_fp_attributes (ibfd, info))
+    return FALSE;
 
   obfd = info->output_bfd;
   in_attrs = elf_known_obj_attributes (ibfd)[OBJ_ATTR_GNU];
@@ -4834,10 +4847,12 @@ ppc_elf_merge_obj_attributes (bfd *ibfd, struct bfd_link_info *info)
      merge non-conflicting ones.  */
   in_attr = &in_attrs[Tag_GNU_Power_ABI_Vector];
   out_attr = &out_attrs[Tag_GNU_Power_ABI_Vector];
+  ret = TRUE;
   if (in_attr->i != out_attr->i)
     {
       int in_vec = in_attr->i & 3;
       int out_vec = out_attr->i & 3;
+      static bfd *last_vec;
 
       if (in_vec == 0)
 	;
@@ -4845,6 +4860,7 @@ ppc_elf_merge_obj_attributes (bfd *ibfd, struct bfd_link_info *info)
 	{
 	  out_attr->type = ATTR_TYPE_FLAG_INT_VAL;
 	  out_attr->i = in_vec;
+	  last_vec = ibfd;
 	}
       /* For now, allow generic to transition to AltiVec or SPE
 	 without a warning.  If GCC marked files with their stack
@@ -4857,22 +4873,25 @@ ppc_elf_merge_obj_attributes (bfd *ibfd, struct bfd_link_info *info)
 	{
 	  out_attr->type = ATTR_TYPE_FLAG_INT_VAL;
 	  out_attr->i = in_vec;
+	  last_vec = ibfd;
 	}
       else if (out_vec < in_vec)
 	{
 	  _bfd_error_handler
 	    /* xgettext:c-format */
-	    (_("warning: %pB uses AltiVec vector ABI, %pB uses SPE vector ABI"),
-	     obfd, ibfd);
+	    (_("%pB uses AltiVec vector ABI, %pB uses SPE vector ABI"),
+	     last_vec, ibfd);
 	  out_attr->type = ATTR_TYPE_FLAG_INT_VAL | ATTR_TYPE_FLAG_ERROR;
+	  ret = FALSE;
 	}
       else if (out_vec > in_vec)
 	{
 	  _bfd_error_handler
 	    /* xgettext:c-format */
-	    (_("warning: %pB uses AltiVec vector ABI, %pB uses SPE vector ABI"),
-	     ibfd, obfd);
+	    (_("%pB uses AltiVec vector ABI, %pB uses SPE vector ABI"),
+	     ibfd, last_vec);
 	  out_attr->type = ATTR_TYPE_FLAG_INT_VAL | ATTR_TYPE_FLAG_ERROR;
+	  ret = FALSE;
 	}
     }
 
@@ -4884,6 +4903,7 @@ ppc_elf_merge_obj_attributes (bfd *ibfd, struct bfd_link_info *info)
     {
       int in_struct = in_attr->i & 3;
       int out_struct = out_attr->i & 3;
+      static bfd *last_struct;
 
       if (in_struct == 0 || in_struct == 3)
        ;
@@ -4891,24 +4911,32 @@ ppc_elf_merge_obj_attributes (bfd *ibfd, struct bfd_link_info *info)
 	{
 	  out_attr->type = ATTR_TYPE_FLAG_INT_VAL;
 	  out_attr->i = in_struct;
+	  last_struct = ibfd;
 	}
       else if (out_struct < in_struct)
 	{
 	  _bfd_error_handler
 	    /* xgettext:c-format */
-	    (_("warning: %pB uses r3/r4 for small structure returns, "
-	       "%pB uses memory"), obfd, ibfd);
+	    (_("%pB uses r3/r4 for small structure returns, "
+	       "%pB uses memory"), last_struct, ibfd);
 	  out_attr->type = ATTR_TYPE_FLAG_INT_VAL | ATTR_TYPE_FLAG_ERROR;
+	  ret = FALSE;
 	}
       else if (out_struct > in_struct)
 	{
 	  _bfd_error_handler
 	    /* xgettext:c-format */
-	    (_("warning: %pB uses r3/r4 for small structure returns, "
-	       "%pB uses memory"), ibfd, obfd);
+	    (_("%pB uses r3/r4 for small structure returns, "
+	       "%pB uses memory"), ibfd, last_struct);
 	  out_attr->type = ATTR_TYPE_FLAG_INT_VAL | ATTR_TYPE_FLAG_ERROR;
+	  ret = FALSE;
 	}
     }
+  if (!ret)
+    {
+      bfd_set_error (bfd_error_bad_value);
+      return FALSE;
+    }
 
   /* Merge Tag_compatibility attributes and any common GNU ones.  */
   return _bfd_elf_merge_object_attributes (ibfd, info);
diff --git a/bfd/elf64-ppc.c b/bfd/elf64-ppc.c
index 894a3b7d1a..b780f1ab13 100644
--- a/bfd/elf64-ppc.c
+++ b/bfd/elf64-ppc.c
@@ -6177,7 +6177,8 @@ ppc64_elf_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info)
       return FALSE;
     }
 
-  _bfd_elf_ppc_merge_fp_attributes (ibfd, info);
+  if (!_bfd_elf_ppc_merge_fp_attributes (ibfd, info))
+    return FALSE;
 
   /* Merge Tag_compatibility attributes and any common GNU ones.  */
   return _bfd_elf_merge_object_attributes (ibfd, info);
diff --git a/ld/testsuite/ld-powerpc/attr-gnu-12-21.d b/ld/testsuite/ld-powerpc/attr-gnu-12-21.d
index d651d7aab0..43ce690ab1 100644
--- a/ld/testsuite/ld-powerpc/attr-gnu-12-21.d
+++ b/ld/testsuite/ld-powerpc/attr-gnu-12-21.d
@@ -2,5 +2,5 @@
 #source: attr-gnu-12-1.s
 #as: -a32
 #ld: -r -melf32ppc
-#warning: warning: .* uses r3/r4 for small structure returns, .* uses memory
+#error: .* uses r3/r4 for small structure returns, .* uses memory
 #target: powerpc*-*-*
diff --git a/ld/testsuite/ld-powerpc/attr-gnu-4-12.d b/ld/testsuite/ld-powerpc/attr-gnu-4-12.d
index 9e5eb45785..642076a2a3 100644
--- a/ld/testsuite/ld-powerpc/attr-gnu-4-12.d
+++ b/ld/testsuite/ld-powerpc/attr-gnu-4-12.d
@@ -2,5 +2,5 @@
 #source: attr-gnu-4-2.s
 #as: -a32
 #ld: -r -melf32ppc
-#warning: warning: .* uses hard float, .* uses soft float
+#error: .* uses hard float, .* uses soft float
 #target: powerpc*-*-*
diff --git a/ld/testsuite/ld-powerpc/attr-gnu-4-13.d b/ld/testsuite/ld-powerpc/attr-gnu-4-13.d
index d69da1d483..255042ca3d 100644
--- a/ld/testsuite/ld-powerpc/attr-gnu-4-13.d
+++ b/ld/testsuite/ld-powerpc/attr-gnu-4-13.d
@@ -2,5 +2,5 @@
 #source: attr-gnu-4-3.s
 #as: -a32
 #ld: -r -melf32ppc
-#warning: warning: .* uses double-precision hard float, .* uses single-precision hard float
+#error: .* uses double-precision hard float, .* uses single-precision hard float
 #target: powerpc*-*-*
diff --git a/ld/testsuite/ld-powerpc/attr-gnu-4-21.d b/ld/testsuite/ld-powerpc/attr-gnu-4-21.d
index 65020cc23f..0e413264c9 100644
--- a/ld/testsuite/ld-powerpc/attr-gnu-4-21.d
+++ b/ld/testsuite/ld-powerpc/attr-gnu-4-21.d
@@ -2,5 +2,5 @@
 #source: attr-gnu-4-1.s
 #as: -a32
 #ld: -r -melf32ppc
-#warning: warning: .* uses hard float, .* uses soft float
+#error: .* uses hard float, .* uses soft float
 #target: powerpc*-*-*
diff --git a/ld/testsuite/ld-powerpc/attr-gnu-4-23.d b/ld/testsuite/ld-powerpc/attr-gnu-4-23.d
index cb22893716..ebac5e0cef 100644
--- a/ld/testsuite/ld-powerpc/attr-gnu-4-23.d
+++ b/ld/testsuite/ld-powerpc/attr-gnu-4-23.d
@@ -2,5 +2,5 @@
 #source: attr-gnu-4-3.s
 #as: -a32
 #ld: -r -melf32ppc
-#warning: warning: .* uses hard float, .* uses soft float
+#error: .* uses hard float, .* uses soft float
 #target: powerpc*-*-*
diff --git a/ld/testsuite/ld-powerpc/attr-gnu-4-31.d b/ld/testsuite/ld-powerpc/attr-gnu-4-31.d
index 1686f4e74a..e893ed1e78 100644
--- a/ld/testsuite/ld-powerpc/attr-gnu-4-31.d
+++ b/ld/testsuite/ld-powerpc/attr-gnu-4-31.d
@@ -2,5 +2,5 @@
 #source: attr-gnu-4-1.s
 #as: -a32
 #ld: -r -melf32ppc
-#warning: warning: .* uses double-precision hard float, .* uses single-precision hard float
+#error: .* uses double-precision hard float, .* uses single-precision hard float
 #target: powerpc*-*-*
diff --git a/ld/testsuite/ld-powerpc/attr-gnu-4-32.d b/ld/testsuite/ld-powerpc/attr-gnu-4-32.d
index aeca8f3ed6..4cadff5323 100644
--- a/ld/testsuite/ld-powerpc/attr-gnu-4-32.d
+++ b/ld/testsuite/ld-powerpc/attr-gnu-4-32.d
@@ -2,5 +2,5 @@
 #source: attr-gnu-4-2.s
 #as: -a32
 #ld: -r -melf32ppc
-#warning: warning: .* uses hard float, .* uses soft float
+#error: .* uses hard float, .* uses soft float
 #target: powerpc*-*-*
diff --git a/ld/testsuite/ld-powerpc/attr-gnu-8-23.d b/ld/testsuite/ld-powerpc/attr-gnu-8-23.d
index 3518956756..efdd4cafcb 100644
--- a/ld/testsuite/ld-powerpc/attr-gnu-8-23.d
+++ b/ld/testsuite/ld-powerpc/attr-gnu-8-23.d
@@ -2,5 +2,5 @@
 #source: attr-gnu-8-3.s
 #as: -a32
 #ld: -r -melf32ppc
-#warning: warning: .* uses AltiVec vector ABI, .* uses SPE vector ABI
+#error: .* uses AltiVec vector ABI, .* uses SPE vector ABI
 #target: powerpc*-*-*

-- 
Alan Modra
Australia Development Lab, IBM



More information about the Binutils mailing list