Message ID | 20131021142058.GF37888@msticlxl57.ims.intel.com |
---|---|
State | New |
Headers | show |
On 10/21/13 08:20, Ilya Enkovich wrote: > diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi > index 8d220f3..79bd0f9 100644 > --- a/gcc/doc/tm.texi > +++ b/gcc/doc/tm.texi > +@deftypefn {Target Hook} rtx TARGET_LOAD_BOUNDS_FOR_ARG (rtx @var{slot}, rtx @var{arg}, rtx @var{slot_no}) > +This hook is used to emit insn to load bounds of @var{arg} passed > +in @var{slot}. In case @var{slot} is not a memory, @var{slot_no} is RTX > +constant holding number of the special slot we should get bounds from. > +Return 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 to emit insn to store bounds of @var{arg} passed > +in @var{slot}. In case @var{slot} is not a memory, @var{slot_no} is RTX > +constant holding number of the special slot we should store bounds to. > +@end deftypefn > + Almost there. What I think is missing is more information about the case where SLOT is not a memory (presumably it's a reg) and how that relates to SLOT_NO. Isn't this just providing a mapping from the input argument registers to some set of bounds pointer registers? Presumably you aren't really exposing the bound registers as argument registers hence this hack? Not asking you to change anything, just trying to understand the rationale. > @node Trampolines > @section Trampolines for Nested Functions > @cindex trampolines for nested functions > @@ -10907,6 +10927,27 @@ 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 > +Pointers 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: > +@code{BUILT_IN_CHKP_BNDMK}, @code{BUILT_IN_CHKP_BNDSTX}, > +@code{BUILT_IN_CHKP_BNDLDX}, @code{BUILT_IN_CHKP_BNDCL}, > +@code{BUILT_IN_CHKP_BNDCU}, @code{BUILT_IN_CHKP_BNDRET}, > +@code{BUILT_IN_CHKP_INTERSECT}, @code{BUILT_IN_CHKP_SET_PTR_BOUNDS}, > +@code{BUILT_IN_CHKP_NARROW}, @code{BUILT_IN_CHKP_ARG_BND}, > +@code{BUILT_IN_CHKP_SIZEOF}, @code{BUILT_IN_CHKP_EXTRACT_LOWER}, > +@code{BUILT_IN_CHKP_EXTRACT_UPPER}. > +@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 So how am I (as a GCC developer) suppsoed to know what BNDMK, BNDLDX, BNDCU, etc mean? The names aren't particularly descriptive. Are these documented elsewhere in a follow-up patch? If not, it seems to me we need to document them here. Jeff
2013/10/24 Jeff Law <law@redhat.com>: > On 10/21/13 08:20, Ilya Enkovich wrote: > >> diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi >> index 8d220f3..79bd0f9 100644 >> --- a/gcc/doc/tm.texi >> +++ b/gcc/doc/tm.texi >> +@deftypefn {Target Hook} rtx TARGET_LOAD_BOUNDS_FOR_ARG (rtx @var{slot}, >> rtx @var{arg}, rtx @var{slot_no}) >> +This hook is used to emit insn to load bounds of @var{arg} passed >> +in @var{slot}. In case @var{slot} is not a memory, @var{slot_no} is RTX >> +constant holding number of the special slot we should get bounds from. >> +Return 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 to emit insn to store bounds of @var{arg} passed >> +in @var{slot}. In case @var{slot} is not a memory, @var{slot_no} is RTX >> +constant holding number of the special slot we should store bounds to. >> +@end deftypefn >> + > > Almost there. What I think is missing is more information about the case > where SLOT is not a memory (presumably it's a reg) and how that relates to > SLOT_NO. > > Isn't this just providing a mapping from the input argument registers to > some set of bounds pointer registers? Presumably you aren't really exposing > the bound registers as argument registers hence this hack? > > Not asking you to change anything, just trying to understand the rationale. > > These two hooks are used by expand pass to pass/receive bounds for args. When bounds are passed in a register, expand does not need this hook and uses regular move insn. If we are out of bound register or platform does not have them at all, this hook is called. If bounded arg is passed in memory, regular way to store associated bounds is supposed to be used in hook. That is why no slot_no value is required, only arg and it's place (slot) are used. If bounded arg is passed in register (e.g. it happens on i386 with MPX when more that 4 pointers are passed in registers), then some special slot has to be used for bounds. slot_no here holds identifier of this special slot. E.g. if we call function with 6 pointer on i386, we call this hook passing R8 and R9 as slot with const1_rtx and const2_rtx as slot_no. > > > >> @node Trampolines >> @section Trampolines for Nested Functions >> @cindex trampolines for nested functions >> @@ -10907,6 +10927,27 @@ 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 >> +Pointers 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: >> +@code{BUILT_IN_CHKP_BNDMK}, @code{BUILT_IN_CHKP_BNDSTX}, >> +@code{BUILT_IN_CHKP_BNDLDX}, @code{BUILT_IN_CHKP_BNDCL}, >> +@code{BUILT_IN_CHKP_BNDCU}, @code{BUILT_IN_CHKP_BNDRET}, >> +@code{BUILT_IN_CHKP_INTERSECT}, @code{BUILT_IN_CHKP_SET_PTR_BOUNDS}, >> +@code{BUILT_IN_CHKP_NARROW}, @code{BUILT_IN_CHKP_ARG_BND}, >> +@code{BUILT_IN_CHKP_SIZEOF}, @code{BUILT_IN_CHKP_EXTRACT_LOWER}, >> +@code{BUILT_IN_CHKP_EXTRACT_UPPER}. >> +@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 > > So how am I (as a GCC developer) suppsoed to know what BNDMK, BNDLDX, BNDCU, > etc mean? The names aren't particularly descriptive. Are these documented > elsewhere in a follow-up patch? If not, it seems to me we need to document > them here. Actually the next patch introduces them and is a good place for documentation. But currently this patch has documentation for user visible built-ins only. For now built-ins used for instrumentation are described on Wiki only (http://gcc.gnu.org/wiki/Intel%20MPX%20support%20in%20the%20GCC%20compiler#Builtins_used_for_instrumentation). Where should I move it? Does it also go to extend.texi? Thanks, Ilya > > Jeff >
On 10/24/13 02:24, Ilya Enkovich wrote: > 2013/10/24 Jeff Law <law@redhat.com>: >> On 10/21/13 08:20, Ilya Enkovich wrote: >> >>> diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi >>> index 8d220f3..79bd0f9 100644 >>> --- a/gcc/doc/tm.texi >>> +++ b/gcc/doc/tm.texi >>> +@deftypefn {Target Hook} rtx TARGET_LOAD_BOUNDS_FOR_ARG (rtx @var{slot}, >>> rtx @var{arg}, rtx @var{slot_no}) >>> +This hook is used to emit insn to load bounds of @var{arg} passed >>> +in @var{slot}. In case @var{slot} is not a memory, @var{slot_no} is RTX >>> +constant holding number of the special slot we should get bounds from. >>> +Return 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 to emit insn to store bounds of @var{arg} passed >>> +in @var{slot}. In case @var{slot} is not a memory, @var{slot_no} is RTX >>> +constant holding number of the special slot we should store bounds to. >>> +@end deftypefn >>> + >> >> Almost there. What I think is missing is more information about the case >> where SLOT is not a memory (presumably it's a reg) and how that relates to >> SLOT_NO. >> >> Isn't this just providing a mapping from the input argument registers to >> some set of bounds pointer registers? Presumably you aren't really exposing >> the bound registers as argument registers hence this hack? >> >> Not asking you to change anything, just trying to understand the rationale. >> >> > > These two hooks are used by expand pass to pass/receive bounds for > args. When bounds are passed in a register, expand does not need this > hook and uses regular move insn. If we are out of bound register or > platform does not have them at all, this hook is called. If bounded > arg is passed in memory, regular way to store associated bounds is > supposed to be used in hook. That is why no slot_no value is required, > only arg and it's place (slot) are used. If bounded arg is passed in > register (e.g. it happens on i386 with MPX when more that 4 pointers > are passed in registers), then some special slot has to be used for > bounds. slot_no here holds identifier of this special slot. E.g. if we > call function with 6 pointer on i386, we call this hook passing R8 and > R9 as slot with const1_rtx and const2_rtx as slot_no. So can we find a concise way to describe this and include that in the docs for the hooks. Otherwise I can't see how a developer is going to know how to use this stuff. >> So how am I (as a GCC developer) suppsoed to know what BNDMK, BNDLDX, BNDCU, >> etc mean? The names aren't particularly descriptive. Are these documented >> elsewhere in a follow-up patch? If not, it seems to me we need to document >> them here. > > Actually the next patch introduces them and is a good place for > documentation. But currently this patch has documentation for user > visible built-ins only. For now built-ins used for instrumentation are > described on Wiki only > (http://gcc.gnu.org/wiki/Intel%20MPX%20support%20in%20the%20GCC%20compiler#Builtins_used_for_instrumentation). > Where should I move it? Does it also go to extend.texi? If they're strictly for developers, then there's not a real good place for them. They're not really extensions we would expect the user to use, so extend.texi seems inappropriate. Perhaps a section in tm.texi? Jeff
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi index 8d220f3..79bd0f9 100644 --- a/gcc/doc/tm.texi +++ b/gcc/doc/tm.texi @@ -4334,6 +4334,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 Pointers 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 @@ -5151,6 +5158,19 @@ 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 to emit insn to load bounds of @var{arg} passed +in @var{slot}. In case @var{slot} is not a memory, @var{slot_no} is RTX +constant holding number of the special slot we should get bounds from. +Return 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 to emit insn to store bounds of @var{arg} passed +in @var{slot}. In case @var{slot} is not a memory, @var{slot_no} is RTX +constant holding number of the special slot we should store bounds to. +@end deftypefn + @node Trampolines @section Trampolines for Nested Functions @cindex trampolines for nested functions @@ -10907,6 +10927,27 @@ 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 +Pointers 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: +@code{BUILT_IN_CHKP_BNDMK}, @code{BUILT_IN_CHKP_BNDSTX}, +@code{BUILT_IN_CHKP_BNDLDX}, @code{BUILT_IN_CHKP_BNDCL}, +@code{BUILT_IN_CHKP_BNDCU}, @code{BUILT_IN_CHKP_BNDRET}, +@code{BUILT_IN_CHKP_INTERSECT}, @code{BUILT_IN_CHKP_SET_PTR_BOUNDS}, +@code{BUILT_IN_CHKP_NARROW}, @code{BUILT_IN_CHKP_ARG_BND}, +@code{BUILT_IN_CHKP_SIZEOF}, @code{BUILT_IN_CHKP_EXTRACT_LOWER}, +@code{BUILT_IN_CHKP_EXTRACT_UPPER}. +@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_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 863e843a..2828361 100644 --- a/gcc/doc/tm.texi.in +++ b/gcc/doc/tm.texi.in @@ -3694,6 +3694,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 @@ -4064,6 +4066,10 @@ 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 + @node Trampolines @section Trampolines for Nested Functions @cindex trampolines for nested functions @@ -8184,6 +8190,10 @@ 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_RESOLVE_OVERLOADED_BUILTIN @hook TARGET_FOLD_BUILTIN diff --git a/gcc/langhooks-def.h b/gcc/langhooks-def.h index 7bd2e99..542c3d7 100644 --- a/gcc/langhooks-def.h +++ b/gcc/langhooks-def.h @@ -117,6 +117,7 @@ extern void lhd_omp_firstprivatize_type_sizes (struct gimplify_omp_ctx *, #define LANG_HOOKS_BLOCK_MAY_FALLTHRU hook_bool_const_tree_true #define LANG_HOOKS_EH_USE_CXA_END_CLEANUP false #define LANG_HOOKS_DEEP_UNSHARING false +#define LANG_HOOKS_CHKP_SUPPORTED false /* Attribute hooks. */ #define LANG_HOOKS_ATTRIBUTE_TABLE NULL @@ -302,7 +303,8 @@ extern void lhd_end_section (void); LANG_HOOKS_EH_PROTECT_CLEANUP_ACTIONS, \ LANG_HOOKS_BLOCK_MAY_FALLTHRU, \ LANG_HOOKS_EH_USE_CXA_END_CLEANUP, \ - LANG_HOOKS_DEEP_UNSHARING \ + LANG_HOOKS_DEEP_UNSHARING, \ + LANG_HOOKS_CHKP_SUPPORTED \ } #endif /* GCC_LANG_HOOKS_DEF_H */ diff --git a/gcc/langhooks.h b/gcc/langhooks.h index 80d4ef3..a4a8764 100644 --- a/gcc/langhooks.h +++ b/gcc/langhooks.h @@ -469,6 +469,9 @@ struct lang_hooks gimplification. */ bool deep_unsharing; + /* True if this language allows pointers checker instrumentation. */ + bool chkp_supported; + /* Whenever you add entries here, make sure you adjust langhooks-def.h and langhooks.c accordingly. */ }; diff --git a/gcc/target.def b/gcc/target.def index 6de513f..20fdb0a 100644 --- a/gcc/target.def +++ b/gcc/target.def @@ -2023,6 +2023,35 @@ 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\ +Pointers 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\ +@code{BUILT_IN_CHKP_BNDMK}, @code{BUILT_IN_CHKP_BNDSTX},\n\ +@code{BUILT_IN_CHKP_BNDLDX}, @code{BUILT_IN_CHKP_BNDCL},\n\ +@code{BUILT_IN_CHKP_BNDCU}, @code{BUILT_IN_CHKP_BNDRET},\n\ +@code{BUILT_IN_CHKP_INTERSECT}, @code{BUILT_IN_CHKP_SET_PTR_BOUNDS},\n\ +@code{BUILT_IN_CHKP_NARROW}, @code{BUILT_IN_CHKP_ARG_BND},\n\ +@code{BUILT_IN_CHKP_SIZEOF}, @code{BUILT_IN_CHKP_EXTRACT_LOWER},\n\ +@code{BUILT_IN_CHKP_EXTRACT_UPPER}.", + 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) + /* 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 @@ -3273,6 +3302,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 Pointers Checker to build bounds for\n\ +@code{va_list} object. Return @code{integer_zero_node} if no bounds should\n\ +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, @@ -3704,6 +3742,23 @@ not generate any instructions in this case.", default_setup_incoming_varargs) DEFHOOK +(load_bounds_for_arg, + "This hook is used to emit insn to load bounds of @var{arg} passed\n\ +in @var{slot}. In case @var{slot} is not a memory, @var{slot_no} is RTX\n\ +constant holding number of the special slot we should get bounds from.\n\ +Return loaded bounds.", + rtx, (rtx slot, rtx arg, rtx slot_no), + default_load_bounds_for_arg) + +DEFHOOK +(store_bounds_for_arg, + "This hook is used to emit insn to store bounds of @var{arg} passed\n\ +in @var{slot}. In case @var{slot} is not a memory, @var{slot_no} is RTX\n\ +constant holding number of the special slot we should store bounds to.", + void, (rtx arg, rtx slot, rtx bounds, rtx slot_no), + default_store_bounds_for_arg) + +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\ diff --git a/gcc/targhooks.c b/gcc/targhooks.c index ec73a64..b912eb8 100644 --- a/gcc/targhooks.c +++ b/gcc/targhooks.c @@ -1556,6 +1556,28 @@ 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 (); +} + +tree +default_fn_abi_va_list_bounds_size (tree fndecl ATTRIBUTE_UNUSED) +{ + return integer_zero_node; +} /* Default version of canonicalize_comparison. */ @@ -1564,4 +1586,25 @@ default_canonicalize_comparison (int *, rtx *, rtx *, bool) { } +tree +default_chkp_bound_type (void) +{ + tree res = make_node (BOUND_TYPE); + TYPE_PRECISION (res) = TYPE_PRECISION (size_type_node) * 2; + 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; +} + #include "gt-targhooks.h" diff --git a/gcc/targhooks.h b/gcc/targhooks.h index b3bd155..184b9c3 100644 --- a/gcc/targhooks.h +++ b/gcc/targhooks.h @@ -202,3 +202,10 @@ extern void default_asm_output_ident_directive (const char*); extern enum machine_mode default_cstore_mode (enum insn_code); extern bool default_member_type_forces_blk (const_tree, enum machine_mode); + +extern rtx default_load_bounds_for_arg (rtx, rtx, rtx); +extern void default_store_bounds_for_arg (rtx, rtx, 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);