PING
2014-04-16 16:19 GMT+04:00 Ilya Enkovich <enkovich....@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.enkov...@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]