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]

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


Hi,

This patch is part of a patch series to add support for ARMv8-M[1] to binutils. This specific patch changes the linker to recognize ARMv8-M as being Thumb-only and to teach it how to merge ARMv8-M object files.

[1] For a quick overview of ARMv8-M please refer to the initial cover letter.


The biggest aspect of the patch is how to deal with merging ARM attributes when one of the input file is using the ARMv8-M architecture. Code for merging Tag_CPU_arch attribute is thus updated with to follow the following rule:

* the result is 16 (ARMv8-M Baseline) if input and output use Thumb-1
* the result is 17 (ARMv8-M Mainline) if input and output use Thumb-2
* the result is 17 (ARMv8-M Mainline) if input and output are ARMv8-M


ChangeLog entries are as follow:


*** bfd/ChangeLog ***

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

        * elf32-arm.c (using_thumb_only): Only check that profile is 'M'.
        (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 49dfc5338e45fd1df518cc8781e918444dc1831e..b10a3430e2d0cd5ad22f136aa5f706506a40759e 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';
 }
@@ -12186,6 +12176,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.  */
@@ -12203,7 +12234,9 @@ tag_cpu_arch_combine (bfd *ibfd, int oldtag, int *secondary_compat_out,
       T(V6S_M),		/* V6S_M.  */
       T(V7E_M),		/* V7E_M.  */
       T(V8),		/* V8.  */
-      T(V4T_PLUS_V6_M)	/* V4T plus V6_M.  */
+      T(V4T_PLUS_V6_M),	/* V4T plus V6_M.  */
+      -1,		/* V8-M BASELINE.  */
+      -1		/* V8-M MAINLINE.  */
     };
   const int *comb[] =
     {
@@ -12214,8 +12247,9 @@ tag_cpu_arch_combine (bfd *ibfd, int oldtag, int *secondary_compat_out,
       v6s_m,
       v7e_m,
       v8,
-      /* Pseudo-architecture.  */
-      v4t_plus_v6_m
+      v4t_plus_v6_m, /* Pseudo-architecture.  */
+      v8m_baseline,
+      v8m_mainline,
     };
 
   /* Check we've not got a higher architecture than we know about.  */
@@ -12429,7 +12463,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 1d9b1c83f4b8f961d0397672ccca705d016e3e52..14b74030fbf2994785e305ab01531f538276f41e 100644
--- a/ld/testsuite/ld-arm/arm-elf.exp
+++ b/ld/testsuite/ld-arm/arm-elf.exp
@@ -370,6 +370,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"}
@@ -433,6 +442,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'


Tests done:

* No regression under binutils testsuite *except for Tag_CPU_name for new ARMv8-M testcases*
* Toolchain was built successfully with and without the ARMv8-M support patches[2] with the following multilib list: armv6-m,armv7-m,armv7e-m,cortex-m7,armv8-m.base,armv8-m.main. The code generation for crtbegin.o, crtend.o, crti.o, crtn.o, libgcc.a, libgcov.a, libc.a, libg.a, libgloss-linux.a, libm.a, libnosys.a, librdimon.a, librdpmon.a, libstdc++.a and libsupc++.a is unchanged for all targets supported before the patches.
* Thumb-1 (default arch and --with-mode=thumb) and Thumb-2 (--with-arch=armv7-a --with-mode=thumb) GCC bootstrap using binutils with this patch
* No GCC testsuite regression on fast model compared to ARMv6s-M (Baseline) or ARMv7-M (Mainline)

[2] including this one, the ld one and the GCC one


Is this ok for the master branch?

Best regards,

Thomas


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