File gcc41-ia64-stack-protector.patch of Package gcc43

2005-07-08  Jakub Jelinek  <jakub@redhat.com>

	* config/ia64/ia64.h (FRAME_GROWS_DOWNWARD): Define to 1 if
	-fstack-protect.
	* config/ia64/ia64.c (ia64_compute_frame_size): Make sure
	size is a multiple of 16 if FRAME_GROWS_DOWNWARD.
	(ia64_initial_elimination_offset): Support FRAME_GROWS_DOWNWARD
	layout.
	* config/ia64/linux.h (TARGET_LIBC_PROVIDES_SSP): Define.
	* config/ia64/ia64.md (stack_protect_set, stack_protect_test): New
	expanders.

Index: gcc/config/ia64/linux.h
===================================================================
--- gcc/config/ia64/linux.h.orig	2008-02-19 10:55:50.000000000 +0100
+++ gcc/config/ia64/linux.h	2009-11-20 13:50:44.000000000 +0100
@@ -59,3 +59,8 @@ do {						\
 #define LINK_EH_SPEC ""
 
 #define MD_UNWIND_SUPPORT "config/ia64/linux-unwind.h"
+
+#ifdef TARGET_LIBC_PROVIDES_SSP
+/* IA-64 glibc provides __stack_chk_guard in [r13-8].  */
+#define TARGET_THREAD_SSP_OFFSET	-8
+#endif
Index: gcc/config/ia64/ia64.c
===================================================================
--- gcc/config/ia64/ia64.c.orig	2009-03-13 16:34:03.000000000 +0100
+++ gcc/config/ia64/ia64.c	2009-11-20 13:50:44.000000000 +0100
@@ -2581,6 +2581,9 @@ ia64_compute_frame_size (HOST_WIDE_INT s
   else
     pretend_args_size = current_function_pretend_args_size;
 
+  if (FRAME_GROWS_DOWNWARD)
+    size = IA64_STACK_ALIGN (size);
+
   total_size = (spill_size + extra_spill_size + size + pretend_args_size
 		+ current_function_outgoing_args_size);
   total_size = IA64_STACK_ALIGN (total_size);
@@ -2605,32 +2608,19 @@ ia64_compute_frame_size (HOST_WIDE_INT s
 HOST_WIDE_INT
 ia64_initial_elimination_offset (int from, int to)
 {
-  HOST_WIDE_INT offset;
+  HOST_WIDE_INT offset, size = get_frame_size ();
 
-  ia64_compute_frame_size (get_frame_size ());
+  ia64_compute_frame_size (size);
   switch (from)
     {
     case FRAME_POINTER_REGNUM:
-      switch (to)
-	{
-	case HARD_FRAME_POINTER_REGNUM:
-	  if (current_function_is_leaf)
-	    offset = -current_frame_info.total_size;
-	  else
-	    offset = -(current_frame_info.total_size
-		       - current_function_outgoing_args_size - 16);
-	  break;
-
-	case STACK_POINTER_REGNUM:
-	  if (current_function_is_leaf)
-	    offset = 0;
-	  else
-	    offset = 16 + current_function_outgoing_args_size;
-	  break;
-
-	default:
-	  gcc_unreachable ();
-	}
+      offset = FRAME_GROWS_DOWNWARD ? IA64_STACK_ALIGN (size) : 0;
+      if (!current_function_is_leaf)
+	offset += 16 + current_function_outgoing_args_size;
+      if (to == HARD_FRAME_POINTER_REGNUM)
+	offset -= current_frame_info.total_size;
+      else
+	gcc_assert (to == STACK_POINTER_REGNUM);
       break;
 
     case ARG_POINTER_REGNUM:
Index: gcc/config/ia64/ia64.md
===================================================================
--- gcc/config/ia64/ia64.md.orig	2008-04-20 23:49:39.000000000 +0200
+++ gcc/config/ia64/ia64.md	2009-11-20 13:50:44.000000000 +0100
@@ -6417,6 +6417,43 @@
  "mov %0 = ip"
   [(set_attr "itanium_class" "frbr")])
 
+;;
+;; Stack guard expanders
+
+(define_expand "stack_protect_set"
+  [(set (match_operand 0 "memory_operand" "")
+        (match_operand 1 "memory_operand" ""))]
+  ""
+{
+#ifdef TARGET_THREAD_SSP_OFFSET
+  rtx thread_pointer_rtx = gen_rtx_REG (Pmode, 13);
+  rtx canary = gen_rtx_MEM (Pmode, gen_rtx_PLUS (Pmode, thread_pointer_rtx,
+					GEN_INT (TARGET_THREAD_SSP_OFFSET)));
+  MEM_VOLATILE_P (canary) = MEM_VOLATILE_P (operands[1]);
+  operands[1] = canary;
+#endif
+  emit_move_insn (operands[0], operands[1]);
+  DONE;
+})
+
+(define_expand "stack_protect_test"
+  [(match_operand 0 "memory_operand" "")
+   (match_operand 1 "memory_operand" "")
+   (match_operand 2 "" "")]
+  ""
+{
+#ifdef TARGET_THREAD_SSP_OFFSET
+  rtx thread_pointer_rtx = gen_rtx_REG (Pmode, 13);
+  rtx canary = gen_rtx_MEM (Pmode, gen_rtx_PLUS (Pmode, thread_pointer_rtx,
+					GEN_INT (TARGET_THREAD_SSP_OFFSET)));
+  MEM_VOLATILE_P (canary) = MEM_VOLATILE_P (operands[1]);
+  operands[1] = canary;
+#endif
+  emit_cmp_and_jump_insns (operands[0], operands[1], EQ, NULL_RTX,
+			   ptr_mode, 1, operands[2]);
+  DONE;
+})
+
 ;; Vector operations
 (include "vect.md")
 ;; Atomic operations
Index: gcc/config/ia64/ia64.h
===================================================================
--- gcc/config/ia64/ia64.h.orig	2008-02-19 10:55:50.000000000 +0100
+++ gcc/config/ia64/ia64.h	2009-11-20 13:50:44.000000000 +0100
@@ -906,7 +906,7 @@ enum reg_class
 
 /* Define this macro to nonzero if the addresses of local variable slots
    are at negative offsets from the frame pointer.  */
-#define FRAME_GROWS_DOWNWARD 0
+#define FRAME_GROWS_DOWNWARD (flag_stack_protect != 0)
 
 /* Offset from the frame pointer to the first local variable slot to
    be allocated.  */