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.
This commit is contained in:
Alan Modra 2018-07-04 10:41:31 +09:30
parent 4423fa9672
commit 4a91d0ba30
13 changed files with 96 additions and 44 deletions

View File

@ -1,3 +1,14 @@
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-04 H.J. Lu <hongjiu.lu@intel.com>
* Makefile.am (bfdinclude_HEADERS): Add $(INCDIR)/diagnostics.h.

View File

@ -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

View File

@ -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);

View File

@ -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);

View File

@ -1,3 +1,14 @@
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-04 H.J. Lu <hongjiu.lu@intel.com>
PR ld/23309

View File

@ -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*-*-*

View File

@ -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*-*-*

View File

@ -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*-*-*

View File

@ -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*-*-*

View File

@ -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*-*-*

View File

@ -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*-*-*

View File

@ -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*-*-*

View File

@ -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*-*-*