public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH, Pointer Bounds Checker 4/x] Built-in functions
@ 2014-04-16 12:22 Ilya Enkovich
  2014-05-06 12:11 ` Ilya Enkovich
  2014-07-18  6:17 ` Jeff Law
  0 siblings, 2 replies; 4+ messages in thread
From: Ilya Enkovich @ 2014-04-16 12:22 UTC (permalink / raw)
  To: gcc-patches

Hi,

This patch introduces built-in functions used by Pointer Bounds Checker.  It is mostly similar to what was reverted from 4.9, I just added types and attributes to builtins.  This patch also introduces pointer_bounds_type_node to be used in built-in function type declarations.

Bootstrapped and tested on linux-x86_64.

OK for trunk?

Thanks,
Ilya
--
gcc/

2014-04-16  Ilya Enkovich  <ilya.enkovich@intel.com>

	* tree-core.h (tree_index): Add TI_POINTER_BOUNDS_TYPE.
	* tree.h (pointer_bounds_type_node): New.
	* tree.c (build_common_tree_nodes): Initialize
	pointer_bounds_type_node.
	* builtin-types.def (BT_BND): New.
	(BT_FN_PTR_CONST_PTR): New.
	(BT_FN_CONST_PTR_CONST_PTR): New.
	(BT_FN_BND_CONST_PTR): New.
	(BT_FN_CONST_PTR_BND): New.
	(BT_FN_PTR_CONST_PTR_SIZE): New.
	(BT_FN_PTR_CONST_PTR_CONST_PTR): New.
	(BT_FN_VOID_PTRPTR_CONST_PTR): New.
	(BT_FN_VOID_CONST_PTR_SIZE): New.
	(BT_FN_VOID_PTR_BND): New.
	(BT_FN_CONST_PTR_CONST_PTR_CONST_PTR): New.
	(BT_FN_BND_CONST_PTR_SIZE): New.
	(BT_FN_PTR_CONST_PTR_CONST_PTR_SIZE): New.
	(BT_FN_VOID_CONST_PTR_BND_CONST_PTR): New.
	* chkp-builtins.def: New.
	* builtins.def: include chkp-builtins.def.
	(DEF_CHKP_BUILTIN): New.
	* builtins.c (expand_builtin): Support BUILT_IN_CHKP_INIT_PTR_BOUNDS,
	BUILT_IN_CHKP_NULL_PTR_BOUNDS, BUILT_IN_CHKP_COPY_PTR_BOUNDS,
	BUILT_IN_CHKP_CHECK_PTR_LBOUNDS, BUILT_IN_CHKP_CHECK_PTR_UBOUNDS,
	BUILT_IN_CHKP_CHECK_PTR_BOUNDS, BUILT_IN_CHKP_SET_PTR_BOUNDS,
	BUILT_IN_CHKP_NARROW_PTR_BOUNDS, BUILT_IN_CHKP_STORE_PTR_BOUNDS,
	BUILT_IN_CHKP_GET_PTR_LBOUND, BUILT_IN_CHKP_GET_PTR_UBOUND,
	BUILT_IN_CHKP_BNDMK, BUILT_IN_CHKP_BNDSTX, BUILT_IN_CHKP_BNDCL,
	BUILT_IN_CHKP_BNDCU, BUILT_IN_CHKP_BNDLDX, BUILT_IN_CHKP_BNDRET,
	BUILT_IN_CHKP_INTERSECT, BUILT_IN_CHKP_NARROW,
	BUILT_IN_CHKP_EXTRACT_LOWER, BUILT_IN_CHKP_EXTRACT_UPPER.
	* c-family/c.opt (fcheck-pointer-bounds): New.
	* toplev.c (process_options): Check Pointer Bounds Checker is supported.
	* doc/extend.texi: Document Pointer Bounds Checker built-in functions.


diff --git a/gcc/builtin-types.def b/gcc/builtin-types.def
index fba9c7d..2e5f361 100644
--- a/gcc/builtin-types.def
+++ b/gcc/builtin-types.def
@@ -133,6 +133,8 @@ DEF_PRIMITIVE_TYPE (BT_I4, builtin_type_for_size (BITS_PER_UNIT*4, 1))
 DEF_PRIMITIVE_TYPE (BT_I8, builtin_type_for_size (BITS_PER_UNIT*8, 1))
 DEF_PRIMITIVE_TYPE (BT_I16, builtin_type_for_size (BITS_PER_UNIT*16, 1))
 
+DEF_PRIMITIVE_TYPE (BT_BND, pointer_bounds_type_node)
+
 DEF_POINTER_TYPE (BT_PTR_CONST_STRING, BT_CONST_STRING)
 DEF_POINTER_TYPE (BT_PTR_LONG, BT_LONG)
 DEF_POINTER_TYPE (BT_PTR_ULONGLONG, BT_ULONGLONG)
@@ -234,6 +236,10 @@ DEF_FUNCTION_TYPE_1 (BT_FN_UINT16_UINT16, BT_UINT16, BT_UINT16)
 DEF_FUNCTION_TYPE_1 (BT_FN_UINT32_UINT32, BT_UINT32, BT_UINT32)
 DEF_FUNCTION_TYPE_1 (BT_FN_UINT64_UINT64, BT_UINT64, BT_UINT64)
 DEF_FUNCTION_TYPE_1 (BT_FN_BOOL_INT, BT_BOOL, BT_INT)
+DEF_FUNCTION_TYPE_1 (BT_FN_PTR_CONST_PTR, BT_PTR, BT_CONST_PTR)
+DEF_FUNCTION_TYPE_1 (BT_FN_CONST_PTR_CONST_PTR, BT_CONST_PTR, BT_CONST_PTR)
+DEF_FUNCTION_TYPE_1 (BT_FN_BND_CONST_PTR, BT_BND, BT_CONST_PTR)
+DEF_FUNCTION_TYPE_1 (BT_FN_CONST_PTR_BND, BT_CONST_PTR, BT_BND)
 
 DEF_POINTER_TYPE (BT_PTR_FN_VOID_PTR, BT_FN_VOID_PTR)
 
@@ -347,6 +353,13 @@ DEF_FUNCTION_TYPE_2 (BT_FN_BOOL_SIZE_CONST_VPTR, BT_BOOL, BT_SIZE,
 		     BT_CONST_VOLATILE_PTR)
 DEF_FUNCTION_TYPE_2 (BT_FN_BOOL_INT_BOOL, BT_BOOL, BT_INT, BT_BOOL)
 DEF_FUNCTION_TYPE_2 (BT_FN_VOID_UINT_UINT, BT_VOID, BT_UINT, BT_UINT)
+DEF_FUNCTION_TYPE_2 (BT_FN_PTR_CONST_PTR_SIZE, BT_PTR, BT_CONST_PTR, BT_SIZE)
+DEF_FUNCTION_TYPE_2 (BT_FN_PTR_CONST_PTR_CONST_PTR, BT_PTR, BT_CONST_PTR, BT_CONST_PTR)
+DEF_FUNCTION_TYPE_2 (BT_FN_VOID_PTRPTR_CONST_PTR, BT_VOID, BT_PTR_PTR, BT_CONST_PTR)
+DEF_FUNCTION_TYPE_2 (BT_FN_VOID_CONST_PTR_SIZE, BT_VOID, BT_CONST_PTR, BT_SIZE)
+DEF_FUNCTION_TYPE_2 (BT_FN_VOID_PTR_BND, BT_VOID, BT_PTR, BT_BND)
+DEF_FUNCTION_TYPE_2 (BT_FN_CONST_PTR_CONST_PTR_CONST_PTR, BT_CONST_PTR, BT_CONST_PTR, BT_CONST_PTR)
+DEF_FUNCTION_TYPE_2 (BT_FN_BND_CONST_PTR_SIZE, BT_BND, BT_CONST_PTR, BT_SIZE)
 
 DEF_POINTER_TYPE (BT_PTR_FN_VOID_PTR_PTR, BT_FN_VOID_PTR_PTR)
 
@@ -430,6 +443,8 @@ DEF_FUNCTION_TYPE_3 (BT_FN_VOID_VPTR_I4_INT, BT_VOID, BT_VOLATILE_PTR, BT_I4, BT
 DEF_FUNCTION_TYPE_3 (BT_FN_VOID_VPTR_I8_INT, BT_VOID, BT_VOLATILE_PTR, BT_I8, BT_INT)
 DEF_FUNCTION_TYPE_3 (BT_FN_VOID_VPTR_I16_INT, BT_VOID, BT_VOLATILE_PTR, BT_I16, BT_INT)
 DEF_FUNCTION_TYPE_3 (BT_FN_INT_PTRPTR_SIZE_SIZE, BT_INT, BT_PTR_PTR, BT_SIZE, BT_SIZE)
+DEF_FUNCTION_TYPE_3 (BT_FN_PTR_CONST_PTR_CONST_PTR_SIZE, BT_PTR, BT_CONST_PTR, BT_CONST_PTR, BT_SIZE)
+DEF_FUNCTION_TYPE_3 (BT_FN_VOID_CONST_PTR_BND_CONST_PTR, BT_VOID, BT_CONST_PTR, BT_BND, BT_CONST_PTR)
 
 DEF_FUNCTION_TYPE_4 (BT_FN_SIZE_CONST_PTR_SIZE_SIZE_FILEPTR,
 		     BT_SIZE, BT_CONST_PTR, BT_SIZE, BT_SIZE, BT_FILEPTR)
diff --git a/gcc/builtins.c b/gcc/builtins.c
index dd57b1a..5ec6cb6 100644
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -5810,7 +5810,19 @@ expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode,
       && fcode != BUILT_IN_EXECVE
       && fcode != BUILT_IN_ALLOCA
       && fcode != BUILT_IN_ALLOCA_WITH_ALIGN
-      && fcode != BUILT_IN_FREE)
+      && fcode != BUILT_IN_FREE
+      && fcode != BUILT_IN_CHKP_SET_PTR_BOUNDS
+      && fcode != BUILT_IN_CHKP_INIT_PTR_BOUNDS
+      && fcode != BUILT_IN_CHKP_NULL_PTR_BOUNDS
+      && fcode != BUILT_IN_CHKP_COPY_PTR_BOUNDS
+      && fcode != BUILT_IN_CHKP_NARROW_PTR_BOUNDS
+      && fcode != BUILT_IN_CHKP_STORE_PTR_BOUNDS
+      && fcode != BUILT_IN_CHKP_CHECK_PTR_LBOUNDS
+      && fcode != BUILT_IN_CHKP_CHECK_PTR_UBOUNDS
+      && fcode != BUILT_IN_CHKP_CHECK_PTR_BOUNDS
+      && fcode != BUILT_IN_CHKP_GET_PTR_LBOUND
+      && fcode != BUILT_IN_CHKP_GET_PTR_UBOUND
+      && fcode != BUILT_IN_CHKP_BNDRET)
     return expand_call (exp, target, ignore);
 
   /* The built-in function expanders test for target == const0_rtx
@@ -6848,6 +6860,51 @@ expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode,
       expand_builtin_cilk_pop_frame (exp);
       return const0_rtx;
 
+    case BUILT_IN_CHKP_INIT_PTR_BOUNDS:
+    case BUILT_IN_CHKP_NULL_PTR_BOUNDS:
+    case BUILT_IN_CHKP_COPY_PTR_BOUNDS:
+    case BUILT_IN_CHKP_CHECK_PTR_LBOUNDS:
+    case BUILT_IN_CHKP_CHECK_PTR_UBOUNDS:
+    case BUILT_IN_CHKP_CHECK_PTR_BOUNDS:
+    case BUILT_IN_CHKP_SET_PTR_BOUNDS:
+    case BUILT_IN_CHKP_NARROW_PTR_BOUNDS:
+    case BUILT_IN_CHKP_STORE_PTR_BOUNDS:
+    case BUILT_IN_CHKP_GET_PTR_LBOUND:
+    case BUILT_IN_CHKP_GET_PTR_UBOUND:
+      /* We allow user CHKP builtins if Pointer Bounds
+	 Checker is off.  */
+      if (!flag_check_pointer_bounds)
+	{
+	  if (fcode == BUILT_IN_CHKP_SET_PTR_BOUNDS
+	      || fcode == BUILT_IN_CHKP_NARROW_PTR_BOUNDS
+	      || fcode == BUILT_IN_CHKP_INIT_PTR_BOUNDS
+	      || fcode == BUILT_IN_CHKP_NULL_PTR_BOUNDS
+	      || fcode == BUILT_IN_CHKP_COPY_PTR_BOUNDS)
+	    return expand_normal (CALL_EXPR_ARG (exp, 0));
+	  else if (fcode == BUILT_IN_CHKP_GET_PTR_LBOUND)
+	    return expand_normal (size_zero_node);
+	  else if (fcode == BUILT_IN_CHKP_GET_PTR_UBOUND)
+	    return expand_normal (size_int (-1));
+	  else
+	    return const0_rtx;
+	}
+      /* FALLTHROUGH */
+
+    case BUILT_IN_CHKP_BNDMK:
+    case BUILT_IN_CHKP_BNDSTX:
+    case BUILT_IN_CHKP_BNDCL:
+    case BUILT_IN_CHKP_BNDCU:
+    case BUILT_IN_CHKP_BNDLDX:
+    case BUILT_IN_CHKP_BNDRET:
+    case BUILT_IN_CHKP_INTERSECT:
+    case BUILT_IN_CHKP_NARROW:
+    case BUILT_IN_CHKP_EXTRACT_LOWER:
+    case BUILT_IN_CHKP_EXTRACT_UPPER:
+      /* Software implementation of Pointer Bounds Checker is NYI.
+	 Target support is required.  */
+      error ("Your target platform does not support -fcheck-pointer-bounds");
+      break;
+
     default:	/* just do library call, if unknown builtin */
       break;
     }
diff --git a/gcc/builtins.def b/gcc/builtins.def
index 5a76ba3..ed2617e 100644
--- a/gcc/builtins.def
+++ b/gcc/builtins.def
@@ -176,6 +176,12 @@ along with GCC; see the file COPYING3.  If not see
   DEF_BUILTIN (ENUM, NAME, BUILT_IN_NORMAL, BT_FN_INT_VAR, BT_LAST, \
   	       false, false, false, ATTRS, false, flag_cilkplus) 
 
+/* Builtin used by the implementation of Pointer Bounds Checker.  */
+#undef DEF_CHKP_BUILTIN
+#define DEF_CHKP_BUILTIN(ENUM, NAME, TYPE, ATTRS) \
+  DEF_BUILTIN (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE, TYPE,    \
+	       true, true, false, ATTRS, true, true)
+
 /* Define an attribute list for math functions that are normally
    "impure" because some of them may write into global memory for
    `errno'.  If !flag_errno_math they are instead "const".  */
