[v6,02/14] aarch64: configure test for BTI support

Message ID c6ec76c5fbd776e0427558a245b462a342ea4734.1593612309.git.szabolcs.nagy@arm.com
State Committed
Commit 1b0a4f58f5b10cf6d5ad10ee8d81772c5bd29248
Headers
Series aarch64: branch protection support |

Commit Message

Szabolcs Nagy July 1, 2020, 2:38 p.m. UTC
  Check BTI support in the compiler and linker.  The check also
requires READELF that understands the BTI GNU property note.
It is expected to succeed with gcc >=gcc-9 configured with
--enable-standard-branch-protection and binutils >=binutils-2.33.

Note: passing -mbranch-protection=bti in CFLAGS when building glibc
may not be enough to get a glibc that supports BTI because crtbegin*
and crtend* provided by the compiler needs to be BTI compatible too.
---
 config.h.in                  |  3 +++
 sysdeps/aarch64/configure    | 42 ++++++++++++++++++++++++++++++++++++
 sysdeps/aarch64/configure.ac | 19 ++++++++++++++++
 3 files changed, 64 insertions(+)
  

Comments

Adhemerval Zanella July 6, 2020, 2:11 p.m. UTC | #1
On 01/07/2020 11:38, Szabolcs Nagy wrote:
> Check BTI support in the compiler and linker.  The check also
> requires READELF that understands the BTI GNU property note.
> It is expected to succeed with gcc >=gcc-9 configured with
> --enable-standard-branch-protection and binutils >=binutils-2.33.
> 
> Note: passing -mbranch-protection=bti in CFLAGS when building glibc
> may not be enough to get a glibc that supports BTI because crtbegin*
> and crtend* provided by the compiler needs to be BTI compatible too.

If I read correctly this scenario should be covered by the configure
test, right?

LGTM, thanks.

Reviewed-by: Adhemerval Zanella  <adhemerval.zanella@linaro.org>

> ---
>  config.h.in                  |  3 +++
>  sysdeps/aarch64/configure    | 42 ++++++++++++++++++++++++++++++++++++
>  sysdeps/aarch64/configure.ac | 19 ++++++++++++++++
>  3 files changed, 64 insertions(+)
> 
> diff --git a/config.h.in b/config.h.in
> index 831eca2fe1..67169e5d01 100644
> --- a/config.h.in
> +++ b/config.h.in
> @@ -109,6 +109,9 @@
>  /* AArch64 big endian ABI */
>  #undef HAVE_AARCH64_BE
>  
> +/* AArch64 BTI support enabled.  */
> +#define HAVE_AARCH64_BTI 0
> +
>  /* C-SKY ABI version.  */
>  #undef CSKYABI
>  

Ok.

