[PING] Re: [RFC][PATCH, ARM 4/8] ARMv8-M Security Extension's cmse_nonsecure_entry: __acle_se label and bxns return

2016-01-29 Thread Andre Vieira (lists)

On 26/12/15 01:52, Thomas Preud'homme wrote:

[Sending on behalf of Andre Vieira]

Hello,

This patch extends support for the ARMv8-M Security Extensions 
'cmse_nonsecure_entry' attribute in two ways:

1) Generate two labels for the function, the regular function name and one with 
the function's name appended to '__acle_se_', this will trigger the linker to 
create a secure gateway veneer for this entry function.
2) Return from cmse_nonsecure_entry marked functions using bxns.

See Section 5.4 of ARM®v8-M Security Extensions 
(http://infocenter.arm.com/help/topic/com.arm.doc.ecm0359818/index.html).


*** gcc/ChangeLog ***
2015-10-27  Andre Vieira
 Thomas Preud'homme  

 * gcc/config/arm/arm.c (use_return_insn): Change to return with  bxns
   when cmse_nonsecure_entry.
   (output_return_instruction): Likewise.
   (arm_output_function_prologue): Likewise.
   (thumb_pop): Likewise.
   (thumb_exit): Likewise.
   (arm_function_ok_for_sibcall): Disable sibcall for entry functions.
   (arm_asm_declare_function_name): New.
   (thumb1_cmse_nonsecure_entry_return): New.
 * gcc/config/arm/arm-protos.h (arm_asm_declare_function_name): New.
 * gcc/config/arm/elf.h (ASM_DECLARE_FUNCTION_NAME): Redefine to
   use arm_asm_declare_function_name.

*** gcc/testsuite/ChangeLog ***
2015-10-27  Andre Vieira
 Thomas Preud'homme  

 * gcc.target/arm/cmse/cmse-2.c: New.
 * gcc.target/arm/cmse/cmse-4.c: New.


diff --git a/gcc/config/arm/arm-protos.h b/gcc/config/arm/arm-protos.h
index 
85dca057d63544c672188db39b05a33b1be10915..9ee8c333046d9a5bb0487f7b710a5aff42d2
 100644
--- a/gcc/config/arm/arm-protos.h
+++ b/gcc/config/arm/arm-protos.h
@@ -31,6 +31,7 @@ extern int arm_volatile_func (void);
  extern void arm_expand_prologue (void);
  extern void arm_expand_epilogue (bool);
  extern void arm_declare_function_name (FILE *, const char *, tree);
+extern void arm_asm_declare_function_name (FILE *, const char *, tree);
  extern void thumb2_expand_return (bool);
  extern const char *arm_strip_name_encoding (const char *);
  extern void arm_asm_output_labelref (FILE *, const char *);
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index 
5b9e51b10e91eee64e3383c1ed50269c3e6cf24c..e530b772e3cc053c16421a2a2861d815d53ebb01
 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -3795,6 +3795,11 @@ use_return_insn (int iscond, rtx sibling)
return 0;
  }

+  /* ARMv8-M nonsecure entry function need to use bxns to return and thus need
+ several instructions if anything needs to be popped.  */
+  if (saved_int_regs && IS_CMSE_ENTRY (func_type))
+return 0;
+
/* If there are saved registers but the LR isn't saved, then we need
   two instructions for the return.  */
if (saved_int_regs && !(saved_int_regs & (1 << LR_REGNUM)))
@@ -6820,6 +6825,11 @@ arm_function_ok_for_sibcall (tree decl, tree exp)
if (IS_INTERRUPT (func_type))
  return false;

