Re: [PATCH] Add security_sensitive attribute to clean function stack and regs.

2016-04-04 Thread Bernd Schmidt

On 03/22/2016 03:15 PM, Marcos Díaz wrote:

the attached patch adds a new attribute 'security_sensitive' for functions.
The idea was discussed in PR middle-end/69976.


The first question would be: I see several submissions from folks 
@tallertechnologies.com. Do you and your employer have copyright 
assignments on file with the FSF?


The patch violates gcc coding guidelines in many ways. I'll point out 
some issues, but in general you are expected to familiarize yourself 
with the requirements first. Please review the entire patch yourself for 
such issues.



+bool ix86_sec_sensitive_attr_p(void)


Break line after return types.

  {
-  return TARGET_RED_ZONE && !TARGET_64BIT_MS_ABI;
+  return TARGET_RED_ZONE && !TARGET_64BIT_MS_ABI
+   && !ix86_sec_sensitive_attr_p();


Wrap multi-line expressions in parentheses to get correct formatting 
from the editor.



+  return (regno == BX_REG)
+|| (regno == BP_REG)
+|| (regno == SP_REG)
+|| (regno == R12_REG)
+|| (regno == R13_REG)
+|| (regno == R14_REG)
+|| (regno == R15_REG);


Same here but also remove unnecessary parentheses (in many places in 
this patch).



+}
+
+/* Returns true iff regno is an integer register.*/
+static inline bool is_integer_reg(unsigned int regno)


Space before open parens.


+  rtx ret = ix86_function_value
+   (TREE_TYPE (DECL_RESULT (cfun->decl)), cfun->decl, true);


Probably better to split this line after one of the commas.


+ // Is parallel


Use C style comments consistently.

+/* Adds to str in pos position the neame of the register regno.*/


Always two spaces after a period, including at the end of a comment.

In general it would be ideal if this functionality was not x86 specific. 
I could imagine that thread_prologue_and_epilogue_insns could do this in 
a machine-independent fashion.



Bernd



Re: [PATCH] Add security_sensitive attribute to clean function stack and regs.

2016-04-04 Thread Marcos Díaz
On Mon, Mar 28, 2016 at 3:05 PM, Marcos Díaz
 wrote:
> (Ping and changelog fix)
>
> On Tue, Mar 22, 2016 at 11:15 AM, Marcos Díaz
>  wrote:
>> Hi,
>>the attached patch adds a new attribute 'security_sensitive' for 
>> functions.
>> The idea was discussed in PR middle-end/69976.
>> This attribute makes gcc to emit clean up code at the function's epilogue.
>> This clean-up code cleans the stack used by this function and that isn't
>> needed anymore. It also cleans used registers. It only works in x86_64.
>> Please, review the discussion here:
>> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69976
>> since we had some doubts with the implementation.
>>
>> We also added some test-cases and ran all tests in x86_64.
>> We think this isn't a bug-fix but a new feature.
>>
>> Changelog
>> 2016-03-21  Marcos Diaz  
>>Andres Tiraboschi  
>>
>> PR tree-optimization/69820
> This line should've been  PR middle-end/69976
>> * config/i386/i386-protos.h: Add ix86_clear_regs_emit and
>> ix86_sec_sensitive_attr_p
>> * config/i386/i386.c: (ix86_sec_sensitive_attr_p): New function
>> (ix86_using_red_zone): now take into account if the function has the new
>> attribute.
>> (is_preserved_reg): New function.
>> (is_integer_reg): New function.
>> (is_used_as_ret): New function.
>> (reg_to_string): New function.
>> (clear_reg_emit): New function.
>> (ix86_clear_regs_emit): New function.
>> (ix86_expand_epilogue): Added code to emit clean up code only when
>> security_sensitive attribute is set.
>> (ix86_handle_security_sensitive_attribute): New function.
>> (ix86_attribute_table): Added new attribute.
>> * config/i386/i386.md: (UNSPECV_CLRSTACK): New unspecv.
>> (UNSPECV_CLRREGS): New unspecv.
>> (return): Conditionally emit cleaning regs code.
>> (simple_return): Likewise
>> (clear_regs): New insn.
>> (clear_stack): New insn.
>> * doc/extend.texi: Added description for new security_sensitive attribute.
>
> Changelog
> 2016-03-21  Marcos Diaz  
>Andres Tiraboschi  
>
> PR middle-end/69976
> * config/i386/i386-protos.h: Add ix86_clear_regs_emit and
> ix86_sec_sensitive_attr_p
> * config/i386/i386.c: (ix86_sec_sensitive_attr_p): New function
> (ix86_using_red_zone): now take into account if the function has the new
> attribute.
> (is_preserved_reg): New function.
> (is_integer_reg): New function.
> (is_used_as_ret): New function.
> (reg_to_string): New function.
> (clear_reg_emit): New function.
> (ix86_clear_regs_emit): New function.
> (ix86_expand_epilogue): Added code to emit clean up code only when
> security_sensitive attribute is set.
> (ix86_handle_security_sensitive_attribute): New function.
> (ix86_attribute_table): Added new attribute.
> * config/i386/i386.md: (UNSPECV_CLRSTACK): New unspecv.
> (UNSPECV_CLRREGS): New unspecv.
> (return): Conditionally emit cleaning regs code.
> (simple_return): Likewise
> (clear_regs): New insn.
> (clear_stack): New insn.
> * doc/extend.texi: Added description for new security_sensitive attribute.

