From patchwork Fri Aug 15 15:08:26 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ilya Enkovich X-Patchwork-Id: 380266 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 1A204140093 for ; Sat, 16 Aug 2014 01:09:02 +1000 (EST) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:cc:subject:message-id:references:mime-version :content-type:in-reply-to; q=dns; s=default; b=VWudpBtxxylfdgqQ2 5g5KvG6DrjBMzQrNupNsvu+Wrv1Pu6/BP57NZyDyfGYwLek8+2z0N57SizPVBA36 NCEOlJ2beg8Py9R6YP4Dh1GrCKMCsZ9D9fnv0AJbujnix1t5e4reh45VZrlk1Ws3 g8vsO6d/ACGZ1/XDDWoUMcoWEw= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:cc:subject:message-id:references:mime-version :content-type:in-reply-to; s=default; bh=AcztC7g8WkrHTgAvkUobHQ2 TfPY=; b=rrDR2OZ06CFbwp1grfJqzBD9u24rBGdwnyej1X/V6uSm4kLMVSZhc34 f+tIWy96HmILGj0E74exy5IjNnoSPXLETRIwK6CLsJQZ8c7BeGunuR4NW4yvY1aK igw8QfOIoeXBBXb3/LTzFFVYCmeicV8TTEi+cdQEY7n/mcmJs1Ys= Received: (qmail 28939 invoked by alias); 15 Aug 2014 15:08:53 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 28855 invoked by uid 89); 15 Aug 2014 15:08:47 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.5 required=5.0 tests=AWL, BAYES_00, FREEMAIL_FROM, RCVD_IN_DNSWL_LOW, SPF_PASS autolearn=ham version=3.3.2 X-HELO: mail-pd0-f171.google.com Received: from mail-pd0-f171.google.com (HELO mail-pd0-f171.google.com) (209.85.192.171) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-SHA encrypted) ESMTPS; Fri, 15 Aug 2014 15:08:39 +0000 Received: by mail-pd0-f171.google.com with SMTP id z10so3480235pdj.2 for ; Fri, 15 Aug 2014 08:08:36 -0700 (PDT) X-Received: by 10.66.152.131 with SMTP id uy3mr13050638pab.13.1408115316472; Fri, 15 Aug 2014 08:08:36 -0700 (PDT) Received: from msticlxl57.ims.intel.com (fmdmzpr03-ext.fm.intel.com. [192.55.54.38]) by mx.google.com with ESMTPSA id re8sm12335496pdb.61.2014.08.15.08.08.34 for (version=TLSv1 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Fri, 15 Aug 2014 08:08:35 -0700 (PDT) Date: Fri, 15 Aug 2014 19:08:26 +0400 From: Ilya Enkovich To: Jeff Law Cc: gcc-patches@gcc.gnu.org Subject: Re: [PATCH, Pointer Bounds Checker 3/x] Target hooks for Pointer Bounds Checker Message-ID: <20140815150300.GA59799@msticlxl57.ims.intel.com> References: <20140416115211.GB4040@msticlxl57.ims.intel.com> <53C7991F.7050204@redhat.com> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <53C7991F.7050204@redhat.com> User-Agent: Mutt/1.5.21 (2010-09-15) X-IsSubscribed: yes 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 * 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);