+  /* ARMv8-M non-secure entry functions need to return with bxns which is only
+ generated for entry functions themselves.  */
+  if (IS_CMSE_ENTRY (arm_current_func_type ()))
+return false;
+
if (!VOID_TYPE_P (TREE_TYPE (DECL_RESULT (cfun->decl
  {
/* Check that the return value locations are the same.  For
@@ -19607,6 +19617,7 @@ output_return_instruction (rtx operand, bool 
really_return, bool reverse,
 (e.g. interworking) then we can load the return address
 directly into the PC.  Otherwise we must load it into LR.  */
if (really_return
+ && !IS_CMSE_ENTRY (func_type)
  && (IS_INTERRUPT (func_type) || !TARGET_INTERWORK))
return_reg = reg_names[PC_REGNUM];
else
@@ -19742,8 +19753,12 @@ output_return_instruction (rtx operand, bool 
really_return, bool reverse,
  break;

default:
+ if (IS_CMSE_ENTRY (func_type))
+   {
+ snprintf (instr, sizeof (instr), "bxns%s\t%%|lr", conditional);
+   }
  /* Use bx if it's available.  */
- if (arm_arch5 || arm_arch4t)
+ else if (arm_arch5 || arm_arch4t)
sprintf (instr, "bx%s\t%%|lr", conditional);
  else
sprintf (instr, "mov%s\t%%|pc, %%|lr", conditional);
@@ -19756,6 +19771,42 @@ output_return_instruction (rtx operand, bool 
really_return, bool reverse,
return "";
  }

+/* Output in FILE asm statements needed to declare the NAME of the function
+   defined by its DECL node.  */
+
+void
+arm_asm_declare_function_name (FILE *file, const char *name, tree decl)
+{
+  size_t cmse_name_len;
+  char *cmse_name = 0;
+  char cmse_prefix[] = "__acle_se_";
+
+  if (use_cmse && lookup_attribute ("cmse_nonsecure_entry",
+   

[RFC][PATCH, ARM 4/8] ARMv8-M Security Extension's cmse_nonsecure_entry: __acle_se label and bxns return

2015-12-25 Thread Thomas Preud'homme
[Sending on behalf of Andre Vieira]

Hello,

This patch extends support for the ARMv8-M Security Extensions 
'cmse_nonsecure_entry' attribute in two ways:

1) Generate two labels for the function, the regular function name and one with 
the function's name appended to '__acle_se_', this will trigger the linker to 
create a secure gateway veneer for this entry function.
2) Return from cmse_nonsecure_entry marked functions using bxns.

See Section 5.4 of ARM®v8-M Security Extensions 
(http://infocenter.arm.com/help/topic/com.arm.doc.ecm0359818/index.html).


*** gcc/ChangeLog ***
2015-10-27  Andre Vieira
Thomas Preud'homme  

* gcc/config/arm/arm.c (use_return_insn): Change to return with  bxns
  when cmse_nonsecure_entry.
  (output_return_instruction): Likewise.
  (arm_output_function_prologue): Likewise.
  (thumb_pop): Likewise.
  (thumb_exit): Likewise.
  (arm_function_ok_for_sibcall): Disable sibcall for entry functions.
  (arm_asm_declare_function_name): New.
  (thumb1_cmse_nonsecure_entry_return): New.
* gcc/config/arm/arm-protos.h (arm_asm_declare_function_name): New.
* gcc/config/arm/elf.h (ASM_DECLARE_FUNCTION_NAME): Redefine to
  use arm_asm_declare_function_name.

*** gcc/testsuite/ChangeLog ***
2015-10-27  Andre Vieira
Thomas Preud'homme  

* gcc.target/arm/cmse/cmse-2.c: New.
* gcc.target/arm/cmse/cmse-4.c: New.


diff --git a/gcc/config/arm/arm-protos.h b/gcc/config/arm/arm-protos.h
index 
85dca057d63544c672188db39b05a33b1be10915..9ee8c333046d9a5bb0487f7b710a5aff42d2
 100644
--- a/gcc/config/arm/arm-protos.h
+++ b/gcc/config/arm/arm-protos.h
@@ -31,6 +31,7 @@ extern int arm_volatile_func (void);
 extern void arm_expand_prologue (void);
 extern void arm_expand_epilogue (bool);
 extern void arm_declare_function_name (FILE *, const char *, tree);
+extern void arm_asm_declare_function_name (FILE *, const char *, tree);
 extern void thumb2_expand_return (bool);
 extern const char *arm_strip_name_encoding (const char *);
 extern void arm_asm_output_labelref (FILE *, const char *);
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index 
5b9e51b10e91eee64e3383c1ed50269c3e6cf24c..e530b772e3cc053c16421a2a2861d815d53ebb01
 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -3795,6 +3795,11 @@ use_return_insn (int iscond, rtx sibling)
return 0;
 }
 
+  /* ARMv8-M nonsecure entry function need to use bxns to return and thus need
+ several instructions if anything needs to be popped.  */
+  if (saved_int_regs && IS_CMSE_ENTRY (func_type))
+return 0;
+
   /* If there are saved registers but the LR isn't saved, then we need
  two instructions for the return.  */
   if (saved_int_regs && !(saved_int_regs & (1 << LR_REGNUM)))
@@ -6820,6 +6825,11 @@ arm_function_ok_for_sibcall (tree decl, tree exp)
   if (IS_INTERRUPT (func_type))
 return false;
 
+  /* ARMv8-M non-secure entry functions need to return with bxns which is only
+ generated for entry functions themselves.  */
+  if (IS_CMSE_ENTRY (arm_current_func_type ()))
+return false;
+
   if (!VOID_TYPE_P (TREE_TYPE (DECL_RESULT (cfun->decl
 {
   /* Check that the return value locations are the same.  For
@@ -19607,6 +19617,7 @@ output_return_instruction (rtx operand, bool 
really_return, bool reverse,
 (e.g. interworking) then we can load the return address
 directly into the PC.  Otherwise we must load it into LR.  */
   if (really_return
+ && !IS_CMSE_ENTRY (func_type)
  && (IS_INTERRUPT (func_type) || !TARGET_INTERWORK))
return_reg = reg_names[PC_REGNUM];
   else
@@ -19742,8 +19753,12 @@ output_return_instruction (rtx operand, bool 
really_return, bool reverse,
  break;
 
default:
+ if (IS_CMSE_ENTRY (func_type))
+   {
+ snprintf (instr, sizeof (instr), "bxns%s\t%%|lr", conditional);
+   }
  /* Use bx if it's available.  */
- if (arm_arch5 || arm_arch4t)
+ else if (arm_arch5 || arm_arch4t)
sprintf (instr, "bx%s\t%%|lr", conditional);
  else
sprintf (instr, "mov%s\t%%|pc, %%|lr", conditional);
@@ -19756,6 +19771,42 @@ output_return_instruction (rtx operand, bool 
really_return, bool reverse,
   return "";
 }
 
+/* Output in FILE asm statements needed to declare the NAME of the function
+   defined by its DECL node.  */
+
+void
+arm_asm_declare_function_name (FILE *file, const char *name, tree decl)
+{
+  size_t cmse_name_len;
+  char *cmse_name = 0;
+  char cmse_prefix[] = "__acle_se_";
+
+  if (use_cmse && lookup_attribute ("cmse_nonsecure_entry",
+   DECL_ATTRIBUTES (decl)))
+{
+  cmse_name_len = sizeof (cmse_prefix) + strlen