ping^2


Re: [PATCH] Add security_sensitive attribute to clean function stack and regs.

2016-03-28 Thread Marcos Díaz
(Ping and changelog fix)

On Tue, Mar 22, 2016 at 11:15 AM, Marcos Díaz
 wrote:
> Hi,
>the attached patch adds a new attribute 'security_sensitive' for functions.
> The idea was discussed in PR middle-end/69976.
> This attribute makes gcc to emit clean up code at the function's epilogue.
> This clean-up code cleans the stack used by this function and that isn't
> needed anymore. It also cleans used registers. It only works in x86_64.
> Please, review the discussion here:
> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69976
> since we had some doubts with the implementation.
>
> We also added some test-cases and ran all tests in x86_64.
> We think this isn't a bug-fix but a new feature.
>
> Changelog
> 2016-03-21  Marcos Diaz  
>Andres Tiraboschi  
>
> PR tree-optimization/69820
This line should've been  PR middle-end/69976
> * config/i386/i386-protos.h: Add ix86_clear_regs_emit and
> ix86_sec_sensitive_attr_p
> * config/i386/i386.c: (ix86_sec_sensitive_attr_p): New function
> (ix86_using_red_zone): now take into account if the function has the new
> attribute.
> (is_preserved_reg): New function.
> (is_integer_reg): New function.
> (is_used_as_ret): New function.
> (reg_to_string): New function.
> (clear_reg_emit): New function.
> (ix86_clear_regs_emit): New function.
> (ix86_expand_epilogue): Added code to emit clean up code only when
> security_sensitive attribute is set.
> (ix86_handle_security_sensitive_attribute): New function.
> (ix86_attribute_table): Added new attribute.
> * config/i386/i386.md: (UNSPECV_CLRSTACK): New unspecv.
> (UNSPECV_CLRREGS): New unspecv.
> (return): Conditionally emit cleaning regs code.
> (simple_return): Likewise
> (clear_regs): New insn.
> (clear_stack): New insn.
> * doc/extend.texi: Added description for new security_sensitive attribute.

Changelog
2016-03-21  Marcos Diaz  
   Andres Tiraboschi  

PR middle-end/69976
* config/i386/i386-protos.h: Add ix86_clear_regs_emit and
ix86_sec_sensitive_attr_p
* config/i386/i386.c: (ix86_sec_sensitive_attr_p): New function
(ix86_using_red_zone): now take into account if the function has the new
attribute.
(is_preserved_reg): New function.
(is_integer_reg): New function.
(is_used_as_ret): New function.
(reg_to_string): New function.
(clear_reg_emit): New function.
(ix86_clear_regs_emit): New function.
(ix86_expand_epilogue): Added code to emit clean up code only when
security_sensitive attribute is set.
(ix86_handle_security_sensitive_attribute): New function.
(ix86_attribute_table): Added new attribute.
* config/i386/i386.md: (UNSPECV_CLRSTACK): New unspecv.
(UNSPECV_CLRREGS): New unspecv.
(return): Conditionally emit cleaning regs code.
(simple_return): Likewise
(clear_regs): New insn.
(clear_stack): New insn.
* doc/extend.texi: Added description for new security_sensitive attribute.


[PATCH] Add security_sensitive attribute to clean function stack and regs.

2016-03-22 Thread Marcos Díaz
Hi,
   the attached patch adds a new attribute 'security_sensitive' for functions.
The idea was discussed in PR middle-end/69976.
This attribute makes gcc to emit clean up code at the function's epilogue.
This clean-up code cleans the stack used by this function and that isn't
needed anymore. It also cleans used registers. It only works in x86_64.
Please, review the discussion here:
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69976
since we had some doubts with the implementation.

We also added some test-cases and ran all tests in x86_64.
We think this isn't a bug-fix but a new feature.

Changelog
2016-03-21  Marcos Diaz  
   Andres Tiraboschi  