@@ -870,3 +876,6 @@ DEF_GCC_BUILTIN (BUILT_IN_LINE, "LINE", BT_FN_INT, ATTR_NOTHROW_LEAF_LIST)
 
 /* Cilk Plus builtins.  */
 #include "cilkplus.def"
+
+/* Pointer Bounds Checker builtins.  */
+#include "chkp-builtins.def"
diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt
index 390c056..3ec5cda 100644
--- a/gcc/c-family/c.opt
+++ b/gcc/c-family/c.opt
@@ -866,6 +866,11 @@ fcanonical-system-headers
 C ObjC C++ ObjC++
 Where shorter, use canonicalized paths to systems headers.
 
+fcheck-pointer-bounds
+Common Report Var(flag_check_pointer_bounds)
+Add Pointer Bounds Checker instrumentation.  fchkp-* flags are used to
+control instrumentation.  Currently available for C, C++ and ObjC.
+
 fcilkplus
 C ObjC C++ ObjC++ LTO Report Var(flag_cilkplus) Init(0)
 Enable Cilk Plus
diff --git a/gcc/chkp-builtins.def b/gcc/chkp-builtins.def
new file mode 100644
index 0000000..cae0332
--- /dev/null
+++ b/gcc/chkp-builtins.def
@@ -0,0 +1,71 @@
+/* This file contains the definitions and documentation for the
+   builtins used in the GNU compiler.
+   Copyright (C) 2013 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3.  If not see
+<http://www.gnu.org/licenses/>.  */
+
+/* Before including this file, you should define macros:
+
+      DEF_BUILTIN_STUB(ENUM, NAME)
+      DEF_CHKP_BUILTIN(ENUM, NAME, TYPE, ATTRS)
+
+   See builtins.def for details.  */
+
+/* Following builtins are used by compiler for Pointer Bounds Checker
+   instrumentation.  Currently these generic builtins are not
+   implemented and target has to provide his own version.  See
+   builtin_chkp_function target hook documentation for more details.  */
+DEF_BUILTIN_STUB (BUILT_IN_CHKP_INTERSECT, "__chkp_intersect")
+DEF_BUILTIN_STUB (BUILT_IN_CHKP_SIZEOF, "__chkp_sizeof")
+DEF_BUILTIN_STUB (BUILT_IN_CHKP_NARROW, "__chkp_narrow")
+DEF_CHKP_BUILTIN (BUILT_IN_CHKP_BNDCL, "__chkp_bndcl", BT_FN_VOID_PTR_BND, ATTR_NOTHROW_LEAF_LIST)
+DEF_CHKP_BUILTIN (BUILT_IN_CHKP_BNDCU, "__chkp_bndcu", BT_FN_VOID_PTR_BND, ATTR_NOTHROW_LEAF_LIST)
+DEF_CHKP_BUILTIN (BUILT_IN_CHKP_BNDSTX, "__chkp_bndstx", BT_FN_VOID_CONST_PTR_BND_CONST_PTR, ATTR_NOTHROW_LEAF_LIST)
+DEF_CHKP_BUILTIN (BUILT_IN_CHKP_BNDLDX, "__chkp_bndldx", BT_FN_CONST_PTR_CONST_PTR_CONST_PTR, ATTR_NOTHROW_LEAF_LIST)
+DEF_CHKP_BUILTIN (BUILT_IN_CHKP_BNDRET, "__chkp_bndret", BT_FN_BND_CONST_PTR, ATTR_CONST_NOTHROW_LEAF_LIST)
+DEF_CHKP_BUILTIN (BUILT_IN_CHKP_BNDMK, "__chkp_bndmk", BT_FN_BND_CONST_PTR_SIZE, ATTR_CONST_NOTHROW_LEAF_LIST)
+DEF_CHKP_BUILTIN (BUILT_IN_CHKP_EXTRACT_LOWER, "__chkp_extract_lower", BT_FN_CONST_PTR_BND, ATTR_CONST_NOTHROW_LEAF_LIST)
+DEF_CHKP_BUILTIN (BUILT_IN_CHKP_EXTRACT_UPPER, "__chkp_extract_upper", BT_FN_CONST_PTR_BND, ATTR_CONST_NOTHROW_LEAF_LIST)
+
+/* Pointer Bounds Checker builtins for users.
+   All builtins calls are expanded in the
+   Pointer Bounds Checker pass.  */
+DEF_CHKP_BUILTIN (BUILT_IN_CHKP_SET_PTR_BOUNDS, "__bnd_set_ptr_bounds", BT_FN_PTR_CONST_PTR_SIZE, ATTR_CONST_NOTHROW_LEAF_LIST)
+DEF_CHKP_BUILTIN (BUILT_IN_CHKP_INIT_PTR_BOUNDS, "__bnd_init_ptr_bounds", BT_FN_PTR_CONST_PTR, ATTR_CONST_NOTHROW_LEAF_LIST)
+DEF_CHKP_BUILTIN (BUILT_IN_CHKP_NULL_PTR_BOUNDS, "__bnd_null_ptr_bounds", BT_FN_PTR_CONST_PTR, ATTR_CONST_NOTHROW_LEAF_LIST)
+DEF_CHKP_BUILTIN (BUILT_IN_CHKP_COPY_PTR_BOUNDS, "__bnd_copy_ptr_bounds", BT_FN_PTR_CONST_PTR_CONST_PTR, ATTR_CONST_NOTHROW_LEAF_LIST)
+DEF_CHKP_BUILTIN (BUILT_IN_CHKP_NARROW_PTR_BOUNDS, "__bnd_narrow_ptr_bounds", BT_FN_PTR_CONST_PTR_CONST_PTR_SIZE, ATTR_CONST_NOTHROW_LEAF_LIST)
+DEF_CHKP_BUILTIN (BUILT_IN_CHKP_STORE_PTR_BOUNDS, "__bnd_store_ptr_bounds", BT_FN_VOID_PTRPTR_CONST_PTR, ATTR_NOTHROW_LEAF_LIST)
+DEF_CHKP_BUILTIN (BUILT_IN_CHKP_CHECK_PTR_LBOUNDS, "__bnd_chk_ptr_lbounds", BT_FN_VOID_CONST_PTR, ATTR_NOTHROW_LEAF_LIST)
+DEF_CHKP_BUILTIN (BUILT_IN_CHKP_CHECK_PTR_UBOUNDS, "__bnd_chk_ptr_ubounds", BT_FN_VOID_CONST_PTR, ATTR_NOTHROW_LEAF_LIST)
+DEF_CHKP_BUILTIN (BUILT_IN_CHKP_CHECK_PTR_BOUNDS, "__bnd_chk_ptr_bounds", BT_FN_VOID_CONST_PTR_SIZE, ATTR_NOTHROW_LEAF_LIST)
+DEF_CHKP_BUILTIN (BUILT_IN_CHKP_GET_PTR_LBOUND, "__bnd_get_ptr_lbound", BT_FN_CONST_PTR_CONST_PTR, ATTR_CONST_NOTHROW_LEAF_LIST)
+DEF_CHKP_BUILTIN (BUILT_IN_CHKP_GET_PTR_UBOUND, "__bnd_get_ptr_ubound", BT_FN_CONST_PTR_CONST_PTR, ATTR_CONST_NOTHROW_LEAF_LIST)
+
+/* Pointer Bounds Checker specific versions of string functions.  */
+DEF_CHKP_BUILTIN (BUILT_IN_CHKP_MEMCPY_NOBND, "chkp_memcpy_nobnd", BT_FN_PTR_PTR_CONST_PTR_SIZE, ATTR_RET1_NOTHROW_NONNULL_LEAF)
+DEF_CHKP_BUILTIN (BUILT_IN_CHKP_MEMCPY_NOCHK, "chkp_memcpy_nochk", BT_FN_PTR_PTR_CONST_PTR_SIZE, ATTR_RET1_NOTHROW_NONNULL_LEAF)
+DEF_CHKP_BUILTIN (BUILT_IN_CHKP_MEMCPY_NOBND_NOCHK, "chkp_memcpy_nobnd_nochk", BT_FN_PTR_PTR_CONST_PTR_SIZE, ATTR_RET1_NOTHROW_NONNULL_LEAF)
+DEF_CHKP_BUILTIN (BUILT_IN_CHKP_MEMMOVE_NOBND, "chkp_memmove_nobnd", BT_FN_PTR_PTR_CONST_PTR_SIZE, ATTR_RET1_NOTHROW_NONNULL_LEAF)
+DEF_CHKP_BUILTIN (BUILT_IN_CHKP_MEMMOVE_NOCHK, "chkp_memmove_nochk", BT_FN_PTR_PTR_CONST_PTR_SIZE, ATTR_RET1_NOTHROW_NONNULL_LEAF)
+DEF_CHKP_BUILTIN (BUILT_IN_CHKP_MEMMOVE_NOBND_NOCHK, "chkp_memmove_nobnd_nochk", BT_FN_PTR_PTR_CONST_PTR_SIZE, ATTR_RET1_NOTHROW_NONNULL_LEAF)
+DEF_CHKP_BUILTIN (BUILT_IN_CHKP_MEMPCPY_NOBND, "chkp_mempcpy_nobnd", BT_FN_PTR_PTR_CONST_PTR_SIZE, ATTR_NOTHROW_NONNULL_LEAF)
+DEF_CHKP_BUILTIN (BUILT_IN_CHKP_MEMPCPY_NOCHK, "chkp_mempcpy_nochk", BT_FN_PTR_PTR_CONST_PTR_SIZE, ATTR_NOTHROW_NONNULL_LEAF)
+DEF_CHKP_BUILTIN (BUILT_IN_CHKP_MEMPCPY_NOBND_NOCHK, "chkp_mempcpy_nobnd_nochk", BT_FN_PTR_PTR_CONST_PTR_SIZE, ATTR_NOTHROW_NONNULL_LEAF)
+DEF_CHKP_BUILTIN (BUILT_IN_CHKP_MEMSET_NOBND, "chkp_memset_nobnd", BT_FN_PTR_PTR_INT_SIZE, ATTR_RET1_NOTHROW_NONNULL_LEAF)
+DEF_CHKP_BUILTIN (BUILT_IN_CHKP_MEMSET_NOCHK, "chkp_memset_nochk", BT_FN_PTR_PTR_INT_SIZE, ATTR_RET1_NOTHROW_NONNULL_LEAF)
+DEF_CHKP_BUILTIN (BUILT_IN_CHKP_MEMSET_NOBND_NOCHK, "chkp_memset_nobnd_nochk", BT_FN_PTR_PTR_INT_SIZE, ATTR_RET1_NOTHROW_NONNULL_LEAF)
diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index 347a94a..1c74990 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -82,6 +82,7 @@ extensions, accepted by GCC in C90 mode and in C++.
 * x86 specific memory model extensions for transactional memory:: x86 memory models.
 * Object Size Checking:: Built-in functions for limited buffer overflow
                         checking.
+* Pointer Bounds Checker builtins:: Built-in functions for Pointer Bounds Checker.
 * Cilk Plus Builtins::  Built-in functions for the Cilk Plus language extension.
 * Other Builtins::      Other built-in functions.
 * Target Builtins::     Built-in functions specific to particular targets.
@@ -7945,6 +7946,176 @@ format string @var{fmt}.  If the compiler is able to optimize them to
 @code{fputc} etc.@: functions, it does, otherwise the checking function
 is called and the @var{flag} argument passed to it.
 
