From patchwork Mon Nov 18 09:39:00 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ilya Enkovich X-Patchwork-Id: 291998 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)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 97AB12C00E3 for ; Mon, 18 Nov 2013 20:40:03 +1100 (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:subject:message-id:mime-version:content-type; q=dns; s= default; b=lMIHVqS4/KvIxz3YM2ImMcWjopALhyLeC8LHqI8FqJzMt1mKBw1T5 IN9HD9x3MedULrN5BxHA/QoHfI5FUlCy1IMkXNebHx92EKNzUA5WBbEk1j1auMwE E4u1jCHfAn3J/QY2kZRzeoHNs+UG41WQFddnPRghQ0xCJQAZDnVujw= 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:subject:message-id:mime-version:content-type; s= default; bh=eci178Yp1O9KGz3u+FCO5qoftsA=; b=SOVOYGseJsC5CM/Kblpe kRQKj2akU5X6nPpbZthQ/5rWj+GNcrGL57KIHHooGxchtkR5VyAh18R9TkmVVJIr k/bIFjktyiuLXoaHwqF5NdWWqo5NVFKqErKsCn1NQVIhzXTKeuEFyyBWmaIqfrPX lwKx3IJoWPe3mV95WZhVbys= Received: (qmail 25024 invoked by alias); 18 Nov 2013 09:39: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 25013 invoked by uid 89); 18 Nov 2013 09:39:52 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=0.8 required=5.0 tests=AWL, BAYES_50, FREEMAIL_FROM, RDNS_NONE, SPF_PASS, URIBL_BLOCKED autolearn=no version=3.3.2 X-HELO: mail-pd0-f181.google.com Received: from Unknown (HELO mail-pd0-f181.google.com) (209.85.192.181) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-SHA encrypted) ESMTPS; Mon, 18 Nov 2013 09:39:51 +0000 Received: by mail-pd0-f181.google.com with SMTP id p10so6211448pdj.26 for ; Mon, 18 Nov 2013 01:39:45 -0800 (PST) X-Received: by 10.66.226.46 with SMTP id rp14mr1990113pac.133.1384767585723; Mon, 18 Nov 2013 01:39:45 -0800 (PST) Received: from msticlxl57.ims.intel.com ([192.55.54.41]) by mx.google.com with ESMTPSA id hn5sm11080667pbb.25.2013.11.18.01.39.44 for (version=TLSv1 cipher=RC4-SHA bits=128/128); Mon, 18 Nov 2013 01:39:45 -0800 (PST) Date: Mon, 18 Nov 2013 13:39:00 +0400 From: Ilya Enkovich To: gcc-patches@gcc.gnu.org Subject: [PATCH, MPX, 2/X] Pointers Checker [11/25] Expand builtins Message-ID: <20131118093900.GE21297@msticlxl57.ims.intel.com> MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.5.21 (2010-09-15) X-IsSubscribed: yes Hi, Here is a patch to adopt some builtins expanding to Pointer Bounds Checker. Patch mostly disables inlining of instrumented calls to string function. Also adds support for _NOBND_NOCHK versions of string functions (this version does not check and copy bounds; therefore may be inlined as regular string function). Thanks, Ilya --- 2013-11-13 Ilya Enkovich * builtins.c: Include rtl-chkp.h, tree-chkp.h. (expand_builtin_mempcpy_args): Add orig exp as argument. Support BUILT_IN_CHKP_MEMPCPY_NOBND_NOCHK. (expand_builtin_mempcpy): Adjust expand_builtin_mempcpy_args call. (expand_builtin_stpcpy): Likewise. (expand_builtin_memset_args): Support BUILT_IN_CHKP_MEMSET_NOBND_NOCHK. (std_expand_builtin_va_start): Initialize bounds for va_list. (expand_builtin): Support instrumented calls. * optabs.c: Include rtl-chkp.h. (expand_unop): Handle bounds in libcall return value. diff --git a/gcc/builtins.c b/gcc/builtins.c index 7a04664..b46c364 100644 --- a/gcc/builtins.c +++ b/gcc/builtins.c @@ -50,6 +50,8 @@ along with GCC; see the file COPYING3. If not see #include "builtins.h" #include "ubsan.h" #include "cilk.h" +#include "tree-chkp.h" +#include "rtl-chkp.h" static tree do_mpc_arg1 (tree, tree, int (*)(mpc_ptr, mpc_srcptr, mpc_rnd_t)); @@ -115,7 +117,7 @@ static rtx builtin_memcpy_read_str (void *, HOST_WIDE_INT, enum machine_mode); static rtx expand_builtin_memcpy (tree, rtx); static rtx expand_builtin_mempcpy (tree, rtx, enum machine_mode); static rtx expand_builtin_mempcpy_args (tree, tree, tree, rtx, - enum machine_mode, int); + enum machine_mode, int, tree); static rtx expand_builtin_strcpy (tree, rtx); static rtx expand_builtin_strcpy_args (tree, tree, rtx); static rtx expand_builtin_stpcpy (tree, rtx, enum machine_mode); @@ -3195,7 +3197,8 @@ expand_builtin_mempcpy (tree exp, rtx target, enum machine_mode mode) tree src = CALL_EXPR_ARG (exp, 1); tree len = CALL_EXPR_ARG (exp, 2); return expand_builtin_mempcpy_args (dest, src, len, - target, mode, /*endp=*/ 1); + target, mode, /*endp=*/ 1, + exp); } } @@ -3207,10 +3210,23 @@ expand_builtin_mempcpy (tree exp, rtx target, enum machine_mode mode) static rtx expand_builtin_mempcpy_args (tree dest, tree src, tree len, - rtx target, enum machine_mode mode, int endp) + rtx target, enum machine_mode mode, int endp, + tree orig_exp) { + tree fndecl = get_callee_fndecl (orig_exp); + /* If return value is ignored, transform mempcpy into memcpy. */ - if (target == const0_rtx && builtin_decl_implicit_p (BUILT_IN_MEMCPY)) + if (target == const0_rtx + && DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CHKP_MEMPCPY_NOBND_NOCHK + && builtin_decl_implicit_p (BUILT_IN_CHKP_MEMCPY_NOBND_NOCHK)) + { + tree fn = builtin_decl_implicit (BUILT_IN_CHKP_MEMCPY_NOBND_NOCHK); + tree result = build_call_nofold_loc (UNKNOWN_LOCATION, fn, 3, + dest, src, len); + return expand_expr (result, target, mode, EXPAND_NORMAL); + } + else if (target == const0_rtx + && builtin_decl_implicit_p (BUILT_IN_MEMCPY)) { tree fn = builtin_decl_implicit (BUILT_IN_MEMCPY); tree result = build_call_nofold_loc (UNKNOWN_LOCATION, fn, 3, @@ -3394,7 +3410,8 @@ expand_builtin_stpcpy (tree exp, rtx target, enum machine_mode mode) lenp1 = size_binop_loc (loc, PLUS_EXPR, len, ssize_int (1)); ret = expand_builtin_mempcpy_args (dst, src, lenp1, - target, mode, /*endp=*/2); + target, mode, /*endp=*/2, + exp); if (ret) return ret; @@ -3679,7 +3696,8 @@ expand_builtin_memset_args (tree dest, tree val, tree len, do_libcall: fndecl = get_callee_fndecl (orig_exp); fcode = DECL_FUNCTION_CODE (fndecl); - if (fcode == BUILT_IN_MEMSET) + if (fcode == BUILT_IN_MEMSET + || fcode == BUILT_IN_CHKP_MEMSET_NOBND_NOCHK) fn = build_call_nofold_loc (EXPR_LOCATION (orig_exp), fndecl, 3, dest, val, len); else if (fcode == BUILT_IN_BZERO) @@ -4231,6 +4249,13 @@ std_expand_builtin_va_start (tree valist, rtx nextarg) { rtx va_r = expand_expr (valist, NULL_RTX, VOIDmode, EXPAND_WRITE); convert_move (va_r, nextarg, 0); + + /* We do not have any valid bounds for the pointer, so + just store zero bounds for it. */ + if (chkp_function_instrumented_p (current_function_decl)) + chkp_expand_bounds_reset_for_mem (valist, + make_tree (TREE_TYPE (valist), + nextarg)); } /* Expand EXP, a call to __builtin_va_start. */ @@ -6031,60 +6056,113 @@ expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode, break; case BUILT_IN_STRLEN: + if (CALL_WITH_BOUNDS_P (exp)) + break; target = expand_builtin_strlen (exp, target, target_mode); if (target) return target; break; case BUILT_IN_STRCPY: + if (CALL_WITH_BOUNDS_P (exp)) + break; target = expand_builtin_strcpy (exp, target); if (target) return target; break; case BUILT_IN_STRNCPY: + if (CALL_WITH_BOUNDS_P (exp)) + break; target = expand_builtin_strncpy (exp, target); if (target) return target; break; case BUILT_IN_STPCPY: + if (CALL_WITH_BOUNDS_P (exp)) + break; target = expand_builtin_stpcpy (exp, target, mode); if (target) return target; break; case BUILT_IN_MEMCPY: + case BUILT_IN_CHKP_MEMCPY_NOBND_NOCHK: + if (CALL_WITH_BOUNDS_P (exp) + && fcode == BUILT_IN_MEMCPY) + break; target = expand_builtin_memcpy (exp, target); if (target) - return target; + { + /* We need to set returned bounds for instrumented + calls. */ + if (CALL_WITH_BOUNDS_P (exp)) + { + rtx bnd = chkp_expand_arg_bounds (CALL_EXPR_ARG (exp, 0)); + target = chkp_join_splitted_slot (target, bnd); + } + return target; + } break; case BUILT_IN_MEMPCPY: + case BUILT_IN_CHKP_MEMPCPY_NOBND_NOCHK: + if (CALL_WITH_BOUNDS_P (exp) + && fcode == BUILT_IN_MEMPCPY) + break; target = expand_builtin_mempcpy (exp, target, mode); if (target) - return target; + { + /* We need to set returned bounds for instrumented + calls. */ + if (CALL_WITH_BOUNDS_P (exp)) + { + rtx bnd = chkp_expand_arg_bounds (CALL_EXPR_ARG (exp, 0)); + target = chkp_join_splitted_slot (target, bnd); + } + return target; + } break; case BUILT_IN_MEMSET: + case BUILT_IN_CHKP_MEMSET_NOBND_NOCHK: + if (CALL_WITH_BOUNDS_P (exp) + && fcode == BUILT_IN_MEMSET) + break; target = expand_builtin_memset (exp, target, mode); if (target) - return target; + { + /* We need to set returned bounds for instrumented + calls. */ + if (CALL_WITH_BOUNDS_P (exp)) + { + rtx bnd = chkp_expand_arg_bounds (CALL_EXPR_ARG (exp, 0)); + target = chkp_join_splitted_slot (target, bnd); + } + return target; + } break; case BUILT_IN_BZERO: + if (CALL_WITH_BOUNDS_P (exp)) + break; target = expand_builtin_bzero (exp); if (target) return target; break; case BUILT_IN_STRCMP: + if (CALL_WITH_BOUNDS_P (exp)) + break; target = expand_builtin_strcmp (exp, target); if (target) return target; break; case BUILT_IN_STRNCMP: + if (CALL_WITH_BOUNDS_P (exp)) + break; target = expand_builtin_strncmp (exp, target, mode); if (target) return target; @@ -6092,6 +6170,8 @@ expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode, case BUILT_IN_BCMP: case BUILT_IN_MEMCMP: + if (CALL_WITH_BOUNDS_P (exp)) + break; target = expand_builtin_memcmp (exp, target, mode); if (target) return target; @@ -6718,6 +6798,8 @@ expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode, case BUILT_IN_MEMPCPY_CHK: case BUILT_IN_MEMMOVE_CHK: case BUILT_IN_MEMSET_CHK: + if (CALL_WITH_BOUNDS_P (exp)) + break; target = expand_builtin_memory_chk (exp, target, mode, fcode); if (target) return target; @@ -6774,7 +6856,7 @@ expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode, case BUILT_IN_CHKP_GET_PTR_UBOUND: /* We allow user CHKP builtins if Pointer Bounds Checker is off. */ - if (!flag_check_pointer_bounds) + if (!chkp_function_instrumented_p (current_function_decl)) { if (fcode == BUILT_IN_CHKP_SET_PTR_BOUNDS || fcode == BUILT_IN_CHKP_NARROW_PTR_BOUNDS) @@ -6799,7 +6881,7 @@ expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode, case BUILT_IN_CHKP_NARROW: case BUILT_IN_CHKP_EXTRACT_LOWER: case BUILT_IN_CHKP_EXTRACT_UPPER: - /* Software implementation of pointers checker is NYI. + /* Software implementation of Pointer Bounds Checker is NYI. Target support is required. */ error ("Your target platform does not support -fcheck-pointers"); break; diff --git a/gcc/optabs.c b/gcc/optabs.c index 164e4dd..736f032 100644 --- a/gcc/optabs.c +++ b/gcc/optabs.c @@ -41,6 +41,7 @@ along with GCC; see the file COPYING3. If not see #include "ggc.h" #include "basic-block.h" #include "target.h" +#include "rtl-chkp.h" struct target_optabs default_target_optabs; struct target_libfuncs default_target_libfuncs; @@ -3256,9 +3257,14 @@ expand_unop (enum machine_mode mode, optab unoptab, rtx op0, rtx target, if (unoptab == ffs_optab || unoptab == clz_optab || unoptab == ctz_optab || unoptab == clrsb_optab || unoptab == popcount_optab || unoptab == parity_optab) - outmode - = GET_MODE (hard_libcall_value (TYPE_MODE (integer_type_node), - optab_libfunc (unoptab, mode))); + { + rtx bnd, val; + + val = hard_libcall_value (TYPE_MODE (integer_type_node), + optab_libfunc (unoptab, mode)); + chkp_split_slot (val, &val, &bnd); + outmode = GET_MODE (val); + } start_sequence ();