This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Re: Add PowerPC .gnu_attribute for the vector ABI
- From: Daniel Jacobowitz <drow at false dot org>
- To: binutils at sourceware dot org
- Date: Thu, 25 Oct 2007 11:21:17 -0400
- Subject: Re: Add PowerPC .gnu_attribute for the vector ABI
- References: <20070807160011.GA5586@caradoc.them.org>
On Tue, Aug 07, 2007 at 12:00:11PM -0400, Daniel Jacobowitz wrote:
> This patch adds merging support for a .gnu_attribute which describes
> the vector ABI: "generic", AltiVec, SPE, or don't-care. I think this
> is the most sensible arrangement, since the AltiVec and SPE
> alternatives can not coexist.
> 2007-08-07 Daniel Jacobowitz <dan@codesourcery.com>
>
> * elf32-ppc.c (ppc_elf_merge_obj_attributes): Add support for
> Tag_GNU_Power_ABI_Vector.
>
> * readelf.c (display_power_gnu_attribute): Add support for
> Tag_GNU_Power_ABI_Vector.
>
> * ppc.h (Tag_GNU_Power_ABI_Vector): New.
>
> * ld-powerpc/attr-gnu-8-1.s, ld-powerpc/attr-gnu-8-11.d,
> ld-powerpc/attr-gnu-8-3.s, ld-powerpc/attr-gnu-8-31.d: New.
There were three problems with this patch. The first is that I didn't
add the tests to powerpc.exp, so they were never run. The second is
that they failed once run. The more serious problem is that the
vector ABI warning is not terribly useful.
In theory, it is no different from the FP warning. If no floating
point arguments are passed to library functions, the soft float ABI
is sufficiently compatible with the hard float ABI that everything
just works. More often this indicates an accident at link time
which selected the wrong libraries.
The vector ABI attribute marks two things: sufficient stack alignment
and the use of vector registers for arguments. My understanding when
I wrote the patch was that most PowerPC 32-bit targets did not have a
sufficiently aligned stack for AltiVec loads and stores; I was wrong.
powerpc-eabi does not, but powerpc-linux always does. And most
code does not take vector arguments. So using -mabi=altivec on
powerpc-linux systems is a sufficiently reasonable thing to do that
I shouldn't make ld scold people for it.
So I tested and committed this version instead, which is more forgiving.
--
Daniel Jacobowitz
CodeSourcery
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 Daniel Jacobowitz <dan@codesourcery.com>
* readelf.c (display_power_gnu_attribute): Add support for
Tag_GNU_Power_ABI_Vector.
2007-10-25 Daniel Jacobowitz <dan@codesourcery.com>
* ppc.h (Tag_GNU_Power_ABI_Vector): New.
2007-10-25 Daniel Jacobowitz <dan@codesourcery.com>
* ld-powerpc/attr-gnu-8-1.s, ld-powerpc/attr-gnu-8-11.d,
ld-powerpc/attr-gnu-8-2.s, ld-powerpc/attr-gnu-8-23.d,
ld-powerpc/attr-gnu-8-3.s, ld-powerpc/attr-gnu-8-31.d: New.
* ld-powerpc/powerpc.exp: Run new tests.
Index: bfd/elf32-ppc.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-ppc.c,v
retrieving revision 1.221
diff -u -p -r1.221 elf32-ppc.c
--- bfd/elf32-ppc.c 26 Sep 2007 13:45:32 -0000 1.221
+++ bfd/elf32-ppc.c 25 Oct 2007 15:15:36 -0000
@@ -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,
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)
- {
- 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)
+ 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->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. */
Index: binutils/readelf.c
===================================================================
RCS file: /cvs/src/src/binutils/readelf.c,v
retrieving revision 1.383
diff -u -p -r1.383 readelf.c
--- binutils/readelf.c 25 Oct 2007 00:41:16 -0000 1.383
+++ binutils/readelf.c 25 Oct 2007 15:15:36 -0000
@@ -8553,6 +8553,32 @@ display_power_gnu_attribute (unsigned ch
return p;
}
+ if (tag == Tag_GNU_Power_ABI_Vector)
+ {
+ val = read_uleb128 (p, &len);
+ p += len;
+ printf (" Tag_GNU_Power_ABI_Vector: ");
+ switch (val)
+ {
+ case 0:
+ printf ("Any\n");
+ break;
+ case 1:
+ printf ("Generic\n");
+ break;
+ case 2:
+ printf ("AltiVec\n");
+ break;
+ case 3:
+ printf ("SPE\n");
+ break;
+ default:
+ printf ("??? (%d)\n", val);
+ break;
+ }
+ return p;
+ }
+
if (tag & 1)
type = 1; /* String. */
else
Index: include/elf/ppc.h
===================================================================
RCS file: /cvs/src/src/include/elf/ppc.h,v
retrieving revision 1.19
diff -u -p -r1.19 ppc.h
--- include/elf/ppc.h 30 Jun 2007 00:03:40 -0000 1.19
+++ include/elf/ppc.h 25 Oct 2007 15:15:37 -0000
@@ -180,6 +180,11 @@ enum
soft-float; 0 for not tagged or not
using any ABIs affected by the
differences. */
+
+ /* Value 1 for general purpose registers only, 2 for AltiVec
+ registers, 3 for SPE registers; 0 for not tagged or not using any
+ ABIs affected by the differences. */
+ Tag_GNU_Power_ABI_Vector = 8,
};
#endif /* _ELF_PPC_H */
Index: ld/testsuite/ld-powerpc/attr-gnu-8-1.s
===================================================================
RCS file: ld/testsuite/ld-powerpc/attr-gnu-8-1.s
diff -N ld/testsuite/ld-powerpc/attr-gnu-8-1.s
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ ld/testsuite/ld-powerpc/attr-gnu-8-1.s 25 Oct 2007 15:15:37 -0000
@@ -0,0 +1 @@
+.gnu_attribute 8,1
Index: ld/testsuite/ld-powerpc/attr-gnu-8-11.d
===================================================================
RCS file: ld/testsuite/ld-powerpc/attr-gnu-8-11.d
diff -N ld/testsuite/ld-powerpc/attr-gnu-8-11.d
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ ld/testsuite/ld-powerpc/attr-gnu-8-11.d 25 Oct 2007 15:15:37 -0000
@@ -0,0 +1,10 @@
+#source: attr-gnu-8-1.s
+#source: attr-gnu-8-1.s
+#as: -a32
+#ld: -r -melf32ppc
+#readelf: -A
+#target: powerpc*-*-*
+
+Attribute Section: gnu
+File Attributes
+ Tag_GNU_Power_ABI_Vector: Generic
Index: ld/testsuite/ld-powerpc/attr-gnu-8-2.s
===================================================================
RCS file: ld/testsuite/ld-powerpc/attr-gnu-8-2.s
diff -N ld/testsuite/ld-powerpc/attr-gnu-8-2.s
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ ld/testsuite/ld-powerpc/attr-gnu-8-2.s 25 Oct 2007 15:15:37 -0000
@@ -0,0 +1 @@
+.gnu_attribute 8,2
Index: ld/testsuite/ld-powerpc/attr-gnu-8-23.d
===================================================================
RCS file: ld/testsuite/ld-powerpc/attr-gnu-8-23.d
diff -N ld/testsuite/ld-powerpc/attr-gnu-8-23.d
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ ld/testsuite/ld-powerpc/attr-gnu-8-23.d 25 Oct 2007 15:15:37 -0000
@@ -0,0 +1,6 @@
+#source: attr-gnu-8-2.s
+#source: attr-gnu-8-3.s
+#as: -a32
+#ld: -r -melf32ppc
+#warning: Warning: .* uses vector ABI "SPE", .* uses "AltiVec"
+#target: powerpc*-*-*
Index: ld/testsuite/ld-powerpc/attr-gnu-8-3.s
===================================================================
RCS file: ld/testsuite/ld-powerpc/attr-gnu-8-3.s
diff -N ld/testsuite/ld-powerpc/attr-gnu-8-3.s
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ ld/testsuite/ld-powerpc/attr-gnu-8-3.s 25 Oct 2007 15:15:37 -0000
@@ -0,0 +1 @@
+.gnu_attribute 8,3
Index: ld/testsuite/ld-powerpc/attr-gnu-8-31.d
===================================================================
RCS file: ld/testsuite/ld-powerpc/attr-gnu-8-31.d
diff -N ld/testsuite/ld-powerpc/attr-gnu-8-31.d
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ ld/testsuite/ld-powerpc/attr-gnu-8-31.d 25 Oct 2007 15:15:37 -0000
@@ -0,0 +1,10 @@
+#source: attr-gnu-8-3.s
+#source: attr-gnu-8-1.s
+#as: -a32
+#ld: -r -melf32ppc
+#readelf: -A
+#target: powerpc*-*-*
+
+Attribute Section: gnu
+File Attributes
+ Tag_GNU_Power_ABI_Vector: SPE
Index: ld/testsuite/ld-powerpc/powerpc.exp
===================================================================
RCS file: /cvs/src/src/ld/testsuite/ld-powerpc/powerpc.exp,v
retrieving revision 1.20
diff -u -p -r1.20 powerpc.exp
--- ld/testsuite/ld-powerpc/powerpc.exp 6 Jul 2007 14:09:45 -0000 1.20
+++ ld/testsuite/ld-powerpc/powerpc.exp 25 Oct 2007 15:15:37 -0000
@@ -165,3 +165,7 @@ run_dump_test "attr-gnu-4-20"
run_dump_test "attr-gnu-4-21"
run_dump_test "attr-gnu-4-22"
run_dump_test "attr-gnu-4-31"
+
+run_dump_test "attr-gnu-8-11"
+run_dump_test "attr-gnu-8-23"
+run_dump_test "attr-gnu-8-31"