+@node Pointer Bounds Checker builtins
+@section Pointer Bounds Checker Built-in Functions
+@findex __builtin___bnd_set_ptr_bounds
+@findex __builtin___bnd_narrow_ptr_bounds
+@findex __builtin___bnd_copy_ptr_bounds
+@findex __builtin___bnd_init_ptr_bounds
+@findex __builtin___bnd_null_ptr_bounds
+@findex __builtin___bnd_store_ptr_bounds
+@findex __builtin___bnd_chk_ptr_lbounds
+@findex __builtin___bnd_chk_ptr_ubounds
+@findex __builtin___bnd_chk_ptr_bounds
+@findex __builtin___bnd_get_ptr_lbound
+@findex __builtin___bnd_get_ptr_ubound
+
+GCC provides a set of built-in functions to control Pointer Bounds Checker
+instrumentation.  Note that all Pointer Bounds Checker builtins are allowed
+to use even if you compile with Pointer Bounds Checker off.  The builtins
+behavior may differ in such case as documented below.
+
+@deftypefn {Built-in Function} void * __builtin___bnd_set_ptr_bounds (const void * @var{q}, size_t @var{size})
+
+This built-in function returns a new pointer with the value of @var{q}, and
+associate it with the bounds [@var{q}, @var{q}+@var{size}-1].  With Pointer
+Bounds Checker off built-in function just returns the first argument.
+
+@smallexample
+extern void *__wrap_malloc (size_t n)
+@{
+  void *p = (void *)__real_malloc (n);
+  if (!p) return __builtin___bnd_null_ptr_bounds (p);
+  return __builtin___bnd_set_ptr_bounds (p, n);
+@}
+@end smallexample
+
+@end deftypefn
+
+@deftypefn {Built-in Function} void * __builtin___bnd_narrow_ptr_bounds (const void * @var{p}, const void * @var{q}, size_t  @var{size})
+
+This built-in function returns a new pointer with the value of @var{p}
+and associate it with the narrowed bounds formed by the intersection
+of bounds associated with @var{q} and the [@var{p}, @var{p} + @var{size} - 1].
+With Pointer Bounds Checker off built-in function just returns the first
+argument.
+
+@smallexample
+void init_objects (object *objs, size_t size)
+@{
+  size_t i;
+  /* Initialize objects one-by-one passing pointers with bounds of an object,
+     not the full array of objects.  */
+  for (i = 0; i < size; i++)
+    init_object (__builtin___bnd_narrow_ptr_bounds (objs + i, objs, sizeof(object)));
+@}
+@end smallexample
+
+@end deftypefn
+
+@deftypefn {Built-in Function} void * __builtin___bnd_copy_ptr_bounds (const void * @var{q}, const void * @var{r})
+
+This built-in function returns a new pointer with the value of @var{q},
+and associate it with the bounds already associated with pointer @var{r}.
+With Pointer Bounds Checker off built-in function just returns the first
+argument.
+
+@smallexample
+/* Here is a way to get pointer to object's field but
+   still with the full object's bounds.  */
+int *field_ptr = __builtin___bnd_copy_ptr_bounds (&objptr->int_filed, objptr);
+@end smallexample
+
+@end deftypefn
+
+@deftypefn {Built-in Function} void * __builtin___bnd_init_ptr_bounds (const void * @var{q})
+
+This built-in function returns a new pointer with the value of @var{q}, and
+associate it with INIT (allowing full memory access) bounds. With Pointer
+Bounds Checker off built-in function just returns the first argument.
+
+@end deftypefn
+
+@deftypefn {Built-in Function} void * __builtin___bnd_null_ptr_bounds (const void * @var{q})
+
+This built-in function returns a new pointer with the value of @var{q}, and
+associate it with NULL (allowing no memory access) bounds. With Pointer
+Bounds Checker off built-in function just returns the first argument.
+
+@end deftypefn
+
+@deftypefn {Built-in Function} void __builtin___bnd_store_ptr_bounds (const void ** @var{ptr_addr}, const void * @var{ptr_val})
+
+This built-in function stores the bounds associated with pointer @var{ptr_val}
+and location @var{ptr_addr} into Bounds Table.  This can be useful to propagate
+bounds from legacy code without touching the associated pointer's memory when
+pointers were copied as integers.  With Pointer Bounds Checker off built-in
+function call is ignored.
+
+@end deftypefn
+
+@deftypefn {Built-in Function} void __builtin___bnd_chk_ptr_lbounds (const void * @var{q})
+
+This built-in function checks if the pointer @var{q} is within the lower
+bound of its associated bounds.  With Pointer Bounds Checker off built-in
+function call is ignored.
+
+@smallexample
+extern void *__wrap_memset (void *dst, int c, size_t len)
+@{
+  if (len > 0)
+    @{
+      __builtin___bnd_chk_ptr_lbounds (dst);
+      __builtin___bnd_chk_ptr_ubounds ((char *)dst + len - 1);
+      __real_memset (dst, c, len);
+    @}
+  return dst;
+@}
+@end smallexample
+
+@end deftypefn
+
+@deftypefn {Built-in Function} void __builtin___bnd_chk_ptr_ubounds (const void * @var{q})
+
+This built-in function checks if the pointer @var{q} is within the upper
+bound of its associated bounds.  With Pointer Bounds Checker off built-in
+function call is ignored.
+
+@end deftypefn
+
+@deftypefn {Built-in Function} void __builtin___bnd_chk_ptr_bounds (const void * @var{q}, size_t @var{size})
+
+This built-in function checks if [@var{q}, @var{q} + @var{size} - 1] is within
+the lower and upper bounds associated with @var{q}.  With Pointer Bounds Checker
+off built-in function call is ignored.
+
+@smallexample
+extern void *__wrap_memcpy (void *dst, const void *src, size_t n)
+@{
+  if (n > 0)
+    @{
+      __bnd_chk_ptr_bounds (dst, n);
+      __bnd_chk_ptr_bounds (src, n);
+      __real_memcpy (dst, src, n);
+    @}
+  return dst;
+@}
+@end smallexample
+
+@end deftypefn
+
+@deftypefn {Built-in Function} const void * __builtin___bnd_get_ptr_lbound (const void * @var{q})
+
+This built-in function returns the lower bound (which is a pointer) associated
+with the pointer @var{q}.  This is at least useful for debugging using printf.
+With Pointer Bounds Checker off built-in function returns 0.
+
+@smallexample
+void *lb = __builtin___bnd_get_ptr_lbound (q);
+void *ub = __builtin___bnd_get_ptr_ubound (q);
+printf ("q = %p  lb(q) = %p  ub(q) = %p", q, lb, ub);
+@end smallexample
+
+@end deftypefn
+
+@deftypefn {Built-in Function} const void * __builtin___bnd_get_ptr_ubound (const void * @var{q})
+
+This built-in function returns the upper bound (which is a pointer) associated
+with the pointer @var{q}.  With Pointer Bounds Checker off built-in function
+returns -1.
+
+@end deftypefn
+
 @node Cilk Plus Builtins
 @section Cilk Plus C/C++ language extension Built-in Functions.
 
diff --git a/gcc/toplev.c b/gcc/toplev.c
index 0f7d452..660a10b 100644
--- a/gcc/toplev.c
+++ b/gcc/toplev.c
@@ -1285,6 +1285,12 @@ process_options (void)
 	   "and -ftree-loop-linear)");
 #endif
 
+  if (flag_check_pointer_bounds)
+    {
+      if (targetm.chkp_bound_mode () == VOIDmode)
+	error ("-fcheck-pointer-bounds is not supported for this target");
+    }
+
   /* One region RA really helps to decrease the code size.  */
   if (flag_ira_region == IRA_REGION_AUTODETECT)
     flag_ira_region
