This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] S/390: stack_protect_set/test


Hi,

the attached patch defines the stack_protect_set/test expanders for S/390.
This is necessary in order to use the stack smashing protector.

Implementing the patterns is easy for S/390 because we have a mem/mem 
compare as well as a mem/mem move.

The only reason we need the stack_protect_test pattern at all is that combine 
can't merge the insns which would be generated without having such an expander 
in place. The problem is that the accesses to the stack guard value have to be 
declared volatile what prevents combine from doing any optimizations.

The stack_protect_set pattern should not be necesssary. Storing the stack guard
value to stack in my tests always produced a single mvc instruction which is fine. 
But it is probably safer to encapsulate the SET with an unspec to prevent the 
optimizers from replacing it with something using a register.

Bootstrapped on s390 and s390x with flag_stack_protect forced to 1 - no testsuite
regressions.

OK for mainline?

Bye,

-Andreas-


2005-07-04  Andreas Krebbel  <krebbel1@de.ibm.com>

	* config/s390/s390.c (print_operand): New output modifier 'G' added.
	* config/s390/s390.md (UNSPEC_SP_SET, UNSPEC_SP_TEST): New constants.
	("stack_protect_set", "stack_protect_test"): New expanders.
	("stack_protect_setsi", "stack_protect_setdi", "stack_protect_testsi",
	"stack_protect_testdi"): New insn definitions.


Index: gcc-4.1/gcc/config/s390/s390.c
===================================================================
--- gcc-4.1.orig/gcc/config/s390/s390.c	2005-06-30 16:30:30.000000000 +0200
+++ gcc-4.1/gcc/config/s390/s390.c	2005-06-30 16:30:35.000000000 +0200
@@ -3802,6 +3802,7 @@ print_operand_address (FILE *file, rtx a
     'C': print opcode suffix for branch condition.
     'D': print opcode suffix for inverse branch condition.
     'J': print tls_load/tls_gdcall/tls_ldcall suffix
+    'G': print the size of the operand in bytes.
     'O': print only the displacement of a memory reference.
     'R': print only the base register of a memory reference.
     'S': print S-type memory reference (base+displacement).
@@ -3848,6 +3849,10 @@ print_operand (FILE *file, rtx x, int co
 	gcc_unreachable ();
       return;
 
+    case 'G':
+      fprintf (file, "%u", GET_MODE_SIZE (GET_MODE (x)));
+      return;
+
     case 'O':
       {
         struct s390_address ad;
Index: gcc-4.1/gcc/config/s390/s390.md
===================================================================
--- gcc-4.1.orig/gcc/config/s390/s390.md	2005-06-30 16:30:30.000000000 +0200
+++ gcc-4.1/gcc/config/s390/s390.md	2005-07-04 09:47:46.000000000 +0200
@@ -122,7 +122,11 @@
    (UNSPEC_TLS_LOAD		512)
 
    ; String Functions
-   (UNSPEC_SRST		600)
+   (UNSPEC_SRST			600)
+   
+   ; Stack Smashing Protector
+   (UNSPEC_SP_SET 		700)
+   (UNSPEC_SP_TEST		701)
  ])
 
 ;;
@@ -7078,3 +7082,52 @@
   DONE;
 })
 
+;
+; Stack Protector Patterns
+;
+
+(define_expand "stack_protect_set"
+  [(set (match_operand 0 "memory_operand" "")
+	(match_operand 1 "memory_operand" ""))]
+  ""
+{
+  if (TARGET_64BIT)
+    emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
+  else
+    emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
+
+  DONE;
+})
+
+(define_insn "stack_protect_set<mode>"
+  [(set (match_operand:DSI 0 "memory_operand" "=Q")
+        (unspec:DSI [(match_operand:DSI 1 "memory_operand" "Q")] UNSPEC_SP_SET))]
+  ""
+  "mvc\t%O0(%G0,%R0),%S1"
+  [(set_attr "op_type" "SS")])
+
+(define_expand "stack_protect_test"
+  [(set (reg:CC CC_REGNUM)
+	(compare (match_operand 0 "memory_operand" "")
+		 (match_operand 1 "memory_operand" "")))]
+  ""
+{
+  s390_compare_op0 = operands[0];
+  s390_compare_op1 = operands[1];
+  s390_compare_emitted = gen_rtx_REG (CCZmode, CC_REGNUM);
+
+  if (TARGET_64BIT)
+    emit_insn (gen_stack_protect_testdi (operands[0], operands[1]));
+  else
+    emit_insn (gen_stack_protect_testsi (operands[0], operands[1]));
+
+  DONE;
+})
+
+(define_insn "stack_protect_test<mode>"
+  [(set (reg:CCZ CC_REGNUM)
+        (unspec:CCZ [(match_operand:DSI 0 "memory_operand" "Q")
+		     (match_operand:DSI 1 "memory_operand" "Q")] UNSPEC_SP_TEST))]
+  ""
+  "clc\t%O0(%G0,%R0),%S1"
+  [(set_attr "op_type" "SS")])


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]