public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
From: Matthew Malcomson <Matthew.Malcomson@arm.com>
To: "gcc-patches@gcc.gnu.org" <gcc-patches@gcc.gnu.org>
Cc: "mliska@suse.cz" <mliska@suse.cz>,
	"dodji@redhat.com" <dodji@redhat.com>,	nd <nd@arm.com>,
	"kcc@google.com" <kcc@google.com>,
	"jakub@redhat.com"	<jakub@redhat.com>,
	"dvyukov@google.com" <dvyukov@google.com>
Subject: [RFC][PATCH 14/X][libsanitizer] Introduce HWASAN block-scope poisoning
Date: Fri, 06 Sep 2019 14:46:00 -0000	[thread overview]
Message-ID: <VI1PR08MB5471728307526AD56137AE10E0BA0@VI1PR08MB5471.eurprd08.prod.outlook.com> (raw)
In-Reply-To: <156778058239.16148.17480879484406897649.scripted-patch-series@arm.com>

[-- Attachment #1: Type: text/plain, Size: 11650 bytes --]

Here we use exactly the same mechanism as ASAN_MARK to poison/unpoison
variables on entry/exit of a block.

In order to simply use the exact same machinery we're using the same
internal functions until the SANOPT pass.  This means that all handling
of ASAN_MARK is the same.
This has the negative that the naming may be a little confusing, but a
positive that handling of the internal function doesn't have to be
duplicated for a function that behaves exactly the same but has a
different name.

gcc/ChangeLog:

2019-09-06  Matthew Malcomson  <matthew.malcomson@arm.com>

	* asan.c (asan_expand_mark_ifn): New.
	(asan_expand_poison_ifn): Add assertion.
	(hwasan_emit_prologue): Add assertion.
	(hwasan_emit_uncolour_frame): Clear hash map of block-scope
	variables.
	(hwasan_extract_tag): New.
	(hwasan_expand_mark_ifn): New.
	(hardware_memory_tagging_p): New.
	* asan.h (hwasan_extract_tag): New.
	(hwasan_expand_mark_ifn): New.
	(enum hwasan_mark_flags): New.
	(hardware_memory_tagging_p): New.
	* cfgexpand.c (expand_stack_vars): Neaten up an if clause.
	* gimple-pretty-print.c (dump_gimple_call_args): Handle
	HWASAN_MARK.
	* gimplify.c (asan_poison_variable): Set alignment for HWASAN.
	(gimplify_function_tree): Record marked variables for both ASAN
	and HWASAN.
	* internal-fn.c (expand_HWASAN_MARK): New.
	(expand_HWASAN_CHOOSE_COLOUR): Use new hwasan_extract_tag
	helper.
	* internal-fn.def (HWASAN_MARK): New.
	* sanopt.c (pass_sanopt::execute): Account for HWASAN.



###############     Attachment also inlined for ease of reply    ###############


diff --git a/gcc/asan.h b/gcc/asan.h
index e4e823080e4ca7489135ee2da9e0727de9bba8ae..6e5ba8be606e9a1eae2afe57f17ccca5562167fd 100644
--- a/gcc/asan.h
+++ b/gcc/asan.h
@@ -30,12 +30,15 @@ extern void hwasan_increment_tag ();
 extern rtx hwasan_with_tag (rtx, poly_int64);
 extern void hwasan_tag_init ();
 extern rtx hwasan_create_untagged_base (rtx);
+extern rtx hwasan_extract_tag (rtx tagged_pointer);
 extern rtx hwasan_base ();
 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 hwasan_expand_check_ifn (gimple_stmt_iterator *, bool);
+extern bool hwasan_expand_mark_ifn (gimple_stmt_iterator *);
 extern bool memory_tagging_p (void);
 extern bool gate_hwasan (void);
+extern bool hardware_memory_tagging_p (void);
 extern rtx_insn *asan_emit_stack_protection (rtx, rtx, unsigned int,
 					     HOST_WIDE_INT *, tree *, int);
 extern rtx_insn *asan_emit_allocas_unpoison (rtx, rtx, rtx_insn *);
@@ -142,6 +145,13 @@ enum asan_mark_flags
 #undef DEF
 };
 
+enum hwasan_mark_flags
+{
+#define DEF(X) HWASAN_MARK_##X
+  IFN_ASAN_MARK_FLAGS
+#undef DEF
+};
+
 /* Return true if STMT is ASAN_MARK with FLAG as first argument.  */
 extern bool asan_mark_p (gimple *stmt, enum asan_mark_flags flag);
 
