From patchwork Wed Jul 27 05:13:52 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexandre Oliva X-Patchwork-Id: 199 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:6a10:b5d6:b0:2b9:3548:2db5 with SMTP id v22csp183307pxt; Tue, 26 Jul 2022 22:14:54 -0700 (PDT) X-Google-Smtp-Source: AGRyM1towYdQMArZKL1XZBtXffSzuQegAMbd6VtO9bWU9rBAALnJ2/2ubp/xIqZZFd5TaqbIOkhS X-Received: by 2002:aa7:cf13:0:b0:43b:a842:e482 with SMTP id a19-20020aa7cf13000000b0043ba842e482mr21499877edy.192.1658898894654; Tue, 26 Jul 2022 22:14:54 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1658898894; cv=none; d=google.com; s=arc-20160816; b=eTWqCPIz7ocaj+XVR1C4HIQRHVe+GhnHbBtOr2dTv9KR1qeguCKpFXLfhu2QDd1ft4 3B8/zKNkwCqGkZmFzqulX/PsRSXOm3JguikLDIiPwP+Dp6rMO+w+AjBRpXYSUbyjf06e Ah3HcOA0NcmjofUL8IqOCTX16ahFrWCCG7zm/RracUEiJ4AHw7fI7ywGKcnkRLcQBJuk 8mba/K0NpZlDlG77qRz9cSvVbNzwnr/XpNwV+n/XVdIhpyYCuv4MfxTmA+pEgbIEOHhX hvmu9NfjJfOnY+IAluMKyIecGmuPQfq5oEJ3wymDjMBU+Mgz7C9U6XvqC0Gd1VPIQvWE j6jQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:reply-to:from:list-subscribe:list-help :list-post:list-archive:list-unsubscribe:list-id:precedence :mime-version:user-agent:message-id:date:organization:subject:to :dmarc-filter:delivered-to:dkim-signature:dkim-filter; bh=6HaQ9uEzkUgKR9qmMsMPz+w0Sf0qWm0qQAP9RjbuqHk=; b=O3pPGBRl41hf3l/Z5IFUFGF3clkyfdlKcmXBYGPaap2DiN3BLS6Zy5X78otqaoUWKE fUWIFe1wBcWI30zD+9898asO/nRx8t6AFcEX0oIcgXr+iLWqCG8W1V44ReTSppovGTRF +7cO0w0nyFYg+a1O+oGp1tj5Lp7P3/PmrEsrRhA6g2zAHW8smLN/PngZXb0zuwfWtsZt QzJwm2I66fZV18TCdMQIPRUROTqibCltCy34ooJxHbmYILgbLGU5t9T+9vP64MgrpBqz wbJKBpCxJtLpcrQj/qHuFQP1OS5XBsEdR6Cvv+Mc0/U/mKSvEiUrUD2BRSKfAZkeC6y4 nkcw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gcc.gnu.org header.s=default header.b="Qh/40qTh"; spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=gnu.org Received: from sourceware.org (server2.sourceware.org. [2620:52:3:1:0:246e:9693:128c]) by mx.google.com with ESMTPS id o5-20020a170906358500b007269e670e4asi13809105ejb.912.2022.07.26.22.14.54 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 26 Jul 2022 22:14:54 -0700 (PDT) Received-SPF: pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) client-ip=2620:52:3:1:0:246e:9693:128c; Authentication-Results: mx.google.com; dkim=pass header.i=@gcc.gnu.org header.s=default header.b="Qh/40qTh"; spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=gnu.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 4FB763857BA8 for ; Wed, 27 Jul 2022 05:14:53 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 4FB763857BA8 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1658898893; bh=6HaQ9uEzkUgKR9qmMsMPz+w0Sf0qWm0qQAP9RjbuqHk=; h=To:Subject:Date:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:Cc:From; b=Qh/40qTh64ITVMZCfl8fVDwbXw4QZ0I1THC943regxgbu/IhiUG1nVH2TgbMI6BzN HJRZYZanhOL2etkDYPBupSSmHKta1STjzCA+ExTdQ6FF2tLtOQO9FJFT/EN+sMjNOG jnlg7eeVV6eF4U2W9JvpXSeUWg73cg5/nf4fhBOQ= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from rock.gnat.com (rock.gnat.com [IPv6:2620:20:4000:0:a9e:1ff:fe9b:1d1]) by sourceware.org (Postfix) with ESMTPS id 505AC3857BA8 for ; Wed, 27 Jul 2022 05:14:10 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 505AC3857BA8 Received: from localhost (localhost.localdomain [127.0.0.1]) by filtered-rock.gnat.com (Postfix) with ESMTP id 1C7F311677B; Wed, 27 Jul 2022 01:14:10 -0400 (EDT) X-Virus-Scanned: Debian amavisd-new at gnat.com Received: from rock.gnat.com ([127.0.0.1]) by localhost (rock.gnat.com [127.0.0.1]) (amavisd-new, port 10024) with LMTP id j6CBZZiuQFUQ; Wed, 27 Jul 2022 01:14:10 -0400 (EDT) Received: from free.home (tron.gnat.com [IPv6:2620:20:4000:0:46a8:42ff:fe0e:e294]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by rock.gnat.com (Postfix) with ESMTPS id 7EAF2116771; Wed, 27 Jul 2022 01:14:03 -0400 (EDT) Received: from livre (livre.home [172.31.160.2]) by free.home (8.15.2/8.15.2) with ESMTPS id 26R5DqFm1760064 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Wed, 27 Jul 2022 02:13:53 -0300 To: gcc-patches@gcc.gnu.org Subject: [PATCH] [PR83782] i386 PIE: avoid @GOTOFF for ifuncs and their aliases Organization: Free thinker, does not speak for AdaCore Date: Wed, 27 Jul 2022 02:13:52 -0300 Message-ID: User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/25.2 (gnu/linux) MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 X-Spam-Status: No, score=-11.5 required=5.0 tests=BAYES_00, GIT_PATCH_0, KAM_DMARC_STATUS, KAM_SHORT, KAM_STOCKGEN, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Alexandre Oliva via Gcc-patches From: Alexandre Oliva Reply-To: Alexandre Oliva Cc: hubicka@ucw.cz Errors-To: gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org Sender: "Gcc-patches" X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1739481567379698630?= X-GMAIL-MSGID: =?utf-8?q?1739481567379698630?= g++.dg/ext/attr-ifunc-3.C and gcc.target/i386/mvc10.c, not changed, have made it clear that there were problems in the optimizations to use @GOTOFF to refer to locally-bound ifuncs. GNU ld as recently as May 2018 would reject such constructs, whereas later versions will silently accept but generate incorrect PIE with them (attr-ifunc-3.C) or still reject them if referenced through aliases (mvc10.c). The use of @GOTOFF for locally-bound but externally-visible symbols (e.g. protected visibility) also breaks pointer identity if the canonical address ends up preempted by a PLT entry. This patch modifies the local_symbolic_operand predicate to disable @GOTOFF for locally-bound symbols that would require @PLT for calls, restoring earlier behavior and disabling the optimization that has proven problematic even on amd64. Eventually we may reintroduce the optimization, when the linker is fixed and we test for the fix before enabling it, and we exclude symbols whose canonical addresses may be preempted even when the symbol definition can't. pr83782 tests have been adjusted to expect @GOT instead of @GOTOFF. Regstrapped on x86_64-linux-gnu; also tested, along with other patches I'm posting today with "i386 PIE" in the subject, and compared default-PIE and default-nonPIE results on it, and on i686-linux-gnu. Ok to install? for gcc/ChangeLog PR target/83782 * config/i386/predicates.md (local_symbolic_operand): Disable GOTOFF even for locally-bound ifuncs. * config/i386/i386.cc (ix86_call_use_plt_p): Follow the alias chain looking for an ifunc, as in gcc.target/i386/mvc10.c. for gcc/testsuite/ChangeLog PR target/83782 * gcc.target/i386/pr83782-1.c: Adjust to require GOT rather than GOTOFF on ia32. * gcc.target/i386/pr83782-2.c: Likewise. --- gcc/config/i386/i386.cc | 16 ++++++++++------ gcc/config/i386/predicates.md | 4 +++- gcc/testsuite/gcc.target/i386/pr83782-1.c | 4 ++-- gcc/testsuite/gcc.target/i386/pr83782-2.c | 4 ++-- 4 files changed, 17 insertions(+), 11 deletions(-) diff --git a/gcc/config/i386/i386.cc b/gcc/config/i386/i386.cc index aab28da4b5d4b..5c5dc8d2373ff 100644 --- a/gcc/config/i386/i386.cc +++ b/gcc/config/i386/i386.cc @@ -16058,13 +16058,17 @@ ix86_call_use_plt_p (rtx call_op) { if (SYMBOL_REF_DECL (call_op) && TREE_CODE (SYMBOL_REF_DECL (call_op)) == FUNCTION_DECL) - { - /* NB: All ifunc functions must be called via PLT. */ - cgraph_node *node - = cgraph_node::get (SYMBOL_REF_DECL (call_op)); - if (node && node->ifunc_resolver) + /* NB: All ifunc functions must be called via PLT, and we have + to explicitly iterate over an alias chain looking for a + node marked as an ifunc(_resolver) to tell. That node is + itself aliased to the actual resolver function, so + ultimate_alias_target would skip the marker, and the call + may be to another declaration aliased to the ifunc. */ + for (cgraph_node *node + = cgraph_node::get (SYMBOL_REF_DECL (call_op)); + node && node->alias; node = node->get_alias_target ()) + if (node->ifunc_resolver) return true; - } return false; } return true; diff --git a/gcc/config/i386/predicates.md b/gcc/config/i386/predicates.md index 42053ea7209f6..411c06e22e600 100644 --- a/gcc/config/i386/predicates.md +++ b/gcc/config/i386/predicates.md @@ -596,7 +596,9 @@ (define_predicate "local_symbolic_operand" if (TARGET_DLLIMPORT_DECL_ATTRIBUTES && SYMBOL_REF_DLLIMPORT_P (op)) return false; if (SYMBOL_REF_LOCAL_P (op)) - return true; + /* ifuncname@GOTOFF was rejected by the x86 linker before May + 2018, and silently generated wrong code for PIE afterwards. */ + return !ix86_call_use_plt_p (op); /* There is, however, a not insubstantial body of code in the rest of the compiler that assumes it can just stick the results of diff --git a/gcc/testsuite/gcc.target/i386/pr83782-1.c b/gcc/testsuite/gcc.target/i386/pr83782-1.c index ce97b12e65d58..af52278ec4df2 100644 --- a/gcc/testsuite/gcc.target/i386/pr83782-1.c +++ b/gcc/testsuite/gcc.target/i386/pr83782-1.c @@ -20,7 +20,7 @@ bar(void) return foo; } -/* { dg-final { scan-assembler {leal[ \t]foo@GOTOFF\(%[^,]*\),[ \t]%eax} { target ia32 } } } */ +/* { dg-final { scan-assembler-not {leal[ \t]foo@GOTOFF\(%[^,]*\),[ \t]%eax} { target ia32 } } } */ /* { dg-final { scan-assembler {lea(?:l|q)[ \t]foo\(%rip\),[ \t]%(?:e|r)ax} { target { ! ia32 } } } } */ -/* { dg-final { scan-assembler-not "foo@GOT\\\(" { target ia32 } } } */ +/* { dg-final { scan-assembler "foo@GOT\\\(" { target ia32 } } } */ /* { dg-final { scan-assembler-not "foo@GOTPCREL\\\(" { target { ! ia32 } } } } */ diff --git a/gcc/testsuite/gcc.target/i386/pr83782-2.c b/gcc/testsuite/gcc.target/i386/pr83782-2.c index e25d258bbda43..15c7dc04e88c3 100644 --- a/gcc/testsuite/gcc.target/i386/pr83782-2.c +++ b/gcc/testsuite/gcc.target/i386/pr83782-2.c @@ -20,7 +20,7 @@ bar(void) return foo; } -/* { dg-final { scan-assembler {leal[ \t]foo@GOTOFF\(%[^,]*\),[ \t]%eax} { target ia32 } } } */ +/* { dg-final { scan-assembler-not {leal[ \t]foo@GOTOFF\(%[^,]*\),[ \t]%eax} { target ia32 } } } */ /* { dg-final { scan-assembler {lea(?:l|q)[ \t]foo\(%rip\),[ \t]%(?:e|r)ax} { target { ! ia32 } } } } */ -/* { dg-final { scan-assembler-not "foo@GOT\\\(" { target ia32 } } } */ +/* { dg-final { scan-assembler "foo@GOT\\\(" { target ia32 } } } */ /* { dg-final { scan-assembler-not "foo@GOTPCREL\\\(" { target { ! ia32 } } } } */