Message ID | 20140416115211.GB4040@msticlxl57.ims.intel.com |
---|---|
State | New |
Headers | show |
PING 2014-04-16 15:52 GMT+04:00 Ilya Enkovich <enkovich.gnu@gmail.com>: > Hi, > > This patch introduces target hooks to be used by Pointer Bounds Checker. Hooks set is different from what was approved for 4.9 (and later reverted). I added hooks to work with returned bounds and to prepare incoming bounds for vararg functions. It allowed to remove some target assumptions from expand code. > > Bootstrapped and tested on linux-x86_64. > > OK for trunk? > > Thanks, > Ilya > -- > gcc/ > > 2014-04-16 Ilya Enkovich <ilya.enkovich@intel.com> > > * target.def (builtin_chkp_function): New. > (chkp_bound_type): New. > (chkp_bound_mode): New. > (chkp_make_bounds_constant): New. > (chkp_initialize_bounds): New. > (fn_abi_va_list_bounds_size): New. > (load_bounds_for_arg): New. > (store_bounds_for_arg): New. > (load_returned_bounds): New. > (store_returned_bounds): New. > (chkp_function_value_bounds): New. > (setup_incoming_vararg_bounds): New. > * targhooks.h (default_load_bounds_for_arg): New. > (default_store_bounds_for_arg): New. > (default_load_returned_bounds): New. > (default_store_returned_bounds): New. > (default_fn_abi_va_list_bounds_size): New. > (default_chkp_bound_type): New. > (default_chkp_bound_mode): New. > (default_builtin_chkp_function): New. > (default_chkp_function_value_bounds): New. > (default_chkp_make_bounds_constant): New. > (default_chkp_initialize_bounds): New. > (default_setup_incoming_vararg_bounds): New. > * targhooks.c (default_load_bounds_for_arg): New. > (default_store_bounds_for_arg): New. > (default_load_returned_bounds): New. > (default_store_returned_bounds): New. > (default_fn_abi_va_list_bounds_size): New. > (default_chkp_bound_type): New. > (default_chkp_bound_mode); New. > (default_builtin_chkp_function): New. > (default_chkp_function_value_bounds): New. > (default_chkp_make_bounds_constant): New. > (default_chkp_initialize_bounds): New. > (default_setup_incoming_vararg_bounds): New. > * doc/tm.texi.in (TARGET_FN_ABI_VA_LIST_BOUNDS_SIZE): New. > (TARGET_LOAD_BOUNDS_FOR_ARG): New. > (TARGET_STORE_BOUNDS_FOR_ARG): New. > (TARGET_LOAD_RETURNED_BOUNDS): New. > (TARGET_STORE_RETURNED_BOUNDS): New. > (TARGET_CHKP_FUNCTION_VALUE_BOUNDS): New. > (TARGET_SETUP_INCOMING_VARARG_BOUNDS): New. > (TARGET_BUILTIN_CHKP_FUNCTION): New. > (TARGET_CHKP_BOUND_TYPE): New. > (TARGET_CHKP_BOUND_MODE): New. > (TARGET_CHKP_MAKE_BOUNDS_CONSTANT): New. > (TARGET_CHKP_INITIALIZE_BOUNDS): New. > * doc/tm.texi: Regenerated. > > diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi > index b8ca17e..d868129 100644 > --- a/gcc/doc/tm.texi > +++ b/gcc/doc/tm.texi > @@ -4333,6 +4333,13 @@ This hook returns the va_list type of the calling convention specified by > The default version of this hook returns @code{va_list_type_node}. > @end deftypefn > > +@deftypefn {Target Hook} tree TARGET_FN_ABI_VA_LIST_BOUNDS_SIZE (tree @var{fndecl}) > +This hook returns size for @code{va_list} object in function specified > +by @var{fndecl}. This hook is used by Pointer Bounds Checker to build bounds > +for @code{va_list} object. Return @code{integer_zero_node} if no bounds > +should be used (e.g. @code{va_list} is a scalar pointer to the stack). > +@end deftypefn > + > @deftypefn {Target Hook} tree TARGET_CANONICAL_VA_LIST_TYPE (tree @var{type}) > This hook returns the va_list type of the calling convention specified by the > type of @var{type}. If @var{type} is not a valid va_list type, it returns > @@ -5150,6 +5157,49 @@ defined, then define this hook to return @code{true} if > Otherwise, you should not define this hook. > @end deftypefn > > +@deftypefn {Target Hook} rtx TARGET_LOAD_BOUNDS_FOR_ARG (rtx @var{slot}, rtx @var{arg}, rtx @var{slot_no}) > +This hook is used by expand pass to emit insn to load bounds of > +@var{arg} passed in @var{slot}. Expand pass uses this hook in case > +bounds of @var{arg} are not passed in register. If @var{slot} is a > +memory, then bounds are loaded as for regular pointer loaded from > +memory. If @var{slot} is not a memory then @var{slot_no} is an integer > +constant holding number of the target dependent special slot which > +should be used to obtain bounds. Hook returns RTX holding loaded bounds. > +@end deftypefn > + > +@deftypefn {Target Hook} void TARGET_STORE_BOUNDS_FOR_ARG (rtx @var{arg}, rtx @var{slot}, rtx @var{bounds}, rtx @var{slot_no}) > +This hook is used by expand pass to emit insns to store @var{bounds} of > +@var{arg} passed in @var{slot}. Expand pass uses this hook in case > +@var{bounds} of @var{arg} are not passed in register. If @var{slot} is a > +memory, then @var{bounds} are stored as for regular pointer stored in > +memory. If @var{slot} is not a memory then @var{slot_no} is an integer > +constant holding number of the target dependent special slot which > +should be used to store @var{bounds}. > +@end deftypefn > + > +@deftypefn {Target Hook} rtx TARGET_LOAD_RETURNED_BOUNDS (rtx @var{slot}) > +This hook is used by expand pass to emit insn to load bounds > +returned by function call in @var{slot}. Hook returns RTX holding > +loaded bounds. > +@end deftypefn > + > +@deftypefn {Target Hook} void TARGET_STORE_RETURNED_BOUNDS (rtx @var{slot}, rtx @var{bounds}) > +This hook is used by expand pass to emit insn to store @var{bounds} > +returned by function call into @var{slot}. > +@end deftypefn > + > +@deftypefn {Target Hook} rtx TARGET_CHKP_FUNCTION_VALUE_BOUNDS (const_tree @var{ret_type}, const_tree @var{fn_decl_or_type}, bool @var{outgoing}) > +Define this to return an RTX representing the place where a function > +returns bounds for returned pointers. Arguments meaning is similar to > +@code{TARGET_FUNCTION_VALUE}. > +@end deftypefn > + > +@deftypefn {Target Hook} void TARGET_SETUP_INCOMING_VARARG_BOUNDS (cumulative_args_t @var{args_so_far}, enum machine_mode @var{mode}, tree @var{type}, int *@var{pretend_args_size}, int @var{second_time}) > +Use it to store bounds for anonymous register arguments stored > +into the stack. Arguments meaning is similar to > +@code{TARGET_SETUP_INCOMING_VARARGS}. > +@end deftypefn > + > @node Trampolines > @section Trampolines for Nested Functions > @cindex trampolines for nested functions > @@ -10952,6 +11002,93 @@ ignored. This function should return the result of the call to the > built-in function. > @end deftypefn > > +@deftypefn {Target Hook} tree TARGET_BUILTIN_CHKP_FUNCTION (unsigned @var{fcode}) > +This hook allows target to redefine built-in functions used by > +Pointer Bounds Checker for code instrumentation. Hook should return > +fndecl of function implementing generic builtin whose code is > +passed in @var{fcode}. Currently following built-in functions are > +obtained using this hook: > +@deftypefn {Built-in Function} __bounds_type __chkp_bndmk (const void *@var{lb}, size_t @var{size}) > +Function code - BUILT_IN_CHKP_BNDMK. This built-in function is used > +by Pointer Bounds Checker to create bound values. @var{lb} holds low > +bound of the resulting bounds. @var{size} holds size of created bounds. > +@end deftypefn > + > +@deftypefn {Built-in Function} void __chkp_bndstx (const void *@var{ptr}, __bounds_type @var{b}, const void **@var{loc}) > +Function code - @code{BUILT_IN_CHKP_BNDSTX}. This built-in function is used > +by Pointer Bounds Checker to store bounds @var{b} for pointer @var{ptr} > +when @var{ptr} is stored by address @var{loc}. > +@end deftypefn > + > +@deftypefn {Built-in Function} __bounds_type __chkp_bndldx (const void **@var{loc}, const void *@var{ptr}) > +Function code - @code{BUILT_IN_CHKP_BNDLDX}. This built-in function is used > +by Pointer Bounds Checker to get bounds of pointer @var{ptr} loaded by > +address @var{loc}. > +@end deftypefn > + > +@deftypefn {Built-in Function} void __chkp_bndcl (const void *@var{ptr}, __bounds_type @var{b}) > +Function code - @code{BUILT_IN_CHKP_BNDCL}. This built-in function is used > +by Pointer Bounds Checker to perform check for pointer @var{ptr} against > +lower bound of bounds @var{b}. > +@end deftypefn > + > +@deftypefn {Built-in Function} void __chkp_bndcu (const void *@var{ptr}, __bounds_type @var{b}) > +Function code - @code{BUILT_IN_CHKP_BNDCU}. This built-in function is used > +by Pointer Bounds Checker to perform check for pointer @var{ptr} against > +upper bound of bounds @var{b}. > +@end deftypefn > + > +@deftypefn {Built-in Function} __bounds_type __chkp_bndret (void *@var{ptr}) > +Function code - @code{BUILT_IN_CHKP_BNDRET}. This built-in function is used > +by Pointer Bounds Checker to obtain bounds returned by a call statement. > +@var{ptr} passed to built-in is @code{SSA_NAME} returned by the call. > +@end deftypefn > + > +@deftypefn {Built-in Function} __bounds_type __chkp_intersect (__bounds_type @var{b1}, __bounds_type @var{b2}) > +Function code - @code{BUILT_IN_CHKP_INTERSECT}. This built-in function > +returns intersection of bounds @var{b1} and @var{b2}. > +@end deftypefn > + > +@deftypefn {Built-in Function} __bounds_type __chkp_narrow (const void *@var{ptr}, __bounds_type @var{b}, size_t @var{s}) > +Function code - @code{BUILT_IN_CHKP_NARROW}. This built-in function > +returns intersection of bounds @var{b} and > +[@var{ptr}, @var{ptr} + @var{s} - @code{1}]. > +@end deftypefn > + > +@deftypefn {Built-in Function} size_t __chkp_sizeof (const void *@var{ptr}) > +Function code - @code{BUILT_IN_CHKP_SIZEOF}. This built-in function > +returns size of object referenced by @var{ptr}. @var{ptr} is always > +@code{ADDR_EXPR} of @code{VAR_DECL}. This built-in is used by > +Pointer Boudns Checker when bounds of object cannot be computed statically > +(e.g. object has incomplete type). > +@end deftypefn > + > +@deftypefn {Built-in Function} const void *__chkp_extract_lower (__bounds_type @var{b}) > +Function code - @code{BUILT_IN_CHKP_EXTRACT_LOWER}. This built-in function > +returns lower bound of bounds @var{b}. > +@end deftypefn > + > +@deftypefn {Built-in Function} const void *__chkp_extract_upper (__bounds_type @var{b}) > +Function code - @code{BUILT_IN_CHKP_EXTRACT_UPPER}. This built-in function > +returns upper bound of bounds @var{b}. > +@end deftypefn > +@end deftypefn > +@deftypefn {Target Hook} tree TARGET_CHKP_BOUND_TYPE (void) > +Return type to be used for bounds > +@end deftypefn > +@deftypefn {Target Hook} {enum machine_mode} TARGET_CHKP_BOUND_MODE (void) > +Return mode to be used for bounds. > +@end deftypefn > +@deftypefn {Target Hook} tree TARGET_CHKP_MAKE_BOUNDS_CONSTANT (HOST_WIDE_INT @var{lb}, HOST_WIDE_INT @var{ub}) > +Return constant used to statically initialize constant bounds > +with specified lower bound @var{lb} and upper bounds @var{ub}. > +@end deftypefn > +@deftypefn {Target Hook} int TARGET_CHKP_INITIALIZE_BOUNDS (tree @var{var}, tree @var{lb}, tree @var{ub}, tree *@var{stmts}) > +Generate a list of statements @var{stmts} to initialize pointer > +bounds variable @var{var} with bounds @var{lb} and @var{ub}. Return > +the number of generated statements. > +@end deftypefn > + > @deftypefn {Target Hook} tree TARGET_RESOLVE_OVERLOADED_BUILTIN (unsigned int @var{loc}, tree @var{fndecl}, void *@var{arglist}) > Select a replacement for a machine specific built-in function that > was set up by @samp{TARGET_INIT_BUILTINS}. This is done > diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in > index d793d26..5c12180 100644 > --- a/gcc/doc/tm.texi.in > +++ b/gcc/doc/tm.texi.in > @@ -3691,6 +3691,8 @@ stack. > > @hook TARGET_FN_ABI_VA_LIST > > +@hook TARGET_FN_ABI_VA_LIST_BOUNDS_SIZE > + > @hook TARGET_CANONICAL_VA_LIST_TYPE > > @hook TARGET_GIMPLIFY_VA_ARG_EXPR > @@ -4061,6 +4063,18 @@ These machine description macros help implement varargs: > > @hook TARGET_PRETEND_OUTGOING_VARARGS_NAMED > > +@hook TARGET_LOAD_BOUNDS_FOR_ARG > + > +@hook TARGET_STORE_BOUNDS_FOR_ARG > + > +@hook TARGET_LOAD_RETURNED_BOUNDS > + > +@hook TARGET_STORE_RETURNED_BOUNDS > + > +@hook TARGET_CHKP_FUNCTION_VALUE_BOUNDS > + > +@hook TARGET_SETUP_INCOMING_VARARG_BOUNDS > + > @node Trampolines > @section Trampolines for Nested Functions > @cindex trampolines for nested functions > @@ -8206,6 +8220,12 @@ to by @var{ce_info}. > > @hook TARGET_EXPAND_BUILTIN > > +@hook TARGET_BUILTIN_CHKP_FUNCTION > +@hook TARGET_CHKP_BOUND_TYPE > +@hook TARGET_CHKP_BOUND_MODE > +@hook TARGET_CHKP_MAKE_BOUNDS_CONSTANT > +@hook TARGET_CHKP_INITIALIZE_BOUNDS > + > @hook TARGET_RESOLVE_OVERLOADED_BUILTIN > > @hook TARGET_FOLD_BUILTIN > diff --git a/gcc/target.def b/gcc/target.def > index 3a64cd1..53505b5 100644 > --- a/gcc/target.def > +++ b/gcc/target.def > @@ -2078,6 +2078,107 @@ built-in function.", > (tree exp, rtx target, rtx subtarget, enum machine_mode mode, int ignore), > default_expand_builtin) > > +DEFHOOK > +(builtin_chkp_function, > + "This hook allows target to redefine built-in functions used by\n\ > +Pointer Bounds Checker for code instrumentation. Hook should return\n\ > +fndecl of function implementing generic builtin whose code is\n\ > +passed in @var{fcode}. Currently following built-in functions are\n\ > +obtained using this hook:\n\ > +@deftypefn {Built-in Function} __bounds_type __chkp_bndmk (const void *@var{lb}, size_t @var{size})\n\ > +Function code - BUILT_IN_CHKP_BNDMK. This built-in function is used\n\ > +by Pointer Bounds Checker to create bound values. @var{lb} holds low\n\ > +bound of the resulting bounds. @var{size} holds size of created bounds.\n\ > +@end deftypefn\n\ > +\n\ > +@deftypefn {Built-in Function} void __chkp_bndstx (const void *@var{ptr}, __bounds_type @var{b}, const void **@var{loc})\n\ > +Function code - @code{BUILT_IN_CHKP_BNDSTX}. This built-in function is used\n\ > +by Pointer Bounds Checker to store bounds @var{b} for pointer @var{ptr}\n\ > +when @var{ptr} is stored by address @var{loc}.\n\ > +@end deftypefn\n\ > +\n\ > +@deftypefn {Built-in Function} __bounds_type __chkp_bndldx (const void **@var{loc}, const void *@var{ptr})\n\ > +Function code - @code{BUILT_IN_CHKP_BNDLDX}. This built-in function is used\n\ > +by Pointer Bounds Checker to get bounds of pointer @var{ptr} loaded by\n\ > +address @var{loc}.\n\ > +@end deftypefn\n\ > +\n\ > +@deftypefn {Built-in Function} void __chkp_bndcl (const void *@var{ptr}, __bounds_type @var{b})\n\ > +Function code - @code{BUILT_IN_CHKP_BNDCL}. This built-in function is used\n\ > +by Pointer Bounds Checker to perform check for pointer @var{ptr} against\n\ > +lower bound of bounds @var{b}.\n\ > +@end deftypefn\n\ > +\n\ > +@deftypefn {Built-in Function} void __chkp_bndcu (const void *@var{ptr}, __bounds_type @var{b})\n\ > +Function code - @code{BUILT_IN_CHKP_BNDCU}. This built-in function is used\n\ > +by Pointer Bounds Checker to perform check for pointer @var{ptr} against\n\ > +upper bound of bounds @var{b}.\n\ > +@end deftypefn\n\ > +\n\ > +@deftypefn {Built-in Function} __bounds_type __chkp_bndret (void *@var{ptr})\n\ > +Function code - @code{BUILT_IN_CHKP_BNDRET}. This built-in function is used\n\ > +by Pointer Bounds Checker to obtain bounds returned by a call statement.\n\ > +@var{ptr} passed to built-in is @code{SSA_NAME} returned by the call.\n\ > +@end deftypefn\n\ > +\n\ > +@deftypefn {Built-in Function} __bounds_type __chkp_intersect (__bounds_type @var{b1}, __bounds_type @var{b2})\n\ > +Function code - @code{BUILT_IN_CHKP_INTERSECT}. This built-in function\n\ > +returns intersection of bounds @var{b1} and @var{b2}.\n\ > +@end deftypefn\n\ > +\n\ > +@deftypefn {Built-in Function} __bounds_type __chkp_narrow (const void *@var{ptr}, __bounds_type @var{b}, size_t @var{s})\n\ > +Function code - @code{BUILT_IN_CHKP_NARROW}. This built-in function\n\ > +returns intersection of bounds @var{b} and\n\ > +[@var{ptr}, @var{ptr} + @var{s} - @code{1}].\n\ > +@end deftypefn\n\ > +\n\ > +@deftypefn {Built-in Function} size_t __chkp_sizeof (const void *@var{ptr})\n\ > +Function code - @code{BUILT_IN_CHKP_SIZEOF}. This built-in function\n\ > +returns size of object referenced by @var{ptr}. @var{ptr} is always\n\ > +@code{ADDR_EXPR} of @code{VAR_DECL}. This built-in is used by\n\ > +Pointer Boudns Checker when bounds of object cannot be computed statically\n\ > +(e.g. object has incomplete type).\n\ > +@end deftypefn\n\ > +\n\ > +@deftypefn {Built-in Function} const void *__chkp_extract_lower (__bounds_type @var{b})\n\ > +Function code - @code{BUILT_IN_CHKP_EXTRACT_LOWER}. This built-in function\n\ > +returns lower bound of bounds @var{b}.\n\ > +@end deftypefn\n\ > +\n\ > +@deftypefn {Built-in Function} const void *__chkp_extract_upper (__bounds_type @var{b})\n\ > +Function code - @code{BUILT_IN_CHKP_EXTRACT_UPPER}. This built-in function\n\ > +returns upper bound of bounds @var{b}.\n\ > +@end deftypefn", > + tree, (unsigned fcode), > + default_builtin_chkp_function) > + > +DEFHOOK > +(chkp_bound_type, > + "Return type to be used for bounds", > + tree, (void), > + default_chkp_bound_type) > + > +DEFHOOK > +(chkp_bound_mode, > + "Return mode to be used for bounds.", > + enum machine_mode, (void), > + default_chkp_bound_mode) > + > +DEFHOOK > +(chkp_make_bounds_constant, > + "Return constant used to statically initialize constant bounds\n\ > +with specified lower bound @var{lb} and upper bounds @var{ub}.", > + tree, (HOST_WIDE_INT lb, HOST_WIDE_INT ub), > + default_chkp_make_bounds_constant) > + > +DEFHOOK > +(chkp_initialize_bounds, > + "Generate a list of statements @var{stmts} to initialize pointer\n\ > +bounds variable @var{var} with bounds @var{lb} and @var{ub}. Return\n\ > +the number of generated statements.", > + int, (tree var, tree lb, tree ub, tree *stmts), > + default_chkp_initialize_bounds) > + > /* Select a replacement for a target-specific builtin. This is done > *before* regular type checking, and so allows the target to > implement a crude form of function overloading. The result is a > @@ -3328,6 +3429,15 @@ The default version of this hook returns @code{va_list_type_node}.", > tree, (tree fndecl), > std_fn_abi_va_list) > > +DEFHOOK > +(fn_abi_va_list_bounds_size, > + "This hook returns size for @code{va_list} object in function specified\n\ > +by @var{fndecl}. This hook is used by Pointer Bounds Checker to build bounds\n\ > +for @code{va_list} object. Return @code{integer_zero_node} if no bounds\n\ > +should be used (e.g. @code{va_list} is a scalar pointer to the stack).", > + tree, (tree fndecl), > + default_fn_abi_va_list_bounds_size) > + > /* Get the __builtin_va_list type dependent on input type. */ > DEFHOOK > (canonical_va_list_type, > @@ -3776,6 +3886,54 @@ not generate any instructions in this case.", > default_setup_incoming_varargs) > > DEFHOOK > +(load_bounds_for_arg, > + "This hook is used by expand pass to emit insn to load bounds of\n\ > +@var{arg} passed in @var{slot}. Expand pass uses this hook in case\n\ > +bounds of @var{arg} are not passed in register. If @var{slot} is a\n\ > +memory, then bounds are loaded as for regular pointer loaded from\n\ > +memory. If @var{slot} is not a memory then @var{slot_no} is an integer\n\ > +constant holding number of the target dependent special slot which\n\ > +should be used to obtain bounds. Hook returns RTX holding loaded bounds.", > + rtx, (rtx slot, rtx arg, rtx slot_no), > + default_load_bounds_for_arg) > + > +DEFHOOK > +(store_bounds_for_arg, > + "This hook is used by expand pass to emit insns to store @var{bounds} of\n\ > +@var{arg} passed in @var{slot}. Expand pass uses this hook in case\n\ > +@var{bounds} of @var{arg} are not passed in register. If @var{slot} is a\n\ > +memory, then @var{bounds} are stored as for regular pointer stored in\n\ > +memory. If @var{slot} is not a memory then @var{slot_no} is an integer\n\ > +constant holding number of the target dependent special slot which\n\ > +should be used to store @var{bounds}.", > + void, (rtx arg, rtx slot, rtx bounds, rtx slot_no), > + default_store_bounds_for_arg) > + > +DEFHOOK > +(load_returned_bounds, > + "This hook is used by expand pass to emit insn to load bounds\n\ > +returned by function call in @var{slot}. Hook returns RTX holding\n\ > +loaded bounds.", > + rtx, (rtx slot), > + default_load_returned_bounds) > + > +DEFHOOK > +(store_returned_bounds, > + "This hook is used by expand pass to emit insn to store @var{bounds}\n\ > +returned by function call into @var{slot}.", > + void, (rtx slot, rtx bounds), > + default_store_returned_bounds) > + > +DEFHOOK > +(setup_incoming_vararg_bounds, > + "Use it to store bounds for anonymous register arguments stored\n\ > +into the stack. Arguments meaning is similar to\n\ > +@code{TARGET_SETUP_INCOMING_VARARGS}.", > + void, (cumulative_args_t args_so_far, enum machine_mode mode, tree type, > + int *pretend_args_size, int second_time), > + default_setup_incoming_vararg_bounds) > + > +DEFHOOK > (strict_argument_naming, > "Define this hook to return @code{true} if the location where a function\n\ > argument is passed depends on whether or not it is a named argument.\n\ > @@ -4052,6 +4210,15 @@ aggregate data types, because these are returned in another way. See\n\ > rtx, (const_tree ret_type, const_tree fn_decl_or_type, bool outgoing), > default_function_value) > > +/* Return the rtx for bounds of returned pointer. */ > +DEFHOOK > +(chkp_function_value_bounds, > + "Define this to return an RTX representing the place where a function\n\ > +returns bounds for returned pointers. Arguments meaning is similar to\n\ > +@code{TARGET_FUNCTION_VALUE}.", > + rtx, (const_tree ret_type, const_tree fn_decl_or_type, bool outgoing), > + default_chkp_function_value_bounds) > + > /* Return the rtx for the result of a libcall of mode MODE, > calling the function FN_NAME. */ > DEFHOOK > diff --git a/gcc/targhooks.c b/gcc/targhooks.c > index 79491c7..28e200e 100644 > --- a/gcc/targhooks.c > +++ b/gcc/targhooks.c > @@ -1574,6 +1574,42 @@ default_member_type_forces_blk (const_tree, enum machine_mode) > return false; > } > > +rtx > +default_load_bounds_for_arg (rtx addr ATTRIBUTE_UNUSED, > + rtx ptr ATTRIBUTE_UNUSED, > + rtx bnd ATTRIBUTE_UNUSED) > +{ > + gcc_unreachable (); > +} > + > +void > +default_store_bounds_for_arg (rtx val ATTRIBUTE_UNUSED, > + rtx addr ATTRIBUTE_UNUSED, > + rtx bounds ATTRIBUTE_UNUSED, > + rtx to ATTRIBUTE_UNUSED) > +{ > + gcc_unreachable (); > +} > + > +rtx > +default_load_returned_bounds (rtx slot ATTRIBUTE_UNUSED) > +{ > + gcc_unreachable (); > +} > + > +void > +default_store_returned_bounds (rtx slot ATTRIBUTE_UNUSED, > + rtx bounds ATTRIBUTE_UNUSED) > +{ > + gcc_unreachable (); > +} > + > +tree > +default_fn_abi_va_list_bounds_size (tree fndecl ATTRIBUTE_UNUSED) > +{ > + return integer_zero_node; > +} > + > /* Default version of canonicalize_comparison. */ > > void > @@ -1698,6 +1734,62 @@ std_gimplify_va_arg_expr (tree valist, tree type, gimple_seq *pre_p, > return build_va_arg_indirect_ref (addr); > } > > +tree > +default_chkp_bound_type (void) > +{ > + tree res = make_node (POINTER_BOUNDS_TYPE); > + TYPE_PRECISION (res) = TYPE_PRECISION (size_type_node) * 2; > + TYPE_NAME (res) = get_identifier ("__bounds_type"); > + SET_TYPE_MODE (res, targetm.chkp_bound_mode ()); > + layout_type (res); > + return res; > +} > + > +enum machine_mode > +default_chkp_bound_mode (void) > +{ > + return VOIDmode; > +} > + > +tree > +default_builtin_chkp_function (unsigned int fcode ATTRIBUTE_UNUSED) > +{ > + return NULL_TREE; > +} > + > +rtx > +default_chkp_function_value_bounds (const_tree ret_type ATTRIBUTE_UNUSED, > + const_tree fn_decl_or_type ATTRIBUTE_UNUSED, > + bool outgoing ATTRIBUTE_UNUSED) > +{ > + gcc_unreachable (); > +} > + > +tree > +default_chkp_make_bounds_constant (HOST_WIDE_INT lb ATTRIBUTE_UNUSED, > + HOST_WIDE_INT ub ATTRIBUTE_UNUSED) > +{ > + return NULL_TREE; > +} > + > +int > +default_chkp_initialize_bounds (tree var ATTRIBUTE_UNUSED, > + tree lb ATTRIBUTE_UNUSED, > + tree ub ATTRIBUTE_UNUSED, > + tree *stmts ATTRIBUTE_UNUSED) > +{ > + return 0; > +} > + > +void > +default_setup_incoming_vararg_bounds (cumulative_args_t ca ATTRIBUTE_UNUSED, > + enum machine_mode mode ATTRIBUTE_UNUSED, > + tree type ATTRIBUTE_UNUSED, > + int *pretend_arg_size ATTRIBUTE_UNUSED, > + int second_time ATTRIBUTE_UNUSED) > +{ > +} > + > /* An implementation of TARGET_CAN_USE_DOLOOP_P for targets that do > not support nested low-overhead loops. */ > > diff --git a/gcc/targhooks.h b/gcc/targhooks.h > index 9dd4c83..4eaf88b 100644 > --- a/gcc/targhooks.h > +++ b/gcc/targhooks.h > @@ -206,5 +206,23 @@ extern bool default_member_type_forces_blk (const_tree, enum machine_mode); > extern void default_atomic_assign_expand_fenv (tree *, tree *, tree *); > extern tree build_va_arg_indirect_ref (tree); > extern tree std_gimplify_va_arg_expr (tree, tree, gimple_seq *, gimple_seq *); > + > +extern rtx default_load_bounds_for_arg (rtx, rtx, rtx); > +extern void default_store_bounds_for_arg (rtx, rtx, rtx, rtx); > +extern rtx default_load_returned_bounds (rtx); > +extern void default_store_returned_bounds (rtx,rtx); > +extern tree default_fn_abi_va_list_bounds_size (tree); > +extern tree default_chkp_bound_type (void); > +extern enum machine_mode default_chkp_bound_mode (void); > +extern tree default_builtin_chkp_function (unsigned int); > +extern rtx default_chkp_function_value_bounds (const_tree, const_tree, bool); > +extern tree default_chkp_make_bounds_constant (HOST_WIDE_INT lb, HOST_WIDE_INT ub); > +extern int default_chkp_initialize_bounds (tree var, tree lb, tree ub, > + tree *stmts); > +extern void default_setup_incoming_vararg_bounds (cumulative_args_t ca ATTRIBUTE_UNUSED, > + enum machine_mode mode ATTRIBUTE_UNUSED, > + tree type ATTRIBUTE_UNUSED, > + int *pretend_arg_size ATTRIBUTE_UNUSED, > + int second_time ATTRIBUTE_UNUSED); > extern bool can_use_doloop_if_innermost (double_int, double_int, > unsigned int, bool);
Ping 2014-05-06 16:11 GMT+04:00 Ilya Enkovich <enkovich.gnu@gmail.com>: > PING > > 2014-04-16 15:52 GMT+04:00 Ilya Enkovich <enkovich.gnu@gmail.com>: >> Hi, >> >> This patch introduces target hooks to be used by Pointer Bounds Checker. Hooks set is different from what was approved for 4.9 (and later reverted). I added hooks to work with returned bounds and to prepare incoming bounds for vararg functions. It allowed to remove some target assumptions from expand code. >> >> Bootstrapped and tested on linux-x86_64. >> >> OK for trunk? >> >> Thanks, >> Ilya >> -- >> gcc/ >> >> 2014-04-16 Ilya Enkovich <ilya.enkovich@intel.com> >> >> * target.def (builtin_chkp_function): New. >> (chkp_bound_type): New. >> (chkp_bound_mode): New. >> (chkp_make_bounds_constant): New. >> (chkp_initialize_bounds): New. >> (fn_abi_va_list_bounds_size): New. >> (load_bounds_for_arg): New. >> (store_bounds_for_arg): New. >> (load_returned_bounds): New. >> (store_returned_bounds): New. >> (chkp_function_value_bounds): New. >> (setup_incoming_vararg_bounds): New. >> * targhooks.h (default_load_bounds_for_arg): New. >> (default_store_bounds_for_arg): New. >> (default_load_returned_bounds): New. >> (default_store_returned_bounds): New. >> (default_fn_abi_va_list_bounds_size): New. >> (default_chkp_bound_type): New. >> (default_chkp_bound_mode): New. >> (default_builtin_chkp_function): New. >> (default_chkp_function_value_bounds): New. >> (default_chkp_make_bounds_constant): New. >> (default_chkp_initialize_bounds): New. >> (default_setup_incoming_vararg_bounds): New. >> * targhooks.c (default_load_bounds_for_arg): New. >> (default_store_bounds_for_arg): New. >> (default_load_returned_bounds): New. >> (default_store_returned_bounds): New. >> (default_fn_abi_va_list_bounds_size): New. >> (default_chkp_bound_type): New. >> (default_chkp_bound_mode); New. >> (default_builtin_chkp_function): New. >> (default_chkp_function_value_bounds): New. >> (default_chkp_make_bounds_constant): New. >> (default_chkp_initialize_bounds): New. >> (default_setup_incoming_vararg_bounds): New. >> * doc/tm.texi.in (TARGET_FN_ABI_VA_LIST_BOUNDS_SIZE): New. >> (TARGET_LOAD_BOUNDS_FOR_ARG): New. >> (TARGET_STORE_BOUNDS_FOR_ARG): New. >> (TARGET_LOAD_RETURNED_BOUNDS): New. >> (TARGET_STORE_RETURNED_BOUNDS): New. >> (TARGET_CHKP_FUNCTION_VALUE_BOUNDS): New. >> (TARGET_SETUP_INCOMING_VARARG_BOUNDS): New. >> (TARGET_BUILTIN_CHKP_FUNCTION): New. >> (TARGET_CHKP_BOUND_TYPE): New. >> (TARGET_CHKP_BOUND_MODE): New. >> (TARGET_CHKP_MAKE_BOUNDS_CONSTANT): New. >> (TARGET_CHKP_INITIALIZE_BOUNDS): New. >> * doc/tm.texi: Regenerated. >> >> diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi >> index b8ca17e..d868129 100644 >> --- a/gcc/doc/tm.texi >> +++ b/gcc/doc/tm.texi >> @@ -4333,6 +4333,13 @@ This hook returns the va_list type of the calling convention specified by >> The default version of this hook returns @code{va_list_type_node}. >> @end deftypefn >> >> +@deftypefn {Target Hook} tree TARGET_FN_ABI_VA_LIST_BOUNDS_SIZE (tree @var{fndecl}) >> +This hook returns size for @code{va_list} object in function specified >> +by @var{fndecl}. This hook is used by Pointer Bounds Checker to build bounds >> +for @code{va_list} object. Return @code{integer_zero_node} if no bounds >> +should be used (e.g. @code{va_list} is a scalar pointer to the stack). >> +@end deftypefn >> + >> @deftypefn {Target Hook} tree TARGET_CANONICAL_VA_LIST_TYPE (tree @var{type}) >> This hook returns the va_list type of the calling convention specified by the >> type of @var{type}. If @var{type} is not a valid va_list type, it returns >> @@ -5150,6 +5157,49 @@ defined, then define this hook to return @code{true} if >> Otherwise, you should not define this hook. >> @end deftypefn >> >> +@deftypefn {Target Hook} rtx TARGET_LOAD_BOUNDS_FOR_ARG (rtx @var{slot}, rtx @var{arg}, rtx @var{slot_no}) >> +This hook is used by expand pass to emit insn to load bounds of >> +@var{arg} passed in @var{slot}. Expand pass uses this hook in case >> +bounds of @var{arg} are not passed in register. If @var{slot} is a >> +memory, then bounds are loaded as for regular pointer loaded from >> +memory. If @var{slot} is not a memory then @var{slot_no} is an integer >> +constant holding number of the target dependent special slot which >> +should be used to obtain bounds. Hook returns RTX holding loaded bounds. >> +@end deftypefn >> + >> +@deftypefn {Target Hook} void TARGET_STORE_BOUNDS_FOR_ARG (rtx @var{arg}, rtx @var{slot}, rtx @var{bounds}, rtx @var{slot_no}) >> +This hook is used by expand pass to emit insns to store @var{bounds} of >> +@var{arg} passed in @var{slot}. Expand pass uses this hook in case >> +@var{bounds} of @var{arg} are not passed in register. If @var{slot} is a >> +memory, then @var{bounds} are stored as for regular pointer stored in >> +memory. If @var{slot} is not a memory then @var{slot_no} is an integer >> +constant holding number of the target dependent special slot which >> +should be used to store @var{bounds}. >> +@end deftypefn >> + >> +@deftypefn {Target Hook} rtx TARGET_LOAD_RETURNED_BOUNDS (rtx @var{slot}) >> +This hook is used by expand pass to emit insn to load bounds >> +returned by function call in @var{slot}. Hook returns RTX holding >> +loaded bounds. >> +@end deftypefn >> + >> +@deftypefn {Target Hook} void TARGET_STORE_RETURNED_BOUNDS (rtx @var{slot}, rtx @var{bounds}) >> +This hook is used by expand pass to emit insn to store @var{bounds} >> +returned by function call into @var{slot}. >> +@end deftypefn >> + >> +@deftypefn {Target Hook} rtx TARGET_CHKP_FUNCTION_VALUE_BOUNDS (const_tree @var{ret_type}, const_tree @var{fn_decl_or_type}, bool @var{outgoing}) >> +Define this to return an RTX representing the place where a function >> +returns bounds for returned pointers. Arguments meaning is similar to >> +@code{TARGET_FUNCTION_VALUE}. >> +@end deftypefn >> + >> +@deftypefn {Target Hook} void TARGET_SETUP_INCOMING_VARARG_BOUNDS (cumulative_args_t @var{args_so_far}, enum machine_mode @var{mode}, tree @var{type}, int *@var{pretend_args_size}, int @var{second_time}) >> +Use it to store bounds for anonymous register arguments stored >> +into the stack. Arguments meaning is similar to >> +@code{TARGET_SETUP_INCOMING_VARARGS}. >> +@end deftypefn >> + >> @node Trampolines >> @section Trampolines for Nested Functions >> @cindex trampolines for nested functions >> @@ -10952,6 +11002,93 @@ ignored. This function should return the result of the call to the >> built-in function. >> @end deftypefn >> >> +@deftypefn {Target Hook} tree TARGET_BUILTIN_CHKP_FUNCTION (unsigned @var{fcode}) >> +This hook allows target to redefine built-in functions used by >> +Pointer Bounds Checker for code instrumentation. Hook should return >> +fndecl of function implementing generic builtin whose code is >> +passed in @var{fcode}. Currently following built-in functions are >> +obtained using this hook: >> +@deftypefn {Built-in Function} __bounds_type __chkp_bndmk (const void *@var{lb}, size_t @var{size}) >> +Function code - BUILT_IN_CHKP_BNDMK. This built-in function is used >> +by Pointer Bounds Checker to create bound values. @var{lb} holds low >> +bound of the resulting bounds. @var{size} holds size of created bounds. >> +@end deftypefn >> + >> +@deftypefn {Built-in Function} void __chkp_bndstx (const void *@var{ptr}, __bounds_type @var{b}, const void **@var{loc}) >> +Function code - @code{BUILT_IN_CHKP_BNDSTX}. This built-in function is used >> +by Pointer Bounds Checker to store bounds @var{b} for pointer @var{ptr} >> +when @var{ptr} is stored by address @var{loc}. >> +@end deftypefn >> + >> +@deftypefn {Built-in Function} __bounds_type __chkp_bndldx (const void **@var{loc}, const void *@var{ptr}) >> +Function code - @code{BUILT_IN_CHKP_BNDLDX}. This built-in function is used >> +by Pointer Bounds Checker to get bounds of pointer @var{ptr} loaded by >> +address @var{loc}. >> +@end deftypefn >> + >> +@deftypefn {Built-in Function} void __chkp_bndcl (const void *@var{ptr}, __bounds_type @var{b}) >> +Function code - @code{BUILT_IN_CHKP_BNDCL}. This built-in function is used >> +by Pointer Bounds Checker to perform check for pointer @var{ptr} against >> +lower bound of bounds @var{b}. >> +@end deftypefn >> + >> +@deftypefn {Built-in Function} void __chkp_bndcu (const void *@var{ptr}, __bounds_type @var{b}) >> +Function code - @code{BUILT_IN_CHKP_BNDCU}. This built-in function is used >> +by Pointer Bounds Checker to perform check for pointer @var{ptr} against >> +upper bound of bounds @var{b}. >> +@end deftypefn >> + >> +@deftypefn {Built-in Function} __bounds_type __chkp_bndret (void *@var{ptr}) >> +Function code - @code{BUILT_IN_CHKP_BNDRET}. This built-in function is used >> +by Pointer Bounds Checker to obtain bounds returned by a call statement. >> +@var{ptr} passed to built-in is @code{SSA_NAME} returned by the call. >> +@end deftypefn >> + >> +@deftypefn {Built-in Function} __bounds_type __chkp_intersect (__bounds_type @var{b1}, __bounds_type @var{b2}) >> +Function code - @code{BUILT_IN_CHKP_INTERSECT}. This built-in function >> +returns intersection of bounds @var{b1} and @var{b2}. >> +@end deftypefn >> + >> +@deftypefn {Built-in Function} __bounds_type __chkp_narrow (const void *@var{ptr}, __bounds_type @var{b}, size_t @var{s}) >> +Function code - @code{BUILT_IN_CHKP_NARROW}. This built-in function >> +returns intersection of bounds @var{b} and >> +[@var{ptr}, @var{ptr} + @var{s} - @code{1}]. >> +@end deftypefn >> + >> +@deftypefn {Built-in Function} size_t __chkp_sizeof (const void *@var{ptr}) >> +Function code - @code{BUILT_IN_CHKP_SIZEOF}. This built-in function >> +returns size of object referenced by @var{ptr}. @var{ptr} is always >> +@code{ADDR_EXPR} of @code{VAR_DECL}. This built-in is used by >> +Pointer Boudns Checker when bounds of object cannot be computed statically >> +(e.g. object has incomplete type). >> +@end deftypefn >> + >> +@deftypefn {Built-in Function} const void *__chkp_extract_lower (__bounds_type @var{b}) >> +Function code - @code{BUILT_IN_CHKP_EXTRACT_LOWER}. This built-in function >> +returns lower bound of bounds @var{b}. >> +@end deftypefn >> + >> +@deftypefn {Built-in Function} const void *__chkp_extract_upper (__bounds_type @var{b}) >> +Function code - @code{BUILT_IN_CHKP_EXTRACT_UPPER}. This built-in function >> +returns upper bound of bounds @var{b}. >> +@end deftypefn >> +@end deftypefn >> +@deftypefn {Target Hook} tree TARGET_CHKP_BOUND_TYPE (void) >> +Return type to be used for bounds >> +@end deftypefn >> +@deftypefn {Target Hook} {enum machine_mode} TARGET_CHKP_BOUND_MODE (void) >> +Return mode to be used for bounds. >> +@end deftypefn >> +@deftypefn {Target Hook} tree TARGET_CHKP_MAKE_BOUNDS_CONSTANT (HOST_WIDE_INT @var{lb}, HOST_WIDE_INT @var{ub}) >> +Return constant used to statically initialize constant bounds >> +with specified lower bound @var{lb} and upper bounds @var{ub}. >> +@end deftypefn >> +@deftypefn {Target Hook} int TARGET_CHKP_INITIALIZE_BOUNDS (tree @var{var}, tree @var{lb}, tree @var{ub}, tree *@var{stmts}) >> +Generate a list of statements @var{stmts} to initialize pointer >> +bounds variable @var{var} with bounds @var{lb} and @var{ub}. Return >> +the number of generated statements. >> +@end deftypefn >> + >> @deftypefn {Target Hook} tree TARGET_RESOLVE_OVERLOADED_BUILTIN (unsigned int @var{loc}, tree @var{fndecl}, void *@var{arglist}) >> Select a replacement for a machine specific built-in function that >> was set up by @samp{TARGET_INIT_BUILTINS}. This is done >> diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in >> index d793d26..5c12180 100644 >> --- a/gcc/doc/tm.texi.in >> +++ b/gcc/doc/tm.texi.in >> @@ -3691,6 +3691,8 @@ stack. >> >> @hook TARGET_FN_ABI_VA_LIST >> >> +@hook TARGET_FN_ABI_VA_LIST_BOUNDS_SIZE >> + >> @hook TARGET_CANONICAL_VA_LIST_TYPE >> >> @hook TARGET_GIMPLIFY_VA_ARG_EXPR >> @@ -4061,6 +4063,18 @@ These machine description macros help implement varargs: >> >> @hook TARGET_PRETEND_OUTGOING_VARARGS_NAMED >> >> +@hook TARGET_LOAD_BOUNDS_FOR_ARG >> + >> +@hook TARGET_STORE_BOUNDS_FOR_ARG >> + >> +@hook TARGET_LOAD_RETURNED_BOUNDS >> + >> +@hook TARGET_STORE_RETURNED_BOUNDS >> + >> +@hook TARGET_CHKP_FUNCTION_VALUE_BOUNDS >> + >> +@hook TARGET_SETUP_INCOMING_VARARG_BOUNDS >> + >> @node Trampolines >> @section Trampolines for Nested Functions >> @cindex trampolines for nested functions >> @@ -8206,6 +8220,12 @@ to by @var{ce_info}. >> >> @hook TARGET_EXPAND_BUILTIN >> >> +@hook TARGET_BUILTIN_CHKP_FUNCTION >> +@hook TARGET_CHKP_BOUND_TYPE >> +@hook TARGET_CHKP_BOUND_MODE >> +@hook TARGET_CHKP_MAKE_BOUNDS_CONSTANT >> +@hook TARGET_CHKP_INITIALIZE_BOUNDS >> + >> @hook TARGET_RESOLVE_OVERLOADED_BUILTIN >> >> @hook TARGET_FOLD_BUILTIN >> diff --git a/gcc/target.def b/gcc/target.def >> index 3a64cd1..53505b5 100644 >> --- a/gcc/target.def >> +++ b/gcc/target.def >> @@ -2078,6 +2078,107 @@ built-in function.", >> (tree exp, rtx target, rtx subtarget, enum machine_mode mode, int ignore), >> default_expand_builtin) >> >> +DEFHOOK >> +(builtin_chkp_function, >> + "This hook allows target to redefine built-in functions used by\n\ >> +Pointer Bounds Checker for code instrumentation. Hook should return\n\ >> +fndecl of function implementing generic builtin whose code is\n\ >> +passed in @var{fcode}. Currently following built-in functions are\n\ >> +obtained using this hook:\n\ >> +@deftypefn {Built-in Function} __bounds_type __chkp_bndmk (const void *@var{lb}, size_t @var{size})\n\ >> +Function code - BUILT_IN_CHKP_BNDMK. This built-in function is used\n\ >> +by Pointer Bounds Checker to create bound values. @var{lb} holds low\n\ >> +bound of the resulting bounds. @var{size} holds size of created bounds.\n\ >> +@end deftypefn\n\ >> +\n\ >> +@deftypefn {Built-in Function} void __chkp_bndstx (const void *@var{ptr}, __bounds_type @var{b}, const void **@var{loc})\n\ >> +Function code - @code{BUILT_IN_CHKP_BNDSTX}. This built-in function is used\n\ >> +by Pointer Bounds Checker to store bounds @var{b} for pointer @var{ptr}\n\ >> +when @var{ptr} is stored by address @var{loc}.\n\ >> +@end deftypefn\n\ >> +\n\ >> +@deftypefn {Built-in Function} __bounds_type __chkp_bndldx (const void **@var{loc}, const void *@var{ptr})\n\ >> +Function code - @code{BUILT_IN_CHKP_BNDLDX}. This built-in function is used\n\ >> +by Pointer Bounds Checker to get bounds of pointer @var{ptr} loaded by\n\ >> +address @var{loc}.\n\ >> +@end deftypefn\n\ >> +\n\ >> +@deftypefn {Built-in Function} void __chkp_bndcl (const void *@var{ptr}, __bounds_type @var{b})\n\ >> +Function code - @code{BUILT_IN_CHKP_BNDCL}. This built-in function is used\n\ >> +by Pointer Bounds Checker to perform check for pointer @var{ptr} against\n\ >> +lower bound of bounds @var{b}.\n\ >> +@end deftypefn\n\ >> +\n\ >> +@deftypefn {Built-in Function} void __chkp_bndcu (const void *@var{ptr}, __bounds_type @var{b})\n\ >> +Function code - @code{BUILT_IN_CHKP_BNDCU}. This built-in function is used\n\ >> +by Pointer Bounds Checker to perform check for pointer @var{ptr} against\n\ >> +upper bound of bounds @var{b}.\n\ >> +@end deftypefn\n\ >> +\n\ >> +@deftypefn {Built-in Function} __bounds_type __chkp_bndret (void *@var{ptr})\n\ >> +Function code - @code{BUILT_IN_CHKP_BNDRET}. This built-in function is used\n\ >> +by Pointer Bounds Checker to obtain bounds returned by a call statement.\n\ >> +@var{ptr} passed to built-in is @code{SSA_NAME} returned by the call.\n\ >> +@end deftypefn\n\ >> +\n\ >> +@deftypefn {Built-in Function} __bounds_type __chkp_intersect (__bounds_type @var{b1}, __bounds_type @var{b2})\n\ >> +Function code - @code{BUILT_IN_CHKP_INTERSECT}. This built-in function\n\ >> +returns intersection of bounds @var{b1} and @var{b2}.\n\ >> +@end deftypefn\n\ >> +\n\ >> +@deftypefn {Built-in Function} __bounds_type __chkp_narrow (const void *@var{ptr}, __bounds_type @var{b}, size_t @var{s})\n\ >> +Function code - @code{BUILT_IN_CHKP_NARROW}. This built-in function\n\ >> +returns intersection of bounds @var{b} and\n\ >> +[@var{ptr}, @var{ptr} + @var{s} - @code{1}].\n\ >> +@end deftypefn\n\ >> +\n\ >> +@deftypefn {Built-in Function} size_t __chkp_sizeof (const void *@var{ptr})\n\ >> +Function code - @code{BUILT_IN_CHKP_SIZEOF}. This built-in function\n\ >> +returns size of object referenced by @var{ptr}. @var{ptr} is always\n\ >> +@code{ADDR_EXPR} of @code{VAR_DECL}. This built-in is used by\n\ >> +Pointer Boudns Checker when bounds of object cannot be computed statically\n\ >> +(e.g. object has incomplete type).\n\ >> +@end deftypefn\n\ >> +\n\ >> +@deftypefn {Built-in Function} const void *__chkp_extract_lower (__bounds_type @var{b})\n\ >> +Function code - @code{BUILT_IN_CHKP_EXTRACT_LOWER}. This built-in function\n\ >> +returns lower bound of bounds @var{b}.\n\ >> +@end deftypefn\n\ >> +\n\ >> +@deftypefn {Built-in Function} const void *__chkp_extract_upper (__bounds_type @var{b})\n\ >> +Function code - @code{BUILT_IN_CHKP_EXTRACT_UPPER}. This built-in function\n\ >> +returns upper bound of bounds @var{b}.\n\ >> +@end deftypefn", >> + tree, (unsigned fcode), >> + default_builtin_chkp_function) >> + >> +DEFHOOK >> +(chkp_bound_type, >> + "Return type to be used for bounds", >> + tree, (void), >> + default_chkp_bound_type) >> + >> +DEFHOOK >> +(chkp_bound_mode, >> + "Return mode to be used for bounds.", >> + enum machine_mode, (void), >> + default_chkp_bound_mode) >> + >> +DEFHOOK >> +(chkp_make_bounds_constant, >> + "Return constant used to statically initialize constant bounds\n\ >> +with specified lower bound @var{lb} and upper bounds @var{ub}.", >> + tree, (HOST_WIDE_INT lb, HOST_WIDE_INT ub), >> + default_chkp_make_bounds_constant) >> + >> +DEFHOOK >> +(chkp_initialize_bounds, >> + "Generate a list of statements @var{stmts} to initialize pointer\n\ >> +bounds variable @var{var} with bounds @var{lb} and @var{ub}. Return\n\ >> +the number of generated statements.", >> + int, (tree var, tree lb, tree ub, tree *stmts), >> + default_chkp_initialize_bounds) >> + >> /* Select a replacement for a target-specific builtin. This is done >> *before* regular type checking, and so allows the target to >> implement a crude form of function overloading. The result is a >> @@ -3328,6 +3429,15 @@ The default version of this hook returns @code{va_list_type_node}.", >> tree, (tree fndecl), >> std_fn_abi_va_list) >> >> +DEFHOOK >> +(fn_abi_va_list_bounds_size, >> + "This hook returns size for @code{va_list} object in function specified\n\ >> +by @var{fndecl}. This hook is used by Pointer Bounds Checker to build bounds\n\ >> +for @code{va_list} object. Return @code{integer_zero_node} if no bounds\n\ >> +should be used (e.g. @code{va_list} is a scalar pointer to the stack).", >> + tree, (tree fndecl), >> + default_fn_abi_va_list_bounds_size) >> + >> /* Get the __builtin_va_list type dependent on input type. */ >> DEFHOOK >> (canonical_va_list_type, >> @@ -3776,6 +3886,54 @@ not generate any instructions in this case.", >> default_setup_incoming_varargs) >> >> DEFHOOK >> +(load_bounds_for_arg, >> + "This hook is used by expand pass to emit insn to load bounds of\n\ >> +@var{arg} passed in @var{slot}. Expand pass uses this hook in case\n\ >> +bounds of @var{arg} are not passed in register. If @var{slot} is a\n\ >> +memory, then bounds are loaded as for regular pointer loaded from\n\ >> +memory. If @var{slot} is not a memory then @var{slot_no} is an integer\n\ >> +constant holding number of the target dependent special slot which\n\ >> +should be used to obtain bounds. Hook returns RTX holding loaded bounds.", >> + rtx, (rtx slot, rtx arg, rtx slot_no), >> + default_load_bounds_for_arg) >> + >> +DEFHOOK >> +(store_bounds_for_arg, >> + "This hook is used by expand pass to emit insns to store @var{bounds} of\n\ >> +@var{arg} passed in @var{slot}. Expand pass uses this hook in case\n\ >> +@var{bounds} of @var{arg} are not passed in register. If @var{slot} is a\n\ >> +memory, then @var{bounds} are stored as for regular pointer stored in\n\ >> +memory. If @var{slot} is not a memory then @var{slot_no} is an integer\n\ >> +constant holding number of the target dependent special slot which\n\ >> +should be used to store @var{bounds}.", >> + void, (rtx arg, rtx slot, rtx bounds, rtx slot_no), >> + default_store_bounds_for_arg) >> + >> +DEFHOOK >> +(load_returned_bounds, >> + "This hook is used by expand pass to emit insn to load bounds\n\ >> +returned by function call in @var{slot}. Hook returns RTX holding\n\ >> +loaded bounds.", >> + rtx, (rtx slot), >> + default_load_returned_bounds) >> + >> +DEFHOOK >> +(store_returned_bounds, >> + "This hook is used by expand pass to emit insn to store @var{bounds}\n\ >> +returned by function call into @var{slot}.", >> + void, (rtx slot, rtx bounds), >> + default_store_returned_bounds) >> + >> +DEFHOOK >> +(setup_incoming_vararg_bounds, >> + "Use it to store bounds for anonymous register arguments stored\n\ >> +into the stack. Arguments meaning is similar to\n\ >> +@code{TARGET_SETUP_INCOMING_VARARGS}.", >> + void, (cumulative_args_t args_so_far, enum machine_mode mode, tree type, >> + int *pretend_args_size, int second_time), >> + default_setup_incoming_vararg_bounds) >> + >> +DEFHOOK >> (strict_argument_naming, >> "Define this hook to return @code{true} if the location where a function\n\ >> argument is passed depends on whether or not it is a named argument.\n\ >> @@ -4052,6 +4210,15 @@ aggregate data types, because these are returned in another way. See\n\ >> rtx, (const_tree ret_type, const_tree fn_decl_or_type, bool outgoing), >> default_function_value) >> >> +/* Return the rtx for bounds of returned pointer. */ >> +DEFHOOK >> +(chkp_function_value_bounds, >> + "Define this to return an RTX representing the place where a function\n\ >> +returns bounds for returned pointers. Arguments meaning is similar to\n\ >> +@code{TARGET_FUNCTION_VALUE}.", >> + rtx, (const_tree ret_type, const_tree fn_decl_or_type, bool outgoing), >> + default_chkp_function_value_bounds) >> + >> /* Return the rtx for the result of a libcall of mode MODE, >> calling the function FN_NAME. */ >> DEFHOOK >> diff --git a/gcc/targhooks.c b/gcc/targhooks.c >> index 79491c7..28e200e 100644 >> --- a/gcc/targhooks.c >> +++ b/gcc/targhooks.c >> @@ -1574,6 +1574,42 @@ default_member_type_forces_blk (const_tree, enum machine_mode) >> return false; >> } >> >> +rtx >> +default_load_bounds_for_arg (rtx addr ATTRIBUTE_UNUSED, >> + rtx ptr ATTRIBUTE_UNUSED, >> + rtx bnd ATTRIBUTE_UNUSED) >> +{ >> + gcc_unreachable (); >> +} >> + >> +void >> +default_store_bounds_for_arg (rtx val ATTRIBUTE_UNUSED, >> + rtx addr ATTRIBUTE_UNUSED, >> + rtx bounds ATTRIBUTE_UNUSED, >> + rtx to ATTRIBUTE_UNUSED) >> +{ >> + gcc_unreachable (); >> +} >> + >> +rtx >> +default_load_returned_bounds (rtx slot ATTRIBUTE_UNUSED) >> +{ >> + gcc_unreachable (); >> +} >> + >> +void >> +default_store_returned_bounds (rtx slot ATTRIBUTE_UNUSED, >> + rtx bounds ATTRIBUTE_UNUSED) >> +{ >> + gcc_unreachable (); >> +} >> + >> +tree >> +default_fn_abi_va_list_bounds_size (tree fndecl ATTRIBUTE_UNUSED) >> +{ >> + return integer_zero_node; >> +} >> + >> /* Default version of canonicalize_comparison. */ >> >> void >> @@ -1698,6 +1734,62 @@ std_gimplify_va_arg_expr (tree valist, tree type, gimple_seq *pre_p, >> return build_va_arg_indirect_ref (addr); >> } >> >> +tree >> +default_chkp_bound_type (void) >> +{ >> + tree res = make_node (POINTER_BOUNDS_TYPE); >> + TYPE_PRECISION (res) = TYPE_PRECISION (size_type_node) * 2; >> + TYPE_NAME (res) = get_identifier ("__bounds_type"); >> + SET_TYPE_MODE (res, targetm.chkp_bound_mode ()); >> + layout_type (res); >> + return res; >> +} >> + >> +enum machine_mode >> +default_chkp_bound_mode (void) >> +{ >> + return VOIDmode; >> +} >> + >> +tree >> +default_builtin_chkp_function (unsigned int fcode ATTRIBUTE_UNUSED) >> +{ >> + return NULL_TREE; >> +} >> + >> +rtx >> +default_chkp_function_value_bounds (const_tree ret_type ATTRIBUTE_UNUSED, >> + const_tree fn_decl_or_type ATTRIBUTE_UNUSED, >> + bool outgoing ATTRIBUTE_UNUSED) >> +{ >> + gcc_unreachable (); >> +} >> + >> +tree >> +default_chkp_make_bounds_constant (HOST_WIDE_INT lb ATTRIBUTE_UNUSED, >> + HOST_WIDE_INT ub ATTRIBUTE_UNUSED) >> +{ >> + return NULL_TREE; >> +} >> + >> +int >> +default_chkp_initialize_bounds (tree var ATTRIBUTE_UNUSED, >> + tree lb ATTRIBUTE_UNUSED, >> + tree ub ATTRIBUTE_UNUSED, >> + tree *stmts ATTRIBUTE_UNUSED) >> +{ >> + return 0; >> +} >> + >> +void >> +default_setup_incoming_vararg_bounds (cumulative_args_t ca ATTRIBUTE_UNUSED, >> + enum machine_mode mode ATTRIBUTE_UNUSED, >> + tree type ATTRIBUTE_UNUSED, >> + int *pretend_arg_size ATTRIBUTE_UNUSED, >> + int second_time ATTRIBUTE_UNUSED) >> +{ >> +} >> + >> /* An implementation of TARGET_CAN_USE_DOLOOP_P for targets that do >> not support nested low-overhead loops. */ >> >> diff --git a/gcc/targhooks.h b/gcc/targhooks.h >> index 9dd4c83..4eaf88b 100644 >> --- a/gcc/targhooks.h >> +++ b/gcc/targhooks.h >> @@ -206,5 +206,23 @@ extern bool default_member_type_forces_blk (const_tree, enum machine_mode); >> extern void default_atomic_assign_expand_fenv (tree *, tree *, tree *); >> extern tree build_va_arg_indirect_ref (tree); >> extern tree std_gimplify_va_arg_expr (tree, tree, gimple_seq *, gimple_seq *); >> + >> +extern rtx default_load_bounds_for_arg (rtx, rtx, rtx); >> +extern void default_store_bounds_for_arg (rtx, rtx, rtx, rtx); >> +extern rtx default_load_returned_bounds (rtx); >> +extern void default_store_returned_bounds (rtx,rtx); >> +extern tree default_fn_abi_va_list_bounds_size (tree); >> +extern tree default_chkp_bound_type (void); >> +extern enum machine_mode default_chkp_bound_mode (void); >> +extern tree default_builtin_chkp_function (unsigned int); >> +extern rtx default_chkp_function_value_bounds (const_tree, const_tree, bool); >> +extern tree default_chkp_make_bounds_constant (HOST_WIDE_INT lb, HOST_WIDE_INT ub); >> +extern int default_chkp_initialize_bounds (tree var, tree lb, tree ub, >> + tree *stmts); >> +extern void default_setup_incoming_vararg_bounds (cumulative_args_t ca ATTRIBUTE_UNUSED, >> + enum machine_mode mode ATTRIBUTE_UNUSED, >> + tree type ATTRIBUTE_UNUSED, >> + int *pretend_arg_size ATTRIBUTE_UNUSED, >> + int second_time ATTRIBUTE_UNUSED); >> extern bool can_use_doloop_if_innermost (double_int, double_int, >> unsigned int, bool);
On 04/16/14 05:52, Ilya Enkovich wrote: > Hi, > > This patch introduces target hooks to be used by Pointer Bounds Checker. Hooks set is different from what was approved for 4.9 (and later reverted). I added hooks to work with returned bounds and to prepare incoming bounds for vararg functions. It allowed to remove some target assumptions from expand code. > > Bootstrapped and tested on linux-x86_64. > > OK for trunk? > > Thanks, > Ilya > -- > gcc/ > > 2014-04-16 Ilya Enkovich <ilya.enkovich@intel.com> > > * target.def (builtin_chkp_function): New. > (chkp_bound_type): New. > (chkp_bound_mode): New. > (chkp_make_bounds_constant): New. > (chkp_initialize_bounds): New. > (fn_abi_va_list_bounds_size): New. > (load_bounds_for_arg): New. > (store_bounds_for_arg): New. > (load_returned_bounds): New. > (store_returned_bounds): New. > (chkp_function_value_bounds): New. > (setup_incoming_vararg_bounds): New. > * targhooks.h (default_load_bounds_for_arg): New. > (default_store_bounds_for_arg): New. > (default_load_returned_bounds): New. > (default_store_returned_bounds): New. > (default_fn_abi_va_list_bounds_size): New. > (default_chkp_bound_type): New. > (default_chkp_bound_mode): New. > (default_builtin_chkp_function): New. > (default_chkp_function_value_bounds): New. > (default_chkp_make_bounds_constant): New. > (default_chkp_initialize_bounds): New. > (default_setup_incoming_vararg_bounds): New. > * targhooks.c (default_load_bounds_for_arg): New. > (default_store_bounds_for_arg): New. > (default_load_returned_bounds): New. > (default_store_returned_bounds): New. > (default_fn_abi_va_list_bounds_size): New. > (default_chkp_bound_type): New. > (default_chkp_bound_mode); New. > (default_builtin_chkp_function): New. > (default_chkp_function_value_bounds): New. > (default_chkp_make_bounds_constant): New. > (default_chkp_initialize_bounds): New. > (default_setup_incoming_vararg_bounds): New. > * doc/tm.texi.in (TARGET_FN_ABI_VA_LIST_BOUNDS_SIZE): New. > (TARGET_LOAD_BOUNDS_FOR_ARG): New. > (TARGET_STORE_BOUNDS_FOR_ARG): New. > (TARGET_LOAD_RETURNED_BOUNDS): New. > (TARGET_STORE_RETURNED_BOUNDS): New. > (TARGET_CHKP_FUNCTION_VALUE_BOUNDS): New. > (TARGET_SETUP_INCOMING_VARARG_BOUNDS): New. > (TARGET_BUILTIN_CHKP_FUNCTION): New. > (TARGET_CHKP_BOUND_TYPE): New. > (TARGET_CHKP_BOUND_MODE): New. > (TARGET_CHKP_MAKE_BOUNDS_CONSTANT): New. > (TARGET_CHKP_INITIALIZE_BOUNDS): New. > * doc/tm.texi: Regenerated. > > diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi > index b8ca17e..d868129 100644 > --- a/gcc/doc/tm.texi > +++ b/gcc/doc/tm.texi > @@ -4333,6 +4333,13 @@ This hook returns the va_list type of the calling convention specified by > The default version of this hook returns @code{va_list_type_node}. > @end deftypefn > > +@deftypefn {Target Hook} tree TARGET_FN_ABI_VA_LIST_BOUNDS_SIZE (tree @var{fndecl}) > +This hook returns size for @code{va_list} object in function specified > +by @var{fndecl}. This hook is used by Pointer Bounds Checker to build bounds > +for @code{va_list} object. Return @code{integer_zero_node} if no bounds > +should be used (e.g. @code{va_list} is a scalar pointer to the stack). > +@end deftypefn What if va_list is an aggregate, but lives in registers? I'm not familiar with the different va_list implementations on all the targets, but GCC has supported aggregates in registers for various ABIs through the years. > +@deftypefn {Built-in Function} size_t __chkp_sizeof (const void *@var{ptr}) > +Function code - @code{BUILT_IN_CHKP_SIZEOF}. This built-in function > +returns size of object referenced by @var{ptr}. @var{ptr} is always > +@code{ADDR_EXPR} of @code{VAR_DECL}. This built-in is used by > +Pointer Boudns Checker when bounds of object cannot be computed statically > +(e.g. object has incomplete type). s/Boudns/Bounds/ OK for the trunk with those two doc fixes. As with the other patches, wait for the remainder to be approved before committing. jeff
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi index b8ca17e..d868129 100644 --- a/gcc/doc/tm.texi +++ b/gcc/doc/tm.texi @@ -4333,6 +4333,13 @@ This hook returns the va_list type of the calling convention specified by The default version of this hook returns @code{va_list_type_node}. @end deftypefn +@deftypefn {Target Hook} tree TARGET_FN_ABI_VA_LIST_BOUNDS_SIZE (tree @var{fndecl}) +This hook returns size for @code{va_list} object in function specified +by @var{fndecl}. This hook is used by Pointer Bounds Checker to build bounds +for @code{va_list} object. Return @code{integer_zero_node} if no bounds +should be used (e.g. @code{va_list} is a scalar pointer to the stack). +@end deftypefn + @deftypefn {Target Hook} tree TARGET_CANONICAL_VA_LIST_TYPE (tree @var{type}) This hook returns the va_list type of the calling convention specified by the type of @var{type}. If @var{type} is not a valid va_list type, it returns @@ -5150,6 +5157,49 @@ defined, then define this hook to return @code{true} if Otherwise, you should not define this hook. @end deftypefn +@deftypefn {Target Hook} rtx TARGET_LOAD_BOUNDS_FOR_ARG (rtx @var{slot}, rtx @var{arg}, rtx @var{slot_no}) +This hook is used by expand pass to emit insn to load bounds of +@var{arg} passed in @var{slot}. Expand pass uses this hook in case +bounds of @var{arg} are not passed in register. If @var{slot} is a +memory, then bounds are loaded as for regular pointer loaded from +memory. If @var{slot} is not a memory then @var{slot_no} is an integer +constant holding number of the target dependent special slot which +should be used to obtain bounds. Hook returns RTX holding loaded bounds. +@end deftypefn + +@deftypefn {Target Hook} void TARGET_STORE_BOUNDS_FOR_ARG (rtx @var{arg}, rtx @var{slot}, rtx @var{bounds}, rtx @var{slot_no}) +This hook is used by expand pass to emit insns to store @var{bounds} of +@var{arg} passed in @var{slot}. Expand pass uses this hook in case +@var{bounds} of @var{arg} are not passed in register. If @var{slot} is a +memory, then @var{bounds} are stored as for regular pointer stored in +memory. If @var{slot} is not a memory then @var{slot_no} is an integer +constant holding number of the target dependent special slot which +should be used to store @var{bounds}. +@end deftypefn + +@deftypefn {Target Hook} rtx TARGET_LOAD_RETURNED_BOUNDS (rtx @var{slot}) +This hook is used by expand pass to emit insn to load bounds +returned by function call in @var{slot}. Hook returns RTX holding +loaded bounds. +@end deftypefn + +@deftypefn {Target Hook} void TARGET_STORE_RETURNED_BOUNDS (rtx @var{slot}, rtx @var{bounds}) +This hook is used by expand pass to emit insn to store @var{bounds} +returned by function call into @var{slot}. +@end deftypefn + +@deftypefn {Target Hook} rtx TARGET_CHKP_FUNCTION_VALUE_BOUNDS (const_tree @var{ret_type}, const_tree @var{fn_decl_or_type}, bool @var{outgoing}) +Define this to return an RTX representing the place where a function +returns bounds for returned pointers. Arguments meaning is similar to +@code{TARGET_FUNCTION_VALUE}. +@end deftypefn + +@deftypefn {Target Hook} void TARGET_SETUP_INCOMING_VARARG_BOUNDS (cumulative_args_t @var{args_so_far}, enum machine_mode @var{mode}, tree @var{type}, int *@var{pretend_args_size}, int @var{second_time}) +Use it to store bounds for anonymous register arguments stored +into the stack. Arguments meaning is similar to +@code{TARGET_SETUP_INCOMING_VARARGS}. +@end deftypefn + @node Trampolines @section Trampolines for Nested Functions @cindex trampolines for nested functions @@ -10952,6 +11002,93 @@ ignored. This function should return the result of the call to the built-in function. @end deftypefn +@deftypefn {Target Hook} tree TARGET_BUILTIN_CHKP_FUNCTION (unsigned @var{fcode}) +This hook allows target to redefine built-in functions used by +Pointer Bounds Checker for code instrumentation. Hook should return +fndecl of function implementing generic builtin whose code is +passed in @var{fcode}. Currently following built-in functions are +obtained using this hook: +@deftypefn {Built-in Function} __bounds_type __chkp_bndmk (const void *@var{lb}, size_t @var{size}) +Function code - BUILT_IN_CHKP_BNDMK. This built-in function is used +by Pointer Bounds Checker to create bound values. @var{lb} holds low +bound of the resulting bounds. @var{size} holds size of created bounds. +@end deftypefn + +@deftypefn {Built-in Function} void __chkp_bndstx (const void *@var{ptr}, __bounds_type @var{b}, const void **@var{loc}) +Function code - @code{BUILT_IN_CHKP_BNDSTX}. This built-in function is used +by Pointer Bounds Checker to store bounds @var{b} for pointer @var{ptr} +when @var{ptr} is stored by address @var{loc}. +@end deftypefn + +@deftypefn {Built-in Function} __bounds_type __chkp_bndldx (const void **@var{loc}, const void *@var{ptr}) +Function code - @code{BUILT_IN_CHKP_BNDLDX}. This built-in function is used +by Pointer Bounds Checker to get bounds of pointer @var{ptr} loaded by +address @var{loc}. +@end deftypefn + +@deftypefn {Built-in Function} void __chkp_bndcl (const void *@var{ptr}, __bounds_type @var{b}) +Function code - @code{BUILT_IN_CHKP_BNDCL}. This built-in function is used +by Pointer Bounds Checker to perform check for pointer @var{ptr} against +lower bound of bounds @var{b}. +@end deftypefn + +@deftypefn {Built-in Function} void __chkp_bndcu (const void *@var{ptr}, __bounds_type @var{b}) +Function code - @code{BUILT_IN_CHKP_BNDCU}. This built-in function is used +by Pointer Bounds Checker to perform check for pointer @var{ptr} against +upper bound of bounds @var{b}. +@end deftypefn + +@deftypefn {Built-in Function} __bounds_type __chkp_bndret (void *@var{ptr}) +Function code - @code{BUILT_IN_CHKP_BNDRET}. This built-in function is used +by Pointer Bounds Checker to obtain bounds returned by a call statement. +@var{ptr} passed to built-in is @code{SSA_NAME} returned by the call. +@end deftypefn + +@deftypefn {Built-in Function} __bounds_type __chkp_intersect (__bounds_type @var{b1}, __bounds_type @var{b2}) +Function code - @code{BUILT_IN_CHKP_INTERSECT}. This built-in function +returns intersection of bounds @var{b1} and @var{b2}. +@end deftypefn + +@deftypefn {Built-in Function} __bounds_type __chkp_narrow (const void *@var{ptr}, __bounds_type @var{b}, size_t @var{s}) +Function code - @code{BUILT_IN_CHKP_NARROW}. This built-in function +returns intersection of bounds @var{b} and +[@var{ptr}, @var{ptr} + @var{s} - @code{1}]. +@end deftypefn + +@deftypefn {Built-in Function} size_t __chkp_sizeof (const void *@var{ptr}) +Function code - @code{BUILT_IN_CHKP_SIZEOF}. This built-in function +returns size of object referenced by @var{ptr}. @var{ptr} is always +@code{ADDR_EXPR} of @code{VAR_DECL}. This built-in is used by +Pointer Boudns Checker when bounds of object cannot be computed statically +(e.g. object has incomplete type). +@end deftypefn + +@deftypefn {Built-in Function} const void *__chkp_extract_lower (__bounds_type @var{b}) +Function code - @code{BUILT_IN_CHKP_EXTRACT_LOWER}. This built-in function +returns lower bound of bounds @var{b}. +@end deftypefn + +@deftypefn {Built-in Function} const void *__chkp_extract_upper (__bounds_type @var{b}) +Function code - @code{BUILT_IN_CHKP_EXTRACT_UPPER}. This built-in function +returns upper bound of bounds @var{b}. +@end deftypefn +@end deftypefn +@deftypefn {Target Hook} tree TARGET_CHKP_BOUND_TYPE (void) +Return type to be used for bounds +@end deftypefn +@deftypefn {Target Hook} {enum machine_mode} TARGET_CHKP_BOUND_MODE (void) +Return mode to be used for bounds. +@end deftypefn +@deftypefn {Target Hook} tree TARGET_CHKP_MAKE_BOUNDS_CONSTANT (HOST_WIDE_INT @var{lb}, HOST_WIDE_INT @var{ub}) +Return constant used to statically initialize constant bounds +with specified lower bound @var{lb} and upper bounds @var{ub}. +@end deftypefn +@deftypefn {Target Hook} int TARGET_CHKP_INITIALIZE_BOUNDS (tree @var{var}, tree @var{lb}, tree @var{ub}, tree *@var{stmts}) +Generate a list of statements @var{stmts} to initialize pointer +bounds variable @var{var} with bounds @var{lb} and @var{ub}. Return +the number of generated statements. +@end deftypefn + @deftypefn {Target Hook} tree TARGET_RESOLVE_OVERLOADED_BUILTIN (unsigned int @var{loc}, tree @var{fndecl}, void *@var{arglist}) Select a replacement for a machine specific built-in function that was set up by @samp{TARGET_INIT_BUILTINS}. This is done diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in index d793d26..5c12180 100644 --- a/gcc/doc/tm.texi.in +++ b/gcc/doc/tm.texi.in @@ -3691,6 +3691,8 @@ stack. @hook TARGET_FN_ABI_VA_LIST +@hook TARGET_FN_ABI_VA_LIST_BOUNDS_SIZE + @hook TARGET_CANONICAL_VA_LIST_TYPE @hook TARGET_GIMPLIFY_VA_ARG_EXPR @@ -4061,6 +4063,18 @@ These machine description macros help implement varargs: @hook TARGET_PRETEND_OUTGOING_VARARGS_NAMED +@hook TARGET_LOAD_BOUNDS_FOR_ARG + +@hook TARGET_STORE_BOUNDS_FOR_ARG + +@hook TARGET_LOAD_RETURNED_BOUNDS + +@hook TARGET_STORE_RETURNED_BOUNDS + +@hook TARGET_CHKP_FUNCTION_VALUE_BOUNDS + +@hook TARGET_SETUP_INCOMING_VARARG_BOUNDS + @node Trampolines @section Trampolines for Nested Functions @cindex trampolines for nested functions @@ -8206,6 +8220,12 @@ to by @var{ce_info}. @hook TARGET_EXPAND_BUILTIN +@hook TARGET_BUILTIN_CHKP_FUNCTION +@hook TARGET_CHKP_BOUND_TYPE +@hook TARGET_CHKP_BOUND_MODE +@hook TARGET_CHKP_MAKE_BOUNDS_CONSTANT +@hook TARGET_CHKP_INITIALIZE_BOUNDS + @hook TARGET_RESOLVE_OVERLOADED_BUILTIN @hook TARGET_FOLD_BUILTIN diff --git a/gcc/target.def b/gcc/target.def index 3a64cd1..53505b5 100644 --- a/gcc/target.def +++ b/gcc/target.def @@ -2078,6 +2078,107 @@ built-in function.", (tree exp, rtx target, rtx subtarget, enum machine_mode mode, int ignore), default_expand_builtin) +DEFHOOK +(builtin_chkp_function, + "This hook allows target to redefine built-in functions used by\n\ +Pointer Bounds Checker for code instrumentation. Hook should return\n\ +fndecl of function implementing generic builtin whose code is\n\ +passed in @var{fcode}. Currently following built-in functions are\n\ +obtained using this hook:\n\ +@deftypefn {Built-in Function} __bounds_type __chkp_bndmk (const void *@var{lb}, size_t @var{size})\n\ +Function code - BUILT_IN_CHKP_BNDMK. This built-in function is used\n\ +by Pointer Bounds Checker to create bound values. @var{lb} holds low\n\ +bound of the resulting bounds. @var{size} holds size of created bounds.\n\ +@end deftypefn\n\ +\n\ +@deftypefn {Built-in Function} void __chkp_bndstx (const void *@var{ptr}, __bounds_type @var{b}, const void **@var{loc})\n\ +Function code - @code{BUILT_IN_CHKP_BNDSTX}. This built-in function is used\n\ +by Pointer Bounds Checker to store bounds @var{b} for pointer @var{ptr}\n\ +when @var{ptr} is stored by address @var{loc}.\n\ +@end deftypefn\n\ +\n\ +@deftypefn {Built-in Function} __bounds_type __chkp_bndldx (const void **@var{loc}, const void *@var{ptr})\n\ +Function code - @code{BUILT_IN_CHKP_BNDLDX}. This built-in function is used\n\ +by Pointer Bounds Checker to get bounds of pointer @var{ptr} loaded by\n\ +address @var{loc}.\n\ +@end deftypefn\n\ +\n\ +@deftypefn {Built-in Function} void __chkp_bndcl (const void *@var{ptr}, __bounds_type @var{b})\n\ +Function code - @code{BUILT_IN_CHKP_BNDCL}. This built-in function is used\n\ +by Pointer Bounds Checker to perform check for pointer @var{ptr} against\n\ +lower bound of bounds @var{b}.\n\ +@end deftypefn\n\ +\n\ +@deftypefn {Built-in Function} void __chkp_bndcu (const void *@var{ptr}, __bounds_type @var{b})\n\ +Function code - @code{BUILT_IN_CHKP_BNDCU}. This built-in function is used\n\ +by Pointer Bounds Checker to perform check for pointer @var{ptr} against\n\ +upper bound of bounds @var{b}.\n\ +@end deftypefn\n\ +\n\ +@deftypefn {Built-in Function} __bounds_type __chkp_bndret (void *@var{ptr})\n\ +Function code - @code{BUILT_IN_CHKP_BNDRET}. This built-in function is used\n\ +by Pointer Bounds Checker to obtain bounds returned by a call statement.\n\ +@var{ptr} passed to built-in is @code{SSA_NAME} returned by the call.\n\ +@end deftypefn\n\ +\n\ +@deftypefn {Built-in Function} __bounds_type __chkp_intersect (__bounds_type @var{b1}, __bounds_type @var{b2})\n\ +Function code - @code{BUILT_IN_CHKP_INTERSECT}. This built-in function\n\ +returns intersection of bounds @var{b1} and @var{b2}.\n\ +@end deftypefn\n\ +\n\ +@deftypefn {Built-in Function} __bounds_type __chkp_narrow (const void *@var{ptr}, __bounds_type @var{b}, size_t @var{s})\n\ +Function code - @code{BUILT_IN_CHKP_NARROW}. This built-in function\n\ +returns intersection of bounds @var{b} and\n\ +[@var{ptr}, @var{ptr} + @var{s} - @code{1}].\n\ +@end deftypefn\n\ +\n\ +@deftypefn {Built-in Function} size_t __chkp_sizeof (const void *@var{ptr})\n\ +Function code - @code{BUILT_IN_CHKP_SIZEOF}. This built-in function\n\ +returns size of object referenced by @var{ptr}. @var{ptr} is always\n\ +@code{ADDR_EXPR} of @code{VAR_DECL}. This built-in is used by\n\ +Pointer Boudns Checker when bounds of object cannot be computed statically\n\ +(e.g. object has incomplete type).\n\ +@end deftypefn\n\ +\n\ +@deftypefn {Built-in Function} const void *__chkp_extract_lower (__bounds_type @var{b})\n\ +Function code - @code{BUILT_IN_CHKP_EXTRACT_LOWER}. This built-in function\n\ +returns lower bound of bounds @var{b}.\n\ +@end deftypefn\n\ +\n\ +@deftypefn {Built-in Function} const void *__chkp_extract_upper (__bounds_type @var{b})\n\ +Function code - @code{BUILT_IN_CHKP_EXTRACT_UPPER}. This built-in function\n\ +returns upper bound of bounds @var{b}.\n\ +@end deftypefn", + tree, (unsigned fcode), + default_builtin_chkp_function) + +DEFHOOK +(chkp_bound_type, + "Return type to be used for bounds", + tree, (void), + default_chkp_bound_type) + +DEFHOOK +(chkp_bound_mode, + "Return mode to be used for bounds.", + enum machine_mode, (void), + default_chkp_bound_mode) + +DEFHOOK +(chkp_make_bounds_constant, + "Return constant used to statically initialize constant bounds\n\ +with specified lower bound @var{lb} and upper bounds @var{ub}.", + tree, (HOST_WIDE_INT lb, HOST_WIDE_INT ub), + default_chkp_make_bounds_constant) + +DEFHOOK +(chkp_initialize_bounds, + "Generate a list of statements @var{stmts} to initialize pointer\n\ +bounds variable @var{var} with bounds @var{lb} and @var{ub}. Return\n\ +the number of generated statements.", + int, (tree var, tree lb, tree ub, tree *stmts), + default_chkp_initialize_bounds) + /* Select a replacement for a target-specific builtin. This is done *before* regular type checking, and so allows the target to implement a crude form of function overloading. The result is a @@ -3328,6 +3429,15 @@ The default version of this hook returns @code{va_list_type_node}.", tree, (tree fndecl), std_fn_abi_va_list) +DEFHOOK +(fn_abi_va_list_bounds_size, + "This hook returns size for @code{va_list} object in function specified\n\ +by @var{fndecl}. This hook is used by Pointer Bounds Checker to build bounds\n\ +for @code{va_list} object. Return @code{integer_zero_node} if no bounds\n\ +should be used (e.g. @code{va_list} is a scalar pointer to the stack).", + tree, (tree fndecl), + default_fn_abi_va_list_bounds_size) + /* Get the __builtin_va_list type dependent on input type. */ DEFHOOK (canonical_va_list_type, @@ -3776,6 +3886,54 @@ not generate any instructions in this case.", default_setup_incoming_varargs) DEFHOOK +(load_bounds_for_arg, + "This hook is used by expand pass to emit insn to load bounds of\n\ +@var{arg} passed in @var{slot}. Expand pass uses this hook in case\n\ +bounds of @var{arg} are not passed in register. If @var{slot} is a\n\ +memory, then bounds are loaded as for regular pointer loaded from\n\ +memory. If @var{slot} is not a memory then @var{slot_no} is an integer\n\ +constant holding number of the target dependent special slot which\n\ +should be used to obtain bounds. Hook returns RTX holding loaded bounds.", + rtx, (rtx slot, rtx arg, rtx slot_no), + default_load_bounds_for_arg) + +DEFHOOK +(store_bounds_for_arg, + "This hook is used by expand pass to emit insns to store @var{bounds} of\n\ +@var{arg} passed in @var{slot}. Expand pass uses this hook in case\n\ +@var{bounds} of @var{arg} are not passed in register. If @var{slot} is a\n\ +memory, then @var{bounds} are stored as for regular pointer stored in\n\ +memory. If @var{slot} is not a memory then @var{slot_no} is an integer\n\ +constant holding number of the target dependent special slot which\n\ +should be used to store @var{bounds}.", + void, (rtx arg, rtx slot, rtx bounds, rtx slot_no), + default_store_bounds_for_arg) + +DEFHOOK +(load_returned_bounds, + "This hook is used by expand pass to emit insn to load bounds\n\ +returned by function call in @var{slot}. Hook returns RTX holding\n\ +loaded bounds.", + rtx, (rtx slot), + default_load_returned_bounds) + +DEFHOOK +(store_returned_bounds, + "This hook is used by expand pass to emit insn to store @var{bounds}\n\ +returned by function call into @var{slot}.", + void, (rtx slot, rtx bounds), + default_store_returned_bounds) + +DEFHOOK +(setup_incoming_vararg_bounds, + "Use it to store bounds for anonymous register arguments stored\n\ +into the stack. Arguments meaning is similar to\n\ +@code{TARGET_SETUP_INCOMING_VARARGS}.", + void, (cumulative_args_t args_so_far, enum machine_mode mode, tree type, + int *pretend_args_size, int second_time), + default_setup_incoming_vararg_bounds) + +DEFHOOK (strict_argument_naming, "Define this hook to return @code{true} if the location where a function\n\ argument is passed depends on whether or not it is a named argument.\n\ @@ -4052,6 +4210,15 @@ aggregate data types, because these are returned in another way. See\n\ rtx, (const_tree ret_type, const_tree fn_decl_or_type, bool outgoing), default_function_value) +/* Return the rtx for bounds of returned pointer. */ +DEFHOOK +(chkp_function_value_bounds, + "Define this to return an RTX representing the place where a function\n\ +returns bounds for returned pointers. Arguments meaning is similar to\n\ +@code{TARGET_FUNCTION_VALUE}.", + rtx, (const_tree ret_type, const_tree fn_decl_or_type, bool outgoing), + default_chkp_function_value_bounds) + /* Return the rtx for the result of a libcall of mode MODE, calling the function FN_NAME. */ DEFHOOK diff --git a/gcc/targhooks.c b/gcc/targhooks.c index 79491c7..28e200e 100644 --- a/gcc/targhooks.c +++ b/gcc/targhooks.c @@ -1574,6 +1574,42 @@ default_member_type_forces_blk (const_tree, enum machine_mode) return false; } +rtx +default_load_bounds_for_arg (rtx addr ATTRIBUTE_UNUSED, + rtx ptr ATTRIBUTE_UNUSED, + rtx bnd ATTRIBUTE_UNUSED) +{ + gcc_unreachable (); +} + +void +default_store_bounds_for_arg (rtx val ATTRIBUTE_UNUSED, + rtx addr ATTRIBUTE_UNUSED, + rtx bounds ATTRIBUTE_UNUSED, + rtx to ATTRIBUTE_UNUSED) +{ + gcc_unreachable (); +} + +rtx +default_load_returned_bounds (rtx slot ATTRIBUTE_UNUSED) +{ + gcc_unreachable (); +} + +void +default_store_returned_bounds (rtx slot ATTRIBUTE_UNUSED, + rtx bounds ATTRIBUTE_UNUSED) +{ + gcc_unreachable (); +} + +tree +default_fn_abi_va_list_bounds_size (tree fndecl ATTRIBUTE_UNUSED) +{ + return integer_zero_node; +} + /* Default version of canonicalize_comparison. */ void @@ -1698,6 +1734,62 @@ std_gimplify_va_arg_expr (tree valist, tree type, gimple_seq *pre_p, return build_va_arg_indirect_ref (addr); } +tree +default_chkp_bound_type (void) +{ + tree res = make_node (POINTER_BOUNDS_TYPE); + TYPE_PRECISION (res) = TYPE_PRECISION (size_type_node) * 2; + TYPE_NAME (res) = get_identifier ("__bounds_type"); + SET_TYPE_MODE (res, targetm.chkp_bound_mode ()); + layout_type (res); + return res; +} + +enum machine_mode +default_chkp_bound_mode (void) +{ + return VOIDmode; +} + +tree +default_builtin_chkp_function (unsigned int fcode ATTRIBUTE_UNUSED) +{ + return NULL_TREE; +} + +rtx +default_chkp_function_value_bounds (const_tree ret_type ATTRIBUTE_UNUSED, + const_tree fn_decl_or_type ATTRIBUTE_UNUSED, + bool outgoing ATTRIBUTE_UNUSED) +{ + gcc_unreachable (); +} + +tree +default_chkp_make_bounds_constant (HOST_WIDE_INT lb ATTRIBUTE_UNUSED, + HOST_WIDE_INT ub ATTRIBUTE_UNUSED) +{ + return NULL_TREE; +} + +int +default_chkp_initialize_bounds (tree var ATTRIBUTE_UNUSED, + tree lb ATTRIBUTE_UNUSED, + tree ub ATTRIBUTE_UNUSED, + tree *stmts ATTRIBUTE_UNUSED) +{ + return 0; +} + +void +default_setup_incoming_vararg_bounds (cumulative_args_t ca ATTRIBUTE_UNUSED, + enum machine_mode mode ATTRIBUTE_UNUSED, + tree type ATTRIBUTE_UNUSED, + int *pretend_arg_size ATTRIBUTE_UNUSED, + int second_time ATTRIBUTE_UNUSED) +{ +} + /* An implementation of TARGET_CAN_USE_DOLOOP_P for targets that do not support nested low-overhead loops. */ diff --git a/gcc/targhooks.h b/gcc/targhooks.h index 9dd4c83..4eaf88b 100644 --- a/gcc/targhooks.h +++ b/gcc/targhooks.h @@ -206,5 +206,23 @@ extern bool default_member_type_forces_blk (const_tree, enum machine_mode); extern void default_atomic_assign_expand_fenv (tree *, tree *, tree *); extern tree build_va_arg_indirect_ref (tree); extern tree std_gimplify_va_arg_expr (tree, tree, gimple_seq *, gimple_seq *); + +extern rtx default_load_bounds_for_arg (rtx, rtx, rtx); +extern void default_store_bounds_for_arg (rtx, rtx, rtx, rtx); +extern rtx default_load_returned_bounds (rtx); +extern void default_store_returned_bounds (rtx,rtx); +extern tree default_fn_abi_va_list_bounds_size (tree); +extern tree default_chkp_bound_type (void); +extern enum machine_mode default_chkp_bound_mode (void); +extern tree default_builtin_chkp_function (unsigned int); +extern rtx default_chkp_function_value_bounds (const_tree, const_tree, bool); +extern tree default_chkp_make_bounds_constant (HOST_WIDE_INT lb, HOST_WIDE_INT ub); +extern int default_chkp_initialize_bounds (tree var, tree lb, tree ub, + tree *stmts); +extern void default_setup_incoming_vararg_bounds (cumulative_args_t ca ATTRIBUTE_UNUSED, + enum machine_mode mode ATTRIBUTE_UNUSED, + tree type ATTRIBUTE_UNUSED, + int *pretend_arg_size ATTRIBUTE_UNUSED, + int second_time ATTRIBUTE_UNUSED); extern bool can_use_doloop_if_innermost (double_int, double_int, unsigned int, bool);