diff --git a/gcc/asan.h b/gcc/asan.h index 028afdd2e7d16245c6cbbe106b7ccb9c5034d542..c5492ce35980d0b26d4707f96482b69dc76a525a 100644 --- a/gcc/asan.h +++ b/gcc/asan.h @@ -31,6 +31,7 @@ extern rtx hwasan_with_tag (rtx, poly_int64); extern void hwasan_tag_init (); extern rtx hwasan_create_untagged_base (rtx); extern void hwasan_emit_prologue (rtx *, rtx *, poly_int64 *, uint8_t *, size_t); +extern rtx_insn *hwasan_emit_uncolour_frame (rtx, rtx, rtx_insn *); extern bool memory_tagging_p (void); extern rtx_insn *asan_emit_stack_protection (rtx, rtx, unsigned int, HOST_WIDE_INT *, tree *, int); diff --git a/gcc/asan.c b/gcc/asan.c index d361b4b562f75cb0c2e081218073eacb3704f8d0..0e74e32ae6ca4e130b3f13abe110364b119def46 100644 --- a/gcc/asan.c +++ b/gcc/asan.c @@ -3836,6 +3836,46 @@ hwasan_emit_prologue (rtx *bases, } } +rtx_insn * +hwasan_emit_uncolour_frame (rtx dynamic, rtx vars, rtx_insn *before) +{ + if (before) + push_to_sequence (before); + else + start_sequence (); + + dynamic = convert_memory_address (ptr_mode, dynamic); + vars = convert_memory_address (ptr_mode, vars); + + rtx top_rtx; + rtx bot_rtx; + if (STACK_GROWS_DOWNWARD) + { + top_rtx = vars; + bot_rtx = dynamic; + } + else + { + top_rtx = dynamic; + bot_rtx = vars; + } + + rtx size_rtx = expand_simple_binop (Pmode, MINUS, top_rtx, bot_rtx, + NULL_RTX, /* unsignedp = */0, OPTAB_DIRECT); + + /* TODO Other options (i.e. inline options) */ + rtx ret = init_one_libfunc ("__hwasan_tag_memory"); + emit_library_call (ret, LCT_NORMAL, VOIDmode, + bot_rtx, ptr_mode, + const0_rtx, QImode, + size_rtx, ptr_mode); + + do_pending_stack_adjust (); + rtx_insn *insns = get_insns (); + end_sequence (); + return insns; +} + rtx hwasan_create_untagged_base (rtx orig_base) { diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c index aacf210facc462675a980ee87bd38d4a7d94ad09..9f0872b32354cbc3186f3f2d2600f711a46926d1 100644 --- a/gcc/cfgexpand.c +++ b/gcc/cfgexpand.c @@ -2412,6 +2412,14 @@ expand_used_vars (void) var_end_seq = asan_emit_allocas_unpoison (virtual_stack_dynamic_rtx, virtual_stack_vars_rtx, var_end_seq); + /* Here we uncolour the entire frame for this function. + We need to uncolour *something* if either we have coloured some local + variables or we have coloured some alloca objects. */ + else if (memory_tagging_p () + && (cfun->calls_alloca || stack_vars_num > 0)) + var_end_seq = hwasan_emit_uncolour_frame (virtual_stack_dynamic_rtx, + virtual_stack_vars_rtx, + var_end_seq); fini_vars_expansion ();