This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

RE: [PATCH, ARM 4/7] Add support for linking ARMv8-M object files


Hi Richard,

> From: binutils-owner@sourceware.org [mailto:binutils-
> owner@sourceware.org] On Behalf Of Richard Earnshaw (lists)
> Sent: Friday, December 18, 2015 10:50 PM
> 
> >
> >
> > diff --git a/bfd/elf32-arm.c b/bfd/elf32-arm.c
> > index
> 49dfc5338e45fd1df518cc8781e918444dc1831e..b10a3430e2d0cd5ad22f13
> 6aa5f706506a40759e 100644
> > --- a/bfd/elf32-arm.c
> > +++ b/bfd/elf32-arm.c
> > @@ -3445,18 +3445,8 @@ create_ifunc_sections (struct bfd_link_info
> *info)
> >  static bfd_boolean
> >  using_thumb_only (struct elf32_arm_link_hash_table *globals)
> >  {
> > -  int arch = bfd_elf_get_obj_attr_int (globals->obfd, OBJ_ATTR_PROC,
> > -				       Tag_CPU_arch);
> > -  int profile;
> > -
> > -  if (arch == TAG_CPU_ARCH_V6_M || arch ==
> TAG_CPU_ARCH_V6S_M)
> > -    return TRUE;
> > -
> > -  if (arch != TAG_CPU_ARCH_V7 && arch != TAG_CPU_ARCH_V7E_M)
> > -    return FALSE;
> > -
> > -  profile = bfd_elf_get_obj_attr_int (globals->obfd, OBJ_ATTR_PROC,
> > -				      Tag_CPU_arch_profile);
> > +  int profile = bfd_elf_get_obj_attr_int (globals->obfd,
> OBJ_ATTR_PROC,
> > +					  Tag_CPU_arch_profile);
> >
> >    return profile == 'M';
> >  }
> 
> 
> I don't think it's completely mandatory that when an Arch tag specifies
> an M-profile architecture that setting the profile tag is also required
>  (don't forget that we may be processing object files produced by other
> toolchains so we have to be as liberal as we can be in terms of what we
> accept).  So the following two test files are probably legal, although
> not standard with the GNU tools.

You're absolutely right. Be liberal in what you accept, and strict in what you produce.

