diff mbox

[7/7,ARM,V8M] Added support for ARMV8-M Security Extension cmse_nonsecure_caller intrinsic

Message ID 57BD7EA4.4010500@arm.com
State New
Headers show

Commit Message

Andre Vieira (lists) Aug. 24, 2016, 11:01 a.m. UTC
On 25/07/16 14:28, Andre Vieira (lists) wrote:
> This patch adds support ARMv8-M's Security Extension's
> cmse_nonsecure_caller intrinsic. This intrinsic is used to check whether
> an entry function was called from a non-secure state.
> See Section 5.4.3 of ARM®v8-M Security Extensions: Requirements on
> Development Tools
> (http://infocenter.arm.com/help/topic/com.arm.doc.ecm0359818/index.html)
> for further details.
> 
> The FIXME in config/arm/arm_cmse.h is for a diagnostic message that is
> suggested in the ARMv8-M Security Extensions document mentioned above,
> to diagnose the use of the cmse_nonsecure_caller intrinsic outside of
> functions with the 'cmse_nonsecure_entry' attribute.  Checking whether
> the intrinsic is called from within such functions can easily be done
> inside 'arm_expand_builtin'. However, making the warning point to the
> right location is more complicated.  The ARMv8-M Security Extensions
> specification does mention that such a diagnostic might become
> mandatory, so I might have to pick this up later, otherwise it is left
> as a potential extra feature.
> 
> 
> *** gcc/ChangeLog ***
> 2016-07-25  Andre Vieira        <andre.simoesdiasvieira@arm.com>
>             Thomas Preud'homme  <thomas.preudhomme@arm.com>
> 
>         * config/arm/arm-builtins.c (arm_builtins): Define
>         ARM_BUILTIN_CMSE_NONSECURE_CALLER.
>         (bdesc_2arg): Add line for cmse_nonsecure_caller.
>         (arm_expand_builtin): Handle cmse_nonsecure_caller.
>         * config/arm/arm_cmse.h (cmse_nonsecure_caller): New.
> 
> *** gcc/testsuite/ChangeLog ***
> 2016-07-25  Andre Vieira        <andre.simoesdiasvieira@arm.com>
>             Thomas Preud'homme  <thomas.preudhomme@arm.com>
> 
>         * gcc.target/arm/cmse/cmse-1.c: Add test for
>         cmse_nonsecure_caller.
> 
Added more documentation as requested.

---

This patch adds support ARMv8-M's Security Extension's
cmse_nonsecure_caller intrinsic. This intrinsic is used to check whether
an entry function was called from a non-secure state.
See Section 5.4.3 of ARM®v8-M Security Extensions: Requirements on
Development Tools
(http://infocenter.arm.com/help/topic/com.arm.doc.ecm0359818/index.html)
for further details.

The FIXME in config/arm/arm_cmse.h is for a diagnostic message that is
suggested in the ARMv8-M Security Extensions document mentioned above,
to diagnose the use of the cmse_nonsecure_caller intrinsic outside of
functions with the 'cmse_nonsecure_entry' attribute.  Checking whether
the intrinsic is called from within such functions can easily be done
inside 'arm_expand_builtin'. However, making the warning point to the
right location is more complicated.  The ARMv8-M Security Extensions
specification does mention that such a diagnostic might become
mandatory, so I might have to pick this up later, otherwise it is left
as a potential extra feature.


*** gcc/ChangeLog ***
2016-07-xx  Andre Vieira        <andre.simoesdiasvieira@arm.com>
            Thomas Preud'homme  <thomas.preudhomme@arm.com>

        * config/arm/arm-builtins.c (arm_builtins): Define
        ARM_BUILTIN_CMSE_NONSECURE_CALLER.
        (bdesc_2arg): Add line for cmse_nonsecure_caller.
        (arm_expand_builtin): Handle cmse_nonsecure_caller.
        * config/arm/arm_cmse.h (cmse_nonsecure_caller): New.
        * doc/extend.texi (ARM ARMv8-M Security Extensions): New intrinsic.

*** gcc/testsuite/ChangeLog ***
2016-07-xx  Andre Vieira        <andre.simoesdiasvieira@arm.com>
            Thomas Preud'homme  <thomas.preudhomme@arm.com>

        * gcc.target/arm/cmse/cmse-1.c: Add test for
        cmse_nonsecure_caller.
diff mbox

Patch

diff --git a/gcc/config/arm/arm-builtins.c b/gcc/config/arm/arm-builtins.c
index 68b2839879f78e8d819444fbc11d2a91f8d6279a..2589ec2d1233f3daff94a1d35ebf63c8a9b93ecf 100644
--- a/gcc/config/arm/arm-builtins.c
+++ b/gcc/config/arm/arm-builtins.c
@@ -515,6 +515,8 @@  enum arm_builtins
   ARM_BUILTIN_GET_FPSCR,
   ARM_BUILTIN_SET_FPSCR,
 
+  ARM_BUILTIN_CMSE_NONSECURE_CALLER,
+
 #undef CRYPTO1
 #undef CRYPTO2
 #undef CRYPTO3
@@ -1789,6 +1791,17 @@  arm_init_builtins (void)
 	= add_builtin_function ("__builtin_arm_stfscr", ftype_set_fpscr,
 				ARM_BUILTIN_SET_FPSCR, BUILT_IN_MD, NULL, NULL_TREE);
     }
+
+  if (arm_arch_cmse)
+    {
+      tree ftype_cmse_nonsecure_caller
+	= build_function_type_list (unsigned_type_node, NULL);
+      arm_builtin_decls[ARM_BUILTIN_CMSE_NONSECURE_CALLER]
+	= add_builtin_function ("__builtin_arm_cmse_nonsecure_caller",
+				ftype_cmse_nonsecure_caller,
+				ARM_BUILTIN_CMSE_NONSECURE_CALLER, BUILT_IN_MD,
+				NULL, NULL_TREE);
+    }
 }
 
 /* Return the ARM builtin for CODE.  */
