diff mbox

[CHKP] Don't generate bndret for not instrumented calls

Message ID 20141202132812.GC2963@msticlxl57.ims.intel.com
State New
Headers show

Commit Message

Ilya Enkovich Dec. 2, 2014, 1:33 p.m. UTC
Hi,

Currently bndret is generated each time we need to get bounds for returned pointer.  It causes bndret generated for not instrumented calls incuding builtin function calls.  Troubles appear when such builtin call is optimized out - bndret needs to be handled appropriately.  Since we don't want not instrumented builtin calls optimizers to be affected by instrumentation, we better avoid bndret for not instrumented calls.  This patch uses zero bounds when we don't expect call to return bounds.

Bootstrapped and tested on  x86_64-unknown-linux-gnu.  OK for trunk?

Thanks,
Ilya
--
gcc/

2014-12-02  Ilya Enkovich  <ilya.enkovich@intel.com>

	* tree-chkp.c (chkp_call_returns_bounds_p): New.
	(chkp_build_returned_bound): Use zero bounds as
	returned by calls not returning bounds.

gcc/testsuite/

2014-12-02  Ilya Enkovich  <ilya.enkovich@intel.com>

	* gcc.target/i386/chkp-bndret.c: New.
	* gcc.target/i386/chkp-strchr.c: New.

Comments

Jeff Law Dec. 5, 2014, 10:57 p.m. UTC | #1
On 12/02/14 06:33, Ilya Enkovich wrote:
> Hi,
>
> Currently bndret is generated each time we need to get bounds for returned pointer.  It causes bndret generated for not instrumented calls incuding builtin function calls.  Troubles appear when such builtin call is optimized out - bndret needs to be handled appropriately.  Since we don't want not instrumented builtin calls optimizers to be affected by instrumentation, we better avoid bndret for not instrumented calls.  This patch uses zero bounds when we don't expect call to return bounds.
>
> Bootstrapped and tested on  x86_64-unknown-linux-gnu.  OK for trunk?
>
> Thanks,
> Ilya
> --
> gcc/
>
> 2014-12-02  Ilya Enkovich  <ilya.enkovich@intel.com>
>
> 	* tree-chkp.c (chkp_call_returns_bounds_p): New.
> 	(chkp_build_returned_bound): Use zero bounds as
> 	returned by calls not returning bounds.
>
> gcc/testsuite/
>
> 2014-12-02  Ilya Enkovich  <ilya.enkovich@intel.com>
>
> 	* gcc.target/i386/chkp-bndret.c: New.
> 	* gcc.target/i386/chkp-strchr.c: New.
OK.
Jeff
diff mbox

Patch

diff --git a/gcc/testsuite/gcc.target/i386/chkp-bndret.c b/gcc/testsuite/gcc.target/i386/chkp-bndret.c
new file mode 100644
index 0000000..3498058
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/chkp-bndret.c
@@ -0,0 +1,15 @@ 
+/* { dg-do compile } */
+/* { dg-require-effective-target mpx } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx -O2 -fdump-tree-chkp" } */
+/* { dg-final { scan-tree-dump-not "bndret" "chkp" } } */
+/* { dg-final { cleanup-tree-dump "chkp" } } */
+
+#include "string.h"
+
+extern int *test1 (int *p) __attribute__((bnd_legacy));
+
+int *
+test2 (int *p)
+{
+  return test1 (p);
+}
diff --git a/gcc/testsuite/gcc.target/i386/chkp-strchr.c b/gcc/testsuite/gcc.target/i386/chkp-strchr.c
new file mode 100644
index 0000000..94a5eaa
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/chkp-strchr.c
@@ -0,0 +1,17 @@ 
+/* { dg-do compile } */
+/* { dg-require-effective-target mpx } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx -O2" } */
+
+#include "string.h"
+
+static char *
+test1 (char *str)
+{
+  return strrchr (str, '_');
+}
+
+char *
+test2 ()
+{
+  return test1 ("test_string");
+}
diff --git a/gcc/tree-chkp.c b/gcc/tree-chkp.c
index 3e38691..f7def51 100644
--- a/gcc/tree-chkp.c
+++ b/gcc/tree-chkp.c
@@ -2080,6 +2080,38 @@  chkp_get_nonpointer_load_bounds (void)
   return chkp_get_zero_bounds ();
 }
 
+/* Return 1 if may use bndret call to get bounds for pointer
+   returned by CALL.  */
+static bool
+chkp_call_returns_bounds_p (gcall *call)
+{
+  if (gimple_call_internal_p (call))
+    return false;
+
+  tree fndecl = gimple_call_fndecl (call);
+
+  if (fndecl && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
+    return false;
+
+  if (fndecl
+      && lookup_attribute ("bnd_legacy", DECL_ATTRIBUTES (fndecl)))
+    return false;
+
+  if (fndecl && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
+    {
+      if (chkp_instrument_normal_builtin (fndecl))
+	return true;
+
+      if (!lookup_attribute ("always_inline", DECL_ATTRIBUTES (fndecl)))
+	return false;
+
+      struct cgraph_node *clone = chkp_maybe_create_clone (fndecl);
+      return (clone && gimple_has_body_p (clone->decl));
+    }
+
+  return true;
+}
+
 /* Build bounds returned by CALL.  */
 static tree
 chkp_build_returned_bound (gcall *call)
@@ -2154,7 +2186,7 @@  chkp_build_returned_bound (gcall *call)
 
       bounds = chkp_find_bounds (gimple_call_arg (call, argno), &iter);
     }
-  else
+  else if (chkp_call_returns_bounds_p (call))
     {
       gcc_assert (TREE_CODE (gimple_call_lhs (call)) == SSA_NAME);
 
@@ -2172,6 +2204,8 @@  chkp_build_returned_bound (gcall *call)
 
       update_stmt (stmt);
     }
+  else
+    bounds = chkp_get_zero_bounds ();
 
   if (dump_file && (dump_flags & TDF_DETAILS))
     {