This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
RE: [PATCH, ARM 4/7] Add support for linking ARMv8-M object files
- From: "Thomas Preud'homme" <thomas dot preudhomme at foss dot arm dot com>
- To: "Richard Earnshaw" <Richard dot Earnshaw at arm dot com>, <binutils at sourceware dot org>
- Date: Wed, 23 Dec 2015 15:02:15 +0800
- Subject: RE: [PATCH, ARM 4/7] Add support for linking ARMv8-M object files
- Authentication-results: sourceware.org; auth=none
- References: <001d01d13873$10d9aab0$328d0010$ at foss dot arm dot com> <56741D1E dot 50203 at arm dot com>
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