public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc(refs/vendors/ARM/heads/gcs-13)] aarch64: Introduce indirect_return attribute
@ 2024-02-14 15:38 Szabolcs Nagy
  0 siblings, 0 replies; only message in thread
From: Szabolcs Nagy @ 2024-02-14 15:38 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:de73a4360882cb1e8325477c807880031f96e00b

commit de73a4360882cb1e8325477c807880031f96e00b
Author: Szabolcs Nagy <szabolcs.nagy@arm.com>
Date:   Thu Dec 28 13:37:38 2023 +0000

    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      | 12 ++++++++++++
 gcc/config/arm/aarch-bti-insert.cc | 36 ++++++++++++++++++++++++++++++++----
 2 files changed, 44 insertions(+), 4 deletions(-)

diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc
index 2499e79338fb..52446db23f41 100644
--- a/gcc/config/aarch64/aarch64.cc
+++ b/gcc/config/aarch64/aarch64.cc
@@ -2795,6 +2795,7 @@ static const struct attribute_spec aarch64_attribute_table[] =
        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 },
@@ -7160,6 +7161,15 @@ aarch64_function_ok_for_sibcall (tree, tree exp)
   if (crtl->abi->id () != expr_callee_abi (exp).id ())
     return false;
 
+  tree fntype = TREE_TYPE (TREE_TYPE (CALL_EXPR_FN (exp)));
+
+  /* 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;
 }
 
@@ -27188,6 +27198,8 @@ aarch64_comp_type_attributes (const_tree type1, const_tree type2)
 
   if (!check_attr ("aarch64_vector_pcs"))
     return 0;
+  if (!check_attr ("indirect_return"))
+    return 0;
   if (!check_attr ("Advanced SIMD type"))
     return 0;
   if (!check_attr ("SVE type"))
diff --git a/gcc/config/arm/aarch-bti-insert.cc b/gcc/config/arm/aarch-bti-insert.cc
index 71a77e29406e..8ebefd48a4a8 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);

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2024-02-14 15:38 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-02-14 15:38 [gcc(refs/vendors/ARM/heads/gcs-13)] aarch64: Introduce indirect_return attribute Szabolcs Nagy

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).