diff --git a/gcc/asan.c b/gcc/asan.c
index fefd28cbd136d74ad3389cf8efbf1949e3815dfd..ad3d5a6451d3ecd9ff79b768c1e9a3fb92272a7e 100644
--- a/gcc/asan.c
+++ b/gcc/asan.c
@@ -3375,6 +3375,22 @@ asan_expand_mark_ifn (gimple_stmt_iterator *iter)
   unsigned HOST_WIDE_INT size_in_bytes = tree_to_shwi (len);
   gcc_assert (size_in_bytes);
 
+  if (memory_tagging_p ())
+    {
+      /* Here we swap the ASAN_MARK for HWASAN_MARK.
+	 This is because we are using the (possibly temporary) approach to
+	 always emit ASAN_MARK in TREE until here.
+	 That approach means we don't yet have to duplicate all the special
+	 cases for ASAN_MARK and ASAN_POISON with the exact same handling but
+	 called HWASAN_MARK etc.  */
+      gimple *hw_poison_call
+	= gimple_build_call_internal (IFN_HWASAN_MARK, 3,
+				      gimple_call_arg (g, 0),
+				      base, len);
+      gsi_replace (iter, hw_poison_call, false);
+      return false;
+    }
+
   g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
 			   NOP_EXPR, base);
   gimple_set_location (g, loc);
@@ -3673,6 +3689,7 @@ asan_expand_poison_ifn (gimple_stmt_iterator *iter,
 			bool *need_commit_edge_insert,
 			hash_map<tree, tree> &shadow_vars_mapping)
 {
+  gcc_assert (! memory_tagging_p ());
   gimple *g = gsi_stmt (*iter);
   tree poisoned_var = gimple_call_lhs (g);
   if (!poisoned_var || has_zero_uses (poisoned_var))
@@ -3968,6 +3985,7 @@ hwasan_emit_prologue (rtx *bases,
 	}
       else
 	{
+	  gcc_assert (known_ge (end, start));
 	  top = end;
 	  bot = start;
 	}
@@ -4037,6 +4055,12 @@ hwasan_emit_uncolour_frame (rtx dynamic, rtx vars, rtx_insn *before)
   do_pending_stack_adjust ();
   rtx_insn *insns = get_insns ();
   end_sequence ();
+
+  /* Clear the hash_map recording which variables are handled by HWASAN_MARK.
+     The only use in HWASAN is to decide which variables need to be coloured in
+     the prologue and which don't.  */
+  delete asan_handled_variables;
+  asan_handled_variables = NULL;
   return insns;
 }
 
@@ -4052,6 +4076,19 @@ hwasan_create_untagged_base (rtx orig_base)
   return untagged_base;
 }
 
+rtx
+hwasan_extract_tag (rtx tagged_pointer)
+{
+  rtx tag = expand_simple_binop (Pmode,
+				 LSHIFTRT,
+				 tagged_pointer,
+				 HWASAN_SHIFT_RTX,
+				 NULL_RTX,
+				 /* unsignedp = */0,
+				 OPTAB_DIRECT);
+  return gen_lowpart (QImode, tag);
+}
+
 /* Needs to be GTY(()), because cgraph_build_static_cdtor may
    invoke ggc_collect.  */
 static GTY(()) tree hwasan_ctor_statements;
@@ -4166,10 +4203,25 @@ hwasan_expand_check_ifn (gimple_stmt_iterator *iter, bool)
 }
 
 bool
+hwasan_expand_mark_ifn (gimple_stmt_iterator *)
+{
+  /* HWASAN_MARK should only ever be available after the sanopt pass.
+     It might be nicer to have it everywhere in the future, so I"m leaving this
+     function and the declaration in asan.h around in case that's requested
+     upstream.  */
+  gcc_unreachable ();
+}
+
+bool
 gate_hwasan ()
 {
   return memory_tagging_p ();
 }
