Commit 2df83626 authored by Alan Modra's avatar Alan Modra

Error for mismatched powerpc ABI tags

And report the two input files that are incompatible rather than
reporting that an input file is incompatible with the output.

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.

(cherry picked from commit 4a91d0ba)
parent e89e89c9
2018-07-05 Alan Modra <amodra@gmail.com>
* 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.
2018-07-03 Alan Modra <amodra@gmail.com>
* elflink.c (bfd_elf_final_link): Remove zero size .gnu.attributes
......
......@@ -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
......
......@@ -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);
......
......@@ -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);
......
2018-07-05 Alan Modra <amodra@gmail.com>
* 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.
2018-07-05 H.J. Lu <hongjiu.lu@intel.com>
PR ld/23309
......
......@@ -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*-*-*
......@@ -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*-*-*
......@@ -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*-*-*
......@@ -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*-*-*
......@@ -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*-*-*
......@@ -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*-*-*
......@@ -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*-*-*
......@@ -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*-*-*
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment