public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc(refs/vendors/ARM/heads/morello)] morello: Narrowing of outgoing varargs
@ 2022-11-01 11:01 Alex Coplan
  0 siblings, 0 replies; only message in thread
From: Alex Coplan @ 2022-11-01 11:01 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:683594a08c44941233b474c991cf5dec17788a66

commit 683594a08c44941233b474c991cf5dec17788a66
Author: Alex Coplan <alex.coplan@arm.com>
Date:   Fri Oct 21 11:39:06 2022 +0100

    morello: Narrowing of outgoing varargs
    
    This patch adds bounds narrowing and permission clearing on the outgoing
    varargs pointer (c9) for pure-capability Morello. The bounds narrowing
    is needed for conformance with AAPCS64-cap (and is of course desirable
    from a security perspective). The permission clearing follows what is
    done in Morello LLVM.
    
    Note we don't handle padding and alignment to ensure tight bounds in the
    case of > 4096 varargs, but this is not required for ABI conformance. It
    could be added in the future as an additional enhancement, if desired.
    
    To assist in implementing the permission clearing, we refactor the code
    that defines the __{ARM,CHERI}_CAP_PERMISSION_* macros. Even the CHERI
    permission macros should be defined by the backend, since the values are
    target specific (they differ between CHERI architectures). Defining them
    in the backend also allows us to use a shared enum across the backend
    which can then be used for codegen. We make use of that in this patch in
    order to clear the write and execute permissions on c9 for outgoing
    varargs.
    
    While refactoring the CHERI permsision macros, we stop defining
    __CHERI_CAP_PERMISSION_PERMIT_CCALL__, which the ACLE explicitly says
    should not be defined on Morello.

Diff:
---
 gcc/c-family/c-cppbuiltin.c    | 14 --------------
 gcc/config/aarch64/aarch64-c.c | 35 +++++++++++++++++++++++++++++++----
 gcc/config/aarch64/aarch64.c   | 23 ++++++++++++++++++-----
 gcc/config/aarch64/aarch64.h   | 18 ++++++++++++++++++
 4 files changed, 67 insertions(+), 23 deletions(-)

