From patchwork Mon Mar 11 10:29:39 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Botcazou X-Patchwork-Id: 1054331 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-497670-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=adacore.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="NyCc/uDy"; dkim-atps=neutral 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 44HvVq42KSz9s00 for ; Mon, 11 Mar 2019 21:29:53 +1100 (AEDT) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:subject:date:message-id:mime-version:content-type :content-transfer-encoding; q=dns; s=default; b=QvttcPJ8u0kHs/iH CLzuSTO5jWRHWcxq9rmqqEgcaF/CHlF7hkKc7zU3MTo3Agtmg8wlsCUrROrEMQjC VCRMjQguKMAu+wCCtZmX0zgZ2kKd2pNjGnoV1t6LEn1d2UiB/kmMEV0onLM1b7R/ VXIi1kMvxyMmqy3/vZQxx2Cv2E4= 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:from :to:subject:date:message-id:mime-version:content-type :content-transfer-encoding; s=default; bh=Eax/id88qS1C08vCQduHfy t+MuI=; b=NyCc/uDytBtHfEBJlAusURW0EX0vsGq5Op1FvQMewZcdTAwT31C+RD Mmu6lppTq9haSP55KL4h7bSQvFesZZHWGXIp8hW21c5vhEuB79ChsEvE42dtcbUo /u4+vsCfA0QNJsAEgVVYf1Cpbx+UifN/w705K1lBbEfjV5IS8yAYU= Received: (qmail 33170 invoked by alias); 11 Mar 2019 10:29:45 -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 33162 invoked by uid 89); 11 Mar 2019 10:29:45 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-6.4 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_2, GIT_PATCH_3, KAM_ASCII_DIVIDERS, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.1 spammy=minor, sk:0xfffff, layout, machine_mode X-HELO: smtp.eu.adacore.com Received: from mel.act-europe.fr (HELO smtp.eu.adacore.com) (194.98.77.210) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Mon, 11 Mar 2019 10:29:43 +0000 Received: from localhost (localhost [127.0.0.1]) by filtered-smtp.eu.adacore.com (Postfix) with ESMTP id 2050D8138B for ; Mon, 11 Mar 2019 11:29:41 +0100 (CET) Received: from smtp.eu.adacore.com ([127.0.0.1]) by localhost (smtp.eu.adacore.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id HsddPoIjloRy for ; Mon, 11 Mar 2019 11:29:41 +0100 (CET) Received: from polaris.localnet (bon31-6-88-161-99-133.fbx.proxad.net [88.161.99.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.eu.adacore.com (Postfix) with ESMTPSA id DABFC81387 for ; Mon, 11 Mar 2019 11:29:40 +0100 (CET) From: Eric Botcazou To: gcc-patches@gcc.gnu.org Subject: [patch] Fix ASAN failures on SPARC64/Linux Date: Mon, 11 Mar 2019 11:29:39 +0100 Message-ID: <4930863.as9yYVlIhr@polaris> MIME-Version: 1.0 Hi, ASAN was enabled for the SPARC architecture during GCC 9 development but it doesn't really work on SPARC64/Linux because of the specific layout of the virtual memory address space. Fortunately this is (easily) fixable and the fix has been accepted upstream, along with other fixes for SPARC (I have attached the asan/asan_mapping_sparc64.h file accepted upstream). But, since GCC also hardcodes the scaling done by ASAN, this also requires a small adjustment to the compiler proper by means of a hook, tentatively called TARGET_ASAN_SHADOW_LEFT_SHIFT, which is defined to NULL except for SPARC. It yields a 100% clean ASAN testsuite on SPARC64/Linux (32-bit and 64-bit). Tested on SPARC64/Linux, SPARC/Solaris and x86-64/Linux, OK for the mainline? 2019-03-11 Eric Botcazou PR sanitizer/80953 * target.def (asan_shadow_left_shift): New hook. (asan_shadow_offset): Minor tweak. * doc/tm.texi.in: Add TARGET_ASAN_SHADOW_LEFT_SHIFT. * doc/tm.texi: Regenerate. * asan.c (asan_emit_stack_protection): Do a preliminary left shift if TARGET_ASAN_SHADOW_LEFT_SHIFT is positive. (build_shadow_mem_access): Likewise. * config/sparc/sparc.c (TARGET_ASAN_SHADOW_LEFT_SHIFT): Define to... (sparc_asan_shadow_left_shift): ...this. New function. Index: asan.c =================================================================== --- asan.c (revision 269546) +++ asan.c (working copy) @@ -1380,6 +1380,7 @@ asan_emit_stack_protection (rtx base, rt unsigned char cur_shadow_byte = ASAN_STACK_MAGIC_LEFT; tree str_cst, decl, id; int use_after_return_class = -1; + unsigned int shift; if (shadow_ptr_types[0] == NULL_TREE) asan_init_shadow_ptr_types (); @@ -1524,8 +1525,19 @@ asan_emit_stack_protection (rtx base, rt TREE_ASM_WRITTEN (decl) = 1; TREE_ASM_WRITTEN (id) = 1; emit_move_insn (mem, expand_normal (build_fold_addr_expr (decl))); - shadow_base = expand_binop (Pmode, lshr_optab, base, - gen_int_shift_amount (Pmode, ASAN_SHADOW_SHIFT), + shadow_base = base; + if (targetm.asan_shadow_left_shift + && (shift = targetm.asan_shadow_left_shift ()) > 0) + { + shadow_base = expand_binop (Pmode, ashl_optab, shadow_base, + gen_int_shift_amount (Pmode, shift), + NULL_RTX, 1, OPTAB_DIRECT); + shift += ASAN_SHADOW_SHIFT; + } + else + shift = ASAN_SHADOW_SHIFT; + shadow_base = expand_binop (Pmode, lshr_optab, shadow_base, + gen_int_shift_amount (Pmode, shift), NULL_RTX, 1, OPTAB_DIRECT); shadow_base = plus_constant (Pmode, shadow_base, @@ -2023,9 +2035,24 @@ build_shadow_mem_access (gimple_stmt_ite { tree t, uintptr_type = TREE_TYPE (base_addr); tree shadow_type = TREE_TYPE (shadow_ptr_type); + unsigned int shift; gimple *g; - t = build_int_cst (uintptr_type, ASAN_SHADOW_SHIFT); + if (targetm.asan_shadow_left_shift + && (shift = targetm.asan_shadow_left_shift ()) > 0) + { + t = build_int_cst (uintptr_type, shift); + g = gimple_build_assign (make_ssa_name (uintptr_type), LSHIFT_EXPR, + base_addr, t); + gimple_set_location (g, location); + gsi_insert_after (gsi, g, GSI_NEW_STMT); + base_addr = gimple_assign_lhs (g); + shift += ASAN_SHADOW_SHIFT; + } + else + shift = ASAN_SHADOW_SHIFT; + + t = build_int_cst (uintptr_type, shift); g = gimple_build_assign (make_ssa_name (uintptr_type), RSHIFT_EXPR, base_addr, t); gimple_set_location (g, location); Index: config/sparc/sparc.c =================================================================== --- config/sparc/sparc.c (revision 269546) +++ config/sparc/sparc.c (working copy) @@ -674,6 +674,7 @@ static rtx sparc_struct_value_rtx (tree, static rtx sparc_function_value (const_tree, const_tree, bool); static rtx sparc_libcall_value (machine_mode, const_rtx); static bool sparc_function_value_regno_p (const unsigned int); +static unsigned int sparc_asan_shadow_left_shift (void); static unsigned HOST_WIDE_INT sparc_asan_shadow_offset (void); static void sparc_output_dwarf_dtprel (FILE *, int, rtx) ATTRIBUTE_UNUSED; static void sparc_file_end (void); @@ -835,6 +836,9 @@ char sparc_hard_reg_printed[8]; #undef TARGET_EXPAND_BUILTIN_SAVEREGS #define TARGET_EXPAND_BUILTIN_SAVEREGS sparc_builtin_saveregs +#undef TARGET_ASAN_SHADOW_LEFT_SHIFT +#define TARGET_ASAN_SHADOW_LEFT_SHIFT sparc_asan_shadow_left_shift + #undef TARGET_ASAN_SHADOW_OFFSET #define TARGET_ASAN_SHADOW_OFFSET sparc_asan_shadow_offset @@ -12493,7 +12497,16 @@ sparc_init_machine_status (void) { return ggc_cleared_alloc (); } - + +/* Implement the TARGET_ASAN_SHADOW_LEFT_SHIFT hook. */ + +static unsigned int +sparc_asan_shadow_left_shift (void) +{ + /* This is tailored to the 52-bit VM layout on SPARC-T4 and later. */ + return TARGET_ARCH64 ? 12 : 0; +} + /* Implement the TARGET_ASAN_SHADOW_OFFSET hook. */ static unsigned HOST_WIDE_INT Index: doc/tm.texi =================================================================== --- doc/tm.texi (revision 269546) +++ doc/tm.texi (working copy) @@ -11975,10 +11975,17 @@ MIPS, where add-immediate takes a 16-bit is zero, which disables this optimization. @end deftypevr +@deftypefn {Target Hook} {unsigned int} TARGET_ASAN_SHADOW_LEFT_SHIFT (void) +Return the amount by which an address must first be shifted to the left +and then back to the right, before being normally shifted to the right, +to get the corresponding Address Sanitizer shadow address. NULL means that +such a left shift is not needed. +@end deftypefn + @deftypefn {Target Hook} {unsigned HOST_WIDE_INT} TARGET_ASAN_SHADOW_OFFSET (void) -Return the offset bitwise ored into shifted address to get corresponding -Address Sanitizer shadow memory address. NULL if Address Sanitizer is not -supported by the target. +Return the offset added to a shifted address to get the corresponding +Address Sanitizer shadow memory address. NULL means that the Address +Sanitizer is not supported by the target. @end deftypefn @deftypefn {Target Hook} {unsigned HOST_WIDE_INT} TARGET_MEMMODEL_CHECK (unsigned HOST_WIDE_INT @var{val}) Index: doc/tm.texi.in =================================================================== --- doc/tm.texi.in (revision 269546) +++ doc/tm.texi.in (working copy) @@ -8110,6 +8110,8 @@ and the associated definitions of those @hook TARGET_CONST_ANCHOR +@hook TARGET_ASAN_SHADOW_LEFT_SHIFT + @hook TARGET_ASAN_SHADOW_OFFSET @hook TARGET_MEMMODEL_CHECK Index: target.def =================================================================== --- target.def (revision 269546) +++ target.def (working copy) @@ -4307,14 +4307,24 @@ DEFHOOK memory model bits are allowed.", unsigned HOST_WIDE_INT, (unsigned HOST_WIDE_INT val), NULL) -/* Defines an offset bitwise ored into shifted address to get corresponding - Address Sanitizer shadow address, or -1 if Address Sanitizer is not - supported by the target. */ +/* Defines the amount by which an address must first be shifted to the left + to get the corresponding Address Sanitizer shadow address. */ +DEFHOOK +(asan_shadow_left_shift, + "Return the amount by which an address must first be shifted to the left\n\ +and then back to the right, before being normally shifted to the right,\n\ +to get the corresponding Address Sanitizer shadow address. NULL means that\n\ +such a left shift is not needed.", + unsigned int, (void), + NULL) + +/* Defines the offset added to a shifted address to get the corresponding + Address Sanitizer shadow address. */ DEFHOOK (asan_shadow_offset, - "Return the offset bitwise ored into shifted address to get corresponding\n\ -Address Sanitizer shadow memory address. NULL if Address Sanitizer is not\n\ -supported by the target.", + "Return the offset added to a shifted address to get the corresponding\n\ +Address Sanitizer shadow memory address. NULL means that the Address\n\ +Sanitizer is not supported by the target.", unsigned HOST_WIDE_INT, (void), NULL)