diff --git a/gcc/tree-core.h b/gcc/tree-core.h
index 1719c7e..b70c262 100644
--- a/gcc/tree-core.h
+++ b/gcc/tree-core.h
@@ -457,6 +457,8 @@ enum tree_index {
   TI_FILEPTR_TYPE,
   TI_POINTER_SIZED_TYPE,
 
+  TI_POINTER_BOUNDS_TYPE,
+
   TI_DFLOAT32_TYPE,
   TI_DFLOAT64_TYPE,
   TI_DFLOAT128_TYPE,
diff --git a/gcc/tree.c b/gcc/tree.c
index 6a2ca1c..f9aa80f 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -9694,6 +9694,8 @@ build_common_tree_nodes (bool signed_char, bool short_double)
   void_type_node = make_node (VOID_TYPE);
   layout_type (void_type_node);
 
+  pointer_bounds_type_node = targetm.chkp_bound_type ();
+
   /* We are not going to have real types in C with less than byte alignment,
      so we might as well not have any types that claim to have it.  */
   TYPE_ALIGN (void_type_node) = BITS_PER_UNIT;
diff --git a/gcc/tree.h b/gcc/tree.h
index f347b9b..801d564 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -3242,6 +3242,8 @@ tree_operand_check_code (const_tree __t, enum tree_code __code, int __i,
 #define complex_double_type_node	global_trees[TI_COMPLEX_DOUBLE_TYPE]
 #define complex_long_double_type_node	global_trees[TI_COMPLEX_LONG_DOUBLE_TYPE]
 
+#define pointer_bounds_type_node        global_trees[TI_POINTER_BOUNDS_TYPE]
+
 #define void_type_node			global_trees[TI_VOID_TYPE]
 /* The C type `void *'.  */
 #define ptr_type_node			global_trees[TI_PTR_TYPE]

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH, Pointer Bounds Checker 4/x] Built-in functions
  2014-04-16 12:22 [PATCH, Pointer Bounds Checker 4/x] Built-in functions Ilya Enkovich
@ 2014-05-06 12:11 ` Ilya Enkovich
  2014-06-27  8:11   ` Ilya Enkovich
  2014-07-18  6:17 ` Jeff Law
  1 sibling, 1 reply; 4+ messages in thread
From: Ilya Enkovich @ 2014-05-06 12:11 UTC (permalink / raw)
  To: gcc-patches

PING

2014-04-16 16:19 GMT+04:00 Ilya Enkovich <enkovich.gnu@gmail.com>:
> Hi,
>
> This patch introduces built-in functions used by Pointer Bounds Checker.  It is mostly similar to what was reverted from 4.9, I just added types and attributes to builtins.  This patch also introduces pointer_bounds_type_node to be used in built-in function type declarations.
>
> Bootstrapped and tested on linux-x86_64.
>
> OK for trunk?
>
> Thanks,
> Ilya
> --
> gcc/
>
> 2014-04-16  Ilya Enkovich  <ilya.enkovich@intel.com>
>
>         * tree-core.h (tree_index): Add TI_POINTER_BOUNDS_TYPE.
>         * tree.h (pointer_bounds_type_node): New.
>         * tree.c (build_common_tree_nodes): Initialize
>         pointer_bounds_type_node.
>         * builtin-types.def (BT_BND): New.
>         (BT_FN_PTR_CONST_PTR): New.
>         (BT_FN_CONST_PTR_CONST_PTR): New.
>         (BT_FN_BND_CONST_PTR): New.
>         (BT_FN_CONST_PTR_BND): New.
>         (BT_FN_PTR_CONST_PTR_SIZE): New.
>         (BT_FN_PTR_CONST_PTR_CONST_PTR): New.
>         (BT_FN_VOID_PTRPTR_CONST_PTR): New.
>         (BT_FN_VOID_CONST_PTR_SIZE): New.
>         (BT_FN_VOID_PTR_BND): New.
>         (BT_FN_CONST_PTR_CONST_PTR_CONST_PTR): New.
>         (BT_FN_BND_CONST_PTR_SIZE): New.
>         (BT_FN_PTR_CONST_PTR_CONST_PTR_SIZE): New.
>         (BT_FN_VOID_CONST_PTR_BND_CONST_PTR): New.
>         * chkp-builtins.def: New.
>         * builtins.def: include chkp-builtins.def.
>         (DEF_CHKP_BUILTIN): New.
>         * builtins.c (expand_builtin): Support BUILT_IN_CHKP_INIT_PTR_BOUNDS,
>         BUILT_IN_CHKP_NULL_PTR_BOUNDS, BUILT_IN_CHKP_COPY_PTR_BOUNDS,
>         BUILT_IN_CHKP_CHECK_PTR_LBOUNDS, BUILT_IN_CHKP_CHECK_PTR_UBOUNDS,
>         BUILT_IN_CHKP_CHECK_PTR_BOUNDS, BUILT_IN_CHKP_SET_PTR_BOUNDS,
>         BUILT_IN_CHKP_NARROW_PTR_BOUNDS, BUILT_IN_CHKP_STORE_PTR_BOUNDS,
>         BUILT_IN_CHKP_GET_PTR_LBOUND, BUILT_IN_CHKP_GET_PTR_UBOUND,
>         BUILT_IN_CHKP_BNDMK, BUILT_IN_CHKP_BNDSTX, BUILT_IN_CHKP_BNDCL,
>         BUILT_IN_CHKP_BNDCU, BUILT_IN_CHKP_BNDLDX, BUILT_IN_CHKP_BNDRET,
>         BUILT_IN_CHKP_INTERSECT, BUILT_IN_CHKP_NARROW,
>         BUILT_IN_CHKP_EXTRACT_LOWER, BUILT_IN_CHKP_EXTRACT_UPPER.
>         * c-family/c.opt (fcheck-pointer-bounds): New.
>         * toplev.c (process_options): Check Pointer Bounds Checker is supported.
>         * doc/extend.texi: Document Pointer Bounds Checker built-in functions.
>
>
> diff --git a/gcc/builtin-types.def b/gcc/builtin-types.def
> index fba9c7d..2e5f361 100644
> --- a/gcc/builtin-types.def
> +++ b/gcc/builtin-types.def
> @@ -133,6 +133,8 @@ DEF_PRIMITIVE_TYPE (BT_I4, builtin_type_for_size (BITS_PER_UNIT*4, 1))
>  DEF_PRIMITIVE_TYPE (BT_I8, builtin_type_for_size (BITS_PER_UNIT*8, 1))
>  DEF_PRIMITIVE_TYPE (BT_I16, builtin_type_for_size (BITS_PER_UNIT*16, 1))
>
> +DEF_PRIMITIVE_TYPE (BT_BND, pointer_bounds_type_node)
> +
>  DEF_POINTER_TYPE (BT_PTR_CONST_STRING, BT_CONST_STRING)
>  DEF_POINTER_TYPE (BT_PTR_LONG, BT_LONG)
>  DEF_POINTER_TYPE (BT_PTR_ULONGLONG, BT_ULONGLONG)
> @@ -234,6 +236,10 @@ DEF_FUNCTION_TYPE_1 (BT_FN_UINT16_UINT16, BT_UINT16, BT_UINT16)
>  DEF_FUNCTION_TYPE_1 (BT_FN_UINT32_UINT32, BT_UINT32, BT_UINT32)
>  DEF_FUNCTION_TYPE_1 (BT_FN_UINT64_UINT64, BT_UINT64, BT_UINT64)
>  DEF_FUNCTION_TYPE_1 (BT_FN_BOOL_INT, BT_BOOL, BT_INT)
> +DEF_FUNCTION_TYPE_1 (BT_FN_PTR_CONST_PTR, BT_PTR, BT_CONST_PTR)
> +DEF_FUNCTION_TYPE_1 (BT_FN_CONST_PTR_CONST_PTR, BT_CONST_PTR, BT_CONST_PTR)
> +DEF_FUNCTION_TYPE_1 (BT_FN_BND_CONST_PTR, BT_BND, BT_CONST_PTR)
> +DEF_FUNCTION_TYPE_1 (BT_FN_CONST_PTR_BND, BT_CONST_PTR, BT_BND)
>
>  DEF_POINTER_TYPE (BT_PTR_FN_VOID_PTR, BT_FN_VOID_PTR)
>
> @@ -347,6 +353,13 @@ DEF_FUNCTION_TYPE_2 (BT_FN_BOOL_SIZE_CONST_VPTR, BT_BOOL, BT_SIZE,
>                      BT_CONST_VOLATILE_PTR)
>  DEF_FUNCTION_TYPE_2 (BT_FN_BOOL_INT_BOOL, BT_BOOL, BT_INT, BT_BOOL)
>  DEF_FUNCTION_TYPE_2 (BT_FN_VOID_UINT_UINT, BT_VOID, BT_UINT, BT_UINT)
> +DEF_FUNCTION_TYPE_2 (BT_FN_PTR_CONST_PTR_SIZE, BT_PTR, BT_CONST_PTR, BT_SIZE)
> +DEF_FUNCTION_TYPE_2 (BT_FN_PTR_CONST_PTR_CONST_PTR, BT_PTR, BT_CONST_PTR, BT_CONST_PTR)
> +DEF_FUNCTION_TYPE_2 (BT_FN_VOID_PTRPTR_CONST_PTR, BT_VOID, BT_PTR_PTR, BT_CONST_PTR)
> +DEF_FUNCTION_TYPE_2 (BT_FN_VOID_CONST_PTR_SIZE, BT_VOID, BT_CONST_PTR, BT_SIZE)
> +DEF_FUNCTION_TYPE_2 (BT_FN_VOID_PTR_BND, BT_VOID, BT_PTR, BT_BND)
> +DEF_FUNCTION_TYPE_2 (BT_FN_CONST_PTR_CONST_PTR_CONST_PTR, BT_CONST_PTR, BT_CONST_PTR, BT_CONST_PTR)
> +DEF_FUNCTION_TYPE_2 (BT_FN_BND_CONST_PTR_SIZE, BT_BND, BT_CONST_PTR, BT_SIZE)
>
>  DEF_POINTER_TYPE (BT_PTR_FN_VOID_PTR_PTR, BT_FN_VOID_PTR_PTR)
>
> @@ -430,6 +443,8 @@ DEF_FUNCTION_TYPE_3 (BT_FN_VOID_VPTR_I4_INT, BT_VOID, BT_VOLATILE_PTR, BT_I4, BT
>  DEF_FUNCTION_TYPE_3 (BT_FN_VOID_VPTR_I8_INT, BT_VOID, BT_VOLATILE_PTR, BT_I8, BT_INT)
>  DEF_FUNCTION_TYPE_3 (BT_FN_VOID_VPTR_I16_INT, BT_VOID, BT_VOLATILE_PTR, BT_I16, BT_INT)
>  DEF_FUNCTION_TYPE_3 (BT_FN_INT_PTRPTR_SIZE_SIZE, BT_INT, BT_PTR_PTR, BT_SIZE, BT_SIZE)
> +DEF_FUNCTION_TYPE_3 (BT_FN_PTR_CONST_PTR_CONST_PTR_SIZE, BT_PTR, BT_CONST_PTR, BT_CONST_PTR, BT_SIZE)
> +DEF_FUNCTION_TYPE_3 (BT_FN_VOID_CONST_PTR_BND_CONST_PTR, BT_VOID, BT_CONST_PTR, BT_BND, BT_CONST_PTR)
>
>  DEF_FUNCTION_TYPE_4 (BT_FN_SIZE_CONST_PTR_SIZE_SIZE_FILEPTR,
>                      BT_SIZE, BT_CONST_PTR, BT_SIZE, BT_SIZE, BT_FILEPTR)
> diff --git a/gcc/builtins.c b/gcc/builtins.c
> index dd57b1a..5ec6cb6 100644
> --- a/gcc/builtins.c
> +++ b/gcc/builtins.c
> @@ -5810,7 +5810,19 @@ expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode,
>        && fcode != BUILT_IN_EXECVE
>        && fcode != BUILT_IN_ALLOCA
>        && fcode != BUILT_IN_ALLOCA_WITH_ALIGN
> -      && fcode != BUILT_IN_FREE)
> +      && fcode != BUILT_IN_FREE
> +      && fcode != BUILT_IN_CHKP_SET_PTR_BOUNDS
> +      && fcode != BUILT_IN_CHKP_INIT_PTR_BOUNDS
> +      && fcode != BUILT_IN_CHKP_NULL_PTR_BOUNDS
> +      && fcode != BUILT_IN_CHKP_COPY_PTR_BOUNDS
> +      && fcode != BUILT_IN_CHKP_NARROW_PTR_BOUNDS
> +      && fcode != BUILT_IN_CHKP_STORE_PTR_BOUNDS
> +      && fcode != BUILT_IN_CHKP_CHECK_PTR_LBOUNDS
> +      && fcode != BUILT_IN_CHKP_CHECK_PTR_UBOUNDS
> +      && fcode != BUILT_IN_CHKP_CHECK_PTR_BOUNDS
> +      && fcode != BUILT_IN_CHKP_GET_PTR_LBOUND
> +      && fcode != BUILT_IN_CHKP_GET_PTR_UBOUND
> +      && fcode != BUILT_IN_CHKP_BNDRET)
>      return expand_call (exp, target, ignore);
>
>    /* The built-in function expanders test for target == const0_rtx
> @@ -6848,6 +6860,51 @@ expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode,
>        expand_builtin_cilk_pop_frame (exp);
>        return const0_rtx;
>
> +    case BUILT_IN_CHKP_INIT_PTR_BOUNDS:
> +    case BUILT_IN_CHKP_NULL_PTR_BOUNDS:
> +    case BUILT_IN_CHKP_COPY_PTR_BOUNDS:
> +    case BUILT_IN_CHKP_CHECK_PTR_LBOUNDS:
> +    case BUILT_IN_CHKP_CHECK_PTR_UBOUNDS:
> +    case BUILT_IN_CHKP_CHECK_PTR_BOUNDS:
> +    case BUILT_IN_CHKP_SET_PTR_BOUNDS:
> +    case BUILT_IN_CHKP_NARROW_PTR_BOUNDS:
> +    case BUILT_IN_CHKP_STORE_PTR_BOUNDS:
> +    case BUILT_IN_CHKP_GET_PTR_LBOUND:
> +    case BUILT_IN_CHKP_GET_PTR_UBOUND:
> +      /* We allow user CHKP builtins if Pointer Bounds
> +        Checker is off.  */
> +      if (!flag_check_pointer_bounds)
> +       {
> +         if (fcode == BUILT_IN_CHKP_SET_PTR_BOUNDS
> +             || fcode == BUILT_IN_CHKP_NARROW_PTR_BOUNDS
> +             || fcode == BUILT_IN_CHKP_INIT_PTR_BOUNDS
> +             || fcode == BUILT_IN_CHKP_NULL_PTR_BOUNDS
> +             || fcode == BUILT_IN_CHKP_COPY_PTR_BOUNDS)
> +           return expand_normal (CALL_EXPR_ARG (exp, 0));
> +         else if (fcode == BUILT_IN_CHKP_GET_PTR_LBOUND)
> +           return expand_normal (size_zero_node);
> +         else if (fcode == BUILT_IN_CHKP_GET_PTR_UBOUND)
> +           return expand_normal (size_int (-1));
> +         else
> +           return const0_rtx;
> +       }
> +      /* FALLTHROUGH */
> +
> +    case BUILT_IN_CHKP_BNDMK:
> +    case BUILT_IN_CHKP_BNDSTX:
> +    case BUILT_IN_CHKP_BNDCL:
> +    case BUILT_IN_CHKP_BNDCU:
> +    case BUILT_IN_CHKP_BNDLDX:
> +    case BUILT_IN_CHKP_BNDRET:
> +    case BUILT_IN_CHKP_INTERSECT:
> +    case BUILT_IN_CHKP_NARROW:
> +    case BUILT_IN_CHKP_EXTRACT_LOWER:
> +    case BUILT_IN_CHKP_EXTRACT_UPPER:
> +      /* Software implementation of Pointer Bounds Checker is NYI.
> +        Target support is required.  */
> +      error ("Your target platform does not support -fcheck-pointer-bounds");
> +      break;
> +
>      default:   /* just do library call, if unknown builtin */
>        break;
>      }
> diff --git a/gcc/builtins.def b/gcc/builtins.def
> index 5a76ba3..ed2617e 100644
> --- a/gcc/builtins.def
> +++ b/gcc/builtins.def
> @@ -176,6 +176,12 @@ along with GCC; see the file COPYING3.  If not see
>    DEF_BUILTIN (ENUM, NAME, BUILT_IN_NORMAL, BT_FN_INT_VAR, BT_LAST, \
>                false, false, false, ATTRS, false, flag_cilkplus)
>
> +/* Builtin used by the implementation of Pointer Bounds Checker.  */
> +#undef DEF_CHKP_BUILTIN
> +#define DEF_CHKP_BUILTIN(ENUM, NAME, TYPE, ATTRS) \
> +  DEF_BUILTIN (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE, TYPE,    \
> +              true, true, false, ATTRS, true, true)
> +
>  /* Define an attribute list for math functions that are normally
>     "impure" because some of them may write into global memory for
>     `errno'.  If !flag_errno_math they are instead "const".  */
> @@ -870,3 +876,6 @@ DEF_GCC_BUILTIN (BUILT_IN_LINE, "LINE", BT_FN_INT, ATTR_NOTHROW_LEAF_LIST)
>
>  /* Cilk Plus builtins.  */
>  #include "cilkplus.def"
> +
> +/* Pointer Bounds Checker builtins.  */
> +#include "chkp-builtins.def"
> diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt
> index 390c056..3ec5cda 100644
> --- a/gcc/c-family/c.opt
> +++ b/gcc/c-family/c.opt
> @@ -866,6 +866,11 @@ fcanonical-system-headers
>  C ObjC C++ ObjC++
>  Where shorter, use canonicalized paths to systems headers.
>
> +fcheck-pointer-bounds
> +Common Report Var(flag_check_pointer_bounds)
> +Add Pointer Bounds Checker instrumentation.  fchkp-* flags are used to
> +control instrumentation.  Currently available for C, C++ and ObjC.
> +
>  fcilkplus
>  C ObjC C++ ObjC++ LTO Report Var(flag_cilkplus) Init(0)
>  Enable Cilk Plus
> diff --git a/gcc/chkp-builtins.def b/gcc/chkp-builtins.def
> new file mode 100644
> index 0000000..cae0332
> --- /dev/null
> +++ b/gcc/chkp-builtins.def
> @@ -0,0 +1,71 @@
> +/* This file contains the definitions and documentation for the
> +   builtins used in the GNU compiler.
> +   Copyright (C) 2013 Free Software Foundation, Inc.
> +
> +This file is part of GCC.
> +
> +GCC is free software; you can redistribute it and/or modify it under
> +the terms of the GNU General Public License as published by the Free
> +Software Foundation; either version 3, or (at your option) any later
> +version.
> +
> +GCC is distributed in the hope that it will be useful, but WITHOUT ANY
> +WARRANTY; without even the implied warranty of MERCHANTABILITY or
> +FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
> +for more details.
> +
> +You should have received a copy of the GNU General Public License
> +along with GCC; see the file COPYING3.  If not see
> +<http://www.gnu.org/licenses/>.  */
> +
> +/* Before including this file, you should define macros:
> +
> +      DEF_BUILTIN_STUB(ENUM, NAME)
> +      DEF_CHKP_BUILTIN(ENUM, NAME, TYPE, ATTRS)
> +
> +   See builtins.def for details.  */
> +
> +/* Following builtins are used by compiler for Pointer Bounds Checker
> +   instrumentation.  Currently these generic builtins are not
> +   implemented and target has to provide his own version.  See
> +   builtin_chkp_function target hook documentation for more details.  */
> +DEF_BUILTIN_STUB (BUILT_IN_CHKP_INTERSECT, "__chkp_intersect")
> +DEF_BUILTIN_STUB (BUILT_IN_CHKP_SIZEOF, "__chkp_sizeof")
> +DEF_BUILTIN_STUB (BUILT_IN_CHKP_NARROW, "__chkp_narrow")
> +DEF_CHKP_BUILTIN (BUILT_IN_CHKP_BNDCL, "__chkp_bndcl", BT_FN_VOID_PTR_BND, ATTR_NOTHROW_LEAF_LIST)
> +DEF_CHKP_BUILTIN (BUILT_IN_CHKP_BNDCU, "__chkp_bndcu", BT_FN_VOID_PTR_BND, ATTR_NOTHROW_LEAF_LIST)
> +DEF_CHKP_BUILTIN (BUILT_IN_CHKP_BNDSTX, "__chkp_bndstx", BT_FN_VOID_CONST_PTR_BND_CONST_PTR, ATTR_NOTHROW_LEAF_LIST)
> +DEF_CHKP_BUILTIN (BUILT_IN_CHKP_BNDLDX, "__chkp_bndldx", BT_FN_CONST_PTR_CONST_PTR_CONST_PTR, ATTR_NOTHROW_LEAF_LIST)
> +DEF_CHKP_BUILTIN (BUILT_IN_CHKP_BNDRET, "__chkp_bndret", BT_FN_BND_CONST_PTR, ATTR_CONST_NOTHROW_LEAF_LIST)
> +DEF_CHKP_BUILTIN (BUILT_IN_CHKP_BNDMK, "__chkp_bndmk", BT_FN_BND_CONST_PTR_SIZE, ATTR_CONST_NOTHROW_LEAF_LIST)
> +DEF_CHKP_BUILTIN (BUILT_IN_CHKP_EXTRACT_LOWER, "__chkp_extract_lower", BT_FN_CONST_PTR_BND, ATTR_CONST_NOTHROW_LEAF_LIST)
> +DEF_CHKP_BUILTIN (BUILT_IN_CHKP_EXTRACT_UPPER, "__chkp_extract_upper", BT_FN_CONST_PTR_BND, ATTR_CONST_NOTHROW_LEAF_LIST)
> +
> +/* Pointer Bounds Checker builtins for users.
> +   All builtins calls are expanded in the
> +   Pointer Bounds Checker pass.  */
> +DEF_CHKP_BUILTIN (BUILT_IN_CHKP_SET_PTR_BOUNDS, "__bnd_set_ptr_bounds", BT_FN_PTR_CONST_PTR_SIZE, ATTR_CONST_NOTHROW_LEAF_LIST)
> +DEF_CHKP_BUILTIN (BUILT_IN_CHKP_INIT_PTR_BOUNDS, "__bnd_init_ptr_bounds", BT_FN_PTR_CONST_PTR, ATTR_CONST_NOTHROW_LEAF_LIST)
> +DEF_CHKP_BUILTIN (BUILT_IN_CHKP_NULL_PTR_BOUNDS, "__bnd_null_ptr_bounds", BT_FN_PTR_CONST_PTR, ATTR_CONST_NOTHROW_LEAF_LIST)
> +DEF_CHKP_BUILTIN (BUILT_IN_CHKP_COPY_PTR_BOUNDS, "__bnd_copy_ptr_bounds", BT_FN_PTR_CONST_PTR_CONST_PTR, ATTR_CONST_NOTHROW_LEAF_LIST)
> +DEF_CHKP_BUILTIN (BUILT_IN_CHKP_NARROW_PTR_BOUNDS, "__bnd_narrow_ptr_bounds", BT_FN_PTR_CONST_PTR_CONST_PTR_SIZE, ATTR_CONST_NOTHROW_LEAF_LIST)
> +DEF_CHKP_BUILTIN (BUILT_IN_CHKP_STORE_PTR_BOUNDS, "__bnd_store_ptr_bounds", BT_FN_VOID_PTRPTR_CONST_PTR, ATTR_NOTHROW_LEAF_LIST)
> +DEF_CHKP_BUILTIN (BUILT_IN_CHKP_CHECK_PTR_LBOUNDS, "__bnd_chk_ptr_lbounds", BT_FN_VOID_CONST_PTR, ATTR_NOTHROW_LEAF_LIST)
> +DEF_CHKP_BUILTIN (BUILT_IN_CHKP_CHECK_PTR_UBOUNDS, "__bnd_chk_ptr_ubounds", BT_FN_VOID_CONST_PTR, ATTR_NOTHROW_LEAF_LIST)
> +DEF_CHKP_BUILTIN (BUILT_IN_CHKP_CHECK_PTR_BOUNDS, "__bnd_chk_ptr_bounds", BT_FN_VOID_CONST_PTR_SIZE, ATTR_NOTHROW_LEAF_LIST)
> +DEF_CHKP_BUILTIN (BUILT_IN_CHKP_GET_PTR_LBOUND, "__bnd_get_ptr_lbound", BT_FN_CONST_PTR_CONST_PTR, ATTR_CONST_NOTHROW_LEAF_LIST)
> +DEF_CHKP_BUILTIN (BUILT_IN_CHKP_GET_PTR_UBOUND, "__bnd_get_ptr_ubound", BT_FN_CONST_PTR_CONST_PTR, ATTR_CONST_NOTHROW_LEAF_LIST)
> +
> +/* Pointer Bounds Checker specific versions of string functions.  */
> +DEF_CHKP_BUILTIN (BUILT_IN_CHKP_MEMCPY_NOBND, "chkp_memcpy_nobnd", BT_FN_PTR_PTR_CONST_PTR_SIZE, ATTR_RET1_NOTHROW_NONNULL_LEAF)
> +DEF_CHKP_BUILTIN (BUILT_IN_CHKP_MEMCPY_NOCHK, "chkp_memcpy_nochk", BT_FN_PTR_PTR_CONST_PTR_SIZE, ATTR_RET1_NOTHROW_NONNULL_LEAF)
> +DEF_CHKP_BUILTIN (BUILT_IN_CHKP_MEMCPY_NOBND_NOCHK, "chkp_memcpy_nobnd_nochk", BT_FN_PTR_PTR_CONST_PTR_SIZE, ATTR_RET1_NOTHROW_NONNULL_LEAF)
> +DEF_CHKP_BUILTIN (BUILT_IN_CHKP_MEMMOVE_NOBND, "chkp_memmove_nobnd", BT_FN_PTR_PTR_CONST_PTR_SIZE, ATTR_RET1_NOTHROW_NONNULL_LEAF)
> +DEF_CHKP_BUILTIN (BUILT_IN_CHKP_MEMMOVE_NOCHK, "chkp_memmove_nochk", BT_FN_PTR_PTR_CONST_PTR_SIZE, ATTR_RET1_NOTHROW_NONNULL_LEAF)
> +DEF_CHKP_BUILTIN (BUILT_IN_CHKP_MEMMOVE_NOBND_NOCHK, "chkp_memmove_nobnd_nochk", BT_FN_PTR_PTR_CONST_PTR_SIZE, ATTR_RET1_NOTHROW_NONNULL_LEAF)
> +DEF_CHKP_BUILTIN (BUILT_IN_CHKP_MEMPCPY_NOBND, "chkp_mempcpy_nobnd", BT_FN_PTR_PTR_CONST_PTR_SIZE, ATTR_NOTHROW_NONNULL_LEAF)
> +DEF_CHKP_BUILTIN (BUILT_IN_CHKP_MEMPCPY_NOCHK, "chkp_mempcpy_nochk", BT_FN_PTR_PTR_CONST_PTR_SIZE, ATTR_NOTHROW_NONNULL_LEAF)
> +DEF_CHKP_BUILTIN (BUILT_IN_CHKP_MEMPCPY_NOBND_NOCHK, "chkp_mempcpy_nobnd_nochk", BT_FN_PTR_PTR_CONST_PTR_SIZE, ATTR_NOTHROW_NONNULL_LEAF)
> +DEF_CHKP_BUILTIN (BUILT_IN_CHKP_MEMSET_NOBND, "chkp_memset_nobnd", BT_FN_PTR_PTR_INT_SIZE, ATTR_RET1_NOTHROW_NONNULL_LEAF)
> +DEF_CHKP_BUILTIN (BUILT_IN_CHKP_MEMSET_NOCHK, "chkp_memset_nochk", BT_FN_PTR_PTR_INT_SIZE, ATTR_RET1_NOTHROW_NONNULL_LEAF)
> +DEF_CHKP_BUILTIN (BUILT_IN_CHKP_MEMSET_NOBND_NOCHK, "chkp_memset_nobnd_nochk", BT_FN_PTR_PTR_INT_SIZE, ATTR_RET1_NOTHROW_NONNULL_LEAF)
> diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
> index 347a94a..1c74990 100644
> --- a/gcc/doc/extend.texi
> +++ b/gcc/doc/extend.texi
> @@ -82,6 +82,7 @@ extensions, accepted by GCC in C90 mode and in C++.
>  * x86 specific memory model extensions for transactional memory:: x86 memory models.
>  * Object Size Checking:: Built-in functions for limited buffer overflow
>                          checking.
> +* Pointer Bounds Checker builtins:: Built-in functions for Pointer Bounds Checker.
>  * Cilk Plus Builtins::  Built-in functions for the Cilk Plus language extension.
>  * Other Builtins::      Other built-in functions.
>  * Target Builtins::     Built-in functions specific to particular targets.
> @@ -7945,6 +7946,176 @@ format string @var{fmt}.  If the compiler is able to optimize them to
>  @code{fputc} etc.@: functions, it does, otherwise the checking function
>  is called and the @var{flag} argument passed to it.
>
> +@node Pointer Bounds Checker builtins
> +@section Pointer Bounds Checker Built-in Functions
> +@findex __builtin___bnd_set_ptr_bounds
> +@findex __builtin___bnd_narrow_ptr_bounds
> +@findex __builtin___bnd_copy_ptr_bounds
> +@findex __builtin___bnd_init_ptr_bounds
> +@findex __builtin___bnd_null_ptr_bounds
> +@findex __builtin___bnd_store_ptr_bounds
> +@findex __builtin___bnd_chk_ptr_lbounds
> +@findex __builtin___bnd_chk_ptr_ubounds
> +@findex __builtin___bnd_chk_ptr_bounds
> +@findex __builtin___bnd_get_ptr_lbound
> +@findex __builtin___bnd_get_ptr_ubound
> +
> +GCC provides a set of built-in functions to control Pointer Bounds Checker
> +instrumentation.  Note that all Pointer Bounds Checker builtins are allowed
> +to use even if you compile with Pointer Bounds Checker off.  The builtins
> +behavior may differ in such case as documented below.
> +
> +@deftypefn {Built-in Function} void * __builtin___bnd_set_ptr_bounds (const void * @var{q}, size_t @var{size})
> +
> +This built-in function returns a new pointer with the value of @var{q}, and
> +associate it with the bounds [@var{q}, @var{q}+@var{size}-1].  With Pointer
> +Bounds Checker off built-in function just returns the first argument.
> +
> +@smallexample
> +extern void *__wrap_malloc (size_t n)
> +@{
> +  void *p = (void *)__real_malloc (n);
> +  if (!p) return __builtin___bnd_null_ptr_bounds (p);
> +  return __builtin___bnd_set_ptr_bounds (p, n);
> +@}
> +@end smallexample
> +
> +@end deftypefn
> +
> +@deftypefn {Built-in Function} void * __builtin___bnd_narrow_ptr_bounds (const void * @var{p}, const void * @var{q}, size_t  @var{size})
> +
> +This built-in function returns a new pointer with the value of @var{p}
> +and associate it with the narrowed bounds formed by the intersection
> +of bounds associated with @var{q} and the [@var{p}, @var{p} + @var{size} - 1].
> +With Pointer Bounds Checker off built-in function just returns the first
> +argument.
> +
> +@smallexample
> +void init_objects (object *objs, size_t size)
> +@{
> +  size_t i;
> +  /* Initialize objects one-by-one passing pointers with bounds of an object,
> +     not the full array of objects.  */
> +  for (i = 0; i < size; i++)
> +    init_object (__builtin___bnd_narrow_ptr_bounds (objs + i, objs, sizeof(object)));
> +@}
> +@end smallexample
> +
> +@end deftypefn
> +
> +@deftypefn {Built-in Function} void * __builtin___bnd_copy_ptr_bounds (const void * @var{q}, const void * @var{r})
> +
> +This built-in function returns a new pointer with the value of @var{q},
> +and associate it with the bounds already associated with pointer @var{r}.
> +With Pointer Bounds Checker off built-in function just returns the first
> +argument.
> +
> +@smallexample
> +/* Here is a way to get pointer to object's field but
> +   still with the full object's bounds.  */
> +int *field_ptr = __builtin___bnd_copy_ptr_bounds (&objptr->int_filed, objptr);
> +@end smallexample
> +
> +@end deftypefn
> +
> +@deftypefn {Built-in Function} void * __builtin___bnd_init_ptr_bounds (const void * @var{q})
> +
> +This built-in function returns a new pointer with the value of @var{q}, and
> +associate it with INIT (allowing full memory access) bounds. With Pointer
> +Bounds Checker off built-in function just returns the first argument.
> +
> +@end deftypefn
> +
> +@deftypefn {Built-in Function} void * __builtin___bnd_null_ptr_bounds (const void * @var{q})
> +
> +This built-in function returns a new pointer with the value of @var{q}, and
> +associate it with NULL (allowing no memory access) bounds. With Pointer
> +Bounds Checker off built-in function just returns the first argument.
> +
> +@end deftypefn
> +
> +@deftypefn {Built-in Function} void __builtin___bnd_store_ptr_bounds (const void ** @var{ptr_addr}, const void * @var{ptr_val})
> +
> +This built-in function stores the bounds associated with pointer @var{ptr_val}
> +and location @var{ptr_addr} into Bounds Table.  This can be useful to propagate
> +bounds from legacy code without touching the associated pointer's memory when
> +pointers were copied as integers.  With Pointer Bounds Checker off built-in
> +function call is ignored.
> +
> +@end deftypefn
> +
> +@deftypefn {Built-in Function} void __builtin___bnd_chk_ptr_lbounds (const void * @var{q})
> +
> +This built-in function checks if the pointer @var{q} is within the lower
> +bound of its associated bounds.  With Pointer Bounds Checker off built-in
> +function call is ignored.
> +
> +@smallexample
> +extern void *__wrap_memset (void *dst, int c, size_t len)
> +@{
> +  if (len > 0)
> +    @{
> +      __builtin___bnd_chk_ptr_lbounds (dst);
> +      __builtin___bnd_chk_ptr_ubounds ((char *)dst + len - 1);
> +      __real_memset (dst, c, len);
> +    @}
> +  return dst;
> +@}
> +@end smallexample
> +
> +@end deftypefn
> +
> +@deftypefn {Built-in Function} void __builtin___bnd_chk_ptr_ubounds (const void * @var{q})
> +
> +This built-in function checks if the pointer @var{q} is within the upper
> +bound of its associated bounds.  With Pointer Bounds Checker off built-in
> +function call is ignored.
> +
> +@end deftypefn
> +
> +@deftypefn {Built-in Function} void __builtin___bnd_chk_ptr_bounds (const void * @var{q}, size_t @var{size})
> +
> +This built-in function checks if [@var{q}, @var{q} + @var{size} - 1] is within
> +the lower and upper bounds associated with @var{q}.  With Pointer Bounds Checker
> +off built-in function call is ignored.
> +
> +@smallexample
> +extern void *__wrap_memcpy (void *dst, const void *src, size_t n)
> +@{
> +  if (n > 0)
> +    @{
> +      __bnd_chk_ptr_bounds (dst, n);
> +      __bnd_chk_ptr_bounds (src, n);
> +      __real_memcpy (dst, src, n);
> +    @}
> +  return dst;
> +@}
> +@end smallexample
> +
> +@end deftypefn
> +
> +@deftypefn {Built-in Function} const void * __builtin___bnd_get_ptr_lbound (const void * @var{q})
> +
> +This built-in function returns the lower bound (which is a pointer) associated
> +with the pointer @var{q}.  This is at least useful for debugging using printf.
> +With Pointer Bounds Checker off built-in function returns 0.
> +
> +@smallexample
> +void *lb = __builtin___bnd_get_ptr_lbound (q);
> +void *ub = __builtin___bnd_get_ptr_ubound (q);
> +printf ("q = %p  lb(q) = %p  ub(q) = %p", q, lb, ub);
> +@end smallexample
> +
> +@end deftypefn
> +
> +@deftypefn {Built-in Function} const void * __builtin___bnd_get_ptr_ubound (const void * @var{q})
> +
> +This built-in function returns the upper bound (which is a pointer) associated
> +with the pointer @var{q}.  With Pointer Bounds Checker off built-in function
> +returns -1.
> +
> +@end deftypefn
> +
>  @node Cilk Plus Builtins
>  @section Cilk Plus C/C++ language extension Built-in Functions.
>
> diff --git a/gcc/toplev.c b/gcc/toplev.c
> index 0f7d452..660a10b 100644
> --- a/gcc/toplev.c
> +++ b/gcc/toplev.c
> @@ -1285,6 +1285,12 @@ process_options (void)
>            "and -ftree-loop-linear)");
>  #endif
>
> +  if (flag_check_pointer_bounds)
> +    {
> +      if (targetm.chkp_bound_mode () == VOIDmode)
> +       error ("-fcheck-pointer-bounds is not supported for this target");
> +    }
> +
>    /* One region RA really helps to decrease the code size.  */
>    if (flag_ira_region == IRA_REGION_AUTODETECT)
>      flag_ira_region
> diff --git a/gcc/tree-core.h b/gcc/tree-core.h
> index 1719c7e..b70c262 100644
> --- a/gcc/tree-core.h
> +++ b/gcc/tree-core.h
> @@ -457,6 +457,8 @@ enum tree_index {
>    TI_FILEPTR_TYPE,
>    TI_POINTER_SIZED_TYPE,
>
> +  TI_POINTER_BOUNDS_TYPE,
> +
>    TI_DFLOAT32_TYPE,
>    TI_DFLOAT64_TYPE,
>    TI_DFLOAT128_TYPE,
> diff --git a/gcc/tree.c b/gcc/tree.c
> index 6a2ca1c..f9aa80f 100644
> --- a/gcc/tree.c
> +++ b/gcc/tree.c
> @@ -9694,6 +9694,8 @@ build_common_tree_nodes (bool signed_char, bool short_double)
>    void_type_node = make_node (VOID_TYPE);
>    layout_type (void_type_node);
>
> +  pointer_bounds_type_node = targetm.chkp_bound_type ();
> +
>    /* We are not going to have real types in C with less than byte alignment,
>       so we might as well not have any types that claim to have it.  */
>    TYPE_ALIGN (void_type_node) = BITS_PER_UNIT;
> diff --git a/gcc/tree.h b/gcc/tree.h
> index f347b9b..801d564 100644
> --- a/gcc/tree.h
> +++ b/gcc/tree.h
> @@ -3242,6 +3242,8 @@ tree_operand_check_code (const_tree __t, enum tree_code __code, int __i,
>  #define complex_double_type_node       global_trees[TI_COMPLEX_DOUBLE_TYPE]
>  #define complex_long_double_type_node  global_trees[TI_COMPLEX_LONG_DOUBLE_TYPE]
>
> +#define pointer_bounds_type_node        global_trees[TI_POINTER_BOUNDS_TYPE]
> +
>  #define void_type_node                 global_trees[TI_VOID_TYPE]
>  /* The C type `void *'.  */
>  #define ptr_type_node                  global_trees[TI_PTR_TYPE]

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH, Pointer Bounds Checker 4/x] Built-in functions
  2014-05-06 12:11 ` Ilya Enkovich
@ 2014-06-27  8:11   ` Ilya Enkovich
  0 siblings, 0 replies; 4+ messages in thread
From: Ilya Enkovich @ 2014-06-27  8:11 UTC (permalink / raw)
  To: gcc-patches

Ping

2014-05-06 16:11 GMT+04:00 Ilya Enkovich <enkovich.gnu@gmail.com>:
> PING
>
> 2014-04-16 16:19 GMT+04:00 Ilya Enkovich <enkovich.gnu@gmail.com>:
>> Hi,
>>
>> This patch introduces built-in functions used by Pointer Bounds Checker.  It is mostly similar to what was reverted from 4.9, I just added types and attributes to builtins.  This patch also introduces pointer_bounds_type_node to be used in built-in function type declarations.
>>
>> Bootstrapped and tested on linux-x86_64.
>>
>> OK for trunk?
>>
>> Thanks,
>> Ilya
>> --
>> gcc/
>>
>> 2014-04-16  Ilya Enkovich  <ilya.enkovich@intel.com>
>>
>>         * tree-core.h (tree_index): Add TI_POINTER_BOUNDS_TYPE.
>>         * tree.h (pointer_bounds_type_node): New.
>>         * tree.c (build_common_tree_nodes): Initialize
>>         pointer_bounds_type_node.
>>         * builtin-types.def (BT_BND): New.
>>         (BT_FN_PTR_CONST_PTR): New.
>>         (BT_FN_CONST_PTR_CONST_PTR): New.
>>         (BT_FN_BND_CONST_PTR): New.
>>         (BT_FN_CONST_PTR_BND): New.
>>         (BT_FN_PTR_CONST_PTR_SIZE): New.
>>         (BT_FN_PTR_CONST_PTR_CONST_PTR): New.
>>         (BT_FN_VOID_PTRPTR_CONST_PTR): New.
>>         (BT_FN_VOID_CONST_PTR_SIZE): New.
>>         (BT_FN_VOID_PTR_BND): New.
>>         (BT_FN_CONST_PTR_CONST_PTR_CONST_PTR): New.
>>         (BT_FN_BND_CONST_PTR_SIZE): New.
>>         (BT_FN_PTR_CONST_PTR_CONST_PTR_SIZE): New.
>>         (BT_FN_VOID_CONST_PTR_BND_CONST_PTR): New.
>>         * chkp-builtins.def: New.
>>         * builtins.def: include chkp-builtins.def.
>>         (DEF_CHKP_BUILTIN): New.
>>         * builtins.c (expand_builtin): Support BUILT_IN_CHKP_INIT_PTR_BOUNDS,
>>         BUILT_IN_CHKP_NULL_PTR_BOUNDS, BUILT_IN_CHKP_COPY_PTR_BOUNDS,
>>         BUILT_IN_CHKP_CHECK_PTR_LBOUNDS, BUILT_IN_CHKP_CHECK_PTR_UBOUNDS,
>>         BUILT_IN_CHKP_CHECK_PTR_BOUNDS, BUILT_IN_CHKP_SET_PTR_BOUNDS,
>>         BUILT_IN_CHKP_NARROW_PTR_BOUNDS, BUILT_IN_CHKP_STORE_PTR_BOUNDS,
>>         BUILT_IN_CHKP_GET_PTR_LBOUND, BUILT_IN_CHKP_GET_PTR_UBOUND,
>>         BUILT_IN_CHKP_BNDMK, BUILT_IN_CHKP_BNDSTX, BUILT_IN_CHKP_BNDCL,
>>         BUILT_IN_CHKP_BNDCU, BUILT_IN_CHKP_BNDLDX, BUILT_IN_CHKP_BNDRET,
>>         BUILT_IN_CHKP_INTERSECT, BUILT_IN_CHKP_NARROW,
>>         BUILT_IN_CHKP_EXTRACT_LOWER, BUILT_IN_CHKP_EXTRACT_UPPER.
>>         * c-family/c.opt (fcheck-pointer-bounds): New.
>>         * toplev.c (process_options): Check Pointer Bounds Checker is supported.
>>         * doc/extend.texi: Document Pointer Bounds Checker built-in functions.
>>
>>
>> diff --git a/gcc/builtin-types.def b/gcc/builtin-types.def
>> index fba9c7d..2e5f361 100644
>> --- a/gcc/builtin-types.def
>> +++ b/gcc/builtin-types.def
>> @@ -133,6 +133,8 @@ DEF_PRIMITIVE_TYPE (BT_I4, builtin_type_for_size (BITS_PER_UNIT*4, 1))
>>  DEF_PRIMITIVE_TYPE (BT_I8, builtin_type_for_size (BITS_PER_UNIT*8, 1))
>>  DEF_PRIMITIVE_TYPE (BT_I16, builtin_type_for_size (BITS_PER_UNIT*16, 1))
>>
>> +DEF_PRIMITIVE_TYPE (BT_BND, pointer_bounds_type_node)
>> +
>>  DEF_POINTER_TYPE (BT_PTR_CONST_STRING, BT_CONST_STRING)
>>  DEF_POINTER_TYPE (BT_PTR_LONG, BT_LONG)
>>  DEF_POINTER_TYPE (BT_PTR_ULONGLONG, BT_ULONGLONG)
>> @@ -234,6 +236,10 @@ DEF_FUNCTION_TYPE_1 (BT_FN_UINT16_UINT16, BT_UINT16, BT_UINT16)
>>  DEF_FUNCTION_TYPE_1 (BT_FN_UINT32_UINT32, BT_UINT32, BT_UINT32)
>>  DEF_FUNCTION_TYPE_1 (BT_FN_UINT64_UINT64, BT_UINT64, BT_UINT64)
>>  DEF_FUNCTION_TYPE_1 (BT_FN_BOOL_INT, BT_BOOL, BT_INT)
>> +DEF_FUNCTION_TYPE_1 (BT_FN_PTR_CONST_PTR, BT_PTR, BT_CONST_PTR)
>> +DEF_FUNCTION_TYPE_1 (BT_FN_CONST_PTR_CONST_PTR, BT_CONST_PTR, BT_CONST_PTR)
>> +DEF_FUNCTION_TYPE_1 (BT_FN_BND_CONST_PTR, BT_BND, BT_CONST_PTR)
>> +DEF_FUNCTION_TYPE_1 (BT_FN_CONST_PTR_BND, BT_CONST_PTR, BT_BND)
>>
>>  DEF_POINTER_TYPE (BT_PTR_FN_VOID_PTR, BT_FN_VOID_PTR)
>>
>> @@ -347,6 +353,13 @@ DEF_FUNCTION_TYPE_2 (BT_FN_BOOL_SIZE_CONST_VPTR, BT_BOOL, BT_SIZE,
>>                      BT_CONST_VOLATILE_PTR)
>>  DEF_FUNCTION_TYPE_2 (BT_FN_BOOL_INT_BOOL, BT_BOOL, BT_INT, BT_BOOL)
>>  DEF_FUNCTION_TYPE_2 (BT_FN_VOID_UINT_UINT, BT_VOID, BT_UINT, BT_UINT)
>> +DEF_FUNCTION_TYPE_2 (BT_FN_PTR_CONST_PTR_SIZE, BT_PTR, BT_CONST_PTR, BT_SIZE)
>> +DEF_FUNCTION_TYPE_2 (BT_FN_PTR_CONST_PTR_CONST_PTR, BT_PTR, BT_CONST_PTR, BT_CONST_PTR)
>> +DEF_FUNCTION_TYPE_2 (BT_FN_VOID_PTRPTR_CONST_PTR, BT_VOID, BT_PTR_PTR, BT_CONST_PTR)
>> +DEF_FUNCTION_TYPE_2 (BT_FN_VOID_CONST_PTR_SIZE, BT_VOID, BT_CONST_PTR, BT_SIZE)
>> +DEF_FUNCTION_TYPE_2 (BT_FN_VOID_PTR_BND, BT_VOID, BT_PTR, BT_BND)
>> +DEF_FUNCTION_TYPE_2 (BT_FN_CONST_PTR_CONST_PTR_CONST_PTR, BT_CONST_PTR, BT_CONST_PTR, BT_CONST_PTR)
>> +DEF_FUNCTION_TYPE_2 (BT_FN_BND_CONST_PTR_SIZE, BT_BND, BT_CONST_PTR, BT_SIZE)
>>
>>  DEF_POINTER_TYPE (BT_PTR_FN_VOID_PTR_PTR, BT_FN_VOID_PTR_PTR)
>>
>> @@ -430,6 +443,8 @@ DEF_FUNCTION_TYPE_3 (BT_FN_VOID_VPTR_I4_INT, BT_VOID, BT_VOLATILE_PTR, BT_I4, BT
>>  DEF_FUNCTION_TYPE_3 (BT_FN_VOID_VPTR_I8_INT, BT_VOID, BT_VOLATILE_PTR, BT_I8, BT_INT)
>>  DEF_FUNCTION_TYPE_3 (BT_FN_VOID_VPTR_I16_INT, BT_VOID, BT_VOLATILE_PTR, BT_I16, BT_INT)
>>  DEF_FUNCTION_TYPE_3 (BT_FN_INT_PTRPTR_SIZE_SIZE, BT_INT, BT_PTR_PTR, BT_SIZE, BT_SIZE)
>> +DEF_FUNCTION_TYPE_3 (BT_FN_PTR_CONST_PTR_CONST_PTR_SIZE, BT_PTR, BT_CONST_PTR, BT_CONST_PTR, BT_SIZE)
>> +DEF_FUNCTION_TYPE_3 (BT_FN_VOID_CONST_PTR_BND_CONST_PTR, BT_VOID, BT_CONST_PTR, BT_BND, BT_CONST_PTR)
>>
>>  DEF_FUNCTION_TYPE_4 (BT_FN_SIZE_CONST_PTR_SIZE_SIZE_FILEPTR,
>>                      BT_SIZE, BT_CONST_PTR, BT_SIZE, BT_SIZE, BT_FILEPTR)
>> diff --git a/gcc/builtins.c b/gcc/builtins.c
>> index dd57b1a..5ec6cb6 100644
>> --- a/gcc/builtins.c
>> +++ b/gcc/builtins.c
>> @@ -5810,7 +5810,19 @@ expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode,
>>        && fcode != BUILT_IN_EXECVE
>>        && fcode != BUILT_IN_ALLOCA
>>        && fcode != BUILT_IN_ALLOCA_WITH_ALIGN
>> -      && fcode != BUILT_IN_FREE)
>> +      && fcode != BUILT_IN_FREE
>> +      && fcode != BUILT_IN_CHKP_SET_PTR_BOUNDS
>> +      && fcode != BUILT_IN_CHKP_INIT_PTR_BOUNDS
>> +      && fcode != BUILT_IN_CHKP_NULL_PTR_BOUNDS
>> +      && fcode != BUILT_IN_CHKP_COPY_PTR_BOUNDS
>> +      && fcode != BUILT_IN_CHKP_NARROW_PTR_BOUNDS
>> +      && fcode != BUILT_IN_CHKP_STORE_PTR_BOUNDS
>> +      && fcode != BUILT_IN_CHKP_CHECK_PTR_LBOUNDS
>> +      && fcode != BUILT_IN_CHKP_CHECK_PTR_UBOUNDS
>> +      && fcode != BUILT_IN_CHKP_CHECK_PTR_BOUNDS
>> +      && fcode != BUILT_IN_CHKP_GET_PTR_LBOUND
>> +      && fcode != BUILT_IN_CHKP_GET_PTR_UBOUND
>> +      && fcode != BUILT_IN_CHKP_BNDRET)
>>      return expand_call (exp, target, ignore);
>>
>>    /* The built-in function expanders test for target == const0_rtx
>> @@ -6848,6 +6860,51 @@ expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode,
>>        expand_builtin_cilk_pop_frame (exp);
>>        return const0_rtx;
>>
>> +    case BUILT_IN_CHKP_INIT_PTR_BOUNDS:
>> +    case BUILT_IN_CHKP_NULL_PTR_BOUNDS:
>> +    case BUILT_IN_CHKP_COPY_PTR_BOUNDS:
>> +    case BUILT_IN_CHKP_CHECK_PTR_LBOUNDS:
>> +    case BUILT_IN_CHKP_CHECK_PTR_UBOUNDS:
>> +    case BUILT_IN_CHKP_CHECK_PTR_BOUNDS:
>> +    case BUILT_IN_CHKP_SET_PTR_BOUNDS:
>> +    case BUILT_IN_CHKP_NARROW_PTR_BOUNDS:
>> +    case BUILT_IN_CHKP_STORE_PTR_BOUNDS:
>> +    case BUILT_IN_CHKP_GET_PTR_LBOUND:
>> +    case BUILT_IN_CHKP_GET_PTR_UBOUND:
>> +      /* We allow user CHKP builtins if Pointer Bounds
>> +        Checker is off.  */
>> +      if (!flag_check_pointer_bounds)
>> +       {
>> +         if (fcode == BUILT_IN_CHKP_SET_PTR_BOUNDS
>> +             || fcode == BUILT_IN_CHKP_NARROW_PTR_BOUNDS
>> +             || fcode == BUILT_IN_CHKP_INIT_PTR_BOUNDS
>> +             || fcode == BUILT_IN_CHKP_NULL_PTR_BOUNDS
>> +             || fcode == BUILT_IN_CHKP_COPY_PTR_BOUNDS)
>> +           return expand_normal (CALL_EXPR_ARG (exp, 0));
>> +         else if (fcode == BUILT_IN_CHKP_GET_PTR_LBOUND)
>> +           return expand_normal (size_zero_node);
>> +         else if (fcode == BUILT_IN_CHKP_GET_PTR_UBOUND)
>> +           return expand_normal (size_int (-1));
>> +         else
>> +           return const0_rtx;
>> +       }
>> +      /* FALLTHROUGH */
>> +
>> +    case BUILT_IN_CHKP_BNDMK:
>> +    case BUILT_IN_CHKP_BNDSTX:
>> +    case BUILT_IN_CHKP_BNDCL:
>> +    case BUILT_IN_CHKP_BNDCU:
>> +    case BUILT_IN_CHKP_BNDLDX:
>> +    case BUILT_IN_CHKP_BNDRET:
>> +    case BUILT_IN_CHKP_INTERSECT:
>> +    case BUILT_IN_CHKP_NARROW:
>> +    case BUILT_IN_CHKP_EXTRACT_LOWER:
>> +    case BUILT_IN_CHKP_EXTRACT_UPPER:
>> +      /* Software implementation of Pointer Bounds Checker is NYI.
>> +        Target support is required.  */
>> +      error ("Your target platform does not support -fcheck-pointer-bounds");
>> +      break;
>> +
>>      default:   /* just do library call, if unknown builtin */
>>        break;
>>      }
>> diff --git a/gcc/builtins.def b/gcc/builtins.def
>> index 5a76ba3..ed2617e 100644
>> --- a/gcc/builtins.def
>> +++ b/gcc/builtins.def
>> @@ -176,6 +176,12 @@ along with GCC; see the file COPYING3.  If not see
>>    DEF_BUILTIN (ENUM, NAME, BUILT_IN_NORMAL, BT_FN_INT_VAR, BT_LAST, \
>>                false, false, false, ATTRS, false, flag_cilkplus)
>>
>> +/* Builtin used by the implementation of Pointer Bounds Checker.  */
>> +#undef DEF_CHKP_BUILTIN
>> +#define DEF_CHKP_BUILTIN(ENUM, NAME, TYPE, ATTRS) \
>> +  DEF_BUILTIN (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE, TYPE,    \
>> +              true, true, false, ATTRS, true, true)
>> +
>>  /* Define an attribute list for math functions that are normally
>>     "impure" because some of them may write into global memory for
>>     `errno'.  If !flag_errno_math they are instead "const".  */
>> @@ -870,3 +876,6 @@ DEF_GCC_BUILTIN (BUILT_IN_LINE, "LINE", BT_FN_INT, ATTR_NOTHROW_LEAF_LIST)
>>
>>  /* Cilk Plus builtins.  */
>>  #include "cilkplus.def"
>> +
>> +/* Pointer Bounds Checker builtins.  */
>> +#include "chkp-builtins.def"
>> diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt
>> index 390c056..3ec5cda 100644
>> --- a/gcc/c-family/c.opt
>> +++ b/gcc/c-family/c.opt
>> @@ -866,6 +866,11 @@ fcanonical-system-headers
>>  C ObjC C++ ObjC++
>>  Where shorter, use canonicalized paths to systems headers.
>>
>> +fcheck-pointer-bounds
>> +Common Report Var(flag_check_pointer_bounds)
>> +Add Pointer Bounds Checker instrumentation.  fchkp-* flags are used to
>> +control instrumentation.  Currently available for C, C++ and ObjC.
>> +
>>  fcilkplus
>>  C ObjC C++ ObjC++ LTO Report Var(flag_cilkplus) Init(0)
>>  Enable Cilk Plus
>> diff --git a/gcc/chkp-builtins.def b/gcc/chkp-builtins.def
>> new file mode 100644
>> index 0000000..cae0332
>> --- /dev/null
>> +++ b/gcc/chkp-builtins.def
>> @@ -0,0 +1,71 @@
>> +/* This file contains the definitions and documentation for the
>> +   builtins used in the GNU compiler.
>> +   Copyright (C) 2013 Free Software Foundation, Inc.
>> +
>> +This file is part of GCC.
>> +
>> +GCC is free software; you can redistribute it and/or modify it under
>> +the terms of the GNU General Public License as published by the Free
>> +Software Foundation; either version 3, or (at your option) any later
>> +version.
>> +
>> +GCC is distributed in the hope that it will be useful, but WITHOUT ANY
>> +WARRANTY; without even the implied warranty of MERCHANTABILITY or
>> +FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
>> +for more details.
>> +
>> +You should have received a copy of the GNU General Public License
>> +along with GCC; see the file COPYING3.  If not see
>> +<http://www.gnu.org/licenses/>.  */
>> +
>> +/* Before including this file, you should define macros:
>> +
>> +      DEF_BUILTIN_STUB(ENUM, NAME)
>> +      DEF_CHKP_BUILTIN(ENUM, NAME, TYPE, ATTRS)
>> +
>> +   See builtins.def for details.  */
>> +
>> +/* Following builtins are used by compiler for Pointer Bounds Checker
>> +   instrumentation.  Currently these generic builtins are not
>> +   implemented and target has to provide his own version.  See
>> +   builtin_chkp_function target hook documentation for more details.  */
>> +DEF_BUILTIN_STUB (BUILT_IN_CHKP_INTERSECT, "__chkp_intersect")
>> +DEF_BUILTIN_STUB (BUILT_IN_CHKP_SIZEOF, "__chkp_sizeof")
>> +DEF_BUILTIN_STUB (BUILT_IN_CHKP_NARROW, "__chkp_narrow")
>> +DEF_CHKP_BUILTIN (BUILT_IN_CHKP_BNDCL, "__chkp_bndcl", BT_FN_VOID_PTR_BND, ATTR_NOTHROW_LEAF_LIST)
>> +DEF_CHKP_BUILTIN (BUILT_IN_CHKP_BNDCU, "__chkp_bndcu", BT_FN_VOID_PTR_BND, ATTR_NOTHROW_LEAF_LIST)
>> +DEF_CHKP_BUILTIN (BUILT_IN_CHKP_BNDSTX, "__chkp_bndstx", BT_FN_VOID_CONST_PTR_BND_CONST_PTR, ATTR_NOTHROW_LEAF_LIST)
>> +DEF_CHKP_BUILTIN (BUILT_IN_CHKP_BNDLDX, "__chkp_bndldx", BT_FN_CONST_PTR_CONST_PTR_CONST_PTR, ATTR_NOTHROW_LEAF_LIST)
>> +DEF_CHKP_BUILTIN (BUILT_IN_CHKP_BNDRET, "__chkp_bndret", BT_FN_BND_CONST_PTR, ATTR_CONST_NOTHROW_LEAF_LIST)
>> +DEF_CHKP_BUILTIN (BUILT_IN_CHKP_BNDMK, "__chkp_bndmk", BT_FN_BND_CONST_PTR_SIZE, ATTR_CONST_NOTHROW_LEAF_LIST)
>> +DEF_CHKP_BUILTIN (BUILT_IN_CHKP_EXTRACT_LOWER, "__chkp_extract_lower", BT_FN_CONST_PTR_BND, ATTR_CONST_NOTHROW_LEAF_LIST)
>> +DEF_CHKP_BUILTIN (BUILT_IN_CHKP_EXTRACT_UPPER, "__chkp_extract_upper", BT_FN_CONST_PTR_BND, ATTR_CONST_NOTHROW_LEAF_LIST)
>> +
>> +/* Pointer Bounds Checker builtins for users.
>> +   All builtins calls are expanded in the
>> +   Pointer Bounds Checker pass.  */
>> +DEF_CHKP_BUILTIN (BUILT_IN_CHKP_SET_PTR_BOUNDS, "__bnd_set_ptr_bounds", BT_FN_PTR_CONST_PTR_SIZE, ATTR_CONST_NOTHROW_LEAF_LIST)
>> +DEF_CHKP_BUILTIN (BUILT_IN_CHKP_INIT_PTR_BOUNDS, "__bnd_init_ptr_bounds", BT_FN_PTR_CONST_PTR, ATTR_CONST_NOTHROW_LEAF_LIST)
>> +DEF_CHKP_BUILTIN (BUILT_IN_CHKP_NULL_PTR_BOUNDS, "__bnd_null_ptr_bounds", BT_FN_PTR_CONST_PTR, ATTR_CONST_NOTHROW_LEAF_LIST)
>> +DEF_CHKP_BUILTIN (BUILT_IN_CHKP_COPY_PTR_BOUNDS, "__bnd_copy_ptr_bounds", BT_FN_PTR_CONST_PTR_CONST_PTR, ATTR_CONST_NOTHROW_LEAF_LIST)
>> +DEF_CHKP_BUILTIN (BUILT_IN_CHKP_NARROW_PTR_BOUNDS, "__bnd_narrow_ptr_bounds", BT_FN_PTR_CONST_PTR_CONST_PTR_SIZE, ATTR_CONST_NOTHROW_LEAF_LIST)
>> +DEF_CHKP_BUILTIN (BUILT_IN_CHKP_STORE_PTR_BOUNDS, "__bnd_store_ptr_bounds", BT_FN_VOID_PTRPTR_CONST_PTR, ATTR_NOTHROW_LEAF_LIST)
>> +DEF_CHKP_BUILTIN (BUILT_IN_CHKP_CHECK_PTR_LBOUNDS, "__bnd_chk_ptr_lbounds", BT_FN_VOID_CONST_PTR, ATTR_NOTHROW_LEAF_LIST)
>> +DEF_CHKP_BUILTIN (BUILT_IN_CHKP_CHECK_PTR_UBOUNDS, "__bnd_chk_ptr_ubounds", BT_FN_VOID_CONST_PTR, ATTR_NOTHROW_LEAF_LIST)
>> +DEF_CHKP_BUILTIN (BUILT_IN_CHKP_CHECK_PTR_BOUNDS, "__bnd_chk_ptr_bounds", BT_FN_VOID_CONST_PTR_SIZE, ATTR_NOTHROW_LEAF_LIST)
>> +DEF_CHKP_BUILTIN (BUILT_IN_CHKP_GET_PTR_LBOUND, "__bnd_get_ptr_lbound", BT_FN_CONST_PTR_CONST_PTR, ATTR_CONST_NOTHROW_LEAF_LIST)
>> +DEF_CHKP_BUILTIN (BUILT_IN_CHKP_GET_PTR_UBOUND, "__bnd_get_ptr_ubound", BT_FN_CONST_PTR_CONST_PTR, ATTR_CONST_NOTHROW_LEAF_LIST)
>> +
>> +/* Pointer Bounds Checker specific versions of string functions.  */
>> +DEF_CHKP_BUILTIN (BUILT_IN_CHKP_MEMCPY_NOBND, "chkp_memcpy_nobnd", BT_FN_PTR_PTR_CONST_PTR_SIZE, ATTR_RET1_NOTHROW_NONNULL_LEAF)
>> +DEF_CHKP_BUILTIN (BUILT_IN_CHKP_MEMCPY_NOCHK, "chkp_memcpy_nochk", BT_FN_PTR_PTR_CONST_PTR_SIZE, ATTR_RET1_NOTHROW_NONNULL_LEAF)
>> +DEF_CHKP_BUILTIN (BUILT_IN_CHKP_MEMCPY_NOBND_NOCHK, "chkp_memcpy_nobnd_nochk", BT_FN_PTR_PTR_CONST_PTR_SIZE, ATTR_RET1_NOTHROW_NONNULL_LEAF)
>> +DEF_CHKP_BUILTIN (BUILT_IN_CHKP_MEMMOVE_NOBND, "chkp_memmove_nobnd", BT_FN_PTR_PTR_CONST_PTR_SIZE, ATTR_RET1_NOTHROW_NONNULL_LEAF)
>> +DEF_CHKP_BUILTIN (BUILT_IN_CHKP_MEMMOVE_NOCHK, "chkp_memmove_nochk", BT_FN_PTR_PTR_CONST_PTR_SIZE, ATTR_RET1_NOTHROW_NONNULL_LEAF)
>> +DEF_CHKP_BUILTIN (BUILT_IN_CHKP_MEMMOVE_NOBND_NOCHK, "chkp_memmove_nobnd_nochk", BT_FN_PTR_PTR_CONST_PTR_SIZE, ATTR_RET1_NOTHROW_NONNULL_LEAF)
>> +DEF_CHKP_BUILTIN (BUILT_IN_CHKP_MEMPCPY_NOBND, "chkp_mempcpy_nobnd", BT_FN_PTR_PTR_CONST_PTR_SIZE, ATTR_NOTHROW_NONNULL_LEAF)
>> +DEF_CHKP_BUILTIN (BUILT_IN_CHKP_MEMPCPY_NOCHK, "chkp_mempcpy_nochk", BT_FN_PTR_PTR_CONST_PTR_SIZE, ATTR_NOTHROW_NONNULL_LEAF)
>> +DEF_CHKP_BUILTIN (BUILT_IN_CHKP_MEMPCPY_NOBND_NOCHK, "chkp_mempcpy_nobnd_nochk", BT_FN_PTR_PTR_CONST_PTR_SIZE, ATTR_NOTHROW_NONNULL_LEAF)
>> +DEF_CHKP_BUILTIN (BUILT_IN_CHKP_MEMSET_NOBND, "chkp_memset_nobnd", BT_FN_PTR_PTR_INT_SIZE, ATTR_RET1_NOTHROW_NONNULL_LEAF)
>> +DEF_CHKP_BUILTIN (BUILT_IN_CHKP_MEMSET_NOCHK, "chkp_memset_nochk", BT_FN_PTR_PTR_INT_SIZE, ATTR_RET1_NOTHROW_NONNULL_LEAF)
>> +DEF_CHKP_BUILTIN (BUILT_IN_CHKP_MEMSET_NOBND_NOCHK, "chkp_memset_nobnd_nochk", BT_FN_PTR_PTR_INT_SIZE, ATTR_RET1_NOTHROW_NONNULL_LEAF)
>> diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
>> index 347a94a..1c74990 100644
>> --- a/gcc/doc/extend.texi
>> +++ b/gcc/doc/extend.texi
>> @@ -82,6 +82,7 @@ extensions, accepted by GCC in C90 mode and in C++.
>>  * x86 specific memory model extensions for transactional memory:: x86 memory models.
>>  * Object Size Checking:: Built-in functions for limited buffer overflow
>>                          checking.
>> +* Pointer Bounds Checker builtins:: Built-in functions for Pointer Bounds Checker.
>>  * Cilk Plus Builtins::  Built-in functions for the Cilk Plus language extension.
>>  * Other Builtins::      Other built-in functions.
>>  * Target Builtins::     Built-in functions specific to particular targets.
>> @@ -7945,6 +7946,176 @@ format string @var{fmt}.  If the compiler is able to optimize them to
>>  @code{fputc} etc.@: functions, it does, otherwise the checking function
>>  is called and the @var{flag} argument passed to it.
>>
>> +@node Pointer Bounds Checker builtins
>> +@section Pointer Bounds Checker Built-in Functions
>> +@findex __builtin___bnd_set_ptr_bounds
>> +@findex __builtin___bnd_narrow_ptr_bounds
>> +@findex __builtin___bnd_copy_ptr_bounds
>> +@findex __builtin___bnd_init_ptr_bounds
>> +@findex __builtin___bnd_null_ptr_bounds
>> +@findex __builtin___bnd_store_ptr_bounds
>> +@findex __builtin___bnd_chk_ptr_lbounds
>> +@findex __builtin___bnd_chk_ptr_ubounds
>> +@findex __builtin___bnd_chk_ptr_bounds
>> +@findex __builtin___bnd_get_ptr_lbound
>> +@findex __builtin___bnd_get_ptr_ubound
>> +
>> +GCC provides a set of built-in functions to control Pointer Bounds Checker
>> +instrumentation.  Note that all Pointer Bounds Checker builtins are allowed
>> +to use even if you compile with Pointer Bounds Checker off.  The builtins
>> +behavior may differ in such case as documented below.
>> +
>> +@deftypefn {Built-in Function} void * __builtin___bnd_set_ptr_bounds (const void * @var{q}, size_t @var{size})
>> +
>> +This built-in function returns a new pointer with the value of @var{q}, and
>> +associate it with the bounds [@var{q}, @var{q}+@var{size}-1].  With Pointer
>> +Bounds Checker off built-in function just returns the first argument.
>> +
>> +@smallexample
>> +extern void *__wrap_malloc (size_t n)
>> +@{
>> +  void *p = (void *)__real_malloc (n);
>> +  if (!p) return __builtin___bnd_null_ptr_bounds (p);
>> +  return __builtin___bnd_set_ptr_bounds (p, n);
>> +@}
>> +@end smallexample
>> +
>> +@end deftypefn
>> +
>> +@deftypefn {Built-in Function} void * __builtin___bnd_narrow_ptr_bounds (const void * @var{p}, const void * @var{q}, size_t  @var{size})
>> +
>> +This built-in function returns a new pointer with the value of @var{p}
>> +and associate it with the narrowed bounds formed by the intersection
>> +of bounds associated with @var{q} and the [@var{p}, @var{p} + @var{size} - 1].
>> +With Pointer Bounds Checker off built-in function just returns the first
>> +argument.
>> +
>> +@smallexample
>> +void init_objects (object *objs, size_t size)
>> +@{
>> +  size_t i;
>> +  /* Initialize objects one-by-one passing pointers with bounds of an object,
>> +     not the full array of objects.  */
>> +  for (i = 0; i < size; i++)
>> +    init_object (__builtin___bnd_narrow_ptr_bounds (objs + i, objs, sizeof(object)));
>> +@}
>> +@end smallexample
>> +
>> +@end deftypefn
>> +
>> +@deftypefn {Built-in Function} void * __builtin___bnd_copy_ptr_bounds (const void * @var{q}, const void * @var{r})
>> +
>> +This built-in function returns a new pointer with the value of @var{q},
>> +and associate it with the bounds already associated with pointer @var{r}.
>> +With Pointer Bounds Checker off built-in function just returns the first
>> +argument.
>> +
>> +@smallexample
>> +/* Here is a way to get pointer to object's field but
>> +   still with the full object's bounds.  */
>> +int *field_ptr = __builtin___bnd_copy_ptr_bounds (&objptr->int_filed, objptr);
>> +@end smallexample
>> +
>> +@end deftypefn
>> +
>> +@deftypefn {Built-in Function} void * __builtin___bnd_init_ptr_bounds (const void * @var{q})
>> +
>> +This built-in function returns a new pointer with the value of @var{q}, and
>> +associate it with INIT (allowing full memory access) bounds. With Pointer
>> +Bounds Checker off built-in function just returns the first argument.
>> +
>> +@end deftypefn
>> +
>> +@deftypefn {Built-in Function} void * __builtin___bnd_null_ptr_bounds (const void * @var{q})
>> +
>> +This built-in function returns a new pointer with the value of @var{q}, and
>> +associate it with NULL (allowing no memory access) bounds. With Pointer
>> +Bounds Checker off built-in function just returns the first argument.
>> +
>> +@end deftypefn
>> +
>> +@deftypefn {Built-in Function} void __builtin___bnd_store_ptr_bounds (const void ** @var{ptr_addr}, const void * @var{ptr_val})
>> +
>> +This built-in function stores the bounds associated with pointer @var{ptr_val}
>> +and location @var{ptr_addr} into Bounds Table.  This can be useful to propagate
>> +bounds from legacy code without touching the associated pointer's memory when
>> +pointers were copied as integers.  With Pointer Bounds Checker off built-in
>> +function call is ignored.
>> +
>> +@end deftypefn
>> +
>> +@deftypefn {Built-in Function} void __builtin___bnd_chk_ptr_lbounds (const void * @var{q})
>> +
>> +This built-in function checks if the pointer @var{q} is within the lower
>> +bound of its associated bounds.  With Pointer Bounds Checker off built-in
>> +function call is ignored.
>> +
>> +@smallexample
>> +extern void *__wrap_memset (void *dst, int c, size_t len)
>> +@{
>> +  if (len > 0)
>> +    @{
>> +      __builtin___bnd_chk_ptr_lbounds (dst);
>> +      __builtin___bnd_chk_ptr_ubounds ((char *)dst + len - 1);
>> +      __real_memset (dst, c, len);
>> +    @}
>> +  return dst;
>> +@}
>> +@end smallexample
>> +
>> +@end deftypefn
>> +
>> +@deftypefn {Built-in Function} void __builtin___bnd_chk_ptr_ubounds (const void * @var{q})
>> +
>> +This built-in function checks if the pointer @var{q} is within the upper
>> +bound of its associated bounds.  With Pointer Bounds Checker off built-in
>> +function call is ignored.
>> +
>> +@end deftypefn
>> +
>> +@deftypefn {Built-in Function} void __builtin___bnd_chk_ptr_bounds (const void * @var{q}, size_t @var{size})
>> +
>> +This built-in function checks if [@var{q}, @var{q} + @var{size} - 1] is within
>> +the lower and upper bounds associated with @var{q}.  With Pointer Bounds Checker
>> +off built-in function call is ignored.
>> +
>> +@smallexample
>> +extern void *__wrap_memcpy (void *dst, const void *src, size_t n)
>> +@{
>> +  if (n > 0)
>> +    @{
>> +      __bnd_chk_ptr_bounds (dst, n);
>> +      __bnd_chk_ptr_bounds (src, n);
>> +      __real_memcpy (dst, src, n);
>> +    @}
>> +  return dst;
>> +@}
>> +@end smallexample
>> +
>> +@end deftypefn
>> +
>> +@deftypefn {Built-in Function} const void * __builtin___bnd_get_ptr_lbound (const void * @var{q})
>> +
>> +This built-in function returns the lower bound (which is a pointer) associated
>> +with the pointer @var{q}.  This is at least useful for debugging using printf.
>> +With Pointer Bounds Checker off built-in function returns 0.
>> +
>> +@smallexample
>> +void *lb = __builtin___bnd_get_ptr_lbound (q);
>> +void *ub = __builtin___bnd_get_ptr_ubound (q);
>> +printf ("q = %p  lb(q) = %p  ub(q) = %p", q, lb, ub);
>> +@end smallexample
>> +
>> +@end deftypefn
>> +
>> +@deftypefn {Built-in Function} const void * __builtin___bnd_get_ptr_ubound (const void * @var{q})
>> +
>> +This built-in function returns the upper bound (which is a pointer) associated
>> +with the pointer @var{q}.  With Pointer Bounds Checker off built-in function
>> +returns -1.
>> +
>> +@end deftypefn
>> +
>>  @node Cilk Plus Builtins
>>  @section Cilk Plus C/C++ language extension Built-in Functions.
>>
>> diff --git a/gcc/toplev.c b/gcc/toplev.c
>> index 0f7d452..660a10b 100644
>> --- a/gcc/toplev.c
>> +++ b/gcc/toplev.c
>> @@ -1285,6 +1285,12 @@ process_options (void)
>>            "and -ftree-loop-linear)");
>>  #endif
>>
>> +  if (flag_check_pointer_bounds)
>> +    {
>> +      if (targetm.chkp_bound_mode () == VOIDmode)
>> +       error ("-fcheck-pointer-bounds is not supported for this target");
>> +    }
>> +
>>    /* One region RA really helps to decrease the code size.  */
>>    if (flag_ira_region == IRA_REGION_AUTODETECT)
>>      flag_ira_region
>> diff --git a/gcc/tree-core.h b/gcc/tree-core.h
>> index 1719c7e..b70c262 100644
>> --- a/gcc/tree-core.h
>> +++ b/gcc/tree-core.h
>> @@ -457,6 +457,8 @@ enum tree_index {
>>    TI_FILEPTR_TYPE,
>>    TI_POINTER_SIZED_TYPE,
>>
>> +  TI_POINTER_BOUNDS_TYPE,
>> +
>>    TI_DFLOAT32_TYPE,
>>    TI_DFLOAT64_TYPE,
>>    TI_DFLOAT128_TYPE,
>> diff --git a/gcc/tree.c b/gcc/tree.c
>> index 6a2ca1c..f9aa80f 100644
>> --- a/gcc/tree.c
>> +++ b/gcc/tree.c
>> @@ -9694,6 +9694,8 @@ build_common_tree_nodes (bool signed_char, bool short_double)
>>    void_type_node = make_node (VOID_TYPE);
>>    layout_type (void_type_node);
>>
>> +  pointer_bounds_type_node = targetm.chkp_bound_type ();
>> +
>>    /* We are not going to have real types in C with less than byte alignment,
>>       so we might as well not have any types that claim to have it.  */
>>    TYPE_ALIGN (void_type_node) = BITS_PER_UNIT;
>> diff --git a/gcc/tree.h b/gcc/tree.h
>> index f347b9b..801d564 100644
>> --- a/gcc/tree.h
>> +++ b/gcc/tree.h
>> @@ -3242,6 +3242,8 @@ tree_operand_check_code (const_tree __t, enum tree_code __code, int __i,
>>  #define complex_double_type_node       global_trees[TI_COMPLEX_DOUBLE_TYPE]
>>  #define complex_long_double_type_node  global_trees[TI_COMPLEX_LONG_DOUBLE_TYPE]
>>
>> +#define pointer_bounds_type_node        global_trees[TI_POINTER_BOUNDS_TYPE]
>> +
>>  #define void_type_node                 global_trees[TI_VOID_TYPE]
>>  /* The C type `void *'.  */
>>  #define ptr_type_node                  global_trees[TI_PTR_TYPE]

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH, Pointer Bounds Checker 4/x] Built-in functions
  2014-04-16 12:22 [PATCH, Pointer Bounds Checker 4/x] Built-in functions Ilya Enkovich
  2014-05-06 12:11 ` Ilya Enkovich
@ 2014-07-18  6:17 ` Jeff Law
  1 sibling, 0 replies; 4+ messages in thread
From: Jeff Law @ 2014-07-18  6:17 UTC (permalink / raw)
  To: Ilya Enkovich, gcc-patches

On 04/16/14 06:19, Ilya Enkovich wrote:
> Hi,
>
> This patch introduces built-in functions used by Pointer Bounds Checker.  It is mostly similar to what was reverted from 4.9, I just added types and attributes to builtins.  This patch also introduces pointer_bounds_type_node to be used in built-in function type declarations.
>
> Bootstrapped and tested on linux-x86_64.
>
> OK for trunk?
>
> Thanks,
> Ilya
> --
> gcc/
>
> 2014-04-16  Ilya Enkovich  <ilya.enkovich@intel.com>
>
> 	* tree-core.h (tree_index): Add TI_POINTER_BOUNDS_TYPE.
> 	* tree.h (pointer_bounds_type_node): New.
> 	* tree.c (build_common_tree_nodes): Initialize
> 	pointer_bounds_type_node.
> 	* builtin-types.def (BT_BND): New.
> 	(BT_FN_PTR_CONST_PTR): New.
> 	(BT_FN_CONST_PTR_CONST_PTR): New.
> 	(BT_FN_BND_CONST_PTR): New.
> 	(BT_FN_CONST_PTR_BND): New.
> 	(BT_FN_PTR_CONST_PTR_SIZE): New.
> 	(BT_FN_PTR_CONST_PTR_CONST_PTR): New.
> 	(BT_FN_VOID_PTRPTR_CONST_PTR): New.
> 	(BT_FN_VOID_CONST_PTR_SIZE): New.
> 	(BT_FN_VOID_PTR_BND): New.
> 	(BT_FN_CONST_PTR_CONST_PTR_CONST_PTR): New.
> 	(BT_FN_BND_CONST_PTR_SIZE): New.
> 	(BT_FN_PTR_CONST_PTR_CONST_PTR_SIZE): New.
> 	(BT_FN_VOID_CONST_PTR_BND_CONST_PTR): New.
> 	* chkp-builtins.def: New.
> 	* builtins.def: include chkp-builtins.def.
> 	(DEF_CHKP_BUILTIN): New.
> 	* builtins.c (expand_builtin): Support BUILT_IN_CHKP_INIT_PTR_BOUNDS,
> 	BUILT_IN_CHKP_NULL_PTR_BOUNDS, BUILT_IN_CHKP_COPY_PTR_BOUNDS,
> 	BUILT_IN_CHKP_CHECK_PTR_LBOUNDS, BUILT_IN_CHKP_CHECK_PTR_UBOUNDS,
> 	BUILT_IN_CHKP_CHECK_PTR_BOUNDS, BUILT_IN_CHKP_SET_PTR_BOUNDS,
> 	BUILT_IN_CHKP_NARROW_PTR_BOUNDS, BUILT_IN_CHKP_STORE_PTR_BOUNDS,
> 	BUILT_IN_CHKP_GET_PTR_LBOUND, BUILT_IN_CHKP_GET_PTR_UBOUND,
> 	BUILT_IN_CHKP_BNDMK, BUILT_IN_CHKP_BNDSTX, BUILT_IN_CHKP_BNDCL,
> 	BUILT_IN_CHKP_BNDCU, BUILT_IN_CHKP_BNDLDX, BUILT_IN_CHKP_BNDRET,
> 	BUILT_IN_CHKP_INTERSECT, BUILT_IN_CHKP_NARROW,
> 	BUILT_IN_CHKP_EXTRACT_LOWER, BUILT_IN_CHKP_EXTRACT_UPPER.
> 	* c-family/c.opt (fcheck-pointer-bounds): New.
> 	* toplev.c (process_options): Check Pointer Bounds Checker is supported.
> 	* doc/extend.texi: Document Pointer Bounds Checker built-in functions.
OK for the trunk.  Please commit when the entire patchset has been approved.

Thanks for your patience,
Jeff

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2014-07-18  5:07 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-04-16 12:22 [PATCH, Pointer Bounds Checker 4/x] Built-in functions Ilya Enkovich
2014-05-06 12:11 ` Ilya Enkovich
2014-06-27  8:11   ` Ilya Enkovich
2014-07-18  6:17 ` Jeff Law

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).