[AArch64] fix unsafe access to deallocated stack
authorJiong Wang <jiwang@gcc.gnu.org>
Tue, 4 Nov 2014 17:13:25 +0000 (17:13 +0000)
committerJiong Wang <jiwang@gcc.gnu.org>
Tue, 4 Nov 2014 17:13:25 +0000 (17:13 +0000)
2014-11-04  Jiong Wang  <jiong.wang@arm.com>
2014-11-04  Wilco Dijkstra  <wilco.dijkstra@arm.com>

  gcc/
    PR target/63293
    * config/aarch64/aarch64.c (aarch64_expand_epiloue): Add barriers before
    stack adjustment.

From-SVN: r217091

gcc/ChangeLog
gcc/config/aarch64/aarch64.c

index c6d729f0a9d598731a6bc52cc88a1a6a64fc98dd..4f741cd4a3afa5a0ed5ae75a38b2c34236701487 100644 (file)
@@ -1,3 +1,10 @@
+2014-11-04  Jiong Wang  <jiong.wang@arm.com>
+2014-11-04  Wilco Dijkstra  <wilco.dijkstra@arm.com>
+
+       PR target/63293
+       * config/aarch64/aarch64.c (aarch64_expand_epiloue): Add barriers before
+       stack adjustment.
+
 2014-11-04  Bernd Schmidt  <bernds@codesourcery.com>
 
        * combine.c (combine_simplify_rtx): In STORE_FLAG_VALUE == -1 case,
index 9aeac7c2f052a78a05d9cc2882b45a7809673eac..4a67e890eac3185eedccb81a8751fe40c5c1ceff 100644 (file)
@@ -2399,6 +2399,9 @@ aarch64_expand_epilogue (bool for_sibcall)
   HOST_WIDE_INT fp_offset;
   HOST_WIDE_INT hard_fp_offset;
   rtx_insn *insn;
+  /* We need to add memory barrier to prevent read from deallocated stack.  */
+  bool need_barrier_p = (get_frame_size () != 0
+                        || cfun->machine->frame.saved_varargs_size);
 
   aarch64_layout_frame ();
 
@@ -2433,6 +2436,9 @@ aarch64_expand_epilogue (bool for_sibcall)
   if (frame_pointer_needed
       && (crtl->outgoing_args_size || cfun->calls_alloca))
     {
+      if (cfun->calls_alloca)
+       emit_insn (gen_stack_tie (stack_pointer_rtx, stack_pointer_rtx));
+
       insn = emit_insn (gen_add3_insn (stack_pointer_rtx,
                                       hard_frame_pointer_rtx,
                                       GEN_INT (0)));
@@ -2459,6 +2465,9 @@ aarch64_expand_epilogue (bool for_sibcall)
       aarch64_restore_callee_saves (DFmode, fp_offset, V0_REGNUM, V31_REGNUM,
                                    skip_wb, &cfi_ops);
 
+      if (need_barrier_p)
+       emit_insn (gen_stack_tie (stack_pointer_rtx, stack_pointer_rtx));
+
       if (skip_wb)
        {
          machine_mode mode1 = (reg1 <= R30_REGNUM) ? DImode : DFmode;
@@ -2499,6 +2508,9 @@ aarch64_expand_epilogue (bool for_sibcall)
 
   if (frame_size > 0)
     {
+      if (need_barrier_p)
+       emit_insn (gen_stack_tie (stack_pointer_rtx, stack_pointer_rtx));
+
       if (frame_size >= 0x1000000)
        {
          rtx op0 = gen_rtx_REG (Pmode, IP0_REGNUM);