summaryrefslogtreecommitdiff
path: root/bfd/elf32-ppc.c
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2018-07-03 14:50:38 +0930
committerAlan Modra <amodra@gmail.com>2018-07-03 16:46:54 +0930
commit8d2c8c3d17926826864f4b739362f66af547428f (patch)
tree1878b3e0bc092c6c79bff4516878e1905efb45b4 /bfd/elf32-ppc.c
parentaf0bfb9c4283ce80fe37ad6360d12cae8ec38696 (diff)
downloadbinutils-gdb-8d2c8c3d17926826864f4b739362f66af547428f.tar.gz
GNU attribute output on errors
.gnu.attributes entries from linker input files are merged to the output file, the output having the union of compatible input attributes. Incompatible attributes generally cause a linker error and no output. However in some cases only a warning is emitted, and one of the incompatible input attributes is passed on to the output. PowerPC tends to emit warnings rather than errors, and the output takes the first input attribute. For example, if we have two input files with Tag_GNU_Power_ABI_FP, the first with a value signifying "double-precision hard float, IBM long double", the second with a value signifying "double-precision hard float, IEEE long double", we'll get a warning about incompatible long double types and the output will say "double-precision hard float, IBM long double". The output attribute of course isn't correct. It would be correct to specify "IBM and IEEE long double", but we don't have a way to represent that currently. While it would be possible to extend the encoding, there isn't much gain in doing so. A shared library providing support for both long double types should link against objects using either long double type without warning or error. That is what you'd get if such a shared library had no Tag_GNU_Power_ABI_FP attribute. So this patch provides a way for the backend to omit .gnu.attributes tags from the output. * elf-bfd.h (ATTR_TYPE_FLAG_ERROR, ATTR_TYPE_HAS_ERROR): Define. * elf-attrs.c (is_default_attr): Handle ATTR_TYPE_HAS_ERROR. * elf32-ppc.c (_bfd_elf_ppc_merge_fp_attributes): Use ATTR_TYPE_FLAG_INT_VAL. Set ATTR_TYPE_HAS_ERROR on finding incompatible attribute. (ppc_elf_merge_obj_attributes): Likewise. Return _bfd_elf_merge_object_attributes result. * elf64-ppc.c (ppc64_elf_merge_private_bfd_data): Return _bfd_elf_merge_object_attributes result.
Diffstat (limited to 'bfd/elf32-ppc.c')
-rw-r--r--bfd/elf32-ppc.c144
1 files changed, 90 insertions, 54 deletions
diff --git a/bfd/elf32-ppc.c b/bfd/elf32-ppc.c
index ea8dbed9819..a97e1279485 100644
--- a/bfd/elf32-ppc.c
+++ b/bfd/elf32-ppc.c
@@ -4735,27 +4735,41 @@ _bfd_elf_ppc_merge_fp_attributes (bfd *ibfd, struct bfd_link_info *info)
;
else if (out_fp == 0)
{
- out_attr->type = 1;
+ out_attr->type = ATTR_TYPE_FLAG_INT_VAL;
out_attr->i ^= in_fp;
}
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);
+ {
+ _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;
+ }
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);
+ {
+ _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;
+ }
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);
+ {
+ _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;
+ }
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);
+ {
+ _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;
+ }
in_fp = in_attr->i & 0xc;
out_fp = out_attr->i & 0xc;
@@ -4763,29 +4777,41 @@ _bfd_elf_ppc_merge_fp_attributes (bfd *ibfd, struct bfd_link_info *info)
;
else if (out_fp == 0)
{
- out_attr->type = 1;
+ out_attr->type = ATTR_TYPE_FLAG_INT_VAL;
out_attr->i ^= in_fp;
}
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);
+ {
+ _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;
+ }
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);
+ {
+ _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;
+ }
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);
+ {
+ _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;
+ }
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);
+ {
+ _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;
+ }
}
}
@@ -4817,7 +4843,7 @@ ppc_elf_merge_obj_attributes (bfd *ibfd, struct bfd_link_info *info)
;
else if (out_vec == 0)
{
- out_attr->type = 1;
+ out_attr->type = ATTR_TYPE_FLAG_INT_VAL;
out_attr->i = in_vec;
}
/* For now, allow generic to transition to AltiVec or SPE
@@ -4829,19 +4855,25 @@ ppc_elf_merge_obj_attributes (bfd *ibfd, struct bfd_link_info *info)
;
else if (out_vec == 1)
{
- out_attr->type = 1;
+ out_attr->type = ATTR_TYPE_FLAG_INT_VAL;
out_attr->i = in_vec;
}
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);
+ {
+ _bfd_error_handler
+ /* xgettext:c-format */
+ (_("warning: %pB uses AltiVec vector ABI, %pB uses SPE vector ABI"),
+ obfd, ibfd);
+ out_attr->type = ATTR_TYPE_FLAG_INT_VAL | ATTR_TYPE_FLAG_ERROR;
+ }
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);
+ {
+ _bfd_error_handler
+ /* xgettext:c-format */
+ (_("warning: %pB uses AltiVec vector ABI, %pB uses SPE vector ABI"),
+ ibfd, obfd);
+ out_attr->type = ATTR_TYPE_FLAG_INT_VAL | ATTR_TYPE_FLAG_ERROR;
+ }
}
/* Check for conflicting Tag_GNU_Power_ABI_Struct_Return attributes
@@ -4857,25 +4889,29 @@ ppc_elf_merge_obj_attributes (bfd *ibfd, struct bfd_link_info *info)
;
else if (out_struct == 0)
{
- out_attr->type = 1;
+ out_attr->type = ATTR_TYPE_FLAG_INT_VAL;
out_attr->i = in_struct;
}
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);
+ {
+ _bfd_error_handler
+ /* xgettext:c-format */
+ (_("warning: %pB uses r3/r4 for small structure returns, "
+ "%pB uses memory"), obfd, ibfd);
+ out_attr->type = ATTR_TYPE_FLAG_INT_VAL | ATTR_TYPE_FLAG_ERROR;
+ }
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);
+ {
+ _bfd_error_handler
+ /* xgettext:c-format */
+ (_("warning: %pB uses r3/r4 for small structure returns, "
+ "%pB uses memory"), ibfd, obfd);
+ out_attr->type = ATTR_TYPE_FLAG_INT_VAL | ATTR_TYPE_FLAG_ERROR;
+ }
}
/* Merge Tag_compatibility attributes and any common GNU ones. */
- _bfd_elf_merge_object_attributes (ibfd, info);
-
- return TRUE;
+ return _bfd_elf_merge_object_attributes (ibfd, info);
}
/* Merge backend specific data from an object file to the output