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

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

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

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

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

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

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

Ping

2014-05-06 16:11 GMT+04:00 Ilya Enkovich <enkovich.gnu@gmail.com>:
> PING
>
> 2014-04-16 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);

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

* Re: [PATCH, Pointer Bounds Checker 3/x] Target hooks for Pointer Bounds Checker
  2014-04-16 12:09 [PATCH, Pointer Bounds Checker 3/x] Target hooks for Pointer Bounds Checker Ilya Enkovich
  2014-05-06 12:11 ` Ilya Enkovich
@ 2014-07-18  5:07 ` Jeff Law
  2014-08-15 15:08   ` Ilya Enkovich
  1 sibling, 1 reply; 6+ messages in thread
From: Jeff Law @ 2014-07-18  5:07 UTC (permalink / raw)
  To: Ilya Enkovich, gcc-patches

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

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

* Re: [PATCH, Pointer Bounds Checker 3/x] Target hooks for Pointer Bounds Checker
  2014-07-18  5:07 ` Jeff Law
@ 2014-08-15 15:08   ` Ilya Enkovich
  2014-09-11 21:12     ` Jeff Law
  0 siblings, 1 reply; 6+ messages in thread
From: Ilya Enkovich @ 2014-08-15 15:08 UTC (permalink / raw)
  To: Jeff Law; +Cc: gcc-patches

On 17 Jul 03:36, Jeff Law wrote:
> On 04/16/14 05:52, Ilya Enkovich wrote:
> >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
> 

Thanks for comments!

TARGET_FN_ABI_VA_LIST_BOUNDS_SIZE was supposed to be used when va_list is a pointer to a structure holding args (as it is for x86_64 where we have a structure holding all incoming registers).  I decided to remove TARGET_FN_ABI_VA_LIST_BOUNDS_SIZE hook because all loads from va_list are generated by compiler and should be safely within its bounds.

Here is an updated patch.

Thanks,
Ilya
--
2014-08-15  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.
	(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_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_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_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 9dd8d68..5d9ac43 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -5028,6 +5028,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
@@ -10786,6 +10829,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 Bounds 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 dd72b98..5e779a7 100644
--- a/gcc/doc/tm.texi.in
+++ b/gcc/doc/tm.texi.in
@@ -3929,6 +3929,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
@@ -8023,6 +8035,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 3a41db1..aad5c29 100644
--- a/gcc/target.def
+++ b/gcc/target.def
@@ -2064,6 +2064,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 Bounds 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
@@ -3774,6 +3875,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\
@@ -4050,6 +4199,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 0f27a5a..1625d17 100644
--- a/gcc/targhooks.c
+++ b/gcc/targhooks.c
@@ -1601,6 +1601,36 @@ 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 ();
+}
+
 /* Default version of canonicalize_comparison.  */
 
 void
@@ -1725,6 +1755,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 4be33f8..b5747a5 100644
--- a/gcc/targhooks.h
+++ b/gcc/targhooks.h
@@ -210,3 +210,20 @@ extern tree std_gimplify_va_arg_expr (tree, tree, gimple_seq *, gimple_seq *);
 extern bool can_use_doloop_if_innermost (const widest_int &,
 					 const widest_int &,
 					 unsigned int, bool);
+
+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_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);

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

* Re: [PATCH, Pointer Bounds Checker 3/x] Target hooks for Pointer Bounds Checker
  2014-08-15 15:08   ` Ilya Enkovich
@ 2014-09-11 21:12     ` Jeff Law
  0 siblings, 0 replies; 6+ messages in thread
From: Jeff Law @ 2014-09-11 21:12 UTC (permalink / raw)
  To: Ilya Enkovich; +Cc: gcc-patches

On 08/15/14 09:08, Ilya Enkovich wrote:
> On 17 Jul 03:36, Jeff Law wrote:
>> On 04/16/14 05:52, Ilya Enkovich wrote:
>>> 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
>>
>
> Thanks for comments!
>
> TARGET_FN_ABI_VA_LIST_BOUNDS_SIZE was supposed to be used when va_list is a pointer to a structure holding args (as it is for x86_64 where we have a structure holding all incoming registers).  I decided to remove TARGET_FN_ABI_VA_LIST_BOUNDS_SIZE hook because all loads from va_list are generated by compiler and should be safely within its bounds.
>
> Here is an updated patch.
>
> Thanks,
> Ilya
> --
> 2014-08-15  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.
> 	(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_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_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_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.
>
Just to be explicit, this is OK when the rest of the pointer bounds 
stuff goes in.

jeff

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

end of thread, other threads:[~2014-09-11 21:12 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-04-16 12:09 [PATCH, Pointer Bounds Checker 3/x] Target hooks for Pointer Bounds Checker Ilya Enkovich
2014-05-06 12:11 ` Ilya Enkovich
2014-06-27  8:10   ` Ilya Enkovich
2014-07-18  5:07 ` Jeff Law
2014-08-15 15:08   ` Ilya Enkovich
2014-09-11 21:12     ` Jeff Law

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).