> 
> t1.s:
> 	.eabi_attribute	Tag_CPU_arch, 11	@ V6-M
> 	.thumb
> 	.type _start, function
> 	.global _start
> 	.text
> _start:
> 	bl	myfunc
> 	b	.
> 
> t2.s:
> 	.eabi_attribute	Tag_CPU_arch, 11	@ V6-M
> 	.thumb
> 	.type myfunc, function
> 	.global myfunc
> 	.text
> 	.space 102400000
> myfunc:
> 	bx	lr
> 
> Now, if I link these together, I expect the linker to generate a veneer
> which is compatible with execution on ARMv6-M devices.  With the
> current
> linker I get that behaviour:
> 
> 00008000 <_start>:
>     8000:       f000 f802       bl      8008 <__myfunc_veneer>
>     8004:       e7fe            b.n     8004 <_start+0x4>
>         ...
> 
> 00008008 <__myfunc_veneer>:
>     8008:       b401            push    {r0}
>     800a:       4802            ldr     r0, [pc, #8]    ; (8014
> <__myfunc_veneer+0xc>)
>     800c:       4684            mov     ip, r0
>     800e:       bc01            pop     {r0}
>     8010:       4760            bx      ip
>     8012:       bf00            nop
>     8014:       061b0019        .word   0x061b0019
>         ...
> 
> 00080000 <_stack>:
>         ...
> 
> 061b0018 <myfunc>:
>  61b0018:       4770            bx      lr
> 
> However, when I apply your patch I then get the tools creating veneers
> that use instructions that do not exist on M-profile devices:
> 
> 00008000 <_start>:
>     8000:       f000 e802       blx     8008 <__myfunc_veneer>
>     8004:       e7fe            b.n     8004 <_start+0x4>
>         ...
> 
> 00008008 <__myfunc_veneer>:
>     8008:       e51ff004        ldr     pc, [pc, #-4]   ; 800c
> <__myfunc_veneer+0x4>
>     800c:       061b0011        .word   0x061b0011
>         ...
> 
> 00080000 <_stack>:
>         ...
> 
> 061b0010 <myfunc>:
>  61b0010:       4770            bx      lr
> 
> which is clearly not what we want.
> 
> If you're going to continue to examine the build attributes directly
> rather than internalising them and canonicalizing the set of attributes
> into a consistent internal description of the machine capabilities, then
> I think you need to continue to explicitly check the architecture tags
> as well here.

This is fixed in this updated patch. I reworked the logic a tad to look at profile first and use that if available, otherwise fallback on arch information. Here are the updated ChangeLog entries and patch:

*** bfd/ChangeLog ***

2015-12-22  Thomas Preud'homme  <thomas.preudhomme@arm.com>

        * elf32-arm.c (using_thumb_only): Check that profile is 'M' and update
        logic around Tag_CPU_arch values to return TRUE for ARMv8-M
        architectures.
        (tag_cpu_arch_combine): Define v8m_baseline and v8m_mainline and update
        v4t_plus_v6_m and comb to deal with ARMv8-M Tag_CPU_arch merging logic.
        (elf32_arm_merge_eabi_attributes): Add Tag_CPU_name values for
        ARMv8-M.


*** bfd/testsuite/ChangeLog ***

2015-12-14  Thomas Preud'homme  <thomas.preudhomme@arm.com>

        * ld-arm/arm-elf.exp (armeabitests_common): Run new tests 
        "Thumb-Thumb farcall v8-M", "EABI attribute merging 8",
        "EABI attribute merging 9" and "EABI attribute merging 10".
        (Thumb-Thumb farcall v8-M): Renamed to ...
        (Thumb-Thumb farcall v8-M Mainline): This.
        (Thumb-Thumb farcall v8-M Baseline): New test. 
        * ld-arm/attr-merge-8a.s: New file.
        * ld-arm/attr-merge-8b.s: Likewise.
        * ld-arm/attr-merge-8.attr: Likewise.
        * ld-arm/attr-merge-9a.s: Likewise.
        * ld-arm/attr-merge-9b.s: Likewise.
        * ld-arm/attr-merge-9.out: Likewise.
        * ld-arm/attr-merge-10a.s: Likewise.
        * ld-arm/attr-merge-10b.s: Likewise.
        * ld-arm/attr-merge-10.attr: Likewise.


diff --git a/bfd/elf32-arm.c b/bfd/elf32-arm.c
index 35177e653bf26e18ff7d147124fee9a2e12b9888..63ff49f57bda6d5656ce39eaa67801870916f861 100644
--- a/bfd/elf32-arm.c
+++ b/bfd/elf32-arm.c
@@ -3503,20 +3503,23 @@ create_ifunc_sections (struct bfd_link_info *info)
 static bfd_boolean
 using_thumb_only (struct elf32_arm_link_hash_table *globals)
 {
-  int arch = bfd_elf_get_obj_attr_int (globals->obfd, OBJ_ATTR_PROC,
-				       Tag_CPU_arch);
-  int profile;
+  int arch;
+  int profile = bfd_elf_get_obj_attr_int (globals->obfd, OBJ_ATTR_PROC,
+					  Tag_CPU_arch_profile);
 
-  if (arch == TAG_CPU_ARCH_V6_M || arch == TAG_CPU_ARCH_V6S_M)
-    return TRUE;
+  if (profile)
+    return profile == 'M';
 
-  if (arch != TAG_CPU_ARCH_V7 && arch != TAG_CPU_ARCH_V7E_M)
-    return FALSE;
+  arch = bfd_elf_get_obj_attr_int (globals->obfd, OBJ_ATTR_PROC, Tag_CPU_arch);
 
-  profile = bfd_elf_get_obj_attr_int (globals->obfd, OBJ_ATTR_PROC,
-				      Tag_CPU_arch_profile);
+  if (arch == TAG_CPU_ARCH_V6_M
+      || arch == TAG_CPU_ARCH_V6S_M
+      || arch == TAG_CPU_ARCH_V7E_M
+      || arch == TAG_CPU_ARCH_V8M_BASE
+      || arch == TAG_CPU_ARCH_V8M_MAIN)
+    return TRUE;
 
-  return profile == 'M';
+  return FALSE;
 }
 
 /* Determine if we're dealing with a Thumb-2 object.  */
@@ -12271,6 +12274,47 @@ tag_cpu_arch_combine (bfd *ibfd, int oldtag, int *secondary_compat_out,
       T(V8),		/* V7E_M.  */
       T(V8)		/* V8.  */
     };
+  const int v8m_baseline[] =
+    {
+      -1,		/* PRE_V4.  */
+      -1,		/* V4.  */
+      -1,		/* V4T.  */
+      -1,		/* V5T.  */
+      -1,		/* V5TE.  */
+      -1,		/* V5TEJ.  */
+      -1,		/* V6.  */
+      -1,		/* V6KZ.  */
+      -1,		/* V6T2.  */
+      -1,		/* V6K.  */
+      -1,		/* V7.  */
+      T(V8M_BASE),	/* V6_M.  */
+      T(V8M_BASE),	/* V6S_M.  */
+      -1,		/* V7E_M.  */
+      -1,		/* V8.  */
+      -1,
+      T(V8M_BASE)	/* V8-M BASELINE.  */
+    };
+  const int v8m_mainline[] =
+    {
+      -1,		/* PRE_V4.  */
+      -1,		/* V4.  */
+      -1,		/* V4T.  */
+      -1,		/* V5T.  */
+      -1,		/* V5TE.  */
+      -1,		/* V5TEJ.  */
+      -1,		/* V6.  */
+      -1,		/* V6KZ.  */
+      -1,		/* V6T2.  */
+      -1,		/* V6K.  */
+      T(V8M_MAIN),	/* V7.  */
+      T(V8M_MAIN),	/* V6_M.  */
+      T(V8M_MAIN),	/* V6S_M.  */
+      T(V8M_MAIN),	/* V7E_M.  */
+      -1,		/* V8.  */
+      -1,
+      T(V8M_MAIN),	/* V8-M BASELINE.  */
+      T(V8M_MAIN)	/* V8-M MAINLINE.  */
+    };
   const int v4t_plus_v6_m[] =
     {
       -1,		/* PRE_V4.  */
@@ -12289,8 +12333,8 @@ tag_cpu_arch_combine (bfd *ibfd, int oldtag, int *secondary_compat_out,
       T(V7E_M),		/* V7E_M.  */
       T(V8),		/* V8.  */
       -1,		/* Unused.  */
-      -1,		/* V8-M BASELINE.  */
-      -1,		/* V8-M MAINLINE.  */
+      T(V8M_BASE),	/* V8-M BASELINE.  */
+      T(V8M_MAIN),	/* V8-M MAINLINE.  */
       T(V4T_PLUS_V6_M)	/* V4T plus V6_M.  */
     };
   const int *comb[] =
@@ -12303,8 +12347,8 @@ tag_cpu_arch_combine (bfd *ibfd, int oldtag, int *secondary_compat_out,
       v7e_m,
       v8,
       NULL,
-      NULL,
-      NULL,
+      v8m_baseline,
+      v8m_mainline,
       /* Pseudo-architecture.  */
       v4t_plus_v6_m
     };
@@ -12520,7 +12564,10 @@ elf32_arm_merge_eabi_attributes (bfd *ibfd, bfd *obfd)
 		"ARM v7",
 		"ARM v6-M",
 		"ARM v6S-M",
-		"ARM v8"
+		"ARM v8",
+		"",
+		"ARM v8-M.baseline",
+		"ARM v8-M.mainline",
 	    };
 
 	    /* Merge Tag_CPU_arch and Tag_also_compatible_with.  */
diff --git a/ld/testsuite/ld-arm/arm-elf.exp b/ld/testsuite/ld-arm/arm-elf.exp
index 23c9e57e48c61a8de0fcae6ffaad7061bc674bf9..20b9456eeffdf1ce1ec27cb0b31cc6f07d60abad 100644
--- a/ld/testsuite/ld-arm/arm-elf.exp
+++ b/ld/testsuite/ld-arm/arm-elf.exp
@@ -376,6 +376,15 @@ set armeabitests_common {
      {"EABI attribute merging 7" "-r" "" "" {attr-merge-7a.s attr-merge-7b.s}
       {{readelf -A attr-merge-7.attr}}
       "attr-merge-7"}
+     {"EABI attribute merging 8" "-r" "" "" {attr-merge-8a.s attr-merge-8b.s}
+      {{readelf -A attr-merge-8.attr}}
+      "attr-merge-8"}
+     {"EABI attribute merging 9" "-r" "" "" {attr-merge-9a.s attr-merge-9b.s}
+      {{ld attr-merge-9.out}}
+      "attr-merge-9"}
+     {"EABI attribute merging 10" "-r" "" "" {attr-merge-10a.s attr-merge-10b.s}
+      {{readelf -A attr-merge-10.attr}}
+      "attr-merge-10"}
      {"EABI attribute arch merging 1" "-r" "" "" {arch-v6k.s arch-v6t2.s}
       {{readelf -A attr-merge-arch-1.attr}}
       "attr-merge-arch-1"}
@@ -439,6 +448,12 @@ set armeabitests_nonacl {
     {"Thumb-Thumb farcall M profile" "-Ttext 0x1000 --section-start .foo=0x2001014" "" "-march=armv7-m" {farcall-thumb-thumb.s}
      {{objdump -d farcall-thumb-thumb-m.d}}
      "farcall-thumb-thumb-m"}
+    {"Thumb-Thumb farcall v8-M Baseline" "-Ttext 0x1000 --section-start .foo=0x2001014" "" "-march=armv8-m.base" {farcall-thumb-thumb.s}
+     {{objdump -d farcall-thumb-thumb-m.d}}
+     "farcall-thumb-thumb-v8-m-base"}
+    {"Thumb-Thumb farcall v8-M Mainline" "-Ttext 0x1000 --section-start .foo=0x2001014" "" "-march=armv8-m.main" {farcall-thumb-thumb.s}
+     {{objdump -d farcall-thumb-thumb-m.d}}
+     "farcall-thumb-thumb-v8-m-main"}
     {"Thumb-Thumb farcall v6-M" "-Ttext 0x1000 --section-start .foo=0x2001014" "" "-march=armv6-m" {farcall-thumb-thumb.s}
      {{objdump -d farcall-thumb-thumb-m.d}}
      "farcall-thumb-thumb-v6-m"}
diff --git a/ld/testsuite/ld-arm/attr-merge-10.attr b/ld/testsuite/ld-arm/attr-merge-10.attr
new file mode 100644
index 0000000000000000000000000000000000000000..3d4e82cdfd105ffbf3d282d34922e998db5dffbf
--- /dev/null
+++ b/ld/testsuite/ld-arm/attr-merge-10.attr
@@ -0,0 +1,6 @@
+Attribute Section: aeabi
+File Attributes
+  Tag_CPU_name: "8-M.MAIN"
+  Tag_CPU_arch: v8-M.mainline
+  Tag_CPU_arch_profile: Microcontroller
+  Tag_THUMB_ISA_use: Yes
diff --git a/ld/testsuite/ld-arm/attr-merge-10a.s b/ld/testsuite/ld-arm/attr-merge-10a.s
new file mode 100644
index 0000000000000000000000000000000000000000..faff6bdd379aceeee60aef05c42eeb577757aa91
--- /dev/null
+++ b/ld/testsuite/ld-arm/attr-merge-10a.s
@@ -0,0 +1,5 @@
+	.arch armv8-m.base
+
+	@ Tag_CPU_arch & Tag_CPU_arch_profile = v8-M.BASE
+	.eabi_attribute Tag_CPU_arch, 16
+	.eabi_attribute Tag_CPU_arch_profile, 'M'
diff --git a/ld/testsuite/ld-arm/attr-merge-10b.s b/ld/testsuite/ld-arm/attr-merge-10b.s
new file mode 100644
index 0000000000000000000000000000000000000000..68625d3d7f0a8c54c4cc234b1f453367903b5d3b
--- /dev/null
+++ b/ld/testsuite/ld-arm/attr-merge-10b.s
@@ -0,0 +1,5 @@
+	.arch armv8-m.main
+
+	@ Tag_CPU_arch & Tag_CPU_arch_profile = v8-M.MAIN
+	.eabi_attribute Tag_CPU_arch, 17
+	.eabi_attribute Tag_CPU_arch_profile, 'M'
diff --git a/ld/testsuite/ld-arm/attr-merge-8.attr b/ld/testsuite/ld-arm/attr-merge-8.attr
new file mode 100644
index 0000000000000000000000000000000000000000..7f922ac6cff48134e9cb177c74e71bc8cd041831
--- /dev/null
+++ b/ld/testsuite/ld-arm/attr-merge-8.attr
@@ -0,0 +1,6 @@
+Attribute Section: aeabi
+File Attributes
+  Tag_CPU_name: "8-M.BASE"
+  Tag_CPU_arch: v8-M.baseline
+  Tag_CPU_arch_profile: Microcontroller
+  Tag_THUMB_ISA_use: Yes
diff --git a/ld/testsuite/ld-arm/attr-merge-8a.s b/ld/testsuite/ld-arm/attr-merge-8a.s
new file mode 100644
index 0000000000000000000000000000000000000000..fc5ea8b39220507a4f2332ed7f7ea3b156943fe3
--- /dev/null
+++ b/ld/testsuite/ld-arm/attr-merge-8a.s
@@ -0,0 +1,5 @@
+	.arch armv6-m
+
+	@ Tag_CPU_arch & Tag_CPU_arch_profile = v6-M
+	.eabi_attribute Tag_CPU_arch, 11
+	.eabi_attribute Tag_CPU_arch_profile, 'M'
diff --git a/ld/testsuite/ld-arm/attr-merge-8b.s b/ld/testsuite/ld-arm/attr-merge-8b.s
new file mode 100644
index 0000000000000000000000000000000000000000..8ee553a988de9a92da690cad7eca1ad01fef37a0
--- /dev/null
+++ b/ld/testsuite/ld-arm/attr-merge-8b.s
@@ -0,0 +1,5 @@
+	.arch armv8-m.base
+
+	@ Tag_CPU_arch & Tag_CPU_arch_profile = v8-M Baseline
+	.eabi_attribute Tag_CPU_arch, 16
+	.eabi_attribute Tag_CPU_arch_profile, 'M'
diff --git a/ld/testsuite/ld-arm/attr-merge-9.out b/ld/testsuite/ld-arm/attr-merge-9.out
new file mode 100644
index 0000000000000000000000000000000000000000..bb09181f6c02f55c11224cddac308085106919ca
--- /dev/null
+++ b/ld/testsuite/ld-arm/attr-merge-9.out
@@ -0,0 +1,2 @@
+.*: error: .*: Conflicting CPU architectures 10/16
+.*: failed to merge target specific data of file tmpdir/attr-merge-9b.o
diff --git a/ld/testsuite/ld-arm/attr-merge-9a.s b/ld/testsuite/ld-arm/attr-merge-9a.s
new file mode 100644
index 0000000000000000000000000000000000000000..0e24017d118a89c1f215ff17a55d4b5b05e2b628
--- /dev/null
+++ b/ld/testsuite/ld-arm/attr-merge-9a.s
@@ -0,0 +1,5 @@
+	.arch armv7-m
+
+	@ Tag_CPU_arch & Tag_CPU_arch_profile = v7-M
+	.eabi_attribute Tag_CPU_arch, 10
+	.eabi_attribute Tag_CPU_arch_profile, 'M'
diff --git a/ld/testsuite/ld-arm/attr-merge-9b.s b/ld/testsuite/ld-arm/attr-merge-9b.s
new file mode 100644
index 0000000000000000000000000000000000000000..8ee553a988de9a92da690cad7eca1ad01fef37a0
--- /dev/null
+++ b/ld/testsuite/ld-arm/attr-merge-9b.s
@@ -0,0 +1,5 @@
+	.arch armv8-m.base
+
+	@ Tag_CPU_arch & Tag_CPU_arch_profile = v8-M Baseline
+	.eabi_attribute Tag_CPU_arch, 16
+	.eabi_attribute Tag_CPU_arch_profile, 'M'


Best regards,

Thomas


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]