ia64: stack protector
authorChanho Park <chanho61.park@samsung.com>
Fri, 18 Jul 2014 08:59:52 +0000 (17:59 +0900)
committerChanho Park <chanho61.park@samsung.com>
Mon, 21 Jul 2014 08:31:24 +0000 (17:31 +0900)
Signed-off-by: Chanho Park <chanho61.park@samsung.com>
gcc/config/ia64/ia64.c
gcc/config/ia64/ia64.h
gcc/config/ia64/ia64.md
gcc/config/ia64/linux.h

index 41adc4a..ea11524 100644 (file)
@@ -2903,6 +2903,9 @@ ia64_compute_frame_size (HOST_WIDE_INT size)
   else
     pretend_args_size = crtl->args.pretend_args_size;
 
+  if (FRAME_GROWS_DOWNWARD)
+    size = IA64_STACK_ALIGN (size);
+
   total_size = (spill_size + extra_spill_size + size + pretend_args_size
                + crtl->outgoing_args_size);
   total_size = IA64_STACK_ALIGN (total_size);
@@ -2937,9 +2940,9 @@ ia64_can_eliminate (const int from ATTRIBUTE_UNUSED, const int to)
 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:
@@ -2960,6 +2963,7 @@ ia64_initial_elimination_offset (int from, int to)
        default:
          gcc_unreachable ();
        }
+      offset += FRAME_GROWS_DOWNWARD ? IA64_STACK_ALIGN (size) : 0;
       break;
 
     case ARG_POINTER_REGNUM:
index dd14b8a..6166d83 100644 (file)
@@ -871,7 +871,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.  */
index 5fedc92..01774ae 100644 (file)
   [(set_attr "itanium_class" "unknown")
    (set_attr "predicable" "no")])
 
+;;
+;; 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 e4a3ea7..3c3d1e3 100644 (file)
@@ -76,6 +76,11 @@ do {                                         \
 #undef LINK_EH_SPEC
 #define LINK_EH_SPEC ""
 
+#ifdef TARGET_LIBC_PROVIDES_SSP
+/* IA-64 glibc provides __stack_chk_guard in [r13-8].  */
+#define TARGET_THREAD_SSP_OFFSET       -8
+#endif
+
 /* Put all *tf routines in libgcc.  */
 #undef LIBGCC2_HAS_TF_MODE
 #define LIBGCC2_HAS_TF_MODE 1