@@ -2368,6 +2381,12 @@  arm_expand_builtin (tree exp,
       emit_insn (pat);
       return target;
 
+    case ARM_BUILTIN_CMSE_NONSECURE_CALLER:
+      target = gen_reg_rtx (SImode);
+      op0 = arm_return_addr (0, NULL_RTX);
+      emit_insn (gen_addsi3 (target, op0, const1_rtx));
+      return target;
+
     case ARM_BUILTIN_TEXTRMSB:
     case ARM_BUILTIN_TEXTRMUB:
     case ARM_BUILTIN_TEXTRMSH:
diff --git a/gcc/config/arm/arm_cmse.h b/gcc/config/arm/arm_cmse.h
index b4232937c6ae04754a6bbc513b143672a4be5530..d3f529cce90b8a7ecf8132ad40843270e0b229d2 100644
--- a/gcc/config/arm/arm_cmse.h
+++ b/gcc/config/arm/arm_cmse.h
@@ -163,6 +163,13 @@  __attribute__ ((__always_inline__))
 cmse_TTAT (void *__p)
 __CMSE_TT_ASM (at)
 
+/* FIXME: diagnose use outside cmse_nonsecure_entry functions.  */
+__extension__ static __inline int __attribute__ ((__always_inline__))
+cmse_nonsecure_caller (void)
+{
+  return __builtin_arm_cmse_nonsecure_caller ();
+}
+
 #define CMSE_AU_NONSECURE	2
 #define CMSE_MPU_NONSECURE	16
 #define CMSE_NONSECURE		18
diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index f1e6a20583f9b16d5a670144a162203a12b239bd..1ec69b088f5dc1def9525450c5513354048e90dd 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -12439,6 +12439,7 @@  cmse_address_info_t cmse_TTAT_fptr (FPTR)
 void * cmse_check_address_range (void *, size_t, int)
 typeof(p) cmse_nsfptr_create (FPTR p)
 intptr_t cmse_is_nsfptr (FPTR)
+int cmse_nonsecure_caller (void)
 @end smallexample
 
 @node AVR Built-in Functions
diff --git a/gcc/testsuite/gcc.target/arm/cmse/cmse-1.c b/gcc/testsuite/gcc.target/arm/cmse/cmse-1.c
index d5b9a2d9d59569de170da814ae660e9fb2b943e7..ddcf12a30a6c1806969d239c448da81ccf49532e 100644
--- a/gcc/testsuite/gcc.target/arm/cmse/cmse-1.c
+++ b/gcc/testsuite/gcc.target/arm/cmse/cmse-1.c
@@ -65,3 +65,32 @@  int foo (char * p)
 /* { dg-final { scan-assembler-times "ttat " 2 } } */
 /* { dg-final { scan-assembler-times "bl.cmse_check_address_range" 7 } } */
 /* { dg-final { scan-assembler-not "cmse_check_pointed_object" } } */
+
+typedef int (*int_ret_funcptr_t) (void);
+typedef int __attribute__ ((cmse_nonsecure_call)) (*int_ret_nsfuncptr_t) (void);
+
+int __attribute__ ((cmse_nonsecure_entry))
+baz (void)
+{
+  return cmse_nonsecure_caller ();
+}
+
+int __attribute__ ((cmse_nonsecure_entry))
+qux (int_ret_funcptr_t int_ret_funcptr)
+{
+  int_ret_nsfuncptr_t int_ret_nsfunc_ptr;
+
+  if (cmse_is_nsfptr (int_ret_funcptr))
+    {
+      int_ret_nsfunc_ptr = cmse_nsfptr_create (int_ret_funcptr);
+      return int_ret_nsfunc_ptr ();
+    }
+  return 0;
+}
+/* { dg-final { scan-assembler "baz:" } } */
+/* { dg-final { scan-assembler "__acle_se_baz:" } } */
+/* { dg-final { scan-assembler-not "\tcmse_nonsecure_caller" } } */
+/* { dg-final { scan-rtl-dump "and.*reg.*const_int 1" expand } } */
+/* { dg-final { scan-assembler "bic" } } */
+/* { dg-final { scan-assembler "push\t\{r4, r5, r6" } } */
+/* { dg-final { scan-assembler "msr\tAPSR_nzcvq" } } */