+bool
+hardware_memory_tagging_p ()
+{
+  return memory_tagging_p () && HARDWARE_MEMORY_TAGGING;
+}
 
 namespace {
 
diff --git a/gcc/gimple-pretty-print.c b/gcc/gimple-pretty-print.c
index 10f79ea619e3ebfdcbe9f5159e174cf2bb08b7d8..52d104857df92bc80db6deb5b18c99ee2caa4151 100644
--- a/gcc/gimple-pretty-print.c
+++ b/gcc/gimple-pretty-print.c
@@ -739,6 +739,7 @@ dump_gimple_call_args (pretty_printer *buffer, gcall *gs, dump_flags_t flags)
 	  limit = ARRAY_SIZE (reduction_args);
 	  break;
 
+	case IFN_HWASAN_MARK:
 	case IFN_ASAN_MARK:
 #define DEF(X) #X
 	  static const char *const asan_mark_args[] = {IFN_ASAN_MARK_FLAGS};
diff --git a/gcc/gimplify.c b/gcc/gimplify.c
index 5bacb255ba75901a3cd95e3b99b1f274216bf85d..d89d81ec112d918912269c90faae468d1d8aa321 100644
--- a/gcc/gimplify.c
+++ b/gcc/gimplify.c
@@ -1202,8 +1202,10 @@ asan_poison_variable (tree decl, bool poison, gimple_stmt_iterator *it,
 
   /* It's necessary to have all stack variables aligned to ASAN granularity
      bytes.  */
-  if (DECL_ALIGN_UNIT (decl) <= ASAN_SHADOW_GRANULARITY)
-    SET_DECL_ALIGN (decl, BITS_PER_UNIT * ASAN_SHADOW_GRANULARITY);
+  unsigned shadow_granularity =
+    memory_tagging_p () ? HWASAN_TAG_GRANULE_SIZE : ASAN_SHADOW_GRANULARITY;
+  if (DECL_ALIGN_UNIT (decl) <= shadow_granularity)
+    SET_DECL_ALIGN (decl, BITS_PER_UNIT * shadow_granularity);
 
   HOST_WIDE_INT flags = poison ? ASAN_MARK_POISON : ASAN_MARK_UNPOISON;
 
@@ -13816,7 +13818,7 @@ gimplify_function_tree (tree fndecl)
       && !needs_to_live_in_memory (ret))
     DECL_GIMPLE_REG_P (ret) = 1;
 
-  if (asan_sanitize_use_after_scope () && sanitize_flags_p (SANITIZE_ADDRESS))
+  if (asan_sanitize_use_after_scope ())
     asan_poisoned_variables = new hash_set<tree> ();
   bind = gimplify_body (fndecl, true);
   if (asan_poisoned_variables)
diff --git a/gcc/internal-fn.c b/gcc/internal-fn.c
index 4eec9919b520691ab3e73a2920ef8b544cf55dfe..c530fe8951c30987c874df83e74be6d058730134 100644
--- a/gcc/internal-fn.c
+++ b/gcc/internal-fn.c
@@ -471,11 +471,7 @@ expand_HWASAN_CHOOSE_COLOUR (internal_fn, gcall *gc)
   machine_mode mode = GET_MODE (target);
   gcc_assert (mode == QImode);
 
-  rtx base_tag = expand_simple_binop (Pmode, LSHIFTRT, hwasan_base (),
-				      HWASAN_SHIFT_RTX,
-				      NULL_RTX, /* unsignedp = */0,
-				      OPTAB_DIRECT);
-
+  rtx base_tag = hwasan_extract_tag (hwasan_base ());
   gcc_assert (base_tag);
   rtx tag_offset = const_int_rtx[MAX_SAVED_CONST_INT + hwasan_current_tag ()];
   rtx chosen_tag = expand_simple_binop (QImode, PLUS, base_tag, tag_offset,
@@ -498,6 +494,39 @@ expand_HWASAN_CHOOSE_COLOUR (internal_fn, gcall *gc)
 }
 
 static void
+expand_HWASAN_MARK (internal_fn, gcall *gc)
+{
+  HOST_WIDE_INT flag = tree_to_shwi (gimple_call_arg (gc, 0));
+  bool is_poison = ((asan_mark_flags)flag) == ASAN_MARK_POISON;
+
+  tree base = gimple_call_arg (gc, 1);
+  gcc_checking_assert (TREE_CODE (base) == ADDR_EXPR);
+  rtx base_rtx = expand_normal (base);
+
+  rtx tag = is_poison ? const0_rtx : hwasan_extract_tag (base_rtx);
+  rtx address = hwasan_create_untagged_base (base_rtx);
+
+  tree len = gimple_call_arg (gc, 2);
+  gcc_assert (tree_fits_shwi_p (len));
+  unsigned HOST_WIDE_INT size_in_bytes = tree_to_shwi (len);
+  uint8_t tg_mask = HWASAN_TAG_GRANULE_SIZE - 1;
+  gcc_assert (size_in_bytes);
+  size_in_bytes = (size_in_bytes + tg_mask) & ~tg_mask;
+  rtx size = gen_int_mode (size_in_bytes, Pmode);
+
+  /* TODO Other options (i.e. inline options)  */
+  rtx func = init_one_libfunc ("__hwasan_tag_memory");
+  emit_library_call (func,
+      LCT_NORMAL,
+      VOIDmode,
+      address, ptr_mode,
+      tag, QImode,
+      size, ptr_mode);
+}
+
+/* This should get expanded in the sanopt pass.  */
+
+static void
 expand_ASAN_CHECK (internal_fn, gcall *)
 {
   gcc_unreachable ();
diff --git a/gcc/internal-fn.def b/gcc/internal-fn.def
index ed0c5bc110f16b2cdbc139403dbdbd8ebe7e2823..100f6fbad0af4fefdd0408384374b8fdcde9bee4 100644
--- a/gcc/internal-fn.def
+++ b/gcc/internal-fn.def
@@ -290,6 +290,7 @@ DEF_INTERNAL_FN (ABNORMAL_DISPATCHER, ECF_NORETURN, NULL)
 DEF_INTERNAL_FN (BUILTIN_EXPECT, ECF_CONST | ECF_LEAF | ECF_NOTHROW, NULL)
 DEF_INTERNAL_FN (HWASAN_CHOOSE_COLOUR, ECF_LEAF | ECF_NOTHROW, ".")
 DEF_INTERNAL_FN (HWASAN_CHECK, ECF_TM_PURE | ECF_LEAF | ECF_NOTHROW, "..R..")
+DEF_INTERNAL_FN (HWASAN_MARK, ECF_LEAF | ECF_NOTHROW, NULL)
 DEF_INTERNAL_FN (ASAN_CHECK, ECF_TM_PURE | ECF_LEAF | ECF_NOTHROW, "..R..")
 DEF_INTERNAL_FN (ASAN_MARK, ECF_LEAF | ECF_NOTHROW, NULL)
 DEF_INTERNAL_FN (ASAN_POISON, ECF_LEAF | ECF_NOTHROW | ECF_NOVOPS, NULL)
diff --git a/gcc/sanopt.c b/gcc/sanopt.c
index 31270153f3cf56bfbad593830de1b9334e7f65d1..29b12a43029cdcce5756354ac12d6d9e963e9ac8 100644
--- a/gcc/sanopt.c
+++ b/gcc/sanopt.c
@@ -1258,6 +1258,12 @@ sanitize_rewrite_addressable_params (function *fun)
 unsigned int
 pass_sanopt::execute (function *fun)
 {
+  /*
+     n.b. ASAN_MARK is used for both HWASAN and ASAN.
+     asan_num_accesses is used to count either HWASAN_CHECK or ASAN_CHECK
+     stuff.  This is fine because you can only have one of these active at a
+     time.
+ */
   basic_block bb;
   int asan_num_accesses = 0;
   bool contains_asan_mark = false;
@@ -1345,6 +1351,9 @@ pass_sanopt::execute (function *fun)
 						    &need_commit_edge_insert,
 						    shadow_vars_mapping);
 		  break;
+		case IFN_HWASAN_MARK:
+		  no_next = hwasan_expand_mark_ifn (&gsi);
+		  break;
 		default:
 		  break;
 		}


[-- Attachment #2: hwasan-implementation13.patch --]
[-- Type: text/plain, Size: 9772 bytes --]

diff --git a/gcc/asan.h b/gcc/asan.h
index e4e823080e4ca7489135ee2da9e0727de9bba8ae..6e5ba8be606e9a1eae2afe57f17ccca5562167fd 100644
--- a/gcc/asan.h
+++ b/gcc/asan.h
@@ -30,12 +30,15 @@ extern void hwasan_increment_tag ();
 extern rtx hwasan_with_tag (rtx, poly_int64);
 extern void hwasan_tag_init ();
 extern rtx hwasan_create_untagged_base (rtx);
+extern rtx hwasan_extract_tag (rtx tagged_pointer);
 extern rtx hwasan_base ();
 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 hwasan_expand_check_ifn (gimple_stmt_iterator *, bool);
+extern bool hwasan_expand_mark_ifn (gimple_stmt_iterator *);
 extern bool memory_tagging_p (void);
 extern bool gate_hwasan (void);
+extern bool hardware_memory_tagging_p (void);
 extern rtx_insn *asan_emit_stack_protection (rtx, rtx, unsigned int,
 					     HOST_WIDE_INT *, tree *, int);
 extern rtx_insn *asan_emit_allocas_unpoison (rtx, rtx, rtx_insn *);
@@ -142,6 +145,13 @@ enum asan_mark_flags
 #undef DEF
 };
 
+enum hwasan_mark_flags
+{
+#define DEF(X) HWASAN_MARK_##X
+  IFN_ASAN_MARK_FLAGS
+#undef DEF
+};
+
 /* Return true if STMT is ASAN_MARK with FLAG as first argument.  */
 extern bool asan_mark_p (gimple *stmt, enum asan_mark_flags flag);
 
diff --git a/gcc/asan.c b/gcc/asan.c
index fefd28cbd136d74ad3389cf8efbf1949e3815dfd..ad3d5a6451d3ecd9ff79b768c1e9a3fb92272a7e 100644
--- a/gcc/asan.c
+++ b/gcc/asan.c
@@ -3375,6 +3375,22 @@ asan_expand_mark_ifn (gimple_stmt_iterator *iter)
   unsigned HOST_WIDE_INT size_in_bytes = tree_to_shwi (len);
   gcc_assert (size_in_bytes);
 
+  if (memory_tagging_p ())
+    {
+      /* Here we swap the ASAN_MARK for HWASAN_MARK.
+	 This is because we are using the (possibly temporary) approach to
+	 always emit ASAN_MARK in TREE until here.
+	 That approach means we don't yet have to duplicate all the special
+	 cases for ASAN_MARK and ASAN_POISON with the exact same handling but
+	 called HWASAN_MARK etc.  */
+      gimple *hw_poison_call
+	= gimple_build_call_internal (IFN_HWASAN_MARK, 3,
+				      gimple_call_arg (g, 0),
+				      base, len);
+      gsi_replace (iter, hw_poison_call, false);
+      return false;
+    }
+
   g = gimple_build_assign (make_ssa_name (pointer_sized_int_node),
 			   NOP_EXPR, base);
   gimple_set_location (g, loc);
@@ -3673,6 +3689,7 @@ asan_expand_poison_ifn (gimple_stmt_iterator *iter,
 			bool *need_commit_edge_insert,
 			hash_map<tree, tree> &shadow_vars_mapping)
 {
+  gcc_assert (! memory_tagging_p ());
   gimple *g = gsi_stmt (*iter);
   tree poisoned_var = gimple_call_lhs (g);
   if (!poisoned_var || has_zero_uses (poisoned_var))
@@ -3968,6 +3985,7 @@ hwasan_emit_prologue (rtx *bases,
 	}
       else
 	{
+	  gcc_assert (known_ge (end, start));
 	  top = end;
 	  bot = start;
 	}
@@ -4037,6 +4055,12 @@ hwasan_emit_uncolour_frame (rtx dynamic, rtx vars, rtx_insn *before)
   do_pending_stack_adjust ();
   rtx_insn *insns = get_insns ();
   end_sequence ();
+
+  /* Clear the hash_map recording which variables are handled by HWASAN_MARK.
+     The only use in HWASAN is to decide which variables need to be coloured in
+     the prologue and which don't.  */
+  delete asan_handled_variables;
+  asan_handled_variables = NULL;
   return insns;
 }
 
@@ -4052,6 +4076,19 @@ hwasan_create_untagged_base (rtx orig_base)
   return untagged_base;
 }
 
