Re: [RFC] Linux system call builtins

2024-04-10 Thread Szabolcs Nagy via Gcc
The 04/09/2024 23:59, Matheus Afonso Martins Moreira via Gcc wrote:
> > and using raw syscalls outside of the single runtime the
> > application is using is problematic (at least on linux).
> 
> Why do you say they are problematic on Linux though? Please elaborate.

because the portable c api layer and syscall abi layer
has a large enough gap that applications can break
libc internals by doing raw syscalls.

and it's not just the call convention that's target
specific (this makes the c syscall() function hard to
use on linux)

and linux evolves fast enough that raw syscalls have
to be adjusted over time (to support new features)
which is harder when they are all over the place
instead of in the libc only.

> 
> The ABI being stable should mean that I can for example
> strace a program, analyze the system calls and implement
> a new version of it that performs the same functions.

you could do that with syscall() but it is not very
useful as the state of the system is not the same
when you rerun a process so syscalls would likely
fail or do different things than in the first run.

> > clone cannot even be used from c code in general
> > as CLONE_VM is not compatible with c semantics
> > without a new stack (child clobbers the parent stack)
> > so the c builtin would not always work
> > it is also a syscall that only freestanding
> > application can use not something that calls
> > into the libc
> 
> There are major projects out there which do use it regardless.

that does not make it right.

> For example, systemd:
> 
> https://github.com/systemd/systemd/blob/main/src/basic/raw-clone.h
> https://github.com/systemd/systemd/blob/main/src/shared/async.h
> https://github.com/systemd/systemd/blob/main/src/shared/async.c
> https://github.com/systemd/systemd/blob/main/docs/CODING_STYLE.md
> 
> > even in a freestanding application it is tricky to use right
> 
> No argument from me there. It is tricky...
> The compiler should make it possible though.
> 
> > so i don't see why clone is the quintessential example.
> 
> I think it is the best example because attempting to use clone
> is not actually supported by glibc.
> 
> https://sourceware.org/bugzilla/show_bug.cgi?id=10311
> 
> "If you use clone() you're on your own."

should be

"if you use clone() *or* raw clone syscall then
 you're on your own"

which is roughly what i said in that discussion.

so your proposal does not fix this particular issue,
just provide a simpler footgun.

> > i guess it's ok if it is by default an error
> > outside of -ffreestanding.
> 
> Hosted C programs could also make good use of them.

they should not.

> They could certainly start out exclusive to freestanding C
> and then made available to general code if there's demand.


[gcc(refs/vendors/ARM/heads/gcs)] aarch64: Introduce indirect_return attribute

2024-04-10 Thread Szabolcs Nagy via Gcc-cvs
https://gcc.gnu.org/g:3458fa6e8c32f128c666b49cfcb65dfdd52d7e43

commit 3458fa6e8c32f128c666b49cfcb65dfdd52d7e43
Author: Szabolcs Nagy 
Date:   Thu Dec 28 13:37:38 2023 +

aarch64: Introduce indirect_return attribute

Tail calls of indirect_return functions from non-indirect_return
functions are disallowed even if BTI is disabled, since the call
site may have BTI enabled.

Following x86, mismatching attribute on function pointers is not
a type error even though this can lead to bugs.

Needed for swapcontext within the same function when GCS is enabled.

TODO: arm? docs, tests. feature detection?

gcc/ChangeLog:

* config/aarch64/aarch64.cc (aarch64_gnu_attributes): Add
indirect_return.
(aarch64_function_ok_for_sibcall): Disallow tail calls if caller
is non-indirect_return but callee is indirect_return.
(aarch64_comp_type_attributes): Check indirect_return attribute.
* config/arm/aarch-bti-insert.cc (call_needs_bti_j): New.
(rest_of_insert_bti): Use call_needs_bti_j.

Diff:
---
 gcc/config/aarch64/aarch64.cc  | 11 +++
 gcc/config/arm/aarch-bti-insert.cc | 36 
 2 files changed, 43 insertions(+), 4 deletions(-)

diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc
index 0119cfdd67b..593b107c8a5 100644
--- a/gcc/config/aarch64/aarch64.cc
+++ b/gcc/config/aarch64/aarch64.cc
@@ -850,6 +850,7 @@ static const attribute_spec aarch64_gnu_attributes[] =
affects_type_identity, handler, exclude } */
   { "aarch64_vector_pcs", 0, 0, false, true,  true,  true,
  handle_aarch64_vector_pcs_attribute, NULL },
+  { "indirect_return",0, 0, false, true, true, false, NULL, NULL },
   { "arm_sve_vector_bits", 1, 1, false, true,  false, true,
  aarch64_sve::handle_arm_sve_vector_bits_attribute,
  NULL },
@@ -6340,6 +6341,14 @@ aarch64_function_ok_for_sibcall (tree, tree exp)
 if (bool (aarch64_cfun_shared_flags (state))
!= bool (aarch64_fntype_shared_flags (fntype, state)))
   return false;
+
+  /* BTI J is needed where indirect_return functions may return
+ if bti is enabled there.  */
+  if (lookup_attribute ("indirect_return", TYPE_ATTRIBUTES (fntype))
+  && !lookup_attribute ("indirect_return",
+   TYPE_ATTRIBUTES (TREE_TYPE (cfun->decl
+return false;
+
   return true;
 }
 
@@ -28855,6 +28864,8 @@ aarch64_comp_type_attributes (const_tree type1, 
const_tree type2)
 
   if (!check_attr ("gnu", "aarch64_vector_pcs"))
 return 0;
+  if (!check_attr ("gnu", "indirect_return"))
+return 0;
   if (!check_attr ("gnu", "Advanced SIMD type"))
 return 0;
   if (!check_attr ("gnu", "SVE type"))
diff --git a/gcc/config/arm/aarch-bti-insert.cc 
b/gcc/config/arm/aarch-bti-insert.cc
index 14d36971cd4..403afff9120 100644
--- a/gcc/config/arm/aarch-bti-insert.cc
+++ b/gcc/config/arm/aarch-bti-insert.cc
@@ -92,6 +92,35 @@ const pass_data pass_data_insert_bti =
   0, /* todo_flags_finish.  */
 };
 
+/* Decide if BTI J is needed after a call instruction.  */
+static bool
+call_needs_bti_j (rtx_insn *insn)
+{
+  /* Call returns twice, one of which may be indirect.  */
+  if (find_reg_note (insn, REG_SETJMP, NULL))
+return true;
+
+  /* Tail call does not return.  */
+  if (SIBLING_CALL_P (insn))
+return false;
+
+  /* Check if the function is marked to return indirectly.  */
+  rtx call = get_call_rtx_from (insn);
+  rtx fnaddr = XEXP (call, 0);
+  tree fndecl = NULL_TREE;
+  if (GET_CODE (XEXP (fnaddr, 0)) == SYMBOL_REF)
+fndecl = SYMBOL_REF_DECL (XEXP (fnaddr, 0));
+  if (fndecl == NULL_TREE)
+fndecl = MEM_EXPR (fnaddr);
+  if (!fndecl)
+return false;
+  if (TREE_CODE (TREE_TYPE (fndecl)) != FUNCTION_TYPE
+  && TREE_CODE (TREE_TYPE (fndecl)) != METHOD_TYPE)
+return false;
+  tree fntype = TREE_TYPE (fndecl);
+  return lookup_attribute ("indirect_return", TYPE_ATTRIBUTES (fntype));
+}
+
 /* Insert the BTI instruction.  */
 /* This is implemented as a late RTL pass that runs before branch
shortening and does the following.  */
@@ -147,10 +176,9 @@ rest_of_insert_bti (void)
}
}
 
- /* Also look for calls to setjmp () which would be marked with
-REG_SETJMP note and put a BTI J after.  This is where longjump ()
-will return.  */
- if (CALL_P (insn) && (find_reg_note (insn, REG_SETJMP, NULL)))
+ /* Also look for calls that may return indirectly, such as setjmp,
+and put a BTI J after them.  */
+ if (CALL_P (insn) && call_needs_bti_j (insn))
{
  bti_insn = aarch_gen_bti_j ();
  emit_insn_after (bti_insn, insn);


[gcc(refs/vendors/ARM/heads/gcs)] aarch64: libitm: Add GCS support

2024-04-10 Thread Szabolcs Nagy via Gcc-cvs
https://gcc.gnu.org/g:9f2fe2932ca35b736685753a85bd5c43459f24de

commit 9f2fe2932ca35b736685753a85bd5c43459f24de
Author: Szabolcs Nagy 
Date:   Tue Apr 2 15:43:23 2024 +0100

aarch64: libitm: Add GCS support

Transaction begin and abort use setjmp/longjmp like operations that
need to be updated for GCS compatibility. We use similar logic to
libc setjmp/longjmp that support switching stack and thus switching
GCS (e.g. due to longjmp out of a makecontext stack), this is kept
even though it is likely not required for transaction aborts.

The gtm_jmpbuf is internal to libitm so we can change its layout
without breaking ABI.

libitm/ChangeLog:

* config/aarch64/sjlj.S: Add GCS support and mark GCS compatible.
* config/aarch64/target.h: Add gcs field to gtm_jmpbuf.

Diff:
---
 libitm/config/aarch64/sjlj.S   | 60 +++---
 libitm/config/aarch64/target.h |  1 +
 2 files changed, 58 insertions(+), 3 deletions(-)

diff --git a/libitm/config/aarch64/sjlj.S b/libitm/config/aarch64/sjlj.S
index 6b248f7c040..e21d751ef21 100644
--- a/libitm/config/aarch64/sjlj.S
+++ b/libitm/config/aarch64/sjlj.S
@@ -29,6 +29,13 @@
 #define AUTIASPhint29
 #define PACIBSPhint27
 #define AUTIBSPhint31
+#define CHKFEAT_X16hint40
+#define MRS_GCSPR(x)   mrs x, s3_3_c2_c5_1
+#define GCSPOPM(x) syslx, #3, c7, c7, #1
+#define GCSSS1(x)  sys #3, c7, c7, #2, x
+#define GCSSS2(x)  syslx, #3, c7, c7, #3
+
+#define L(name) .L##name
 
 #if defined(HAVE_AS_CFI_PSEUDO_OP) && defined(__GCC_HAVE_DWARF2_CFI_ASM)
 # define cfi_window_save .cfi_window_save
@@ -80,7 +87,16 @@ _ITM_beginTransaction:
stp d10, d11, [sp, 7*16]
stp d12, d13, [sp, 8*16]
stp d14, d15, [sp, 9*16]
-   str x1, [sp, 10*16]
+
+   /* GCS support.  */
+   mov x2, 0
+   mov x16, 1
+   CHKFEAT_X16
+   tbnzx16, 0, L(gcs_done_sj)
+   MRS_GCSPR (x2)
+   add x2, x2, 8 /* GCS after _ITM_beginTransaction returns.  */
+L(gcs_done_sj):
+   stp x2, x1, [sp, 10*16]
 
/* Invoke GTM_begin_transaction with the struct we just built.  */
mov x1, sp
@@ -117,7 +133,38 @@ GTM_longjmp:
ldp d10, d11, [x1, 7*16]
ldp d12, d13, [x1, 8*16]
ldp d14, d15, [x1, 9*16]
+
+   /* GCS support.  */
+   mov x16, 1
+   CHKFEAT_X16
+   tbnzx16, 0, L(gcs_done_lj)
+   MRS_GCSPR (x7)
ldr x3, [x1, 10*16]
+   mov x4, x3
+   /* x7: GCSPR now.  x3, x4: target GCSPR.  x5, x6: tmp regs.  */
+L(gcs_scan):
+   cmp x7, x4
+   b.eqL(gcs_pop)
+   sub x4, x4, 8
+   /* Check for a cap token.  */
+   ldr x5, [x4]
+   and x6, x4, 0xf000
+   orr x6, x6, 1
+   cmp x5, x6
+   b.neL(gcs_scan)
+L(gcs_switch):
+   add x7, x4, 8
+   GCSSS1 (x4)
+   GCSSS2 (xzr)
+L(gcs_pop):
+   cmp x7, x3
+   b.eqL(gcs_done_lj)
+   GCSPOPM (xzr)
+   add x7, x7, 8
+   b   L(gcs_pop)
+L(gcs_done_lj):
+
+   ldr x3, [x1, 10*16 + 8]
ldp x29, x30, [x1]
cfi_def_cfa(x1, 0)
CFI_PAC_TOGGLE
@@ -132,6 +179,7 @@ GTM_longjmp:
 #define FEATURE_1_AND 0xc000
 #define FEATURE_1_BTI 1
 #define FEATURE_1_PAC 2
+#define FEATURE_1_GCS 4
 
 /* Supported features based on the code generation options.  */
 #if defined(__ARM_FEATURE_BTI_DEFAULT)
@@ -146,6 +194,12 @@ GTM_longjmp:
 # define PAC_FLAG 0
 #endif
 
+#if __ARM_FEATURE_GCS_DEFAULT
+# define GCS_FLAG FEATURE_1_GCS
+#else
+# define GCS_FLAG 0
+#endif
+
 /* Add a NT_GNU_PROPERTY_TYPE_0 note.  */
 #define GNU_PROPERTY(type, value)  \
   .section .note.gnu.property, "a";\
@@ -163,7 +217,7 @@ GTM_longjmp:
 .section .note.GNU-stack, "", %progbits
 
 /* Add GNU property note if built with branch protection.  */
-# if (BTI_FLAG|PAC_FLAG) != 0
-GNU_PROPERTY (FEATURE_1_AND, BTI_FLAG|PAC_FLAG)
+# if (BTI_FLAG|PAC_FLAG|GCS_FLAG) != 0
+GNU_PROPERTY (FEATURE_1_AND, BTI_FLAG|PAC_FLAG|GCS_FLAG)
 # endif
 #endif
diff --git a/libitm/config/aarch64/target.h b/libitm/config/aarch64/target.h
index 3d99197bfab..a1f39b4bf7a 100644
--- a/libitm/config/aarch64/target.h
+++ b/libitm/config/aarch64/target.h
@@ -30,6 +30,7 @@ typedef struct gtm_jmpbuf
   unsigned long long pc;   /* x30 */
   unsigned long long gr[10];   /* x19-x28 */
   unsigned long long vr[8];/* d8-d15 */
+  void *gcs;   /* GCSPR_EL0 */
   void *cfa;
 } gtm_jmpbuf;


[gcc(refs/vendors/ARM/heads/gcs)] aarch64: libatomic: add GCS marking to asm

2024-04-10 Thread Szabolcs Nagy via Gcc-cvs
https://gcc.gnu.org/g:78b29b5934193bd7e057aa8196ab8645df092d44

commit 78b29b5934193bd7e057aa8196ab8645df092d44
Author: Szabolcs Nagy 
Date:   Fri Dec 22 15:11:25 2023 +

aarch64: libatomic: add GCS marking to asm

libatomic/ChangeLog:

* config/linux/aarch64/atomic_16.S (FEATURE_1_GCS): Define.
(GCS_FLAG): Define if GCS is enabled.
(GNU_PROPERTY): Add GCS_FLAG.

Diff:
---
 libatomic/config/linux/aarch64/atomic_16.S | 11 +--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/libatomic/config/linux/aarch64/atomic_16.S 
b/libatomic/config/linux/aarch64/atomic_16.S
index 4e3fa870b03..d6f34eee146 100644
--- a/libatomic/config/linux/aarch64/atomic_16.S
+++ b/libatomic/config/linux/aarch64/atomic_16.S
@@ -790,6 +790,7 @@ ALIAS2 (test_and_set_16)
 #define FEATURE_1_AND 0xc000
 #define FEATURE_1_BTI 1
 #define FEATURE_1_PAC 2
+#define FEATURE_1_GCS 4
 
 /* Supported features based on the code generation options.  */
 #if defined(__ARM_FEATURE_BTI_DEFAULT)
@@ -804,6 +805,12 @@ ALIAS2 (test_and_set_16)
 # define PAC_FLAG 0
 #endif
 
+#if __ARM_FEATURE_GCS_DEFAULT
+# define GCS_FLAG FEATURE_1_GCS
+#else
+# define GCS_FLAG 0
+#endif
+
 /* Add a NT_GNU_PROPERTY_TYPE_0 note.  */
 #define GNU_PROPERTY(type, value)  \
   .section .note.gnu.property, "a"; \
@@ -821,7 +828,7 @@ ALIAS2 (test_and_set_16)
 .section .note.GNU-stack, "", %progbits
 
 /* Add GNU property note if built with branch protection.  */
-# if (BTI_FLAG|PAC_FLAG) != 0
-GNU_PROPERTY (FEATURE_1_AND, BTI_FLAG|PAC_FLAG)
+# if (BTI_FLAG|PAC_FLAG|GCS_FLAG) != 0
+GNU_PROPERTY (FEATURE_1_AND, BTI_FLAG|PAC_FLAG|GCS_FLAG)
 # endif
 #endif


[gcc(refs/vendors/ARM/heads/gcs)] aarch64: Emit GNU property NOTE for GCS

2024-04-10 Thread Szabolcs Nagy via Gcc-cvs
https://gcc.gnu.org/g:99a291c0313e8e839c3ffd1fdc5132b4d6462968

commit 99a291c0313e8e839c3ffd1fdc5132b4d6462968
Author: Szabolcs Nagy 
Date:   Tue May 9 14:32:46 2023 +0100

aarch64: Emit GNU property NOTE for GCS

TODO: relies on experimental binutils ABI, should use build attributes.

gcc/ChangeLog:

* config/aarch64/aarch64.cc (GNU_PROPERTY_AARCH64_FEATURE_1_GCS):
Define.
(aarch64_file_end_indicate_exec_stack): Set GCS property bit.

Diff:
---
 gcc/config/aarch64/aarch64.cc | 5 +
 1 file changed, 5 insertions(+)

diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc
index 73969721906..0119cfdd67b 100644
--- a/gcc/config/aarch64/aarch64.cc
+++ b/gcc/config/aarch64/aarch64.cc
@@ -28962,6 +28962,7 @@ aarch64_can_tag_addresses ()
 #define GNU_PROPERTY_AARCH64_FEATURE_1_AND 0xc000
 #define GNU_PROPERTY_AARCH64_FEATURE_1_BTI (1U << 0)
 #define GNU_PROPERTY_AARCH64_FEATURE_1_PAC (1U << 1)
+#define GNU_PROPERTY_AARCH64_FEATURE_1_GCS (1U << 2)
 void
 aarch64_file_end_indicate_exec_stack ()
 {
@@ -28974,6 +28975,9 @@ aarch64_file_end_indicate_exec_stack ()
   if (aarch_ra_sign_scope != AARCH_FUNCTION_NONE)
 feature_1_and |= GNU_PROPERTY_AARCH64_FEATURE_1_PAC;
 
+  if (aarch64_gcs_enabled ())
+feature_1_and |= GNU_PROPERTY_AARCH64_FEATURE_1_GCS;
+
   if (feature_1_and)
 {
   /* Generate .note.gnu.property section.  */
@@ -29005,6 +29009,7 @@ aarch64_file_end_indicate_exec_stack ()
   assemble_align (POINTER_SIZE);
 }
 }
+#undef GNU_PROPERTY_AARCH64_FEATURE_1_GCS
 #undef GNU_PROPERTY_AARCH64_FEATURE_1_PAC
 #undef GNU_PROPERTY_AARCH64_FEATURE_1_BTI
 #undef GNU_PROPERTY_AARCH64_FEATURE_1_AND


[gcc(refs/vendors/ARM/heads/gcs)] aarch64: libgcc: add GCS marking to asm

2024-04-10 Thread Szabolcs Nagy via Gcc-cvs
https://gcc.gnu.org/g:b32a17f9f43d68859e31d7a6af7b21ac2ed42742

commit b32a17f9f43d68859e31d7a6af7b21ac2ed42742
Author: Szabolcs Nagy 
Date:   Fri Dec 22 13:44:19 2023 +

aarch64: libgcc: add GCS marking to asm

libgcc/ChangeLog:

* config/aarch64/aarch64-asm.h (FEATURE_1_GCS): Define.
(GCS_FLAG): Define if GCS is enabled.
(GNU_PROPERTY): Add GCS_FLAG.

Diff:
---
 libgcc/config/aarch64/aarch64-asm.h | 11 +--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/libgcc/config/aarch64/aarch64-asm.h 
b/libgcc/config/aarch64/aarch64-asm.h
index 83c2e5944b3..86a9a0e662e 100644
--- a/libgcc/config/aarch64/aarch64-asm.h
+++ b/libgcc/config/aarch64/aarch64-asm.h
@@ -38,6 +38,7 @@
 #define FEATURE_1_AND 0xc000
 #define FEATURE_1_BTI 1
 #define FEATURE_1_PAC 2
+#define FEATURE_1_GCS 4
 
 /* Supported features based on the code generation options.  */
 #if defined(__ARM_FEATURE_BTI_DEFAULT)
@@ -58,6 +59,12 @@
 # define AUTIASP
 #endif
 
+#if __ARM_FEATURE_GCS_DEFAULT
+# define GCS_FLAG FEATURE_1_GCS
+#else
+# define GCS_FLAG 0
+#endif
+
 #ifdef __ELF__
 #define HIDDEN(name) .hidden name
 #define SYMBOL_SIZE(name) .size name, .-name
@@ -88,8 +95,8 @@
 .previous
 
 /* Add GNU property note if built with branch protection.  */
-# if (BTI_FLAG|PAC_FLAG) != 0
-GNU_PROPERTY (FEATURE_1_AND, BTI_FLAG|PAC_FLAG)
+# if (BTI_FLAG|PAC_FLAG|GCS_FLAG) != 0
+GNU_PROPERTY (FEATURE_1_AND, BTI_FLAG|PAC_FLAG|GCS_FLAG)
 # endif
 #endif


[gcc(refs/vendors/ARM/heads/gcs)] aarch64: Add test for GCS ACLE defs

2024-04-10 Thread Szabolcs Nagy via Gcc-cvs
https://gcc.gnu.org/g:2a9d500c8f2fd1004cdcbcdec063681dbb0bb1f1

commit 2a9d500c8f2fd1004cdcbcdec063681dbb0bb1f1
Author: Szabolcs Nagy 
Date:   Wed Jun 7 16:17:53 2023 +0100

aarch64: Add test for GCS ACLE defs

gcc/testsuite/ChangeLog:

* gcc.target/aarch64/pragma_cpp_predefs_1.c: GCS test.

Diff:
---
 .../gcc.target/aarch64/pragma_cpp_predefs_1.c  | 30 ++
 1 file changed, 30 insertions(+)

diff --git a/gcc/testsuite/gcc.target/aarch64/pragma_cpp_predefs_1.c 
b/gcc/testsuite/gcc.target/aarch64/pragma_cpp_predefs_1.c
index 307fa3d67da..6122cd55d66 100644
--- a/gcc/testsuite/gcc.target/aarch64/pragma_cpp_predefs_1.c
+++ b/gcc/testsuite/gcc.target/aarch64/pragma_cpp_predefs_1.c
@@ -268,6 +268,36 @@
 #error "__ARM_FEATURE_RCPC is not defined but should be!"
 #endif
 
+#pragma GCC target ("arch=armv8.8-a+gcs")
+#ifndef __ARM_FEATURE_GCS
+#error "__ARM_FEATURE_GCS is not defined but should be!"
+#endif
+
+#pragma GCC target ("arch=armv8.8-a+nogcs")
+#ifdef __ARM_FEATURE_GCS
+#error "__ARM_FEATURE_GCS is defined but should not be!"
+#endif
+
+#pragma GCC target ("arch=armv8.8-a")
+#ifdef __ARM_FEATURE_GCS
+#error "__ARM_FEATURE_GCS is defined but should not be!"
+#endif
+
+#pragma GCC target ("branch-protection=gcs")
+#ifndef __ARM_FEATURE_GCS_DEFAULT
+#error "__ARM_FEATURE_GCS_DEFAULT is not defined but should be!"
+#endif
+
+#pragma GCC target ("branch-protection=none")
+#ifdef __ARM_FEATURE_GCS_DEFAULT
+#error "__ARM_FEATURE_GCS_DEFAULT is defined but should not be!"
+#endif
+
+#pragma GCC target ("branch-protection=standard")
+#ifndef __ARM_FEATURE_GCS_DEFAULT
+#error "__ARM_FEATURE_GCS_DEFAULT is not defined but should be!"
+#endif
+
 int
 foo (int a)
 {


[gcc(refs/vendors/ARM/heads/gcs)] aarch64: Add GCS support to the unwinder

2024-04-10 Thread Szabolcs Nagy via Gcc-cvs
https://gcc.gnu.org/g:2185dc7cdb6d536e4d9a49a77c552e58041cb0bc

commit 2185dc7cdb6d536e4d9a49a77c552e58041cb0bc
Author: Szabolcs Nagy 
Date:   Wed Apr 19 14:01:36 2023 +0100

aarch64: Add GCS support to the unwinder

TODO:
- Follows the current linux ABI that uses single signal entry token
  and shared shadow stack between thread and alt stack.
- Could be behind __ARM_FEATURE_GCS_DEFAULT ifdef (only do anything
  special with gcs compat codegen) but there is a runtime check anyway.

libgcc/ChangeLog:

* config/aarch64/aarch64-unwind.h (_Unwind_Frames_Extra): Update.
(_Unwind_Frames_Increment): Define.

Diff:
---
 libgcc/config/aarch64/aarch64-unwind.h | 59 +-
 1 file changed, 58 insertions(+), 1 deletion(-)

diff --git a/libgcc/config/aarch64/aarch64-unwind.h 
b/libgcc/config/aarch64/aarch64-unwind.h
index daf96624b5e..c22a3fc20d2 100644
--- a/libgcc/config/aarch64/aarch64-unwind.h
+++ b/libgcc/config/aarch64/aarch64-unwind.h
@@ -78,6 +78,9 @@ aarch64_demangle_return_addr (struct _Unwind_Context *context,
   return addr;
 }
 
+/* GCS enable flag for chkfeat instruction.  */
+#define CHKFEAT_GCS 1
+
 /* SME runtime function local to libgcc, streaming compatible
and preserves more registers than the base PCS requires, but
we don't rely on that here.  */
@@ -85,12 +88,66 @@ __attribute__ ((visibility ("hidden")))
 void __libgcc_arm_za_disable (void);
 
 /* Disable the SME ZA state in case an unwound frame used the ZA
-   lazy saving scheme.  */
+   lazy saving scheme. And unwind the GCS for EH.  */
 #undef _Unwind_Frames_Extra
 #define _Unwind_Frames_Extra(x)\
   do   \
 {  \
   __libgcc_arm_za_disable ();  \
+  if (__builtin_aarch64_chkfeat (CHKFEAT_GCS) == 0)\
+   {   \
+ for (_Unwind_Word n = (x); n != 0; n--)   \
+   __builtin_aarch64_gcspopm ();   \
+   }   \
+}  \
+  while (0)
+
+/* On signal entry the OS places a token on the GCS that can be used to
+   verify the integrity of the GCS pointer on signal return.  It also
+   places the signal handler return address (the restorer that calls the
+   signal return syscall) on the GCS so the handler can return.
+   Because of this token, each stack frame visited during unwinding has
+   exactly one corresponding entry on the GCS, so the frame count is
+   the number of entries that will have to be popped at EH return time.
+
+   Note: This depends on the GCS signal ABI of the OS.
+
+   When unwinding across a stack frame for each frame the corresponding
+   entry is checked on the GCS against the computed return address from
+   the normal stack.  If they don't match then _URC_FATAL_PHASE2_ERROR
+   is returned.  This check is omitted if
+
+   1. GCS is disabled. Note: asynchronous GCS disable is supported here
+  if GCSPR and the GCS remains readable.
+   2. Non-catchable exception where exception_class == 0.  Note: the
+  pthread cancellation implementation in glibc sets exception_class
+  to 0 when the unwinder is used for cancellation cleanup handling,
+  so this allows the GCS to get out of sync during cancellation.
+  This weakens security but avoids an ABI break in glibc.
+   3. Zero return address which marks the outermost stack frame.
+   4. Signal stack frame, the GCS entry is an OS specific token then
+  with the top bit set.
+ */
+#undef _Unwind_Frames_Increment
+#define _Unwind_Frames_Increment(exc, context, frames) \
+  do   \
+{  \
+  frames++;\
+  if (__builtin_aarch64_chkfeat (CHKFEAT_GCS) != 0 \
+ || exc->exception_class == 0  \
+ || _Unwind_GetIP (context) == 0)  \
+   break;  \
+  const _Unwind_Word *gcs = __builtin_aarch64_gcspr (); \
+  if (_Unwind_IsSignalFrame (context)) \
+   {   \
+ if (gcs[frames] >> 63 == 0)   \
+   return _URC_FATAL_PHASE2_ERROR; \
+   }   \
+  else \
+   {   \
+ if (gcs[frames] != _Unwind_GetIP (context))   \
+   return _URC_FATAL_PHASE2_ERROR; \
+   }   \
 }  \
   while (0)


[gcc(refs/vendors/ARM/heads/gcs)] aarch64: Add GCS support for nonlocal stack save

2024-04-10 Thread Szabolcs Nagy via Gcc-cvs
https://gcc.gnu.org/g:d5a22a53f58403c888a43c75c5983ba3cb5023ae

commit d5a22a53f58403c888a43c75c5983ba3cb5023ae
Author: Szabolcs Nagy 
Date:   Fri Apr 14 18:23:52 2023 +0100

aarch64: Add GCS support for nonlocal stack save

Nonlocal stack save and restore has to also save and restore the GCS
pointer. This is used in __builtin_setjmp/longjmp and nonlocal goto.

The GCS specific code is only emitted if GCS branch-protection is
enabled and the code always checks at runtime if GCS is enabled.

The new -mbranch-protection=gcs and old -mbranch-protection=none code
are ABI compatible: jmpbuf for __builtin_setjmp has space for 5
pointers, the layout is

  old layout: fp, pc, sp, unused, unused
  new layout: fp, pc, sp, gcsp, unused

Note: the ILP32 code generation is wrong as it saves the pointers with
Pmode (i.e. 8 bytes per pointer), but the user supplied buffer size is
for 5 pointers (4 bytes per pointer), this is not fixed.

The nonlocal goto has no ABI compatibility issues as the goto and its
destination are in the same translation unit.

TODO:
- can we simplify the define_expand rtls?

gcc/ChangeLog:

* config/aarch64/aarch64.h (STACK_SAVEAREA_MODE): Make space for 
gcs.
* config/aarch64/aarch64.md (save_stack_nonlocal): New.
(restore_stack_nonlocal): New.

Diff:
---
 gcc/config/aarch64/aarch64.h  |  7 
 gcc/config/aarch64/aarch64.md | 82 +++
 2 files changed, 89 insertions(+)

diff --git a/gcc/config/aarch64/aarch64.h b/gcc/config/aarch64/aarch64.h
index 45e901cda64..3238452f53f 100644
--- a/gcc/config/aarch64/aarch64.h
+++ b/gcc/config/aarch64/aarch64.h
@@ -1294,6 +1294,13 @@ typedef struct
 #define CTZ_DEFINED_VALUE_AT_ZERO(MODE, VALUE) \
   ((VALUE) = GET_MODE_UNIT_BITSIZE (MODE), 2)
 
+/* Have space for both SP and GCSPR in the NONLOCAL case in
+   emit_stack_save as well as in __builtin_setjmp, __builtin_longjmp
+   and __builtin_nonlocal_goto.
+   Note: On ILP32 the documented buf size is not enough PR84150.  */
+#define STACK_SAVEAREA_MODE(LEVEL) \
+  ((LEVEL) == SAVE_NONLOCAL ? TImode : Pmode)
+
 #define INCOMING_RETURN_ADDR_RTX gen_rtx_REG (Pmode, LR_REGNUM)
 
 #define RETURN_ADDR_RTX aarch64_return_addr
diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md
index 8defd6e0582..2d36af12cfb 100644
--- a/gcc/config/aarch64/aarch64.md
+++ b/gcc/config/aarch64/aarch64.md
@@ -1183,6 +1183,88 @@
  (const_int 1)))]
 )
 
+(define_expand "save_stack_nonlocal"
+  [(set (match_operand 0 "memory_operand")
+(match_operand 1 "register_operand"))]
+  ""
+{
+  rtx stack_slot = adjust_address (operands[0], Pmode, 0);
+  emit_move_insn (stack_slot, operands[1]);
+
+  if (aarch64_gcs_enabled ())
+{
+  /* Save GCS with code like
+   mov x16, 1
+   chkfeat x16
+   tbnzx16, 0, .L_done
+   mrs tmp, gcspr_el0
+   str tmp, [%0, 8]
+   .L_done:  */
+
+  rtx done_label = gen_label_rtx ();
+  rtx r16 = gen_rtx_REG (DImode, R16_REGNUM);
+  emit_move_insn (r16, const1_rtx);
+  emit_insn (gen_aarch64_chkfeat ());
+  emit_insn (gen_tbranch_neqi3 (r16, const0_rtx, done_label));
+  rtx gcs_slot = adjust_address (operands[0], Pmode, GET_MODE_SIZE 
(Pmode));
+  rtx gcs = force_reg (Pmode, const0_rtx);
+  emit_insn (gen_aarch64_load_gcspr (gcs));
+  emit_move_insn (gcs_slot, gcs);
+  emit_label (done_label);
+}
+  DONE;
+})
+
+(define_expand "restore_stack_nonlocal"
+  [(set (match_operand 0 "register_operand" "")
+   (match_operand 1 "memory_operand" ""))]
+  ""
+{
+  rtx stack_slot = adjust_address (operands[1], Pmode, 0);
+  emit_move_insn (operands[0], stack_slot);
+
+  if (aarch64_gcs_enabled ())
+{
+  /* Restore GCS with code like
+   mov x16, 1
+   chkfeat x16
+   tbnzx16, 0, .L_done
+   ldr tmp1, [%1, 8]
+   mrs tmp2, gcspr_el0
+   substmp2, tmp1, tmp2
+   b.eq.L_done
+   .L_loop:
+   gcspopm
+   substmp2, tmp2, 8
+   b.ne.L_loop
+   .L_done:  */
+
+  rtx loop_label = gen_label_rtx ();
+  rtx done_label = gen_label_rtx ();
+  rtx r16 = gen_rtx_REG (DImode, R16_REGNUM);
+  emit_move_insn (r16, const1_rtx);
+  emit_insn (gen_aarch64_chkfeat ());
+  emit_insn (gen_tbranch_neqi3 (r16, const0_rtx, done_label));
+  rtx gcs_slot = adjust_address (operands[1], Pmode, GET_MODE_SIZE 
(Pmode));
+  rtx gcs_old = force_reg (Pmode, const0_rtx);
+  emit_move_insn (gcs_old, gcs_slot);
+  rtx gcs_now = force_reg (Pmode, const0_rtx);
+  emit_insn 

[gcc(refs/vendors/ARM/heads/gcs)] aarch64: Add ACLE feature macros for GCS

2024-04-10 Thread Szabolcs Nagy via Gcc-cvs
https://gcc.gnu.org/g:f94cfdab086f521592939f03408f59f39a4bdd5a

commit f94cfdab086f521592939f03408f59f39a4bdd5a
Author: Szabolcs Nagy 
Date:   Tue May 9 17:04:34 2023 +0100

aarch64: Add ACLE feature macros for GCS

gcc/ChangeLog:

* config/aarch64/aarch64-c.cc (aarch64_update_cpp_builtins): Define
macros for GCS.

Diff:
---
 gcc/config/aarch64/aarch64-c.cc | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/gcc/config/aarch64/aarch64-c.cc b/gcc/config/aarch64/aarch64-c.cc
index fe1a20e4e54..64c34e73573 100644
--- a/gcc/config/aarch64/aarch64-c.cc
+++ b/gcc/config/aarch64/aarch64-c.cc
@@ -246,6 +246,9 @@ aarch64_update_cpp_builtins (cpp_reader *pfile)
 
   aarch64_def_or_undef (TARGET_PAUTH, "__ARM_FEATURE_PAUTH", pfile);
   aarch64_def_or_undef (TARGET_BTI, "__ARM_FEATURE_BTI", pfile);
+  aarch64_def_or_undef (aarch64_gcs_enabled (),
+   "__ARM_FEATURE_GCS_DEFAULT", pfile);
+  aarch64_def_or_undef (TARGET_GCS, "__ARM_FEATURE_GCS", pfile);
   aarch64_def_or_undef (TARGET_I8MM, "__ARM_FEATURE_MATMUL_INT8", pfile);
   aarch64_def_or_undef (TARGET_BF16_SIMD,
"__ARM_FEATURE_BF16_VECTOR_ARITHMETIC", pfile);


[gcc(refs/vendors/ARM/heads/gcs)] aarch64: Add GCS instructions

2024-04-10 Thread Szabolcs Nagy via Gcc-cvs
https://gcc.gnu.org/g:57aec9c418f837bf427d8317bebdc0f825cbb043

commit 57aec9c418f837bf427d8317bebdc0f825cbb043
Author: Szabolcs Nagy 
Date:   Tue May 9 16:00:01 2023 +0100

aarch64: Add GCS instructions

Add instructions for the Guarded Control Stack extension.

GCSSS1 and GCSSS2 are modelled as a single GCSSS unspec, because they
are always used together in the compiler.

Before GCSPOPM and GCSSS2 an extra "mov xn, 0" is added to clear the
output register, this is needed to get reasonable result when GCS is
disabled, when the instructions are NOPs. Since the instructions are
expecetd to be used behind runtime feature checks, this is mainly
relevant if GCS can be disabled asynchronously.

The output of GCSPOPM is usually not needed, so a separate gcspopm_xzr
was added to model that. Did not do the same for GCSSS as it is a less
common operation.

The used mnemonics do not depend on updated assembler since these
instructions can be used without new -march setting behind a runtime
check.

Reading the GCSPR is modelled as unspec_volatile so it does not get
reordered wrt the other instructions changing the GCSPR.

TODO:
- Do we care about async disable?
- Do we need GCSSS_xzr? (to avoid the mov x,0)

gcc/ChangeLog:

* config/aarch64/aarch64.md (aarch64_load_gcspr): New.
(aarch64_gcspopm): New.
(aarch64_gcspopm_xzr): New.
(aarch64_gcsss): New.

Diff:
---
 gcc/config/aarch64/aarch64.md | 35 +++
 1 file changed, 35 insertions(+)

diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md
index a20462303b5..8defd6e0582 100644
--- a/gcc/config/aarch64/aarch64.md
+++ b/gcc/config/aarch64/aarch64.md
@@ -379,6 +379,9 @@
 UNSPECV_BTI_J  ; Represent BTI j.
 UNSPECV_BTI_JC ; Represent BTI jc.
 UNSPECV_CHKFEAT; Represent CHKFEAT X16.
+UNSPECV_GCSPR  ; Represent MRS Xn, GCSPR_EL0
+UNSPECV_GCSPOPM; Represent GCSPOPM.
+UNSPECV_GCSSS  ; Represent GCSSS1 and GCSSS2.
 UNSPECV_TSTART ; Represent transaction start.
 UNSPECV_TCOMMIT; Represent transaction commit.
 UNSPECV_TCANCEL; Represent transaction cancel.
@@ -8267,6 +8270,38 @@
   "hint\\t40 // chkfeat x16"
 )
 
+;; Guarded Control Stack (GCS) instructions
+(define_insn "aarch64_load_gcspr"
+  [(set (match_operand:DI 0 "register_operand" "=r")
+   (unspec_volatile:DI [(const_int 0)] UNSPECV_GCSPR))]
+  ""
+  "mrs\\t%0, s3_3_c2_c5_1 // gcspr_el0"
+  [(set_attr "type" "mrs")]
+)
+
+(define_insn "aarch64_gcspopm"
+  [(set (match_operand:DI 0 "register_operand" "=r")
+   (unspec_volatile:DI [(const_int 0)] UNSPECV_GCSPOPM))]
+  ""
+  "mov\\t%0, 0\;sysl\\t%0, #3, c7, c7, #1 // gcspopm"
+  [(set_attr "length" "8")]
+)
+
+(define_insn "aarch64_gcspopm_xzr"
+  [(unspec_volatile [(const_int 0)] UNSPECV_GCSPOPM)]
+  ""
+  "sysl\\txzr, #3, c7, c7, #1 // gcspopm"
+)
+
+(define_insn "aarch64_gcsss"
+  [(set (match_operand:DI 0 "register_operand" "=r")
+   (unspec_volatile:DI [(match_operand:DI 1 "register_operand" "r")]
+ UNSPECV_GCSSS))]
+  ""
+  "sys\\t#3, c7, c7, #2, %1 // gcsss1\;mov\\t%0, 0\;sysl\\t%0, #3, c7, c7, #3 
// gcsss2"
+  [(set_attr "length" "12")]
+)
+
 ;; AdvSIMD Stuff
 (include "aarch64-simd.md")


[gcc(refs/vendors/ARM/heads/gcs)] aarch64: Add non-local goto and jump tests for GCS

2024-04-10 Thread Szabolcs Nagy via Gcc-cvs
https://gcc.gnu.org/g:87217fd89a9bd595a58897bafc593a7e25051ee4

commit 87217fd89a9bd595a58897bafc593a7e25051ee4
Author: Szabolcs Nagy 
Date:   Wed Jun 7 10:58:06 2023 +0100

aarch64: Add non-local goto and jump tests for GCS

These are scan asm tests only, relying on existing execution tests
for runtime coverage.

gcc/testsuite/ChangeLog:

* gcc.target/aarch64/gcs-nonlocal-1.c: New test.
* gcc.target/aarch64/gcs-nonlocal-2.c: New test.

Diff:
---
 gcc/testsuite/gcc.target/aarch64/gcs-nonlocal-1.c | 25 +++
 gcc/testsuite/gcc.target/aarch64/gcs-nonlocal-2.c | 21 +++
 2 files changed, 46 insertions(+)

diff --git a/gcc/testsuite/gcc.target/aarch64/gcs-nonlocal-1.c 
b/gcc/testsuite/gcc.target/aarch64/gcs-nonlocal-1.c
new file mode 100644
index 000..821fab816f9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/gcs-nonlocal-1.c
@@ -0,0 +1,25 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mbranch-protection=gcs" } */
+/* { dg-final { scan-assembler-times "hint\\t40 // chkfeat x16" 2 } } */
+/* { dg-final { scan-assembler-times "mrs\\tx\[0-9\]+, s3_3_c2_c5_1 // 
gcspr_el0" 2 } } */
+/* { dg-final { scan-assembler-times "sysl\\txzr, #3, c7, c7, #1 // gcspopm" 1 
} } */
+
+int bar1 (int);
+int bar2 (int);
+
+void foo (int cmd)
+{
+  __label__ start;
+  int x = 0;
+
+  void nonlocal_goto (void)
+  {
+x++;
+goto start;
+  }
+
+start:
+  while (bar1 (x))
+if (bar2 (x))
+  nonlocal_goto ();
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/gcs-nonlocal-2.c 
b/gcc/testsuite/gcc.target/aarch64/gcs-nonlocal-2.c
new file mode 100644
index 000..63dbce36e1e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/gcs-nonlocal-2.c
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mbranch-protection=gcs" } */
+/* { dg-final { scan-assembler-times "hint\\t40 // chkfeat x16" 2 } } */
+/* { dg-final { scan-assembler-times "mrs\\tx\[0-9\]+, s3_3_c2_c5_1 // 
gcspr_el0" 2 } } */
+/* { dg-final { scan-assembler-times "sysl\\txzr, #3, c7, c7, #1 // gcspopm" 1 
} } */
+
+void longj (void *buf)
+{
+  __builtin_longjmp (buf, 1);
+}
+
+void foo (void);
+void bar (void);
+
+void setj (void *buf)
+{
+  if (__builtin_setjmp (buf))
+foo ();
+  else
+bar ();
+}


[gcc(refs/vendors/ARM/heads/gcs)] aarch64: Add __builtin_aarch64_gcs* tests

2024-04-10 Thread Szabolcs Nagy via Gcc-cvs
https://gcc.gnu.org/g:90ff9175ede4f4671755f0296b5ce89d8d69f966

commit 90ff9175ede4f4671755f0296b5ce89d8d69f966
Author: Szabolcs Nagy 
Date:   Tue Jun 6 17:35:51 2023 +0100

aarch64: Add __builtin_aarch64_gcs* tests

gcc/testsuite/ChangeLog:

* gcc.target/aarch64/gcspopm-1.c: New test.
* gcc.target/aarch64/gcspr-1.c: New test.
* gcc.target/aarch64/gcsss-1.c: New test.

Diff:
---
 gcc/testsuite/gcc.target/aarch64/gcspopm-1.c | 69 
 gcc/testsuite/gcc.target/aarch64/gcspr-1.c   | 31 +
 gcc/testsuite/gcc.target/aarch64/gcsss-1.c   | 49 
 3 files changed, 149 insertions(+)

diff --git a/gcc/testsuite/gcc.target/aarch64/gcspopm-1.c 
b/gcc/testsuite/gcc.target/aarch64/gcspopm-1.c
new file mode 100644
index 000..6e6add39cf7
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/gcspopm-1.c
@@ -0,0 +1,69 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mbranch-protection=none" } */
+/* { dg-final { check-function-bodies "**" "" "" } } */
+
+/*
+**foo1:
+** syslxzr, #3, c7, c7, #1 // gcspopm
+** ret
+*/
+void
+foo1 (void)
+{
+  __builtin_aarch64_gcspopm ();
+}
+
+/*
+**foo2:
+** mov x0, 0
+** syslx0, #3, c7, c7, #1 // gcspopm
+** ret
+*/
+unsigned long long
+foo2 (void)
+{
+  return __builtin_aarch64_gcspopm ();
+}
+
+/*
+**foo3:
+** mov x16, 1
+** (
+** mov x0, 0
+** hint40 // chkfeat x16
+** |
+** hint40 // chkfeat x16
+** mov x0, 0
+** )
+** cbz x16, .*
+** ret
+** mov x0, 0
+** syslx0, #3, c7, c7, #1 // gcspopm
+** ret
+*/
+unsigned long long
+foo3 (void)
+{
+  if (__builtin_aarch64_chkfeat (1) == 0)
+return __builtin_aarch64_gcspopm ();
+  return 0;
+}
+
+/*
+**foo4:
+** syslxzr, #3, c7, c7, #1 // gcspopm
+** mov x0, 0
+** syslx0, #3, c7, c7, #1 // gcspopm
+** syslxzr, #3, c7, c7, #1 // gcspopm
+** ret
+*/
+unsigned long long
+foo4 (void)
+{
+  unsigned long long a = __builtin_aarch64_gcspopm ();
+  unsigned long long b = __builtin_aarch64_gcspopm ();
+  unsigned long long c = __builtin_aarch64_gcspopm ();
+  (void) a;
+  (void) c;
+  return b;
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/gcspr-1.c 
b/gcc/testsuite/gcc.target/aarch64/gcspr-1.c
new file mode 100644
index 000..0e651979551
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/gcspr-1.c
@@ -0,0 +1,31 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mbranch-protection=none" } */
+/* { dg-final { check-function-bodies "**" "" "" } } */
+
+/*
+**foo1:
+** mrs x0, s3_3_c2_c5_1 // gcspr_el0
+** ret
+*/
+void *
+foo1 (void)
+{
+  return __builtin_aarch64_gcspr ();
+}
+
+/*
+**foo2:
+** mrs x[0-9]*, s3_3_c2_c5_1 // gcspr_el0
+** syslxzr, #3, c7, c7, #1 // gcspopm
+** mrs x[0-9]*, s3_3_c2_c5_1 // gcspr_el0
+** sub x0, x[0-9]*, x[0-9]*
+** ret
+*/
+long
+foo2 (void)
+{
+  const char *p = __builtin_aarch64_gcspr ();
+  __builtin_aarch64_gcspopm ();
+  const char *q = __builtin_aarch64_gcspr ();
+  return p - q;
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/gcsss-1.c 
b/gcc/testsuite/gcc.target/aarch64/gcsss-1.c
new file mode 100644
index 000..025c7fee647
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/gcsss-1.c
@@ -0,0 +1,49 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mbranch-protection=none" } */
+/* { dg-final { check-function-bodies "**" "" "" } } */
+
+/*
+**foo1:
+** sys #3, c7, c7, #2, x0 // gcsss1
+** mov x[0-9]*, 0
+** syslx[0-9]*, #3, c7, c7, #3 // gcsss2
+** ret
+*/
+void
+foo1 (void *p)
+{
+  __builtin_aarch64_gcsss (p);
+}
+
+/*
+**foo2:
+** sys #3, c7, c7, #2, x0 // gcsss1
+** mov x0, 0
+** syslx0, #3, c7, c7, #3 // gcsss2
+** ret
+*/
+void *
+foo2 (void *p)
+{
+  return __builtin_aarch64_gcsss (p);
+}
+
+/*
+**foo3:
+** mov x16, 1
+** hint40 // chkfeat x16
+** cbnzx16, .*
+** sys #3, c7, c7, #2, x0 // gcsss1
+** mov x0, 0
+** syslx0, #3, c7, c7, #3 // gcsss2
+** ret
+** mov x0, 0
+** ret
+*/
+void *
+foo3 (void *p)
+{
+  if (__builtin_aarch64_chkfeat (1) == 0)
+return __builtin_aarch64_gcsss (p);
+  return 0;
+}


[gcc(refs/vendors/ARM/heads/gcs)] aarch64: Add GCS builtins

2024-04-10 Thread Szabolcs Nagy via Gcc-cvs
https://gcc.gnu.org/g:4880a14b6222839396bcb93ee27669db4e88ff01

commit 4880a14b6222839396bcb93ee27669db4e88ff01
Author: Szabolcs Nagy 
Date:   Tue May 9 16:21:28 2023 +0100

aarch64: Add GCS builtins

Add new builtins for GCS:

  void *__builtin_aarch64_gcspr (void)
  uint64_t __builtin_aarch64_gcspopm (void)
  void *__builtin_aarch64_gcsss (void *)

The builtins are always enabled, but should be used behind runtime
checks in case the target does not support GCS. They are thin
wrappers around the corresponding instructions.

The GCS pointer is modelled with void * type (normal stores do not
work on GCS memory, but it is writable via the gcsss operation or
via GCSSTR if enabled so not const) and an entry on the GCS is
modelled with uint64_t (since it has fixed size and can be a token
that's not a pointer).

gcc/ChangeLog:

* config/aarch64/aarch64-builtins.cc (enum aarch64_builtins): Add
AARCH64_BUILTIN_GCSPR, AARCH64_BUILTIN_GCSPOPM, 
AARCH64_BUILTIN_GCSSS.
(aarch64_init_gcs_builtins): New.
(aarch64_general_init_builtins): Call aarch64_init_gcs_builtins.
(aarch64_expand_gcs_builtin): New.
(aarch64_general_expand_builtin): Call aarch64_expand_gcs_builtin.

Diff:
---
 gcc/config/aarch64/aarch64-builtins.cc | 70 ++
 1 file changed, 70 insertions(+)

diff --git a/gcc/config/aarch64/aarch64-builtins.cc 
b/gcc/config/aarch64/aarch64-builtins.cc
index 1c08f56ab6b..30c977586f9 100644
--- a/gcc/config/aarch64/aarch64-builtins.cc
+++ b/gcc/config/aarch64/aarch64-builtins.cc
@@ -790,6 +790,9 @@ enum aarch64_builtins
   AARCH64_PLIX,
   /* Armv8.9-A / Armv9.4-A builtins.  */
   AARCH64_BUILTIN_CHKFEAT,
+  AARCH64_BUILTIN_GCSPR,
+  AARCH64_BUILTIN_GCSPOPM,
+  AARCH64_BUILTIN_GCSSS,
   AARCH64_BUILTIN_MAX
 };
 
@@ -2041,6 +2044,29 @@ aarch64_init_fpsr_fpcr_builtins (void)
   AARCH64_BUILTIN_SET_FPSR64);
 }
 
+/* Add builtins for Guarded Control Stack instructions.  */
+
+static void
+aarch64_init_gcs_builtins (void)
+{
+  tree ftype;
+
+  ftype = build_function_type_list (ptr_type_node, NULL);
+  aarch64_builtin_decls[AARCH64_BUILTIN_GCSPR]
+= aarch64_general_add_builtin ("__builtin_aarch64_gcspr", ftype,
+  AARCH64_BUILTIN_GCSPR);
+
+  ftype = build_function_type_list (uint64_type_node, NULL);
+  aarch64_builtin_decls[AARCH64_BUILTIN_GCSPOPM]
+= aarch64_general_add_builtin ("__builtin_aarch64_gcspopm", ftype,
+  AARCH64_BUILTIN_GCSPOPM);
+
+  ftype = build_function_type_list (ptr_type_node, ptr_type_node, NULL);
+  aarch64_builtin_decls[AARCH64_BUILTIN_GCSSS]
+= aarch64_general_add_builtin ("__builtin_aarch64_gcsss", ftype,
+  AARCH64_BUILTIN_GCSSS);
+}
+
 /* Initialize all builtins in the AARCH64_BUILTIN_GENERAL group.  */
 
 void
@@ -2092,6 +2118,8 @@ aarch64_general_init_builtins (void)
 = aarch64_general_add_builtin ("__builtin_aarch64_chkfeat", ftype_chkfeat,
   AARCH64_BUILTIN_CHKFEAT);
 
+  aarch64_init_gcs_builtins ();
+
   if (in_lto_p)
 handle_arm_acle_h ();
 }
@@ -3020,6 +3048,43 @@ aarch64_expand_fpsr_fpcr_getter (enum insn_code icode, 
machine_mode mode,
   return op.value;
 }
 
+/* Expand GCS builtin EXP with code FCODE, putting the result
+   int TARGET.  If IGNORE is true the return value is ignored.  */
+
+rtx
+aarch64_expand_gcs_builtin (tree exp, rtx target, int fcode, int ignore)
+{
+  if (fcode == AARCH64_BUILTIN_GCSPR)
+{
+  expand_operand op;
+  create_output_operand (, target, DImode);
+  expand_insn (CODE_FOR_aarch64_load_gcspr, 1, );
+  return op.value;
+}
+  if (fcode == AARCH64_BUILTIN_GCSPOPM && ignore)
+{
+  expand_insn (CODE_FOR_aarch64_gcspopm_xzr, 0, 0);
+  return target;
+}
+  if (fcode == AARCH64_BUILTIN_GCSPOPM)
+{
+  expand_operand op;
+  create_output_operand (, target, Pmode);
+  expand_insn (CODE_FOR_aarch64_gcspopm, 1, );
+  return op.value;
+}
+  if (fcode == AARCH64_BUILTIN_GCSSS)
+{
+  expand_operand ops[2];
+  rtx op1 = expand_normal (CALL_EXPR_ARG (exp, 0));
+  create_output_operand ([0], target, Pmode);
+  create_input_operand ([1], op1, Pmode);
+  expand_insn (CODE_FOR_aarch64_gcsss, 2, ops);
+  return ops[0].value;
+}
+  gcc_unreachable ();
+}
+
 /* Expand an expression EXP that calls built-in function FCODE,
with result going to TARGET if that's convenient.  IGNORE is true
if the result of the builtin is ignored.  */
@@ -3155,6 +3220,11 @@ aarch64_general_expand_builtin (unsigned int fcode, tree 
exp, rtx target,
emit_move_insn (target, x16_reg);
return target;
   }
+
+case AARCH64_BUILTIN_GCSPR:
+case AARCH64_BUILTIN_GCSPOPM

[gcc(refs/vendors/ARM/heads/gcs)] aarch64: Add __builtin_aarch64_chkfeat tests

2024-04-10 Thread Szabolcs Nagy via Gcc-cvs
https://gcc.gnu.org/g:0c0ee07e8b10e071c5b88fbae6f109778a4e578c

commit 0c0ee07e8b10e071c5b88fbae6f109778a4e578c
Author: Szabolcs Nagy 
Date:   Fri Jun 2 16:15:25 2023 +0100

aarch64: Add __builtin_aarch64_chkfeat tests

gcc/testsuite/ChangeLog:

* gcc.target/aarch64/chkfeat-1.c: New test.
* gcc.target/aarch64/chkfeat-2.c: New test.

Diff:
---
 gcc/testsuite/gcc.target/aarch64/chkfeat-1.c | 75 
 gcc/testsuite/gcc.target/aarch64/chkfeat-2.c | 15 ++
 2 files changed, 90 insertions(+)

diff --git a/gcc/testsuite/gcc.target/aarch64/chkfeat-1.c 
b/gcc/testsuite/gcc.target/aarch64/chkfeat-1.c
new file mode 100644
index 000..2fae81e740f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/chkfeat-1.c
@@ -0,0 +1,75 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mbranch-protection=none" } */
+/* { dg-final { check-function-bodies "**" "" "" } } */
+
+/*
+**foo1:
+** mov x16, 1
+** hint40 // chkfeat x16
+** mov x0, x16
+** ret
+*/
+unsigned long long
+foo1 (void)
+{
+  return __builtin_aarch64_chkfeat (1);
+}
+
+/*
+**foo2:
+** mov x16, 1
+** movkx16, 0x5678, lsl 32
+** movkx16, 0x1234, lsl 48
+** hint40 // chkfeat x16
+** mov x0, x16
+** ret
+*/
+unsigned long long
+foo2 (void)
+{
+  return __builtin_aarch64_chkfeat (0x123456780001);
+}
+
+/*
+**foo3:
+** mov x16, x0
+** hint40 // chkfeat x16
+** mov x0, x16
+** ret
+*/
+unsigned long long
+foo3 (unsigned long long x)
+{
+  return __builtin_aarch64_chkfeat (x);
+}
+
+/*
+**foo4:
+** ldr x16, \[x0\]
+** hint40 // chkfeat x16
+** str x16, \[x0\]
+** ret
+*/
+void
+foo4 (unsigned long long *p)
+{
+  *p = __builtin_aarch64_chkfeat (*p);
+}
+
+/*
+**foo5:
+** mov x16, 1
+** hint40 // chkfeat x16
+** cmp x16, 0
+**(
+** cselw0, w1, w0, eq
+**|
+** cselw0, w0, w1, ne
+**)
+** ret
+*/
+int
+foo5 (int x, int y)
+{
+  return __builtin_aarch64_chkfeat (1) ? x : y;
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/chkfeat-2.c 
b/gcc/testsuite/gcc.target/aarch64/chkfeat-2.c
new file mode 100644
index 000..682524e244f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/chkfeat-2.c
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+/* { dg-final { scan-assembler-times {hint\t40 // chkfeat x16} 2 } } */
+
+void bar (void);
+
+/* Extern call may change enabled HW features.  */
+unsigned long long
+foo (void)
+{
+  unsigned long long a = __builtin_aarch64_chkfeat (1);
+  bar ();
+  unsigned long long b = __builtin_aarch64_chkfeat (1);
+  return a + b;
+}


[gcc(refs/vendors/ARM/heads/gcs)] aarch64: Add __builtin_aarch64_chkfeat

2024-04-10 Thread Szabolcs Nagy via Gcc-cvs
https://gcc.gnu.org/g:e26ccd302f4face487da5b530d4dbeb4eebf7d43

commit e26ccd302f4face487da5b530d4dbeb4eebf7d43
Author: Szabolcs Nagy 
Date:   Tue May 9 15:24:18 2023 +0100

aarch64: Add __builtin_aarch64_chkfeat

Builtin for chkfeat: the input argument is used to initialize x16 then
execute chkfeat and return the updated x16.

Note: ACLE __chkfeat(x) plans to flip the bits to be more intuitive
(xor the input to output), but for the builtin that seems unnecessary
complication.

gcc/ChangeLog:

* config/aarch64/aarch64-builtins.cc (enum aarch64_builtins):
Define AARCH64_BUILTIN_CHKFEAT.
(aarch64_general_init_builtins): Handle chkfeat.
(aarch64_general_expand_builtin): Handle chkfeat.

Diff:
---
 gcc/config/aarch64/aarch64-builtins.cc | 18 ++
 1 file changed, 18 insertions(+)

diff --git a/gcc/config/aarch64/aarch64-builtins.cc 
b/gcc/config/aarch64/aarch64-builtins.cc
index 75d21de1401..1c08f56ab6b 100644
--- a/gcc/config/aarch64/aarch64-builtins.cc
+++ b/gcc/config/aarch64/aarch64-builtins.cc
@@ -788,6 +788,8 @@ enum aarch64_builtins
   AARCH64_PLDX,
   AARCH64_PLI,
   AARCH64_PLIX,
+  /* Armv8.9-A / Armv9.4-A builtins.  */
+  AARCH64_BUILTIN_CHKFEAT,
   AARCH64_BUILTIN_MAX
 };
 
@@ -2084,6 +2086,12 @@ aarch64_general_init_builtins (void)
   if (TARGET_MEMTAG)
 aarch64_init_memtag_builtins ();
 
+  tree ftype_chkfeat
+= build_function_type_list (uint64_type_node, uint64_type_node, NULL);
+  aarch64_builtin_decls[AARCH64_BUILTIN_CHKFEAT]
+= aarch64_general_add_builtin ("__builtin_aarch64_chkfeat", ftype_chkfeat,
+  AARCH64_BUILTIN_CHKFEAT);
+
   if (in_lto_p)
 handle_arm_acle_h ();
 }
@@ -3137,6 +3145,16 @@ aarch64_general_expand_builtin (unsigned int fcode, tree 
exp, rtx target,
 case AARCH64_PLIX:
   aarch64_expand_prefetch_builtin (exp, fcode);
   return target;
+
+case AARCH64_BUILTIN_CHKFEAT:
+  {
+   rtx x16_reg = gen_rtx_REG (DImode, R16_REGNUM);
+   op0 = expand_normal (CALL_EXPR_ARG (exp, 0));
+   emit_move_insn (x16_reg, op0);
+   expand_insn (CODE_FOR_aarch64_chkfeat, 0, 0);
+   emit_move_insn (target, x16_reg);
+   return target;
+  }
 }
 
   if (fcode >= AARCH64_SIMD_BUILTIN_BASE && fcode <= AARCH64_SIMD_BUILTIN_MAX)


[gcc(refs/vendors/ARM/heads/gcs)] aarch64: Add support for chkfeat insn

2024-04-10 Thread Szabolcs Nagy via Gcc-cvs
https://gcc.gnu.org/g:309f26c5301d11891a6adddf9515adf5a9b0

commit 309f26c5301d11891a6adddf9515adf5a9b0
Author: Szabolcs Nagy 
Date:   Tue May 9 15:37:49 2023 +0100

aarch64: Add support for chkfeat insn

This is a hint space instruction to check for enabled HW features and
update the x16 register accordingly.

Use unspec_volatile to prevent reordering it around calls since calls
can enable or disable HW features.

gcc/ChangeLog:

* config/aarch64/aarch64.md (aarch64_chkfeat): New.

Diff:
---
 gcc/config/aarch64/aarch64.md | 9 +
 1 file changed, 9 insertions(+)

diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md
index 385a669b9b3..a20462303b5 100644
--- a/gcc/config/aarch64/aarch64.md
+++ b/gcc/config/aarch64/aarch64.md
@@ -378,6 +378,7 @@
 UNSPECV_BTI_C  ; Represent BTI c.
 UNSPECV_BTI_J  ; Represent BTI j.
 UNSPECV_BTI_JC ; Represent BTI jc.
+UNSPECV_CHKFEAT; Represent CHKFEAT X16.
 UNSPECV_TSTART ; Represent transaction start.
 UNSPECV_TCOMMIT; Represent transaction commit.
 UNSPECV_TCANCEL; Represent transaction cancel.
@@ -8258,6 +8259,14 @@
   "msr\tnzcv, %0"
 )
 
+;; CHKFEAT instruction
+(define_insn "aarch64_chkfeat"
+  [(set (reg:DI R16_REGNUM)
+(unspec_volatile:DI [(reg:DI R16_REGNUM)] UNSPECV_CHKFEAT))]
+  ""
+  "hint\\t40 // chkfeat x16"
+)
+
 ;; AdvSIMD Stuff
 (include "aarch64-simd.md")


[gcc(refs/vendors/ARM/heads/gcs)] aarch64: Add target pragma tests for gcs

2024-04-10 Thread Szabolcs Nagy via Gcc-cvs
https://gcc.gnu.org/g:311c3aa1e58672c36991a193db5752d3dcf8e7d9

commit 311c3aa1e58672c36991a193db5752d3dcf8e7d9
Author: Szabolcs Nagy 
Date:   Fri Jun 30 16:50:23 2023 +0100

aarch64: Add target pragma tests for gcs

gcc/testsuite/ChangeLog:

* gcc.target/aarch64/pragma_cpp_predefs_4.c: Add gcs specific
tests.

Diff:
---
 .../gcc.target/aarch64/pragma_cpp_predefs_4.c  | 35 ++
 1 file changed, 35 insertions(+)

diff --git a/gcc/testsuite/gcc.target/aarch64/pragma_cpp_predefs_4.c 
b/gcc/testsuite/gcc.target/aarch64/pragma_cpp_predefs_4.c
index 8e707630774..417293d4d5a 100644
--- a/gcc/testsuite/gcc.target/aarch64/pragma_cpp_predefs_4.c
+++ b/gcc/testsuite/gcc.target/aarch64/pragma_cpp_predefs_4.c
@@ -91,6 +91,9 @@
 #if __ARM_FEATURE_PAC_DEFAULT != 1
 #error Foo
 #endif
+#ifndef __ARM_FEATURE_GCS_DEFAULT
+#error Foo
+#endif
 
 #pragma GCC target ("branch-protection=none")
 #ifdef __ARM_FEATURE_BTI_DEFAULT
@@ -99,6 +102,9 @@
 #ifdef __ARM_FEATURE_PAC_DEFAULT
 #error Foo
 #endif
+#ifdef __ARM_FEATURE_GCS_DEFAULT
+#error Foo
+#endif
 
 #pragma GCC push_options
 #pragma GCC target "branch-protection=bti+pac-ret"
@@ -117,6 +123,9 @@
 #ifdef __ARM_FEATURE_PAC_DEFAULT
 #error Foo
 #endif
+#ifdef __ARM_FEATURE_GCS_DEFAULT
+#error Foo
+#endif
 
 #pragma GCC target "branch-protection=pac-ret"
 #ifdef __ARM_FEATURE_BTI_DEFAULT
@@ -133,3 +142,29 @@
 #if __ARM_FEATURE_PAC_DEFAULT != 6
 #error Foo
 #endif
+
+#pragma GCC target "branch-protection=gcs"
+#ifdef __ARM_FEATURE_BTI_DEFAULT
+#error Foo
+#endif
+#ifdef __ARM_FEATURE_PAC_DEFAULT
+#error Foo
+#endif
+#ifndef __ARM_FEATURE_GCS_DEFAULT
+#error Foo
+#endif
+
+#pragma GCC target "arch=armv8.8-a+gcs"
+#ifndef __ARM_FEATURE_GCS
+#error Foo
+#endif
+
+#pragma GCC target "arch=armv8.8-a+nogcs"
+#ifdef __ARM_FEATURE_GCS
+#error Foo
+#endif
+
+#pragma GCC target "arch=armv8.8-a"
+#ifdef __ARM_FEATURE_GCS
+#error Foo
+#endif


[gcc(refs/vendors/ARM/heads/gcs)] aarch64: Add branch-protection target pragma tests

2024-04-10 Thread Szabolcs Nagy via Gcc-cvs
https://gcc.gnu.org/g:2c160a731e7764e97a2b8014149aaee47a11fbba

commit 2c160a731e7764e97a2b8014149aaee47a11fbba
Author: Szabolcs Nagy 
Date:   Fri Jun 30 16:31:23 2023 +0100

aarch64: Add branch-protection target pragma tests

gcc/testsuite/ChangeLog:

* gcc.target/aarch64/pragma_cpp_predefs_4.c: Add branch-protection
tests.

Diff:
---
 .../gcc.target/aarch64/pragma_cpp_predefs_4.c  | 50 ++
 1 file changed, 50 insertions(+)

diff --git a/gcc/testsuite/gcc.target/aarch64/pragma_cpp_predefs_4.c 
b/gcc/testsuite/gcc.target/aarch64/pragma_cpp_predefs_4.c
index 23ebe5e4f50..8e707630774 100644
--- a/gcc/testsuite/gcc.target/aarch64/pragma_cpp_predefs_4.c
+++ b/gcc/testsuite/gcc.target/aarch64/pragma_cpp_predefs_4.c
@@ -83,3 +83,53 @@
 #ifndef __ARM_FEATURE_SME_F64F64
 #error Foo
 #endif
+
+#pragma GCC target "branch-protection=standard"
+#ifndef __ARM_FEATURE_BTI_DEFAULT
+#error Foo
+#endif
+#if __ARM_FEATURE_PAC_DEFAULT != 1
+#error Foo
+#endif
+
+#pragma GCC target ("branch-protection=none")
+#ifdef __ARM_FEATURE_BTI_DEFAULT
+#error Foo
+#endif
+#ifdef __ARM_FEATURE_PAC_DEFAULT
+#error Foo
+#endif
+
+#pragma GCC push_options
+#pragma GCC target "branch-protection=bti+pac-ret"
+#ifndef __ARM_FEATURE_BTI_DEFAULT
+#error Foo
+#endif
+#pragma GCC pop_options
+#ifdef __ARM_FEATURE_BTI_DEFAULT
+#error Foo
+#endif
+
+#pragma GCC target "branch-protection=bti"
+#ifndef __ARM_FEATURE_BTI_DEFAULT
+#error Foo
+#endif
+#ifdef __ARM_FEATURE_PAC_DEFAULT
+#error Foo
+#endif
+
+#pragma GCC target "branch-protection=pac-ret"
+#ifdef __ARM_FEATURE_BTI_DEFAULT
+#error Foo
+#endif
+#if __ARM_FEATURE_PAC_DEFAULT != 1
+#error Foo
+#endif
+
+#pragma GCC target "branch-protection=pac-ret+leaf+b-key"
+#ifdef __ARM_FEATURE_BTI_DEFAULT
+#error Foo
+#endif
+#if __ARM_FEATURE_PAC_DEFAULT != 6
+#error Foo
+#endif


[gcc(refs/vendors/ARM/heads/gcs)] aarch64: Add -mbranch-protection=gcs option

2024-04-10 Thread Szabolcs Nagy via Gcc-cvs
https://gcc.gnu.org/g:50dc77071139c477a10c78d3d73ff2db4dcd6ef7

commit 50dc77071139c477a10c78d3d73ff2db4dcd6ef7
Author: Szabolcs Nagy 
Date:   Mon Jun 19 12:57:56 2023 +0100

aarch64: Add -mbranch-protection=gcs option

This enables Guarded Control Stack (GCS) compatible code generation.

The "standard" branch-protection type enables it, and the default
depends on the compiler default.

TODO: gcs compatibility marking is missing.

gcc/ChangeLog:

* config/aarch64/aarch64-protos.h (aarch_gcs_enabled): Declare.
* config/aarch64/aarch64.cc (aarch_gcs_enabled): Define.
(aarch_handle_no_branch_protection): Handle gcs.
(aarch_handle_standard_branch_protection): Handle gcs.
(aarch_handle_gcs_protection): New.
* config/aarch64/aarch64.opt: Add aarch_enable_gcs.
* configure: Regenerate.
* configure.ac: Handle gcs in --enable-standard-branch-protection.
* doc/invoke.texi: Document -mbranch-protection=gcs.

Diff:
---
 gcc/config/aarch64/aarch64-protos.h |  2 ++
 gcc/config/aarch64/aarch64.cc   | 24 
 gcc/config/aarch64/aarch64.opt  |  3 +++
 gcc/configure   |  2 +-
 gcc/configure.ac|  2 +-
 gcc/doc/invoke.texi |  5 +++--
 6 files changed, 34 insertions(+), 4 deletions(-)

diff --git a/gcc/config/aarch64/aarch64-protos.h 
b/gcc/config/aarch64/aarch64-protos.h
index 42639e9efcf..ed5f9622658 100644
--- a/gcc/config/aarch64/aarch64-protos.h
+++ b/gcc/config/aarch64/aarch64-protos.h
@@ -1113,4 +1113,6 @@ extern void aarch64_adjust_reg_alloc_order ();
 bool aarch64_optimize_mode_switching (aarch64_mode_entity);
 void aarch64_restore_za (rtx);
 
+extern bool aarch64_gcs_enabled ();
+
 #endif /* GCC_AARCH64_PROTOS_H */
diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc
index 1ea84c8bd73..73969721906 100644
--- a/gcc/config/aarch64/aarch64.cc
+++ b/gcc/config/aarch64/aarch64.cc
@@ -8375,6 +8375,13 @@ aarch_bti_j_insn_p (rtx_insn *insn)
   return GET_CODE (pat) == UNSPEC_VOLATILE && XINT (pat, 1) == UNSPECV_BTI_J;
 }
 
+/* Return TRUE if Guarded Control Stack is enabled.  */
+bool
+aarch64_gcs_enabled (void)
+{
+  return (aarch64_enable_gcs == 1);
+}
+
 /* Check if X (or any sub-rtx of X) is a PACIASP/PACIBSP instruction.  */
 bool
 aarch_pac_insn_p (rtx x)
@@ -18694,6 +18701,7 @@ aarch64_handle_no_branch_protection (void)
 {
   aarch_ra_sign_scope = AARCH_FUNCTION_NONE;
   aarch_enable_bti = 0;
+  aarch64_enable_gcs = 0;
 }
 
 static void
@@ -18702,6 +18710,7 @@ aarch64_handle_standard_branch_protection (void)
   aarch_ra_sign_scope = AARCH_FUNCTION_NON_LEAF;
   aarch64_ra_sign_key = AARCH64_KEY_A;
   aarch_enable_bti = 1;
+  aarch64_enable_gcs = 1;
 }
 
 static void
@@ -18728,6 +18737,11 @@ aarch64_handle_bti_protection (void)
 {
   aarch_enable_bti = 1;
 }
+static void
+aarch64_handle_gcs_protection (void)
+{
+  aarch64_enable_gcs = 1;
+}
 
 static const struct aarch_branch_protect_type aarch64_pac_ret_subtypes[] = {
   { "leaf", false, aarch64_handle_pac_ret_leaf, NULL, 0 },
@@ -18742,6 +18756,7 @@ static const struct aarch_branch_protect_type 
aarch64_branch_protect_types[] =
   { "pac-ret", false, aarch64_handle_pac_ret_protection,
 aarch64_pac_ret_subtypes, ARRAY_SIZE (aarch64_pac_ret_subtypes) },
   { "bti", false, aarch64_handle_bti_protection, NULL, 0 },
+  { "gcs", false, aarch64_handle_gcs_protection, NULL, 0 },
   { NULL, false, NULL, NULL, 0 }
 };
 
@@ -18842,6 +18857,15 @@ aarch64_override_options (void)
 #endif
 }
 
+  if (aarch64_enable_gcs == 2)
+{
+#ifdef TARGET_ENABLE_GCS
+  aarch64_enable_gcs = 1;
+#else
+  aarch64_enable_gcs = 0;
+#endif
+}
+
   /* Return address signing is currently not supported for ILP32 targets.  For
  LP64 targets use the configured option in the absence of a command-line
  option for -mbranch-protection.  */
diff --git a/gcc/config/aarch64/aarch64.opt b/gcc/config/aarch64/aarch64.opt
index 6356c419399..aeb710449fb 100644
--- a/gcc/config/aarch64/aarch64.opt
+++ b/gcc/config/aarch64/aarch64.opt
@@ -39,6 +39,9 @@ aarch64_feature_flags aarch64_isa_flags = 0
 TargetVariable
 unsigned aarch_enable_bti = 2
 
+TargetVariable
+unsigned aarch64_enable_gcs = 2
+
 TargetVariable
 enum aarch64_key_type aarch64_ra_sign_key = AARCH64_KEY_A
 
diff --git a/gcc/configure b/gcc/configure
index 266ab8f84b2..45725639fd2 100755
--- a/gcc/configure
+++ b/gcc/configure
@@ -28221,7 +28221,7 @@ if test "${enable_standard_branch_protection+set}" = 
set; then :
   enableval=$enable_standard_branch_protection;
 case $enableval in
   yes)
-tm_defines="${tm_defines} TARGET_ENABLE_BTI=1 
TARGET_ENABLE_PAC_RET=1"
+tm_defines="${tm_defines} TARGET_ENABLE_BTI=1 
TARGET_ENABLE_PAC_RET=1 TARGET_ENABLE_GC

[gcc/ARM/heads/gcs] (924 commits) aarch64: Introduce indirect_return attribute

2024-04-10 Thread Szabolcs Nagy via Gcc-cvs
The branch 'ARM/heads/gcs' was updated to point to:

 3458fa6e8c3... aarch64: Introduce indirect_return attribute

It previously pointed to:

 7f952ecef18... aarch64: Introduce indirect_return attribute

Diff:

!!! WARNING: THE FOLLOWING COMMITS ARE NO LONGER ACCESSIBLE (LOST):
---

  7f952ec... aarch64: Introduce indirect_return attribute
  af7a4e5... aarch64: libatomic: add GCS marking to asm
  3bdac55... aarch64: libgcc: add GCS marking to asm
  0c8f137... aarch64: Emit GNU property NOTE for GCS
  49b5b4f... aarch64: Add GCS support to the unwinder
  d907060... aarch64: Add test for GCS ACLE defs
  642ea9d... aarch64: Add ACLE feature macros for GCS
  5e09337... aarch64: Add non-local goto and jump tests for GCS
  701b6b5... aarch64: Add GCS support for nonlocal stack save
  5011ae6... aarch64: Add __builtin_aarch64_gcs* tests
  70e678a... aarch64: Add GCS builtins
  9b2e109... aarch64: Add GCS instructions
  f0908f3... aarch64: Add __builtin_aarch64_chkfeat tests
  cd72de0... aarch64: Add __builtin_aarch64_chkfeat
  3e65859... aarch64: Add support for chkfeat insn
  f98aa4a... aarch64: Add target pragma tests for gcs
  76060fa... aarch64: Add branch-protection target pragma tests
  d6f5213... aarch64: Add -mbranch-protection=gcs option
  b8a248a... aarch64,arm: Move branch-protection data to targets


Summary of changes (added commits):
---

  3458fa6... aarch64: Introduce indirect_return attribute
  9f2fe29... aarch64: libitm: Add GCS support
  78b29b5... aarch64: libatomic: add GCS marking to asm
  b32a17f... aarch64: libgcc: add GCS marking to asm
  99a291c... aarch64: Emit GNU property NOTE for GCS
  2185dc7... aarch64: Add GCS support to the unwinder
  2a9d500... aarch64: Add test for GCS ACLE defs
  f94cfda... aarch64: Add ACLE feature macros for GCS
  87217fd... aarch64: Add non-local goto and jump tests for GCS
  d5a22a5... aarch64: Add GCS support for nonlocal stack save
  90ff917... aarch64: Add __builtin_aarch64_gcs* tests
  4880a14... aarch64: Add GCS builtins
  57aec9c... aarch64: Add GCS instructions
  0c0ee07... aarch64: Add __builtin_aarch64_chkfeat tests
  e26ccd3... aarch64: Add __builtin_aarch64_chkfeat
  309f26c... aarch64: Add support for chkfeat insn
  311c3aa... aarch64: Add target pragma tests for gcs
  2c160a7... aarch64: Add branch-protection target pragma tests
  50dc770... aarch64: Add -mbranch-protection=gcs option
  4923ed4... testsuite: Adjust pr113359-2_*.c with unsigned long long [P (*)
  109f1b2... Revert "combine: Don't combine if I2 does not change" (*)
  7924e35... rs6000: Replace OPTION_MASK_DIRECT_MOVE with OPTION_MASK_P8 (*)
  0774240... c++: Keep DECL_SAVED_TREE of cdtor instantiations in module (*)
  ea665f9... [APX] Prohibit SHA/KEYLOCKER usage of EGPR when APX enabled (*)
  77c0b5b... c++: Track declarations imported from partitions [PR99377] (*)
  0753ae1... Daily bump. (*)
  92b38ec... libstdc++: Fix build for targets without FP std::from_chars (*)
  639215c... btf: improve btf-datasec-3.c test [PR114642] (*)
  1f719aa... s390x: Optimize vector permute with constant indexes (*)
  8075477... btf: emit symbol refs in DATASEC entries only for BPF [PR11 (*)
  685d822... aarch64: Fix ACLE SME streaming mode error in neon-sve-brid (*)
  de82b0c... Fortran: Fix ICE in trans-stmt.cc(gfc_trans_call) [PR114535 (*)
  88aea12... Fortran: Fix ICE in gfc_trans_pointer_assignment [PR113956] (*)
  32fb04a... lto/114655 - -flto=4 at link time doesn't override -flto=au (*)
  ce3c743... RTEMS: Fix powerpc configuration (*)
  dd78e6a... Guard function->cond_uids access [PR114601] (*)
  a79d13a... i386: Fix aes/vaes patterns [PR114576] (*)
  897a241... modula2: remove description of fdebug-trace-quad, fdebug-tr (*)
  46120d7... modula2: tidyup makeSystem (*)
  8657d76... LoongArch: Enable switchable target (*)
  73fb0a6... rust: Add rust.install-dvi and rust.install-html rules (*)
  a244755... Generate constant at start of loop, without UB (*)
  2daeb89... Add tree-inlined gconds to caller cond->expr map (*)
  21c9fd9... libquadmath: Provide __BYTE_ORDER, __LITTLE_ENDIAN and __BI (*)
  cfed80b... c++: Fix up maybe_warn_for_constant_evaluated calls [PR1145 (*)
  64aa48c... Fix up duplicated words mostly in comments, part 2 (*)
  7dd1f9d... bitint: Don't move debug stmts from before returns_twice ca (*)
  46c9166... libgcc: Add basic support for aarch64-gnu (GNU/Hurd on AArc (*)
  9670a23... aarch64: Add support for aarch64-gnu (GNU/Hurd on AArch64) (*)
  532c57f... Move GNU/Hurd startfile spec from config/i386/gnu.h to conf (*)
  d76df69... middle-end/114604 - ranger allocates bitmap without initial (*)
  ddee437... RTEMS: Add multilib configuration for aarch64 (*)
  481ba4f... libquadmath: Use soft-fp for sqrtq finite positive argument (*)
  18e94e0... x86: Define __APX_INLINE_ASM_USE_GPR32__ (*)
  9c97de6... testsuite: Add profile_update_atomic check to gcov-20.c [PR (*)
  

Re: [RFC] Linux system call builtins

2024-04-09 Thread Szabolcs Nagy via Gcc
The 04/08/2024 06:19, Matheus Afonso Martins Moreira via Gcc wrote:
> __builtin_linux_system_call(long n, ...)
...
> Calling these builtins will make GCC place all the parameters
> in the correct registers for the system call, emit the appropriate
> instruction for the target architecture and return the result.
> In other words, they would implement the calling convention[1] of
> the Linux system calls.

note: some syscalls / features don't work without asm
(posix thread cancellation, vfork, signal return,..)

and using raw syscalls outside of the single runtime the
application is using is problematic (at least on linux).

>   + It doesn't make sense for libraries to support it
> 
> There are libraries out there that provide
> system call functionality. The various libcs do.
> However they usually don't support the full set
> of Linux system calls. Using certain system calls
> could invalidate global state in these libraries
> which leads to them not being supported. Clone is
> the quintessential example. So I think libraries
> are not the proper place for this functionality.

i don't follow the reasoning here, where should the
syscall be if not in a library like libc?

clone cannot even be used from c code in general as
CLONE_VM is not compatible with c semantics without
a new stack (child clobbers the parent stack), so
the c builtin would not always work, but it is also
a syscall that only freestanding application can use
not something that calls into the libc, and even in
a freestanding application it is tricky to use right
(especially in a portable way or with features like
shadow stack), so i don't see why clone is the
quintessential example.

>   + It allows freestanding software to easily target Linux
> 
> Freestanding code usually refers to bare metal
> targets but Linux is also a viable target.
> This will make it much easier for developers
> to create freestanding nolibc no dependency
> software targeting Linux without having to
> write any assembly code at all, making GCC
> ever more useful.

i think the asm call convention bit is by far not the
hardest part in providing portable linux syscall wrappers.

my main worry is that the builtins encourage the use of raw
syscalls and outside of libc development it is not well
understood how to do that correctly, but i guess it's ok if
it is by default an error outside of -ffreestanding.


[gcc r14-9426] aarch64,arm: Move branch-protection data to targets

2024-03-11 Thread Szabolcs Nagy via Gcc-cvs
https://gcc.gnu.org/g:1bf70e68e4910fe0904466d06cae7f747c02ab72

commit r14-9426-g1bf70e68e4910fe0904466d06cae7f747c02ab72
Author: Szabolcs Nagy 
Date:   Mon Jun 19 12:56:41 2023 +0100

aarch64,arm: Move branch-protection data to targets

The branch-protection types are target specific, not the same on arm
and aarch64.  This currently affects pac-ret+b-key, but there will be
a new type on aarch64 that is not relevant for arm.

After the move, change aarch_ identifiers to aarch64_ or arm_ as
appropriate.

Refactor aarch_validate_mbranch_protection to take the target specific
branch-protection types as an argument.

In case of invalid input currently no hints are provided: the way
branch-protection types and subtypes can be mixed makes it difficult
without causing confusion.

gcc/ChangeLog:

* config/aarch64/aarch64.md: Rename aarch_ to aarch64_.
* config/aarch64/aarch64.opt: Likewise.
* config/aarch64/aarch64-c.cc (aarch64_update_cpp_builtins): 
Likewise.
* config/aarch64/aarch64.cc (aarch64_expand_prologue): Likewise.
(aarch64_expand_epilogue): Likewise.
(aarch64_post_cfi_startproc): Likewise.
(aarch64_handle_no_branch_protection): Copy and rename.
(aarch64_handle_standard_branch_protection): Likewise.
(aarch64_handle_pac_ret_protection): Likewise.
(aarch64_handle_pac_ret_leaf): Likewise.
(aarch64_handle_pac_ret_b_key): Likewise.
(aarch64_handle_bti_protection): Likewise.
(aarch64_override_options): Update branch protection validation.
(aarch64_handle_attr_branch_protection): Likewise.
* config/arm/aarch-common-protos.h 
(aarch_validate_mbranch_protection):
Pass branch protection type description as argument.
(struct aarch_branch_protect_type): Move from aarch-common.h.
* config/arm/aarch-common.cc (aarch_handle_no_branch_protection):
Remove.
(aarch_handle_standard_branch_protection): Remove.
(aarch_handle_pac_ret_protection): Remove.
(aarch_handle_pac_ret_leaf): Remove.
(aarch_handle_pac_ret_b_key): Remove.
(aarch_handle_bti_protection): Remove.
(aarch_validate_mbranch_protection): Pass branch protection type
description as argument.
* config/arm/aarch-common.h (enum aarch_key_type): Remove.
(struct aarch_branch_protect_type): Remove.
* config/arm/arm-c.cc (arm_cpu_builtins): Remove aarch_ra_sign_key.
* config/arm/arm.cc (arm_handle_no_branch_protection): Copy and 
rename.
(arm_handle_standard_branch_protection): Likewise.
(arm_handle_pac_ret_protection): Likewise.
(arm_handle_pac_ret_leaf): Likewise.
(arm_handle_bti_protection): Likewise.
(arm_configure_build_target): Update branch protection validation.
* config/arm/arm.opt: Remove aarch_ra_sign_key.

Diff:
---
 gcc/config/aarch64/aarch64-c.cc  |  4 +-
 gcc/config/aarch64/aarch64.cc| 75 +++-
 gcc/config/aarch64/aarch64.md|  2 +-
 gcc/config/aarch64/aarch64.opt   |  2 +-
 gcc/config/arm/aarch-common-protos.h | 19 -
 gcc/config/arm/aarch-common.cc   | 71 +-
 gcc/config/arm/aarch-common.h| 20 --
 gcc/config/arm/arm-c.cc  |  2 -
 gcc/config/arm/arm.cc| 55 ++
 gcc/config/arm/arm.opt   |  3 --
 10 files changed, 145 insertions(+), 108 deletions(-)

diff --git a/gcc/config/aarch64/aarch64-c.cc b/gcc/config/aarch64/aarch64-c.cc
index c3bc8c49034..b5a6917d06d 100644
--- a/gcc/config/aarch64/aarch64-c.cc
+++ b/gcc/config/aarch64/aarch64-c.cc
@@ -235,9 +235,9 @@ aarch64_update_cpp_builtins (cpp_reader *pfile)
   if (aarch_ra_sign_scope != AARCH_FUNCTION_NONE)
 {
   int v = 0;
-  if (aarch_ra_sign_key == AARCH_KEY_A)
+  if (aarch64_ra_sign_key == AARCH64_KEY_A)
v |= 1;
-  if (aarch_ra_sign_key == AARCH_KEY_B)
+  if (aarch64_ra_sign_key == AARCH64_KEY_B)
v |= 2;
   if (aarch_ra_sign_scope == AARCH_FUNCTION_ALL)
v |= 4;
diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc
index 0a28e033088..ae040781c43 100644
--- a/gcc/config/aarch64/aarch64.cc
+++ b/gcc/config/aarch64/aarch64.cc
@@ -9541,12 +9541,12 @@ aarch64_expand_prologue (void)
   /* Sign return address for functions.  */
   if (aarch64_return_address_signing_enabled ())
 {
-  switch (aarch_ra_sign_key)
+  switch (aarch64_ra_sign_key)
{
- case AARCH_KEY_A:
+ case AARCH64_KEY_A:
insn = emit_insn (gen_paciasp ());
break;
- case AARCH_KEY_B:
+ case AARCH64_KEY_B:
insn = emit_insn

[PATCH] aarch64: libgcc: Cleanup ELF marking in asm

2024-01-30 Thread Szabolcs Nagy
Use aarch64-asm.h in asm code consistently, this was started in

  commit c608ada288ced0268c1fd4136f56c34b24d4
  Author: Zac Walker 
  CommitDate: 2024-01-23 15:32:30 +

  Ifdef `.hidden`, `.type`, and `.size` pseudo-ops for `aarch64-w64-mingw32` 
target

But that commit failed to remove some existing markings from asm files,
which means some objects got double marked with gnu property notes.

libgcc/ChangeLog:

* config/aarch64/crti.S: Remove stack marking.
* config/aarch64/crtn.S: Remove stack marking, include aarch64-asm.h
* config/aarch64/lse.S: Remove stack and GNU property markings.
---
 libgcc/config/aarch64/crti.S |  6 --
 libgcc/config/aarch64/crtn.S |  6 +-
 libgcc/config/aarch64/lse.S  | 40 
 3 files changed, 1 insertion(+), 51 deletions(-)

diff --git a/libgcc/config/aarch64/crti.S b/libgcc/config/aarch64/crti.S
index b6805b86421..52ca1bb56d6 100644
--- a/libgcc/config/aarch64/crti.S
+++ b/libgcc/config/aarch64/crti.S
@@ -23,12 +23,6 @@
 
 #include "aarch64-asm.h"
 
-/* An executable stack is *not* required for these functions.  */
-#if defined(__ELF__) && defined(__linux__)
-.section .note.GNU-stack,"",%progbits
-.previous
-#endif
-
 # This file creates a stack frame for the contents of the .fini and
 # .init sections.  Users may put any desired instructions in those
 # sections.
diff --git a/libgcc/config/aarch64/crtn.S b/libgcc/config/aarch64/crtn.S
index 59f2441032a..67bcfab8564 100644
--- a/libgcc/config/aarch64/crtn.S
+++ b/libgcc/config/aarch64/crtn.S
@@ -21,11 +21,7 @@
 # see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
 # .
 
-/* An executable stack is *not* required for these functions.  */
-#if defined(__ELF__) && defined(__linux__)
-.section .note.GNU-stack,"",%progbits
-.previous
-#endif
+#include "aarch64-asm.h"
 
 # This file just makes sure that the .fini and .init sections do in
 # fact return.  Users may put any desired instructions in those sections.
diff --git a/libgcc/config/aarch64/lse.S b/libgcc/config/aarch64/lse.S
index cee1e88c6a4..ecef47086c6 100644
--- a/libgcc/config/aarch64/lse.S
+++ b/libgcc/config/aarch64/lse.S
@@ -315,43 +315,3 @@ STARTFNNAME(LDNM)
 
 ENDFN  NAME(LDNM)
 #endif
-
-/* GNU_PROPERTY_AARCH64_* macros from elf.h for use in asm code.  */
-#define FEATURE_1_AND 0xc000
-#define FEATURE_1_BTI 1
-#define FEATURE_1_PAC 2
-
-/* Supported features based on the code generation options.  */
-#if defined(__ARM_FEATURE_BTI_DEFAULT)
-# define BTI_FLAG FEATURE_1_BTI
-#else
-# define BTI_FLAG 0
-#endif
-
-#if __ARM_FEATURE_PAC_DEFAULT & 3
-# define PAC_FLAG FEATURE_1_PAC
-#else
-# define PAC_FLAG 0
-#endif
-
-/* Add a NT_GNU_PROPERTY_TYPE_0 note.  */
-#define GNU_PROPERTY(type, value)  \
-  .section .note.gnu.property, "a";\
-  .p2align 3;  \
-  .word 4; \
-  .word 16;\
-  .word 5; \
-  .asciz "GNU";\
-  .word type;  \
-  .word 4; \
-  .word value; \
-  .word 0;
-
-#if defined(__linux__) || defined(__FreeBSD__)
-.section .note.GNU-stack, "", %progbits
-
-/* Add GNU property note if built with branch protection.  */
-# if (BTI_FLAG|PAC_FLAG) != 0
-GNU_PROPERTY (FEATURE_1_AND, BTI_FLAG|PAC_FLAG)
-# endif
-#endif
-- 
2.25.1



Re: [RFC] Either fix or disable SME feature for `aarch64-w64-mingw32` target?

2024-01-25 Thread Szabolcs Nagy
this patch added double notes on crt*.o and lse derived objects.
(which does not seem to cause build break but some linkers may
not like it)

after #include "aarch64-asm.h" all gnu-stack and gnu-property
related stuff should be removed since the header takes care of it.





Re: [RFC] Either fix or disable SME feature for `aarch64-w64-mingw32` target?

2024-01-25 Thread Szabolcs Nagy
The 01/15/2024 17:21, Radek Barton wrote:


v4-0001-Ifdef-.hidden-.type-and-.size-pseudo-ops-for-aarc.patch
Description: v4-0001-Ifdef-.hidden-.type-and-.size-pseudo-ops-for-aarc.patch


[PATCH v2] aarch64: Fix eh_return for -mtrack-speculation [PR112987]

2024-01-25 Thread Szabolcs Nagy
Recent commit introduced a conditional branch in eh_return epilogues
that is not compatible with speculation tracking:

  commit 426fddcbdad6746fe70e031f707fb07f55dfb405
  Author: Szabolcs Nagy 
  CommitDate: 2023-11-27 15:52:48 +

  aarch64: Use br instead of ret for eh_return

Refactor the compare zero and jump pattern and use it to fix the issue.

gcc/ChangeLog:

PR target/112987
* config/aarch64/aarch64.cc (aarch64_gen_compare_zero_and_branch): New.
(aarch64_expand_epilogue): Use the new function.
(aarch64_split_compare_and_swap): Likewise.
(aarch64_split_atomic_op): Likewise.
---
v2: factor out aarch64_gen_compare_zero_and_branch

 gcc/config/aarch64/aarch64.cc | 75 +++
 1 file changed, 32 insertions(+), 43 deletions(-)

diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc
index 3d6dd98c5c5..d2014ce1527 100644
--- a/gcc/config/aarch64/aarch64.cc
+++ b/gcc/config/aarch64/aarch64.cc
@@ -2637,6 +2637,28 @@ aarch64_gen_compare_reg_maybe_ze (RTX_CODE code, rtx x, 
rtx y,
   return aarch64_gen_compare_reg (code, x, y);
 }
 
+/* Generate conditional branch to LABEL, comparing X to 0 using CODE.
+   Return the jump instruction.  */
+
+static rtx
+aarch64_gen_compare_zero_and_branch (rtx_code code, rtx x,
+rtx_code_label *label)
+{
+  if (aarch64_track_speculation)
+{
+  /* Emit an explicit compare instruction, so that we can correctly
+track the condition codes.  */
+  rtx cc_reg = aarch64_gen_compare_reg (code, x, const0_rtx);
+  x = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
+}
+  else
+x = gen_rtx_fmt_ee (code, VOIDmode, x, const0_rtx);
+
+  x = gen_rtx_IF_THEN_ELSE (VOIDmode, x,
+   gen_rtx_LABEL_REF (Pmode, label), pc_rtx);
+  return gen_rtx_SET (pc_rtx, x);
+}
+
 /* Consider the operation:
 
  OPERANDS[0] = CODE (OPERANDS[1], OPERANDS[2]) + OPERANDS[3]
@@ -9882,11 +9904,10 @@ aarch64_expand_epilogue (rtx_call_insn *sibcall)
 to be SP; letting the CFA move during this adjustment
 is just as correct as retaining the CFA from the body
 of the function.  Therefore, do nothing special.  */
-  rtx label = gen_label_rtx ();
-  rtx x = gen_rtx_EQ (VOIDmode, EH_RETURN_TAKEN_RTX, const0_rtx);
-  x = gen_rtx_IF_THEN_ELSE (VOIDmode, x,
-   gen_rtx_LABEL_REF (Pmode, label), pc_rtx);
-  rtx jump = emit_jump_insn (gen_rtx_SET (pc_rtx, x));
+  rtx_code_label *label = gen_label_rtx ();
+  rtx x = aarch64_gen_compare_zero_and_branch (EQ, EH_RETURN_TAKEN_RTX,
+  label);
+  rtx jump = emit_jump_insn (x);
   JUMP_LABEL (jump) = label;
   LABEL_NUSES (label)++;
   emit_insn (gen_add2_insn (stack_pointer_rtx,
@@ -24657,19 +24678,8 @@ aarch64_split_compare_and_swap (rtx operands[])
 
   if (!is_weak)
 {
-  if (aarch64_track_speculation)
-   {
- /* Emit an explicit compare instruction, so that we can correctly
-track the condition codes.  */
- rtx cc_reg = aarch64_gen_compare_reg (NE, scratch, const0_rtx);
- x = gen_rtx_NE (GET_MODE (cc_reg), cc_reg, const0_rtx);
-   }
-  else
-   x = gen_rtx_NE (VOIDmode, scratch, const0_rtx);
-
-  x = gen_rtx_IF_THEN_ELSE (VOIDmode, x,
-   gen_rtx_LABEL_REF (Pmode, label1), pc_rtx);
-  aarch64_emit_unlikely_jump (gen_rtx_SET (pc_rtx, x));
+  x = aarch64_gen_compare_zero_and_branch (NE, scratch, label1);
+  aarch64_emit_unlikely_jump (x);
 }
   else
 aarch64_gen_compare_reg (NE, scratch, const0_rtx);
@@ -24685,18 +24695,8 @@ aarch64_split_compare_and_swap (rtx operands[])
   emit_label (label2);
   aarch64_emit_store_exclusive (mode, scratch, mem, rval, model_rtx);
 
-  if (aarch64_track_speculation)
-   {
- /* Emit an explicit compare instruction, so that we can correctly
-track the condition codes.  */
- rtx cc_reg = aarch64_gen_compare_reg (NE, scratch, const0_rtx);
- x = gen_rtx_NE (GET_MODE (cc_reg), cc_reg, const0_rtx);
-   }
-  else
-   x = gen_rtx_NE (VOIDmode, scratch, const0_rtx);
-  x = gen_rtx_IF_THEN_ELSE (VOIDmode, x,
-   gen_rtx_LABEL_REF (Pmode, label1), pc_rtx);
-  aarch64_emit_unlikely_jump (gen_rtx_SET (pc_rtx, x));
+  x = aarch64_gen_compare_zero_and_branch (NE, scratch, label1);
+  aarch64_emit_unlikely_jump (x);
 
   label2 = label3;
 }
@@ -24780,19 +24780,8 @@ aarch64_split_atomic_op (enum rtx_code code, rtx 
old_out, rtx new_out, rtx mem,
   aarch64_emit_store_exclusive (mode, cond, mem,
gen_lowpart (mode, new_out), model_rtx);
 
-  if (aarch64_track_speculation)
-{
-  /* Emit an explicit compare instruction, so that we can correctly
-track

[PATCH] aarch64: Fix eh_return for -mtrack-speculation [PR112987]

2024-01-17 Thread Szabolcs Nagy
Recent commit introduced a conditional branch in eh_return epilogues
that is not compatible with speculation tracking:

  commit 426fddcbdad6746fe70e031f707fb07f55dfb405
  Author: Szabolcs Nagy 
  CommitDate: 2023-11-27 15:52:48 +

  aarch64: Use br instead of ret for eh_return

gcc/ChangeLog:

PR target/112987
* config/aarch64/aarch64.cc (aarch64_expand_epilogue): Use
explicit compare and separate jump with speculation tracking.
---
 gcc/config/aarch64/aarch64.cc | 12 +++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc
index e6bd3fd0bb4..e6de62dc02a 100644
--- a/gcc/config/aarch64/aarch64.cc
+++ b/gcc/config/aarch64/aarch64.cc
@@ -9879,7 +9879,17 @@ aarch64_expand_epilogue (rtx_call_insn *sibcall)
 is just as correct as retaining the CFA from the body
 of the function.  Therefore, do nothing special.  */
   rtx label = gen_label_rtx ();
-  rtx x = gen_rtx_EQ (VOIDmode, EH_RETURN_TAKEN_RTX, const0_rtx);
+  rtx x;
+  if (aarch64_track_speculation)
+   {
+ /* Emit an explicit compare, so cc can be tracked.  */
+ rtx cc_reg = aarch64_gen_compare_reg (EQ,
+   EH_RETURN_TAKEN_RTX,
+   const0_rtx);
+ x = gen_rtx_EQ (GET_MODE (cc_reg), cc_reg, const0_rtx);
+   }
+  else
+   x = gen_rtx_EQ (VOIDmode, EH_RETURN_TAKEN_RTX, const0_rtx);
   x = gen_rtx_IF_THEN_ELSE (VOIDmode, x,
gen_rtx_LABEL_REF (Pmode, label), pc_rtx);
   rtx jump = emit_jump_insn (gen_rtx_SET (pc_rtx, x));
-- 
2.25.1



Re: New TLS usage in libgcc_s.so.1, compatibility impact

2024-01-15 Thread Szabolcs Nagy via Gcc
The 01/13/2024 13:49, Florian Weimer wrote:
> This commit
> 
> commit 8abddb187b33480d8827f44ec655f45734a1749d
> Author: Andrew Burgess 
> Date:   Sat Aug 5 14:31:06 2023 +0200
> 
> libgcc: support heap-based trampolines
> 
> Add support for heap-based trampolines on x86_64-linux, aarch64-linux,
> and x86_64-darwin. Implement the __builtin_nested_func_ptr_created and
> __builtin_nested_func_ptr_deleted functions for these targets.
> 
> Co-Authored-By: Maxim Blinov 
> Co-Authored-By: Iain Sandoe 
> Co-Authored-By: Francois-Xavier Coudert 
> 
> added TLS usage to libgcc_s.so.1.  The way that libgcc_s is currently
> built, it ends up using a dynamic TLS variant on the Linux targets.
> This means that there is no up-front TLS allocation with glibc (but
> there would be one with musl).
> 
> There is still a compatibility impact because glibc assigns a TLS module
> ID upfront.  This seems to be what causes the
> ust/libc-wrapper/test_libc-wrapper test in lttng-tools to fail.  We end
> up with an infinite regress during process termination because
> libgcc_s.so.1 has been loaded, resulting in a DTV update.  When this
> happens, the bottom of the stack looks like this:
> 
> #4447 0x77f288f0 in free () from /lib64/liblttng-ust-libc-wrapper.so.1
> #4448 0x77fdb142 in free (ptr=)
> at ../include/rtld-malloc.h:50
> #4449 _dl_update_slotinfo (req_modid=3, new_gen=2) at ../elf/dl-tls.c:822
> #4450 0x77fdb214 in update_get_addr (ti=0x77f2bfc0, 
> gen=) at ../elf/dl-tls.c:916
> #4451 0x77fddccc in __tls_get_addr ()
> at ../sysdeps/x86_64/tls_get_addr.S:55
> #4452 0x77f288f0 in free () from /lib64/liblttng-ust-libc-wrapper.so.1
> #4453 0x77fdb142 in free (ptr=)
> at ../include/rtld-malloc.h:50
> #4454 _dl_update_slotinfo (req_modid=2, new_gen=2) at ../elf/dl-tls.c:822
> #4455 0x77fdb214 in update_get_addr (ti=0x77f39fa0, 
> gen=) at ../elf/dl-tls.c:916
> #4456 0x77fddccc in __tls_get_addr ()
> at ../sysdeps/x86_64/tls_get_addr.S:55
> #4457 0x77f36113 in lttng_ust_cancelstate_disable_push ()
>from /lib64/liblttng-ust-common.so.1
> #4458 0x77f4c2e8 in ust_lock_nocheck () from /lib64/liblttng-ust.so.1
> #4459 0x77f5175a in lttng_ust_cleanup () from /lib64/liblttng-ust.so.1
> #4460 0x77fca0f2 in _dl_call_fini (
> closure_map=closure_map@entry=0x77fbe000) at dl-call_fini.c:43
> #4461 0x77fce06e in _dl_fini () at dl-fini.c:114
> #4462 0x77d82fe6 in __run_exit_handlers () from /lib64/libc.so.6
> 
> Cc:ing  for awareness.
> 
> The issue also requires a recent glibc with changes to DTV management:
> commit d2123d68275acc0f061e73d5f86ca504e0d5a344 ("elf: Fix slow tls
> access after dlopen [BZ #19924]").  If I understand things correctly,
> before this glibc change, we didn't deallocate the old DTV, so there was
> no call to the free function.

with 19924 fixed, after a dlopen or dlclose every thread updates
its dtv on the next dynamic tls access.

before that, dtv was only updated up to the generation of the
module being accessed for a particular tls access.

so hitting the free in the dtv update path is now more likely
but the free is not new, it was there before.

also note that this is unlikely to happen on aarch64 since
tlsdesc only does dynamic tls access after a 512byte static
tls reservation runs out.

> 
> On the glibc side, we should recommend that intercepting mallocs and its
> dependencies use initial-exec TLS because that kind of TLS does not use
> malloc.  If intercepting mallocs using dynamic TLS work at all, that's
> totally by accident, and was in the past helped by glibc bug 19924.  (I

right.

> don't think there is anything special about libgcc_s.so.1 that triggers
> the test failure above, it is just an object with dynamic TLS that is
> implicitly loaded via dlopen at the right stage of the test.)  In this
> particular case, we can also paper over the test failure in glibc by not
> call free at all because the argument is a null pointer:
> 
> diff --git a/elf/dl-tls.c b/elf/dl-tls.c
> index 7b3dd9ab60..14c71cbd06 100644
> --- a/elf/dl-tls.c
> +++ b/elf/dl-tls.c
> @@ -819,7 +819,8 @@ _dl_update_slotinfo (unsigned long int req_modid, size_t 
> new_gen)
>dtv entry free it.  Note: this is not AS-safe.  */
> /* XXX Ideally we will at some point create a memory
>pool.  */
> -   free (dtv[modid].pointer.to_free);
> +   if (dtv[modid].pointer.to_free != NULL)
> + free (dtv[modid].pointer.to_free);
> dtv[modid].pointer.val = TLS_DTV_UNALLOCATED;
> dtv[modid].pointer.to_free = NULL;

can be done, but !=NULL is more likely since we do modid reuse
after dlclose.

there is also a realloc in dtv resizing which happens when more
than 16 modules with tls are loaded after thread creation
(DTV_SURPLUS).

i'm not sure if it's worth supporting 

Re: [PATCH v2 7/7] aarch64,arm: Move branch-protection data to targets

2024-01-11 Thread Szabolcs Nagy
The 12/07/2023 13:13, Richard Earnshaw wrote:
> On 03/11/2023 15:36, Szabolcs Nagy wrote:
> > * config/aarch64/aarch64.cc (aarch_handle_no_branch_protection): Copy.
> > (aarch_handle_standard_branch_protection): Copy.
> > (aarch_handle_pac_ret_protection): Copy.
> > (aarch_handle_pac_ret_leaf): Copy.
> > (aarch_handle_pac_ret_b_key): Copy.
> > (aarch_handle_bti_protection): Copy.
> 
> I think all of the above functions that have been moved back from
> aarch-common should be renamed back to aarch64_..., unless they are directly
> referenced statically by code in aarch-common.c.

done.

> > +const struct aarch_branch_protect_type aarch_branch_protect_types[] = {
> 
> can this be made static now?  And maybe pass the structure as a parameter if
> that's not done already.

done in v4.

> It would be nice if, when we raise an error, we could print out the list of
> valid options (and modifiers), much like we do on Arm for -march/-mcpu.
> 
> eg.
> $ gcc -mcpu=crotex-a8
> cc1: error: unrecognised -mcpu target: crotex-a8
> cc1: note: valid arguments are: arm8 arm810 strongarm strongarm110 fa526
> [...rest of list]; did you mean ‘cortex-a8’?

i implemented this with candidates_list_and_hint but it does
not work very well if the typo is in a subtype, so i think
this should be done in a separate patch if at all.



[PATCH v4] aarch64,arm: Move branch-protection data to targets

2024-01-11 Thread Szabolcs Nagy
The branch-protection types are target specific, not the same on arm
and aarch64.  This currently affects pac-ret+b-key, but there will be
a new type on aarch64 that is not relevant for arm.

After the move, change aarch_ identifiers to aarch64_ or arm_ as
appropriate.

Refactor aarch_validate_mbranch_protection to take the target specific
branch-protection types as an argument.

In case of invalid input currently no hints are provided: the way
branch-protection types and subtypes can be mixed makes it difficult
without causing confusion.

gcc/ChangeLog:

* config/aarch64/aarch64.md: Rename aarch_ to aarch64_.
* config/aarch64/aarch64.opt: Likewise.
* config/aarch64/aarch64-c.cc (aarch64_update_cpp_builtins): Likewise.
* config/aarch64/aarch64.cc (aarch64_expand_prologue): Likewise.
(aarch64_expand_epilogue): Likewise.
(aarch64_post_cfi_startproc): Likewise.
(aarch64_handle_no_branch_protection): Copy and rename.
(aarch64_handle_standard_branch_protection): Likewise.
(aarch64_handle_pac_ret_protection): Likewise.
(aarch64_handle_pac_ret_leaf): Likewise.
(aarch64_handle_pac_ret_b_key): Likewise.
(aarch64_handle_bti_protection): Likewise.
(aarch64_override_options): Update branch protection validation.
(aarch64_handle_attr_branch_protection): Likewise.
* config/arm/aarch-common-protos.h (aarch_validate_mbranch_protection):
Pass branch protection type description as argument.
(struct aarch_branch_protect_type): Move from aarch-common.h.
* config/arm/aarch-common.cc (aarch_handle_no_branch_protection):
Remove.
(aarch_handle_standard_branch_protection): Remove.
(aarch_handle_pac_ret_protection): Remove.
(aarch_handle_pac_ret_leaf): Remove.
(aarch_handle_pac_ret_b_key): Remove.
(aarch_handle_bti_protection): Remove.
(aarch_validate_mbranch_protection): Pass branch protection type
description as argument.
* config/arm/aarch-common.h (enum aarch_key_type): Remove.
(struct aarch_branch_protect_type): Remove.
* config/arm/arm-c.cc (arm_cpu_builtins): Remove aarch_ra_sign_key.
* config/arm/arm.cc (arm_handle_no_branch_protection): Copy and rename.
(arm_handle_standard_branch_protection): Likewise.
(arm_handle_pac_ret_protection): Likewise.
(arm_handle_pac_ret_leaf): Likewise.
(arm_handle_bti_protection): Likewise.
(arm_configure_build_target): Update branch protection validation.
* config/arm/arm.opt: Remove aarch_ra_sign_key.
---
v4:
- pass types as argument to validation.
- make target specific types data static.

 gcc/config/aarch64/aarch64-c.cc  |  4 +-
 gcc/config/aarch64/aarch64.cc| 75 
 gcc/config/aarch64/aarch64.md|  2 +-
 gcc/config/aarch64/aarch64.opt   |  2 +-
 gcc/config/arm/aarch-common-protos.h | 19 ++-
 gcc/config/arm/aarch-common.cc   | 71 --
 gcc/config/arm/aarch-common.h| 20 
 gcc/config/arm/arm-c.cc  |  2 -
 gcc/config/arm/arm.cc| 55 +---
 gcc/config/arm/arm.opt   |  3 --
 10 files changed, 145 insertions(+), 108 deletions(-)

diff --git a/gcc/config/aarch64/aarch64-c.cc b/gcc/config/aarch64/aarch64-c.cc
index c3bc8c49034..b5a6917d06d 100644
--- a/gcc/config/aarch64/aarch64-c.cc
+++ b/gcc/config/aarch64/aarch64-c.cc
@@ -235,9 +235,9 @@ aarch64_update_cpp_builtins (cpp_reader *pfile)
   if (aarch_ra_sign_scope != AARCH_FUNCTION_NONE)
 {
   int v = 0;
-  if (aarch_ra_sign_key == AARCH_KEY_A)
+  if (aarch64_ra_sign_key == AARCH64_KEY_A)
v |= 1;
-  if (aarch_ra_sign_key == AARCH_KEY_B)
+  if (aarch64_ra_sign_key == AARCH64_KEY_B)
v |= 2;
   if (aarch_ra_sign_scope == AARCH_FUNCTION_ALL)
v |= 4;
diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc
index a5a6b52730d..3ae8fc1878f 100644
--- a/gcc/config/aarch64/aarch64.cc
+++ b/gcc/config/aarch64/aarch64.cc
@@ -9478,12 +9478,12 @@ aarch64_expand_prologue (void)
   /* Sign return address for functions.  */
   if (aarch64_return_address_signing_enabled ())
 {
-  switch (aarch_ra_sign_key)
+  switch (aarch64_ra_sign_key)
{
- case AARCH_KEY_A:
+ case AARCH64_KEY_A:
insn = emit_insn (gen_paciasp ());
break;
- case AARCH_KEY_B:
+ case AARCH64_KEY_B:
insn = emit_insn (gen_pacibsp ());
break;
  default:
@@ -9897,12 +9897,12 @@ aarch64_expand_epilogue (rtx_call_insn *sibcall)
   if (aarch64_return_address_signing_enabled ()
   && (sibcall || !TARGET_ARMV8_3))
 {
-  switch (aarch_ra_sign_key)
+  switch (aarch64_ra_sign_key)
{
- case AARCH_KEY_A:
+ case AARCH64_KEY_A:
insn = emit_insn (gen_autiasp 

[PATCH] aarch64: fortran: Adjust vect-8.f90 for libmvec

2023-12-28 Thread Szabolcs Nagy
With new glibc one more loop can be vectorized via simd exp in libmvec.

Found by the Linaro TCWG CI.

gcc/testsuite/ChangeLog:

* gfortran/vect/vect-8.f90: Accept more vectorized loops.
---
 gcc/testsuite/gfortran.dg/vect/vect-8.f90 | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/gcc/testsuite/gfortran.dg/vect/vect-8.f90 
b/gcc/testsuite/gfortran.dg/vect/vect-8.f90
index ca72ddcffca..938dfc29754 100644
--- a/gcc/testsuite/gfortran.dg/vect/vect-8.f90
+++ b/gcc/testsuite/gfortran.dg/vect/vect-8.f90
@@ -704,7 +704,7 @@ CALL track('KERNEL  ')
 RETURN
 END SUBROUTINE kernel
 
-! { dg-final { scan-tree-dump-times "vectorized 25 loops" 1 "vect" { target 
aarch64_sve } } }
-! { dg-final { scan-tree-dump-times "vectorized 24 loops" 1 "vect" { target { 
aarch64*-*-* && { ! aarch64_sve } } } } }
+! { dg-final { scan-tree-dump-times "vectorized 2\[56\] loops" 1 "vect" { 
target aarch64_sve } } }
+! { dg-final { scan-tree-dump-times "vectorized 2\[45\] loops" 1 "vect" { 
target { aarch64*-*-* && { ! aarch64_sve } } } } }
 ! { dg-final { scan-tree-dump-times "vectorized 2\[234\] loops" 1 "vect" { 
target { vect_intdouble_cvt && { ! aarch64*-*-* } } } } }
 ! { dg-final { scan-tree-dump-times "vectorized 17 loops" 1 "vect" { target { 
{ ! vect_intdouble_cvt } && { ! aarch64*-*-* } } } } }
-- 
2.25.1



[PATCH v3] aarch64,arm: Move branch-protection data to targets

2023-12-12 Thread Szabolcs Nagy
The branch-protection types are target specific, not the same on arm
and aarch64.  This currently affects pac-ret+b-key, but there will be
a new type on aarch64 that is not relevant for arm.

After the move, change aarch_ identifiers to aarch64_ or arm_ as
appropriate.

gcc/ChangeLog:

* config/aarch64/aarch64.md: Rename aarch_ to aarch64_.
* config/aarch64/aarch64.opt: Likewise.
* config/aarch64/aarch64-c.cc (aarch64_update_cpp_builtins): Likewise.
* config/aarch64/aarch64.cc (aarch64_expand_prologue): Likewise.
(aarch64_expand_epilogue): Likewise.
(aarch64_post_cfi_startproc): Likewise.
(aarch64_handle_no_branch_protection): Copy and rename.
(aarch64_handle_standard_branch_protection): Likewise.
(aarch64_handle_pac_ret_protection): Likewise.
(aarch64_handle_pac_ret_leaf): Likewise.
(aarch64_handle_pac_ret_b_key): Likewise.
(aarch64_handle_bti_protection): Likewise.
* config/arm/aarch-common.cc (aarch_handle_no_branch_protection):
Remove.
(aarch_handle_standard_branch_protection): Remove.
(aarch_handle_pac_ret_protection): Remove.
(aarch_handle_pac_ret_leaf): Remove.
(aarch_handle_pac_ret_b_key): Remove.
(aarch_handle_bti_protection): Remove.
* config/arm/aarch-common.h (enum aarch_key_type): Remove.
(struct aarch_branch_protect_type): Declare.
* config/arm/arm-c.cc (arm_cpu_builtins): Remove aarch_ra_sign_key.
* config/arm/arm.cc (arm_handle_no_branch_protection): Copy and rename.
(arm_handle_standard_branch_protection): Likewise.
(arm_handle_pac_ret_protection): Likewise.
(arm_handle_pac_ret_leaf): Likewise.
(arm_handle_bti_protection): Likewise.
(arm_configure_build_target): Likewise.
* config/arm/arm.opt: Remove aarch_ra_sign_key.
---
v3: aarch_ to aarch64_/arm_ renames.
---
 gcc/config/aarch64/aarch64-c.cc |  4 +-
 gcc/config/aarch64/aarch64.cc   | 69 +
 gcc/config/aarch64/aarch64.md   |  2 +-
 gcc/config/aarch64/aarch64.opt  |  2 +-
 gcc/config/arm/aarch-common.cc  | 55 --
 gcc/config/arm/aarch-common.h   | 11 +++---
 gcc/config/arm/arm-c.cc |  2 -
 gcc/config/arm/arm.cc   | 52 ++---
 gcc/config/arm/arm.opt  |  3 --
 9 files changed, 117 insertions(+), 83 deletions(-)

diff --git a/gcc/config/aarch64/aarch64-c.cc b/gcc/config/aarch64/aarch64-c.cc
index 115a2a8b756..553c99845e2 100644
--- a/gcc/config/aarch64/aarch64-c.cc
+++ b/gcc/config/aarch64/aarch64-c.cc
@@ -235,9 +235,9 @@ aarch64_update_cpp_builtins (cpp_reader *pfile)
   if (aarch_ra_sign_scope != AARCH_FUNCTION_NONE)
 {
   int v = 0;
-  if (aarch_ra_sign_key == AARCH_KEY_A)
+  if (aarch64_ra_sign_key == AARCH64_KEY_A)
v |= 1;
-  if (aarch_ra_sign_key == AARCH_KEY_B)
+  if (aarch64_ra_sign_key == AARCH64_KEY_B)
v |= 2;
   if (aarch_ra_sign_scope == AARCH_FUNCTION_ALL)
v |= 4;
diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc
index 9530618abea..dfd374c901e 100644
--- a/gcc/config/aarch64/aarch64.cc
+++ b/gcc/config/aarch64/aarch64.cc
@@ -9461,12 +9461,12 @@ aarch64_expand_prologue (void)
   /* Sign return address for functions.  */
   if (aarch64_return_address_signing_enabled ())
 {
-  switch (aarch_ra_sign_key)
+  switch (aarch64_ra_sign_key)
{
- case AARCH_KEY_A:
+ case AARCH64_KEY_A:
insn = emit_insn (gen_paciasp ());
break;
- case AARCH_KEY_B:
+ case AARCH64_KEY_B:
insn = emit_insn (gen_pacibsp ());
break;
  default:
@@ -9880,12 +9880,12 @@ aarch64_expand_epilogue (rtx_call_insn *sibcall)
   if (aarch64_return_address_signing_enabled ()
   && (sibcall || !TARGET_ARMV8_3))
 {
-  switch (aarch_ra_sign_key)
+  switch (aarch64_ra_sign_key)
{
- case AARCH_KEY_A:
+ case AARCH64_KEY_A:
insn = emit_insn (gen_autiasp ());
break;
- case AARCH_KEY_B:
+ case AARCH64_KEY_B:
insn = emit_insn (gen_autibsp ());
break;
  default:
@@ -18541,6 +18541,61 @@ aarch64_set_asm_isa_flags (aarch64_feature_flags flags)
   aarch64_set_asm_isa_flags (_options, flags);
 }
 
+static void
+aarch64_handle_no_branch_protection (void)
+{
+  aarch_ra_sign_scope = AARCH_FUNCTION_NONE;
+  aarch_enable_bti = 0;
+}
+
+static void
+aarch64_handle_standard_branch_protection (void)
+{
+  aarch_ra_sign_scope = AARCH_FUNCTION_NON_LEAF;
+  aarch64_ra_sign_key = AARCH64_KEY_A;
+  aarch_enable_bti = 1;
+}
+
+static void
+aarch64_handle_pac_ret_protection (void)
+{
+  aarch_ra_sign_scope = AARCH_FUNCTION_NON_LEAF;
+  aarch64_ra_sign_key = AARCH64_KEY_A;
+}
+
+static void
+aarch64_handle_pac_ret_leaf (void)
+{
+  aarch_ra_sign_scope = AARCH_FUNCTION_ALL;
+}
+
+static 

Re: [PATCH] libatomic: Add rcpc3 128-bit atomic operations for AArch64

2023-12-08 Thread Szabolcs Nagy
The 11/13/2023 11:47, Victor Do Nascimento wrote:
> +/* LRCPC atomic support encoded in ID_AA64ISAR1_EL1.Atomic,
> +   bits[23:20].  The expected value is 0b0011.  Check that.  */
> +#define HAS_LRCPC3() ({  \
> +  unsigned long val; \
> +  asm volatile ("mrs %0, ID_AA64ISAR1_EL1" : "=r" (val));\
> +  (val & 0xf0) >= 0x30;  \
> +})

same comment as for the lse128 patch: use hwcaps
(and wait for linux release before committing).


Re: [PATCH v2 2/2] libatomic: Enable LSE128 128-bit atomics for armv9.4-a

2023-12-08 Thread Szabolcs Nagy
The 11/29/2023 15:15, Richard Earnshaw wrote:
> On 13/11/2023 11:37, Victor Do Nascimento wrote:
> > +/* LSE128 atomic support encoded in ID_AA64ISAR0_EL1.Atomic,
> > +   bits[23:20].  The expected value is 0b0011.  Check that.  */
> > +#define HAS_LSE128() ({\
> > +  unsigned long val;   \
> > +  asm volatile ("mrs %0, ID_AA64ISAR0_EL1" : "=r" (val));  \
> > +  (val & 0xf0) >= 0x30;\
> > +})
> > +
> 
> The pseudo-code for this register reads:
> 
> if PSTATE.EL == EL0 then
>   if IsFeatureImplemented(FEAT_IDST) then
> if EL2Enabled() && HCR_EL2.TGE == '1' then
>   AArch64.SystemAccessTrap(EL2, 0x18);
> else
>   AArch64.SystemAccessTrap(EL1, 0x18);
>   else
> UNDEFINED;
> ...
> 
> So this instruction may result in SIGILL if run on cores without FEAT_IDST.
> SystemAccessTrap just punts the problem up to the kernel or hypervisor as
> well.

yes, HWCAP_CPUID has to be checked to see if
linux traps and emulates the mrs for userspace.

> I think we need a hwcap bit to work this out, which is the preferred way on

yes, use hwcap instead of id reg (hwcap2 is
passed to aarch64 ifuncs or __getauxval works)

> Linux anyway.  Something like this? :) 
> https://lore.kernel.org/linux-arm-kernel/20231003124544.858804-2-joey.go...@arm.com/T/

note that there was no linux release since this
got added.

we can add the hwcap values tentatively, but
there is a risk of revert on the kernel side
(which means libatomic vs linux abi break) so
i would only commit the patch into gcc after
a linux release is tagged.


[committed] libgcc: Fix config.in

2023-12-08 Thread Szabolcs Nagy
It was updated incorrectly in

  commit dbbfb52b0e9c66ee9d05b8fd17c4f44655e48463
  Author: Szabolcs Nagy 
  CommitDate: 2023-12-08 11:29:06 +

libgcc: aarch64: Configure check for __getauxval

so regenerate it.

libgcc/ChangeLog:

* config.in: Regenerate.
---
 libgcc/config.in | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/libgcc/config.in b/libgcc/config.in
index 441d4d39b95..8f7dd437b0e 100644
--- a/libgcc/config.in
+++ b/libgcc/config.in
@@ -16,9 +16,6 @@
 /* Define to 1 if the assembler supports .variant_pcs. */
 #undef HAVE_AS_VARIANT_PCS
 
-/* Define to 1 if __getauxval is available. */
-#undef HAVE___GETAUXVAL
-
 /* Define to 1 if the target assembler supports thread-local storage. */
 #undef HAVE_CC_TLS
 
@@ -67,6 +64,9 @@
 /* Define to 1 if you have the  header file. */
 #undef HAVE_UNISTD_H
 
+/* Define to 1 if __getauxval is available. */
+#undef HAVE___GETAUXVAL
+
 /* Define to the address where bug reports for this package should be sent. */
 #undef PACKAGE_BUGREPORT
 
-- 
2.25.1



[PATCH v2] libgcc: aarch64: Add SME runtime support

2023-12-08 Thread Szabolcs Nagy
The call ABI for SME (Scalable Matrix Extension) requires a number of
helper routines which are added to libgcc so they are tied to the
compiler version instead of the libc version. See
https://github.com/ARM-software/abi-aa/blob/main/aapcs64/aapcs64.rst#sme-support-routines

The routines are in shared libgcc and static libgcc eh, even though
they are not related to exception handling.  This is to avoid linking
a copy of the routines into dynamic linked binaries, because TPIDR2_EL0
block can be extended in the future which is better to handle in a
single place per process.

The support routines have to decide if SME is accessible or not. Linux
tells userspace if SME is accessible via AT_HWCAP2, otherwise a new
__aarch64_sme_accessible symbol was introduced that a libc can define.
Due to libgcc and libc build order, the symbol availability cannot be
checked so for __aarch64_sme_accessible an unistd.h feature test macro
is used while such detection mechanism is not available for __getauxval
so we rely on configure checks based on the target triplet.

Asm helper code is added to make writing the routines easier.

libgcc/ChangeLog:

* config/aarch64/t-aarch64: Add sources to the build.
* config/aarch64/__aarch64_have_sme.c: New file.
* config/aarch64/__arm_sme_state.S: New file.
* config/aarch64/__arm_tpidr2_restore.S: New file.
* config/aarch64/__arm_tpidr2_save.S: New file.
* config/aarch64/__arm_za_disable.S: New file.
* config/aarch64/aarch64-asm.h: New file.
* config/aarch64/libgcc-sme.ver: New file.
---
v2:
- do not include unistd.h when inhibit_libc is set.
- use msr tpidr2_el0,xzr in __arm_za_disable.

 libgcc/config/aarch64/__aarch64_have_sme.c   |  75 ++
 libgcc/config/aarch64/__arm_sme_state.S  |  55 ++
 libgcc/config/aarch64/__arm_tpidr2_restore.S |  89 
 libgcc/config/aarch64/__arm_tpidr2_save.S| 101 +++
 libgcc/config/aarch64/__arm_za_disable.S |  65 
 libgcc/config/aarch64/aarch64-asm.h  |  98 ++
 libgcc/config/aarch64/libgcc-sme.ver |  24 +
 libgcc/config/aarch64/t-aarch64  |  10 ++
 8 files changed, 517 insertions(+)
 create mode 100644 libgcc/config/aarch64/__aarch64_have_sme.c
 create mode 100644 libgcc/config/aarch64/__arm_sme_state.S
 create mode 100644 libgcc/config/aarch64/__arm_tpidr2_restore.S
 create mode 100644 libgcc/config/aarch64/__arm_tpidr2_save.S
 create mode 100644 libgcc/config/aarch64/__arm_za_disable.S
 create mode 100644 libgcc/config/aarch64/aarch64-asm.h
 create mode 100644 libgcc/config/aarch64/libgcc-sme.ver

diff --git a/libgcc/config/aarch64/__aarch64_have_sme.c 
b/libgcc/config/aarch64/__aarch64_have_sme.c
new file mode 100644
index 000..5e649246270
--- /dev/null
+++ b/libgcc/config/aarch64/__aarch64_have_sme.c
@@ -0,0 +1,75 @@
+/* Initializer for SME support.
+   Copyright (C) 2023 Free Software Foundation, Inc.
+
+   This file is part of GCC.
+
+   GCC is free software; you can redistribute it and/or modify it
+   under the terms of the GNU General Public License as published
+   by the Free Software Foundation; either version 3, or (at your
+   option) any later version.
+
+   GCC is distributed in the hope that it will be useful, but WITHOUT
+   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+   License for more details.
+
+   Under Section 7 of GPL version 3, you are granted additional
+   permissions described in the GCC Runtime Library Exception, version
+   3.1, as published by the Free Software Foundation.
+
+   You should have received a copy of the GNU General Public License and
+   a copy of the GCC Runtime Library Exception along with this program;
+   see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+   .  */
+
+#include "auto-target.h"
+
+#ifndef inhibit_libc
+/* For libc feature test macros.  */
+# include 
+#endif
+
+#if __ARM_FEATURE_SME
+/* Avoid runtime SME detection if libgcc is built with SME.  */
+# define HAVE_SME_CONST const
+# define HAVE_SME_VALUE 1
+#elif HAVE___GETAUXVAL
+/* SME access detection on Linux.  */
+# define HAVE_SME_CONST
+# define HAVE_SME_VALUE 0
+# define HAVE_SME_CTOR sme_accessible ()
+
+# define AT_HWCAP2 26
+# define HWCAP2_SME(1 << 23)
+unsigned long int __getauxval (unsigned long int);
+
+static _Bool
+sme_accessible (void)
+{
+  unsigned long hwcap2 = __getauxval (AT_HWCAP2);
+  return (hwcap2 & HWCAP2_SME) != 0;
+}
+#elif __LIBC___AARCH64_SME_ACCESSIBLE
+/* Alternative SME access detection.  */
+# define HAVE_SME_CONST
+# define HAVE_SME_VALUE 0
+# define HAVE_SME_CTOR __aarch64_sme_accessible ()
+_Bool __aarch64_sme_accessible (void);
+#else
+# define HAVE_SME_CONST const
+# define HAVE_SME_VALUE 0
+#endif
+
+/* Define the symbol gating SME support in libgcc.  */

Re: [PATCH 3/4] libgcc: aarch64: Add SME runtime support

2023-12-07 Thread Szabolcs Nagy
The 12/07/2023 17:36, Richard Sandiford wrote:
> Szabolcs Nagy  writes:
> > +
> > +#include "auto-target.h"
> > +#include 
> > +

sorry, this seems to fail when building --without-headers

i will respin this, handling the 'inhibit_libc' case.


[PATCH 4/4] libgcc: aarch64: Add SME unwinder support

2023-12-07 Thread Szabolcs Nagy
To support the ZA lazy save scheme, the PCS requires the unwinder to
reset the SME state to PSTATE.SM=0, PSTATE.ZA=0, TPIDR2_EL0=0 on entry
to an exception handler. We use the __arm_za_disable SME runtime call
unconditionally to achieve this.
https://github.com/ARM-software/abi-aa/blob/main/aapcs64/aapcs64.rst#exceptions

The hidden alias is used to avoid a PLT and avoid inconsistent VPCS
marking (we don't rely on special PCS at the call site). In case of
static linking the SME runtime init code is linked in code that raises
exceptions.

libgcc/ChangeLog:

* config/aarch64/__arm_za_disable.S: Add hidden alias.
* config/aarch64/aarch64-unwind.h: Reset the SME state before
EH return via the _Unwind_Frames_Extra hook.
---
 libgcc/config/aarch64/__arm_za_disable.S |  5 +
 libgcc/config/aarch64/aarch64-unwind.h   | 16 
 2 files changed, 21 insertions(+)

diff --git a/libgcc/config/aarch64/__arm_za_disable.S 
b/libgcc/config/aarch64/__arm_za_disable.S
index 7a888a98d49..f61d4255fdc 100644
--- a/libgcc/config/aarch64/__arm_za_disable.S
+++ b/libgcc/config/aarch64/__arm_za_disable.S
@@ -64,3 +64,8 @@ ENTRY (__arm_za_disable)
 L(end):
ret
 END (__arm_za_disable)
+
+/* Hidden alias used by the unwinder.  */
+.global __libgcc_arm_za_disable
+.hidden __libgcc_arm_za_disable
+.set __libgcc_arm_za_disable, __arm_za_disable
diff --git a/libgcc/config/aarch64/aarch64-unwind.h 
b/libgcc/config/aarch64/aarch64-unwind.h
index d669edd671b..9fe6c8f61c3 100644
--- a/libgcc/config/aarch64/aarch64-unwind.h
+++ b/libgcc/config/aarch64/aarch64-unwind.h
@@ -78,4 +78,20 @@ aarch64_demangle_return_addr (struct _Unwind_Context 
*context,
   return addr;
 }
 
+/* SME runtime function local to libgcc, streaming compatible
+   and preserves more registers than the base PCS requires, but
+   we don't rely on that here.  */
+__attribute__ ((visibility ("hidden")))
+void __libgcc_arm_za_disable (void);
+
+/* Disable the SME ZA state in case an unwound frame used the ZA
+   lazy saving scheme.  */
+#undef _Unwind_Frames_Extra
+#define _Unwind_Frames_Extra(x)\
+  do   \
+{  \
+  __libgcc_arm_za_disable ();  \
+}  \
+  while (0)
+
 #endif /* defined AARCH64_UNWIND_H && defined __ILP32__ */
-- 
2.25.1



[PATCH 3/4] libgcc: aarch64: Add SME runtime support

2023-12-07 Thread Szabolcs Nagy
The call ABI for SME (Scalable Matrix Extension) requires a number of
helper routines which are added to libgcc so they are tied to the
compiler version instead of the libc version. See
https://github.com/ARM-software/abi-aa/blob/main/aapcs64/aapcs64.rst#sme-support-routines

The routines are in shared libgcc and static libgcc eh, even though
they are not related to exception handling.  This is to avoid linking
a copy of the routines into dynamic linked binaries, because TPIDR2_EL0
block can be extended in the future which is better to handle in a
single place per process.

The support routines have to decide if SME is accessible or not. Linux
tells userspace if SME is accessible via AT_HWCAP2, otherwise a new
__aarch64_sme_accessible symbol was introduced that a libc can define.
Due to libgcc and libc build order, the symbol availability cannot be
checked so for __aarch64_sme_accessible an unistd.h feature test macro
is used while such detection mechanism is not available for __getauxval
so we rely on configure checks based on the target triplet.

Asm helper code is added to make writing the routines easier.

libgcc/ChangeLog:

* config/aarch64/t-aarch64: Add sources to the build.
* config/aarch64/__aarch64_have_sme.c: New file.
* config/aarch64/__arm_sme_state.S: New file.
* config/aarch64/__arm_tpidr2_restore.S: New file.
* config/aarch64/__arm_tpidr2_save.S: New file.
* config/aarch64/__arm_za_disable.S: New file.
* config/aarch64/aarch64-asm.h: New file.
* config/aarch64/libgcc-sme.ver: New file.
---
 libgcc/config/aarch64/__aarch64_have_sme.c   |  71 +
 libgcc/config/aarch64/__arm_sme_state.S  |  55 ++
 libgcc/config/aarch64/__arm_tpidr2_restore.S |  89 
 libgcc/config/aarch64/__arm_tpidr2_save.S| 101 +++
 libgcc/config/aarch64/__arm_za_disable.S |  66 
 libgcc/config/aarch64/aarch64-asm.h  |  98 ++
 libgcc/config/aarch64/libgcc-sme.ver |  24 +
 libgcc/config/aarch64/t-aarch64  |  10 ++
 8 files changed, 514 insertions(+)
 create mode 100644 libgcc/config/aarch64/__aarch64_have_sme.c
 create mode 100644 libgcc/config/aarch64/__arm_sme_state.S
 create mode 100644 libgcc/config/aarch64/__arm_tpidr2_restore.S
 create mode 100644 libgcc/config/aarch64/__arm_tpidr2_save.S
 create mode 100644 libgcc/config/aarch64/__arm_za_disable.S
 create mode 100644 libgcc/config/aarch64/aarch64-asm.h
 create mode 100644 libgcc/config/aarch64/libgcc-sme.ver

diff --git a/libgcc/config/aarch64/__aarch64_have_sme.c 
b/libgcc/config/aarch64/__aarch64_have_sme.c
new file mode 100644
index 000..2dc6be63ce9
--- /dev/null
+++ b/libgcc/config/aarch64/__aarch64_have_sme.c
@@ -0,0 +1,71 @@
+/* Initializer for SME support.
+   Copyright (C) 2023 Free Software Foundation, Inc.
+
+   This file is part of GCC.
+
+   GCC is free software; you can redistribute it and/or modify it
+   under the terms of the GNU General Public License as published
+   by the Free Software Foundation; either version 3, or (at your
+   option) any later version.
+
+   GCC is distributed in the hope that it will be useful, but WITHOUT
+   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+   License for more details.
+
+   Under Section 7 of GPL version 3, you are granted additional
+   permissions described in the GCC Runtime Library Exception, version
+   3.1, as published by the Free Software Foundation.
+
+   You should have received a copy of the GNU General Public License and
+   a copy of the GCC Runtime Library Exception along with this program;
+   see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+   .  */
+
+#include "auto-target.h"
+#include 
+
+#if __ARM_FEATURE_SME
+/* Avoid runtime SME detection if libgcc is built with SME.  */
+# define HAVE_SME_CONST const
+# define HAVE_SME_VALUE 1
+#elif HAVE___GETAUXVAL
+/* SME access detection on Linux.  */
+# define HAVE_SME_CONST
+# define HAVE_SME_VALUE 0
+# define HAVE_SME_CTOR sme_accessible ()
+
+# define AT_HWCAP2 26
+# define HWCAP2_SME(1 << 23)
+unsigned long int __getauxval (unsigned long int);
+
+static _Bool
+sme_accessible (void)
+{
+  unsigned long hwcap2 = __getauxval (AT_HWCAP2);
+  return (hwcap2 & HWCAP2_SME) != 0;
+}
+#elif __LIBC___AARCH64_SME_ACCESSIBLE
+/* Alternative SME access detection.  */
+# define HAVE_SME_CONST
+# define HAVE_SME_VALUE 0
+# define HAVE_SME_CTOR __aarch64_sme_accessible ()
+_Bool __aarch64_sme_accessible (void);
+#else
+# define HAVE_SME_CONST const
+# define HAVE_SME_VALUE 0
+#endif
+
+/* Define the symbol gating SME support in libgcc.  */
+HAVE_SME_CONST _Bool __aarch64_have_sme
+  __attribute__((visibility("hidden"), nocommon)) = HAVE_SME_VALUE;
+
+#ifdef HAVE_SME_CTOR
+/* Use a higher priority to ensure it runs before 

[PATCH 2/4] libgcc: aarch64: Configure check for __getauxval

2023-12-07 Thread Szabolcs Nagy
Add configure check for the __getauxval ABI symbol, which is always
available on aarch64 glibc, and may be available on other linux C
runtimes. For now only enabled on glibc, others have to override it

  target_configargs=libgcc_cv_have___getauxval=yes

This is deliberately obscure as it should be auto detected, ideally
via a feature test macro in unistd.h (link time detection is not
possible since the libc may not be installed at libgcc build time),
but currently there is no such feature test mechanism.

Without __getauxval, libgcc cannot do runtime CPU feature detection
and has to assume only the build time known features are available.

libgcc/ChangeLog:

* config.in: Undef HAVE___GETAUXVAL.
* configure: Regenerate.
* configure.ac: Check for __getauxval.
---
 libgcc/config.in|  3 +++
 libgcc/configure| 26 ++
 libgcc/configure.ac | 19 +++
 3 files changed, 48 insertions(+)

diff --git a/libgcc/config.in b/libgcc/config.in
index 5dd96cdf648..441d4d39b95 100644
--- a/libgcc/config.in
+++ b/libgcc/config.in
@@ -16,6 +16,9 @@
 /* Define to 1 if the assembler supports .variant_pcs. */
 #undef HAVE_AS_VARIANT_PCS
 
+/* Define to 1 if __getauxval is available. */
+#undef HAVE___GETAUXVAL
+
 /* Define to 1 if the target assembler supports thread-local storage. */
 #undef HAVE_CC_TLS
 
diff --git a/libgcc/configure b/libgcc/configure
index 571e3437701..746d29587d5 100755
--- a/libgcc/configure
+++ b/libgcc/configure
@@ -5657,6 +5657,32 @@ $as_echo "#define HAVE_AS_VARIANT_PCS 1" >>confdefs.h
   ;;
 esac
 
+# Check __getauxval ABI symbol for CPU feature detection.
+case ${target} in
+aarch64*-linux-*)
+  # No link check because the libc may not be present.
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for __getauxval" >&5
+$as_echo_n "checking for __getauxval... " >&6; }
+if ${libgcc_cv_have___getauxval+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  case ${target} in
+ *-linux-gnu*)
+   libgcc_cv_have___getauxval=yes
+   ;;
+ *)
+   libgcc_cv_have___getauxval=no
+ esac
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libgcc_cv_have___getauxval" 
>&5
+$as_echo "$libgcc_cv_have___getauxval" >&6; }
+  if test x$libgcc_cv_have___getauxval = xyes; then
+
+$as_echo "#define HAVE___GETAUXVAL 1" >>confdefs.h
+
+  fi
+esac
+
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for init priority support" 
>&5
 $as_echo_n "checking for init priority support... " >&6; }
 if ${libgcc_cv_init_priority+:} false; then :
diff --git a/libgcc/configure.ac b/libgcc/configure.ac
index abc398c91e4..64b45ae1423 100644
--- a/libgcc/configure.ac
+++ b/libgcc/configure.ac
@@ -665,6 +665,25 @@ aarch64*-*-*)
 esac])
 LIBGCC_CHECK_AS_VARIANT_PCS
 
+# Check __getauxval ABI symbol for CPU feature detection.
+case ${target} in
+aarch64*-linux-*)
+  # No link check because the libc may not be present.
+  AC_CACHE_CHECK([for __getauxval],
+[libgcc_cv_have___getauxval],
+[case ${target} in
+ *-linux-gnu*)
+   libgcc_cv_have___getauxval=yes
+   ;;
+ *)
+   libgcc_cv_have___getauxval=no
+ esac])
+  if test x$libgcc_cv_have___getauxval = xyes; then
+AC_DEFINE(HAVE___GETAUXVAL, 1,
+ [Define to 1 if __getauxval is available.])
+  fi
+esac
+
 dnl Check if as supports RTM instructions.
 AC_CACHE_CHECK(for init priority support, libgcc_cv_init_priority, [
 AC_COMPILE_IFELSE([AC_LANG_PROGRAM(,
-- 
2.25.1



[PATCH 1/4] libgcc: aarch64: Configure check for .variant_pcs support

2023-12-07 Thread Szabolcs Nagy
Ideally SME support routines in libgcc are marked as variant PCS symbols
so check if as supports the directive.
---
 libgcc/config.in|  3 +++
 libgcc/configure| 39 +++
 libgcc/configure.ac | 17 +
 3 files changed, 59 insertions(+)

diff --git a/libgcc/config.in b/libgcc/config.in
index f93c64a00c3..5dd96cdf648 100644
--- a/libgcc/config.in
+++ b/libgcc/config.in
@@ -13,6 +13,9 @@
 /* Define to 1 if the assembler supports LSE. */
 #undef HAVE_AS_LSE
 
+/* Define to 1 if the assembler supports .variant_pcs. */
+#undef HAVE_AS_VARIANT_PCS
+
 /* Define to 1 if the target assembler supports thread-local storage. */
 #undef HAVE_CC_TLS
 
diff --git a/libgcc/configure b/libgcc/configure
index cf149209652..571e3437701 100755
--- a/libgcc/configure
+++ b/libgcc/configure
@@ -5618,6 +5618,45 @@ $as_echo "#define HAVE_AS_LSE 1" >>confdefs.h
   ;;
 esac
 
+
+
+case "${target}" in
+aarch64*-*-*)
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking if as supports 
.variant_pcs" >&5
+$as_echo_n "checking if as supports .variant_pcs... " >&6; }
+if ${libgcc_cv_as_variant_pcs+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+asm (".variant_pcs foobar");
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  libgcc_cv_as_variant_pcs=yes
+else
+  libgcc_cv_as_variant_pcs=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libgcc_cv_as_variant_pcs" >&5
+$as_echo "$libgcc_cv_as_variant_pcs" >&6; }
+  if test x$libgcc_cv_as_variant_pcs = xyes; then
+
+$as_echo "#define HAVE_AS_VARIANT_PCS 1" >>confdefs.h
+
+  fi
+  ;;
+esac
+
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for init priority support" 
>&5
 $as_echo_n "checking for init priority support... " >&6; }
 if ${libgcc_cv_init_priority+:} false; then :
diff --git a/libgcc/configure.ac b/libgcc/configure.ac
index 2fc9d5d7c93..abc398c91e4 100644
--- a/libgcc/configure.ac
+++ b/libgcc/configure.ac
@@ -648,6 +648,23 @@ changequote([,])dnl
 esac])
 LIBGCC_CHECK_AS_LSE
 
+dnl Check if as supports .variant_pcs.
+AC_DEFUN([LIBGCC_CHECK_AS_VARIANT_PCS], [
+case "${target}" in
+aarch64*-*-*)
+  AC_CACHE_CHECK([if as supports .variant_pcs], libgcc_cv_as_variant_pcs, [
+AC_COMPILE_IFELSE([AC_LANG_PROGRAM(,
+  [[asm (".variant_pcs foobar");]])],
+  [libgcc_cv_as_variant_pcs=yes], [libgcc_cv_as_variant_pcs=no])
+  ])
+  if test x$libgcc_cv_as_variant_pcs = xyes; then
+AC_DEFINE(HAVE_AS_VARIANT_PCS, 1,
+ [Define to 1 if the assembler supports .variant_pcs.])
+  fi
+  ;;
+esac])
+LIBGCC_CHECK_AS_VARIANT_PCS
+
 dnl Check if as supports RTM instructions.
 AC_CACHE_CHECK(for init priority support, libgcc_cv_init_priority, [
 AC_COMPILE_IFELSE([AC_LANG_PROGRAM(,
-- 
2.25.1



[PATCH 0/4] libgcc: aarch64: Add SME runtime

2023-12-07 Thread Szabolcs Nagy
Add SME (Scalable Matrix Extension) support to libgcc.

Szabolcs Nagy (4):
  libgcc: aarch64: Configure check for .variant_pcs support
  libgcc: aarch64: Configure check for __getauxval
  libgcc: aarch64: Add SME runtime support
  libgcc: aarch64: Add SME unwinder support

 libgcc/config.in |   6 ++
 libgcc/config/aarch64/__aarch64_have_sme.c   |  71 +
 libgcc/config/aarch64/__arm_sme_state.S  |  55 ++
 libgcc/config/aarch64/__arm_tpidr2_restore.S |  89 
 libgcc/config/aarch64/__arm_tpidr2_save.S| 101 +++
 libgcc/config/aarch64/__arm_za_disable.S |  71 +
 libgcc/config/aarch64/aarch64-asm.h  |  98 ++
 libgcc/config/aarch64/aarch64-unwind.h   |  16 +++
 libgcc/config/aarch64/libgcc-sme.ver |  24 +
 libgcc/config/aarch64/t-aarch64  |  10 ++
 libgcc/configure |  65 
 libgcc/configure.ac  |  36 +++
 12 files changed, 642 insertions(+)
 create mode 100644 libgcc/config/aarch64/__aarch64_have_sme.c
 create mode 100644 libgcc/config/aarch64/__arm_sme_state.S
 create mode 100644 libgcc/config/aarch64/__arm_tpidr2_restore.S
 create mode 100644 libgcc/config/aarch64/__arm_tpidr2_save.S
 create mode 100644 libgcc/config/aarch64/__arm_za_disable.S
 create mode 100644 libgcc/config/aarch64/aarch64-asm.h
 create mode 100644 libgcc/config/aarch64/libgcc-sme.ver

-- 
2.25.1



[PATCH] aarch64: fix eh_return-3.c test

2023-12-04 Thread Szabolcs Nagy
gcc/testsuite/ChangeLog:

* gcc.target/aarch64/eh_return-3.c: Fix when retaa is available.
---
 gcc/testsuite/gcc.target/aarch64/eh_return-3.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/gcc/testsuite/gcc.target/aarch64/eh_return-3.c 
b/gcc/testsuite/gcc.target/aarch64/eh_return-3.c
index a17baa86501..d180fa7c455 100644
--- a/gcc/testsuite/gcc.target/aarch64/eh_return-3.c
+++ b/gcc/testsuite/gcc.target/aarch64/eh_return-3.c
@@ -12,8 +12,12 @@
 ** cbz x4, .*
 ** add sp, sp, x5
 ** br  x6
+** (
 ** hint29 // autiasp
 ** ret
+** |
+** retaa
+** )
 ** mov x5, x0
 ** mov x4, 1
 ** mov x6, x1
-- 
2.25.1



Re: [PATCH] aarch64: Avoid -Wincompatible-pointer-types warning in Linux unwinder

2023-11-29 Thread Szabolcs Nagy
The 11/10/2023 19:48, Florian Weimer wrote:
>   * config/aarch64/linux-unwind.h
>   (aarch64_fallback_frame_state): Add cast to the expected type
>   in sc assignment.
> 
> (Almost a v2, but the other issue was already fixed via in r14-4183.)
> 
> ---
>  libgcc/config/aarch64/linux-unwind.h | 5 -
>  1 file changed, 4 insertions(+), 1 deletion(-)
> 
> diff --git a/libgcc/config/aarch64/linux-unwind.h 
> b/libgcc/config/aarch64/linux-unwind.h
> index 00eba866049..18b3df71e7b 100644
> --- a/libgcc/config/aarch64/linux-unwind.h
> +++ b/libgcc/config/aarch64/linux-unwind.h
> @@ -77,7 +77,10 @@ aarch64_fallback_frame_state (struct _Unwind_Context 
> *context,
>  }
>  
>rt_ = context->cfa;
> -  sc = _->uc.uc_mcontext;
> +  /* Historically, the uc_mcontext member was of type struct sigcontext, but
> + glibc uses a different type now with member names in the implementation
> + namespace.  */
> +  sc = (struct sigcontext *) _->uc.uc_mcontext;

FWIW this looks good to me.
(but i cannot approve patches)

(changing the type of sc to mcontext_t* is another option,
but then _GNU_SOURCE is required for the field names to
remain the same across glibc versions, while struct
sigcontext* is unlikely to cause API issues.)

>  
>  /* This define duplicates the definition in aarch64.md */
>  #define SP_REGNUM 31
> 
> base-commit: 3a6df3281a525ae6113f50d7b38b09fcd803801e
> 


Re: [PATCH] aarch64: Call named function in gcc.target/aarch64/aapcs64/ice_1.c

2023-11-29 Thread Szabolcs Nagy
The 11/10/2023 12:22, Florian Weimer wrote:
> This test looks like it intends to pass a small struct argument
> through both a non-variadic and variadic argument, but due to
> the typo, it does not achieve that.
> 
> gcc/testsuite/
> 
>   * gcc.target/aarch64/aapcs64/ice_1.c (foo): Call named.


FWIW, this looks good to me.
(but i cannot approve patches)

> 
> ---
>  gcc/testsuite/gcc.target/aarch64/aapcs64/ice_1.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/gcc/testsuite/gcc.target/aarch64/aapcs64/ice_1.c 
> b/gcc/testsuite/gcc.target/aarch64/aapcs64/ice_1.c
> index 906ccebf616..edc35db2f6e 100644
> --- a/gcc/testsuite/gcc.target/aarch64/aapcs64/ice_1.c
> +++ b/gcc/testsuite/gcc.target/aarch64/aapcs64/ice_1.c
> @@ -16,6 +16,6 @@ void unnamed (int, ...);
>  
>  void foo ()
>  {
> -  name (0, );
> +  named (0, );
>unnamed (0, );
>  }
> 
> base-commit: 5f6c5fe078c45bc32c8d21da6b14c27c0ed7be6e
> 


Re: [PATCH v2 3/7] aarch64: Add eh_return compile tests

2023-11-27 Thread Szabolcs Nagy
The 11/26/2023 14:37, Richard Sandiford wrote:
> Szabolcs Nagy  writes:
> > +++ b/gcc/testsuite/gcc.target/aarch64/eh_return-3.c
> > @@ -0,0 +1,30 @@
> > +/* { dg-do compile } */
> > +/* { dg-options "-O2 -mbranch-protection=pac-ret+leaf" } */
> 
> Probably best to add -fno-schedule-insns -fno-schedule-insns2, so that the
> instructions in the check-function-bodies are in a more predictable order.
> 
> > +/* { dg-final { check-function-bodies "**" "" "" } } */
> > +
> > +/*
> > +**foo:
> > +** hint25 // paciasp
> > +** stp x0, x1, .*
> > +** stp x2, x3, .*
> > +** cbz w2, .*
> > +** mov x4, 0
> > +** ldp x2, x3, .*
> > +** ldp x0, x1, .*
> > +** cbz x4, .*
> > +** add sp, sp, x5
> > +** br  x6
> > +** hint29 // autiasp
> > +** ret
> > +** mov x5, x0
> > +** mov x6, x1
> > +** mov x4, 1
> > +** b   .*
> > +*/
> 
> What's the significance of x3 here?  It looks from the function definition
> like it should be undefined.  And what are the stps and ldps doing?
> 
> If those aren't an important part of the test, it might be better
> to stub them out with "...", e.g.:
> 
> /*
> **foo:
> **hint25 // paciasp
> **...
> **cbz w2, .*
> **mov x4, 0
> **...
> **cbz x4, .*
> **add sp, sp, x5
> **br  x6
> **hint29 // autiasp
> **ret
> **mov x5, x0
> **mov x6, x1
> **mov x4, 1
> **b   .*
> */
> 
> LGTM otherwise.

committed as

>From cad7e1e3e0dea1922f89290bbbc27b4c44f53bf5 Mon Sep 17 00:00:00 2001
From: Szabolcs Nagy 
Date: Fri, 2 Jun 2023 14:17:02 +0100
Subject: [PATCH] aarch64: Add eh_return compile tests

gcc/testsuite/ChangeLog:

* gcc.target/aarch64/eh_return-2.c: New test.
* gcc.target/aarch64/eh_return-3.c: New test.
---
 .../gcc.target/aarch64/eh_return-2.c  |  9 ++
 .../gcc.target/aarch64/eh_return-3.c  | 28 +++
 2 files changed, 37 insertions(+)
 create mode 100644 gcc/testsuite/gcc.target/aarch64/eh_return-2.c
 create mode 100644 gcc/testsuite/gcc.target/aarch64/eh_return-3.c

diff --git a/gcc/testsuite/gcc.target/aarch64/eh_return-2.c 
b/gcc/testsuite/gcc.target/aarch64/eh_return-2.c
new file mode 100644
index 000..4a9d124e891
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/eh_return-2.c
@@ -0,0 +1,9 @@
+/* { dg-do compile } */
+/* { dg-final { scan-assembler "add\tsp, sp, x5" } } */
+/* { dg-final { scan-assembler "br\tx6" } } */
+
+void
+foo (unsigned long off, void *handler)
+{
+  __builtin_eh_return (off, handler);
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/eh_return-3.c 
b/gcc/testsuite/gcc.target/aarch64/eh_return-3.c
new file mode 100644
index 000..a17baa86501
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/eh_return-3.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mbranch-protection=pac-ret+leaf -fno-schedule-insns 
-fno-schedule-insns2" } */
+/* { dg-final { check-function-bodies "**" "" "" } } */
+
+/*
+**foo:
+** hint25 // paciasp
+** ...
+** cbz w2, .*
+** mov x4, 0
+** ...
+** cbz x4, .*
+** add sp, sp, x5
+** br  x6
+** hint29 // autiasp
+** ret
+** mov x5, x0
+** mov x4, 1
+** mov x6, x1
+** b   .*
+*/
+void
+foo (unsigned long off, void *handler, int c)
+{
+  if (c)
+return;
+  __builtin_eh_return (off, handler);
+}
-- 
2.25.1



Re: [PATCH v2 3/7] aarch64: Add eh_return compile tests

2023-11-27 Thread Szabolcs Nagy
The 11/26/2023 14:37, Richard Sandiford wrote:
> Szabolcs Nagy  writes:
> > +++ b/gcc/testsuite/gcc.target/aarch64/eh_return-3.c
> > @@ -0,0 +1,30 @@
> > +/* { dg-do compile } */
> > +/* { dg-options "-O2 -mbranch-protection=pac-ret+leaf" } */
> 
> Probably best to add -fno-schedule-insns -fno-schedule-insns2, so that the
> instructions in the check-function-bodies are in a more predictable order.
> 
> > +/* { dg-final { check-function-bodies "**" "" "" } } */
> > +
> > +/*
> > +**foo:
> > +** hint25 // paciasp
> > +** stp x0, x1, .*
> > +** stp x2, x3, .*
> > +** cbz w2, .*
> > +** mov x4, 0
> > +** ldp x2, x3, .*
> > +** ldp x0, x1, .*
> > +** cbz x4, .*
> > +** add sp, sp, x5
> > +** br  x6
> > +** hint29 // autiasp
> > +** ret
> > +** mov x5, x0
> > +** mov x6, x1
> > +** mov x4, 1
> > +** b   .*
> > +*/
> 
> What's the significance of x3 here?  It looks from the function definition
> like it should be undefined.  And what are the stps and ldps doing?

x0,..,x3 are preserved registers for eh (EH_RETURN_DATA_REGNO).

they are saved in the prologue and restored in the epilogue so
they can pass arguments to eh, which i think is relevant to an
eh_return test, although if the compiler knows they are not
clobbered then it could eliminate the save/restore.

> If those aren't an important part of the test, it might be better
> to stub them out with "...", e.g.:

i can do that.

> /*
> **foo:
> **hint25 // paciasp
> **...
> **cbz w2, .*
> **mov x4, 0
> **...
> **cbz x4, .*
> **add sp, sp, x5
> **br  x6
> **hint29 // autiasp
> **ret
> **mov x5, x0
> **mov x6, x1
> **mov x4, 1
> **b   .*
> */
> 
> LGTM otherwise.

thanks.


Re: [PATCH v2 1/7] aarch64: Use br instead of ret for eh_return

2023-11-13 Thread Szabolcs Nagy
The 11/13/2023 01:27, Hans-Peter Nilsson wrote:
> > From: Szabolcs Nagy 
> > Date: Fri, 3 Nov 2023 15:36:08 +
> 
> I don't see others commenting on this patch, and you're not
> mentioning this aspect, so I wonder:
> 
> > * config/aarch64/aarch64.h (EH_RETURN_TAKEN_RTX): Define.
> > (EH_RETURN_STACKADJ_RTX): Change to R5.
> > (EH_RETURN_HANDLER_RTX): Change to R6.
> 
> Isn't this an ABI change?

not really: this is interface between the function body
and the epilogue, so all within the code of a single
function doing eh return, not a public abi boundary.

(e.g. R0..R3 are preserved from the function throwing
the exception to the exception handler, so that's abi.
R4..R6 are just an internal detail of the function doing
the eh return in the unwinder.)

> 
> (I've forgotten relevant bits of the exception machinery; if
> throw and catch are always in the same object and everything
> in between register-number-agnostic then the only flaw would
> be not mentioning that in the commit message.)
> 
> brgds, H-P


[PATCH v2 7/7] aarch64,arm: Move branch-protection data to targets

2023-11-03 Thread Szabolcs Nagy
The branch-protection types are target specific, not the same on arm
and aarch64.  This currently affects pac-ret+b-key, but there will be
a new type on aarch64 that is not relevant for arm.

gcc/ChangeLog:

* config/aarch64/aarch64-opts.h (enum aarch64_key_type): Rename to ...
(enum aarch_key_type): ... this.
* config/aarch64/aarch64.cc (aarch_handle_no_branch_protection): Copy.
(aarch_handle_standard_branch_protection): Copy.
(aarch_handle_pac_ret_protection): Copy.
(aarch_handle_pac_ret_leaf): Copy.
(aarch_handle_pac_ret_b_key): Copy.
(aarch_handle_bti_protection): Copy.
* config/arm/aarch-common.cc (aarch_handle_no_branch_protection):
Remove.
(aarch_handle_standard_branch_protection): Remove.
(aarch_handle_pac_ret_protection): Remove.
(aarch_handle_pac_ret_leaf): Remove.
(aarch_handle_pac_ret_b_key): Remove.
(aarch_handle_bti_protection): Remove.
* config/arm/aarch-common.h (enum aarch_key_type): Remove.
(struct aarch_branch_protect_type): Declare.
* config/arm/arm-c.cc (arm_cpu_builtins): Remove aarch_ra_sign_key.
* config/arm/arm.cc (aarch_handle_no_branch_protection): Copy.
(aarch_handle_standard_branch_protection): Copy.
(aarch_handle_pac_ret_protection): Copy.
(aarch_handle_pac_ret_leaf): Copy.
(aarch_handle_bti_protection): Copy.
(arm_configure_build_target): Copy.
* config/arm/arm.opt: Remove aarch_ra_sign_key.
---
unchanged compared to v1.
---
 gcc/config/aarch64/aarch64-opts.h |  6 ++--
 gcc/config/aarch64/aarch64.cc | 55 +++
 gcc/config/arm/aarch-common.cc| 55 ---
 gcc/config/arm/aarch-common.h | 11 +++
 gcc/config/arm/arm-c.cc   |  2 --
 gcc/config/arm/arm.cc | 52 +
 gcc/config/arm/arm.opt|  3 --
 7 files changed, 109 insertions(+), 75 deletions(-)

diff --git a/gcc/config/aarch64/aarch64-opts.h 
b/gcc/config/aarch64/aarch64-opts.h
index 831e28ab52a..1abae1442b5 100644
--- a/gcc/config/aarch64/aarch64-opts.h
+++ b/gcc/config/aarch64/aarch64-opts.h
@@ -103,9 +103,9 @@ enum stack_protector_guard {
 };
 
 /* The key type that -msign-return-address should use.  */
-enum aarch64_key_type {
-  AARCH64_KEY_A,
-  AARCH64_KEY_B
+enum aarch_key_type {
+  AARCH_KEY_A,
+  AARCH_KEY_B
 };
 
 /* An enum specifying how to handle load and store pairs using
diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc
index 4f7f707b675..9739223831f 100644
--- a/gcc/config/aarch64/aarch64.cc
+++ b/gcc/config/aarch64/aarch64.cc
@@ -18620,6 +18620,61 @@ aarch64_set_asm_isa_flags (aarch64_feature_flags flags)
   aarch64_set_asm_isa_flags (_options, flags);
 }
 
+static void
+aarch_handle_no_branch_protection (void)
+{
+  aarch_ra_sign_scope = AARCH_FUNCTION_NONE;
+  aarch_enable_bti = 0;
+}
+
+static void
+aarch_handle_standard_branch_protection (void)
+{
+  aarch_ra_sign_scope = AARCH_FUNCTION_NON_LEAF;
+  aarch_ra_sign_key = AARCH_KEY_A;
+  aarch_enable_bti = 1;
+}
+
+static void
+aarch_handle_pac_ret_protection (void)
+{
+  aarch_ra_sign_scope = AARCH_FUNCTION_NON_LEAF;
+  aarch_ra_sign_key = AARCH_KEY_A;
+}
+
+static void
+aarch_handle_pac_ret_leaf (void)
+{
+  aarch_ra_sign_scope = AARCH_FUNCTION_ALL;
+}
+
+static void
+aarch_handle_pac_ret_b_key (void)
+{
+  aarch_ra_sign_key = AARCH_KEY_B;
+}
+
+static void
+aarch_handle_bti_protection (void)
+{
+  aarch_enable_bti = 1;
+}
+
+static const struct aarch_branch_protect_type aarch_pac_ret_subtypes[] = {
+  { "leaf", false, aarch_handle_pac_ret_leaf, NULL, 0 },
+  { "b-key", false, aarch_handle_pac_ret_b_key, NULL, 0 },
+  { NULL, false, NULL, NULL, 0 }
+};
+
+const struct aarch_branch_protect_type aarch_branch_protect_types[] = {
+  { "none", true, aarch_handle_no_branch_protection, NULL, 0 },
+  { "standard", true, aarch_handle_standard_branch_protection, NULL, 0 },
+  { "pac-ret", false, aarch_handle_pac_ret_protection, aarch_pac_ret_subtypes,
+ARRAY_SIZE (aarch_pac_ret_subtypes) },
+  { "bti", false, aarch_handle_bti_protection, NULL, 0 },
+  { NULL, false, NULL, NULL, 0 }
+};
+
 /* Implement TARGET_OPTION_OVERRIDE.  This is called once in the beginning
and is used to parse the -m{cpu,tune,arch} strings and setup the initial
tuning structs.  In particular it must set selected_tune and
diff --git a/gcc/config/arm/aarch-common.cc b/gcc/config/arm/aarch-common.cc
index 159c61b786c..92e1248f83f 100644
--- a/gcc/config/arm/aarch-common.cc
+++ b/gcc/config/arm/aarch-common.cc
@@ -659,61 +659,6 @@ arm_md_asm_adjust (vec , vec & 
/*inputs*/,
   return saw_asm_flag ? seq : NULL;
 }
 
-static void
-aarch_handle_no_branch_protection (void)
-{
-  aarch_ra_sign_scope = AARCH_FUNCTION_NONE;
-  aarch_enable_bti = 0;
-}
-
-static void
-aarch_handle_standard_branch_protection (void)
-{
-  aarch_ra_sign_scope = 

[PATCH v2 4/7] aarch64: Disable branch-protection for pcs tests

2023-11-03 Thread Szabolcs Nagy
The tests manipulate the return address in abitest-2.h and thus not
compatible with -mbranch-protection=pac-ret+leaf or
-mbranch-protection=gcs.

gcc/testsuite/ChangeLog:

* gcc.target/aarch64/aapcs64/func-ret-1.c: Disable branch-protection.
* gcc.target/aarch64/aapcs64/func-ret-2.c: Likewise.
* gcc.target/aarch64/aapcs64/func-ret-3.c: Likewise.
* gcc.target/aarch64/aapcs64/func-ret-4.c: Likewise.
* gcc.target/aarch64/aapcs64/func-ret-64x1_1.c: Likewise.
---
unchanged compared to v1
already approved at
https://gcc.gnu.org/pipermail/gcc-patches/2023-September/629353.html
---
 gcc/testsuite/gcc.target/aarch64/aapcs64/func-ret-1.c  | 1 +
 gcc/testsuite/gcc.target/aarch64/aapcs64/func-ret-2.c  | 1 +
 gcc/testsuite/gcc.target/aarch64/aapcs64/func-ret-3.c  | 1 +
 gcc/testsuite/gcc.target/aarch64/aapcs64/func-ret-4.c  | 1 +
 gcc/testsuite/gcc.target/aarch64/aapcs64/func-ret-64x1_1.c | 1 +
 5 files changed, 5 insertions(+)

diff --git a/gcc/testsuite/gcc.target/aarch64/aapcs64/func-ret-1.c 
b/gcc/testsuite/gcc.target/aarch64/aapcs64/func-ret-1.c
index 5405e1e4920..7bd7757efe6 100644
--- a/gcc/testsuite/gcc.target/aarch64/aapcs64/func-ret-1.c
+++ b/gcc/testsuite/gcc.target/aarch64/aapcs64/func-ret-1.c
@@ -4,6 +4,7 @@
AAPCS64 \S 4.1.  */
 
 /* { dg-do run { target aarch64*-*-* } } */
+/* { dg-additional-options "-mbranch-protection=none" } */
 /* { dg-additional-sources "abitest.S" } */
 
 #ifndef IN_FRAMEWORK
diff --git a/gcc/testsuite/gcc.target/aarch64/aapcs64/func-ret-2.c 
b/gcc/testsuite/gcc.target/aarch64/aapcs64/func-ret-2.c
index 6b171c46fbb..85a822ace4a 100644
--- a/gcc/testsuite/gcc.target/aarch64/aapcs64/func-ret-2.c
+++ b/gcc/testsuite/gcc.target/aarch64/aapcs64/func-ret-2.c
@@ -4,6 +4,7 @@
Homogeneous floating-point aggregate types are covered in func-ret-3.c.  */
 
 /* { dg-do run { target aarch64*-*-* } } */
+/* { dg-additional-options "-mbranch-protection=none" } */
 /* { dg-additional-sources "abitest.S" } */
 
 #ifndef IN_FRAMEWORK
diff --git a/gcc/testsuite/gcc.target/aarch64/aapcs64/func-ret-3.c 
b/gcc/testsuite/gcc.target/aarch64/aapcs64/func-ret-3.c
index ad312b675b9..1d35ebf14b4 100644
--- a/gcc/testsuite/gcc.target/aarch64/aapcs64/func-ret-3.c
+++ b/gcc/testsuite/gcc.target/aarch64/aapcs64/func-ret-3.c
@@ -4,6 +4,7 @@
in AAPCS64 \S 4.3.5.  */
 
 /* { dg-do run { target aarch64-*-* } } */
+/* { dg-additional-options "-mbranch-protection=none" } */
 /* { dg-additional-sources "abitest.S" } */
 /* { dg-require-effective-target aarch64_big_endian } */
 
diff --git a/gcc/testsuite/gcc.target/aarch64/aapcs64/func-ret-4.c 
b/gcc/testsuite/gcc.target/aarch64/aapcs64/func-ret-4.c
index af05fbe9fdf..15e1408c62d 100644
--- a/gcc/testsuite/gcc.target/aarch64/aapcs64/func-ret-4.c
+++ b/gcc/testsuite/gcc.target/aarch64/aapcs64/func-ret-4.c
@@ -5,6 +5,7 @@
are treated as general composite types.  */
 
 /* { dg-do run { target aarch64*-*-* } } */
+/* { dg-additional-options "-mbranch-protection=none" } */
 /* { dg-additional-sources "abitest.S" } */
 /* { dg-require-effective-target aarch64_big_endian } */
 
diff --git a/gcc/testsuite/gcc.target/aarch64/aapcs64/func-ret-64x1_1.c 
b/gcc/testsuite/gcc.target/aarch64/aapcs64/func-ret-64x1_1.c
index 05957e2dcae..fe7bbb6a835 100644
--- a/gcc/testsuite/gcc.target/aarch64/aapcs64/func-ret-64x1_1.c
+++ b/gcc/testsuite/gcc.target/aarch64/aapcs64/func-ret-64x1_1.c
@@ -3,6 +3,7 @@
   Test 64-bit singleton vector types which should be in FP/SIMD registers.  */
 
 /* { dg-do run { target aarch64*-*-* } } */
+/* { dg-additional-options "-mbranch-protection=none" } */
 /* { dg-additional-sources "abitest.S" } */
 
 #ifndef IN_FRAMEWORK
-- 
2.25.1



[PATCH v2 2/7] aarch64: Do not force a stack frame for EH returns

2023-11-03 Thread Szabolcs Nagy
EH returns no longer rely on clobbering the return address on the stack
so forcing a stack frame is not necessary.

This does not actually change the code gen for the unwinder since there
are calls before the EH return.

gcc/ChangeLog:

* config/aarch64/aarch64.cc (aarch64_needs_frame_chain): Do not
force frame chain for eh_return.
---
unchanged compared to v1
already approved at:
https://gcc.gnu.org/pipermail/gcc-patches/2023-September/629346.html
---
 gcc/config/aarch64/aarch64.cc | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc
index 5cdb33dd3dc..88594bed8ce 100644
--- a/gcc/config/aarch64/aarch64.cc
+++ b/gcc/config/aarch64/aarch64.cc
@@ -8492,8 +8492,7 @@ aarch64_output_probe_sve_stack_clash (rtx base, rtx 
adjustment,
 static bool
 aarch64_needs_frame_chain (void)
 {
-  /* Force a frame chain for EH returns so the return address is at FP+8.  */
-  if (frame_pointer_needed || crtl->calls_eh_return)
+  if (frame_pointer_needed)
 return true;
 
   /* A leaf function cannot have calls or write LR.  */
-- 
2.25.1



[PATCH v2 6/7] aarch64,arm: Fix branch-protection= parsing

2023-11-03 Thread Szabolcs Nagy
Refactor the parsing to have a single API and fix a few parsing issues:

- Different handling of "bti+none" and "none+bti": these should be
  rejected because "none" can only appear alone.

- Accepted empty strings such as "bti++pac-ret" or "bti+", this bug
  was caused by using strtok_r.

- Memory got leaked (str_root was never freed). And two buffers got
  allocated when one is enough.

The callbacks now have no failure mode, only parsing can fail and
all failures are handled locally.  The "-mbranch-protection=" vs
"target("branch-protection=")" difference in the error message is
handled by a separate argument to aarch_validate_mbranch_protection.

gcc/ChangeLog:

* config/aarch64/aarch64.cc (aarch64_override_options): Update.
(aarch64_handle_attr_branch_protection): Update.
* config/arm/aarch-common-protos.h (aarch_parse_branch_protection):
Remove.
(aarch_validate_mbranch_protection): Add new argument.
* config/arm/aarch-common.cc (aarch_handle_no_branch_protection):
Update.
(aarch_handle_standard_branch_protection): Update.
(aarch_handle_pac_ret_protection): Update.
(aarch_handle_pac_ret_leaf): Update.
(aarch_handle_pac_ret_b_key): Update.
(aarch_handle_bti_protection): Update.
(aarch_parse_branch_protection): Remove.
(next_tok): New.
(aarch_validate_mbranch_protection): Rewrite.
* config/arm/aarch-common.h (struct aarch_branch_protect_type):
Add field "alone".
* config/arm/arm.cc (arm_configure_build_target): Update.

gcc/testsuite/ChangeLog:

* gcc.target/aarch64/branch-protection-attr.c: Update.
* gcc.target/aarch64/branch-protection-option.c: Update.
---
v2: merge tests updates into the patch
error message is not changed, see previous discussion:
https://gcc.gnu.org/pipermail/gcc-patches/2023-October/633945.html
---
 gcc/config/aarch64/aarch64.cc |  37 +--
 gcc/config/arm/aarch-common-protos.h  |   5 +-
 gcc/config/arm/aarch-common.cc| 214 --
 gcc/config/arm/aarch-common.h |  14 +-
 gcc/config/arm/arm.cc |   3 +-
 .../aarch64/branch-protection-attr.c  |   6 +-
 .../aarch64/branch-protection-option.c|   2 +-
 7 files changed, 113 insertions(+), 168 deletions(-)

diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc
index f8e8fefc8d8..4f7f707b675 100644
--- a/gcc/config/aarch64/aarch64.cc
+++ b/gcc/config/aarch64/aarch64.cc
@@ -18642,7 +18642,8 @@ aarch64_override_options (void)
 aarch64_validate_sls_mitigation (aarch64_harden_sls_string);
 
   if (aarch64_branch_protection_string)
-aarch_validate_mbranch_protection (aarch64_branch_protection_string);
+aarch_validate_mbranch_protection (aarch64_branch_protection_string,
+  "-mbranch-protection=");
 
   /* -mcpu=CPU is shorthand for -march=ARCH_FOR_CPU, -mtune=CPU.
  If either of -march or -mtune is given, they override their
@@ -19016,34 +19017,12 @@ aarch64_handle_attr_cpu (const char *str)
 
 /* Handle the argument STR to the branch-protection= attribute.  */
 
- static bool
- aarch64_handle_attr_branch_protection (const char* str)
- {
-  char *err_str = (char *) xmalloc (strlen (str) + 1);
-  enum aarch_parse_opt_result res = aarch_parse_branch_protection (str,
-  _str);
-  bool success = false;
-  switch (res)
-{
- case AARCH_PARSE_MISSING_ARG:
-   error ("missing argument to % pragma 
or"
- " attribute");
-   break;
- case AARCH_PARSE_INVALID_ARG:
-   error ("invalid protection type %qs in % pragma or attribute", err_str);
-   break;
- case AARCH_PARSE_OK:
-   success = true;
-  /* Fall through.  */
- case AARCH_PARSE_INVALID_FEATURE:
-   break;
- default:
-   gcc_unreachable ();
-}
-  free (err_str);
-  return success;
- }
+static bool
+aarch64_handle_attr_branch_protection (const char* str)
+{
+  return aarch_validate_mbranch_protection (str,
+   "target(\"branch-protection=\")");
+}
 
 /* Handle the argument STR to the tune= target attribute.  */
 
diff --git a/gcc/config/arm/aarch-common-protos.h 
b/gcc/config/arm/aarch-common-protos.h
index f8cb6562096..75ffdfbb050 100644
--- a/gcc/config/arm/aarch-common-protos.h
+++ b/gcc/config/arm/aarch-common-protos.h
@@ -159,10 +159,7 @@ rtx_insn *arm_md_asm_adjust (vec , vec & 
/*inputs*/,
 vec , HARD_REG_SET _regs,
 location_t loc);
 
-/* Parsing routine for branch-protection common to AArch64 and Arm.  */
-enum aarch_parse_opt_result aarch_parse_branch_protection (const char*, 
char**);
-
 /* Validation routine for branch-protection common to AArch64 and Arm.  */
-bool aarch_validate_mbranch_protection (const char *);
+bool 

[PATCH v2 3/7] aarch64: Add eh_return compile tests

2023-11-03 Thread Szabolcs Nagy
gcc/testsuite/ChangeLog:

* gcc.target/aarch64/eh_return-2.c: New test.
* gcc.target/aarch64/eh_return-3.c: New test.

---
v2: check-function-bodies in eh_return-3.c
(this is not very robust, but easier to read)
---
 .../gcc.target/aarch64/eh_return-2.c  |  9 ++
 .../gcc.target/aarch64/eh_return-3.c  | 30 +++
 2 files changed, 39 insertions(+)
 create mode 100644 gcc/testsuite/gcc.target/aarch64/eh_return-2.c
 create mode 100644 gcc/testsuite/gcc.target/aarch64/eh_return-3.c

diff --git a/gcc/testsuite/gcc.target/aarch64/eh_return-2.c 
b/gcc/testsuite/gcc.target/aarch64/eh_return-2.c
new file mode 100644
index 000..4a9d124e891
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/eh_return-2.c
@@ -0,0 +1,9 @@
+/* { dg-do compile } */
+/* { dg-final { scan-assembler "add\tsp, sp, x5" } } */
+/* { dg-final { scan-assembler "br\tx6" } } */
+
+void
+foo (unsigned long off, void *handler)
+{
+  __builtin_eh_return (off, handler);
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/eh_return-3.c 
b/gcc/testsuite/gcc.target/aarch64/eh_return-3.c
new file mode 100644
index 000..bfbe92af427
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/eh_return-3.c
@@ -0,0 +1,30 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mbranch-protection=pac-ret+leaf" } */
+/* { dg-final { check-function-bodies "**" "" "" } } */
+
+/*
+**foo:
+** hint25 // paciasp
+** stp x0, x1, .*
+** stp x2, x3, .*
+** cbz w2, .*
+** mov x4, 0
+** ldp x2, x3, .*
+** ldp x0, x1, .*
+** cbz x4, .*
+** add sp, sp, x5
+** br  x6
+** hint29 // autiasp
+** ret
+** mov x5, x0
+** mov x6, x1
+** mov x4, 1
+** b   .*
+*/
+void
+foo (unsigned long off, void *handler, int c)
+{
+  if (c)
+return;
+  __builtin_eh_return (off, handler);
+}
-- 
2.25.1



[PATCH v2 5/7] aarch64,arm: Remove accepted_branch_protection_string

2023-11-03 Thread Szabolcs Nagy
On aarch64 this caused ICE with pragma push_options since

  commit ae54c1b09963779c5c3914782324ff48af32e2f1
  Author: Wilco Dijkstra 
  CommitDate: 2022-06-01 18:13:57 +0100

  AArch64: Cleanup option processing code

The failure is at pop_options:

internal compiler error: ‘global_options’ are modified in local context

On arm the variable was unused.

gcc/ChangeLog:

* config/aarch64/aarch64.cc (aarch64_override_options_after_change_1):
Do not override branch_protection options.
(aarch64_override_options): Remove accepted_branch_protection_string.
* config/arm/aarch-common.cc (BRANCH_PROTECT_STR_MAX): Remove.
(aarch_parse_branch_protection): Remove
accepted_branch_protection_string.
* config/arm/arm.cc: Likewise.
---
unchanged from v1
---
 gcc/config/aarch64/aarch64.cc  | 10 +-
 gcc/config/arm/aarch-common.cc | 16 
 gcc/config/arm/arm.cc  |  2 --
 3 files changed, 1 insertion(+), 27 deletions(-)

diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc
index 88594bed8ce..f8e8fefc8d8 100644
--- a/gcc/config/aarch64/aarch64.cc
+++ b/gcc/config/aarch64/aarch64.cc
@@ -323,8 +323,6 @@ bool aarch64_pcrelative_literal_loads;
 /* Global flag for whether frame pointer is enabled.  */
 bool aarch64_use_frame_pointer;
 
-char *accepted_branch_protection_string = NULL;
-
 /* Support for command line parsing of boolean flags in the tuning
structures.  */
 struct aarch64_flag_desc
@@ -18101,12 +18099,6 @@ aarch64_adjust_generic_arch_tuning (struct tune_params 
_tune)
 static void
 aarch64_override_options_after_change_1 (struct gcc_options *opts)
 {
-  if (accepted_branch_protection_string)
-{
-  opts->x_aarch64_branch_protection_string
-   = xstrdup (accepted_branch_protection_string);
-}
-
   /* PR 70044: We have to be careful about being called multiple times for the
  same function.  This means all changes should be repeatable.  */
 
@@ -18715,7 +18707,7 @@ aarch64_override_options (void)
   /* Return address signing is currently not supported for ILP32 targets.  For
  LP64 targets use the configured option in the absence of a command-line
  option for -mbranch-protection.  */
-  if (!TARGET_ILP32 && accepted_branch_protection_string == NULL)
+  if (!TARGET_ILP32 && aarch64_branch_protection_string == NULL)
 {
 #ifdef TARGET_ENABLE_PAC_RET
   aarch_ra_sign_scope = AARCH_FUNCTION_NON_LEAF;
diff --git a/gcc/config/arm/aarch-common.cc b/gcc/config/arm/aarch-common.cc
index 5b96ff4c2e8..cbc7f68a8bf 100644
--- a/gcc/config/arm/aarch-common.cc
+++ b/gcc/config/arm/aarch-common.cc
@@ -659,9 +659,6 @@ arm_md_asm_adjust (vec , vec & /*inputs*/,
   return saw_asm_flag ? seq : NULL;
 }
 
-#define BRANCH_PROTECT_STR_MAX 255
-extern char *accepted_branch_protection_string;
-
 static enum aarch_parse_opt_result
 aarch_handle_no_branch_protection (char* str, char* rest)
 {
@@ -812,19 +809,6 @@ aarch_parse_branch_protection (const char *const_str, 
char** last_str)
   else
*last_str = NULL;
 }
-
-  if (res == AARCH_PARSE_OK)
-{
-  /* If needed, alloc the accepted string then copy in const_str.
-   Used by override_option_after_change_1.  */
-  if (!accepted_branch_protection_string)
-   accepted_branch_protection_string
- = (char *) xmalloc (BRANCH_PROTECT_STR_MAX + 1);
-  strncpy (accepted_branch_protection_string, const_str,
-  BRANCH_PROTECT_STR_MAX + 1);
-  /* Forcibly null-terminate.  */
-  accepted_branch_protection_string[BRANCH_PROTECT_STR_MAX] = '\0';
-}
   return res;
 }
 
diff --git a/gcc/config/arm/arm.cc b/gcc/config/arm/arm.cc
index 6e933c80183..f49312cace0 100644
--- a/gcc/config/arm/arm.cc
+++ b/gcc/config/arm/arm.cc
@@ -2424,8 +2424,6 @@ const struct tune_params arm_fa726te_tune =
   tune_params::SCHED_AUTOPREF_OFF
 };
 
-char *accepted_branch_protection_string = NULL;
-
 /* Auto-generated CPU, FPU and architecture tables.  */
 #include "arm-cpu-data.h"
 
-- 
2.25.1



[PATCH v2 1/7] aarch64: Use br instead of ret for eh_return

2023-11-03 Thread Szabolcs Nagy
The expected way to handle eh_return is to pass the stack adjustment
offset and landing pad address via

  EH_RETURN_STACKADJ_RTX
  EH_RETURN_HANDLER_RTX

to the epilogue that is shared between normal return paths and the
eh_return paths.  EH_RETURN_HANDLER_RTX is the stack slot of the
return address that is overwritten with the landing pad in the
eh_return case and EH_RETURN_STACKADJ_RTX is a register added to sp
right before return and it is set to 0 in the normal return case.

The issue with this design is that eh_return and normal return may
require different return sequence but there is no way to distinguish
the two cases in the epilogue (the stack adjustment may be 0 in the
eh_return case too).

The reason eh_return and normal return requires different return
sequence is that control flow integrity hardening may need to treat
eh_return as a forward-edge transfer (it is not returning to the
previous stack frame) and normal return as a backward-edge one.
In case of AArch64 forward-edge is protected by BTI and requires br
instruction and backward-edge is protected by PAUTH or GCS and
requires ret (or authenticated ret) instruction.

This patch resolves the issue by introducing EH_RETURN_TAKEN_RTX that
is a flag set to 1 in the eh_return path and 0 in normal return paths.
Branching on the EH_RETURN_TAKEN_RTX flag, the right return sequence
can be used in the epilogue.

The handler could be passed the old way via clobbering the return
address, but since now the eh_return case can be distinguished, the
handler can be in a different register than x30 and no stack frame
is needed for eh_return.

This patch fixes a return to anywhere gadget in the unwinder with
existing standard branch protection as well as makes EH return
compatible with the Guarded Control Stack (GCS) extension.

Some tests are adjusted because eh_return no longer prevents pac-ret
in the normal return path.

gcc/ChangeLog:

* config/aarch64/aarch64-protos.h (aarch64_eh_return_handler_rtx):
Remove.
* config/aarch64/aarch64.cc (aarch64_return_address_signing_enabled):
Sign return address even in functions with eh_return.
(aarch64_expand_epilogue): Conditionally return with br or ret.
(aarch64_eh_return_handler_rtx): Remove.
* config/aarch64/aarch64.h (EH_RETURN_TAKEN_RTX): Define.
(EH_RETURN_STACKADJ_RTX): Change to R5.
(EH_RETURN_HANDLER_RTX): Change to R6.
* df-scan.cc: Handle EH_RETURN_TAKEN_RTX.
* doc/tm.texi: Regenerate.
* doc/tm.texi.in: Document EH_RETURN_TAKEN_RTX.
* except.cc (expand_eh_return): Handle EH_RETURN_TAKEN_RTX.

gcc/testsuite/ChangeLog:

* gcc.target/aarch64/return_address_sign_1.c: Move func4 to ...
* gcc.target/aarch64/return_address_sign_2.c: ... here and fix the
scan asm check.
* gcc.target/aarch64/return_address_sign_b_1.c: Move func4 to ...
* gcc.target/aarch64/return_address_sign_b_2.c: ... here and fix the
scan asm check.

---
v2:
- Introduce EH_RETURN_TAKEN_RTX instead of abusing EH_RETURN_STACKADJ_RTX.
- Merge test fixes.
---
 gcc/config/aarch64/aarch64-protos.h   |  1 -
 gcc/config/aarch64/aarch64.cc | 88 ++-
 gcc/config/aarch64/aarch64.h  |  9 +-
 gcc/df-scan.cc| 10 +++
 gcc/doc/tm.texi   | 12 +++
 gcc/doc/tm.texi.in| 12 +++
 gcc/except.cc | 20 +
 .../aarch64/return_address_sign_1.c   | 13 +--
 .../aarch64/return_address_sign_2.c   | 17 +++-
 .../aarch64/return_address_sign_b_1.c | 11 ---
 .../aarch64/return_address_sign_b_2.c | 17 +++-
 11 files changed, 116 insertions(+), 94 deletions(-)

diff --git a/gcc/config/aarch64/aarch64-protos.h 
b/gcc/config/aarch64/aarch64-protos.h
index 60a55f4bc19..80296024f04 100644
--- a/gcc/config/aarch64/aarch64-protos.h
+++ b/gcc/config/aarch64/aarch64-protos.h
@@ -859,7 +859,6 @@ machine_mode aarch64_hard_regno_caller_save_mode (unsigned, 
unsigned,
   machine_mode);
 int aarch64_uxt_size (int, HOST_WIDE_INT);
 int aarch64_vec_fpconst_pow_of_2 (rtx);
-rtx aarch64_eh_return_handler_rtx (void);
 rtx aarch64_mask_from_zextract_ops (rtx, rtx);
 const char *aarch64_output_move_struct (rtx *operands);
 rtx aarch64_return_addr_rtx (void);
diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc
index a28b66acf6a..5cdb33dd3dc 100644
--- a/gcc/config/aarch64/aarch64.cc
+++ b/gcc/config/aarch64/aarch64.cc
@@ -9113,17 +9113,6 @@ aarch64_return_address_signing_enabled (void)
   /* This function should only be called after frame laid out.   */
   gcc_assert (cfun->machine->frame.laid_out);
 
-  /* Turn return address signing off in any function that uses
- __builtin_eh_return.  The address passed to __builtin_eh_return
- is not signed so either it has 

[PATCH v2 0/7] aarch64 GCS preliminary patches

2023-11-03 Thread Szabolcs Nagy
I'm working on Guarded Control Stack support for aarch64 and have a
set of patches that are needed for GCS but seem useful without it so
makes sense to review them separately from the rest of the GCS work.

previous version:
https://gcc.gnu.org/pipermail/gcc-patches/2023-August/628123.html

Szabolcs Nagy (7):
  aarch64: Use br instead of ret for eh_return
  aarch64: Do not force a stack frame for EH returns
  aarch64: Add eh_return compile tests
  aarch64: Disable branch-protection for pcs tests
  aarch64,arm: Remove accepted_branch_protection_string
  aarch64,arm: Fix branch-protection= parsing
  aarch64,arm: Move branch-protection data to targets

 gcc/config/aarch64/aarch64-opts.h |   6 +-
 gcc/config/aarch64/aarch64-protos.h   |   1 -
 gcc/config/aarch64/aarch64.cc | 193 +++
 gcc/config/aarch64/aarch64.h  |   9 +-
 gcc/config/arm/aarch-common-protos.h  |   5 +-
 gcc/config/arm/aarch-common.cc| 229 +-
 gcc/config/arm/aarch-common.h |  25 +-
 gcc/config/arm/arm-c.cc   |   2 -
 gcc/config/arm/arm.cc |  57 -
 gcc/config/arm/arm.opt|   3 -
 gcc/df-scan.cc|  10 +
 gcc/doc/tm.texi   |  12 +
 gcc/doc/tm.texi.in|  12 +
 gcc/except.cc |  20 ++
 .../gcc.target/aarch64/aapcs64/func-ret-1.c   |   1 +
 .../gcc.target/aarch64/aapcs64/func-ret-2.c   |   1 +
 .../gcc.target/aarch64/aapcs64/func-ret-3.c   |   1 +
 .../gcc.target/aarch64/aapcs64/func-ret-4.c   |   1 +
 .../aarch64/aapcs64/func-ret-64x1_1.c |   1 +
 .../aarch64/branch-protection-attr.c  |   6 +-
 .../aarch64/branch-protection-option.c|   2 +-
 .../gcc.target/aarch64/eh_return-2.c  |   9 +
 .../gcc.target/aarch64/eh_return-3.c  |  30 +++
 .../aarch64/return_address_sign_1.c   |  13 +-
 .../aarch64/return_address_sign_2.c   |  17 +-
 .../aarch64/return_address_sign_b_1.c |  11 -
 .../aarch64/return_address_sign_b_2.c |  17 +-
 27 files changed, 356 insertions(+), 338 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/aarch64/eh_return-2.c
 create mode 100644 gcc/testsuite/gcc.target/aarch64/eh_return-3.c

-- 
2.25.1



Re: [PATCH 10/11] aarch64: Fix branch-protection error message tests

2023-10-23 Thread Szabolcs Nagy
The 10/13/2023 11:29, Richard Earnshaw (lists) wrote:
> On 05/09/2023 16:00, Richard Sandiford via Gcc-patches wrote:
> > Szabolcs Nagy  writes:
> >> @@ -4,19 +4,19 @@ void __attribute__ ((target("branch-protection=leaf")))
> >>  foo1 ()
> >>  {
> >>  }
> >> -/* { dg-error {invalid protection type 'leaf' in 
> >> 'target\("branch-protection="\)' pragma or attribute} "" { target *-*-* } 
> >> 5 } */
> >> +/* { dg-error {invalid argument 'leaf' for 
> >> 'target\("branch-protection="\)'} "" { target *-*-* } 5 } */
> >>  /* { dg-error {pragma or attribute 'target\("branch-protection=leaf"\)' 
> >> is not valid} "" { target *-*-* } 5 } */
> 
> 'leaf' is really a modifier for the other branch protection strategies; 
> perhaps it would be better to describe it as that.

this error message is used for arbitrary strings, e.g.
branch-protection=foobar or branch-protection=bti+foo.

with further processing we can figure out that 'leaf'
is a valid modifier for pac-ret and change the error to

invalid placement of modifier 'leaf' in 'target("branch-protection=")'

otherwise fall back to

invalid argument 'foobar' for 'target("branch-protection=")'.

does that help?

(currently 'leaf' and 'b-key' are the only modifiers.)

> But this brings up another issue/question.  If the compiler has been 
> configured with, say, '--enable-branch-protection=standard' or some other 
> variety, is there (or do we want) a way to extend that to leaf functions 
> without changing the underlying strategy?

there are several limitations in branch-protection handling,
i'm only fixing bugs and assumptions that don't work when arm
and aarch64 has different set of branch-protection options.

i think it can be useful to add/remove branch-protection options
incrementally in cflags instead of having one string, but it's
not obvious to me how to get there.

> >>  void __attribute__ ((target("branch-protection=none+pac-ret")))
> >>  foo2 ()
> >>  {
> >>  }
> >> -/* { dg-error "unexpected 'pac-ret' after 'none'" "" { target *-*-* } 12 
> >> } */
> >> +/* { dg-error {argument 'none' can only appear alone in 
> >> 'target\("branch-protection="\)'} "" { target *-*-* } 12 } */
> 
> Or maybe better still: "branch protection strategies 'none' and 'pac-ret' are 
> incompatible".

i can make this change, but e.g.

in case of branch-protection=standard+bti+foo it would
say "'standard' and 'bti' are incompatible" which can be
surprising given that standard includes bti, meanwhile
"'standard' can only appear alone" explains the problem.

> But this is all a matter of taste.
> 
> However, this patch should be merged with the patch that changes the error 
> messages.  Or has that already gone in?

i can do that merge.


[PATCH 11/11] aarch64,arm: Move branch-protection data to targets

2023-08-22 Thread Szabolcs Nagy via Gcc-patches
The branch-protection types are target specific, not the same on arm
and aarch64.  This currently affects pac-ret+b-key, but there will be
a new type on aarch64 that is not relevant for arm.

gcc/ChangeLog:

* config/aarch64/aarch64-opts.h (enum aarch64_key_type): Rename to ...
(enum aarch_key_type): ... this.
* config/aarch64/aarch64.cc (aarch_handle_no_branch_protection): Copy.
(aarch_handle_standard_branch_protection): Copy.
(aarch_handle_pac_ret_protection): Copy.
(aarch_handle_pac_ret_leaf): Copy.
(aarch_handle_pac_ret_b_key): Copy.
(aarch_handle_bti_protection): Copy.
* config/arm/aarch-common.cc (aarch_handle_no_branch_protection):
Remove.
(aarch_handle_standard_branch_protection): Remove.
(aarch_handle_pac_ret_protection): Remove.
(aarch_handle_pac_ret_leaf): Remove.
(aarch_handle_pac_ret_b_key): Remove.
(aarch_handle_bti_protection): Remove.
* config/arm/aarch-common.h (enum aarch_key_type): Remove.
(struct aarch_branch_protect_type): Declare.
* config/arm/arm-c.cc (arm_cpu_builtins): Remove aarch_ra_sign_key.
* config/arm/arm.cc (aarch_handle_no_branch_protection): Copy.
(aarch_handle_standard_branch_protection): Copy.
(aarch_handle_pac_ret_protection): Copy.
(aarch_handle_pac_ret_leaf): Copy.
(aarch_handle_bti_protection): Copy.
(arm_configure_build_target): Copy.
* config/arm/arm.opt: Remove aarch_ra_sign_key.
---
 gcc/config/aarch64/aarch64-opts.h |  6 ++--
 gcc/config/aarch64/aarch64.cc | 55 +++
 gcc/config/arm/aarch-common.cc| 55 ---
 gcc/config/arm/aarch-common.h | 11 +++
 gcc/config/arm/arm-c.cc   |  2 --
 gcc/config/arm/arm.cc | 52 +
 gcc/config/arm/arm.opt|  3 --
 7 files changed, 109 insertions(+), 75 deletions(-)

diff --git a/gcc/config/aarch64/aarch64-opts.h 
b/gcc/config/aarch64/aarch64-opts.h
index 7e8f1babed8..75ef00b60d4 100644
--- a/gcc/config/aarch64/aarch64-opts.h
+++ b/gcc/config/aarch64/aarch64-opts.h
@@ -103,9 +103,9 @@ enum stack_protector_guard {
 };
 
 /* The key type that -msign-return-address should use.  */
-enum aarch64_key_type {
-  AARCH64_KEY_A,
-  AARCH64_KEY_B
+enum aarch_key_type {
+  AARCH_KEY_A,
+  AARCH_KEY_B
 };
 
 #endif
diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc
index 661ac12cacc..734980f78ec 100644
--- a/gcc/config/aarch64/aarch64.cc
+++ b/gcc/config/aarch64/aarch64.cc
@@ -18517,6 +18517,61 @@ aarch64_set_asm_isa_flags (aarch64_feature_flags flags)
   aarch64_set_asm_isa_flags (_options, flags);
 }
 
+static void
+aarch_handle_no_branch_protection (void)
+{
+  aarch_ra_sign_scope = AARCH_FUNCTION_NONE;
+  aarch_enable_bti = 0;
+}
+
+static void
+aarch_handle_standard_branch_protection (void)
+{
+  aarch_ra_sign_scope = AARCH_FUNCTION_NON_LEAF;
+  aarch_ra_sign_key = AARCH_KEY_A;
+  aarch_enable_bti = 1;
+}
+
+static void
+aarch_handle_pac_ret_protection (void)
+{
+  aarch_ra_sign_scope = AARCH_FUNCTION_NON_LEAF;
+  aarch_ra_sign_key = AARCH_KEY_A;
+}
+
+static void
+aarch_handle_pac_ret_leaf (void)
+{
+  aarch_ra_sign_scope = AARCH_FUNCTION_ALL;
+}
+
+static void
+aarch_handle_pac_ret_b_key (void)
+{
+  aarch_ra_sign_key = AARCH_KEY_B;
+}
+
+static void
+aarch_handle_bti_protection (void)
+{
+  aarch_enable_bti = 1;
+}
+
+static const struct aarch_branch_protect_type aarch_pac_ret_subtypes[] = {
+  { "leaf", false, aarch_handle_pac_ret_leaf, NULL, 0 },
+  { "b-key", false, aarch_handle_pac_ret_b_key, NULL, 0 },
+  { NULL, false, NULL, NULL, 0 }
+};
+
+const struct aarch_branch_protect_type aarch_branch_protect_types[] = {
+  { "none", true, aarch_handle_no_branch_protection, NULL, 0 },
+  { "standard", true, aarch_handle_standard_branch_protection, NULL, 0 },
+  { "pac-ret", false, aarch_handle_pac_ret_protection, aarch_pac_ret_subtypes,
+ARRAY_SIZE (aarch_pac_ret_subtypes) },
+  { "bti", false, aarch_handle_bti_protection, NULL, 0 },
+  { NULL, false, NULL, NULL, 0 }
+};
+
 /* Implement TARGET_OPTION_OVERRIDE.  This is called once in the beginning
and is used to parse the -m{cpu,tune,arch} strings and setup the initial
tuning structs.  In particular it must set selected_tune and
diff --git a/gcc/config/arm/aarch-common.cc b/gcc/config/arm/aarch-common.cc
index 159c61b786c..92e1248f83f 100644
--- a/gcc/config/arm/aarch-common.cc
+++ b/gcc/config/arm/aarch-common.cc
@@ -659,61 +659,6 @@ arm_md_asm_adjust (vec , vec & 
/*inputs*/,
   return saw_asm_flag ? seq : NULL;
 }
 
-static void
-aarch_handle_no_branch_protection (void)
-{
-  aarch_ra_sign_scope = AARCH_FUNCTION_NONE;
-  aarch_enable_bti = 0;
-}
-
-static void
-aarch_handle_standard_branch_protection (void)
-{
-  aarch_ra_sign_scope = AARCH_FUNCTION_NON_LEAF;
-  aarch_ra_sign_key = AARCH_KEY_A;
-  aarch_enable_bti = 1;
-}
-

[PATCH 05/11] aarch64: Add eh_return compile tests

2023-08-22 Thread Szabolcs Nagy via Gcc-patches
gcc/testsuite/ChangeLog:

* gcc.target/aarch64/eh_return-2.c: New test.
* gcc.target/aarch64/eh_return-3.c: New test.
---
 gcc/testsuite/gcc.target/aarch64/eh_return-2.c |  9 +
 gcc/testsuite/gcc.target/aarch64/eh_return-3.c | 14 ++
 2 files changed, 23 insertions(+)
 create mode 100644 gcc/testsuite/gcc.target/aarch64/eh_return-2.c
 create mode 100644 gcc/testsuite/gcc.target/aarch64/eh_return-3.c

diff --git a/gcc/testsuite/gcc.target/aarch64/eh_return-2.c 
b/gcc/testsuite/gcc.target/aarch64/eh_return-2.c
new file mode 100644
index 000..4a9d124e891
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/eh_return-2.c
@@ -0,0 +1,9 @@
+/* { dg-do compile } */
+/* { dg-final { scan-assembler "add\tsp, sp, x5" } } */
+/* { dg-final { scan-assembler "br\tx6" } } */
+
+void
+foo (unsigned long off, void *handler)
+{
+  __builtin_eh_return (off, handler);
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/eh_return-3.c 
b/gcc/testsuite/gcc.target/aarch64/eh_return-3.c
new file mode 100644
index 000..35989eee806
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/eh_return-3.c
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mbranch-protection=pac-ret+leaf" } */
+/* { dg-final { scan-assembler "add\tsp, sp, x5" } } */
+/* { dg-final { scan-assembler "br\tx6" } } */
+/* { dg-final { scan-assembler "hint\t25 // paciasp" } } */
+/* { dg-final { scan-assembler "hint\t29 // autiasp" } } */
+
+void
+foo (unsigned long off, void *handler, int c)
+{
+  if (c)
+return;
+  __builtin_eh_return (off, handler);
+}
-- 
2.25.1



[PATCH 10/11] aarch64: Fix branch-protection error message tests

2023-08-22 Thread Szabolcs Nagy via Gcc-patches
Update tests for the new branch-protection parser errors.

gcc/testsuite/ChangeLog:

* gcc.target/aarch64/branch-protection-attr.c: Update.
* gcc.target/aarch64/branch-protection-option.c: Update.
---
 gcc/testsuite/gcc.target/aarch64/branch-protection-attr.c   | 6 +++---
 gcc/testsuite/gcc.target/aarch64/branch-protection-option.c | 2 +-
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/gcc/testsuite/gcc.target/aarch64/branch-protection-attr.c 
b/gcc/testsuite/gcc.target/aarch64/branch-protection-attr.c
index 272000c2747..dae2a758a56 100644
--- a/gcc/testsuite/gcc.target/aarch64/branch-protection-attr.c
+++ b/gcc/testsuite/gcc.target/aarch64/branch-protection-attr.c
@@ -4,19 +4,19 @@ void __attribute__ ((target("branch-protection=leaf")))
 foo1 ()
 {
 }
-/* { dg-error {invalid protection type 'leaf' in 
'target\("branch-protection="\)' pragma or attribute} "" { target *-*-* } 5 } */
+/* { dg-error {invalid argument 'leaf' for 'target\("branch-protection="\)'} 
"" { target *-*-* } 5 } */
 /* { dg-error {pragma or attribute 'target\("branch-protection=leaf"\)' is not 
valid} "" { target *-*-* } 5 } */
 
 void __attribute__ ((target("branch-protection=none+pac-ret")))
 foo2 ()
 {
 }
-/* { dg-error "unexpected 'pac-ret' after 'none'" "" { target *-*-* } 12 } */
+/* { dg-error {argument 'none' can only appear alone in 
'target\("branch-protection="\)'} "" { target *-*-* } 12 } */
 /* { dg-error {pragma or attribute 
'target\("branch-protection=none\+pac-ret"\)' is not valid} "" { target *-*-* } 
12 } */
 
 void __attribute__ ((target("branch-protection=")))
 foo3 ()
 {
 }
-/* { dg-error {missing argument to 'target\("branch-protection="\)' pragma or 
attribute} "" { target *-*-* } 19 } */
+/* { dg-error {invalid argument '' for 'target\("branch-protection="\)'} "" { 
target *-*-* } 19 } */
 /* { dg-error {pragma or attribute 'target\("branch-protection="\)' is not 
valid} "" { target *-*-* } 19 } */
diff --git a/gcc/testsuite/gcc.target/aarch64/branch-protection-option.c 
b/gcc/testsuite/gcc.target/aarch64/branch-protection-option.c
index 1b3bf4ee2b8..e2f847a31c4 100644
--- a/gcc/testsuite/gcc.target/aarch64/branch-protection-option.c
+++ b/gcc/testsuite/gcc.target/aarch64/branch-protection-option.c
@@ -1,4 +1,4 @@
 /* { dg-do "compile" } */
 /* { dg-options "-mbranch-protection=leaf -mbranch-protection=none+pac-ret" } 
*/
 
-/* { dg-error "unexpected 'pac-ret' after 'none'"  "" { target *-*-* } 0 } */
+/* { dg-error "argument 'none' can only appear alone in 
'-mbranch-protection='" "" { target *-*-* } 0 } */
-- 
2.25.1



[PATCH 04/11] aarch64: Do not force a stack frame for EH returns

2023-08-22 Thread Szabolcs Nagy via Gcc-patches
EH returns no longer rely on clobbering the return address on the stack
so forcing a stack frame is not necessary.

This does not actually change the code gen for the unwinder since there
are calls before the EH return.

gcc/ChangeLog:

* config/aarch64/aarch64.cc (aarch64_needs_frame_chain): Do not
force frame chain for eh_return.
---
 gcc/config/aarch64/aarch64.cc | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc
index 36cd172d182..afdbf4213c1 100644
--- a/gcc/config/aarch64/aarch64.cc
+++ b/gcc/config/aarch64/aarch64.cc
@@ -8417,8 +8417,7 @@ aarch64_output_probe_sve_stack_clash (rtx base, rtx 
adjustment,
 static bool
 aarch64_needs_frame_chain (void)
 {
-  /* Force a frame chain for EH returns so the return address is at FP+8.  */
-  if (frame_pointer_needed || crtl->calls_eh_return)
+  if (frame_pointer_needed)
 return true;
 
   /* A leaf function cannot have calls or write LR.  */
-- 
2.25.1



[PATCH 09/11] aarch64,arm: Fix branch-protection= parsing

2023-08-22 Thread Szabolcs Nagy via Gcc-patches
Refactor the parsing to have a single API and fix a few parsing issues:

- Different handling of "bti+none" and "none+bti": these should be
  rejected because "none" can only appear alone.

- Accepted empty strings such as "bti++pac-ret" or "bti+", this bug
  was caused by using strtok_r.

- Memory got leaked (str_root was never freed). And two buffers got
  allocated when one is enough.

The callbacks now have no failure mode, only parsing can fail and
all failures are handled locally.  The "-mbranch-protection=" vs
"target("branch-protection=")" difference in the error message is
handled by a separate argument to aarch_validate_mbranch_protection.

gcc/ChangeLog:

* config/aarch64/aarch64.cc (aarch64_override_options): Update.
(aarch64_handle_attr_branch_protection): Update.
* config/arm/aarch-common-protos.h (aarch_parse_branch_protection):
Remove.
(aarch_validate_mbranch_protection): Add new argument.
* config/arm/aarch-common.cc (aarch_handle_no_branch_protection):
Update.
(aarch_handle_standard_branch_protection): Update.
(aarch_handle_pac_ret_protection): Update.
(aarch_handle_pac_ret_leaf): Update.
(aarch_handle_pac_ret_b_key): Update.
(aarch_handle_bti_protection): Update.
(aarch_parse_branch_protection): Remove.
(next_tok): New.
(aarch_validate_mbranch_protection): Rewrite.
* config/arm/aarch-common.h (struct aarch_branch_protect_type):
Add field "alone".
* config/arm/arm.cc (arm_configure_build_target): Update.
---
 gcc/config/aarch64/aarch64.cc|  37 +
 gcc/config/arm/aarch-common-protos.h |   5 +-
 gcc/config/arm/aarch-common.cc   | 214 ---
 gcc/config/arm/aarch-common.h|  14 +-
 gcc/config/arm/arm.cc|   3 +-
 5 files changed, 109 insertions(+), 164 deletions(-)

diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc
index 7f0a22fae9c..661ac12cacc 100644
--- a/gcc/config/aarch64/aarch64.cc
+++ b/gcc/config/aarch64/aarch64.cc
@@ -18539,7 +18539,8 @@ aarch64_override_options (void)
 aarch64_validate_sls_mitigation (aarch64_harden_sls_string);
 
   if (aarch64_branch_protection_string)
-aarch_validate_mbranch_protection (aarch64_branch_protection_string);
+aarch_validate_mbranch_protection (aarch64_branch_protection_string,
+  "-mbranch-protection=");
 
   /* -mcpu=CPU is shorthand for -march=ARCH_FOR_CPU, -mtune=CPU.
  If either of -march or -mtune is given, they override their
@@ -18913,34 +18914,12 @@ aarch64_handle_attr_cpu (const char *str)
 
 /* Handle the argument STR to the branch-protection= attribute.  */
 
- static bool
- aarch64_handle_attr_branch_protection (const char* str)
- {
-  char *err_str = (char *) xmalloc (strlen (str) + 1);
-  enum aarch_parse_opt_result res = aarch_parse_branch_protection (str,
-  _str);
-  bool success = false;
-  switch (res)
-{
- case AARCH_PARSE_MISSING_ARG:
-   error ("missing argument to % pragma 
or"
- " attribute");
-   break;
- case AARCH_PARSE_INVALID_ARG:
-   error ("invalid protection type %qs in % pragma or attribute", err_str);
-   break;
- case AARCH_PARSE_OK:
-   success = true;
-  /* Fall through.  */
- case AARCH_PARSE_INVALID_FEATURE:
-   break;
- default:
-   gcc_unreachable ();
-}
-  free (err_str);
-  return success;
- }
+static bool
+aarch64_handle_attr_branch_protection (const char* str)
+{
+  return aarch_validate_mbranch_protection (str,
+   "target(\"branch-protection=\")");
+}
 
 /* Handle the argument STR to the tune= target attribute.  */
 
diff --git a/gcc/config/arm/aarch-common-protos.h 
b/gcc/config/arm/aarch-common-protos.h
index f8cb6562096..75ffdfbb050 100644
--- a/gcc/config/arm/aarch-common-protos.h
+++ b/gcc/config/arm/aarch-common-protos.h
@@ -159,10 +159,7 @@ rtx_insn *arm_md_asm_adjust (vec , vec & 
/*inputs*/,
 vec , HARD_REG_SET _regs,
 location_t loc);
 
-/* Parsing routine for branch-protection common to AArch64 and Arm.  */
-enum aarch_parse_opt_result aarch_parse_branch_protection (const char*, 
char**);
-
 /* Validation routine for branch-protection common to AArch64 and Arm.  */
-bool aarch_validate_mbranch_protection (const char *);
+bool aarch_validate_mbranch_protection (const char *, const char *);
 
 #endif /* GCC_AARCH_COMMON_PROTOS_H */
diff --git a/gcc/config/arm/aarch-common.cc b/gcc/config/arm/aarch-common.cc
index cbc7f68a8bf..159c61b786c 100644
--- a/gcc/config/arm/aarch-common.cc
+++ b/gcc/config/arm/aarch-common.cc
@@ -659,169 +659,143 @@ arm_md_asm_adjust (vec , vec & 
/*inputs*/,
   return saw_asm_flag ? seq : NULL;
 }
 
-static enum aarch_parse_opt_result

[PATCH 02/11] Handle epilogues that contain jumps

2023-08-22 Thread Szabolcs Nagy via Gcc-patches
From: Richard Sandiford 

The prologue/epilogue pass allows the prologue sequence
to contain jumps.  The sequence is then partitioned into
basic blocks using find_many_sub_basic_blocks.

This patch treats epilogues in the same way.  It's needed for
a follow-on aarch64 patch that adds conditional code to both
the prologue and the epilogue.

Tested on aarch64-linux-gnu (including with a follow-on patch)
and x86_64-linux-gnu.  OK to install?

Richard

gcc/
* function.cc (thread_prologue_and_epilogue_insns): Handle
epilogues that contain jumps.
---

This is a previously approved patch that was not committed
because it was not needed at the time, but i'd like to commit
it as it is needed for the followup aarch64 eh_return changes:

https://gcc.gnu.org/pipermail/gcc-patches/2022-November/605769.html

---
 gcc/function.cc | 10 ++
 1 file changed, 10 insertions(+)

diff --git a/gcc/function.cc b/gcc/function.cc
index dd2c1136e07..70d1cd65303 100644
--- a/gcc/function.cc
+++ b/gcc/function.cc
@@ -6120,6 +6120,11 @@ thread_prologue_and_epilogue_insns (void)
  && returnjump_p (BB_END (e->src)))
e->flags &= ~EDGE_FALLTHRU;
}
+
+ auto_sbitmap blocks (last_basic_block_for_fn (cfun));
+ bitmap_clear (blocks);
+   bitmap_set_bit (blocks, BLOCK_FOR_INSN (epilogue_seq)->index);
+ find_many_sub_basic_blocks (blocks);
}
   else if (next_active_insn (BB_END (exit_fallthru_edge->src)))
{
@@ -6218,6 +6223,11 @@ thread_prologue_and_epilogue_insns (void)
  set_insn_locations (seq, epilogue_location);
 
  emit_insn_before (seq, insn);
+
+ auto_sbitmap blocks (last_basic_block_for_fn (cfun));
+ bitmap_clear (blocks);
+ bitmap_set_bit (blocks, BLOCK_FOR_INSN (insn)->index);
+ find_many_sub_basic_blocks (blocks);
}
 }
 
-- 
2.25.1



[PATCH 03/11] aarch64: Use br instead of ret for eh_return

2023-08-22 Thread Szabolcs Nagy via Gcc-patches
The expected way to handle eh_return is to pass the stack adjustment
offset and landing pad address via

  EH_RETURN_STACKADJ_RTX
  EH_RETURN_HANDLER_RTX

to the epilogue that is shared between normal return paths and the
eh_return paths.  EH_RETURN_HANDLER_RTX is the stack slot of the
return address that is overwritten with the landing pad in the
eh_return case and EH_RETURN_STACKADJ_RTX is a register added to sp
right before return and it is set to 0 in the normal return case.

The issue with this design is that eh_return and normal return may
require different return sequence but there is no way to distinguish
the two cases in the epilogue (the stack adjustment may be 0 in the
eh_return case too).

The reason eh_return and normal return requires different return
sequence is that control flow integrity hardening may need to treat
eh_return as a forward-edge transfer (it is not returning to the
previous stack frame) and normal return as a backward-edge one.
In case of AArch64 forward-edge is protected by BTI and requires br
instruction and backward-edge is protected by PAUTH or GCS and
requires ret (or authenticated ret) instruction.

This patch resolves the issue by using the EH_RETURN_STACKADJ_RTX
register only as a flag that is set to 1 in the eh_return paths
(it is 0 in normal return paths) and introduces

  AARCH64_EH_RETURN_STACKADJ_RTX
  AARCH64_EH_RETURN_HANDLER_RTX

to pass the actual stack adjustment and landing pad address to the
epilogue in the eh_return case. Then the epilogue can use the right
return sequence based on the EH_RETURN_STACKADJ_RTX flag.

The handler could be passed the old way via clobbering the return
address, but since now the eh_return case can be distinguished, the
handler can be in a different register than x30 and no stack frame
is needed for eh_return.

The new code generation for functions with eh_return is not amazing,
since x5 and x6 is assumed to be used by the epilogue even in the
normal return path, not just for eh_return.  But only the unwinder
is expected to use eh_return so this is fine.

This patch fixes a return to anywhere gadget in the unwinder with
existing standard branch protection as well as makes EH return
compatible with the Guarded Control Stack (GCS) extension.

gcc/ChangeLog:

* config/aarch64/aarch64-protos.h (aarch64_eh_return_handler_rtx):
Remove.
(aarch64_eh_return): New.
* config/aarch64/aarch64.cc (aarch64_return_address_signing_enabled):
Sign return address even in functions with eh_return.
(aarch64_epilogue_uses): Mark two registers as used.
(aarch64_expand_epilogue): Conditionally return with br or ret.
(aarch64_eh_return_handler_rtx): Remove.
(aarch64_eh_return): New.
* config/aarch64/aarch64.h (EH_RETURN_HANDLER_RTX): Remove.
(AARCH64_EH_RETURN_STACKADJ_REGNUM): Define.
(AARCH64_EH_RETURN_STACKADJ_RTX): Define.
(AARCH64_EH_RETURN_HANDLER_REGNUM): Define.
(AARCH64_EH_RETURN_HANDLER_RTX): Define.
* config/aarch64/aarch64.md (eh_return): New.
---
 gcc/config/aarch64/aarch64-protos.h |   2 +-
 gcc/config/aarch64/aarch64.cc   | 106 +++-
 gcc/config/aarch64/aarch64.h|  11 ++-
 gcc/config/aarch64/aarch64.md   |   8 +++
 4 files changed, 73 insertions(+), 54 deletions(-)

diff --git a/gcc/config/aarch64/aarch64-protos.h 
b/gcc/config/aarch64/aarch64-protos.h
index 70303d6fd95..5d1834162a4 100644
--- a/gcc/config/aarch64/aarch64-protos.h
+++ b/gcc/config/aarch64/aarch64-protos.h
@@ -855,7 +855,7 @@ machine_mode aarch64_hard_regno_caller_save_mode (unsigned, 
unsigned,
   machine_mode);
 int aarch64_uxt_size (int, HOST_WIDE_INT);
 int aarch64_vec_fpconst_pow_of_2 (rtx);
-rtx aarch64_eh_return_handler_rtx (void);
+void aarch64_eh_return (rtx);
 rtx aarch64_mask_from_zextract_ops (rtx, rtx);
 const char *aarch64_output_move_struct (rtx *operands);
 rtx aarch64_return_addr_rtx (void);
diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc
index eba5d4a7e04..36cd172d182 100644
--- a/gcc/config/aarch64/aarch64.cc
+++ b/gcc/config/aarch64/aarch64.cc
@@ -8972,17 +8972,6 @@ aarch64_return_address_signing_enabled (void)
   /* This function should only be called after frame laid out.   */
   gcc_assert (cfun->machine->frame.laid_out);
 
-  /* Turn return address signing off in any function that uses
- __builtin_eh_return.  The address passed to __builtin_eh_return
- is not signed so either it has to be signed (with original sp)
- or the code path that uses it has to avoid authenticating it.
- Currently eh return introduces a return to anywhere gadget, no
- matter what we do here since it uses ret with user provided
- address. An ideal fix for that is to use indirect branch which
- can be protected with BTI j (to some extent).  */
-  if (crtl->calls_eh_return)
-return false;
-
   /* If signing scope 

[PATCH 08/11] aarch64,arm: Remove accepted_branch_protection_string

2023-08-22 Thread Szabolcs Nagy via Gcc-patches
On aarch64 this caused ICE with pragma push_options since

  commit ae54c1b09963779c5c3914782324ff48af32e2f1
  Author: Wilco Dijkstra 
  CommitDate: 2022-06-01 18:13:57 +0100

  AArch64: Cleanup option processing code

The failure is at pop_options:

internal compiler error: ‘global_options’ are modified in local context

On arm the variable was unused.

gcc/ChangeLog:

* config/aarch64/aarch64.cc (aarch64_override_options_after_change_1):
Do not override branch_protection options.
(aarch64_override_options): Remove accepted_branch_protection_string.
* config/arm/aarch-common.cc (BRANCH_PROTECT_STR_MAX): Remove.
(aarch_parse_branch_protection): Remove
accepted_branch_protection_string.
* config/arm/arm.cc: Likewise.
---
 gcc/config/aarch64/aarch64.cc  | 10 +-
 gcc/config/arm/aarch-common.cc | 16 
 gcc/config/arm/arm.cc  |  2 --
 3 files changed, 1 insertion(+), 27 deletions(-)

diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc
index afdbf4213c1..7f0a22fae9c 100644
--- a/gcc/config/aarch64/aarch64.cc
+++ b/gcc/config/aarch64/aarch64.cc
@@ -322,8 +322,6 @@ bool aarch64_pcrelative_literal_loads;
 /* Global flag for whether frame pointer is enabled.  */
 bool aarch64_use_frame_pointer;
 
-char *accepted_branch_protection_string = NULL;
-
 /* Support for command line parsing of boolean flags in the tuning
structures.  */
 struct aarch64_flag_desc
@@ -18004,12 +18002,6 @@ aarch64_adjust_generic_arch_tuning (struct tune_params 
_tune)
 static void
 aarch64_override_options_after_change_1 (struct gcc_options *opts)
 {
-  if (accepted_branch_protection_string)
-{
-  opts->x_aarch64_branch_protection_string
-   = xstrdup (accepted_branch_protection_string);
-}
-
   /* PR 70044: We have to be careful about being called multiple times for the
  same function.  This means all changes should be repeatable.  */
 
@@ -18612,7 +18604,7 @@ aarch64_override_options (void)
   /* Return address signing is currently not supported for ILP32 targets.  For
  LP64 targets use the configured option in the absence of a command-line
  option for -mbranch-protection.  */
-  if (!TARGET_ILP32 && accepted_branch_protection_string == NULL)
+  if (!TARGET_ILP32 && aarch64_branch_protection_string == NULL)
 {
 #ifdef TARGET_ENABLE_PAC_RET
   aarch_ra_sign_scope = AARCH_FUNCTION_NON_LEAF;
diff --git a/gcc/config/arm/aarch-common.cc b/gcc/config/arm/aarch-common.cc
index 5b96ff4c2e8..cbc7f68a8bf 100644
--- a/gcc/config/arm/aarch-common.cc
+++ b/gcc/config/arm/aarch-common.cc
@@ -659,9 +659,6 @@ arm_md_asm_adjust (vec , vec & /*inputs*/,
   return saw_asm_flag ? seq : NULL;
 }
 
-#define BRANCH_PROTECT_STR_MAX 255
-extern char *accepted_branch_protection_string;
-
 static enum aarch_parse_opt_result
 aarch_handle_no_branch_protection (char* str, char* rest)
 {
@@ -812,19 +809,6 @@ aarch_parse_branch_protection (const char *const_str, 
char** last_str)
   else
*last_str = NULL;
 }
-
-  if (res == AARCH_PARSE_OK)
-{
-  /* If needed, alloc the accepted string then copy in const_str.
-   Used by override_option_after_change_1.  */
-  if (!accepted_branch_protection_string)
-   accepted_branch_protection_string
- = (char *) xmalloc (BRANCH_PROTECT_STR_MAX + 1);
-  strncpy (accepted_branch_protection_string, const_str,
-  BRANCH_PROTECT_STR_MAX + 1);
-  /* Forcibly null-terminate.  */
-  accepted_branch_protection_string[BRANCH_PROTECT_STR_MAX] = '\0';
-}
   return res;
 }
 
diff --git a/gcc/config/arm/arm.cc b/gcc/config/arm/arm.cc
index 6e933c80183..f49312cace0 100644
--- a/gcc/config/arm/arm.cc
+++ b/gcc/config/arm/arm.cc
@@ -2424,8 +2424,6 @@ const struct tune_params arm_fa726te_tune =
   tune_params::SCHED_AUTOPREF_OFF
 };
 
-char *accepted_branch_protection_string = NULL;
-
 /* Auto-generated CPU, FPU and architecture tables.  */
 #include "arm-cpu-data.h"
 
-- 
2.25.1



[PATCH 07/11] aarch64: Disable branch-protection for pcs tests

2023-08-22 Thread Szabolcs Nagy via Gcc-patches
The tests manipulate the return address in abitest-2.h and thus not
compatible with -mbranch-protection=pac-ret+leaf or
-mbranch-protection=gcs.

gcc/testsuite/ChangeLog:

* gcc.target/aarch64/aapcs64/func-ret-1.c: Disable branch-protection.
* gcc.target/aarch64/aapcs64/func-ret-2.c: Likewise.
* gcc.target/aarch64/aapcs64/func-ret-3.c: Likewise.
* gcc.target/aarch64/aapcs64/func-ret-4.c: Likewise.
* gcc.target/aarch64/aapcs64/func-ret-64x1_1.c: Likewise.
---
 gcc/testsuite/gcc.target/aarch64/aapcs64/func-ret-1.c  | 1 +
 gcc/testsuite/gcc.target/aarch64/aapcs64/func-ret-2.c  | 1 +
 gcc/testsuite/gcc.target/aarch64/aapcs64/func-ret-3.c  | 1 +
 gcc/testsuite/gcc.target/aarch64/aapcs64/func-ret-4.c  | 1 +
 gcc/testsuite/gcc.target/aarch64/aapcs64/func-ret-64x1_1.c | 1 +
 5 files changed, 5 insertions(+)

diff --git a/gcc/testsuite/gcc.target/aarch64/aapcs64/func-ret-1.c 
b/gcc/testsuite/gcc.target/aarch64/aapcs64/func-ret-1.c
index 5405e1e4920..7bd7757efe6 100644
--- a/gcc/testsuite/gcc.target/aarch64/aapcs64/func-ret-1.c
+++ b/gcc/testsuite/gcc.target/aarch64/aapcs64/func-ret-1.c
@@ -4,6 +4,7 @@
AAPCS64 \S 4.1.  */
 
 /* { dg-do run { target aarch64*-*-* } } */
+/* { dg-additional-options "-mbranch-protection=none" } */
 /* { dg-additional-sources "abitest.S" } */
 
 #ifndef IN_FRAMEWORK
diff --git a/gcc/testsuite/gcc.target/aarch64/aapcs64/func-ret-2.c 
b/gcc/testsuite/gcc.target/aarch64/aapcs64/func-ret-2.c
index 6b171c46fbb..85a822ace4a 100644
--- a/gcc/testsuite/gcc.target/aarch64/aapcs64/func-ret-2.c
+++ b/gcc/testsuite/gcc.target/aarch64/aapcs64/func-ret-2.c
@@ -4,6 +4,7 @@
Homogeneous floating-point aggregate types are covered in func-ret-3.c.  */
 
 /* { dg-do run { target aarch64*-*-* } } */
+/* { dg-additional-options "-mbranch-protection=none" } */
 /* { dg-additional-sources "abitest.S" } */
 
 #ifndef IN_FRAMEWORK
diff --git a/gcc/testsuite/gcc.target/aarch64/aapcs64/func-ret-3.c 
b/gcc/testsuite/gcc.target/aarch64/aapcs64/func-ret-3.c
index ad312b675b9..1d35ebf14b4 100644
--- a/gcc/testsuite/gcc.target/aarch64/aapcs64/func-ret-3.c
+++ b/gcc/testsuite/gcc.target/aarch64/aapcs64/func-ret-3.c
@@ -4,6 +4,7 @@
in AAPCS64 \S 4.3.5.  */
 
 /* { dg-do run { target aarch64-*-* } } */
+/* { dg-additional-options "-mbranch-protection=none" } */
 /* { dg-additional-sources "abitest.S" } */
 /* { dg-require-effective-target aarch64_big_endian } */
 
diff --git a/gcc/testsuite/gcc.target/aarch64/aapcs64/func-ret-4.c 
b/gcc/testsuite/gcc.target/aarch64/aapcs64/func-ret-4.c
index af05fbe9fdf..15e1408c62d 100644
--- a/gcc/testsuite/gcc.target/aarch64/aapcs64/func-ret-4.c
+++ b/gcc/testsuite/gcc.target/aarch64/aapcs64/func-ret-4.c
@@ -5,6 +5,7 @@
are treated as general composite types.  */
 
 /* { dg-do run { target aarch64*-*-* } } */
+/* { dg-additional-options "-mbranch-protection=none" } */
 /* { dg-additional-sources "abitest.S" } */
 /* { dg-require-effective-target aarch64_big_endian } */
 
diff --git a/gcc/testsuite/gcc.target/aarch64/aapcs64/func-ret-64x1_1.c 
b/gcc/testsuite/gcc.target/aarch64/aapcs64/func-ret-64x1_1.c
index 05957e2dcae..fe7bbb6a835 100644
--- a/gcc/testsuite/gcc.target/aarch64/aapcs64/func-ret-64x1_1.c
+++ b/gcc/testsuite/gcc.target/aarch64/aapcs64/func-ret-64x1_1.c
@@ -3,6 +3,7 @@
   Test 64-bit singleton vector types which should be in FP/SIMD registers.  */
 
 /* { dg-do run { target aarch64*-*-* } } */
+/* { dg-additional-options "-mbranch-protection=none" } */
 /* { dg-additional-sources "abitest.S" } */
 
 #ifndef IN_FRAMEWORK
-- 
2.25.1



[PATCH 06/11] aarch64: Fix pac-ret eh_return tests

2023-08-22 Thread Szabolcs Nagy via Gcc-patches
This is needed since eh_return no longer prevents pac-ret in the
normal return path.

gcc/testsuite/ChangeLog:

* gcc.target/aarch64/return_address_sign_1.c: Move func4 to ...
* gcc.target/aarch64/return_address_sign_2.c: ... here and fix the
scan asm check.
* gcc.target/aarch64/return_address_sign_b_1.c: Move func4 to ...
* gcc.target/aarch64/return_address_sign_b_2.c: ... here and fix the
scan asm check.
---
 .../gcc.target/aarch64/return_address_sign_1.c  | 13 +
 .../gcc.target/aarch64/return_address_sign_2.c  | 17 +++--
 .../aarch64/return_address_sign_b_1.c   | 11 ---
 .../aarch64/return_address_sign_b_2.c   | 17 +++--
 4 files changed, 31 insertions(+), 27 deletions(-)

diff --git a/gcc/testsuite/gcc.target/aarch64/return_address_sign_1.c 
b/gcc/testsuite/gcc.target/aarch64/return_address_sign_1.c
index 232ba67ade0..114a9dacb3f 100644
--- a/gcc/testsuite/gcc.target/aarch64/return_address_sign_1.c
+++ b/gcc/testsuite/gcc.target/aarch64/return_address_sign_1.c
@@ -37,16 +37,5 @@ func3 (int a, int b, int c)
   /* autiasp */
 }
 
-/* eh_return.  */
-void __attribute__ ((target ("arch=armv8.3-a")))
-func4 (long offset, void *handler, int *ptr, int imm1, int imm2)
-{
-  /* no paciasp */
-  *ptr = imm1 + foo (imm1) + imm2;
-  __builtin_eh_return (offset, handler);
-  /* no autiasp */
-  return;
-}
-
-/* { dg-final { scan-assembler-times "autiasp" 3 } } */
 /* { dg-final { scan-assembler-times "paciasp" 3 } } */
+/* { dg-final { scan-assembler-times "autiasp" 3 } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/return_address_sign_2.c 
b/gcc/testsuite/gcc.target/aarch64/return_address_sign_2.c
index a4bc5b45333..d93492c3c43 100644
--- a/gcc/testsuite/gcc.target/aarch64/return_address_sign_2.c
+++ b/gcc/testsuite/gcc.target/aarch64/return_address_sign_2.c
@@ -14,5 +14,18 @@ func1 (int a, int b, int c)
   /* retaa */
 }
 
-/* { dg-final { scan-assembler-times "paciasp" 1 } } */
-/* { dg-final { scan-assembler-times "retaa" 1 } } */
+/* eh_return.  */
+void __attribute__ ((target ("arch=armv8.3-a")))
+func4 (long offset, void *handler, int *ptr, int imm1, int imm2)
+{
+  /* paciasp */
+  *ptr = imm1 + foo (imm1) + imm2;
+  if (handler)
+/* br */
+__builtin_eh_return (offset, handler);
+  /* retaa */
+  return;
+}
+
+/* { dg-final { scan-assembler-times "paciasp" 2 } } */
+/* { dg-final { scan-assembler-times "retaa" 2 } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/return_address_sign_b_1.c 
b/gcc/testsuite/gcc.target/aarch64/return_address_sign_b_1.c
index 43e32ab6cb7..697fa30dc5a 100644
--- a/gcc/testsuite/gcc.target/aarch64/return_address_sign_b_1.c
+++ b/gcc/testsuite/gcc.target/aarch64/return_address_sign_b_1.c
@@ -37,16 +37,5 @@ func3 (int a, int b, int c)
   /* autibsp */
 }
 
-/* eh_return.  */
-void __attribute__ ((target ("arch=armv8.3-a")))
-func4 (long offset, void *handler, int *ptr, int imm1, int imm2)
-{
-  /* no pacibsp */
-  *ptr = imm1 + foo (imm1) + imm2;
-  __builtin_eh_return (offset, handler);
-  /* no autibsp */
-  return;
-}
-
 /* { dg-final { scan-assembler-times "pacibsp" 3 } } */
 /* { dg-final { scan-assembler-times "autibsp" 3 } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/return_address_sign_b_2.c 
b/gcc/testsuite/gcc.target/aarch64/return_address_sign_b_2.c
index 9ed64ce0591..748924c72f3 100644
--- a/gcc/testsuite/gcc.target/aarch64/return_address_sign_b_2.c
+++ b/gcc/testsuite/gcc.target/aarch64/return_address_sign_b_2.c
@@ -14,5 +14,18 @@ func1 (int a, int b, int c)
   /* retab */
 }
 
-/* { dg-final { scan-assembler-times "pacibsp" 1 } } */
-/* { dg-final { scan-assembler-times "retab" 1 } } */
+/* eh_return.  */
+void __attribute__ ((target ("arch=armv8.3-a")))
+func4 (long offset, void *handler, int *ptr, int imm1, int imm2)
+{
+  /* paciasp */
+  *ptr = imm1 + foo (imm1) + imm2;
+  if (handler)
+/* br */
+__builtin_eh_return (offset, handler);
+  /* retab */
+  return;
+}
+
+/* { dg-final { scan-assembler-times "pacibsp" 2 } } */
+/* { dg-final { scan-assembler-times "retab" 2 } } */
-- 
2.25.1



[PATCH 01/11] aarch64: AARCH64_ISA_RCPC was defined twice

2023-08-22 Thread Szabolcs Nagy via Gcc-patches
gcc/ChangeLog:

* config/aarch64/aarch64.h (AARCH64_ISA_RCPC): Remove dup.
---
 gcc/config/aarch64/aarch64.h | 1 -
 1 file changed, 1 deletion(-)

diff --git a/gcc/config/aarch64/aarch64.h b/gcc/config/aarch64/aarch64.h
index 2b0fc97bb71..c783cb96c48 100644
--- a/gcc/config/aarch64/aarch64.h
+++ b/gcc/config/aarch64/aarch64.h
@@ -222,7 +222,6 @@ enum class aarch64_feature : unsigned char {
 #define AARCH64_ISA_MOPS  (aarch64_isa_flags & AARCH64_FL_MOPS)
 #define AARCH64_ISA_LS64  (aarch64_isa_flags & AARCH64_FL_LS64)
 #define AARCH64_ISA_CSSC  (aarch64_isa_flags & AARCH64_FL_CSSC)
-#define AARCH64_ISA_RCPC   (aarch64_isa_flags & AARCH64_FL_RCPC)
 
 /* Crypto is an optional extension to AdvSIMD.  */
 #define TARGET_CRYPTO (AARCH64_ISA_CRYPTO)
-- 
2.25.1



[PATCH 00/11] aarch64 GCS preliminary patches

2023-08-22 Thread Szabolcs Nagy via Gcc-patches
I'm working on Guarded Control Stack support for aarch64 and have a
set of patches that are needed for GCS but seem useful without it so
makes sense to review them separately from the rest of the GCS work.

GCS support will depend on the linux ABI that is under discussion at
https://lore.kernel.org/lkml/20230807-arm64-gcs-v4-0-68cfa37f9...@kernel.org/
so it will come later.

Richard Sandiford (1):
  Handle epilogues that contain jumps

Szabolcs Nagy (10):
  aarch64: AARCH64_ISA_RCPC was defined twice
  aarch64: Use br instead of ret for eh_return
  aarch64: Do not force a stack frame for EH returns
  aarch64: Add eh_return compile tests
  aarch64: Fix pac-ret eh_return tests
  aarch64: Disable branch-protection for pcs tests
  aarch64,arm: Remove accepted_branch_protection_string
  aarch64,arm: Fix branch-protection= parsing
  aarch64: Fix branch-protection error message tests
  aarch64,arm: Move branch-protection data to targets

 gcc/config/aarch64/aarch64-opts.h |   6 +-
 gcc/config/aarch64/aarch64-protos.h   |   2 +-
 gcc/config/aarch64/aarch64.cc | 211 +---
 gcc/config/aarch64/aarch64.h  |  12 +-
 gcc/config/aarch64/aarch64.md |   8 +
 gcc/config/arm/aarch-common-protos.h  |   5 +-
 gcc/config/arm/aarch-common.cc| 229 +-
 gcc/config/arm/aarch-common.h |  25 +-
 gcc/config/arm/arm-c.cc   |   2 -
 gcc/config/arm/arm.cc |  57 -
 gcc/config/arm/arm.opt|   3 -
 gcc/function.cc   |  10 +
 .../gcc.target/aarch64/aapcs64/func-ret-1.c   |   1 +
 .../gcc.target/aarch64/aapcs64/func-ret-2.c   |   1 +
 .../gcc.target/aarch64/aapcs64/func-ret-3.c   |   1 +
 .../gcc.target/aarch64/aapcs64/func-ret-4.c   |   1 +
 .../aarch64/aapcs64/func-ret-64x1_1.c |   1 +
 .../aarch64/branch-protection-attr.c  |   6 +-
 .../aarch64/branch-protection-option.c|   2 +-
 .../gcc.target/aarch64/eh_return-2.c  |   9 +
 .../gcc.target/aarch64/eh_return-3.c  |  14 ++
 .../aarch64/return_address_sign_1.c   |  13 +-
 .../aarch64/return_address_sign_2.c   |  17 +-
 .../aarch64/return_address_sign_b_1.c |  11 -
 .../aarch64/return_address_sign_b_2.c |  17 +-
 25 files changed, 338 insertions(+), 326 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/aarch64/eh_return-2.c
 create mode 100644 gcc/testsuite/gcc.target/aarch64/eh_return-3.c

-- 
2.25.1



Re: [PATCH] aarch64: Fix warnings during libgcc build

2023-07-12 Thread Szabolcs Nagy via Gcc-patches
The 07/11/2023 17:20, Florian Weimer wrote:
> * Richard Earnshaw:
> 
> > On 11/07/2023 10:37, Florian Weimer via Gcc-patches wrote:
> >> libgcc/
> >>* config/aarch64/aarch64-unwind.h
> >> (aarch64_cie_signed_with_b_key):
> >>Add missing const qualifier.  Cast from const unsigned char *
> >>to const char *.  Use __builtin_strchr to avoid an implicit
> >>function declaration.
> >>* config/aarch64/linux-unwind.h (aarch64_fallback_frame_state):
> >>Add missing cast.
> >> ---
> >> diff --git a/libgcc/config/aarch64/linux-unwind.h 
> >> b/libgcc/config/aarch64/linux-unwind.h
> >> index 00eba866049..93da7a9537d 100644
> >> --- a/libgcc/config/aarch64/linux-unwind.h
> >> +++ b/libgcc/config/aarch64/linux-unwind.h
> >> @@ -77,7 +77,7 @@ aarch64_fallback_frame_state (struct _Unwind_Context 
> >> *context,
> >>   }
> >>   rt_ = context->cfa;
> >> -  sc = _->uc.uc_mcontext;
> >> +  sc = (struct sigcontext *) _->uc.uc_mcontext;
> >> /* This define duplicates the definition in aarch64.md */
> >>   #define SP_REGNUM 31
> >> 
> >
> > This looks somewhat dubious.  I'm not particularly familiar with the
> > kernel headers, but a quick look suggests an mcontext_t is nothing
> > like a sigcontext_t.  So isn't the cast just papering over some more
> > fundamental problem?
> 
> I agree it looks dubious.  Note that it's struct sigcontext, not
> (not-struct) sigcontext_t.  I don't know why the uc_mcontext members
> aren't accessed directly, so I can't really write a good comment about
> it.

historically glibc typedefed mcontext_t to linux struct sigcontext
so this used to work fine. (i dont know about other os-es)

then at some point glibc fixed the namespace polluting fields
when building for posix which required a separate mcontext_t.

i guess either fix works: moving to the correct mcontext_t or to
cast to struct sigcontext, but the former means the fields must
be changed when building in a posix conforming mode (i guess
libgcc is built with _GNU_SOURCE so may not be an issue) and
they may be different across different libcs (or even different
versions of glibc) then.

> 
> Obviously it works quite well as-is. 8-)  Similar code is present in
> many, many Linux targets.
> 
> Thanks,
> Florian
> 


Re: [PATCH] libgcc: Fix uninitialized RA signing on AArch64 [PR107678]

2023-01-05 Thread Szabolcs Nagy via Gcc-patches
The 01/03/2023 17:27, Wilco Dijkstra wrote:
> 
> > Also, if I understood correctly, the reason we use REG_UNSAVED is to
> > ensure that state from one frame isn't carried across to a parent frame,
> > in cases where the parent frame lacks any signing.  That is, each frame
> > should start out with a zero bit even if a child frame is unwound while
> > it has a set bit.
> 
> This works fine since all registers are initialized to REG_UNSAVED every 
> frame.
> 
> In v2 I've removed some clutter and encode the signing state in REG_UNSAVED/
> REG_UNDEFINED.

this looks good to me.


> @@ -1206,8 +1205,10 @@ execute_cfa_program (const unsigned char *insn_ptr,
>   /* This CFA is multiplexed with Sparc.  On AArch64 it's used to 
> toggle
>  return address signing status.  */
>   reg = DWARF_REGNUM_AARCH64_RA_STATE;
> - gcc_assert (fs->regs.how[reg] == REG_UNSAVED);
> - fs->regs.reg[reg].loc.offset ^= 1;
> + if (fs->regs.how[reg] == REG_UNSAVED)
> +   fs->regs.how[reg] = REG_UNDEFINED;
> + else
> +   fs->regs.how[reg] = REG_UNSAVED;
>  #else
>   /* ??? Hardcoded for SPARC register window configuration.  */
>   if (__LIBGCC_DWARF_FRAME_REGISTERS__ >= 32)

i would keep the assert: how[reg] must be either UNSAVED or UNDEFINED
here, other how[reg] means the toggle cfi instruction is mixed with
incompatible instructions for the pseudo reg.

and i would add a comment about this e.g. saying that UNSAVED/UNDEFINED
how[reg] is used for tracking the return address signing status and
other how[reg] is not allowed here.

otherwise the patch looks good.



Re: [PATCH] libgcc: Fix uninitialized RA signing on AArch64 [PR107678]

2022-12-06 Thread Szabolcs Nagy via Gcc-patches
The 12/06/2022 11:58, Wilco Dijkstra wrote:
> > i don't think how[*RA_STATE] can ever be set to REG_SAVED_OFFSET,
> > this pseudo reg is not spilled to the stack, it is reset to 0 in
> > each frame and then toggled within a frame.
> 
> It's is just a state, we can use any state we want since it is a pseudo reg.
> These registers are global and shared across all functions in an unwind,
> so their state or value isn't reset for each frame. So if we want to reset
> it in each frame then using a virtual register to hold per-function data
> seems like a bad design. I'm surprised nobody has ever tested it...

it was tested (and worked when the frame state was initialized).

in principle the CIE can contain instructions to initialize the
register state for a frame. the RA_STATE pseudo reg behaves as if
the CIE always set its value to 0 at the start of the frame.

the design has issues, but this is what we have now.

the toggle instruction for RA_STATE does not really fit the dwarf
model: the CFI instruction sequence is evaluated with a context
that is valid at the end of the sequence so an unwinder only wants
to evaluate a register's state at the end, not intermediate values
(where the context might not even be valid). so we limited the
instructions allowed for RA_STATE: only remember_/restore_state,
toggle and val_expression are supported and the latter two cannot
be mixed. we still have to use the existing struct for keeping
track of this hence reg[RA_STATE].loc.offset.

and of course the RA_STATE pseudo reg is only used for computing
the return address not propagated to the previous frame so it is
special in many ways. so we will need target hooks to fix this
and i think the cleanest is to initialize RA_STATE per frame and
leave the rest as is.



Re: [PATCH] libgcc: Fix uninitialized RA signing on AArch64 [PR107678]

2022-12-06 Thread Szabolcs Nagy via Gcc-patches
The 12/05/2022 19:04, Richard Sandiford wrote:
> Wilco Dijkstra  writes:
> > A recent change only initializes the regs.how[] during Dwarf unwinding
> > which resulted in an uninitialized offset used in return address signing
> > and random failures during unwinding.  The fix is to use REG_SAVED_OFFSET
> > as the state where the return address signing bit is valid, and if the
> > state is REG_UNSAVED, initialize it to 0.
> >
> > Passes bootstrap & regress, OK for commit?
> >
> > libgcc/
> > PR target/107678
> > * unwind-dw2.c (execute_cfa_program): Initialize offset of
> > DWARF_REGNUM_AARCH64_RA_STATE if in REG_UNSAVED state.
> > * config/aarch64/aarch64-unwind.h (aarch64_frob_update_contex):
> > Check state is REG_SAVED_OFFSET before using offset for RA state.
> >
> > ---
> >
> > diff --git a/libgcc/config/aarch64/aarch64-unwind.h 
> > b/libgcc/config/aarch64/aarch64-unwind.h
> > index 
> > 26db9cbd9e5c526e0c410a4fc6be2bedb7d261cf..597133b3d708a50a366c8bfeff57475f5522b3f6
> >  100644
> > --- a/libgcc/config/aarch64/aarch64-unwind.h
> > +++ b/libgcc/config/aarch64/aarch64-unwind.h
> > @@ -71,21 +71,15 @@ aarch64_demangle_return_addr (struct _Unwind_Context 
> > *context,
> >  }
> >  
> >  /* Do AArch64 private initialization on CONTEXT based on frame info FS.  
> > Mark
> > -   CONTEXT as return address signed if bit 0 of 
> > DWARF_REGNUM_AARCH64_RA_STATE is
> > -   set.  */
> > +   CONTEXT as having a signed return address if 
> > DWARF_REGNUM_AARCH64_RA_STATE
> > +   is initialized (REG_SAVED_OFFSET state) and the offset has bit 0 set.  
> > */
> >  
> >  static inline void
> >  aarch64_frob_update_context (struct _Unwind_Context *context,
> >  _Unwind_FrameState *fs)
> >  {
> > -  const int reg = DWARF_REGNUM_AARCH64_RA_STATE;
> > -  int ra_signed;
> > -  if (fs->regs.how[reg] == REG_UNSAVED)
> > -ra_signed = fs->regs.reg[reg].loc.offset & 0x1;
> > -  else
> > -ra_signed = _Unwind_GetGR (context, reg) & 0x1;
> > -  if (ra_signed)
> > -/* The flag is used for re-authenticating EH handler's address.  */
> > +  if (fs->regs.how[DWARF_REGNUM_AARCH64_RA_STATE] == REG_SAVED_OFFSET
> > +  && (fs->regs.reg[DWARF_REGNUM_AARCH64_RA_STATE].loc.offset & 1) != 0)
> >  context->flags |= RA_SIGNED_BIT;
> >else
> >  context->flags &= ~RA_SIGNED_BIT;
> 
> Hmm, but the point of the original patch was to support code generators
> that emit DW_CFA_val_expression instead of DW_CFA_AARCH64_negate_ra_state.
> Doesn't this patch undo that?
> 
> Also, if I understood correctly, the reason we use REG_UNSAVED is to
> ensure that state from one frame isn't carried across to a parent frame,
> in cases where the parent frame lacks any signing.  That is, each frame
> should start out with a zero bit even if a child frame is unwound while
> it has a set bit.

yes.

i don't think how[*RA_STATE] can ever be set to REG_SAVED_OFFSET,
this pseudo reg is not spilled to the stack, it is reset to 0 in
each frame and then toggled within a frame.

unwind-dw2.c has

case DW_CFA_GNU_window_save:
#if defined (__aarch64__) && !defined (__ILP32__)
  /* This CFA is multiplexed with Sparc.  On AArch64 it's used to toggle
 return address signing status.  */
  reg = DWARF_REGNUM_AARCH64_RA_STATE;
  gcc_assert (fs->regs.how[reg] == REG_UNSAVED);
  fs->regs.reg[reg].loc.offset ^= 1;

for this to work, loc.offset must be reset in uw_frame_state_for.
we may need a new hook for that.


> 
> Thanks,
> Richard
> 
> > diff --git a/libgcc/unwind-dw2.c b/libgcc/unwind-dw2.c
> > index 
> > eaceace20298b9b13344aff9d1fe9ee5f9c7bd73..87f2ae065b67982ce48f74e45523d9c754a7661c
> >  100644
> > --- a/libgcc/unwind-dw2.c
> > +++ b/libgcc/unwind-dw2.c
> > @@ -1203,11 +1203,16 @@ execute_cfa_program (const unsigned char *insn_ptr,
> >  
> > case DW_CFA_GNU_window_save:
> >  #if defined (__aarch64__) && !defined (__ILP32__)
> > - /* This CFA is multiplexed with Sparc.  On AArch64 it's used to toggle
> > -return address signing status.  */
> > - reg = DWARF_REGNUM_AARCH64_RA_STATE;
> > - gcc_assert (fs->regs.how[reg] == REG_UNSAVED);
> > - fs->regs.reg[reg].loc.offset ^= 1;
> > +/* This CFA is multiplexed with Sparc.  On AArch64 it's used to toggle
> > +   the return address signing status.  It is initialized at the first
> > +   use and the state is stored in bit 0 of the offset.  */
> > +reg = DWARF_REGNUM_AARCH64_RA_STATE;
> > +if (fs->regs.how[reg] == REG_UNSAVED)
> > +  {
> > +fs->regs.how[reg] = REG_SAVED_OFFSET;
> > +fs->regs.reg[reg].loc.offset = 0;
> > +  }
> > +fs->regs.reg[reg].loc.offset ^= 1;
> >  #else
> >   /* ??? Hardcoded for SPARC register window configuration.  */
> >   if (__LIBGCC_DWARF_FRAME_REGISTERS__ >= 32)


Re: Division by zero on A53 which does not raise an exception

2022-11-29 Thread Szabolcs Nagy via Gcc
The 11/28/2022 21:37, Stephen Smith via Binutils wrote:
> I am working on a project which is using an A53 core.   The core does not 
> raise an exception if there is a division by zero (for either integer or 
> floating point division).

floating-point division by zero signals the FE_DIVBYZERO exception.
you can test this via fetestexcept(FE_DIVBYZERO).

integer operations must not affect fenv status flags so integer
division by zero does not do that.

if you want to *trap* division by zero, there is no reliable way
to do that in c (this is not related to particular cpus though).


Re: Adding file descriptor attribute(s) to gcc and glibc

2022-07-14 Thread Szabolcs Nagy via Gcc
The 07/13/2022 12:55, David Malcolm wrote:
> On Wed, 2022-07-13 at 16:01 +0200, Florian Weimer wrote:
> > * David Malcolm:
> GCC trunk's -fanalyzer implements the new warnings via a state machine
> for file-descriptor values; it currently has rules for handling "open",
> "close", "read", and "write", and these functions are currently hard-
> coded inside the analyzer.
> 
> Here are some examples on Compiler Explorer of what it can/cannot
> detect:
>   https://godbolt.org/z/nqPadvM4f
> 
> Probably the most important one IMHO is the leak detection.

nice.

> Would it be helpful to have some kind of attribute for "returns a new
> open FD"?  Are there other ways to close a FD other than calling
> "close" on it?  (Would converting that to some kind of "closes"
> attribute be a good idea?)

dup2(oldfd, newfd)
dup3(oldfd, newfd, flags)

closes newfd (and also opens it to be a dup of oldfd)
unless the call fails.

close_range(first, last, flags)

fclose(fdopen(fd, mode))

but users can write all sorts of wrappers around close too.

> 
> Are there any other "magic" values for file-descriptors we should be
> aware of?
> 

mmap may require fd==-1 for anonymous maps.


Re: Adding file descriptor attribute(s) to gcc and glibc

2022-07-13 Thread Szabolcs Nagy via Gcc
The 07/12/2022 18:25, David Malcolm via Libc-alpha wrote:
> On Tue, 2022-07-12 at 18:16 -0400, David Malcolm wrote:
> > On Tue, 2022-07-12 at 23:03 +0530, Mir Immad wrote:
> > GCC's attribute syntax here:
> >   https://gcc.gnu.org/onlinedocs/gcc/Attribute-Syntax.html
> > allows for a parenthesized list of parameters for the attribute, which
> > can be:
> >  (a) An identifier
> >  (b) An identifier followed by a comma and a non-empty comma-separated
> > list of expressions
> >  (c) A possibly empty comma-separated list of expressions
> > 
> > I'd hoped to have an argument number, with an optional extra param
> > describing the direction of the access, but syntax (b) puts the
> > identifier first, alas.
> > 
> > Here's one possible way of doing it with a single attribute, via syntax
> > (b):
> > e.g.
> >    __attribute__((fd_argument (access, 1))
> >    __attribute__((fd_argument (read, 1))
> >    __attribute__((fd_argument (write, 1))
> > 
> > meaning that argument 1 of the function is expected to be an open file-
> > descriptor, and that it must be possible to read from/write to that fd
> > for cases 2 and 3.
> > 
> > Here are some possible examples of how glibc might use this syntax:
> > 
> >     int dup (int oldfd)
> >   __attribute((fd_argument (access, 1)); 
> > 
> >     int ftruncate (int fd, off_t length)
> >   __attribute((fd_argument (access, 1)); 
> > 
> >     ssize_t pread(int fd, void *buf, size_t count, off_t offset)
> >   __attribute((fd_argument (read, 1));
> > 
> >     ssize_t pwrite(int fd, const void *buf, size_t count, 
> >    off_t offset);
> >   __attribute((fd_argument (write, 1));
> > 
> > ...but as I said, I'm most interested in input from glibc developers on
> > this.

note that glibc headers have to be namespace clean so it
would be more like

  __attribute__((__fd_argument (__access, 1)))
  __attribute__((__fd_argument (__read, 1)))
  __attribute__((__fd_argument (__write, 1)))

so it would be even shorter to write

  __attribute__((__fd_argument_access (1)))
  __attribute__((__fd_argument_read (1)))
  __attribute__((__fd_argument_write (1)))

> 
> I just realized that the attribute could accept both the single integer
> argument number (syntax (c)) for the "don't care about access
> direction" case, or the ({read|write}, N) of syntax (b) above, giving
> e.g.:
> 
> int dup (int oldfd)
>   __attribute((fd_argument (1)); 
> 
> int ftruncate (int fd, off_t length)
>   __attribute((fd_argument (1)); 
> 
> ssize_t pread(int fd, void *buf, size_t count, off_t offset)
>   __attribute((fd_argument (read, 1));
> 
> ssize_t pwrite(int fd, const void *buf, size_t count, 
>off_t offset);
>   __attribute((fd_argument (write, 1));
> 
> for the above examples.
> 
> How does that look?
> Dave

i think fd in ftruncate should be open for writing.

to be honest, i'd expect interesting fd bugs to be
dynamic and not easy to statically analyze.
the use-after-unchecked-open maybe useful. i would
not expect the access direction to catch many bugs.


AArch64 vector ABI vs OpenMP

2022-06-29 Thread Szabolcs Nagy via Gcc
Last time aarch64 libmvec was discussed, the OpenMP
declare variant syntax support was not ready in gcc
and there were open questions around how simd isa
variants would be supported.

https://gcc.gnu.org/pipermail/gcc-patches/2019-October/532940.html

The vector function ABI for aarch64 allows the declare
variant syntax and that is the only way to declare
vector math functions for a particular isa only.

https://github.com/ARM-software/abi-aa/blob/main/vfabia64/vfabia64.rst#aarch64-variant-traits

I would like to get feedback if there may be anything
preventing declare variant simd support on aarch64 like

  float64x2_t simd_cos (float64x2_t);

  #pragma omp declare variant(simd_cos) \
 match(construct={simd(simdlen(2), notinbranch)}, device={isa("simd")})
  double cos (double);

where isa("simd") means simd_cos can be used when
auto vectorizing cos calls with advanced simd.

Our hope is that this enables libmvec on aarch64
such that at least advanced simd variants of
some math functions can be declared in math.h
and implemented in libm, suitable for vectorization.
(Using the vector ABI names of those functions.)

Eventually we want to add isa("sve") support too,
but that may require further work on how scalable
vector length is represented.

Please let me know if there are outstanding issues
with this approach.

thanks.


Re: [PATCH] aarch64: Fix pac-ret with unusual dwarf in libgcc unwinder [PR104689]

2022-05-24 Thread Szabolcs Nagy via Gcc-patches
The 05/13/2022 16:35, Richard Sandiford wrote:
> Szabolcs Nagy via Gcc-patches  writes:
> > The RA_SIGN_STATE dwarf pseudo-register is normally only set using the
> > DW_CFA_AARCH64_negate_ra_state (== DW_CFA_window_save) operation which
> > toggles the return address signedness state (the default state is 0).
> > (It may be set by remember/restore_state CFI too, those save/restore
> > the state of all registers.)
> >
> > However RA_SIGN_STATE can be set directly via DW_CFA_val_expression too.
> > GCC does not generate such CFI but some other compilers reportedly do.
> >
> > Note: the toggle operation must not be mixed with other dwarf register
> > rule CFI within the same CIE and FDE.
> >
> > In libgcc we assume REG_UNSAVED means the RA_STATE is set using toggle
> > operations, otherwise we assume its value is set by other CFI.
> 
> AFAIK, this is the first time I've looked at the RA_SIGN_STATE code,
> so this is probably a naive point/question, but: it seems a bit
> underhand for the existing code to be using REG_UNSAVED and
> loc.offset to hold the toggle state.  Would it make sense to add
> a new enum value for known, pre-evaluated constants?  _Unwind_GetGR
> would then DTRT for both cases.
> 
> That's a comment about the pre-existing code though.  I agree this
> patch looks like the right fix if we keep to the current approach.

yes, this is a hack. i looked at introducing a generic REG_*
enum to deal with RA_SIGN_STATE now, but it's a bit awkward:

normally frame state for a reg starts out REG_UNSAVED, which
should mean 0 value for the RA_SIGN_STATE pseudo register.

when moving up frames the uw context gets copied and updated
according to the frame state (where REG_UNSAVED normally means
unmodified copy), this is not right for RA_SIGN_STATE which
should be reset in the absence of related dwarf ops. we can
fix this up in target hooks for update context, but we still
have to special case REG_UNSAVED.

i think introducing a new REG_CONST does not simplify the
aarch64 target code (we might need further changes to get
a clean solution).


[PATCH] aarch64: Fix pac-ret with unusual dwarf in libgcc unwinder [PR104689]

2022-05-10 Thread Szabolcs Nagy via Gcc-patches
The RA_SIGN_STATE dwarf pseudo-register is normally only set using the
DW_CFA_AARCH64_negate_ra_state (== DW_CFA_window_save) operation which
toggles the return address signedness state (the default state is 0).
(It may be set by remember/restore_state CFI too, those save/restore
the state of all registers.)

However RA_SIGN_STATE can be set directly via DW_CFA_val_expression too.
GCC does not generate such CFI but some other compilers reportedly do.

Note: the toggle operation must not be mixed with other dwarf register
rule CFI within the same CIE and FDE.

In libgcc we assume REG_UNSAVED means the RA_STATE is set using toggle
operations, otherwise we assume its value is set by other CFI.

libgcc/ChangeLog:

PR target/104689
* config/aarch64/aarch64-unwind.h (aarch64_frob_update_context):
Handle the !REG_UNSAVED case.
* unwind-dw2.c (execute_cfa_program): Fail toggle if !REG_UNSAVED.

gcc/testsuite/ChangeLog:

PR target/104689
* gcc.target/aarch64/pr104689.c: New test.
---
 gcc/testsuite/gcc.target/aarch64/pr104689.c | 149 
 libgcc/config/aarch64/aarch64-unwind.h  |   8 +-
 libgcc/unwind-dw2.c |   4 +-
 3 files changed, 159 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/aarch64/pr104689.c

diff --git a/gcc/testsuite/gcc.target/aarch64/pr104689.c 
b/gcc/testsuite/gcc.target/aarch64/pr104689.c
new file mode 100644
index 000..3b7adbdfe7d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/pr104689.c
@@ -0,0 +1,149 @@
+/* PR target/104689. Unwind across pac-ret frames with unusual dwarf.  */
+/* { dg-do run } */
+/* { dg-require-effective-target lp64 } */
+/* { dg-options "-fexceptions -O2" } */
+
+#include 
+#include 
+#include 
+
+#define die() \
+  do { \
+printf ("%s:%d: reached unexpectedly.\n", __FILE__, __LINE__); \
+fflush (stdout); \
+abort (); \
+  } while (0)
+
+
+/* Code to invoke unwinding with a logging callback.  */
+
+static struct _Unwind_Exception exc;
+
+static _Unwind_Reason_Code
+force_unwind_stop (int version, _Unwind_Action actions,
+   _Unwind_Exception_Class exc_class,
+   struct _Unwind_Exception *exc_obj,
+   struct _Unwind_Context *context,
+   void *stop_parameter)
+{
+  printf ("%s: CFA: %p PC: %p actions: %d\n",
+ __func__,
+ (void *)_Unwind_GetCFA (context),
+ (void *)_Unwind_GetIP (context),
+ (int)actions);
+  if (actions & _UA_END_OF_STACK)
+die ();
+  return _URC_NO_REASON;
+}
+
+static void force_unwind (void)
+{
+#ifndef __USING_SJLJ_EXCEPTIONS__
+  _Unwind_ForcedUnwind (, force_unwind_stop, 0);
+#else
+  _Unwind_SjLj_ForcedUnwind (, force_unwind_stop, 0);
+#endif
+}
+
+
+/* Define functions with unusual pac-ret dwarf via top level asm.  */
+
+#define STR(x) #x
+#define DW_CFA_val_expression 0x16
+#define RA_SIGN_STATE 34
+#define DW_OP_lit0 0x30
+#define DW_OP_lit1 0x31
+
+#define cfi_escape(a1, a2, a3, a4) \
+  ".cfi_escape " STR(a1) ", " STR(a2) ", " STR(a3) ", " STR(a4)
+
+/* Bytes: 0x16 0x22 0x01 0x30  */
+#define SET_RA_STATE_0 \
+  cfi_escape (DW_CFA_val_expression, RA_SIGN_STATE, 1, DW_OP_lit0)
+
+/* Bytes: 0x16 0x22 0x01 0x31  */
+#define SET_RA_STATE_1 \
+  cfi_escape (DW_CFA_val_expression, RA_SIGN_STATE, 1, DW_OP_lit1)
+
+/* These function call their argument.  */
+void unusual_pac_ret (void *);
+void unusual_no_pac_ret (void *);
+
+asm(""
+".global unusual_pac_ret\n"
+".type unusual_pac_ret, %function\n"
+"unusual_pac_ret:\n"
+"  .cfi_startproc\n"
+"  " SET_RA_STATE_0 "\n"
+"  hint25 // paciasp\n"
+"  " SET_RA_STATE_1 "\n"
+"  stp x29, x30, [sp, -16]!\n"
+"  .cfi_def_cfa_offset 16\n"
+"  .cfi_offset 29, -16\n"
+"  .cfi_offset 30, -8\n"
+"  mov x29, sp\n"
+"  blr x0\n"
+"  ldp x29, x30, [sp], 16\n"
+"  .cfi_restore 30\n"
+"  .cfi_restore 29\n"
+"  .cfi_def_cfa_offset 0\n"
+"  hint29 // autiasp\n"
+"  " SET_RA_STATE_0 "\n"
+"  ret\n"
+"  .cfi_endproc\n");
+
+asm(""
+".global unusual_no_pac_ret\n"
+".type unusual_no_pac_ret, %function\n"
+"unusual_no_pac_ret:\n"
+"  .cfi_startproc\n"
+"  " SET_RA_STATE_0 "\n"
+"  stp x29, x30, [sp, -16]!\n"
+"  .cfi_def_cfa_offset 16\n"
+"  .cfi_offset 29, -16\n"
+"  .cfi_offset 30, -8\n"
+"  mov x29, sp\n"
+"  blr x0\n"
+"  ldp x29, x30, [sp], 16\n"
+"  .cfi_restore 30\n"
+"  .cfi_restore 29\n"
+"  .cfi_def_cfa_offset 0\n"
+"  ret\n"
+"  .cfi_endproc\n");
+
+
+/* Functions to create a call chain with mixed pac-ret dwarf.  */
+
+__attribute__((target("branch-protection=pac-ret")))
+static void f2_pac_ret (void)
+{
+  force_unwind ();
+  die ();
+}
+
+__attribute__((target("branch-protection=none")))
+static void f1_no_pac_ret (void)
+{
+  unusual_pac_ret (f2_pac_ret);
+  die ();
+}
+
+__attribute__((noinline, 

Re: [PATCH] [RFC][PR102768] aarch64: Add compiler support for Shadow Call Stack

2021-11-23 Thread Szabolcs Nagy via Gcc-patches
The 11/23/2021 16:32, Dan Li wrote:
> On 11/3/21 8:00 PM, Szabolcs Nagy wrote:
> > i assume exception handling info has to change for scs to
> > work (to pop the shadow stack when transferring control),
> > so either scs must require -fno-exceptions or the eh info
> > changes must be implemented.
> > 
> > i think the kernel does not require exceptions and does
> > not depend on the unwinder runtime in libgcc, so this
> > is optional for the linux kernel use-case.
> > 
> I recompiled a glibc and gcc runtime library with -ffixed-x18 enabled.
> As you said, the scs stack needs to be popped at the same time during
> exception handling.
> 
> I saw that Clang is processed by adding
> ".cfi_escape 0x16, 0x12, 0x02, 0x82, 0x78"
> directive (x18 -= 8;) after each emit of scs push[2].
> 
> But this directive has problems when executed in libgcc:
> 1)context->reg[x] in uw_init_context_1 are all based on cfa, most
>   registers have no initial values by default.
> 2)Address of shadow call stack (x18) cannot(and should not) be calculated
>   based on cfa, and I did not yet find a way to assign hardware register
>   x18 to context->reg[18].
> 3)This causes libgcc to crash when parsing .cfi_escape exp because of 0
>   address dereference (* x18)
>   (execute_stack_op => case DW_OP_breg18: _Unwind_GetGR)
> 4)uw_install_context_1 does not restore all hardware registers by default
>   before eh return, so context->reg[18] can't write directly to hw x18.
>   (In clang, __unw_getcontext/__unw_resume will save/restore all hardware
>   registers, so this directive works fine in my libunwind test.)
> 
> I tried to fix this problem through a patch[3], the exception handling
> works fine in my test environment, but I'm not sure if this fix is
> ppropriate for two reasons:
> 1)libgcc does not push/pop all registers by default during exception
>   handling. Is this change appropriate?
> 2)The test case may not be able to test this patch, because the test
>   environment requires at least on glibc/gcc runtime compiled with
>   -ffixed-x18.
> 
> May be it's better to rely on -fno-exceptions for this patch first? and If
> the glibc/gcc runtime also supports SCS later, the problem can be fixed
> at the same time.

i did not look at the exception handling in detail (that's
difficult to understand for me too).

to use scs, non-default abi is required anyway, so not
supporting exceptions sounds fine to me. however it should
be documented and ideally enforced (-fexceptions should
be rejected, just like -fno-fixed-x18).

i assume the linux kernel does not require -fexceptions.

> 
> PS:
> I'm still not familiar enough with exception handling in libgcc/libunwind,
> please correct me if there are any mistakes :)
> 
> [1] 
> https://github.com/llvm/llvm-project/commit/f11eb3ebe77729426e562d7d4d7ebb1d5ff2e7c8
> [2] https://reviews.llvm.org/D54609
> [3] https://gcc.gnu.org/bugzilla/attachment.cgi?id=51854=diff
> 


Re: [PATCH] [RFC][PR102768] aarch64: Add compiler support for Shadow Call Stack

2021-11-03 Thread Szabolcs Nagy via Gcc-patches
The 11/03/2021 00:24, Dan Li wrote:
> On 11/2/21 9:04 PM, Szabolcs Nagy wrote:
> > The 11/02/2021 00:06, Dan Li via Gcc-patches wrote:
> > > Shadow Call Stack can be used to protect the return address of a
> > > function at runtime, and clang already supports this feature[1].
> > > 
> > > To enable SCS in user mode, in addition to compiler, other support
> > > is also required (as described in [2]). This patch only adds basic
> > > support for SCS from the compiler side, and provides convenience
> > > for users to enable SCS.
> > > 
> > > For linux kernel, only the support of the compiler is required.
> > > 
> > > [1] https://clang.llvm.org/docs/ShadowCallStack.html
> > > [2] https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102768
> > 
> > i'm not a gcc maintainer, but i prefer such feature
> > to be in upstream gcc instead of in a plugin.
> > 
> > it will require update to the documentation:
> > 
> > which should mention that it depends on -ffixed-x18
> > (probably that should be enforced too) which is an
> > important abi issue: functions following the normal
> > pcs can clobber x18 and break scs.
> > 
> Thanks Szabolcs, I will update the documentation in next version.
> 
> It sounds reasonable to enforced -ffixed-x18 with scs, but I see
> that clang doesn’t do that. Maybe it is better to be consistent
> with clang here?

i mean gcc can issue a diagnostic if -ffixed-x18 is not passed.
(it seems clang rejects scs too without -ffixed-x18)

> > and that there is no unwinder support.
> > 
> Ok, let me try to add a support for this.

i assume exception handling info has to change for scs to
work (to pop the shadow stack when transferring control),
so either scs must require -fno-exceptions or the eh info
changes must be implemented.

i think the kernel does not require exceptions and does
not depend on the unwinder runtime in libgcc, so this
is optional for the linux kernel use-case.


Re: [PATCH] [RFC][PR102768] aarch64: Add compiler support for Shadow Call Stack

2021-11-02 Thread Szabolcs Nagy via Gcc-patches
The 11/02/2021 00:06, Dan Li via Gcc-patches wrote:
> Shadow Call Stack can be used to protect the return address of a
> function at runtime, and clang already supports this feature[1].
> 
> To enable SCS in user mode, in addition to compiler, other support
> is also required (as described in [2]). This patch only adds basic
> support for SCS from the compiler side, and provides convenience
> for users to enable SCS.
> 
> For linux kernel, only the support of the compiler is required.
> 
> [1] https://clang.llvm.org/docs/ShadowCallStack.html
> [2] https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102768

i'm not a gcc maintainer, but i prefer such feature
to be in upstream gcc instead of in a plugin.

it will require update to the documentation:

which should mention that it depends on -ffixed-x18
(probably that should be enforced too) which is an
important abi issue: functions following the normal
pcs can clobber x18 and break scs.

and that there is no unwinder support.

the abi issue means it is unlikely to be useful in
linux user space (even if libc and unwinder support
is implemented), but it can be still useful in
freestanding code such as the linux kernel.

thanks.

> 
> gcc/c-family/ChangeLog:
> 
>   * c-attribs.c (handle_no_sanitize_shadow_call_stack_attribute):
> 
> gcc/ChangeLog:
> 
>   * config/aarch64/aarch64-protos.h (aarch64_shadow_call_stack_enabled):
>   * config/aarch64/aarch64.c (aarch64_shadow_call_stack_enabled):
>   (aarch64_expand_prologue):
>   (aarch64_expand_epilogue):
>   * config/aarch64/aarch64.h (TARGET_SUPPORT_SHADOW_CALL_STACK):
>   * config/aarch64/aarch64.md (scs_push):
>   (scs_pop):
>   * defaults.h (TARGET_SUPPORT_SHADOW_CALL_STACK):
>   * flag-types.h (enum sanitize_code):
>   * opts.c (finish_options):
> 
> Signed-off-by: Dan Li 
> ---
>  gcc/c-family/c-attribs.c| 21 +
>  gcc/config/aarch64/aarch64-protos.h |  1 +
>  gcc/config/aarch64/aarch64.c| 27 +++
>  gcc/config/aarch64/aarch64.h|  4 
>  gcc/config/aarch64/aarch64.md   | 18 ++
>  gcc/defaults.h  |  4 
>  gcc/flag-types.h|  2 ++
>  gcc/opts.c  |  6 ++
>  8 files changed, 83 insertions(+)
> 
> diff --git a/gcc/c-family/c-attribs.c b/gcc/c-family/c-attribs.c
> index 007b928c54b..9b3a35c06bf 100644
> --- a/gcc/c-family/c-attribs.c
> +++ b/gcc/c-family/c-attribs.c
> @@ -56,6 +56,8 @@ static tree handle_cold_attribute (tree *, tree, tree, int, 
> bool *);
>  static tree handle_no_sanitize_attribute (tree *, tree, tree, int, bool *);
>  static tree handle_no_sanitize_address_attribute (tree *, tree, tree,
> int, bool *);
> +static tree handle_no_sanitize_shadow_call_stack_attribute (tree *, tree,
> +   tree, int, bool *);
>  static tree handle_no_sanitize_thread_attribute (tree *, tree, tree,
>int, bool *);
>  static tree handle_no_address_safety_analysis_attribute (tree *, tree, tree,
> @@ -454,6 +456,10 @@ const struct attribute_spec c_common_attribute_table[] =
> handle_no_sanitize_attribute, NULL },
>{ "no_sanitize_address",0, 0, true, false, false, false,
> handle_no_sanitize_address_attribute, NULL },
> +  { "no_sanitize_shadow_call_stack",
> +   0, 0, true, false, false, false,
> +   handle_no_sanitize_shadow_call_stack_attribute,
> +   NULL },
>{ "no_sanitize_thread", 0, 0, true, false, false, false,
> handle_no_sanitize_thread_attribute, NULL },
>{ "no_sanitize_undefined",  0, 0, true, false, false, false,
> @@ -1175,6 +1181,21 @@ handle_no_sanitize_address_attribute (tree *node, tree 
> name, tree, int,
>return NULL_TREE;
>  }
>  
> +/* Handle a "no_sanitize_shadow_call_stack" attribute; arguments as in
> +   struct attribute_spec.handler.  */
> +static tree
> +handle_no_sanitize_shadow_call_stack_attribute (tree *node, tree name,
> +   tree, int, bool *no_add_attrs)
> +{
> +  *no_add_attrs = true;
> +  if (TREE_CODE (*node) != FUNCTION_DECL)
> +warning (OPT_Wattributes, "%qE attribute ignored", name);
> +  else
> +add_no_sanitize_value (*node, SANITIZE_SHADOW_CALL_STACK);
> +
> +  return NULL_TREE;
> +}
> +
>  /* Handle a "no_sanitize_thread" attribute; arguments as in
> struct attribute_spec.handler.  */
>  
> diff --git a/gcc/config/aarch64/aarch64-protos.h 
> b/gcc/config/aarch64/aarch64-protos.h
> index 768e8fae136..150c015df21 100644
> --- a/gcc/config/aarch64/aarch64-protos.h
> +++ b/gcc/config/aarch64/aarch64-protos.h
> @@ -893,6 +893,7 @@ void aarch64_register_pragmas (void);
>  void aarch64_relayout_simd_types (void);
>  void 

Re: unnormal Intel 80-bit long doubles and isnanl

2020-11-24 Thread Szabolcs Nagy via Gcc
The 11/24/2020 16:23, Siddhesh Poyarekar wrote:
> Hi,
> 
> The Intel 80-bit long double format has a concept of "unnormal" numbers that
> have a non-zero exponent and zero integer bit (i.e. bit 63) in the mantissa;
> all valid long double numbers have their integer bit set to 1.  Unnormal
> numbers are mentioned in "8.2.2 Unsupported Double Extended-Precision
> Floating-Point Encodings and Pseudo-Denormals" and listed in Table 8-3 in
> the Intel 64 and IA-32 Architectures Software Developer’s Manual Volume
> 1:Basic Architecture.
> 
> As per the manual, these numbers are considered unsupported and generate an
> invalid-operation exception if they are used as operands to any floating
> point instructions.  The question of this email is how the toolchain
> (including glibc) should treat these numbers since as things stand today,
> glibc and gcc disagree when it comes to isnanl.

ideally fpclassify (and other classification macros) would
handle all representations.

architecturally invalid or trap representations can be a
non-standard class but i think classifying them as FP_NAN
would break the least amount of code.

> glibc evaluates the bit pattern of the 80-bit long double and in the
> process, ignores the integer bit, i.e. bit 63.  As a result, it considers
> the unnormal number as a valid long double and isnanl returns 0.

i think m68k and x86 are different here.

> 
> gcc on the other hand, simply uses the number in a floating point comparison
> and uses the parity flag (which indicates an unordered compare, signalling a
> NaN) to decide if the number is a NaN.  The unnormal numbers behave like
> NaNs in this respect, in that they set the parity flag and with
> -fsignalling-nans, would result in an invalid-operation exception.  As a
> result, __builtin_isnanl returns 1 for an unnormal number.

compiling isnanl to a quiet fp compare is wrong with
-fsignalling-nans: classification is not supposed to
signal exceptions for snan.

> 
> So the question is, which behaviour should be considered correct? Strictly
> speaking, unnormal numbers are listed separately from NaNs in the document
> and as such are distinct from NaNs.  So on the question of "is nan?" the
> answer ought to be "No".
> 
> On the flip side, the behaviour described (and experienced through code) is
> exactly the same as a NaN, i.e. a floating point operation sets the parity
> flag and generates an invalid-operation exception.  So if it looks like a
> NaN, behaves like a NaN, then even if the document hints (and it is just a
> hint right, since it doesn't specifically state it?) that it's different, it
> likely is a NaN.  What's more, one of the fixes to glibc[1] assumes that
> __builtin_isnanl will do the right thing.
> 
> The third alternative (which seems like a step back to me, but will concede
> that it is a valid resolution) is to state that unnormal input to isnanl
> would result in undefined behaviour and hence it is the responsibility of
> the application to ensure that inputs to isnanl are never unnormal.
> 
> Thoughts?
> 
> Siddhesh
> 
> [1] 
> https://sourceware.org/git/?p=glibc.git;h=0474cd5de60448f31d7b872805257092faa626e4


Re: Fix handling of stores in modref_summary::useful_p

2020-10-06 Thread Szabolcs Nagy via Gcc-patches
The 10/05/2020 23:45, Jan Hubicka wrote:
> > The 10/05/2020 17:28, Szabolcs Nagy via Gcc-patches wrote:
> > minimal reproducer:
> > 
> > #include 
> > int main()
> > {
> > int r,t;
> > r = sscanf("01", "%2x", );
> > printf("scanf: %d  %02x\n", r, t);
> > return 0;
> > }
> > 
> > should print
> > 
> > scanf: 1  01
> > 
> > but when glibc is compiled with gcc trunk on aarch64 it prints
> > 
> > scanf: 0  00
> > 
> > i will continute the debugging from here tomorrow.
> 
> There is a report on glibc issue here 
> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97264
> it turned out to be a latent glibc bug type punning const char * and
> const unsigned char *.
> 
> I wonder if it is same as problem you are seeing?

thanks, that indeed looks very similar, i'll comment on the glibc bug.


Re: Fix handling of stores in modref_summary::useful_p

2020-10-05 Thread Szabolcs Nagy via Gcc-patches
The 10/05/2020 17:28, Szabolcs Nagy via Gcc-patches wrote:
> The 10/05/2020 12:52, Vaseeharan Vinayagamoorthy wrote:
> > Hi,
> > 
> > After this patch, I am noticing that some glibc crypto tests get stuck in 
> > scanf which goes into busy loop.
> > 
> > My build/host/target setup is:
> > Build: aarch64-none-linux-gnu
> > Host: aarch64-none-linux-gnu
> > Target: aarch64-none-linux-gnu
> 
> i can reproduce this on aarch64, i'm looking at it:
> 
> if i compile glibc with gcc trunk after this commit i see
> 
> $ ./testrun.sh crypt/cert < $glibcsrc/crypt/cert.input
>  K:  P:  C:  Encrypt FAIL
>  K:  P:  C:  Encrypt FAIL
>  K:  P:  C:  Encrypt FAIL
>  K:  P:  C:  Encrypt FAIL
>  K:  P:  C:  Encrypt FAIL
>  K:  P:  C:  Encrypt FAIL
> ...
> 
> it just keeps printing this.
> 
> same test binary with glibc code compiled with an
> older gcc works, so something in glibc gets miscompiled.
> 
> i will have to do more digging to figure out what.

minimal reproducer:

#include 
int main()
{
int r,t;
r = sscanf("01", "%2x", );
printf("scanf: %d  %02x\n", r, t);
return 0;
}

should print

scanf: 1  01

but when glibc is compiled with gcc trunk on aarch64 it prints

scanf: 0  00

i will continute the debugging from here tomorrow.


> > On 27/09/2020, 22:46, "Gcc-patches on behalf of Jan Hubicka" 
> >  wrote:
> > 
> > Hi,
> > this patch fixes a pasto in modref_summary::useful_p that made
> > ipa-modref to give up on tracking stores when all load info got lost.
> > 
> > Bootstrapped/regtested x86_64-linux, comitted.
> > 
> > gcc/ChangeLog:
> > 
> > 2020-09-27  Jan Hubicka  
> > 
> > * ipa-modref.c (modref_summary::useful_p): Fix testing of stores.
> > 
> > diff --git a/gcc/ipa-modref.c b/gcc/ipa-modref.c
> > index 728c6c1523d..6225552e41a 100644
> > --- a/gcc/ipa-modref.c
> > +++ b/gcc/ipa-modref.c
> > @@ -135,7 +135,7 @@ modref_summary::useful_p (int ecf_flags)
> >  return true;
> >if (ecf_flags & ECF_PURE)
> >  return false;
> > -  return stores && !loads->every_base;
> > +  return stores && !stores->every_base;
> >  }
> > 
> >  /* Dump A to OUT.  */
> > 


Re: Fix handling of stores in modref_summary::useful_p

2020-10-05 Thread Szabolcs Nagy via Gcc-patches
The 10/05/2020 12:52, Vaseeharan Vinayagamoorthy wrote:
> Hi,
> 
> After this patch, I am noticing that some glibc crypto tests get stuck in 
> scanf which goes into busy loop.
> 
> My build/host/target setup is:
> Build: aarch64-none-linux-gnu
> Host: aarch64-none-linux-gnu
> Target: aarch64-none-linux-gnu

i can reproduce this on aarch64, i'm looking at it:

if i compile glibc with gcc trunk after this commit i see

$ ./testrun.sh crypt/cert < $glibcsrc/crypt/cert.input
 K:  P:  C:  Encrypt FAIL
 K:  P:  C:  Encrypt FAIL
 K:  P:  C:  Encrypt FAIL
 K:  P:  C:  Encrypt FAIL
 K:  P:  C:  Encrypt FAIL
 K:  P:  C:  Encrypt FAIL
...

it just keeps printing this.

same test binary with glibc code compiled with an
older gcc works, so something in glibc gets miscompiled.

i will have to do more digging to figure out what.




> 
> 
> 
> Kind regards
> Vasee
> 
> 
> On 27/09/2020, 22:46, "Gcc-patches on behalf of Jan Hubicka" 
>  wrote:
> 
> Hi,
> this patch fixes a pasto in modref_summary::useful_p that made
> ipa-modref to give up on tracking stores when all load info got lost.
> 
> Bootstrapped/regtested x86_64-linux, comitted.
> 
> gcc/ChangeLog:
> 
> 2020-09-27  Jan Hubicka  
> 
> * ipa-modref.c (modref_summary::useful_p): Fix testing of stores.
> 
> diff --git a/gcc/ipa-modref.c b/gcc/ipa-modref.c
> index 728c6c1523d..6225552e41a 100644
> --- a/gcc/ipa-modref.c
> +++ b/gcc/ipa-modref.c
> @@ -135,7 +135,7 @@ modref_summary::useful_p (int ecf_flags)
>  return true;
>if (ecf_flags & ECF_PURE)
>  return false;
> -  return stores && !loads->every_base;
> +  return stores && !stores->every_base;
>  }
> 
>  /* Dump A to OUT.  */
> 

-- 


Re: [PING 2][PATCH 2/5] C front end support to detect out-of-bounds accesses to array parameters

2020-10-05 Thread Szabolcs Nagy via Gcc-patches
The 09/23/2020 21:45, Jeff Law wrote:
> On 9/23/20 11:45 AM, Martin Sebor via Gcc-patches wrote:
> > On 9/23/20 9:44 AM, Szabolcs Nagy wrote:
> > > The 09/23/2020 09:22, Szabolcs Nagy wrote:
> > > > The 09/21/2020 12:45, Martin Sebor via Gcc-patches wrote:
> > > > > On 9/21/20 12:20 PM, Vaseeharan Vinayagamoorthy wrote:
> > > > > > After this patch, I am seeing this -Warray-parameter error:
> > > > > > 
> > > > > > In file included from ../include/pthread.h:1,
> > > > > >    from ../sysdeps/nptl/thread_db.h:25,
> > > > > >    from ../nptl/descr.h:32,
> > > > > >    from ../sysdeps/aarch64/nptl/tls.h:44,
> > > > > >    from ../include/errno.h:25,
> > > > > >    from ../sysdeps/unix/sysv/linux/sysdep.h:23,
> > > > > >    from
> > > > > > ../sysdeps/unix/sysv/linux/generic/sysdep.h:22,
> > > > > >    from
> > > > > > ../sysdeps/unix/sysv/linux/aarch64/sysdep.h:24,
> > > > > >    from :1:
> > > > > > ../sysdeps/nptl/pthread.h:734:47: error: argument 1 of
> > > > > > type ‘struct __jmp_buf_tag *’ declared as a pointer
> > > > > > [-Werror=array-parameter=]
> > > > > >     734 | extern int __sigsetjmp (struct __jmp_buf_tag
> > > > > > *__env, int __savemask) __THROWNL;
> > > > > >     | ~~^
> > > > > > In file included from ../include/setjmp.h:2,
> > > > > >    from ../nptl/descr.h:24,
> > > > > >    from ../sysdeps/aarch64/nptl/tls.h:44,
> > > > > >    from ../include/errno.h:25,
> > > > > >    from ../sysdeps/unix/sysv/linux/sysdep.h:23,
> > > > > >    from
> > > > > > ../sysdeps/unix/sysv/linux/generic/sysdep.h:22,
> > > > > >    from
> > > > > > ../sysdeps/unix/sysv/linux/aarch64/sysdep.h:24,
> > > > > >    from :1:
> > > > > > ../setjmp/setjmp.h:54:46: note: previously declared as
> > > > > > an array ‘struct __jmp_buf_tag[1]’
> > > > > >  54 | extern int __sigsetjmp (struct __jmp_buf_tag
> > > > > > __env[1], int __savemask) __THROWNL;
> > > > > >     | ~^~~~
> > > > > > cc1: all warnings being treated as errors
> > > > > 
> > > > > The warning flags differences between the forms of array parameters
> > > > > in redeclarations of the same function, including pointers vs arrays
> > > > > as in this instance.  It needs to be suppressed in glibc, either by
> > > > > making the function declarations consistent, or by #pragma diagnostic.
> > > > > (IIRC, the pointer declaration comes before struct __jmp_buf_tag has
> > > > > been defined so simply using the array form there doesn't work without
> > > > > defining the type first.)
> > > > > 
> > > > > I would expect the warning to be suppressed when using the installed
> > > > > library thanks to -Wno-system-headers.
> > > > 
> > > > why is this a warning? i'm not convinced it
> > > > should be in -Wall.
> > 
> > The main motivation for the warning is to detect unintentional
> > inconsistencies between function redeclarations that make deriving
> > true true intent difficult or impossible  (e.g, T[3] vs T[1], or
> > T[] vs T[1], or equivalently T* vs T[1]).
> > 
> > One goal is to support the convention where a constant array bound
> > in a function array parameter is used in lieu of the [static N]
> > notation (i.e., the minimum number of elements the caller is
> > expected to  make available).  The [static N] notation is little
> > known, used only exceedingly rarely, and isn't available in C++.
> > The array notation is used more often, although by no means common.
> > 
> > The ultimate goal is to motivate users to take advantage of GCC's
> > ability to check ordinary functions for out-of-bounds accesses to
> > array arguments.  The checking is only feasible if all declarations
> > of the same function, including its definition, use a consistent
> > notation to specify the same bound.  Including th

Re: [RFC] man7/system_data_types.7: Document [unsigned] __int128

2020-10-01 Thread Szabolcs Nagy via Gcc
The 10/01/2020 12:14, Alejandro Colomar via Gcc wrote:
> Here is the rendered intmax_t:
> 
> intmax_t
>   Include: .  Alternatively, .
> 
>   A  signed  integer type capable of representing any value of any
>   signed integer type supported by the implementation.   According
>   to  the C language standard, it shall be capable of storing val-
>   ues in the range [INTMAX_MIN, INTMAX_MAX].
> 
>   The macro INTMAX_C() expands its argument to an integer constant
>   of type intmax_t.
> 
>   The  length  modifier  for  intmax_t  for  the printf(3) and the
>   scanf(3) families of functions is j; resulting commonly  in  %jd
>   or %ji for printing intmax_t values.
> 
>   Bugs:  intmax_t  is not large enough to represent values of type
>   __int128 in implementations where __int128 is defined  and  long
>   long is less than 128 bits wide.

or __int128 is not an integer type.

integer types are either standard or extended.
and __int128 is neither because it can be
larger than intmax_t and stdint.h does not
provide the necessary macros for it.

> 
>   Conforming to: C99 and later; POSIX.1-2001 and later.
> 
>   See also the uintmax_t type in this page.



Re: [PING 2][PATCH 2/5] C front end support to detect out-of-bounds accesses to array parameters

2020-09-23 Thread Szabolcs Nagy
The 09/23/2020 09:22, Szabolcs Nagy wrote:
> The 09/21/2020 12:45, Martin Sebor via Gcc-patches wrote:
> > On 9/21/20 12:20 PM, Vaseeharan Vinayagamoorthy wrote:
> > > After this patch, I am seeing this -Warray-parameter error:
> > > 
> > > In file included from ../include/pthread.h:1,
> > >   from ../sysdeps/nptl/thread_db.h:25,
> > >   from ../nptl/descr.h:32,
> > >   from ../sysdeps/aarch64/nptl/tls.h:44,
> > >   from ../include/errno.h:25,
> > >   from ../sysdeps/unix/sysv/linux/sysdep.h:23,
> > >   from ../sysdeps/unix/sysv/linux/generic/sysdep.h:22,
> > >   from ../sysdeps/unix/sysv/linux/aarch64/sysdep.h:24,
> > >   from :1:
> > > ../sysdeps/nptl/pthread.h:734:47: error: argument 1 of type ‘struct 
> > > __jmp_buf_tag *’ declared as a pointer [-Werror=array-parameter=]
> > >734 | extern int __sigsetjmp (struct __jmp_buf_tag *__env, int 
> > > __savemask) __THROWNL;
> > >| ~~^
> > > In file included from ../include/setjmp.h:2,
> > >   from ../nptl/descr.h:24,
> > >   from ../sysdeps/aarch64/nptl/tls.h:44,
> > >   from ../include/errno.h:25,
> > >   from ../sysdeps/unix/sysv/linux/sysdep.h:23,
> > >   from ../sysdeps/unix/sysv/linux/generic/sysdep.h:22,
> > >   from ../sysdeps/unix/sysv/linux/aarch64/sysdep.h:24,
> > >   from :1:
> > > ../setjmp/setjmp.h:54:46: note: previously declared as an array ‘struct 
> > > __jmp_buf_tag[1]’
> > > 54 | extern int __sigsetjmp (struct __jmp_buf_tag __env[1], int 
> > > __savemask) __THROWNL;
> > >| ~^~~~
> > > cc1: all warnings being treated as errors
> > 
> > The warning flags differences between the forms of array parameters
> > in redeclarations of the same function, including pointers vs arrays
> > as in this instance.  It needs to be suppressed in glibc, either by
> > making the function declarations consistent, or by #pragma diagnostic.
> > (IIRC, the pointer declaration comes before struct __jmp_buf_tag has
> > been defined so simply using the array form there doesn't work without
> > defining the type first.)
> > 
> > I would expect the warning to be suppressed when using the installed
> > library thanks to -Wno-system-headers.
> 
> why is this a warning? i'm not convinced it
> should be in -Wall.
> 
> this is a warning with false positives that
> have no portable workaround and does not
> really help catching bugs (at least i doubt
> inconsistent array vs pointer declaration
> is causing common problems).
> 
> what gcc should warn about is if there is an
> array style argument declaration and a caller
> passes an array that's provably shorter than
> that.

i take this back: such warning only makes
sense when the static keyword is used in
the array declarator.

i really think this issue should be fixed
in gcc and not in glibc: it's not true that
the argument has array type, the standard
requires the parameter type to be adjusted:

  A declaration of a parameter as "array of type"
  shall be adjusted to "qualified pointer to type"

this warning will just confuse users and
make them believe that the two declaration
styles for pointer arguments are somehow
different.


Re: [PING 2][PATCH 2/5] C front end support to detect out-of-bounds accesses to array parameters

2020-09-23 Thread Szabolcs Nagy
The 09/21/2020 12:45, Martin Sebor via Gcc-patches wrote:
> On 9/21/20 12:20 PM, Vaseeharan Vinayagamoorthy wrote:
> > After this patch, I am seeing this -Warray-parameter error:
> > 
> > In file included from ../include/pthread.h:1,
> >   from ../sysdeps/nptl/thread_db.h:25,
> >   from ../nptl/descr.h:32,
> >   from ../sysdeps/aarch64/nptl/tls.h:44,
> >   from ../include/errno.h:25,
> >   from ../sysdeps/unix/sysv/linux/sysdep.h:23,
> >   from ../sysdeps/unix/sysv/linux/generic/sysdep.h:22,
> >   from ../sysdeps/unix/sysv/linux/aarch64/sysdep.h:24,
> >   from :1:
> > ../sysdeps/nptl/pthread.h:734:47: error: argument 1 of type ‘struct 
> > __jmp_buf_tag *’ declared as a pointer [-Werror=array-parameter=]
> >734 | extern int __sigsetjmp (struct __jmp_buf_tag *__env, int 
> > __savemask) __THROWNL;
> >| ~~^
> > In file included from ../include/setjmp.h:2,
> >   from ../nptl/descr.h:24,
> >   from ../sysdeps/aarch64/nptl/tls.h:44,
> >   from ../include/errno.h:25,
> >   from ../sysdeps/unix/sysv/linux/sysdep.h:23,
> >   from ../sysdeps/unix/sysv/linux/generic/sysdep.h:22,
> >   from ../sysdeps/unix/sysv/linux/aarch64/sysdep.h:24,
> >   from :1:
> > ../setjmp/setjmp.h:54:46: note: previously declared as an array ‘struct 
> > __jmp_buf_tag[1]’
> > 54 | extern int __sigsetjmp (struct __jmp_buf_tag __env[1], int 
> > __savemask) __THROWNL;
> >| ~^~~~
> > cc1: all warnings being treated as errors
> 
> The warning flags differences between the forms of array parameters
> in redeclarations of the same function, including pointers vs arrays
> as in this instance.  It needs to be suppressed in glibc, either by
> making the function declarations consistent, or by #pragma diagnostic.
> (IIRC, the pointer declaration comes before struct __jmp_buf_tag has
> been defined so simply using the array form there doesn't work without
> defining the type first.)
> 
> I would expect the warning to be suppressed when using the installed
> library thanks to -Wno-system-headers.

why is this a warning? i'm not convinced it
should be in -Wall.

this is a warning with false positives that
have no portable workaround and does not
really help catching bugs (at least i doubt
inconsistent array vs pointer declaration
is causing common problems).

what gcc should warn about is if there is an
array style argument declaration and a caller
passes an array that's provably shorter than
that.

pointer style declaration should be possible
to mix with array style (this is important
for standard headers but any api with multiple
implementations can end up in situations where
both array and pointer style decl will be
present).



Re: [PATCH] configure: Require C++11 for building code generation tools

2020-08-20 Thread Szabolcs Nagy
The 08/20/2020 13:59, Vasee Vinayagamoorthy wrote:
> +# Also require C++11 for building code generation tools.
> +# Do nothing if "${build}" = "${host}", because in this case
> +# CXX_FOR_BUILD="\$(CXX)", and $CXX is already set to the correct value 
> above.
> +if test "${build}" != "${host}"; then
> +  saved_CXX=$CXX
> +  saved_CXXCPP=$CXXCPP
> +  CXX=$CXX_FOR_BUILD
> +  CXXCPP=
> +  AX_CXX_COMPILE_STDCXX(11)
> +  CXX="$CXX -std=c++11"
> +  CXX_FOR_BUILD=$CXX
> +  CXX=$saved_CXX
> +  CXXCPP=$saved_CXXCPP
> +fi

i think AX_CXX_COMPILE_STDCXX(11) should
set CXX correctly (it seems it would set
it to "g++ -std=gnu++11" instead of
"g++ -std=c++11" but either should work)

please look at the top level config.log
i think you should look for

"checking whether g++ supports C++11 features with -std=gnu++11"

and that check should be successful.


[PATCH 2/2] aarch64: add PAC-RET protection to libitm sjlj.S

2020-07-23 Thread Szabolcs Nagy
_ITM_beginTransaction is a 'returns_twice' function that saves x30
on the stack as part of gtm_jmpbuf (that is passed down to
GTM_begin_transaction), but the saved x30 is also used for return.

The return path should be protected so we don't leave an
  ldp x29, x30, [sp]
  ret
gadget in the code, so x30 is signed on function entry. This
exposes the signed address in the gtm_jmpbuf too. The jmpbuf does
not need a signed address since GTM_longjmp uses
  ldp x29, x30, [x1]
  br x30
and with BTI there is a BTI j at the _ITM_beginTransaction call site
where this jump returns. Using PAC does not hurt: the gtm_jmpbuf is
internal to libitm and its layout is only used by sjlj.S so the
signed address does not escape. Saving signed x30 into gtm_jmpbuf
provides a bit of extra protection, but more importantly it allows
adding the PAC-RET support without changing the existing code much.

In theory bti and pac-ret protection can be added unconditionally
since the instructions are in the nop space, in practice they
can cause trouble if some tooling does not understand the gnu
property note (e.g. old binutils) or some unwinder or debugger
does not understand the new dwarf op code used for pac-ret (e.g
old gdb). So the code is written to only support branch-protection
according to the code generation options.

libitm/ChangeLog:

* config/aarch64/sjlj.S: Add conditional pac-ret protection.
---
 libitm/config/aarch64/sjlj.S | 56 ++--
 1 file changed, 53 insertions(+), 3 deletions(-)

diff --git a/libitm/config/aarch64/sjlj.S b/libitm/config/aarch64/sjlj.S
index e2093ca1a97..c84e98aecad 100644
--- a/libitm/config/aarch64/sjlj.S
+++ b/libitm/config/aarch64/sjlj.S
@@ -25,6 +25,35 @@
 #include "asmcfi.h"
 
 #define BTI_C  hint34
+#define PACIASPhint25
+#define AUTIASPhint29
+#define PACIBSPhint27
+#define AUTIBSPhint31
+
+#if defined(HAVE_AS_CFI_PSEUDO_OP) && defined(__GCC_HAVE_DWARF2_CFI_ASM)
+# define cfi_window_save .cfi_window_save
+# define cfi_b_key_frame .cfi_b_key_frame
+#else
+# define cfi_window_save
+# define cfi_b_key_frame
+#endif
+
+#if __ARM_FEATURE_PAC_DEFAULT & 1
+# define CFI_PAC_TOGGLEcfi_window_save
+# define CFI_PAC_KEY
+# define PAC_AND_BTI   PACIASP
+# define AUT   AUTIASP
+#elif __ARM_FEATURE_PAC_DEFAULT & 2
+# define CFI_PAC_TOGGLEcfi_window_save
+# define CFI_PAC_KEY   cfi_b_key_frame
+# define PAC_AND_BTI   PACIBSP
+# define AUT   AUTIBSP
+#else
+# define CFI_PAC_TOGGLE
+# define CFI_PAC_KEY
+# define PAC_AND_BTI   BTI_C
+# define AUT
+#endif
 
.text
.align  2
@@ -33,7 +62,9 @@
 
 _ITM_beginTransaction:
cfi_startproc
-   BTI_C
+   CFI_PAC_KEY
+   PAC_AND_BTI
+   CFI_PAC_TOGGLE
mov x1, sp
stp x29, x30, [sp, -11*16]!
cfi_adjust_cfa_offset(11*16)
@@ -60,6 +91,8 @@ _ITM_beginTransaction:
cfi_adjust_cfa_offset(-11*16)
cfi_restore(x29)
cfi_restore(x30)
+   AUT
+   CFI_PAC_TOGGLE
ret
cfi_endproc
.size   _ITM_beginTransaction, . - _ITM_beginTransaction
@@ -73,6 +106,7 @@ GTM_longjmp:
/* The first parameter becomes the return value (x0).
   The third parameter is ignored for now.  */
cfi_startproc
+   CFI_PAC_KEY
BTI_C
ldp x19, x20, [x1, 1*16]
ldp x21, x22, [x1, 2*16]
@@ -86,7 +120,10 @@ GTM_longjmp:
ldr x3, [x1, 10*16]
ldp x29, x30, [x1]
cfi_def_cfa(x1, 0)
+   CFI_PAC_TOGGLE
mov sp, x3
+   AUT
+   CFI_PAC_TOGGLE
br  x30
cfi_endproc
.size   GTM_longjmp, . - GTM_longjmp
@@ -96,6 +133,19 @@ GTM_longjmp:
 #define FEATURE_1_BTI 1
 #define FEATURE_1_PAC 2
 
+/* Supported features based on the code generation options.  */
+#if defined(__ARM_FEATURE_BTI_DEFAULT)
+# define BTI_FLAG FEATURE_1_BTI
+#else
+# define BTI_FLAG 0
+#endif
+
+#if __ARM_FEATURE_PAC_DEFAULT & 3
+# define PAC_FLAG FEATURE_1_PAC
+#else
+# define PAC_FLAG 0
+#endif
+
 /* Add a NT_GNU_PROPERTY_TYPE_0 note.  */
 #define GNU_PROPERTY(type, value)  \
   .section .note.gnu.property, "a";\
@@ -113,7 +163,7 @@ GTM_longjmp:
 .section .note.GNU-stack, "", %progbits
 
 /* Add GNU property note if built with branch protection.  */
-# ifdef __ARM_FEATURE_BTI_DEFAULT
-GNU_PROPERTY (FEATURE_1_AND, FEATURE_1_BTI)
+# if (BTI_FLAG|PAC_FLAG) != 0
+GNU_PROPERTY (FEATURE_1_AND, BTI_FLAG|PAC_FLAG)
 # endif
 #endif
-- 
2.17.1



[PATCH 1/2] aarch64: add PAC GNU property note to libgcc lse.S

2020-07-23 Thread Szabolcs Nagy
This note is not used anywhere currently but it is supposed to mark
objects if the return address is protected with PAC on the stack.
Since lse.S only has leaf functions the return address is never
saved on the stack so we can add the note.

The note is only added if pac-ret is enabled because it can cause
problems with old linkers and we don't have checks for that. This
can be changed later to be unconditional, for now it is consistent
with how gcc generates the notes.

libgcc/ChangeLog:

* config/aarch64/lse.S: Add PAC property note.
---
 libgcc/config/aarch64/lse.S | 17 +++--
 1 file changed, 15 insertions(+), 2 deletions(-)

diff --git a/libgcc/config/aarch64/lse.S b/libgcc/config/aarch64/lse.S
index 64691c601c1..aa3e3dc4f2d 100644
--- a/libgcc/config/aarch64/lse.S
+++ b/libgcc/config/aarch64/lse.S
@@ -283,6 +283,19 @@ ENDFN  NAME(LDNM)
 #define FEATURE_1_BTI 1
 #define FEATURE_1_PAC 2
 
+/* Supported features based on the code generation options.  */
+#if defined(__ARM_FEATURE_BTI_DEFAULT)
+# define BTI_FLAG FEATURE_1_BTI
+#else
+# define BTI_FLAG 0
+#endif
+
+#if __ARM_FEATURE_PAC_DEFAULT & 3
+# define PAC_FLAG FEATURE_1_PAC
+#else
+# define PAC_FLAG 0
+#endif
+
 /* Add a NT_GNU_PROPERTY_TYPE_0 note.  */
 #define GNU_PROPERTY(type, value)  \
   .section .note.gnu.property, "a";\
@@ -300,7 +313,7 @@ ENDFN   NAME(LDNM)
 .section .note.GNU-stack, "", %progbits
 
 /* Add GNU property note if built with branch protection.  */
-# ifdef __ARM_FEATURE_BTI_DEFAULT
-GNU_PROPERTY (FEATURE_1_AND, FEATURE_1_BTI)
+# if (BTI_FLAG|PAC_FLAG) != 0
+GNU_PROPERTY (FEATURE_1_AND, BTI_FLAG|PAC_FLAG)
 # endif
 #endif
-- 
2.17.1



Re: [PATCH 4/4] doc: Clarify __builtin_return_address [PR94891]

2020-07-13 Thread Szabolcs Nagy
The 07/13/2020 12:24, Richard Sandiford wrote:
> Szabolcs Nagy  writes:
> > The expected semantics and valid usage of __builtin_return_address is
> > not clear since it exposes implementation internals that are normally
> > not meaningful to portable c code.
> >
> > This documentation change tries to clarify the semantics in case the
> > return address is stored in a mangled form. This affects AArch64 when
> > pointer authentication is used for the return address signing (i.e.
> > -mbranch-protection=pac-ret).
> >
> > gcc/ChangeLog:
> >
> > 2020-06-04  Szabolcs Nagy  
> >
> > * doc/extend.texi: Update the text for  __builtin_return_address.
> 
> LGTM apart from minor nits:
...
> OK for trunk and branches with those changes.

thanks, committed with those changes
and backported to gcc-10 now.

(i will backport to gcc-9 and gcc-8
a bit later.)


[PATCH 6/6] aarch64: Fix BTI support in libitm

2020-07-08 Thread Szabolcs Nagy
sjlj.S did not have the GNU property note markup and the BTI c
instructions that are necessary when it is built with branch
protection.

The notes are only added when libitm is built with branch
protection, because old linkers mishandle the note (merge
them incorrectly or emit warnings), the BTI instructions
are added unconditionally.

libitm/ChangeLog:

2020-07-08  Szabolcs Nagy  

* config/aarch64/sjlj.S: Add BTI marking and related definitions,
and add BTI c to function entries.

---
Note: there is some redundancy: the libgcc fixup patch needed
the same macro definitions, but i did not find a convenient
place from where both libgcc and libitm can include them. Since
this is a common problem i expect a change in the assembler
that will be able to add the note without doing this manually,
until then i think we can live with the code duplication.
---
 libitm/config/aarch64/sjlj.S | 27 +++
 1 file changed, 27 insertions(+)

diff --git a/libitm/config/aarch64/sjlj.S b/libitm/config/aarch64/sjlj.S
index 5b97b973e27..e2093ca1a97 100644
--- a/libitm/config/aarch64/sjlj.S
+++ b/libitm/config/aarch64/sjlj.S
@@ -24,6 +24,8 @@
 
 #include "asmcfi.h"
 
+#define BTI_C  hint34
+
.text
.align  2
.global _ITM_beginTransaction
@@ -31,6 +33,7 @@
 
 _ITM_beginTransaction:
cfi_startproc
+   BTI_C
mov x1, sp
stp x29, x30, [sp, -11*16]!
cfi_adjust_cfa_offset(11*16)
@@ -70,6 +73,7 @@ GTM_longjmp:
/* The first parameter becomes the return value (x0).
   The third parameter is ignored for now.  */
cfi_startproc
+   BTI_C
ldp x19, x20, [x1, 1*16]
ldp x21, x22, [x1, 2*16]
ldp x23, x24, [x1, 3*16]
@@ -87,6 +91,29 @@ GTM_longjmp:
cfi_endproc
.size   GTM_longjmp, . - GTM_longjmp
 
+/* GNU_PROPERTY_AARCH64_* macros from elf.h for use in asm code.  */
+#define FEATURE_1_AND 0xc000
+#define FEATURE_1_BTI 1
+#define FEATURE_1_PAC 2
+
+/* Add a NT_GNU_PROPERTY_TYPE_0 note.  */
+#define GNU_PROPERTY(type, value)  \
+  .section .note.gnu.property, "a";\
+  .p2align 3;  \
+  .word 4; \
+  .word 16;\
+  .word 5; \
+  .asciz "GNU";\
+  .word type;  \
+  .word 4; \
+  .word value; \
+  .word 0;
+
 #if defined(__linux__) || defined(__FreeBSD__)
 .section .note.GNU-stack, "", %progbits
+
+/* Add GNU property note if built with branch protection.  */
+# ifdef __ARM_FEATURE_BTI_DEFAULT
+GNU_PROPERTY (FEATURE_1_AND, FEATURE_1_BTI)
+# endif
 #endif
-- 
2.17.1



[PATCH 4/6] aarch64: Fix noexecstack note in libgcc

2020-07-08 Thread Szabolcs Nagy
lse.S did not have GNU stack note, this may cause missing
PT_GNU_STACK in binaries on Linux and FreeBSD.

libgcc/ChangeLog:

2020-07-08  Szabolcs Nagy  

* config/aarch64/lse.S: Add stack note.
---
 libgcc/config/aarch64/lse.S | 4 
 1 file changed, 4 insertions(+)

diff --git a/libgcc/config/aarch64/lse.S b/libgcc/config/aarch64/lse.S
index f3ccf5cf543..9e2acae806b 100644
--- a/libgcc/config/aarch64/lse.S
+++ b/libgcc/config/aarch64/lse.S
@@ -274,3 +274,7 @@ STARTFN NAME(LDNM)
 
 ENDFN  NAME(LDNM)
 #endif
+
+#if defined(__linux__) || defined(__FreeBSD__)
+.section .note.GNU-stack, "", %progbits
+#endif
-- 
2.17.1



[PATCH 3/6] aarch64: Fix noexecstack note in libitm

2020-07-08 Thread Szabolcs Nagy
sjlj.S only had the note on Linux, but it is supposed
to have it on FreeBSD too.

libitm/ChangeLog:

2020-07-08  Szabolcs Nagy  

* config/aarch64/sjlj.S: Add stack note if __FreeBSD__ is defined.

---
Note: this is a minor change to make the asm consistent with
gcc code generation (which emits the note on freebsd too).
the linker defaults to noexecstack on aarch64 so this should
not matter much in practice.
---
 libitm/config/aarch64/sjlj.S | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libitm/config/aarch64/sjlj.S b/libitm/config/aarch64/sjlj.S
index 27626c1f378..5b97b973e27 100644
--- a/libitm/config/aarch64/sjlj.S
+++ b/libitm/config/aarch64/sjlj.S
@@ -87,6 +87,6 @@ GTM_longjmp:
cfi_endproc
.size   GTM_longjmp, . - GTM_longjmp
 
-#ifdef __linux__
+#if defined(__linux__) || defined(__FreeBSD__)
 .section .note.GNU-stack, "", %progbits
 #endif
-- 
2.17.1



[PATCH 5/6] aarch64: Fix BTI support in libgcc

2020-07-08 Thread Szabolcs Nagy
lse.S did not have the GNU property note markup and the BTI c
instructions that are necessary when it is built with branch
protection.

The notes are only added when libgcc is built with branch
protection, because old linkers mishandle the note (merge
them incorrectly or emit warnings), the BTI instructions
are added unconditionally.

Note: BTI c is only necessary at function entry if the function
may be called indirectly, currently lse functions are not called
indirectly, but BTI is added for ABI reasons e.g. to allow
linkers later to emit stub code with indirect jump.

libgcc/ChangeLog:

2020-07-08  Szabolcs Nagy  

* config/aarch64/lse.S: Add BTI marking and related definitions,
and add BTI c to function entries.
---
 libgcc/config/aarch64/lse.S | 26 ++
 1 file changed, 26 insertions(+)

diff --git a/libgcc/config/aarch64/lse.S b/libgcc/config/aarch64/lse.S
index 9e2acae806b..64691c601c1 100644
--- a/libgcc/config/aarch64/lse.S
+++ b/libgcc/config/aarch64/lse.S
@@ -136,6 +136,8 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  
If not, see
 #define tmp1   17
 #define tmp2   15
 
+#define BTI_C  hint34
+
 /* Start and end a function.  */
 .macro STARTFN name
.text
@@ -145,6 +147,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  
If not, see
.type   \name, %function
.cfi_startproc
 \name:
+   BTI_C
 .endm
 
 .macro ENDFN name
@@ -275,6 +278,29 @@ STARTFNNAME(LDNM)
 ENDFN  NAME(LDNM)
 #endif
 
+/* GNU_PROPERTY_AARCH64_* macros from elf.h for use in asm code.  */
+#define FEATURE_1_AND 0xc000
+#define FEATURE_1_BTI 1
+#define FEATURE_1_PAC 2
+
+/* Add a NT_GNU_PROPERTY_TYPE_0 note.  */
+#define GNU_PROPERTY(type, value)  \
+  .section .note.gnu.property, "a";\
+  .p2align 3;  \
+  .word 4; \
+  .word 16;\
+  .word 5; \
+  .asciz "GNU";\
+  .word type;  \
+  .word 4; \
+  .word value; \
+  .word 0;
+
 #if defined(__linux__) || defined(__FreeBSD__)
 .section .note.GNU-stack, "", %progbits
+
+/* Add GNU property note if built with branch protection.  */
+# ifdef __ARM_FEATURE_BTI_DEFAULT
+GNU_PROPERTY (FEATURE_1_AND, FEATURE_1_BTI)
+# endif
 #endif
-- 
2.17.1



[PATCH 1/6] aarch64: Add missing ACLE support for BTI

2020-07-08 Thread Szabolcs Nagy
Define the __ARM_FEATURE_BTI_DEFAULT feature test
macro when BTI branch protection is enabled.

gcc/ChangeLog:

2020-07-08  Szabolcs Nagy  

* config/aarch64/aarch64-c.c (aarch64_update_cpp_builtins): Add
__ARM_FEATURE_BTI_DEFAULT support.
---
 gcc/config/aarch64/aarch64-c.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/gcc/config/aarch64/aarch64-c.c b/gcc/config/aarch64/aarch64-c.c
index e1c1cd415dc..1882288af8d 100644
--- a/gcc/config/aarch64/aarch64-c.c
+++ b/gcc/config/aarch64/aarch64-c.c
@@ -178,6 +178,9 @@ aarch64_update_cpp_builtins (cpp_reader *pfile)
   aarch64_def_or_undef (TARGET_RNG, "__ARM_FEATURE_RNG", pfile);
   aarch64_def_or_undef (TARGET_MEMTAG, "__ARM_FEATURE_MEMORY_TAGGING", pfile);
 
+  aarch64_def_or_undef (aarch64_bti_enabled (),
+   "__ARM_FEATURE_BTI_DEFAULT", pfile);
+
   aarch64_def_or_undef (TARGET_I8MM, "__ARM_FEATURE_MATMUL_INT8", pfile);
   aarch64_def_or_undef (TARGET_BF16_SIMD,
"__ARM_FEATURE_BF16_VECTOR_ARITHMETIC", pfile);
-- 
2.17.1



  1   2   3   4   5   >