Message ID | 20131115143459.GC21297@msticlxl57.ims.intel.com |
---|---|
State | New |
Headers | show |
On Fri, Nov 15, 2013 at 3:34 PM, Ilya Enkovich <enkovich.gnu@gmail.com> wrote: > On 15 Nov 18:12, Ilya Enkovich wrote: >> 2013/11/15 Richard Biener <richard.guenther@gmail.com>: >> > On Fri, Nov 15, 2013 at 2:19 PM, Ilya Enkovich <enkovich.gnu@gmail.com> wrote: >> >> Hi, >> >> >> >> Here is a patch to introduce builtin to bind bounds for call arguments as was discussed here (http://gcc.gnu.org/ml/gcc-patches/2013-11/msg00872.html). Patch also removes outdated gimple ifaces. >> > >> > Looks good to me in principle but "instrumented" sounds a bit generic, can you >> > rename it to "with_bounds" in both the gimple and the rtl flag? >> >> Sure. Will do. >> >> > Also on RTL it's CALL_INSN, not CALL_EXPR, and the flag is already >> > taken to mark sibling calls there (there doesn't seem to be a flag left >> > for CALL_INSNs). >> >> Each call_insn has call expression inside. I use flags for CALL expr >> because there are no free flags for CALL_INSN. >> >> Ilya > > Here is updated version. Is it OK for trunk? Ok (if properly tested). Richard. > Thanks, > Ilya > -- > 2013-11-15 Ilya Enkovich <ilya.enkovich@intel.com> > > * builtin-types.def (BT_FN_PTR_CONST_PTR_VAR): New. > * chkp-builtins.def (BUILT_IN_CHKP_BIND_BOUNDS): New. > * cfgexpand.c (expand_call_stmt): Expand BUILT_IN_CHKP_BIND_BOUNDS. > * gimple.c (gimple_call_get_nobnd_arg_index): Remove. > * gimple.h (gf_mask): Add GF_CALL_WITH_BOUNDS. > (gimple_call_with_bounds_p): New. > (gimple_call_set_with_bounds): New. > (gimple_call_num_nobnd_args): Remove. > (gimple_call_nobnd_arg): Remove. > * tree.h (CALL_WITH_BOUNDS_P): New. > * rtl.h (CALL_EXPR_WITH_BOUNDS_P): New. > > > diff --git a/gcc/builtin-types.def b/gcc/builtin-types.def > index 1f9ae4e..e7bfaf9 100644 > --- a/gcc/builtin-types.def > +++ b/gcc/builtin-types.def > @@ -542,6 +542,8 @@ DEF_FUNCTION_TYPE_VAR_1 (BT_FN_INT_CONST_STRING_VAR, > BT_INT, BT_CONST_STRING) > DEF_FUNCTION_TYPE_VAR_1 (BT_FN_UINT32_UINT32_VAR, > BT_UINT32, BT_UINT32) > +DEF_FUNCTION_TYPE_VAR_1 (BT_FN_PTR_CONST_PTR_VAR, > + BT_PTR, BT_CONST_PTR) > > DEF_FUNCTION_TYPE_VAR_2 (BT_FN_INT_FILEPTR_CONST_STRING_VAR, > BT_INT, BT_FILEPTR, BT_CONST_STRING) > diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c > index 9705036..8a738d4 100644 > --- a/gcc/cfgexpand.c > +++ b/gcc/cfgexpand.c > @@ -2121,12 +2121,22 @@ expand_call_stmt (gimple stmt) > return; > } > > - exp = build_vl_exp (CALL_EXPR, gimple_call_num_args (stmt) + 3); > - > - CALL_EXPR_FN (exp) = gimple_call_fn (stmt); > decl = gimple_call_fndecl (stmt); > builtin_p = decl && DECL_BUILT_IN (decl); > > + /* Bind bounds call is expanded as assignment. */ > + if (builtin_p > + && DECL_BUILT_IN_CLASS (decl) == BUILT_IN_NORMAL > + && DECL_FUNCTION_CODE (decl) == BUILT_IN_CHKP_BIND_BOUNDS) > + { > + expand_assignment (gimple_call_lhs (stmt), > + gimple_call_arg (stmt, 0), false); > + return; > + } > + > + exp = build_vl_exp (CALL_EXPR, gimple_call_num_args (stmt) + 3); > + CALL_EXPR_FN (exp) = gimple_call_fn (stmt); > + > /* If this is not a builtin function, the function type through which the > call is made may be different from the type of the function. */ > if (!builtin_p) > diff --git a/gcc/chkp-builtins.def b/gcc/chkp-builtins.def > index d19b541..b920950 100644 > --- a/gcc/chkp-builtins.def > +++ b/gcc/chkp-builtins.def > @@ -42,6 +42,9 @@ DEF_BUILTIN_STUB (BUILT_IN_CHKP_EXTRACT_LOWER, "__chkp_extract_lower") > DEF_BUILTIN_STUB (BUILT_IN_CHKP_EXTRACT_UPPER, "__chkp_extract_upper") > DEF_BUILTIN_STUB (BUILT_IN_CHKP_NARROW, "__chkp_narrow") > > +/* Builtins to bind bounds to call arguments. */ > +DEF_CHKP_BUILTIN (BUILT_IN_CHKP_BIND_BOUNDS, "__chkp_bind_bounds", BT_FN_PTR_CONST_PTR_VAR, ATTR_CONST_NOTHROW_LEAF_LIST) > + > /* Pointer Bounds Checker builtins for users. Only > BUILT_IN_CHKP_SET_PTR_BOUNDS may be redefined > by target. Other builtins calls are expanded > diff --git a/gcc/gimple.c b/gcc/gimple.c > index 20f6010..72c10c0 100644 > --- a/gcc/gimple.c > +++ b/gcc/gimple.c > @@ -366,26 +366,6 @@ gimple_build_call_from_tree (tree t) > } > > > -/* Return index of INDEX's non bound argument of the call. */ > - > -unsigned > -gimple_call_get_nobnd_arg_index (const_gimple gs, unsigned index) > -{ > - unsigned num_args = gimple_call_num_args (gs); > - for (unsigned n = 0; n < num_args; n++) > - { > - if (POINTER_BOUNDS_P (gimple_call_arg (gs, n))) > - continue; > - else if (index) > - index--; > - else > - return n; > - } > - > - gcc_unreachable (); > -} > - > - > /* Extract the operands and code for expression EXPR into *SUBCODE_P, > *OP1_P, *OP2_P and *OP3_P respectively. */ > > diff --git a/gcc/gimple.h b/gcc/gimple.h > index c7ce394..7e98ab4 100644 > --- a/gcc/gimple.h > +++ b/gcc/gimple.h > @@ -101,6 +101,7 @@ enum gf_mask { > GF_CALL_NOTHROW = 1 << 4, > GF_CALL_ALLOCA_FOR_VAR = 1 << 5, > GF_CALL_INTERNAL = 1 << 6, > + GF_CALL_WITH_BOUNDS = 1 << 7, > GF_OMP_PARALLEL_COMBINED = 1 << 0, > GF_OMP_FOR_KIND_MASK = 3 << 0, > GF_OMP_FOR_KIND_FOR = 0 << 0, > @@ -919,7 +920,6 @@ extern tree get_initialized_tmp_var (tree, gimple_seq *, gimple_seq *); > extern tree get_formal_tmp_var (tree, gimple_seq *); > extern void declare_vars (tree, gimple, bool); > extern void annotate_all_with_location (gimple_seq, location_t); > -extern unsigned gimple_call_get_nobnd_arg_index (const_gimple, unsigned); > > /* Validation of GIMPLE expressions. Note that these predicates only check > the basic form of the expression, they don't recurse to make sure that > @@ -2231,6 +2231,31 @@ gimple_call_internal_p (const_gimple gs) > } > > > +/* Return true if call GS is marked as instrumented by > + Pointer Bounds Checker. */ > + > +static inline bool > +gimple_call_with_bounds_p (const_gimple gs) > +{ > + GIMPLE_CHECK (gs, GIMPLE_CALL); > + return (gs->gsbase.subcode & GF_CALL_WITH_BOUNDS) != 0; > +} > + > + > +/* If INSTRUMENTED_P is true, marm statement GS as instrumented by > + Pointer Bounds Checker. */ > + > +static inline void > +gimple_call_set_with_bounds (gimple gs, bool with_bounds) > +{ > + GIMPLE_CHECK (gs, GIMPLE_CALL); > + if (with_bounds) > + gs->gsbase.subcode |= GF_CALL_WITH_BOUNDS; > + else > + gs->gsbase.subcode &= ~GF_CALL_WITH_BOUNDS; > +} > + > + > /* Return the target of internal call GS. */ > > static inline enum internal_fn > @@ -2415,32 +2440,6 @@ gimple_call_arg (const_gimple gs, unsigned index) > } > > > -/* Return the number of arguments used by call statement GS > - ignoring bound ones. */ > - > -static inline unsigned > -gimple_call_num_nobnd_args (const_gimple gs) > -{ > - unsigned num_args = gimple_call_num_args (gs); > - unsigned res = num_args; > - for (unsigned n = 0; n < num_args; n++) > - if (POINTER_BOUNDS_P (gimple_call_arg (gs, n))) > - res--; > - return res; > -} > - > - > -/* Return INDEX's call argument ignoring bound ones. */ > -static inline tree > -gimple_call_nobnd_arg (const_gimple gs, unsigned index) > -{ > - /* No bound args may exist if pointers checker is off. */ > - if (!flag_check_pointer_bounds) > - return gimple_call_arg (gs, index); > - return gimple_call_arg (gs, gimple_call_get_nobnd_arg_index (gs, index)); > -} > - > - > /* Return a pointer to the argument at position INDEX for call > statement GS. */ > > diff --git a/gcc/rtl.h b/gcc/rtl.h > index 247a0d0..bab5b7c 100644 > --- a/gcc/rtl.h > +++ b/gcc/rtl.h > @@ -266,7 +266,8 @@ struct GTY((chain_next ("RTX_NEXT (&%h)"), > In a CODE_LABEL, part of the two-bit alternate entry field. > 1 in a CONCAT is VAL_EXPR_IS_COPIED in var-tracking.c. > 1 in a VALUE is SP_BASED_VALUE_P in cselib.c. > - 1 in a SUBREG generated by LRA for reload insns. */ > + 1 in a SUBREG generated by LRA for reload insns. > + 1 in a CALL for calls instrumented by Pointer Bounds Checker. */ > unsigned int jump : 1; > /* In a CODE_LABEL, part of the two-bit alternate entry field. > 1 in a MEM if it cannot trap. > @@ -1420,6 +1421,10 @@ do { \ > #define LRA_SUBREG_P(RTX) \ > (RTL_FLAG_CHECK1 ("LRA_SUBREG_P", (RTX), SUBREG)->jump) > > +/* True if call is instrumented by Pointer Bounds Checker. */ > +#define CALL_EXPR_WITH_BOUNDS_P(RTX) \ > + (RTL_FLAG_CHECK1 ("CALL_EXPR_WITH_BOUNDS_P", (RTX), CALL)->jump) > + > /* Access various components of an ASM_OPERANDS rtx. */ > > #define ASM_OPERANDS_TEMPLATE(RTX) XCSTR (RTX, 0, ASM_OPERANDS) > diff --git a/gcc/tree.h b/gcc/tree.h > index 3fe751e..0dff25e 100644 > --- a/gcc/tree.h > +++ b/gcc/tree.h > @@ -828,6 +828,9 @@ extern void omp_clause_range_check_failed (const_tree, const char *, int, > #define CALL_ALLOCA_FOR_VAR_P(NODE) \ > (CALL_EXPR_CHECK (NODE)->base.protected_flag) > > +/* In a CALL_EXPR, means call was instrumented by Pointer Bounds Checker. */ > +#define CALL_WITH_BOUNDS_P(NODE) (CALL_EXPR_CHECK (NODE)->base.deprecated_flag) > + > /* In a type, nonzero means that all objects of the type are guaranteed by the > language or front-end to be properly aligned, so we can indicate that a MEM > of this type is aligned at least to the alignment of the type, even if it
2013/11/15 Richard Biener <richard.guenther@gmail.com>: > On Fri, Nov 15, 2013 at 3:34 PM, Ilya Enkovich <enkovich.gnu@gmail.com> wrote: >> On 15 Nov 18:12, Ilya Enkovich wrote: >>> 2013/11/15 Richard Biener <richard.guenther@gmail.com>: >>> > On Fri, Nov 15, 2013 at 2:19 PM, Ilya Enkovich <enkovich.gnu@gmail.com> wrote: >>> >> Hi, >>> >> >>> >> Here is a patch to introduce builtin to bind bounds for call arguments as was discussed here (http://gcc.gnu.org/ml/gcc-patches/2013-11/msg00872.html). Patch also removes outdated gimple ifaces. >>> > >>> > Looks good to me in principle but "instrumented" sounds a bit generic, can you >>> > rename it to "with_bounds" in both the gimple and the rtl flag? >>> >>> Sure. Will do. >>> >>> > Also on RTL it's CALL_INSN, not CALL_EXPR, and the flag is already >>> > taken to mark sibling calls there (there doesn't seem to be a flag left >>> > for CALL_INSNs). >>> >>> Each call_insn has call expression inside. I use flags for CALL expr >>> because there are no free flags for CALL_INSN. >>> >>> Ilya >> >> Here is updated version. Is it OK for trunk? > > Ok (if properly tested). Thanks! Will install it and send subsequent patches from a series based on a new approach. Ilya > > Richard. > >> Thanks, >> Ilya >> -- >> 2013-11-15 Ilya Enkovich <ilya.enkovich@intel.com> >> >> * builtin-types.def (BT_FN_PTR_CONST_PTR_VAR): New. >> * chkp-builtins.def (BUILT_IN_CHKP_BIND_BOUNDS): New. >> * cfgexpand.c (expand_call_stmt): Expand BUILT_IN_CHKP_BIND_BOUNDS. >> * gimple.c (gimple_call_get_nobnd_arg_index): Remove. >> * gimple.h (gf_mask): Add GF_CALL_WITH_BOUNDS. >> (gimple_call_with_bounds_p): New. >> (gimple_call_set_with_bounds): New. >> (gimple_call_num_nobnd_args): Remove. >> (gimple_call_nobnd_arg): Remove. >> * tree.h (CALL_WITH_BOUNDS_P): New. >> * rtl.h (CALL_EXPR_WITH_BOUNDS_P): New. >> >> >> diff --git a/gcc/builtin-types.def b/gcc/builtin-types.def >> index 1f9ae4e..e7bfaf9 100644 >> --- a/gcc/builtin-types.def >> +++ b/gcc/builtin-types.def >> @@ -542,6 +542,8 @@ DEF_FUNCTION_TYPE_VAR_1 (BT_FN_INT_CONST_STRING_VAR, >> BT_INT, BT_CONST_STRING) >> DEF_FUNCTION_TYPE_VAR_1 (BT_FN_UINT32_UINT32_VAR, >> BT_UINT32, BT_UINT32) >> +DEF_FUNCTION_TYPE_VAR_1 (BT_FN_PTR_CONST_PTR_VAR, >> + BT_PTR, BT_CONST_PTR) >> >> DEF_FUNCTION_TYPE_VAR_2 (BT_FN_INT_FILEPTR_CONST_STRING_VAR, >> BT_INT, BT_FILEPTR, BT_CONST_STRING) >> diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c >> index 9705036..8a738d4 100644 >> --- a/gcc/cfgexpand.c >> +++ b/gcc/cfgexpand.c >> @@ -2121,12 +2121,22 @@ expand_call_stmt (gimple stmt) >> return; >> } >> >> - exp = build_vl_exp (CALL_EXPR, gimple_call_num_args (stmt) + 3); >> - >> - CALL_EXPR_FN (exp) = gimple_call_fn (stmt); >> decl = gimple_call_fndecl (stmt); >> builtin_p = decl && DECL_BUILT_IN (decl); >> >> + /* Bind bounds call is expanded as assignment. */ >> + if (builtin_p >> + && DECL_BUILT_IN_CLASS (decl) == BUILT_IN_NORMAL >> + && DECL_FUNCTION_CODE (decl) == BUILT_IN_CHKP_BIND_BOUNDS) >> + { >> + expand_assignment (gimple_call_lhs (stmt), >> + gimple_call_arg (stmt, 0), false); >> + return; >> + } >> + >> + exp = build_vl_exp (CALL_EXPR, gimple_call_num_args (stmt) + 3); >> + CALL_EXPR_FN (exp) = gimple_call_fn (stmt); >> + >> /* If this is not a builtin function, the function type through which the >> call is made may be different from the type of the function. */ >> if (!builtin_p) >> diff --git a/gcc/chkp-builtins.def b/gcc/chkp-builtins.def >> index d19b541..b920950 100644 >> --- a/gcc/chkp-builtins.def >> +++ b/gcc/chkp-builtins.def >> @@ -42,6 +42,9 @@ DEF_BUILTIN_STUB (BUILT_IN_CHKP_EXTRACT_LOWER, "__chkp_extract_lower") >> DEF_BUILTIN_STUB (BUILT_IN_CHKP_EXTRACT_UPPER, "__chkp_extract_upper") >> DEF_BUILTIN_STUB (BUILT_IN_CHKP_NARROW, "__chkp_narrow") >> >> +/* Builtins to bind bounds to call arguments. */ >> +DEF_CHKP_BUILTIN (BUILT_IN_CHKP_BIND_BOUNDS, "__chkp_bind_bounds", BT_FN_PTR_CONST_PTR_VAR, ATTR_CONST_NOTHROW_LEAF_LIST) >> + >> /* Pointer Bounds Checker builtins for users. Only >> BUILT_IN_CHKP_SET_PTR_BOUNDS may be redefined >> by target. Other builtins calls are expanded >> diff --git a/gcc/gimple.c b/gcc/gimple.c >> index 20f6010..72c10c0 100644 >> --- a/gcc/gimple.c >> +++ b/gcc/gimple.c >> @@ -366,26 +366,6 @@ gimple_build_call_from_tree (tree t) >> } >> >> >> -/* Return index of INDEX's non bound argument of the call. */ >> - >> -unsigned >> -gimple_call_get_nobnd_arg_index (const_gimple gs, unsigned index) >> -{ >> - unsigned num_args = gimple_call_num_args (gs); >> - for (unsigned n = 0; n < num_args; n++) >> - { >> - if (POINTER_BOUNDS_P (gimple_call_arg (gs, n))) >> - continue; >> - else if (index) >> - index--; >> - else >> - return n; >> - } >> - >> - gcc_unreachable (); >> -} >> - >> - >> /* Extract the operands and code for expression EXPR into *SUBCODE_P, >> *OP1_P, *OP2_P and *OP3_P respectively. */ >> >> diff --git a/gcc/gimple.h b/gcc/gimple.h >> index c7ce394..7e98ab4 100644 >> --- a/gcc/gimple.h >> +++ b/gcc/gimple.h >> @@ -101,6 +101,7 @@ enum gf_mask { >> GF_CALL_NOTHROW = 1 << 4, >> GF_CALL_ALLOCA_FOR_VAR = 1 << 5, >> GF_CALL_INTERNAL = 1 << 6, >> + GF_CALL_WITH_BOUNDS = 1 << 7, >> GF_OMP_PARALLEL_COMBINED = 1 << 0, >> GF_OMP_FOR_KIND_MASK = 3 << 0, >> GF_OMP_FOR_KIND_FOR = 0 << 0, >> @@ -919,7 +920,6 @@ extern tree get_initialized_tmp_var (tree, gimple_seq *, gimple_seq *); >> extern tree get_formal_tmp_var (tree, gimple_seq *); >> extern void declare_vars (tree, gimple, bool); >> extern void annotate_all_with_location (gimple_seq, location_t); >> -extern unsigned gimple_call_get_nobnd_arg_index (const_gimple, unsigned); >> >> /* Validation of GIMPLE expressions. Note that these predicates only check >> the basic form of the expression, they don't recurse to make sure that >> @@ -2231,6 +2231,31 @@ gimple_call_internal_p (const_gimple gs) >> } >> >> >> +/* Return true if call GS is marked as instrumented by >> + Pointer Bounds Checker. */ >> + >> +static inline bool >> +gimple_call_with_bounds_p (const_gimple gs) >> +{ >> + GIMPLE_CHECK (gs, GIMPLE_CALL); >> + return (gs->gsbase.subcode & GF_CALL_WITH_BOUNDS) != 0; >> +} >> + >> + >> +/* If INSTRUMENTED_P is true, marm statement GS as instrumented by >> + Pointer Bounds Checker. */ >> + >> +static inline void >> +gimple_call_set_with_bounds (gimple gs, bool with_bounds) >> +{ >> + GIMPLE_CHECK (gs, GIMPLE_CALL); >> + if (with_bounds) >> + gs->gsbase.subcode |= GF_CALL_WITH_BOUNDS; >> + else >> + gs->gsbase.subcode &= ~GF_CALL_WITH_BOUNDS; >> +} >> + >> + >> /* Return the target of internal call GS. */ >> >> static inline enum internal_fn >> @@ -2415,32 +2440,6 @@ gimple_call_arg (const_gimple gs, unsigned index) >> } >> >> >> -/* Return the number of arguments used by call statement GS >> - ignoring bound ones. */ >> - >> -static inline unsigned >> -gimple_call_num_nobnd_args (const_gimple gs) >> -{ >> - unsigned num_args = gimple_call_num_args (gs); >> - unsigned res = num_args; >> - for (unsigned n = 0; n < num_args; n++) >> - if (POINTER_BOUNDS_P (gimple_call_arg (gs, n))) >> - res--; >> - return res; >> -} >> - >> - >> -/* Return INDEX's call argument ignoring bound ones. */ >> -static inline tree >> -gimple_call_nobnd_arg (const_gimple gs, unsigned index) >> -{ >> - /* No bound args may exist if pointers checker is off. */ >> - if (!flag_check_pointer_bounds) >> - return gimple_call_arg (gs, index); >> - return gimple_call_arg (gs, gimple_call_get_nobnd_arg_index (gs, index)); >> -} >> - >> - >> /* Return a pointer to the argument at position INDEX for call >> statement GS. */ >> >> diff --git a/gcc/rtl.h b/gcc/rtl.h >> index 247a0d0..bab5b7c 100644 >> --- a/gcc/rtl.h >> +++ b/gcc/rtl.h >> @@ -266,7 +266,8 @@ struct GTY((chain_next ("RTX_NEXT (&%h)"), >> In a CODE_LABEL, part of the two-bit alternate entry field. >> 1 in a CONCAT is VAL_EXPR_IS_COPIED in var-tracking.c. >> 1 in a VALUE is SP_BASED_VALUE_P in cselib.c. >> - 1 in a SUBREG generated by LRA for reload insns. */ >> + 1 in a SUBREG generated by LRA for reload insns. >> + 1 in a CALL for calls instrumented by Pointer Bounds Checker. */ >> unsigned int jump : 1; >> /* In a CODE_LABEL, part of the two-bit alternate entry field. >> 1 in a MEM if it cannot trap. >> @@ -1420,6 +1421,10 @@ do { \ >> #define LRA_SUBREG_P(RTX) \ >> (RTL_FLAG_CHECK1 ("LRA_SUBREG_P", (RTX), SUBREG)->jump) >> >> +/* True if call is instrumented by Pointer Bounds Checker. */ >> +#define CALL_EXPR_WITH_BOUNDS_P(RTX) \ >> + (RTL_FLAG_CHECK1 ("CALL_EXPR_WITH_BOUNDS_P", (RTX), CALL)->jump) >> + >> /* Access various components of an ASM_OPERANDS rtx. */ >> >> #define ASM_OPERANDS_TEMPLATE(RTX) XCSTR (RTX, 0, ASM_OPERANDS) >> diff --git a/gcc/tree.h b/gcc/tree.h >> index 3fe751e..0dff25e 100644 >> --- a/gcc/tree.h >> +++ b/gcc/tree.h >> @@ -828,6 +828,9 @@ extern void omp_clause_range_check_failed (const_tree, const char *, int, >> #define CALL_ALLOCA_FOR_VAR_P(NODE) \ >> (CALL_EXPR_CHECK (NODE)->base.protected_flag) >> >> +/* In a CALL_EXPR, means call was instrumented by Pointer Bounds Checker. */ >> +#define CALL_WITH_BOUNDS_P(NODE) (CALL_EXPR_CHECK (NODE)->base.deprecated_flag) >> + >> /* In a type, nonzero means that all objects of the type are guaranteed by the >> language or front-end to be properly aligned, so we can indicate that a MEM >> of this type is aligned at least to the alignment of the type, even if it
diff --git a/gcc/builtin-types.def b/gcc/builtin-types.def index 1f9ae4e..e7bfaf9 100644 --- a/gcc/builtin-types.def +++ b/gcc/builtin-types.def @@ -542,6 +542,8 @@ DEF_FUNCTION_TYPE_VAR_1 (BT_FN_INT_CONST_STRING_VAR, BT_INT, BT_CONST_STRING) DEF_FUNCTION_TYPE_VAR_1 (BT_FN_UINT32_UINT32_VAR, BT_UINT32, BT_UINT32) +DEF_FUNCTION_TYPE_VAR_1 (BT_FN_PTR_CONST_PTR_VAR, + BT_PTR, BT_CONST_PTR) DEF_FUNCTION_TYPE_VAR_2 (BT_FN_INT_FILEPTR_CONST_STRING_VAR, BT_INT, BT_FILEPTR, BT_CONST_STRING) diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c index 9705036..8a738d4 100644 --- a/gcc/cfgexpand.c +++ b/gcc/cfgexpand.c @@ -2121,12 +2121,22 @@ expand_call_stmt (gimple stmt) return; } - exp = build_vl_exp (CALL_EXPR, gimple_call_num_args (stmt) + 3); - - CALL_EXPR_FN (exp) = gimple_call_fn (stmt); decl = gimple_call_fndecl (stmt); builtin_p = decl && DECL_BUILT_IN (decl); + /* Bind bounds call is expanded as assignment. */ + if (builtin_p + && DECL_BUILT_IN_CLASS (decl) == BUILT_IN_NORMAL + && DECL_FUNCTION_CODE (decl) == BUILT_IN_CHKP_BIND_BOUNDS) + { + expand_assignment (gimple_call_lhs (stmt), + gimple_call_arg (stmt, 0), false); + return; + } + + exp = build_vl_exp (CALL_EXPR, gimple_call_num_args (stmt) + 3); + CALL_EXPR_FN (exp) = gimple_call_fn (stmt); + /* If this is not a builtin function, the function type through which the call is made may be different from the type of the function. */ if (!builtin_p) diff --git a/gcc/chkp-builtins.def b/gcc/chkp-builtins.def index d19b541..b920950 100644 --- a/gcc/chkp-builtins.def +++ b/gcc/chkp-builtins.def @@ -42,6 +42,9 @@ DEF_BUILTIN_STUB (BUILT_IN_CHKP_EXTRACT_LOWER, "__chkp_extract_lower") DEF_BUILTIN_STUB (BUILT_IN_CHKP_EXTRACT_UPPER, "__chkp_extract_upper") DEF_BUILTIN_STUB (BUILT_IN_CHKP_NARROW, "__chkp_narrow") +/* Builtins to bind bounds to call arguments. */ +DEF_CHKP_BUILTIN (BUILT_IN_CHKP_BIND_BOUNDS, "__chkp_bind_bounds", BT_FN_PTR_CONST_PTR_VAR, ATTR_CONST_NOTHROW_LEAF_LIST) + /* Pointer Bounds Checker builtins for users. Only BUILT_IN_CHKP_SET_PTR_BOUNDS may be redefined by target. Other builtins calls are expanded diff --git a/gcc/gimple.c b/gcc/gimple.c index 20f6010..72c10c0 100644 --- a/gcc/gimple.c +++ b/gcc/gimple.c @@ -366,26 +366,6 @@ gimple_build_call_from_tree (tree t) } -/* Return index of INDEX's non bound argument of the call. */ - -unsigned -gimple_call_get_nobnd_arg_index (const_gimple gs, unsigned index) -{ - unsigned num_args = gimple_call_num_args (gs); - for (unsigned n = 0; n < num_args; n++) - { - if (POINTER_BOUNDS_P (gimple_call_arg (gs, n))) - continue; - else if (index) - index--; - else - return n; - } - - gcc_unreachable (); -} - - /* Extract the operands and code for expression EXPR into *SUBCODE_P, *OP1_P, *OP2_P and *OP3_P respectively. */ diff --git a/gcc/gimple.h b/gcc/gimple.h index c7ce394..7e98ab4 100644 --- a/gcc/gimple.h +++ b/gcc/gimple.h @@ -101,6 +101,7 @@ enum gf_mask { GF_CALL_NOTHROW = 1 << 4, GF_CALL_ALLOCA_FOR_VAR = 1 << 5, GF_CALL_INTERNAL = 1 << 6, + GF_CALL_WITH_BOUNDS = 1 << 7, GF_OMP_PARALLEL_COMBINED = 1 << 0, GF_OMP_FOR_KIND_MASK = 3 << 0, GF_OMP_FOR_KIND_FOR = 0 << 0, @@ -919,7 +920,6 @@ extern tree get_initialized_tmp_var (tree, gimple_seq *, gimple_seq *); extern tree get_formal_tmp_var (tree, gimple_seq *); extern void declare_vars (tree, gimple, bool); extern void annotate_all_with_location (gimple_seq, location_t); -extern unsigned gimple_call_get_nobnd_arg_index (const_gimple, unsigned); /* Validation of GIMPLE expressions. Note that these predicates only check the basic form of the expression, they don't recurse to make sure that @@ -2231,6 +2231,31 @@ gimple_call_internal_p (const_gimple gs) } +/* Return true if call GS is marked as instrumented by + Pointer Bounds Checker. */ + +static inline bool +gimple_call_with_bounds_p (const_gimple gs) +{ + GIMPLE_CHECK (gs, GIMPLE_CALL); + return (gs->gsbase.subcode & GF_CALL_WITH_BOUNDS) != 0; +} + + +/* If INSTRUMENTED_P is true, marm statement GS as instrumented by + Pointer Bounds Checker. */ + +static inline void +gimple_call_set_with_bounds (gimple gs, bool with_bounds) +{ + GIMPLE_CHECK (gs, GIMPLE_CALL); + if (with_bounds) + gs->gsbase.subcode |= GF_CALL_WITH_BOUNDS; + else + gs->gsbase.subcode &= ~GF_CALL_WITH_BOUNDS; +} + + /* Return the target of internal call GS. */ static inline enum internal_fn @@ -2415,32 +2440,6 @@ gimple_call_arg (const_gimple gs, unsigned index) } -/* Return the number of arguments used by call statement GS - ignoring bound ones. */ - -static inline unsigned -gimple_call_num_nobnd_args (const_gimple gs) -{ - unsigned num_args = gimple_call_num_args (gs); - unsigned res = num_args; - for (unsigned n = 0; n < num_args; n++) - if (POINTER_BOUNDS_P (gimple_call_arg (gs, n))) - res--; - return res; -} - - -/* Return INDEX's call argument ignoring bound ones. */ -static inline tree -gimple_call_nobnd_arg (const_gimple gs, unsigned index) -{ - /* No bound args may exist if pointers checker is off. */ - if (!flag_check_pointer_bounds) - return gimple_call_arg (gs, index); - return gimple_call_arg (gs, gimple_call_get_nobnd_arg_index (gs, index)); -} - - /* Return a pointer to the argument at position INDEX for call statement GS. */ diff --git a/gcc/rtl.h b/gcc/rtl.h index 247a0d0..bab5b7c 100644 --- a/gcc/rtl.h +++ b/gcc/rtl.h @@ -266,7 +266,8 @@ struct GTY((chain_next ("RTX_NEXT (&%h)"), In a CODE_LABEL, part of the two-bit alternate entry field. 1 in a CONCAT is VAL_EXPR_IS_COPIED in var-tracking.c. 1 in a VALUE is SP_BASED_VALUE_P in cselib.c. - 1 in a SUBREG generated by LRA for reload insns. */ + 1 in a SUBREG generated by LRA for reload insns. + 1 in a CALL for calls instrumented by Pointer Bounds Checker. */ unsigned int jump : 1; /* In a CODE_LABEL, part of the two-bit alternate entry field. 1 in a MEM if it cannot trap. @@ -1420,6 +1421,10 @@ do { \ #define LRA_SUBREG_P(RTX) \ (RTL_FLAG_CHECK1 ("LRA_SUBREG_P", (RTX), SUBREG)->jump) +/* True if call is instrumented by Pointer Bounds Checker. */ +#define CALL_EXPR_WITH_BOUNDS_P(RTX) \ + (RTL_FLAG_CHECK1 ("CALL_EXPR_WITH_BOUNDS_P", (RTX), CALL)->jump) + /* Access various components of an ASM_OPERANDS rtx. */ #define ASM_OPERANDS_TEMPLATE(RTX) XCSTR (RTX, 0, ASM_OPERANDS) diff --git a/gcc/tree.h b/gcc/tree.h index 3fe751e..0dff25e 100644 --- a/gcc/tree.h +++ b/gcc/tree.h @@ -828,6 +828,9 @@ extern void omp_clause_range_check_failed (const_tree, const char *, int, #define CALL_ALLOCA_FOR_VAR_P(NODE) \ (CALL_EXPR_CHECK (NODE)->base.protected_flag) +/* In a CALL_EXPR, means call was instrumented by Pointer Bounds Checker. */ +#define CALL_WITH_BOUNDS_P(NODE) (CALL_EXPR_CHECK (NODE)->base.deprecated_flag) + /* In a type, nonzero means that all objects of the type are guaranteed by the language or front-end to be properly aligned, so we can indicate that a MEM of this type is aligned at least to the alignment of the type, even if it