Hi,

Here is a patch to adopt some builtins expanding to Pointer Bounds Checker.  
Patch mostly disables inlining of instrumented calls to string function.  Also 
adds support for _NOBND_NOCHK versions of string functions (this version does 
not check and copy bounds; therefore may be inlined as regular string function).

Thanks,
Ilya
--
2013-11-13  Ilya Enkovich  <ilya.enkov...@intel.com>

        * builtins.c: Include rtl-chkp.h, tree-chkp.h.
        (expand_builtin_mempcpy_args): Add orig exp as argument.
        Support BUILT_IN_CHKP_MEMPCPY_NOBND_NOCHK.
        (expand_builtin_mempcpy): Adjust expand_builtin_mempcpy_args call.
        (expand_builtin_stpcpy): Likewise.
        (expand_builtin_memset_args): Support BUILT_IN_CHKP_MEMSET_NOBND_NOCHK.
        (std_expand_builtin_va_start): Initialize bounds for va_list.
        (expand_builtin): Support instrumented calls.
        * optabs.c: Include rtl-chkp.h.
        (expand_unop): Handle bounds in libcall return value.


diff --git a/gcc/builtins.c b/gcc/builtins.c
index 7a04664..b46c364 100644
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -50,6 +50,8 @@ along with GCC; see the file COPYING3.  If not see
 #include "builtins.h"
 #include "ubsan.h"
 #include "cilk.h"
+#include "tree-chkp.h"
+#include "rtl-chkp.h"
 
 
 static tree do_mpc_arg1 (tree, tree, int (*)(mpc_ptr, mpc_srcptr, mpc_rnd_t));
@@ -115,7 +117,7 @@ static rtx builtin_memcpy_read_str (void *, HOST_WIDE_INT, 
enum machine_mode);
 static rtx expand_builtin_memcpy (tree, rtx);
 static rtx expand_builtin_mempcpy (tree, rtx, enum machine_mode);
 static rtx expand_builtin_mempcpy_args (tree, tree, tree, rtx,
-                                       enum machine_mode, int);
+                                       enum machine_mode, int, tree);
 static rtx expand_builtin_strcpy (tree, rtx);
 static rtx expand_builtin_strcpy_args (tree, tree, rtx);
 static rtx expand_builtin_stpcpy (tree, rtx, enum machine_mode);
@@ -3195,7 +3197,8 @@ expand_builtin_mempcpy (tree exp, rtx target, enum 
machine_mode mode)
       tree src = CALL_EXPR_ARG (exp, 1);
       tree len = CALL_EXPR_ARG (exp, 2);
       return expand_builtin_mempcpy_args (dest, src, len,
-                                         target, mode, /*endp=*/ 1);
+                                         target, mode, /*endp=*/ 1,
+                                         exp);
     }
 }
 
