aboutsummaryrefslogtreecommitdiff
path: root/gcc/cfgexpand.c
diff options
context:
space:
mode:
authorMax Ostapenko <m.ostapenko@partner.samsung.com>2015-03-16 13:17:32 +0200
committerMaxim Ostapenko <chefmax@gcc.gnu.org>2015-03-16 13:17:32 +0200
commit435be74793042d6f627732cb5a3b32dd24cd382c (patch)
tree5befcb0a95eb0b574dcccdbbeb824653033f6f53 /gcc/cfgexpand.c
parent6c25f7962556e2217d5070720ac879c40063209a (diff)
downloadgcc-435be74793042d6f627732cb5a3b32dd24cd382c.zip
gcc-435be74793042d6f627732cb5a3b32dd24cd382c.tar.gz
gcc-435be74793042d6f627732cb5a3b32dd24cd382c.tar.bz2
re PR sanitizer/64820 (Libsanitizer fails with ((AddrIsAlignedByGranularity(addr + size))) != (0)" (0x0, 0x0) if ssp is enabled.)
2015-03-16 Max Ostapenko <m.ostapenko@partner.samsung.com> PR sanitizer/64820 gcc/ * cfgexpand.c (align_base): New function. (alloc_stack_frame_space): Call it. (expand_stack_vars): Align prev_frame to be sure data->asan_vec elements aligned properly. gcc/testsuite/ * c-c++-common/asan/pr64820.c: New test. From-SVN: r221457
Diffstat (limited to 'gcc/cfgexpand.c')
-rw-r--r--gcc/cfgexpand.c29
1 files changed, 19 insertions, 10 deletions
diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c
index 67be09f..97e7a25 100644
--- a/gcc/cfgexpand.c
+++ b/gcc/cfgexpand.c
@@ -282,6 +282,15 @@ align_local_variable (tree decl)
return align / BITS_PER_UNIT;
}
+/* Align given offset BASE with ALIGN. Truncate up if ALIGN_UP is true,
+ down otherwise. Return truncated BASE value. */
+
+static inline unsigned HOST_WIDE_INT
+align_base (HOST_WIDE_INT base, unsigned HOST_WIDE_INT align, bool align_up)
+{
+ return align_up ? (base + align - 1) & -align : base & -align;
+}
+
/* Allocate SIZE bytes at byte alignment ALIGN from the stack frame.
Return the frame offset. */
@@ -290,20 +299,17 @@ alloc_stack_frame_space (HOST_WIDE_INT size, unsigned HOST_WIDE_INT align)
{
HOST_WIDE_INT offset, new_frame_offset;
- new_frame_offset = frame_offset;
if (FRAME_GROWS_DOWNWARD)
{
- new_frame_offset -= size + frame_phase;
- new_frame_offset &= -align;
- new_frame_offset += frame_phase;
+ new_frame_offset
+ = align_base (frame_offset - frame_phase - size,
+ align, false) + frame_phase;
offset = new_frame_offset;
}
else
{
- new_frame_offset -= frame_phase;
- new_frame_offset += align - 1;
- new_frame_offset &= -align;
- new_frame_offset += frame_phase;
+ new_frame_offset
+ = align_base (frame_offset - frame_phase, align, true) + frame_phase;
offset = new_frame_offset;
new_frame_offset += size;
}
@@ -1038,13 +1044,16 @@ expand_stack_vars (bool (*pred) (size_t), struct stack_vars_data *data)
base = virtual_stack_vars_rtx;
if ((flag_sanitize & SANITIZE_ADDRESS) && ASAN_STACK && pred)
{
- HOST_WIDE_INT prev_offset = frame_offset;
+ HOST_WIDE_INT prev_offset
+ = align_base (frame_offset,
+ MAX (alignb, ASAN_RED_ZONE_SIZE),
+ FRAME_GROWS_DOWNWARD);
tree repr_decl = NULL_TREE;
-
offset
= alloc_stack_frame_space (stack_vars[i].size
+ ASAN_RED_ZONE_SIZE,
MAX (alignb, ASAN_RED_ZONE_SIZE));
+
data->asan_vec.safe_push (prev_offset);
data->asan_vec.safe_push (offset + stack_vars[i].size);
/* Find best representative of the partition.