From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-lf1-x12b.google.com (mail-lf1-x12b.google.com [IPv6:2a00:1450:4864:20::12b]) by sourceware.org (Postfix) with ESMTPS id 30D063858D37 for ; Tue, 24 Oct 2023 07:22:40 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 30D063858D37 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=gmail.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 30D063858D37 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=2a00:1450:4864:20::12b ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1698132165; cv=none; b=xfKgnrygWGGpnF0IQk0f+t8ulPzn5qSB8HptnjwJb1kK5LUd8GeTj82Hw86TflAoduBAgXlRkRuFu+XStouGopPxwKD6X3QiDb6O2dw5ku7k88GUIkeU/wfSzOagfVR++oI1JzPpomCedJORanDen9GJzosEhdNxJJp6TUgHY/I= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1698132165; c=relaxed/simple; bh=wVCIEXsUIFOoZZNUQCXsXNYl4zsfSxAL9iqi/hUol/o=; h=DKIM-Signature:MIME-Version:From:Date:Message-ID:Subject:To; b=DwLqr57WhHeVh1PjdLTneJ0Qh9G2YO04czCLxOeXxSkiiCEorIWDTtmtdNdUg94UH5ojwaa0EfU9HsiEN6OVsRYm6SbGucYQi+BYzKW6HYQySnPmKrlWcBlb5bz7A3xFjMGGGK80KOr0yN64YNg07FJCxofRsPR8H9/JfEP4Jik= ARC-Authentication-Results: i=1; server2.sourceware.org Received: by mail-lf1-x12b.google.com with SMTP id 2adb3069b0e04-507ac66a969so5589021e87.3 for ; Tue, 24 Oct 2023 00:22:40 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1698132159; x=1698736959; darn=gcc.gnu.org; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:from:to:cc:subject:date :message-id:reply-to; bh=7R/eWDDeSrShuwKPI69CcrhxXfhIuNN0yn6tptVdSSw=; b=LSzG695atM//5eXAaXv7HgQQsxfGazyfvmT6D9jF9f3K7EJ4Nn6txphfuYYH8KMpqj P51DC9+Kxt/J8FcvZAorKUSCdhDGkQ8TmyDqBKNUq+OxYKJJcYnPh11Jlcytk/zXomXL Ol7ORtqJ9nqGJT3KY58WAQ94AHMrQIjJAe9VDaxBsqy+f7EYzVrOUI2jkMHcsNBoyX0H jRFbu5ovfHMYT4eAbdjTDAwwN63+g4i4pSpeHU1nKhp1J6HwpWgaoKgUnNclfcfGXA+3 7NXh+YhdVJvfOn7Lf099jTgF806V+0u22KneOc/88Hl2QTHHGiKuWKZngaSA/FiFrbiQ BUug== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1698132159; x=1698736959; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=7R/eWDDeSrShuwKPI69CcrhxXfhIuNN0yn6tptVdSSw=; b=Zj8k3UXEoZ06ux4eIcjArC6T12wdndhFrcff4QQnl7JU6zv47gyRaTPL7oZeQ+89Ei WBihtlm5X3wbr5/220VjoJ5i0kQKq2hVBX4HoCDEK3yfVvuso8tMY/uybqmDgItW+b+l WOs7ZHuSPKb2dOIBfYafNwrwdOkLR0VRaoVuRkvdxqESEFQxx7/kuKvvl3vTW+GzFbLG Vq/PJEJ+YmgAm95VDVaqkhemRC60qzqKBAnRCpf2GUv1O4lm3Dtyn1TlFP4cFgyG6EuM rW0QDI8wKA0Xero1E/gJUI/gbvkOvDa0FxyEP6Shog1YFlolYATY5qgS4wKqu47qCDaI j+rw== X-Gm-Message-State: AOJu0YyYiF+t2dfzdkLlktWYXD5gXAT+FSdBoqiQ2pTuvoXgPMNEhJr8 0kV5FNjD9OLxQhScJCOK0NAaAtlhXTtLVgNrDlA= X-Google-Smtp-Source: AGHT+IFLV/P8WfKrgqWR9cp6kUeoyscn3Sr5Ze2KP0wyuByEPUMF7pcUeJC0gRsb6vq9JllElm4NQXbycbTLPh+fedI= X-Received: by 2002:a05:6512:34c7:b0:500:ac71:8464 with SMTP id w7-20020a05651234c700b00500ac718464mr6311729lfr.66.1698132157965; Tue, 24 Oct 2023 00:22:37 -0700 (PDT) MIME-Version: 1.0 References: <20230915150816.18190-1-polacek@redhat.com> In-Reply-To: From: Richard Biener Date: Tue, 24 Oct 2023 09:22:25 +0200 Message-ID: Subject: Re: [PATCH v3] gcc: Introduce -fhardened To: Marek Polacek Cc: iain@sandoe.co.uk, GCC Patches Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable X-Spam-Status: No, score=-7.4 required=5.0 tests=BAYES_00,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM,GIT_PATCH_0,KAM_SHORT,RCVD_IN_DNSWL_NONE,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 List-Id: On Mon, Oct 23, 2023 at 9:26=E2=80=AFPM Marek Polacek = wrote: > > On Thu, Oct 19, 2023 at 02:24:11PM +0200, Richard Biener wrote: > > On Wed, Oct 11, 2023 at 10:48=E2=80=AFPM Marek Polacek wrote: > > > > > > On Tue, Sep 19, 2023 at 10:58:19AM -0400, Marek Polacek wrote: > > > > On Mon, Sep 18, 2023 at 08:57:39AM +0200, Richard Biener wrote: > > > > > On Fri, Sep 15, 2023 at 5:09=E2=80=AFPM Marek Polacek via Gcc-pat= ches > > > > > wrote: > > > > > > > > > > > > Bootstrapped/regtested on x86_64-pc-linux-gnu, powerpc64le-unkn= own-linux-gnu, > > > > > > and aarch64-unknown-linux-gnu; ok for trunk? > > > > > > > > > > > > -- >8 -- > > > > > > In > > > > > > I proposed -fhardened, a new umbrella option that enables a rea= sonable set > > > > > > of hardening flags. The read of the room seems to be that the = option > > > > > > would be useful. So here's a patch implementing that option. > > > > > > > > > > > > Currently, -fhardened enables: > > > > > > > > > > > > -D_FORTIFY_SOURCE=3D3 (or =3D2 for older glibcs) > > > > > > -D_GLIBCXX_ASSERTIONS > > > > > > -ftrivial-auto-var-init=3Dpattern > > > > I think =3Dzero is much better here given the overhead is way > > cheaper and pointers get a more reliable behavior. > > Ok, changed now. > > > > > > > -fPIE -pie -Wl,-z,relro,-z,now > > > > > > -fstack-protector-strong > > > > > > -fstack-clash-protection > > > > > > -fcf-protection=3Dfull (x86 GNU/Linux only) > > > > > > > > > > > > -fhardened will not override options that were specified on the= command line > > > > > > (before or after -fhardened). For example, > > > > > > > > > > > > -D_FORTIFY_SOURCE=3D1 -fhardened > > > > > > > > > > > > means that _FORTIFY_SOURCE=3D1 will be used. Similarly, > > > > > > > > > > > > -fhardened -fstack-protector > > > > > > > > > > > > will not enable -fstack-protector-strong. > > > > > > > > > > > > In DW_AT_producer it is reflected only as -fhardened; it doesn'= t expand > > > > > > to anything. I think we need a better way to show what it actu= ally > > > > > > enables. > > > > > > > > > > I do think we need to find a solution here to solve asserting com= pliance. > > > > > > > > Fair enough. > > > > > > > > > Maybe we can have -Whardened that will diagnose any altering of > > > > > -fhardened by other options on the command-line or by missed targ= et > > > > > implementations? People might for example use -fstack-protector > > > > > but don't really want to make protection lower than requested wit= h -fhardened. > > > > > > > > > > Any such conflict is much less appearant than when you use the > > > > > flags -fhardened composes. > > > > > > > > How about: --help=3Dhardened says which options -fhardened attempts= to > > > > enable, and -Whardened warns when it didn't enable an option? E.g.= , > > > > > > > > -fstack-protector -fhardened -Whardened > > > > > > > > would say that it didn't enable -fstack-protector-strong because > > > > -fstack-protector was specified on the command line? > > > > > > > > If !HAVE_LD_NOW_SUPPORT, --help=3Dhardened probably doesn't even ha= ve to > > > > list -z now, likewise for -z relro. > > > > > > > > Unclear if -Whardened should be enabled by default, but probably ye= s? > > > > > > Here's v2 which adds -Whardened (enabled by default). > > > > > > Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk? > > > > I think it's OK but I'd like to see a second ACK here. > > Thanks! > > > Can you see how our > > primary and secondary targets (+ host OS) behave here? > > That's very reasonable. I tried to build gcc on Compile Farm 119 (AIX) b= ut > that fails with: > > ar -X64 x ../ppc64/libgcc/libgcc_s.a shr.o > ar: 0707-100 ../ppc64/libgcc/libgcc_s.a does not exist. > make[2]: *** [/home/polacek/gcc/libgcc/config/rs6000/t-slibgcc-aix:98: al= l] Error 1 > make[2]: Leaving directory '/home/polacek/x/trunk/powerpc-ibm-aix7.3.1.0/= libgcc' > > and I tried Darwin (104) and that fails with > > *** Configuration aarch64-apple-darwin21.6.0 not supported > > Is anyone else able to build gcc on those machines, or test the attached > patch? > > > I think the > > documentation should elaborate a bit on expectations for non-Linux/GNU > > targets, specifically I think the default configuration for a target sh= ould > > with -fhardened _not_ have any -Whardened diagnostics. Maybe we can > > have a testcase for this? > > Sorry, I'm not sure how to test that. I suppose if -fhardened enables > something not supported on those systems, and it's something for which > we have a configure test, then we shouldn't warn. This is already the > case for -pie, -z relro, and -z now. I was thinking of /* { dg-do compile } */ /* { dg-additional-options "-fhardened -Whardened" } */ int main () {} and excess errors should catch "misconfigurations"? > Should the docs say something like the following for features without > configure checks? > > @option{-fhardened} can, on certain systems, attempt to enable features > not supported on that particular system. In that case, it's possible to > prevent the warning using the @option{-Wno-hardened} option. Yeah, but ideally @option{-fhardened} can, on certain systems, not enable features not available on those systems and @option{-Whardened} will not diagnose those as missing. But I understand it doesn't work like that? > I've added a line saying: > > +This option is intended to be used in production builds, not merely > +in debug builds. > > -- >8 -- > In > I proposed -fhardened, a new umbrella option that enables a reasonable se= t > of hardening flags. The read of the room seems to be that the option > would be useful. So here's a patch implementing that option. > > Currently, -fhardened enables: > > -D_FORTIFY_SOURCE=3D3 (or =3D2 for older glibcs) > -D_GLIBCXX_ASSERTIONS > -ftrivial-auto-var-init=3Dzero > -fPIE -pie -Wl,-z,relro,-z,now > -fstack-protector-strong > -fstack-clash-protection > -fcf-protection=3Dfull (x86 GNU/Linux only) > > -fhardened will not override options that were specified on the command l= ine > (before or after -fhardened). For example, > > -D_FORTIFY_SOURCE=3D1 -fhardened > > means that _FORTIFY_SOURCE=3D1 will be used. Similarly, > > -fhardened -fstack-protector > > will not enable -fstack-protector-strong. > > In DW_AT_producer it is reflected only as -fhardened; it doesn't expand > to anything. This patch provides -Whardened, enabled by default, which > warns when -fhardened couldn't enable a particular option. I think most > often it will say that _FORTIFY_SOURCE wasn't enabled because optimizatio= n > were not enabled. > > gcc/c-family/ChangeLog: > > * c-opts.cc (c_finish_options): Maybe cpp_define _FORTIFY_SOURCE > and _GLIBCXX_ASSERTIONS. > > gcc/ChangeLog: > > * common.opt (Whardened, fhardened): New options. > * config.in: Regenerate. > * config/bpf/bpf.cc: Include "opts.h". > (bpf_option_override): If flag_stack_protector_set_by_fhardened_p= , do > not inform that -fstack-protector does not work. > * config/i386/i386-options.cc (ix86_option_override_internal): Wh= en > -fhardened, maybe enable -fcf-protection=3Dfull. > * configure: Regenerate. > * configure.ac: Check if the linker supports '-z now' and '-z rel= ro'. > * doc/invoke.texi: Document -fhardened and -Whardened. > * gcc.cc (driver_handle_option): Remember if any link options or = -static > were specified on the command line. > (process_command): When -fhardened, maybe enable -pie and > -Wl,-z,relro,-z,now. > * opts.cc (flag_stack_protector_set_by_fhardened_p): New global. > (finish_options): When -fhardened, enable > -ftrivial-auto-var-init=3Dzero and -fstack-protector-strong. > (print_help_hardened): New. > (print_help): Call it. > * toplev.cc (process_options): When -fhardened, enable > -fstack-clash-protection. If flag_stack_protector_set_by_fharden= ed_p, > do not warn that -fstack-protector not supported for this target. > > gcc/testsuite/ChangeLog: > > * gcc.misc-tests/help.exp: Test -fhardened. > * c-c++-common/fhardened-1.S: New test. > * c-c++-common/fhardened-1.c: New test. > * c-c++-common/fhardened-10.c: New test. > * c-c++-common/fhardened-11.c: New test. > * c-c++-common/fhardened-12.c: New test. > * c-c++-common/fhardened-13.c: New test. > * c-c++-common/fhardened-14.c: New test. > * c-c++-common/fhardened-15.c: New test. > * c-c++-common/fhardened-2.c: New test. > * c-c++-common/fhardened-3.c: New test. > * c-c++-common/fhardened-4.c: New test. > * c-c++-common/fhardened-5.c: New test. > * c-c++-common/fhardened-6.c: New test. > * c-c++-common/fhardened-7.c: New test. > * c-c++-common/fhardened-8.c: New test. > * c-c++-common/fhardened-9.c: New test. > * gcc.target/i386/cf_check-6.c: New test. > --- > gcc/c-family/c-opts.cc | 42 ++++++++++++++ > gcc/common.opt | 8 +++ > gcc/config.in | 12 ++++ > gcc/config/bpf/bpf.cc | 8 ++- > gcc/config/i386/i386-options.cc | 17 +++++- > gcc/configure | 50 +++++++++++++++- > gcc/configure.ac | 42 +++++++++++++- > gcc/doc/invoke.texi | 47 ++++++++++++++- > gcc/gcc.cc | 48 +++++++++++++++- > gcc/opts.cc | 67 +++++++++++++++++++++- > gcc/opts.h | 1 + > gcc/testsuite/c-c++-common/fhardened-1.S | 6 ++ > gcc/testsuite/c-c++-common/fhardened-1.c | 14 +++++ > gcc/testsuite/c-c++-common/fhardened-10.c | 12 ++++ > gcc/testsuite/c-c++-common/fhardened-11.c | 10 ++++ > gcc/testsuite/c-c++-common/fhardened-12.c | 11 ++++ > gcc/testsuite/c-c++-common/fhardened-13.c | 6 ++ > gcc/testsuite/c-c++-common/fhardened-14.c | 6 ++ > gcc/testsuite/c-c++-common/fhardened-15.c | 5 ++ > gcc/testsuite/c-c++-common/fhardened-2.c | 12 ++++ > gcc/testsuite/c-c++-common/fhardened-3.c | 14 +++++ > gcc/testsuite/c-c++-common/fhardened-4.c | 4 ++ > gcc/testsuite/c-c++-common/fhardened-5.c | 11 ++++ > gcc/testsuite/c-c++-common/fhardened-6.c | 12 ++++ > gcc/testsuite/c-c++-common/fhardened-7.c | 7 +++ > gcc/testsuite/c-c++-common/fhardened-8.c | 7 +++ > gcc/testsuite/c-c++-common/fhardened-9.c | 9 +++ > gcc/testsuite/gcc.misc-tests/help.exp | 2 + > gcc/testsuite/gcc.target/i386/cf_check-6.c | 12 ++++ > gcc/toplev.cc | 18 +++++- > 30 files changed, 506 insertions(+), 14 deletions(-) > create mode 100644 gcc/testsuite/c-c++-common/fhardened-1.S > create mode 100644 gcc/testsuite/c-c++-common/fhardened-1.c > create mode 100644 gcc/testsuite/c-c++-common/fhardened-10.c > create mode 100644 gcc/testsuite/c-c++-common/fhardened-11.c > create mode 100644 gcc/testsuite/c-c++-common/fhardened-12.c > create mode 100644 gcc/testsuite/c-c++-common/fhardened-13.c > create mode 100644 gcc/testsuite/c-c++-common/fhardened-14.c > create mode 100644 gcc/testsuite/c-c++-common/fhardened-15.c > create mode 100644 gcc/testsuite/c-c++-common/fhardened-2.c > create mode 100644 gcc/testsuite/c-c++-common/fhardened-3.c > create mode 100644 gcc/testsuite/c-c++-common/fhardened-4.c > create mode 100644 gcc/testsuite/c-c++-common/fhardened-5.c > create mode 100644 gcc/testsuite/c-c++-common/fhardened-6.c > create mode 100644 gcc/testsuite/c-c++-common/fhardened-7.c > create mode 100644 gcc/testsuite/c-c++-common/fhardened-8.c > create mode 100644 gcc/testsuite/c-c++-common/fhardened-9.c > create mode 100644 gcc/testsuite/gcc.target/i386/cf_check-6.c > > diff --git a/gcc/c-family/c-opts.cc b/gcc/c-family/c-opts.cc > index ce2e021e69d..f5f6ba24290 100644 > --- a/gcc/c-family/c-opts.cc > +++ b/gcc/c-family/c-opts.cc > @@ -1556,6 +1556,9 @@ c_finish_options (void) > cb_file_change (parse_in, cmd_map); > linemap_line_start (line_table, 0, 1); > > + bool fortify_seen_p =3D false; > + bool cxx_assert_seen_p =3D false; > + > /* All command line defines must have the same location. */ > cpp_force_token_locations (parse_in, line_table->highest_line); > for (size_t i =3D 0; i < deferred_count; i++) > @@ -1573,6 +1576,45 @@ c_finish_options (void) > else > cpp_assert (parse_in, opt->arg); > } > + > + if (UNLIKELY (flag_hardened) > + && (opt->code =3D=3D OPT_D || opt->code =3D=3D OPT_U)) > + { > + if (!fortify_seen_p) > + fortify_seen_p > + =3D (!strncmp (opt->arg, "_FORTIFY_SOURCE", 15) > + && (opt->arg[15] =3D=3D '\0' || opt->arg[15] =3D=3D = '=3D')); > + if (!cxx_assert_seen_p) > + cxx_assert_seen_p > + =3D (!strncmp (opt->arg, "_GLIBCXX_ASSERTIONS", 19) > + && (opt->arg[19] =3D=3D '\0' || opt->arg[19] =3D=3D = '=3D')); > + } > + } > + > + if (flag_hardened) > + { > + if (!fortify_seen_p && optimize > 0) > + { > + if (TARGET_GLIBC_MAJOR =3D=3D 2 && TARGET_GLIBC_MINOR >=3D = 35) > + cpp_define (parse_in, "_FORTIFY_SOURCE=3D3"); > + else > + cpp_define (parse_in, "_FORTIFY_SOURCE=3D2"); > + } > + else if (optimize =3D=3D 0) > + warning_at (UNKNOWN_LOCATION, OPT_Whardened, > + "%<_FORTIFY_SOURCE%> is not enabled by %<-fharden= ed%> " > + "because optimizations are turned off"); > + else > + warning_at (UNKNOWN_LOCATION, OPT_Whardened, > + "%<_FORTIFY_SOURCE%> is not enabled by %<-fharden= ed%> " > + "because it was specified in %<-D%> or %<-U%>"); > + if (!cxx_assert_seen_p) > + cpp_define (parse_in, "_GLIBCXX_ASSERTIONS"); > + else > + warning_at (UNKNOWN_LOCATION, OPT_Whardened, > + "%<_GLIBCXX_ASSERTIONS%> is not enabled by " > + "%<-fhardened%> because it was specified in %<-D%= > " > + "or %<-U%>"); > } > > cpp_stop_forcing_token_locations (parse_in); > diff --git a/gcc/common.opt b/gcc/common.opt > index 1cf3bdd3b51..48a15f077ef 100644 > --- a/gcc/common.opt > +++ b/gcc/common.opt > @@ -634,6 +634,10 @@ Wfree-nonheap-object > Common Var(warn_free_nonheap_object) Init(1) Warning > Warn when attempting to free a non-heap object. > > +Whardened > +Common Var(warn_hardened) Init(1) Warning > +Warn when -fhardened did not enable an option from its set. > + > Whsa > Common Ignore Warning > Does nothing. Preserved for backward compatibility. > @@ -1823,6 +1827,10 @@ fguess-branch-probability > Common Var(flag_guess_branch_prob) Optimization > Enable guessing of branch probabilities. > > +fhardened > +Common Driver Var(flag_hardened) > +Enable various security-relevant flags. > + > fharden-compares > Common Var(flag_harden_compares) Optimization > Harden conditionals not used in branches, checking reversed conditions. > diff --git a/gcc/config.in b/gcc/config.in > index 03faee1c6ac..327b1e3e2ee 100644 > --- a/gcc/config.in > +++ b/gcc/config.in > @@ -1695,6 +1695,12 @@ > #endif > > > +/* Define 0/1 if your linker supports -z now */ > +#ifndef USED_FOR_TARGET > +#undef HAVE_LD_NOW_SUPPORT > +#endif > + > + > /* Define if your PowerPC64 linker only needs function descriptor syms. = */ > #ifndef USED_FOR_TARGET > #undef HAVE_LD_NO_DOT_SYMS > @@ -1738,6 +1744,12 @@ > #endif > > > +/* Define 0/1 if your linker supports -z relro */ > +#ifndef USED_FOR_TARGET > +#undef HAVE_LD_RELRO_SUPPORT > +#endif > + > + > /* Define if your linker links a mix of read-only and read-write section= s into > a read-write section. */ > #ifndef USED_FOR_TARGET > diff --git a/gcc/config/bpf/bpf.cc b/gcc/config/bpf/bpf.cc > index 437bd652de3..41dc7fd3dae 100644 > --- a/gcc/config/bpf/bpf.cc > +++ b/gcc/config/bpf/bpf.cc > @@ -70,6 +70,7 @@ along with GCC; see the file COPYING3. If not see > #include "gimplify-me.h" > > #include "core-builtins.h" > +#include "opts.h" > > /* Per-function machine data. */ > struct GTY(()) machine_function > @@ -250,9 +251,10 @@ bpf_option_override (void) > /* Disable -fstack-protector as it is not supported in BPF. */ > if (flag_stack_protect) > { > - inform (input_location, > - "%<-fstack-protector%> does not work " > - "on this architecture"); > + if (!flag_stack_protector_set_by_fhardened_p) > + inform (input_location, > + "%<-fstack-protector%> does not work " > + "on this architecture"); > flag_stack_protect =3D 0; > } > > diff --git a/gcc/config/i386/i386-options.cc b/gcc/config/i386/i386-optio= ns.cc > index 072bbc628e2..8b31ee5b80c 100644 > --- a/gcc/config/i386/i386-options.cc > +++ b/gcc/config/i386/i386-options.cc > @@ -3069,10 +3069,25 @@ ix86_option_override_internal (bool main_args_p, > =3D build_target_option_node (opts, opts_set); > } > > + const bool cf_okay_p =3D (TARGET_64BIT || TARGET_CMOV); > + /* When -fhardened, enable -fcf-protection=3Dfull, but only when it's > + compatible with this target, and when it wasn't already specified > + on the command line. */ > + if (opts->x_flag_hardened && cf_okay_p) > + { > + if (opts->x_flag_cf_protection =3D=3D CF_NONE) > + opts->x_flag_cf_protection =3D CF_FULL; > + else if (opts->x_flag_cf_protection !=3D CF_FULL) > + warning_at (UNKNOWN_LOCATION, OPT_Whardened, > + "%<-fcf-protection=3Dfull%> is not enabled by " > + "%<-fhardened%> because it was specified on the comma= nd " > + "line"); > + } > + > if (opts->x_flag_cf_protection !=3D CF_NONE) > { > if ((opts->x_flag_cf_protection & CF_BRANCH) =3D=3D CF_BRANCH > - && !TARGET_64BIT && !TARGET_CMOV) > + && !cf_okay_p) > error ("%<-fcf-protection%> is not compatible with this target"); > > opts->x_flag_cf_protection > diff --git a/gcc/configure b/gcc/configure > index 77f33ee4df6..00ffc82ced8 100755 > --- a/gcc/configure > +++ b/gcc/configure > @@ -32883,7 +32883,7 @@ if test x"$ld_is_gold" =3D xno; then > ld_bndplt_support=3Dyes > fi > elif test x$gcc_cv_ld !=3D x; then > - # Check if linker supports -a bndplt option > + # Check if linker supports -z bndplt option > if $gcc_cv_ld --help 2>&1 | grep -- '-z bndplt' > /dev/null; then > ld_bndplt_support=3Dyes > fi > @@ -33012,6 +33012,54 @@ $as_echo "#define ENABLE_S390_EXCESS_FLOAT_PRECI= SION 1" >>confdefs.h > ;; > esac > > +# Check if the linker supports '-z now' > +ld_now_support=3Dno > +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking linker -z now option" = >&5 > +$as_echo_n "checking linker -z now option... " >&6; } > +if test x"$ld_is_gold" =3D xyes; then > + ld_now_support=3Dyes > +elif test $in_tree_ld =3D yes ; then > + if test "$gcc_cv_gld_major_version" -eq 2 -a "$gcc_cv_gld_minor_versio= n" -ge 14 -o "$gcc_cv_gld_major_version" -gt 2; then > + ld_now_support=3Dyes > + fi > +elif test x$gcc_cv_ld !=3D x; then > + # Check if linker supports -z now > + if $gcc_cv_ld --help 2>&1 | grep -- '-z now' > /dev/null; then > + ld_now_support=3Dyes > + fi > +fi > + > +cat >>confdefs.h <<_ACEOF > +#define HAVE_LD_NOW_SUPPORT `if test x"$ld_now_support" =3D xyes; then e= cho 1; else echo 0; fi` > +_ACEOF > + > +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_now_support" >&5 > +$as_echo "$ld_now_support" >&6; } > + > +# Check if the linker supports '-z relro' > +ld_relro_support=3Dno > +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking linker -z relro option= " >&5 > +$as_echo_n "checking linker -z relro option... " >&6; } > +if test x"$ld_is_gold" =3D xyes; then > + ld_relro_support=3Dyes > +elif test $in_tree_ld =3D yes ; then > + if test "$gcc_cv_gld_major_version" -eq 2 -a "$gcc_cv_gld_minor_versio= n" -ge 15 -o "$gcc_cv_gld_major_version" -gt 2; then > + ld_relro_support=3Dyes > + fi > +elif test x$gcc_cv_ld !=3D x; then > + # Check if linker supports -z relro > + if $gcc_cv_ld --help 2>&1 | grep -- '-z relro' > /dev/null; then > + ld_relro_support=3Dyes > + fi > +fi > + > +cat >>confdefs.h <<_ACEOF > +#define HAVE_LD_RELRO_SUPPORT `if test x"$ld_relro_support" =3D xyes; th= en echo 1; else echo 0; fi` > +_ACEOF > + > +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_relro_support" >&5 > +$as_echo "$ld_relro_support" >&6; } > + > # Configure the subdirectories > # AC_CONFIG_SUBDIRS($subdirs) > > diff --git a/gcc/configure.ac b/gcc/configure.ac > index 10982cdfc09..fd845308a24 100644 > --- a/gcc/configure.ac > +++ b/gcc/configure.ac > @@ -7701,7 +7701,7 @@ if test x"$ld_is_gold" =3D xno; then > ld_bndplt_support=3Dyes > fi > elif test x$gcc_cv_ld !=3D x; then > - # Check if linker supports -a bndplt option > + # Check if linker supports -z bndplt option > if $gcc_cv_ld --help 2>&1 | grep -- '-z bndplt' > /dev/null; then > ld_bndplt_support=3Dyes > fi > @@ -7802,6 +7802,46 @@ standards-compatible mode on s390 targets.]) > ;; > esac > > +# Check if the linker supports '-z now' > +ld_now_support=3Dno > +AC_MSG_CHECKING(linker -z now option) > +if test x"$ld_is_gold" =3D xyes; then > + ld_now_support=3Dyes > +elif test $in_tree_ld =3D yes ; then > + if test "$gcc_cv_gld_major_version" -eq 2 -a "$gcc_cv_gld_minor_versio= n" -ge 14 -o "$gcc_cv_gld_major_version" -gt 2; then > + ld_now_support=3Dyes > + fi > +elif test x$gcc_cv_ld !=3D x; then > + # Check if linker supports -z now > + if $gcc_cv_ld --help 2>&1 | grep -- '-z now' > /dev/null; then > + ld_now_support=3Dyes > + fi > +fi > +AC_DEFINE_UNQUOTED(HAVE_LD_NOW_SUPPORT, > + [`if test x"$ld_now_support" =3D xyes; then echo 1; else echo 0; fi`], > + [Define 0/1 if your linker supports -z now]) > +AC_MSG_RESULT($ld_now_support) > + > +# Check if the linker supports '-z relro' > +ld_relro_support=3Dno > +AC_MSG_CHECKING(linker -z relro option) > +if test x"$ld_is_gold" =3D xyes; then > + ld_relro_support=3Dyes > +elif test $in_tree_ld =3D yes ; then > + if test "$gcc_cv_gld_major_version" -eq 2 -a "$gcc_cv_gld_minor_versio= n" -ge 15 -o "$gcc_cv_gld_major_version" -gt 2; then > + ld_relro_support=3Dyes > + fi > +elif test x$gcc_cv_ld !=3D x; then > + # Check if linker supports -z relro > + if $gcc_cv_ld --help 2>&1 | grep -- '-z relro' > /dev/null; then > + ld_relro_support=3Dyes > + fi > +fi > +AC_DEFINE_UNQUOTED(HAVE_LD_RELRO_SUPPORT, > + [`if test x"$ld_relro_support" =3D xyes; then echo 1; else echo 0; fi`= ], > + [Define 0/1 if your linker supports -z relro]) > +AC_MSG_RESULT($ld_relro_support) > + > # Configure the subdirectories > # AC_CONFIG_SUBDIRS($subdirs) > > diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi > index 5a9284d635c..e4237c28608 100644 > --- a/gcc/doc/invoke.texi > +++ b/gcc/doc/invoke.texi > @@ -366,7 +366,7 @@ Objective-C and Objective-C++ Dialects}. > -Wformat-y2k -Wframe-address > -Wframe-larger-than=3D@var{byte-size} -Wno-free-nonheap-object > -Wno-if-not-aligned -Wno-ignored-attributes > --Wignored-qualifiers -Wno-incompatible-pointer-types > +-Wignored-qualifiers -Wno-incompatible-pointer-types -Whardened > -Wimplicit -Wimplicit-fallthrough -Wimplicit-fallthrough=3D@var{n} > -Wno-implicit-function-declaration -Wno-implicit-int > -Winfinite-recursion > @@ -641,7 +641,7 @@ Objective-C and Objective-C++ Dialects}. > -fasan-shadow-offset=3D@var{number} -fsanitize-sections=3D@var{s1},@var= {s2},... > -fsanitize-undefined-trap-on-error -fbounds-check > -fcf-protection=3D@r{[}full@r{|}branch@r{|}return@r{|}none@r{|}check@r{]= } > --fharden-compares -fharden-conditional-branches > +-fharden-compares -fharden-conditional-branches -fhardened > -fharden-control-flow-redundancy -fhardcfr-skip-leaf > -fhardcfr-check-exceptions -fhardcfr-check-returning-calls > -fhardcfr-check-noreturn-calls=3D@r{[}always@r{|}no-xthrow@r{|}nothrow@r= {|}never@r{]} > @@ -6860,6 +6860,18 @@ This warning is upgraded to an error by @option{-p= edantic-errors}. > Same as @option{-Wimplicit-int} and @option{-Wimplicit-function-declarat= ion}. > This warning is enabled by @option{-Wall}. > > +@opindex Whardened > +@opindex Wno-hardened > +@item -Whardened > +Warn when @option{-fhardened} did not enable an option from its set (for > +which see @option{-fhardened}). For instance, using @option{-fhardened} > +and @option{-fstack-protector} at the same time on the command line caus= es > +@option{-Whardened} to warn because @option{-fstack-protector-strong} is > +not enabled by @option{-fhardened}. > + > +This warning is enabled by default and has effect only when @option{-fha= rdened} > +is enabled. > + > @opindex Wimplicit-fallthrough > @opindex Wno-implicit-fallthrough > @item -Wimplicit-fallthrough > @@ -17542,6 +17554,37 @@ made @option{no-xthrow} the default setting for = this option: it excludes > from the @code{noreturn} treatment only internal functions used to > (re)raise exceptions, that are not affected by these optimizations. > > +@opindex fhardened > +@item -fhardened > +Enable a set of flags for C and C++ that improve the security of the > +generated code without affecting its ABI. The precise flags enabled > +may change between major releases of GCC, but are currently: > + > +@c Keep this in sync with print_help_hardened! > +@gccoptlist{ > +-D_FORTIFY_SOURCE=3D3 > +-D_GLIBCXX_ASSERTIONS > +-ftrivial-auto-var-init=3Dzero > +-fPIE -pie -Wl,-z,relro,-z,now > +-fstack-protector-strong > +-fstack-clash-protection > +-fcf-protection=3Dfull @r{(x86 GNU/Linux only)} > +} > + > +The list of options enabled by @option{-fhardened} can be generated usin= g > +the @option{--help=3Dhardened} option. > + > +When the system glibc is older than 2.35, @option{-D_FORTIFY_SOURCE=3D2} > +is used instead. > + > +This option is intended to be used in production builds, not merely > +in debug builds. > + > +@option{-fhardened} only enables a particular option if it wasn't > +already specified anywhere on the command line. For instance, > +@option{-fhardened} @option{-fstack-protector} will only enable > +@option{-fstack-protector}, but not @option{-fstack-protector-strong}. > + > @opindex fstack-protector > @item -fstack-protector > Emit extra code to check for buffer overflows, such as stack smashing > diff --git a/gcc/gcc.cc b/gcc/gcc.cc > index 884284e66b4..a7e5774dcfa 100644 > --- a/gcc/gcc.cc > +++ b/gcc/gcc.cc > @@ -302,6 +302,13 @@ static size_t dumpdir_length =3D 0; > driver added to dumpdir after dumpbase or linker output name. */ > static bool dumpdir_trailing_dash_added =3D false; > > +/* True if -r, -shared, -pie, or -no-pie were specified on the command > + line. */ > +static bool any_link_options_p; > + > +/* True if -static was specified on the command line. */ > +static bool static_p; > + > /* Basename of dump and aux outputs, computed from dumpbase (given or > derived from output name), to override input_basename in non-%w %b > et al. */ > @@ -4606,10 +4613,20 @@ driver_handle_option (struct gcc_options *opts, > save_switch ("-o", 1, &arg, validated, true); > return true; > > -#ifdef ENABLE_DEFAULT_PIE > case OPT_pie: > +#ifdef ENABLE_DEFAULT_PIE > /* -pie is turned on by default. */ > + validated =3D true; > #endif > + case OPT_r: > + case OPT_shared: > + case OPT_no_pie: > + any_link_options_p =3D true; > + break; > + > + case OPT_static: > + static_p =3D true; > + break; > > case OPT_static_libgcc: > case OPT_shared_libgcc: > @@ -4985,6 +5002,35 @@ process_command (unsigned int decoded_options_coun= t, > #endif > } > > + /* TODO: check if -static -pie works and maybe use it. */ > + if (flag_hardened) > + { > + if (!any_link_options_p && !static_p) > + { > +#ifdef HAVE_LD_PIE > + save_switch (LD_PIE_SPEC, 0, NULL, /*validated=3D*/true, /*know= n=3D*/false); > +#endif > + /* These are passed straight down to collect2 so we have to bre= ak > + it up like this. */ > + if (HAVE_LD_NOW_SUPPORT) > + { > + add_infile ("-z", "*"); > + add_infile ("now", "*"); > + } > + if (HAVE_LD_RELRO_SUPPORT) > + { > + add_infile ("-z", "*"); > + add_infile ("relro", "*"); > + } > + } > + /* We can't use OPT_Whardened yet. Sigh. */ > + else if (warn_hardened) > + warning_at (UNKNOWN_LOCATION, 0, > + "linker hardening options not enabled by %<-fhardened= %> " > + "because other link options were specified on the com= mand " > + "line"); > + } > + > /* Handle -gtoggle as it would later in toplev.cc:process_options to > make the debug-level-gt spec function work as expected. */ > if (flag_gtoggle) > diff --git a/gcc/opts.cc b/gcc/opts.cc > index 573dcf8e497..c5fc065ce68 100644 > --- a/gcc/opts.cc > +++ b/gcc/opts.cc > @@ -43,6 +43,10 @@ along with GCC; see the file COPYING3. If not see > /* Set by -fcanon-prefix-map. */ > bool flag_canon_prefix_map; > > +/* Set by finish_options when flag_stack_protector was set only because = of > + -fhardened. Yuck. */ > +bool flag_stack_protector_set_by_fhardened_p; > + > static void set_Wstrict_aliasing (struct gcc_options *opts, int onoff); > > /* Names of fundamental debug info formats indexed by enum > @@ -1093,6 +1097,17 @@ finish_options (struct gcc_options *opts, struct g= cc_options *opts_set, > opts->x_flag_section_anchors =3D 0; > } > > + if (opts->x_flag_hardened) > + { > + if (!opts_set->x_flag_auto_var_init) > + opts->x_flag_auto_var_init =3D AUTO_INIT_ZERO; > + else if (opts->x_flag_auto_var_init !=3D AUTO_INIT_ZERO) > + warning_at (loc, OPT_Whardened, > + "%<-ftrivial-auto-var-init=3Dzero%> is not enabled by= " > + "%<-fhardened%> because it was specified on the comma= nd " > + "line"); > + } > + > if (!opts->x_flag_opts_finished) > { > /* We initialize opts->x_flag_pie to -1 so that targets can set a > @@ -1102,7 +1117,8 @@ finish_options (struct gcc_options *opts, struct gc= c_options *opts_set, > /* We initialize opts->x_flag_pic to -1 so that we can tell if > -fpic, -fPIC, -fno-pic or -fno-PIC is used. */ > if (opts->x_flag_pic =3D=3D -1) > - opts->x_flag_pie =3D DEFAULT_FLAG_PIE; > + opts->x_flag_pie =3D (opts->x_flag_hardened > + ? /*-fPIE*/ 2 : DEFAULT_FLAG_PIE); > else > opts->x_flag_pie =3D 0; > } > @@ -1117,9 +1133,29 @@ finish_options (struct gcc_options *opts, struct g= cc_options *opts_set, > } > > /* We initialize opts->x_flag_stack_protect to -1 so that targets > - can set a default value. */ > + can set a default value. With --enable-default-ssp or -fhardened > + the default is -fstack-protector-strong. */ > if (opts->x_flag_stack_protect =3D=3D -1) > - opts->x_flag_stack_protect =3D DEFAULT_FLAG_SSP; > + { > + /* This should check FRAME_GROWS_DOWNWARD, but on some targets it'= s > + defined in such a way that it uses flag_stack_protect which can'= t > + be used here. Moreover, some targets like BPF don't support > + -fstack-protector at all but we don't know that here. So rememb= er > + that flag_stack_protect was set at the behest of -fhardened. */ > + if (opts->x_flag_hardened) > + { > + opts->x_flag_stack_protect =3D SPCT_FLAG_STRONG; > + flag_stack_protector_set_by_fhardened_p =3D true; > + } > + else > + opts->x_flag_stack_protect =3D DEFAULT_FLAG_SSP; > + } > + else if (opts->x_flag_hardened > + && opts->x_flag_stack_protect !=3D SPCT_FLAG_STRONG) > + warning_at (UNKNOWN_LOCATION, OPT_Whardened, > + "%<-fstack-protector-strong%> is not enabled by " > + "%<-fhardened%> because it was specified on the command " > + "line"); > > if (opts->x_optimize =3D=3D 0) > { > @@ -2461,6 +2497,29 @@ parse_and_check_patch_area (const char *arg, bool = report_error, > free (patch_area_arg); > } > > +/* Print options enabled by -fhardened. Keep this in sync with the manu= al! */ > + > +static void > +print_help_hardened () > +{ > + printf ("%s\n", "The following options are enabled by -fhardened:"); > + printf (" %s=3D%d\n", "-D_FORTIFY_SOURCE", > + (TARGET_GLIBC_MAJOR =3D=3D 2 && TARGET_GLIBC_MINOR >=3D 35) ? 3= : 2); > + printf (" %s\n", "-D_GLIBCXX_ASSERTIONS"); > + printf (" %s\n", "-ftrivial-auto-var-init=3Dzero"); > +#ifdef HAVE_LD_PIE > + printf (" %s %s\n", "-fPIE", "-pie"); > +#endif > + if (HAVE_LD_NOW_SUPPORT) > + printf (" %s\n", "-Wl,-z,now"); > + if (HAVE_LD_RELRO_SUPPORT) > + printf (" %s\n", "-Wl,-z,relro"); > + printf (" %s\n", "-fstack-protector-strong"); > + printf (" %s\n", "-fstack-clash-protection"); > + printf (" %s\n", "-fcf-protection=3Dfull"); > + putchar ('\n'); > +} > + > /* Print help when OPT__help_ is set. */ > > void > @@ -2576,6 +2635,8 @@ print_help (struct gcc_options *opts, unsigned int = lang_mask, > } > else if (lang_flag !=3D 0) > *pflags |=3D lang_flag; > + else if (strncasecmp (a, "hardened", len) =3D=3D 0) > + print_help_hardened (); > else > warning (0, > "unrecognized argument to %<--help=3D%> option: %q.*s", > diff --git a/gcc/opts.h b/gcc/opts.h > index 00f377f9ca7..d89c5de8114 100644 > --- a/gcc/opts.h > +++ b/gcc/opts.h > @@ -344,6 +344,7 @@ struct cl_option_handlers > /* Hold command-line options associated with stack limitation. */ > extern const char *opt_fstack_limit_symbol_arg; > extern int opt_fstack_limit_register_no; > +extern bool flag_stack_protector_set_by_fhardened_p; > > /* Input file names. */ > > diff --git a/gcc/testsuite/c-c++-common/fhardened-1.S b/gcc/testsuite/c-c= ++-common/fhardened-1.S > new file mode 100644 > index 00000000000..4dd22cdfe45 > --- /dev/null > +++ b/gcc/testsuite/c-c++-common/fhardened-1.S > @@ -0,0 +1,6 @@ > +/* { dg-do preprocess { target pie } } */ > +/* { dg-options "-fhardened -O" } */ > + > +#if __PIE__ !=3D 2 > +# error "-fPIE not enabled" > +#endif > diff --git a/gcc/testsuite/c-c++-common/fhardened-1.c b/gcc/testsuite/c-c= ++-common/fhardened-1.c > new file mode 100644 > index 00000000000..dd3cde93805 > --- /dev/null > +++ b/gcc/testsuite/c-c++-common/fhardened-1.c > @@ -0,0 +1,14 @@ > +/* { dg-do compile } */ > +/* { dg-options "-fhardened -O" } */ > + > +#ifndef __SSP_STRONG__ > +# error "-fstack-protector-strong not enabled" > +#endif > + > +#if _FORTIFY_SOURCE < 2 > +# error "_FORTIFY_SOURCE not enabled" > +#endif > + > +#ifndef _GLIBCXX_ASSERTIONS > +# error "_GLIBCXX_ASSERTIONS not enabled" > +#endif > diff --git a/gcc/testsuite/c-c++-common/fhardened-10.c b/gcc/testsuite/c-= c++-common/fhardened-10.c > new file mode 100644 > index 00000000000..8242530bc4d > --- /dev/null > +++ b/gcc/testsuite/c-c++-common/fhardened-10.c > @@ -0,0 +1,12 @@ > +/* { dg-do compile } */ > +/* { dg-options "-fhardened -D_FORTIFY_SOURCE=3D1" } */ > + > +#if _FORTIFY_SOURCE !=3D 1 > +# error "_FORTIFY_SOURCE !=3D 1" > +#endif > + > +#ifndef _GLIBCXX_ASSERTIONS > +# error "_GLIBCXX_ASSERTIONS disabled when it should not be" > +#endif > + > +/* { dg-warning "._FORTIFY_SOURCE. is not enabled" "" { target *-*-* } 0= } */ > diff --git a/gcc/testsuite/c-c++-common/fhardened-11.c b/gcc/testsuite/c-= c++-common/fhardened-11.c > new file mode 100644 > index 00000000000..b8fd65a960c > --- /dev/null > +++ b/gcc/testsuite/c-c++-common/fhardened-11.c > @@ -0,0 +1,10 @@ > +/* { dg-do compile } */ > +/* { dg-options "-fhardened -O -D_FORTIFY_SOURCE_ -D_GLIBCXX_ASSERTIONS_= " } */ > + > +#ifndef _FORTIFY_SOURCE > +# error "_FORTIFY_SOURCE disabled when it should not be" > +#endif > + > +#ifndef _GLIBCXX_ASSERTIONS > +# error "_GLIBCXX_ASSERTIONS disabled when it should not be" > +#endif > diff --git a/gcc/testsuite/c-c++-common/fhardened-12.c b/gcc/testsuite/c-= c++-common/fhardened-12.c > new file mode 100644 > index 00000000000..42594e4c0e0 > --- /dev/null > +++ b/gcc/testsuite/c-c++-common/fhardened-12.c > @@ -0,0 +1,11 @@ > +/* { dg-do compile } */ > +/* { dg-options "-fhardened -O -fdump-tree-gimple" } */ > + > +int > +foo () > +{ > + int i; > + return i; > +} > + > +/* { dg-final { scan-tree-dump ".DEFERRED_INIT" "gimple" } } */ > diff --git a/gcc/testsuite/c-c++-common/fhardened-13.c b/gcc/testsuite/c-= c++-common/fhardened-13.c > new file mode 100644 > index 00000000000..6945a6391a9 > --- /dev/null > +++ b/gcc/testsuite/c-c++-common/fhardened-13.c > @@ -0,0 +1,6 @@ > +/* { dg-do compile { target pie } } */ > +/* { dg-options "-fhardened -O" } */ > + > +#if __PIE__ !=3D 2 > +# error "-fPIE not enabled" > +#endif > diff --git a/gcc/testsuite/c-c++-common/fhardened-14.c b/gcc/testsuite/c-= c++-common/fhardened-14.c > new file mode 100644 > index 00000000000..652ece3d4c4 > --- /dev/null > +++ b/gcc/testsuite/c-c++-common/fhardened-14.c > @@ -0,0 +1,6 @@ > +/* { dg-do compile { target pie } } */ > +/* { dg-options "-fhardened -O -fno-PIE" } */ > + > +#ifdef __PIE__ > +# error "PIE enabled when it should not be" > +#endif > diff --git a/gcc/testsuite/c-c++-common/fhardened-15.c b/gcc/testsuite/c-= c++-common/fhardened-15.c > new file mode 100644 > index 00000000000..c6202754bf5 > --- /dev/null > +++ b/gcc/testsuite/c-c++-common/fhardened-15.c > @@ -0,0 +1,5 @@ > +/* { dg-do compile } */ > +/* { dg-require-stack-check "specific" } */ > +/* { dg-options "-fhardened -O -fstack-check" } */ > + > +/* { dg-warning ".-fstack-clash-protection. is not enabled by .-fhardene= d. because .-fstack-check. was specified" "" { target *-*-* } 0 } */ > diff --git a/gcc/testsuite/c-c++-common/fhardened-2.c b/gcc/testsuite/c-c= ++-common/fhardened-2.c > new file mode 100644 > index 00000000000..283867ca806 > --- /dev/null > +++ b/gcc/testsuite/c-c++-common/fhardened-2.c > @@ -0,0 +1,12 @@ > +/* { dg-do compile } */ > +/* { dg-options "-fhardened -fstack-protector" } */ > + > +#ifdef __SSP_STRONG__ > +# error "-fstack-protector-strong enabled when it should not be" > +#endif > +#ifndef __SSP__ > +# error "-fstack-protector not enabled" > +#endif > + > +/* { dg-warning ".-fstack-protector-strong. is not enabled" "" { target = *-*-* } 0 } */ > +/* { dg-warning "._FORTIFY_SOURCE. is not enabled" "" { target *-*-* } 0= } */ > diff --git a/gcc/testsuite/c-c++-common/fhardened-3.c b/gcc/testsuite/c-c= ++-common/fhardened-3.c > new file mode 100644 > index 00000000000..6924ba242f0 > --- /dev/null > +++ b/gcc/testsuite/c-c++-common/fhardened-3.c > @@ -0,0 +1,14 @@ > +/* { dg-do compile } */ > +/* { dg-options "-fhardened -O0" } */ > +/* Test that we don't get any diagnostic coming from libc headers. */ > + > +#include > + > +/* The most useful C program known to man. */ > + > +int > +main () > +{ > +} > + > +/* { dg-warning "._FORTIFY_SOURCE. is not enabled" "" { target *-*-* } 0= } */ > diff --git a/gcc/testsuite/c-c++-common/fhardened-4.c b/gcc/testsuite/c-c= ++-common/fhardened-4.c > new file mode 100644 > index 00000000000..7d44d299f19 > --- /dev/null > +++ b/gcc/testsuite/c-c++-common/fhardened-4.c > @@ -0,0 +1,4 @@ > +/* { dg-do compile } */ > +/* { dg-options "-fhardened -O0 -Wno-hardened" } */ > + > +/* { dg-bogus "._FORTIFY_SOURCE. is not enabled" "" { target *-*-* } 0 }= */ > diff --git a/gcc/testsuite/c-c++-common/fhardened-5.c b/gcc/testsuite/c-c= ++-common/fhardened-5.c > new file mode 100644 > index 00000000000..42594e4c0e0 > --- /dev/null > +++ b/gcc/testsuite/c-c++-common/fhardened-5.c > @@ -0,0 +1,11 @@ > +/* { dg-do compile } */ > +/* { dg-options "-fhardened -O -fdump-tree-gimple" } */ > + > +int > +foo () > +{ > + int i; > + return i; > +} > + > +/* { dg-final { scan-tree-dump ".DEFERRED_INIT" "gimple" } } */ > diff --git a/gcc/testsuite/c-c++-common/fhardened-6.c b/gcc/testsuite/c-c= ++-common/fhardened-6.c > new file mode 100644 > index 00000000000..744384f317f > --- /dev/null > +++ b/gcc/testsuite/c-c++-common/fhardened-6.c > @@ -0,0 +1,12 @@ > +/* { dg-do compile } */ > +/* { dg-options "-fhardened -O -ftrivial-auto-var-init=3Duninitialized -= fdump-tree-gimple" } */ > + > +int > +foo () > +{ > + int i; > + return i; > +} > + > +/* { dg-final { scan-tree-dump-not ".DEFERRED_INIT" "gimple" } } */ > +/* { dg-warning ".-ftrivial-auto-var-init=3Dzero. is not enabled" "" { t= arget *-*-* } 0 } */ > diff --git a/gcc/testsuite/c-c++-common/fhardened-7.c b/gcc/testsuite/c-c= ++-common/fhardened-7.c > new file mode 100644 > index 00000000000..32f35eb2595 > --- /dev/null > +++ b/gcc/testsuite/c-c++-common/fhardened-7.c > @@ -0,0 +1,7 @@ > +/* { dg-do compile { target pie } } */ > +/* { dg-options "-fhardened -O -fpie" } */ > + > +/* -fpie takes precedence over -fhardened */ > +#if __PIE__ !=3D 1 > +# error "__PIE__ !=3D 1" > +#endif > diff --git a/gcc/testsuite/c-c++-common/fhardened-8.c b/gcc/testsuite/c-c= ++-common/fhardened-8.c > new file mode 100644 > index 00000000000..5b3162b4d1f > --- /dev/null > +++ b/gcc/testsuite/c-c++-common/fhardened-8.c > @@ -0,0 +1,7 @@ > +/* { dg-do compile { target pie } } */ > +/* { dg-options "-fhardened -O -fPIC" } */ > + > +/* -fPIC takes precedence over -fhardened */ > +#ifdef __PIE__ > +# error "PIE enabled when it should not be" > +#endif > diff --git a/gcc/testsuite/c-c++-common/fhardened-9.c b/gcc/testsuite/c-c= ++-common/fhardened-9.c > new file mode 100644 > index 00000000000..d3b9e79b9b6 > --- /dev/null > +++ b/gcc/testsuite/c-c++-common/fhardened-9.c > @@ -0,0 +1,9 @@ > +/* { dg-do compile } */ > +/* { dg-options "-fhardened -U_FORTIFY_SOURCE -U_GLIBCXX_ASSERTIONS" } *= / > + > +#if defined(_FORTIFY_SOURCE) || defined(_GLIBCXX_ASSERTIONS) > +# error "hardening enabled when it should not be" > +#endif > + > +/* { dg-warning "._FORTIFY_SOURCE. is not enabled" "" { target *-*-* } 0= } */ > +/* { dg-warning "._GLIBCXX_ASSERTIONS. is not enabled" "" { target *-*-*= } 0 } */ > diff --git a/gcc/testsuite/gcc.misc-tests/help.exp b/gcc/testsuite/gcc.mi= sc-tests/help.exp > index 52b9cb0ab90..15d618a2528 100644 > --- a/gcc/testsuite/gcc.misc-tests/help.exp > +++ b/gcc/testsuite/gcc.misc-tests/help.exp > @@ -151,6 +151,8 @@ foreach cls { "ada" "c" "c++" "d" "fortran" "go" \ > # Listing only excludes gives empty results. > check_for_options c "--help=3D^joined,^separate" "" "" "" > > +check_for_options c "--help=3Dhardened" "The following options are enabl= ed by -fhardened" "" "" > + > if [ info exists prev_columns ] { > # Reset the enviroment variable to its oriuginal value. > set env(COLUMNS) $prev_columns > diff --git a/gcc/testsuite/gcc.target/i386/cf_check-6.c b/gcc/testsuite/g= cc.target/i386/cf_check-6.c > new file mode 100644 > index 00000000000..73b78dce889 > --- /dev/null > +++ b/gcc/testsuite/gcc.target/i386/cf_check-6.c > @@ -0,0 +1,12 @@ > +/* { dg-do compile } */ > +/* { dg-options "-O2 -fhardened -mno-manual-endbr" } */ > +/* { dg-final { scan-assembler-times {\mendbr} 1 } } */ > +/* Test that -fhardened enables CET. */ > + > +extern void bar (void) __attribute__((__cf_check__)); > + > +void > +foo (void) > +{ > + bar (); > +} > diff --git a/gcc/toplev.cc b/gcc/toplev.cc > index 8af9bf5090e..743a3a91684 100644 > --- a/gcc/toplev.cc > +++ b/gcc/toplev.cc > @@ -1575,6 +1575,19 @@ process_options (bool no_backend) > "where the stack grows from lower to higher addresses")= ; > flag_stack_clash_protection =3D 0; > } > + else if (flag_hardened) > + { > + if (!flag_stack_clash_protection > + /* Don't enable -fstack-clash-protection when -fstack-check=3D > + is used: it would result in confusing errors. */ > + && flag_stack_check =3D=3D NO_STACK_CHECK) > + flag_stack_clash_protection =3D 1; > + else if (flag_stack_check !=3D NO_STACK_CHECK) > + warning_at (UNKNOWN_LOCATION, OPT_Whardened, > + "%<-fstack-clash-protection%> is not enabled by " > + "%<-fhardened%> because %<-fstack-check%> was " > + "specified on the command line"); > + } > > /* We cannot support -fstack-check=3D and -fstack-clash-protection at > the same time. */ > @@ -1590,8 +1603,9 @@ process_options (bool no_backend) > target already uses a soft frame pointer, the transition is trivial= . */ > if (!FRAME_GROWS_DOWNWARD && flag_stack_protect) > { > - warning_at (UNKNOWN_LOCATION, 0, > - "%<-fstack-protector%> not supported for this target"); > + if (!flag_stack_protector_set_by_fhardened_p) > + warning_at (UNKNOWN_LOCATION, 0, > + "%<-fstack-protector%> not supported for this target"= ); > flag_stack_protect =3D 0; > } > if (!flag_stack_protect) > > base-commit: 32b74c9e1d46932a4bbb1f46353bfc43c702c20a > -- > 2.41.0 >