From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-oa1-x2e.google.com (mail-oa1-x2e.google.com [IPv6:2001:4860:4864:20::2e]) by sourceware.org (Postfix) with ESMTPS id CA81138319DB for ; Fri, 16 Jun 2023 07:26:43 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org CA81138319DB Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=adacore.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=adacore.com Received: by mail-oa1-x2e.google.com with SMTP id 586e51a60fabf-1a98a7fdf3bso368036fac.1 for ; Fri, 16 Jun 2023 00:26:43 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=adacore.com; s=google; t=1686900403; x=1689492403; h=content-transfer-encoding:mime-version:user-agent:message-id :in-reply-to:date:errors-to:references:organization:subject:cc:to :from:from:to:cc:subject:date:message-id:reply-to; bh=0pIfBootcGRBUNsx000mJ2M1pwuC5O5Su+1k0IwTkSM=; b=gQ52AldXQiRoHIPLiG+Bv8Bk2eo3A2nHMEXhC6MDjCG4v8f/59bASTjZ7SShZMAHjc oIJ6nW+wqm2vyvnKhKkJSH8Fd9GYQr6efhRlCvjtzOBTXEaonYvvNF56Y1XW0kf2dRn+ OplWk67VQ3wsH2c16e0/Y4HtgZFPZOn61cfTyJ3oX4dGGXhDxsNOLtfRhRkfP3gdCZmE 5BcuWqm1Z99tm2u0nQXExwbFbj4kJIUnNVaFERpZd9xPBG3Sh4277NUR3+cL6AP8H7MY 78GRY9YoVRphyGgLeH4mGsRGYuwxgykDDGZINGMycC6wgBEEQbj14CXwAwuD9vPthVLD OOHQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1686900403; x=1689492403; h=content-transfer-encoding:mime-version:user-agent:message-id :in-reply-to:date:errors-to:references:organization:subject:cc:to :from:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=0pIfBootcGRBUNsx000mJ2M1pwuC5O5Su+1k0IwTkSM=; b=QQTZ8Oyr09GGTUafM78mANuDznHEunN0kPaYA6fwkig4F6t7ieid7YJzAEbxG5Jja/ H7XLMuNzvUaScB9EzO5K6fXhZjtSE/giRTPBJE2AcmjPm0N3ph1mFV68kgIn/H4ZluTC NGuDWDrP5z+jVbmL67FIUrod7AStuqKzt8PiVQxXd4t/ZqGjiCSAxyjEUX3jTqMtIwYY ZZ5JfXrBrQVSTvoW67ls0awUw7CXOM/du0snq3i22VbHIL6JV3qZZSUdYUKnYRVJfww5 p9FCBiHpthFEWjHOmXaiHCYvErk47x9Z8YQD+JgqwZVZ/51tZIUg/PoR/Y8Zi2yx6lD0 xL0g== X-Gm-Message-State: AC+VfDys/C80/rdDxqr/PcQQRJG3r6Zdzi9ozPR3PHQCQejpNWBUxDgH kE4BQssNrf/cGPCnUFYKPaBbIQ== X-Google-Smtp-Source: ACHHUZ44G4sErOrdXC//bO1NRj9Gr4bkvRFUt63h9z6umxFcr5Oxrev/PaSn8NoR10k/NhH/zgZ8cw== X-Received: by 2002:a05:6870:a2c5:b0:1a9:953e:f22c with SMTP id w5-20020a056870a2c500b001a9953ef22cmr698705oak.4.1686900402831; Fri, 16 Jun 2023 00:26:42 -0700 (PDT) Received: from free.home ([2804:7f1:2080:2b05:3128:ead8:cd43:416f]) by smtp.gmail.com with ESMTPSA id eq3-20020a056870a90300b001962e45f0d4sm11223632oab.24.2023.06.16.00.26.41 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 16 Jun 2023 00:26:42 -0700 (PDT) Received: from livre (livre.home [172.31.160.2]) by free.home (8.15.2/8.15.2) with ESMTPS id 35G7QUY7479699 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NOT); Fri, 16 Jun 2023 04:26:32 -0300 From: Alexandre Oliva To: Qing Zhao Cc: "gcc-patches@gcc.gnu.org" Subject: Re: [PATCH zero-call-used-regs] Add leafy mode for zero-call-used-regs Organization: Free thinker, does not speak for AdaCore References: <66ECAC37-E763-4469-B31A-7A2B031026F4@oracle.com> <0DA25420-AE6D-418B-B2F6-7A99BCC34345@oracle.com> <3CF608E7-C293-4627-8FE9-8B580D69D764@oracle.com> Errors-To: aoliva@lxoliva.fsfla.org Date: Fri, 16 Jun 2023 04:26:30 -0300 In-Reply-To: <3CF608E7-C293-4627-8FE9-8B580D69D764@oracle.com> (Qing Zhao's message of "Thu, 27 Oct 2022 13:30:10 +0000") Message-ID: User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.1 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 2.84 X-Spam-Status: No, score=-12.4 required=5.0 tests=BAYES_00,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,GIT_PATCH_0,KAM_SHORT,RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS,TXREP,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: Hello, Qing, On Oct 27, 2022, Qing Zhao wrote: > On Oct 26, 2022, at 5:29 PM, Alexandre Oliva wrote: >> I'm sure there are other scenarios in which keeping at least the >> possibility of 'all' is useful. > Okay. > i.e, instead introducing a new MODE =E2=80=9CLEAFY_MODE=E2=80=9D and a ne= w user > sub-option, for LEAF functions, only > Clear its=E2=80=99 used registers even for =E2=80=9CALL=E2=80=9D. > However, since there is need to clear the un-used registers for leaf > functions. It looks like it is needed to provide > This new sub-option to users. > Is this clear this time? Yeah, I guess I understand what you mean. But since there are cases in which clearing all (call-clobbered) registers in a leaf function is useful, I suppose it makes sense to offer both possibilities. If there was a default operation mode for -fzero-call-used-regs, I guess it would make sense to consider leafy the default, rather than all, but since there isn't, and it always has to be specified explicitly, that's not something to be considered. So the available choices are: 1. introduce 'leafy' as a separate mode, leaving 'all' alone 2. change the behavior of 'all' to that of the proposed 'leafy', and either 2.a) add another mode that retains the currently-useful behavior of 'all', or 2.b) make the current behavior of 'all' no longer available Personally, I find 1. the least disruptive to existing users of -fzero-call-used-regs. If we were introducing the option now, maybe 2.a would be more sensible, but at this point, changing the meaning of 'all' seems to be a disservice to security-sensitive users. Those who would prefer the leaner operation on leaf functions can then switch to 'leafy' mode, but that's better than finding carefully-crafted code relying on the current behavior of 'all' for security suddenly changes from under them, isn't it? That said, I'm willing to implement the alternate change, if changing the expected behavior is preferred over offering a different choice, if needed to get closure on this feature. For now, I'm just pinging the refreshed and retested patch. Ok to install? Add leafy mode for zero-call-used-regs Introduce 'leafy' to auto-select between 'used' and 'all' for leaf and nonleaf functions, respectively. for gcc/ChangeLog * doc/extend.texi (zero-call-used-regs): Document leafy and variants thereof. * flag-types.h (zero_regs_flags): Add LEAFY_MODE, as well as LEAFY and variants. * function.cc (gen_call_ued_regs_seq): Set only_used for leaf functions in leafy mode. * opts.cc (zero_call_used_regs_opts): Add leafy and variants. for gcc/testsuite/ChangeLog * c-c++-common/zero-scratch-regs-leafy-1.c: New. * c-c++-common/zero-scratch-regs-leafy-2.c: New. * gcc.target/i386/zero-scratch-regs-leafy-1.c: New. * gcc.target/i386/zero-scratch-regs-leafy-2.c: New. --- gcc/doc/extend.texi | 22 ++++++++++++++++= ++-- gcc/flag-types.h | 5 +++++ gcc/function.cc | 3 +++ gcc/opts.cc | 4 ++++ .../c-c++-common/zero-scratch-regs-leafy-1.c | 15 ++++++++++++++ .../c-c++-common/zero-scratch-regs-leafy-2.c | 21 ++++++++++++++++= +++ .../gcc.target/i386/zero-scratch-regs-leafy-1.c | 12 +++++++++++ .../gcc.target/i386/zero-scratch-regs-leafy-2.c | 16 +++++++++++++++ 8 files changed, 96 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/c-c++-common/zero-scratch-regs-leafy-1.c create mode 100644 gcc/testsuite/c-c++-common/zero-scratch-regs-leafy-2.c create mode 100644 gcc/testsuite/gcc.target/i386/zero-scratch-regs-leafy-1= .c create mode 100644 gcc/testsuite/gcc.target/i386/zero-scratch-regs-leafy-2= .c diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index 7b5592502734e..f8b0bb53ef5d4 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -4412,10 +4412,28 @@ zeros all call-used registers that pass arguments. @item all-gpr-arg zeros all call-used general purpose registers that pass arguments. + +@item leafy +Same as @samp{used} in a leaf function, and same as @samp{all} in a +nonleaf function. + +@item leafy-gpr +Same as @samp{used-gpr} in a leaf function, and same as @samp{all-gpr} +in a nonleaf function. + +@item leafy-arg +Same as @samp{used-arg} in a leaf function, and same as @samp{all-arg} +in a nonleaf function. + +@item leafy-gpr-arg +Same as @samp{used-gpr-arg} in a leaf function, and same as +@samp{all-gpr-arg} in a nonleaf function. + @end table =20 -Of this list, @samp{used-arg}, @samp{used-gpr-arg}, @samp{all-arg}, -and @samp{all-gpr-arg} are mainly used for ROP mitigation. +Of this list, @samp{used-arg}, @samp{used-gpr-arg}, @samp{leafy-arg}, +@samp{leafy-gpr-arg}, @samp{all-arg}, and @samp{all-gpr-arg} are mainly +used for ROP mitigation. =20 The default for the attribute is controlled by @option{-fzero-call-used-re= gs}. @end table diff --git a/gcc/flag-types.h b/gcc/flag-types.h index f83d165fbfef1..6a2e1beb997ef 100644 --- a/gcc/flag-types.h +++ b/gcc/flag-types.h @@ -348,6 +348,7 @@ namespace zero_regs_flags { const unsigned int ONLY_GPR =3D 1UL << 2; const unsigned int ONLY_ARG =3D 1UL << 3; const unsigned int ENABLED =3D 1UL << 4; + const unsigned int LEAFY_MODE =3D 1UL << 5; const unsigned int USED_GPR_ARG =3D ENABLED | ONLY_USED | ONLY_GPR | ONL= Y_ARG; const unsigned int USED_GPR =3D ENABLED | ONLY_USED | ONLY_GPR; const unsigned int USED_ARG =3D ENABLED | ONLY_USED | ONLY_ARG; @@ -356,6 +357,10 @@ namespace zero_regs_flags { const unsigned int ALL_GPR =3D ENABLED | ONLY_GPR; const unsigned int ALL_ARG =3D ENABLED | ONLY_ARG; const unsigned int ALL =3D ENABLED; + const unsigned int LEAFY_GPR_ARG =3D ENABLED | LEAFY_MODE | ONLY_GPR | O= NLY_ARG; + const unsigned int LEAFY_GPR =3D ENABLED | LEAFY_MODE | ONLY_GPR; + const unsigned int LEAFY_ARG =3D ENABLED | LEAFY_MODE | ONLY_ARG; + const unsigned int LEAFY =3D ENABLED | LEAFY_MODE; } =20 /* Settings of flag_incremental_link. */ diff --git a/gcc/function.cc b/gcc/function.cc index 82102ed78d7e6..7b03f9e744199 100644 --- a/gcc/function.cc +++ b/gcc/function.cc @@ -5868,6 +5868,9 @@ gen_call_used_regs_seq (rtx_insn *ret, unsigned int z= ero_regs_type) only_used =3D zero_regs_type & ONLY_USED; only_arg =3D zero_regs_type & ONLY_ARG; =20 + if ((zero_regs_type & LEAFY_MODE) && leaf_function_p ()) + only_used =3D true; + /* For each of the hard registers, we should zero it if: 1. it is a call-used register; and 2. it is not a fixed register; diff --git a/gcc/opts.cc b/gcc/opts.cc index 86b94d62b588c..93c78be8b0d9a 100644 --- a/gcc/opts.cc +++ b/gcc/opts.cc @@ -2114,6 +2114,10 @@ const struct zero_call_used_regs_opts_s zero_call_us= ed_regs_opts[] =3D ZERO_CALL_USED_REGS_OPT (all-gpr, zero_regs_flags::ALL_GPR), ZERO_CALL_USED_REGS_OPT (all-arg, zero_regs_flags::ALL_ARG), ZERO_CALL_USED_REGS_OPT (all, zero_regs_flags::ALL), + ZERO_CALL_USED_REGS_OPT (leafy-gpr-arg, zero_regs_flags::LEAFY_GPR_ARG), + ZERO_CALL_USED_REGS_OPT (leafy-gpr, zero_regs_flags::LEAFY_GPR), + ZERO_CALL_USED_REGS_OPT (leafy-arg, zero_regs_flags::LEAFY_ARG), + ZERO_CALL_USED_REGS_OPT (leafy, zero_regs_flags::LEAFY), #undef ZERO_CALL_USED_REGS_OPT {NULL, 0U} }; diff --git a/gcc/testsuite/c-c++-common/zero-scratch-regs-leafy-1.c b/gcc/t= estsuite/c-c++-common/zero-scratch-regs-leafy-1.c new file mode 100644 index 0000000000000..c1a0c31ba1c37 --- /dev/null +++ b/gcc/testsuite/c-c++-common/zero-scratch-regs-leafy-1.c @@ -0,0 +1,15 @@ +/* { dg-do run } */ +/* { dg-options "-O2 -fzero-call-used-regs=3Dleafy" } */ + +volatile int result =3D 0; +int=20 +__attribute__((noipa)) +foo (int x) +{ + return x; +} +int main() +{ + result =3D foo (2); + return 0; +} diff --git a/gcc/testsuite/c-c++-common/zero-scratch-regs-leafy-2.c b/gcc/t= estsuite/c-c++-common/zero-scratch-regs-leafy-2.c new file mode 100644 index 0000000000000..d450620c1fcfe --- /dev/null +++ b/gcc/testsuite/c-c++-common/zero-scratch-regs-leafy-2.c @@ -0,0 +1,21 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +#include +int result =3D 0; + +int=20 +__attribute__((noipa)) +__attribute__ ((zero_call_used_regs("leafy"))) +foo1 (int x) +{ + return (x + 1); +} + +int=20 +__attribute__((noipa)) +__attribute__ ((zero_call_used_regs("leafy"))) +foo2 (int x) +{ + return foo1 (x + 2); +} diff --git a/gcc/testsuite/gcc.target/i386/zero-scratch-regs-leafy-1.c b/gc= c/testsuite/gcc.target/i386/zero-scratch-regs-leafy-1.c new file mode 100644 index 0000000000000..2277710c771b7 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/zero-scratch-regs-leafy-1.c @@ -0,0 +1,12 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fzero-call-used-regs=3Dleafy -fno-stack-protector -f= no-PIC" } */ + +void +foo (void) +{ +} + +/* { dg-final { scan-assembler-not "vzeroall" } } */ +/* { dg-final { scan-assembler-not "%xmm" } } */ +/* { dg-final { scan-assembler-not "xorl\[ \t\]+%" } } */ +/* { dg-final { scan-assembler-not "movl\[ \t\]+%" } } */ diff --git a/gcc/testsuite/gcc.target/i386/zero-scratch-regs-leafy-2.c b/gc= c/testsuite/gcc.target/i386/zero-scratch-regs-leafy-2.c new file mode 100644 index 0000000000000..24b85c3dbb766 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/zero-scratch-regs-leafy-2.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fzero-call-used-regs=3Dleafy-gpr -fno-stack-protecto= r -fno-PIC" } */ + +extern int bar (int); + +void +foo (void) +{ + int x =3D bar (0); + if (x) + bar (1); +} + +/* { dg-final { scan-assembler "xorl\[ \t\]+%eax, %eax" } } */ +/* { dg-final { scan-assembler "xorl\[ \t\]+%edx, %edx" } } */ +/* { dg-final { scan-assembler "xorl\[ \t\]+%ecx, %ecx" } } */ --=20 Alexandre Oliva, happy hacker https://FSFLA.org/blogs/lxo/ Free Software Activist GNU Toolchain Engineer Disinformation flourishes because many people care deeply about injustice but very few check the facts. Ask me about