@@ -3207,10 +3210,23 @@ expand_builtin_mempcpy (tree exp, rtx target, enum 
machine_mode mode)
 
 static rtx
 expand_builtin_mempcpy_args (tree dest, tree src, tree len,
-                            rtx target, enum machine_mode mode, int endp)
+                            rtx target, enum machine_mode mode, int endp,
+                            tree orig_exp)
 {
+  tree fndecl = get_callee_fndecl (orig_exp);
+
     /* If return value is ignored, transform mempcpy into memcpy.  */
-  if (target == const0_rtx && builtin_decl_implicit_p (BUILT_IN_MEMCPY))
+  if (target == const0_rtx
+      && DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CHKP_MEMPCPY_NOBND_NOCHK
+      && builtin_decl_implicit_p (BUILT_IN_CHKP_MEMCPY_NOBND_NOCHK))
+    {
+      tree fn = builtin_decl_implicit (BUILT_IN_CHKP_MEMCPY_NOBND_NOCHK);
+      tree result = build_call_nofold_loc (UNKNOWN_LOCATION, fn, 3,
+                                          dest, src, len);
+      return expand_expr (result, target, mode, EXPAND_NORMAL);
+    }
+  else if (target == const0_rtx
+          && builtin_decl_implicit_p (BUILT_IN_MEMCPY))
     {
       tree fn = builtin_decl_implicit (BUILT_IN_MEMCPY);
       tree result = build_call_nofold_loc (UNKNOWN_LOCATION, fn, 3,
@@ -3394,7 +3410,8 @@ expand_builtin_stpcpy (tree exp, rtx target, enum 
machine_mode mode)
 
       lenp1 = size_binop_loc (loc, PLUS_EXPR, len, ssize_int (1));
       ret = expand_builtin_mempcpy_args (dst, src, lenp1,
-                                        target, mode, /*endp=*/2);
+                                        target, mode, /*endp=*/2,
+                                        exp);
 
       if (ret)
        return ret;
@@ -3679,7 +3696,8 @@ expand_builtin_memset_args (tree dest, tree val, tree len,
  do_libcall:
   fndecl = get_callee_fndecl (orig_exp);
   fcode = DECL_FUNCTION_CODE (fndecl);
-  if (fcode == BUILT_IN_MEMSET)
+  if (fcode == BUILT_IN_MEMSET
+      || fcode == BUILT_IN_CHKP_MEMSET_NOBND_NOCHK)
     fn = build_call_nofold_loc (EXPR_LOCATION (orig_exp), fndecl, 3,
                                dest, val, len);
   else if (fcode == BUILT_IN_BZERO)
@@ -4231,6 +4249,13 @@ std_expand_builtin_va_start (tree valist, rtx nextarg)
 {
   rtx va_r = expand_expr (valist, NULL_RTX, VOIDmode, EXPAND_WRITE);
   convert_move (va_r, nextarg, 0);
+
+  /* We do not have any valid bounds for the pointer, so
+     just store zero bounds for it.  */
+  if (chkp_function_instrumented_p (current_function_decl))
+    chkp_expand_bounds_reset_for_mem (valist,
+                                     make_tree (TREE_TYPE (valist),
+                                                nextarg));
 }
 
 /* Expand EXP, a call to __builtin_va_start.  */
@@ -6031,60 +6056,113 @@ expand_builtin (tree exp, rtx target, rtx subtarget, 
enum machine_mode mode,
       break;
 
     case BUILT_IN_STRLEN:
+      if (CALL_WITH_BOUNDS_P (exp))
+       break;
       target = expand_builtin_strlen (exp, target, target_mode);
       if (target)
        return target;
       break;
 
     case BUILT_IN_STRCPY:
+      if (CALL_WITH_BOUNDS_P (exp))
+       break;
       target = expand_builtin_strcpy (exp, target);
       if (target)
        return target;
       break;
 
     case BUILT_IN_STRNCPY:
+      if (CALL_WITH_BOUNDS_P (exp))
+       break;
       target = expand_builtin_strncpy (exp, target);
       if (target)
        return target;
       break;
 
     case BUILT_IN_STPCPY:
+      if (CALL_WITH_BOUNDS_P (exp))
+       break;
       target = expand_builtin_stpcpy (exp, target, mode);
       if (target)
        return target;
       break;
 
     case BUILT_IN_MEMCPY:
+    case BUILT_IN_CHKP_MEMCPY_NOBND_NOCHK:
+      if (CALL_WITH_BOUNDS_P (exp)
+         && fcode == BUILT_IN_MEMCPY)
+       break;
       target = expand_builtin_memcpy (exp, target);
       if (target)
-       return target;
+       {
+         /* We need to set returned bounds for instrumented
+            calls.  */
+         if (CALL_WITH_BOUNDS_P (exp))
+           {
+             rtx bnd = chkp_expand_arg_bounds (CALL_EXPR_ARG (exp, 0));
+             target = chkp_join_splitted_slot (target, bnd);
+           }
+         return target;
+       }
       break;
 
     case BUILT_IN_MEMPCPY:
+      case BUILT_IN_CHKP_MEMPCPY_NOBND_NOCHK:
+       if (CALL_WITH_BOUNDS_P (exp)
+           && fcode == BUILT_IN_MEMPCPY)
+       break;
       target = expand_builtin_mempcpy (exp, target, mode);
       if (target)
-       return target;
+       {
+         /* We need to set returned bounds for instrumented
+            calls.  */
+         if (CALL_WITH_BOUNDS_P (exp))
+           {
+             rtx bnd = chkp_expand_arg_bounds (CALL_EXPR_ARG (exp, 0));
+             target = chkp_join_splitted_slot (target, bnd);
+           }
+         return target;
+       }
       break;
 
     case BUILT_IN_MEMSET:
+    case BUILT_IN_CHKP_MEMSET_NOBND_NOCHK:
+      if (CALL_WITH_BOUNDS_P (exp)
+         && fcode == BUILT_IN_MEMSET)
+       break;
       target = expand_builtin_memset (exp, target, mode);
       if (target)
-       return target;
+       {
+         /* We need to set returned bounds for instrumented
+            calls.  */
+         if (CALL_WITH_BOUNDS_P (exp))
+           {
+             rtx bnd = chkp_expand_arg_bounds (CALL_EXPR_ARG (exp, 0));
+             target = chkp_join_splitted_slot (target, bnd);
+           }
+         return target;
+       }
       break;
 
     case BUILT_IN_BZERO:
+      if (CALL_WITH_BOUNDS_P (exp))
+       break;
       target = expand_builtin_bzero (exp);
       if (target)
        return target;
       break;
 
     case BUILT_IN_STRCMP:
+      if (CALL_WITH_BOUNDS_P (exp))
+       break;
       target = expand_builtin_strcmp (exp, target);
       if (target)
        return target;
       break;
 
     case BUILT_IN_STRNCMP:
+      if (CALL_WITH_BOUNDS_P (exp))
+       break;
       target = expand_builtin_strncmp (exp, target, mode);
       if (target)
        return target;
@@ -6092,6 +6170,8 @@ expand_builtin (tree exp, rtx target, rtx subtarget, enum 
machine_mode mode,
 
     case BUILT_IN_BCMP:
     case BUILT_IN_MEMCMP:
+      if (CALL_WITH_BOUNDS_P (exp))
+       break;
       target = expand_builtin_memcmp (exp, target, mode);
       if (target)
        return target;
@@ -6718,6 +6798,8 @@ expand_builtin (tree exp, rtx target, rtx subtarget, enum 
machine_mode mode,
     case BUILT_IN_MEMPCPY_CHK:
     case BUILT_IN_MEMMOVE_CHK:
     case BUILT_IN_MEMSET_CHK:
+      if (CALL_WITH_BOUNDS_P (exp))
+       break;
       target = expand_builtin_memory_chk (exp, target, mode, fcode);
       if (target)
        return target;
@@ -6774,7 +6856,7 @@ expand_builtin (tree exp, rtx target, rtx subtarget, enum 
machine_mode mode,
     case BUILT_IN_CHKP_GET_PTR_UBOUND:
       /* We allow user CHKP builtins if Pointer Bounds
         Checker is off.  */
-      if (!flag_check_pointer_bounds)
+      if (!chkp_function_instrumented_p (current_function_decl))
        {
          if (fcode == BUILT_IN_CHKP_SET_PTR_BOUNDS
              || fcode == BUILT_IN_CHKP_NARROW_PTR_BOUNDS)
@@ -6799,7 +6881,7 @@ expand_builtin (tree exp, rtx target, rtx subtarget, enum 
machine_mode mode,
     case BUILT_IN_CHKP_NARROW:
     case BUILT_IN_CHKP_EXTRACT_LOWER:
     case BUILT_IN_CHKP_EXTRACT_UPPER:
-      /* Software implementation of pointers checker is NYI.
+      /* Software implementation of Pointer Bounds Checker is NYI.
         Target support is required.  */
       error ("Your target platform does not support -fcheck-pointers");
       break;
diff --git a/gcc/optabs.c b/gcc/optabs.c
index 164e4dd..736f032 100644
--- a/gcc/optabs.c
+++ b/gcc/optabs.c
@@ -41,6 +41,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "ggc.h"
 #include "basic-block.h"
 #include "target.h"
+#include "rtl-chkp.h"
 
 struct target_optabs default_target_optabs;
 struct target_libfuncs default_target_libfuncs;
@@ -3256,9 +3257,14 @@ expand_unop (enum machine_mode mode, optab unoptab, rtx 
op0, rtx target,
       if (unoptab == ffs_optab || unoptab == clz_optab || unoptab == ctz_optab
          || unoptab == clrsb_optab || unoptab == popcount_optab
          || unoptab == parity_optab)
-       outmode
-         = GET_MODE (hard_libcall_value (TYPE_MODE (integer_type_node),
-                                         optab_libfunc (unoptab, mode)));
+       {
+         rtx bnd, val;
+
+         val = hard_libcall_value (TYPE_MODE (integer_type_node),
+                                   optab_libfunc (unoptab, mode));
+         chkp_split_slot (val, &val, &bnd);
+         outmode = GET_MODE (val);
+       }
 
       start_sequence ();
 

Reply via email to