> diff --git a/sysdeps/aarch64/configure b/sysdeps/aarch64/configure
> index 5bd355a691..70477a7fa5 100644
> --- a/sysdeps/aarch64/configure
> +++ b/sysdeps/aarch64/configure
> @@ -172,3 +172,45 @@ else
>    config_vars="$config_vars
>  default-abi = lp64"
>  fi
> +
> +# Only consider BTI supported if -mbranch-protection=bti is
> +# on by default in the compiler and the linker produces
> +# binaries with GNU property notes in PT_GNU_PROPERTY segment.
> +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for BTI support" >&5
> +$as_echo_n "checking for BTI support... " >&6; }
> +if ${libc_cv_aarch64_bti+:} false; then :
> +  $as_echo_n "(cached) " >&6
> +else
> +    cat > conftest.c <<EOF
> +void foo (void) { }
> +EOF
> +  libc_cv_aarch64_bti=no
> +  if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS -nostdlib -nostartfiles $no_ssp -shared -fPIC -o conftest.so conftest.c'
> +  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
> +  (eval $ac_try) 2>&5
> +  ac_status=$?
> +  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
> +  test $ac_status = 0; }; } \
> +     && { ac_try='$READELF -lW conftest.so | grep -q GNU_PROPERTY'
> +  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
> +  (eval $ac_try) 2>&5
> +  ac_status=$?
> +  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
> +  test $ac_status = 0; }; } \
> +     && { ac_try='$READELF -nW conftest.so | grep -q "NT_GNU_PROPERTY_TYPE_0.*AArch64 feature:.* BTI"'
> +  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
> +  (eval $ac_try) 2>&5
> +  ac_status=$?
> +  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
> +  test $ac_status = 0; }; }
> +  then
> +    libc_cv_aarch64_bti=yes
> +  fi
> +  rm -rf conftest.*
> +fi
> +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_aarch64_bti" >&5
> +$as_echo "$libc_cv_aarch64_bti" >&6; }
> +if test $libc_cv_aarch64_bti = yes; then
> +  $as_echo "#define HAVE_AARCH64_BTI 1" >>confdefs.h
> +
> +fi
> diff --git a/sysdeps/aarch64/configure.ac b/sysdeps/aarch64/configure.ac
> index 7851dd4dac..798f494740 100644
> --- a/sysdeps/aarch64/configure.ac
> +++ b/sysdeps/aarch64/configure.ac
> @@ -20,3 +20,22 @@ if test $libc_cv_aarch64_be = yes; then
>  else
>    LIBC_CONFIG_VAR([default-abi], [lp64])
>  fi
> +
> +# Only consider BTI supported if -mbranch-protection=bti is
> +# on by default in the compiler and the linker produces
> +# binaries with GNU property notes in PT_GNU_PROPERTY segment.
> +AC_CACHE_CHECK([for BTI support], [libc_cv_aarch64_bti], [dnl
> +  cat > conftest.c <<EOF
> +void foo (void) { }
> +EOF
> +  libc_cv_aarch64_bti=no
> +  if AC_TRY_COMMAND([${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS -nostdlib -nostartfiles $no_ssp -shared -fPIC -o conftest.so conftest.c]) \
> +     && AC_TRY_COMMAND([$READELF -lW conftest.so | grep -q GNU_PROPERTY]) \
> +     && AC_TRY_COMMAND([$READELF -nW conftest.so | grep -q "NT_GNU_PROPERTY_TYPE_0.*AArch64 feature:.* BTI"])
> +  then
> +    libc_cv_aarch64_bti=yes
> +  fi
> +  rm -rf conftest.*])
> +if test $libc_cv_aarch64_bti = yes; then
> +  AC_DEFINE(HAVE_AARCH64_BTI)
> +fi
> 

Ok.
  
Szabolcs Nagy July 6, 2020, 6:07 p.m. UTC | #2
The 07/06/2020 11:11, Adhemerval Zanella via Libc-alpha wrote:
> 
> 
> On 01/07/2020 11:38, Szabolcs Nagy wrote:
> > Check BTI support in the compiler and linker.  The check also
> > requires READELF that understands the BTI GNU property note.
> > It is expected to succeed with gcc >=gcc-9 configured with
> > --enable-standard-branch-protection and binutils >=binutils-2.33.
> > 
> > Note: passing -mbranch-protection=bti in CFLAGS when building glibc
> > may not be enough to get a glibc that supports BTI because crtbegin*
> > and crtend* provided by the compiler needs to be BTI compatible too.
> 
> If I read correctly this scenario should be covered by the configure
> test, right?

it is not covered because the config checks use -nostdlib
and -nostartfiles (otherwise objects from the libc that
the toolchain uses would leak into the checks).

so if gcc startfiles are not bti compatible then configure
succeeds (but later on there will be link failures so the
build fails).

> 
> LGTM, thanks.
> 
> Reviewed-by: Adhemerval Zanella  <adhemerval.zanella@linaro.org>
> 
> > ---
> >  config.h.in                  |  3 +++
> >  sysdeps/aarch64/configure    | 42 ++++++++++++++++++++++++++++++++++++
> >  sysdeps/aarch64/configure.ac | 19 ++++++++++++++++
> >  3 files changed, 64 insertions(+)
> > 
> > diff --git a/config.h.in b/config.h.in
> > index 831eca2fe1..67169e5d01 100644
> > --- a/config.h.in
> > +++ b/config.h.in
> > @@ -109,6 +109,9 @@
> >  /* AArch64 big endian ABI */
> >  #undef HAVE_AARCH64_BE
> >  
> > +/* AArch64 BTI support enabled.  */
> > +#define HAVE_AARCH64_BTI 0
> > +
> >  /* C-SKY ABI version.  */
> >  #undef CSKYABI
> >  
> 
> Ok.
> 
> > diff --git a/sysdeps/aarch64/configure b/sysdeps/aarch64/configure
> > index 5bd355a691..70477a7fa5 100644
> > --- a/sysdeps/aarch64/configure
> > +++ b/sysdeps/aarch64/configure
> > @@ -172,3 +172,45 @@ else
> >    config_vars="$config_vars
> >  default-abi = lp64"
> >  fi
> > +
> > +# Only consider BTI supported if -mbranch-protection=bti is
> > +# on by default in the compiler and the linker produces
> > +# binaries with GNU property notes in PT_GNU_PROPERTY segment.
> > +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for BTI support" >&5
> > +$as_echo_n "checking for BTI support... " >&6; }
> > +if ${libc_cv_aarch64_bti+:} false; then :
> > +  $as_echo_n "(cached) " >&6
> > +else
> > +    cat > conftest.c <<EOF
> > +void foo (void) { }
> > +EOF
> > +  libc_cv_aarch64_bti=no
> > +  if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS -nostdlib -nostartfiles $no_ssp -shared -fPIC -o conftest.so conftest.c'
> > +  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
> > +  (eval $ac_try) 2>&5
> > +  ac_status=$?
> > +  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
> > +  test $ac_status = 0; }; } \
> > +     && { ac_try='$READELF -lW conftest.so | grep -q GNU_PROPERTY'
> > +  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
> > +  (eval $ac_try) 2>&5
> > +  ac_status=$?
> > +  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
> > +  test $ac_status = 0; }; } \
> > +     && { ac_try='$READELF -nW conftest.so | grep -q "NT_GNU_PROPERTY_TYPE_0.*AArch64 feature:.* BTI"'
> > +  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
> > +  (eval $ac_try) 2>&5
> > +  ac_status=$?
> > +  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
> > +  test $ac_status = 0; }; }
> > +  then
> > +    libc_cv_aarch64_bti=yes
> > +  fi
> > +  rm -rf conftest.*
> > +fi
> > +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_aarch64_bti" >&5
> > +$as_echo "$libc_cv_aarch64_bti" >&6; }
> > +if test $libc_cv_aarch64_bti = yes; then
> > +  $as_echo "#define HAVE_AARCH64_BTI 1" >>confdefs.h
> > +
> > +fi
> > diff --git a/sysdeps/aarch64/configure.ac b/sysdeps/aarch64/configure.ac
> > index 7851dd4dac..798f494740 100644
> > --- a/sysdeps/aarch64/configure.ac
> > +++ b/sysdeps/aarch64/configure.ac
> > @@ -20,3 +20,22 @@ if test $libc_cv_aarch64_be = yes; then
> >  else
> >    LIBC_CONFIG_VAR([default-abi], [lp64])
> >  fi
> > +
> > +# Only consider BTI supported if -mbranch-protection=bti is
> > +# on by default in the compiler and the linker produces
> > +# binaries with GNU property notes in PT_GNU_PROPERTY segment.
> > +AC_CACHE_CHECK([for BTI support], [libc_cv_aarch64_bti], [dnl
> > +  cat > conftest.c <<EOF
> > +void foo (void) { }
> > +EOF
> > +  libc_cv_aarch64_bti=no
> > +  if AC_TRY_COMMAND([${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS -nostdlib -nostartfiles $no_ssp -shared -fPIC -o conftest.so conftest.c]) \
> > +     && AC_TRY_COMMAND([$READELF -lW conftest.so | grep -q GNU_PROPERTY]) \
> > +     && AC_TRY_COMMAND([$READELF -nW conftest.so | grep -q "NT_GNU_PROPERTY_TYPE_0.*AArch64 feature:.* BTI"])
> > +  then
> > +    libc_cv_aarch64_bti=yes
> > +  fi
> > +  rm -rf conftest.*])
> > +if test $libc_cv_aarch64_bti = yes; then
> > +  AC_DEFINE(HAVE_AARCH64_BTI)
> > +fi
> > 
> 
> Ok.

--
  
Adhemerval Zanella July 6, 2020, 6:12 p.m. UTC | #3
On 06/07/2020 15:07, Szabolcs Nagy wrote:
> The 07/06/2020 11:11, Adhemerval Zanella via Libc-alpha wrote:
>>
>>
>> On 01/07/2020 11:38, Szabolcs Nagy wrote:
>>> Check BTI support in the compiler and linker.  The check also
>>> requires READELF that understands the BTI GNU property note.
>>> It is expected to succeed with gcc >=gcc-9 configured with
>>> --enable-standard-branch-protection and binutils >=binutils-2.33.
>>>
>>> Note: passing -mbranch-protection=bti in CFLAGS when building glibc
>>> may not be enough to get a glibc that supports BTI because crtbegin*
>>> and crtend* provided by the compiler needs to be BTI compatible too.
>>
>> If I read correctly this scenario should be covered by the configure
>> test, right?
> 
> it is not covered because the config checks use -nostdlib
> and -nostartfiles (otherwise objects from the libc that
> the toolchain uses would leak into the checks).
> 
> so if gcc startfiles are not bti compatible then configure
> succeeds (but later on there will be link failures so the
> build fails).

Right, would be hard to try to fail early on configure for this
case?
  
Szabolcs Nagy July 7, 2020, 2:26 p.m. UTC | #4
The 07/06/2020 15:12, Adhemerval Zanella wrote:
> 
> 
> On 06/07/2020 15:07, Szabolcs Nagy wrote:
> > The 07/06/2020 11:11, Adhemerval Zanella via Libc-alpha wrote:
> >>
> >>
> >> On 01/07/2020 11:38, Szabolcs Nagy wrote:
> >>> Check BTI support in the compiler and linker.  The check also
> >>> requires READELF that understands the BTI GNU property note.
> >>> It is expected to succeed with gcc >=gcc-9 configured with
> >>> --enable-standard-branch-protection and binutils >=binutils-2.33.
> >>>
> >>> Note: passing -mbranch-protection=bti in CFLAGS when building glibc
> >>> may not be enough to get a glibc that supports BTI because crtbegin*
> >>> and crtend* provided by the compiler needs to be BTI compatible too.
> >>
> >> If I read correctly this scenario should be covered by the configure
> >> test, right?
> > 
> > it is not covered because the config checks use -nostdlib
> > and -nostartfiles (otherwise objects from the libc that
> > the toolchain uses would leak into the checks).
> > 
> > so if gcc startfiles are not bti compatible then configure
> > succeeds (but later on there will be link failures so the
> > build fails).
> 
> Right, would be hard to try to fail early on configure for this
> case?

i don't know how to reliably link with gcc start files
but not with libc start files.

explicit link wiht crtbeginS.o may not be right, the
exact name depends on the compiler driver.

so i would have to provide dummy libc start files to be
able to do the check, but that can go bad in many ways
so the check may not be reliable.
  
H.J. Lu July 7, 2020, 2:39 p.m. UTC | #5
On Tue, Jul 7, 2020 at 7:27 AM Szabolcs Nagy <szabolcs.nagy@arm.com> wrote:
>
> The 07/06/2020 15:12, Adhemerval Zanella wrote:
> >
> >
> > On 06/07/2020 15:07, Szabolcs Nagy wrote:
> > > The 07/06/2020 11:11, Adhemerval Zanella via Libc-alpha wrote:
> > >>
> > >>
> > >> On 01/07/2020 11:38, Szabolcs Nagy wrote:
> > >>> Check BTI support in the compiler and linker.  The check also
> > >>> requires READELF that understands the BTI GNU property note.
> > >>> It is expected to succeed with gcc >=gcc-9 configured with
> > >>> --enable-standard-branch-protection and binutils >=binutils-2.33.
> > >>>
> > >>> Note: passing -mbranch-protection=bti in CFLAGS when building glibc
> > >>> may not be enough to get a glibc that supports BTI because crtbegin*
> > >>> and crtend* provided by the compiler needs to be BTI compatible too.
> > >>
> > >> If I read correctly this scenario should be covered by the configure
> > >> test, right?
> > >
> > > it is not covered because the config checks use -nostdlib
> > > and -nostartfiles (otherwise objects from the libc that
> > > the toolchain uses would leak into the checks).
> > >
> > > so if gcc startfiles are not bti compatible then configure
> > > succeeds (but later on there will be link failures so the
> > > build fails).
> >
> > Right, would be hard to try to fail early on configure for this
> > case?
>
> i don't know how to reliably link with gcc start files
> but not with libc start files.
>
> explicit link wiht crtbeginS.o may not be right, the
> exact name depends on the compiler driver.
>
> so i would have to provide dummy libc start files to be
> able to do the check, but that can go bad in many ways
> so the check may not be reliable.

For CET, I added --enable-cet to enable CET in GCC run-time,
including crtbeginS.o, ...  Since CET enabled run-time is backward
compatible, it is safe to do so.  In fact, --enable-cet is the default
starting from GCC 10.
  
Szabolcs Nagy July 7, 2020, 4:58 p.m. UTC | #6
The 07/07/2020 07:39, H.J. Lu wrote:
> On Tue, Jul 7, 2020 at 7:27 AM Szabolcs Nagy <szabolcs.nagy@arm.com> wrote:
> > i don't know how to reliably link with gcc start files
> > but not with libc start files.
> >
> > explicit link wiht crtbeginS.o may not be right, the
> > exact name depends on the compiler driver.
> >
> > so i would have to provide dummy libc start files to be
> > able to do the check, but that can go bad in many ways
> > so the check may not be reliable.
> 
> For CET, I added --enable-cet to enable CET in GCC run-time,
> including crtbeginS.o, ...  Since CET enabled run-time is backward
> compatible, it is safe to do so.  In fact, --enable-cet is the default
> starting from GCC 10.

makes sense.

on aarch64, bti needs a recent binutils otherwise
there are ugly linker warnings for the unknown gnu
properties so i don't think it's a good idea to
turn it on by default just yet.
  
H.J. Lu July 7, 2020, 5:24 p.m. UTC | #7
On Tue, Jul 7, 2020 at 9:59 AM Szabolcs Nagy <szabolcs.nagy@arm.com> wrote:
>
> The 07/07/2020 07:39, H.J. Lu wrote:
> > On Tue, Jul 7, 2020 at 7:27 AM Szabolcs Nagy <szabolcs.nagy@arm.com> wrote:
> > > i don't know how to reliably link with gcc start files
> > > but not with libc start files.
> > >
> > > explicit link wiht crtbeginS.o may not be right, the
> > > exact name depends on the compiler driver.
> > >
> > > so i would have to provide dummy libc start files to be
> > > able to do the check, but that can go bad in many ways
> > > so the check may not be reliable.
> >
> > For CET, I added --enable-cet to enable CET in GCC run-time,
> > including crtbeginS.o, ...  Since CET enabled run-time is backward
> > compatible, it is safe to do so.  In fact, --enable-cet is the default
> > starting from GCC 10.
>
> makes sense.
>
> on aarch64, bti needs a recent binutils otherwise
> there are ugly linker warnings for the unknown gnu
> properties so i don't think it's a good idea to
> turn it on by default just yet.

config/cet.m4 has --enable-cet=auto.   CET is enabled only
if binutuls supports CET.
  

Patch

diff --git a/config.h.in b/config.h.in
index 831eca2fe1..67169e5d01 100644
--- a/config.h.in
+++ b/config.h.in
@@ -109,6 +109,9 @@ 
 /* AArch64 big endian ABI */
 #undef HAVE_AARCH64_BE
 
+/* AArch64 BTI support enabled.  */
+#define HAVE_AARCH64_BTI 0
+
 /* C-SKY ABI version.  */
 #undef CSKYABI
 
diff --git a/sysdeps/aarch64/configure b/sysdeps/aarch64/configure
index 5bd355a691..70477a7fa5 100644
--- a/sysdeps/aarch64/configure
+++ b/sysdeps/aarch64/configure
@@ -172,3 +172,45 @@  else
   config_vars="$config_vars
 default-abi = lp64"
 fi
+
+# Only consider BTI supported if -mbranch-protection=bti is
+# on by default in the compiler and the linker produces
+# binaries with GNU property notes in PT_GNU_PROPERTY segment.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for BTI support" >&5
+$as_echo_n "checking for BTI support... " >&6; }
+if ${libc_cv_aarch64_bti+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+    cat > conftest.c <<EOF
+void foo (void) { }
+EOF
+  libc_cv_aarch64_bti=no
+  if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS -nostdlib -nostartfiles $no_ssp -shared -fPIC -o conftest.so conftest.c'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } \
+     && { ac_try='$READELF -lW conftest.so | grep -q GNU_PROPERTY'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } \
+     && { ac_try='$READELF -nW conftest.so | grep -q "NT_GNU_PROPERTY_TYPE_0.*AArch64 feature:.* BTI"'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }
+  then
+    libc_cv_aarch64_bti=yes
+  fi
+  rm -rf conftest.*
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_aarch64_bti" >&5
+$as_echo "$libc_cv_aarch64_bti" >&6; }
+if test $libc_cv_aarch64_bti = yes; then
+  $as_echo "#define HAVE_AARCH64_BTI 1" >>confdefs.h
+
+fi
diff --git a/sysdeps/aarch64/configure.ac b/sysdeps/aarch64/configure.ac
index 7851dd4dac..798f494740 100644
--- a/sysdeps/aarch64/configure.ac
+++ b/sysdeps/aarch64/configure.ac
@@ -20,3 +20,22 @@  if test $libc_cv_aarch64_be = yes; then
 else
   LIBC_CONFIG_VAR([default-abi], [lp64])
 fi
+
+# Only consider BTI supported if -mbranch-protection=bti is
+# on by default in the compiler and the linker produces
+# binaries with GNU property notes in PT_GNU_PROPERTY segment.
+AC_CACHE_CHECK([for BTI support], [libc_cv_aarch64_bti], [dnl
+  cat > conftest.c <<EOF
+void foo (void) { }
+EOF
+  libc_cv_aarch64_bti=no
+  if AC_TRY_COMMAND([${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS -nostdlib -nostartfiles $no_ssp -shared -fPIC -o conftest.so conftest.c]) \
+     && AC_TRY_COMMAND([$READELF -lW conftest.so | grep -q GNU_PROPERTY]) \
+     && AC_TRY_COMMAND([$READELF -nW conftest.so | grep -q "NT_GNU_PROPERTY_TYPE_0.*AArch64 feature:.* BTI"])
+  then
+    libc_cv_aarch64_bti=yes
+  fi
+  rm -rf conftest.*])
+if test $libc_cv_aarch64_bti = yes; then
+  AC_DEFINE(HAVE_AARCH64_BTI)
+fi