@@ -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);
@@ -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)
{
@@ -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 ();