diff --git a/gcc/c-family/c-cppbuiltin.c b/gcc/c-family/c-cppbuiltin.c
index a6c912dc352..5a0bb473b43 100644
--- a/gcc/c-family/c-cppbuiltin.c
+++ b/gcc/c-family/c-cppbuiltin.c
@@ -1460,21 +1460,7 @@ c_cpp_builtins (cpp_reader *pfile)
   if (targetm.capability_mode ().exists ()
       && targetm.capabilities_in_hardware ())
     {
-      /* N.b. I've not found these values defined in a document anywhere.
-	 The values were found by looking at the assembly after using them in
-	 the CUCL CHERI compiler explorer.  */
       cpp_define (pfile, "__CHERI__");
-      builtin_define_with_int_value ("__CHERI_CAP_PERMISSION_GLOBAL__", 1);
-      builtin_define_with_int_value ("__CHERI_CAP_PERMISSION_PERMIT_CCALL__", 256);
-      builtin_define_with_int_value ("__CHERI_CAP_PERMISSION_ACCESS_SYSTEM_REGISTERS__", 512);
-      builtin_define_with_int_value ("__CHERI_CAP_PERMISSION_PERMIT_UNSEAL__", 1024);
-      builtin_define_with_int_value ("__CHERI_CAP_PERMISSION_PERMIT_SEAL__", 2048);
-      builtin_define_with_int_value ("__CHERI_CAP_PERMISSION_PERMIT_STORE_LOCAL__", 4096);
-      builtin_define_with_int_value ("__CHERI_CAP_PERMISSION_PERMIT_STORE_CAPABILITY__", 8192);
-      builtin_define_with_int_value ("__CHERI_CAP_PERMISSION_PERMIT_LOAD_CAPABILITY__", 16384);
-      builtin_define_with_int_value ("__CHERI_CAP_PERMISSION_PERMIT_EXECUTE__", 32768);
-      builtin_define_with_int_value ("__CHERI_CAP_PERMISSION_PERMIT_STORE__", 65536);
-      builtin_define_with_int_value ("__CHERI_CAP_PERMISSION_PERMIT_LOAD__", 131072);
 
       if (targetm.capability_mode ().require () == Pmode)
 	cpp_define (pfile, "__CHERI_PURE_CAPABILITY__");
diff --git a/gcc/config/aarch64/aarch64-c.c b/gcc/config/aarch64/aarch64-c.c
index 4798d80407e..eb07ec78c84 100644
--- a/gcc/config/aarch64/aarch64-c.c
+++ b/gcc/config/aarch64/aarch64-c.c
@@ -144,11 +144,38 @@ aarch64_update_cpp_builtins (cpp_reader *pfile)
 
   if (TARGET_MORELLO)
     {
+#define CAP_PERM(prefix, acle_name, arch_name)\
+      builtin_define_with_int_value ("__" prefix "_CAP_PERMISSION_" \
+				     acle_name "__", \
+				     AARCH64_CAP_PERM_##arch_name)
+
       /* These defines are Morello-specific, as per the Morello ACLE.  */
-      builtin_define_with_int_value ("__ARM_CAP_PERMISSION_EXECUTIVE__", 2);
-      builtin_define_with_int_value ("__ARM_CAP_PERMISSION_MUTABLE_LOAD__", 64);
-      builtin_define_with_int_value ("__ARM_CAP_PERMISSION_COMPARTMENT_ID__", 128);
-      builtin_define_with_int_value ("__ARM_CAP_PERMISSION_BRANCH_SEALED_PAIR__", 256);
+#define ARM_PERM(x) CAP_PERM ("ARM", #x, x)
+      ARM_PERM (EXECUTIVE);
+      ARM_PERM (MUTABLE_LOAD);
+      ARM_PERM (COMPARTMENT_ID);
+      ARM_PERM (BRANCH_SEALED_PAIR);
+#undef ARM_PERM
+
+      /* These defines are common to all CHERI architectures, but have
+	 Morello-specific values, hence defining them in the backend.  */
+#define CHERI_PERM(acle, arch) CAP_PERM ("CHERI", acle, arch)
+#define CHERI_PERMIT_1(acle, arch) CHERI_PERM ("PERMIT_" acle, arch)
+#define CHERI_PERMIT(x) CHERI_PERMIT_1 (#x, x)
+      CHERI_PERM ("GLOBAL", GLOBAL);
+      CHERI_PERM ("ACCESS_SYSTEM_REGISTERS", SYSTEM);
+      CHERI_PERMIT (UNSEAL);
+      CHERI_PERMIT (SEAL);
+      CHERI_PERMIT (STORE_LOCAL);
+      CHERI_PERMIT_1 ("STORE_CAPABILITY", STORE_CAP);
+      CHERI_PERMIT_1 ("LOAD_CAPABILITY", LOAD_CAP);
+      CHERI_PERMIT (EXECUTE);
+      CHERI_PERMIT (STORE);
+      CHERI_PERMIT (LOAD);
+#undef CHERI_PERMIT
+#undef CHERI_PERMIT_1
+#undef CHERI_PERM
+#undef CAP_PERM
     }
 
   aarch64_def_or_undef (TARGET_CRYPTO, "__ARM_FEATURE_CRYPTO", pfile);
diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index 5179f310552..d4be34d1d35 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -17962,16 +17962,29 @@ aarch64_setup_incoming_varargs (cumulative_args_t cum_v,
 }
 
 static void
-aarch64_handle_outgoing_varargs (rtx aama_addr,
-				 int n_anon_args ATTRIBUTE_UNUSED,
-				 rtx *fusage)
+aarch64_handle_outgoing_varargs (rtx aama_addr, int n_anon_args, rtx *fusage)
 {
   if (!TARGET_CAPABILITY_PURE)
     return;
 
-  /* Morello TODO: emit scbnds with size of (n_anon_args * 16).  */
   rtx c9 = gen_rtx_REG (CADImode, R9_REGNUM);
-  emit_move_insn (c9, aama_addr);
+
+  if (CONST_NULL_P (aama_addr))
+    emit_move_insn (c9, aama_addr);
+  else
+    {
+      const auto aama_size = (unsigned HOST_WIDE_INT)n_anon_args * 16;
+
+      rtx bounded = expand_binop (CADImode, cap_bounds_set_optab,
+				  aama_addr, gen_int_mode (aama_size, DImode),
+				  NULL_RTX, 1, OPTAB_DIRECT);
+
+      rtx perms_to_clear
+	= gen_int_mode (AARCH64_CAP_PERM_EXECUTE | AARCH64_CAP_PERM_STORE,
+			DImode);
+      emit_insn (gen_aarch64_cap_clear_perm (c9, bounded, perms_to_clear));
+    }
+
   use_reg (fusage, c9);
 }
 
diff --git a/gcc/config/aarch64/aarch64.h b/gcc/config/aarch64/aarch64.h
index f9fcb173f60..76a4de5aadf 100644
--- a/gcc/config/aarch64/aarch64.h
+++ b/gcc/config/aarch64/aarch64.h
@@ -986,6 +986,24 @@ enum aarch64_abi_type
 
 #define TARGET_ILP32	(aarch64_abi == AARCH64_ABI_ILP32)
 
+enum aarch64_cap_permissions {
+    AARCH64_CAP_PERM_GLOBAL		= (1LU << 0),
+    AARCH64_CAP_PERM_EXECUTIVE		= (1LU << 1),
+    /* 4 bits of User permissions.  */
+    AARCH64_CAP_PERM_MUTABLE_LOAD	= (1LU << 6),
+    AARCH64_CAP_PERM_COMPARTMENT_ID	= (1LU << 7),
+    AARCH64_CAP_PERM_BRANCH_SEALED_PAIR = (1LU << 8),
+    AARCH64_CAP_PERM_SYSTEM		= (1LU << 9),
+    AARCH64_CAP_PERM_UNSEAL		= (1LU << 10),
+    AARCH64_CAP_PERM_SEAL		= (1LU << 11),
+    AARCH64_CAP_PERM_STORE_LOCAL	= (1LU << 12),
+    AARCH64_CAP_PERM_STORE_CAP		= (1LU << 13),
+    AARCH64_CAP_PERM_LOAD_CAP		= (1LU << 14),
+    AARCH64_CAP_PERM_EXECUTE		= (1LU << 15),
+    AARCH64_CAP_PERM_STORE		= (1LU << 16),
+    AARCH64_CAP_PERM_LOAD		= (1LU << 17),
+};
+
 enum aarch64_capability {
     AARCH64_CAPABILITY_NONE,
     AARCH64_CAPABILITY_FAKE,

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

only message in thread, other threads:[~2022-11-01 11:01 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-11-01 11:01 [gcc(refs/vendors/ARM/heads/morello)] morello: Narrowing of outgoing varargs Alex Coplan

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).