diff options
author | Jakub Jelinek <jakub@redhat.com> | 2013-11-28 09:18:59 +0100 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2013-11-28 09:18:59 +0100 |
commit | e361382f655dcba3b6538d9157c6d378db57158b (patch) | |
tree | b8e14dee616a6f5428fd7b804709a5da8b7d3073 /gcc/cfgexpand.c | |
parent | 8b5e12023b56dfc83c037053612b08f5ee7eac61 (diff) | |
download | gcc-e361382f655dcba3b6538d9157c6d378db57158b.zip gcc-e361382f655dcba3b6538d9157c6d378db57158b.tar.gz gcc-e361382f655dcba3b6538d9157c6d378db57158b.tar.bz2 |
cfgexpand.c (struct stack_vars_data): Add asan_base and asan_alignb fields.
* cfgexpand.c (struct stack_vars_data): Add asan_base and asan_alignb
fields.
(expand_stack_vars): For -fsanitize=address, use (and set initially)
data->asan_base as base for vars and update asan_alignb.
(expand_used_vars): Initialize data.asan_base and data.asan_alignb.
Pass them to asan_emit_stack_protection.
* asan.c (asan_detect_stack_use_after_return): New variable.
(asan_emit_stack_protection): Add pbase and alignb arguments.
Implement use after return sanitization.
* asan.h (asan_emit_stack_protection): Adjust prototype.
(ASAN_STACK_MAGIC_USE_AFTER_RET, ASAN_STACK_RETIRED_MAGIC): Define.
From-SVN: r205476
Diffstat (limited to 'gcc/cfgexpand.c')
-rw-r--r-- | gcc/cfgexpand.c | 31 |
1 files changed, 26 insertions, 5 deletions
diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c index 207f876..622b7ea 100644 --- a/gcc/cfgexpand.c +++ b/gcc/cfgexpand.c @@ -890,6 +890,12 @@ struct stack_vars_data /* Vector of partition representative decls in between the paddings. */ vec<tree> asan_decl_vec; + + /* Base pseudo register for Address Sanitizer protected automatic vars. */ + rtx asan_base; + + /* Alignment needed for the Address Sanitizer protected automatic vars. */ + unsigned int asan_alignb; }; /* A subroutine of expand_used_vars. Give each partition representative @@ -974,6 +980,7 @@ expand_stack_vars (bool (*pred) (size_t), struct stack_vars_data *data) alignb = stack_vars[i].alignb; if (alignb * BITS_PER_UNIT <= MAX_SUPPORTED_STACK_ALIGNMENT) { + base = virtual_stack_vars_rtx; if ((flag_sanitize & SANITIZE_ADDRESS) && pred) { HOST_WIDE_INT prev_offset = frame_offset; @@ -1002,10 +1009,13 @@ expand_stack_vars (bool (*pred) (size_t), struct stack_vars_data *data) if (repr_decl == NULL_TREE) repr_decl = stack_vars[i].decl; data->asan_decl_vec.safe_push (repr_decl); + data->asan_alignb = MAX (data->asan_alignb, alignb); + if (data->asan_base == NULL) + data->asan_base = gen_reg_rtx (Pmode); + base = data->asan_base; } else offset = alloc_stack_frame_space (stack_vars[i].size, alignb); - base = virtual_stack_vars_rtx; base_align = crtl->max_used_stack_slot_alignment; } else @@ -1792,6 +1802,8 @@ expand_used_vars (void) data.asan_vec = vNULL; data.asan_decl_vec = vNULL; + data.asan_base = NULL_RTX; + data.asan_alignb = 0; /* Reorder decls to be protected by iterating over the variables array multiple times, and allocating out of each phase in turn. */ @@ -1816,16 +1828,25 @@ expand_used_vars (void) if (!data.asan_vec.is_empty ()) { HOST_WIDE_INT prev_offset = frame_offset; - HOST_WIDE_INT offset - = alloc_stack_frame_space (ASAN_RED_ZONE_SIZE, - ASAN_RED_ZONE_SIZE); + HOST_WIDE_INT offset, sz, redzonesz; + redzonesz = ASAN_RED_ZONE_SIZE; + sz = data.asan_vec[0] - prev_offset; + if (data.asan_alignb > ASAN_RED_ZONE_SIZE + && data.asan_alignb <= 4096 + && sz + ASAN_RED_ZONE_SIZE >= data.asan_alignb) + redzonesz = ((sz + ASAN_RED_ZONE_SIZE + data.asan_alignb - 1) + & ~(data.asan_alignb - HOST_WIDE_INT_1)) - sz; + offset + = alloc_stack_frame_space (redzonesz, ASAN_RED_ZONE_SIZE); data.asan_vec.safe_push (prev_offset); data.asan_vec.safe_push (offset); var_end_seq = asan_emit_stack_protection (virtual_stack_vars_rtx, + data.asan_base, + data.asan_alignb, data.asan_vec.address (), - data.asan_decl_vec. address (), + data.asan_decl_vec.address (), data.asan_vec.length ()); } |