aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJiong Wang <jiwang@gcc.gnu.org>2014-11-04 17:13:25 +0000
committerJiong Wang <jiwang@gcc.gnu.org>2014-11-04 17:13:25 +0000
commit7e8c2bd54af9629d2554698e6cc6ca084015d78a (patch)
tree96617f592239ea197e9a7d844f09b6daf7f75c1c /gcc
parent2acb70965451b3859a0ef1232fd35501e217fd09 (diff)
downloadgcc-7e8c2bd54af9629d2554698e6cc6ca084015d78a.zip
gcc-7e8c2bd54af9629d2554698e6cc6ca084015d78a.tar.gz
gcc-7e8c2bd54af9629d2554698e6cc6ca084015d78a.tar.bz2
[AArch64] fix unsafe access to deallocated stack
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/config/aarch64/aarch64.c12
2 files changed, 19 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index c6d729f..4f741cd 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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,
diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index 9aeac7c..4a67e89 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -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);