+rtx
+hwasan_extract_tag (rtx tagged_pointer)
+{
+  rtx tag = expand_simple_binop (Pmode,
+				 LSHIFTRT,
+				 tagged_pointer,
+				 HWASAN_SHIFT_RTX,
+				 NULL_RTX,
+				 /* unsignedp = */0,
+				 OPTAB_DIRECT);
+  return gen_lowpart (QImode, tag);
+}
+
 /* Needs to be GTY(()), because cgraph_build_static_cdtor may
    invoke ggc_collect.  */
 static GTY(()) tree hwasan_ctor_statements;
@@ -4166,10 +4203,25 @@ hwasan_expand_check_ifn (gimple_stmt_iterator *iter, bool)
 }
 
 bool
+hwasan_expand_mark_ifn (gimple_stmt_iterator *)
+{
+  /* HWASAN_MARK should only ever be available after the sanopt pass.
+     It might be nicer to have it everywhere in the future, so I"m leaving this
+     function and the declaration in asan.h around in case that's requested
+     upstream.  */
+  gcc_unreachable ();
+}
+
+bool
 gate_hwasan ()
 {
   return memory_tagging_p ();
 }
+bool
+hardware_memory_tagging_p ()
+{
+  return memory_tagging_p () && HARDWARE_MEMORY_TAGGING;
+}
 
 namespace {
 
diff --git a/gcc/gimple-pretty-print.c b/gcc/gimple-pretty-print.c
index 10f79ea619e3ebfdcbe9f5159e174cf2bb08b7d8..52d104857df92bc80db6deb5b18c99ee2caa4151 100644
--- a/gcc/gimple-pretty-print.c
+++ b/gcc/gimple-pretty-print.c
@@ -739,6 +739,7 @@ dump_gimple_call_args (pretty_printer *buffer, gcall *gs, dump_flags_t flags)
 	  limit = ARRAY_SIZE (reduction_args);
 	  break;
 
+	case IFN_HWASAN_MARK:
 	case IFN_ASAN_MARK:
 #define DEF(X) #X
 	  static const char *const asan_mark_args[] = {IFN_ASAN_MARK_FLAGS};
diff --git a/gcc/gimplify.c b/gcc/gimplify.c
index 5bacb255ba75901a3cd95e3b99b1f274216bf85d..d89d81ec112d918912269c90faae468d1d8aa321 100644
--- a/gcc/gimplify.c
+++ b/gcc/gimplify.c
@@ -1202,8 +1202,10 @@ asan_poison_variable (tree decl, bool poison, gimple_stmt_iterator *it,
 
   /* It's necessary to have all stack variables aligned to ASAN granularity
      bytes.  */
-  if (DECL_ALIGN_UNIT (decl) <= ASAN_SHADOW_GRANULARITY)
-    SET_DECL_ALIGN (decl, BITS_PER_UNIT * ASAN_SHADOW_GRANULARITY);
+  unsigned shadow_granularity =
+    memory_tagging_p () ? HWASAN_TAG_GRANULE_SIZE : ASAN_SHADOW_GRANULARITY;
+  if (DECL_ALIGN_UNIT (decl) <= shadow_granularity)
+    SET_DECL_ALIGN (decl, BITS_PER_UNIT * shadow_granularity);
 
   HOST_WIDE_INT flags = poison ? ASAN_MARK_POISON : ASAN_MARK_UNPOISON;
 
@@ -13816,7 +13818,7 @@ gimplify_function_tree (tree fndecl)
       && !needs_to_live_in_memory (ret))
     DECL_GIMPLE_REG_P (ret) = 1;
 
-  if (asan_sanitize_use_after_scope () && sanitize_flags_p (SANITIZE_ADDRESS))
+  if (asan_sanitize_use_after_scope ())
     asan_poisoned_variables = new hash_set<tree> ();
   bind = gimplify_body (fndecl, true);
   if (asan_poisoned_variables)
diff --git a/gcc/internal-fn.c b/gcc/internal-fn.c
index 4eec9919b520691ab3e73a2920ef8b544cf55dfe..c530fe8951c30987c874df83e74be6d058730134 100644
--- a/gcc/internal-fn.c
+++ b/gcc/internal-fn.c
@@ -471,11 +471,7 @@ expand_HWASAN_CHOOSE_COLOUR (internal_fn, gcall *gc)
   machine_mode mode = GET_MODE (target);
   gcc_assert (mode == QImode);
 
-  rtx base_tag = expand_simple_binop (Pmode, LSHIFTRT, hwasan_base (),
-				      HWASAN_SHIFT_RTX,
-				      NULL_RTX, /* unsignedp = */0,
-				      OPTAB_DIRECT);
-
+  rtx base_tag = hwasan_extract_tag (hwasan_base ());
   gcc_assert (base_tag);
   rtx tag_offset = const_int_rtx[MAX_SAVED_CONST_INT + hwasan_current_tag ()];
   rtx chosen_tag = expand_simple_binop (QImode, PLUS, base_tag, tag_offset,
@@ -498,6 +494,39 @@ expand_HWASAN_CHOOSE_COLOUR (internal_fn, gcall *gc)
 }
 
 static void
+expand_HWASAN_MARK (internal_fn, gcall *gc)
+{
+  HOST_WIDE_INT flag = tree_to_shwi (gimple_call_arg (gc, 0));
+  bool is_poison = ((asan_mark_flags)flag) == ASAN_MARK_POISON;
+
+  tree base = gimple_call_arg (gc, 1);
+  gcc_checking_assert (TREE_CODE (base) == ADDR_EXPR);
+  rtx base_rtx = expand_normal (base);
+
+  rtx tag = is_poison ? const0_rtx : hwasan_extract_tag (base_rtx);
+  rtx address = hwasan_create_untagged_base (base_rtx);
+
+  tree len = gimple_call_arg (gc, 2);
+  gcc_assert (tree_fits_shwi_p (len));
+  unsigned HOST_WIDE_INT size_in_bytes = tree_to_shwi (len);
+  uint8_t tg_mask = HWASAN_TAG_GRANULE_SIZE - 1;
+  gcc_assert (size_in_bytes);
+  size_in_bytes = (size_in_bytes + tg_mask) & ~tg_mask;
+  rtx size = gen_int_mode (size_in_bytes, Pmode);
+
+  /* TODO Other options (i.e. inline options)  */
+  rtx func = init_one_libfunc ("__hwasan_tag_memory");
+  emit_library_call (func,
+      LCT_NORMAL,
+      VOIDmode,
+      address, ptr_mode,
+      tag, QImode,
+      size, ptr_mode);
+}
+
+/* This should get expanded in the sanopt pass.  */
+
+static void
 expand_ASAN_CHECK (internal_fn, gcall *)
 {
   gcc_unreachable ();
diff --git a/gcc/internal-fn.def b/gcc/internal-fn.def
index ed0c5bc110f16b2cdbc139403dbdbd8ebe7e2823..100f6fbad0af4fefdd0408384374b8fdcde9bee4 100644
--- a/gcc/internal-fn.def
+++ b/gcc/internal-fn.def
@@ -290,6 +290,7 @@ DEF_INTERNAL_FN (ABNORMAL_DISPATCHER, ECF_NORETURN, NULL)
 DEF_INTERNAL_FN (BUILTIN_EXPECT, ECF_CONST | ECF_LEAF | ECF_NOTHROW, NULL)
 DEF_INTERNAL_FN (HWASAN_CHOOSE_COLOUR, ECF_LEAF | ECF_NOTHROW, ".")
 DEF_INTERNAL_FN (HWASAN_CHECK, ECF_TM_PURE | ECF_LEAF | ECF_NOTHROW, "..R..")
+DEF_INTERNAL_FN (HWASAN_MARK, ECF_LEAF | ECF_NOTHROW, NULL)
 DEF_INTERNAL_FN (ASAN_CHECK, ECF_TM_PURE | ECF_LEAF | ECF_NOTHROW, "..R..")
 DEF_INTERNAL_FN (ASAN_MARK, ECF_LEAF | ECF_NOTHROW, NULL)
 DEF_INTERNAL_FN (ASAN_POISON, ECF_LEAF | ECF_NOTHROW | ECF_NOVOPS, NULL)
diff --git a/gcc/sanopt.c b/gcc/sanopt.c
index 31270153f3cf56bfbad593830de1b9334e7f65d1..29b12a43029cdcce5756354ac12d6d9e963e9ac8 100644
--- a/gcc/sanopt.c
+++ b/gcc/sanopt.c
@@ -1258,6 +1258,12 @@ sanitize_rewrite_addressable_params (function *fun)
 unsigned int
 pass_sanopt::execute (function *fun)
 {
+  /*
+     n.b. ASAN_MARK is used for both HWASAN and ASAN.
+     asan_num_accesses is used to count either HWASAN_CHECK or ASAN_CHECK
+     stuff.  This is fine because you can only have one of these active at a
+     time.
+ */
   basic_block bb;
   int asan_num_accesses = 0;
   bool contains_asan_mark = false;
@@ -1345,6 +1351,9 @@ pass_sanopt::execute (function *fun)
 						    &need_commit_edge_insert,
 						    shadow_vars_mapping);
 		  break;
+		case IFN_HWASAN_MARK:
+		  no_next = hwasan_expand_mark_ifn (&gsi);
+		  break;
 		default:
 		  break;
 		}


  parent reply	other threads:[~2019-09-06 14:46 UTC|newest]

Thread overview: 35+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-09-06 14:46 [Patch 0/X] [WIP][RFC][libsanitizer] Introduce HWASAN to GCC Matthew Malcomson
2019-09-06 14:46 ` [RFC][PATCH 1/X][libsanitizer] Introduce libsanitizer to GCC tree Matthew Malcomson
2019-09-09  9:26   ` Martin Liška
2019-09-06 14:46 ` Matthew Malcomson [this message]
2019-09-06 14:46 ` [RFC][PATCH 5/X][libsanitizer] Introduce longjmp/setjmp interceptors to libhwasan Matthew Malcomson
2019-09-09 10:02   ` Martin Liška
2019-09-09 10:29     ` Matthew Malcomson
2019-09-09 10:49       ` Martin Liška
2019-09-06 14:46 ` [RFC][PATCH 8/X][libsanitizer] Ensure HWASAN required alignment for stack variables Matthew Malcomson
2019-09-06 14:46 ` [RFC][PATCH 7/X][libsanitizer] Add option to bootstrap using HWASAN Matthew Malcomson
2019-09-06 14:46 ` [RFC][PATCH 4/X][libsanitizer] Pass size and pointer info to error reporting functions Matthew Malcomson
2019-09-09  9:27   ` Martin Liška
2019-09-06 14:46 ` [RFC][PATCH 2/X][libsanitizer] Tie the hwasan library into our build system Matthew Malcomson
2019-09-06 14:46 ` [RFC][PATCH 3/X][libsanitizer] Allow compilation for HWASAN_WITH_INTERCEPTORS=OFF Matthew Malcomson
2019-09-09  9:27   ` Martin Liška
2019-09-06 14:47 ` [RFC][PATCH 9/X][libsanitizer] Put tags into each stack variable pointer Matthew Malcomson
2019-09-06 14:47 ` [RFC][PATCH 6/X][libsanitizer] Add -fsanitize=hwaddress flags Matthew Malcomson
2019-09-09 10:06   ` Martin Liška
2019-09-09 10:18     ` Matthew Malcomson
2019-09-09 10:20       ` Martin Liška
2019-09-06 14:47 ` [RFC][PATCH 12/X][libsanitizer] Check pointer tags match address tags Matthew Malcomson
2019-09-06 14:47 ` [RFC][PATCH 16/X][libsanitizer] Build libhwasan with interceptors Matthew Malcomson
2019-09-06 14:47 ` [RFC][PATCH 11/X][libsanitizer] Uncolour stack frame on function exit Matthew Malcomson
2019-09-06 14:47 ` [RFC][PATCH 15/X][libsanitizer] Add in MTE stubs Matthew Malcomson
2019-09-06 14:47 ` [RFC][PATCH 10/X][libsanitizer] Colour the shadow stack for each stack variable Matthew Malcomson
2019-09-06 14:47 ` [RFC][PATCH 13/X][libsanitizer] Instrument known builtin function calls Matthew Malcomson
2019-09-09 10:47 ` [Patch 0/X] [WIP][RFC][libsanitizer] Introduce HWASAN to GCC Martin Liška
2019-09-09 15:55   ` Matthew Malcomson
2019-09-10  1:06     ` Kostya Serebryany via gcc-patches
2019-09-11 11:53     ` Martin Liška
2019-09-11 16:37       ` Matthew Malcomson
2019-09-11 18:34         ` Evgenii Stepanov via gcc-patches
2019-09-23  8:02 ` Martin Liška
2019-10-23 11:02   ` Matthew Malcomson
2019-10-24 10:11     ` Martin Liška

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=VI1PR08MB5471728307526AD56137AE10E0BA0@VI1PR08MB5471.eurprd08.prod.outlook.com \
    --to=matthew.malcomson@arm.com \
    --cc=dodji@redhat.com \
    --cc=dvyukov@google.com \
    --cc=gcc-patches@gcc.gnu.org \
    --cc=jakub@redhat.com \
    --cc=kcc@google.com \
    --cc=mliska@suse.cz \
    --cc=nd@arm.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).