PR tree-optimization/69820
* config/i386/i386-protos.h: Add ix86_clear_regs_emit and
ix86_sec_sensitive_attr_p
* config/i386/i386.c: (ix86_sec_sensitive_attr_p): New function
(ix86_using_red_zone): now take into account if the function has the new
attribute.
(is_preserved_reg): New function.
(is_integer_reg): New function.
(is_used_as_ret): New function.
(reg_to_string): New function.
(clear_reg_emit): New function.
(ix86_clear_regs_emit): New function.
(ix86_expand_epilogue): Added code to emit clean up code only when
security_sensitive attribute is set.
(ix86_handle_security_sensitive_attribute): New function.
(ix86_attribute_table): Added new attribute.
* config/i386/i386.md: (UNSPECV_CLRSTACK): New unspecv.
(UNSPECV_CLRREGS): New unspecv.
(return): Conditionally emit cleaning regs code.
(simple_return): Likewise
(clear_regs): New insn.
(clear_stack): New insn.
* doc/extend.texi: Added description for new security_sensitive attribute.
diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h
index e4652f3..b69aa59 100644
--- a/gcc/config/i386/i386-protos.h
+++ b/gcc/config/i386/i386-protos.h
@@ -32,6 +32,8 @@ extern HOST_WIDE_INT ix86_initial_elimination_offset (int, 
int);
 extern void ix86_expand_prologue (void);
 extern void ix86_maybe_emit_epilogue_vzeroupper (void);
 extern void ix86_expand_epilogue (int);
+extern void ix86_clear_regs_emit (rtx*);
+extern bool ix86_sec_sensitive_attr_p(void);
 extern void ix86_expand_split_stack_prologue (void);
 
 extern void ix86_output_addr_vec_elt (FILE *, int);
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 3d8dbc4..7c58d6d 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -3690,12 +3690,19 @@ make_pass_stv (gcc::context *ctxt)
   return new pass_stv (ctxt);
 }
 
+bool ix86_sec_sensitive_attr_p(void)
+{
+  return lookup_attribute ("security_sensitive", DECL_ATTRIBUTES (cfun->decl));
+}
+
+
 /* Return true if a red-zone is in use.  */
 
 static inline bool
 ix86_using_red_zone (void)
 {
-  return TARGET_RED_ZONE && !TARGET_64BIT_MS_ABI;
+  return TARGET_RED_ZONE && !TARGET_64BIT_MS_ABI
+   && !ix86_sec_sensitive_attr_p();
 }
 
 /* Return a string that documents the current -m options.  The caller is
@@ -13325,6 +13332,144 @@ ix86_emit_restore_sse_regs_using_mov (HOST_WIDE_INT 
cfa_offset,
   }
 }
 
+/* Returns true iff regno is a register that must be preserved in a function.*/
+static inline bool
+is_preserved_reg(const unsigned int regno)
+{
+  return (regno == BX_REG)
+|| (regno == BP_REG)
+|| (regno == SP_REG)
+|| (regno == R12_REG)
+|| (regno == R13_REG)
+|| (regno == R14_REG)
+|| (regno == R15_REG);
+}
+
+/* Returns true iff regno is an integer register.*/
+static inline bool is_integer_reg(unsigned int regno)
+{
+  return (regno <= 7u) ||
+ ((FIRST_REX_INT_REG <= regno) && (regno <= LAST_REX_INT_REG));
+}
+
+/* Returns true iff regno is used to return in the current function.*/
+static inline bool
+is_used_as_ret(const unsigned int reg_number)
+{
+  bool is_ret = ix86_function_value_regno_p(reg_number);
+  if (is_ret)
+{
+  rtx ret = ix86_function_value
+   (TREE_TYPE (DECL_RESULT (cfun->decl)), cfun->decl, true);
+  if ((REG_P(ret))
+ && (is_integer_reg(REGNO(ret)))
+ && (is_integer_reg(reg_number))
+)
+   {
+ if ((GET_MODE(ret) == TImode) || (GET_MODE(ret) == CDImode))
+   is_ret = (reg_number == AX_REG) || (reg_number == DX_REG);
+ else
+   is_ret = (reg_number == AX_REG);
+   }
+  else if ((REG_P(ret)))
+   is_ret = REGNO(ret) == reg_number;
+  else
+   {
+ // Is parallel
+ const unsigned int len = XVECLEN(ret, 0);
+ unsigned int j = 0u;
+ bool found = false;
+ while (!found && j < len)
+   {
+ const rtx explist = XVECEXP(ret, 0, j);
+ const rtx ret_reg = XEXP(explist, 0);
+ found = REGNO(ret_reg) == reg_number;
+ ++j;
+   }
+ is_ret = found;
+   }
+
+}
+  return is_ret;
+}
+
+// Make this big enough to store any instruction
+#define MAX_CLEAR_STRING_SIZE 50
+
+/* Adds to str in pos position the neame of the register regno.*/
+static size_t
+reg_to_string(const unsigned in