aboutsummaryrefslogtreecommitdiff
path: root/bfd
diff options
context:
space:
mode:
Diffstat (limited to 'bfd')
-rw-r--r--bfd/ChangeLog5
-rw-r--r--bfd/elf32-ppc.c83
2 files changed, 72 insertions, 16 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 27f12d9..7034943 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,8 @@
+2007-10-25 Daniel Jacobowitz <dan@codesourcery.com>
+
+ * elf32-ppc.c (ppc_elf_merge_obj_attributes): Add support for
+ Tag_GNU_Power_ABI_Vector.
+
2007-10-25 Joseph Myers <joseph@codesourcery.com>
* elfxx-mips.c (_bfd_mips_elf_modify_segment_map): Do not add
diff --git a/bfd/elf32-ppc.c b/bfd/elf32-ppc.c
index 68804ad..a855440 100644
--- a/bfd/elf32-ppc.c
+++ b/bfd/elf32-ppc.c
@@ -3603,8 +3603,8 @@ ppc_elf_check_relocs (bfd *abfd,
static bfd_boolean
ppc_elf_merge_obj_attributes (bfd *ibfd, bfd *obfd)
{
- obj_attribute *in_attr;
- obj_attribute *out_attr;
+ obj_attribute *in_attr, *in_attrs;
+ obj_attribute *out_attr, *out_attrs;
if (!elf_known_obj_attributes_proc (obfd)[0].i)
{
@@ -3618,33 +3618,84 @@ ppc_elf_merge_obj_attributes (bfd *ibfd, bfd *obfd)
return TRUE;
}
+ in_attrs = elf_known_obj_attributes (ibfd)[OBJ_ATTR_GNU];
+ out_attrs = elf_known_obj_attributes (obfd)[OBJ_ATTR_GNU];
+
/* Check for conflicting Tag_GNU_Power_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_Power_ABI_FP].i != out_attr[Tag_GNU_Power_ABI_FP].i)
+ in_attr = &in_attrs[Tag_GNU_Power_ABI_FP];
+ out_attr = &out_attrs[Tag_GNU_Power_ABI_FP];
+ if (in_attr->i != out_attr->i)
{
- out_attr[Tag_GNU_Power_ABI_FP].type = 1;
- if (out_attr[Tag_GNU_Power_ABI_FP].i == 0)
- out_attr[Tag_GNU_Power_ABI_FP].i = in_attr[Tag_GNU_Power_ABI_FP].i;
- else if (in_attr[Tag_GNU_Power_ABI_FP].i == 0)
+ out_attr->type = 1;
+ if (out_attr->i == 0)
+ out_attr->i = in_attr->i;
+ else if (in_attr->i == 0)
;
- else if (out_attr[Tag_GNU_Power_ABI_FP].i == 1
- && in_attr[Tag_GNU_Power_ABI_FP].i == 2)
+ else if (out_attr->i == 1 && in_attr->i == 2)
_bfd_error_handler
(_("Warning: %B uses hard float, %B uses soft float"), obfd, ibfd);
- else if (out_attr[Tag_GNU_Power_ABI_FP].i == 2
- && in_attr[Tag_GNU_Power_ABI_FP].i == 1)
+ else if (out_attr->i == 2 && in_attr->i == 1)
_bfd_error_handler
(_("Warning: %B uses hard float, %B uses soft float"), ibfd, obfd);
- else if (in_attr[Tag_GNU_Power_ABI_FP].i > 2)
+ else if (in_attr->i > 2)
_bfd_error_handler
(_("Warning: %B uses unknown floating point ABI %d"), ibfd,
- in_attr[Tag_GNU_Power_ABI_FP].i);
+ in_attr->i);
else
_bfd_error_handler
(_("Warning: %B uses unknown floating point ABI %d"), obfd,
- out_attr[Tag_GNU_Power_ABI_FP].i);
+ out_attr->i);
+ }
+
+ /* Check for conflicting Tag_GNU_Power_ABI_Vector attributes and
+ merge non-conflicting ones. */
+ in_attr = &in_attrs[Tag_GNU_Power_ABI_Vector];
+ out_attr = &out_attrs[Tag_GNU_Power_ABI_Vector];
+ if (in_attr->i != out_attr->i)
+ {
+ const char *in_abi = NULL, *out_abi = NULL;
+
+ switch (in_attr->i)
+ {
+ case 1: in_abi = "generic"; break;
+ case 2: in_abi = "AltiVec"; break;
+ case 3: in_abi = "SPE"; break;
+ }
+
+ switch (out_attr->i)
+ {
+ case 1: out_abi = "generic"; break;
+ case 2: out_abi = "AltiVec"; break;
+ case 3: out_abi = "SPE"; break;
+ }
+
+ out_attr->type = 1;
+ if (out_attr->i == 0)
+ out_attr->i = in_attr->i;
+ else if (in_attr->i == 0)
+ ;
+ /* For now, allow generic to transition to AltiVec or SPE
+ without a warning. If GCC marked files with their stack
+ alignment and used don't-care markings for files which are
+ not affected by the vector ABI, we could warn about this
+ case too. */
+ else if (out_attr->i == 1)
+ out_attr->i = in_attr->i;
+ else if (in_attr->i == 1)
+ ;
+ else if (in_abi == NULL)
+ _bfd_error_handler
+ (_("Warning: %B uses unknown vector ABI %d"), ibfd,
+ in_attr->i);
+ else if (out_abi == NULL)
+ _bfd_error_handler
+ (_("Warning: %B uses unknown vector ABI %d"), obfd,
+ in_attr->i);
+ else
+ _bfd_error_handler
+ (_("Warning: %B uses vector ABI \"%s\", %B uses \"%s\""),
+ ibfd, obfd, in_abi, out_abi);
}
/* Merge Tag_compatibility attributes and any common GNU ones. */