Ping.

On Fri, Nov 03, 2023 at 06:51:16PM -0400, Marek Polacek wrote:
> On Thu, Oct 26, 2023 at 05:55:56PM +0200, Richard Biener wrote:
> > 
> > 
> > > Am 24.10.2023 um 21:09 schrieb Marek Polacek <pola...@redhat.com>:
> > > 
> > > On Tue, Oct 24, 2023 at 09:22:25AM +0200, Richard Biener wrote:
> > >>> On Mon, Oct 23, 2023 at 9:26 PM Marek Polacek <pola...@redhat.com> 
> > >>> wrote:
> > >>> 
> > >>> On Thu, Oct 19, 2023 at 02:24:11PM +0200, Richard Biener wrote:
> > >>>> 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) 
> > >>> but
> > >>> 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: 
> > >>> all] 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 
> > >>>> should
> > >>>> 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"?
> > > 
> > > I see.  fhardened-3.c is basically just like this (-Whardened is on by 
> > > default).
> > > 
> > >>> 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?
> > > 
> > > Right.  It will not diagnose missing features if they have a configure
> > > check, otherwise it will.  And I don't know if we want a configure check
> > > for every feature.  Maybe we can add them in the future if the current
> > > patch turns out to be problematical in practice?
> > 
> > Maybe we can have a switch on known target triples and statically configure 
> > based
> > On that, eventually even not support -fhardened for targets not listed.  
> > That’s certainly easier than detecting the target system features (think of 
> > cross compilers)
> 
> You mean like the following?  The only difference is the addition of
> HAVE_FHARDENED_SUPPORT and updating the tests to only run on gnu/linux
> targets.  If other OSs want to use -fhardened, they need to update the
> configure test.  Thanks,
> 
> Bootstrapped/regtested on x86_64-pc-linux-gnu and
> powerpc64le-unknown-linux-gnu.
> 
> -- >8 --
> In <https://gcc.gnu.org/pipermail/gcc-patches/2023-August/628748.html>
> I proposed -fhardened, a new umbrella option that enables a reasonable 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=3 (or =2 for older glibcs)
>   -D_GLIBCXX_ASSERTIONS
>   -ftrivial-auto-var-init=zero
>   -fPIE  -pie  -Wl,-z,relro,-z,now
>   -fstack-protector-strong
>   -fstack-clash-protection
>   -fcf-protection=full (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=1 -fhardened
> 
> means that _FORTIFY_SOURCE=1 will be used.  Similarly,
> 
>       -fhardened -fstack-protector
> 
> will not enable -fstack-protector-strong.
> 
> Currently, -fhardened is only supported on GNU/Linux.
> 
> 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 optimization
> 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): When
>       -fhardened, maybe enable -fcf-protection=full.
>       * configure: Regenerate.
>       * configure.ac: Check if the linker supports '-z now' and '-z relro'.
>       Check if -fhardened is supported on $target_os.
>       * 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=zero 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_fhardened_p,
>       do not warn that -fstack-protector not supported for this target.
>       Don't enable -fhardened when !HAVE_FHARDENED_SUPPORT.
> 
> 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                              | 18 ++++++
>  gcc/config/bpf/bpf.cc                      |  8 ++-
>  gcc/config/i386/i386-options.cc            | 17 ++++-
>  gcc/configure                              | 72 +++++++++++++++++++++-
>  gcc/configure.ac                           | 57 ++++++++++++++++-
>  gcc/doc/invoke.texi                        | 49 ++++++++++++++-
>  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                              | 25 +++++++-
>  30 files changed, 556 insertions(+), 16 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 e9f7e6d424d..26f009f2da5 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 = false;
> +      bool cxx_assert_seen_p = false;
> +
>        /* All command line defines must have the same location.  */
>        cpp_force_token_locations (parse_in, line_table->highest_line);
>        for (size_t i = 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 == OPT_D || opt->code == OPT_U))
> +         {
> +           if (!fortify_seen_p)
> +             fortify_seen_p
> +               = (!strncmp (opt->arg, "_FORTIFY_SOURCE", 15)
> +                  && (opt->arg[15] == '\0' || opt->arg[15] == '='));
> +           if (!cxx_assert_seen_p)
> +             cxx_assert_seen_p
> +               = (!strncmp (opt->arg, "_GLIBCXX_ASSERTIONS", 19)
> +                  && (opt->arg[19] == '\0' || opt->arg[19] == '='));
> +         }
> +     }
> +
> +      if (flag_hardened)
> +     {
> +       if (!fortify_seen_p && optimize > 0)
> +         {
> +           if (TARGET_GLIBC_MAJOR == 2 && TARGET_GLIBC_MINOR >= 35)
> +             cpp_define (parse_in, "_FORTIFY_SOURCE=3");
> +           else
> +             cpp_define (parse_in, "_FORTIFY_SOURCE=2");
> +         }
> +       else if (optimize == 0)
> +         warning_at (UNKNOWN_LOCATION, OPT_Whardened,
> +                     "%<_FORTIFY_SOURCE%> is not enabled by %<-fhardened%> "
> +                     "because optimizations are turned off");
> +       else
> +         warning_at (UNKNOWN_LOCATION, OPT_Whardened,
> +                     "%<_FORTIFY_SOURCE%> is not enabled by %<-fhardened%> "
> +                     "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..97b483ddd97 100644
> --- a/gcc/config.in
> +++ b/gcc/config.in
> @@ -1293,6 +1293,12 @@
>  #endif
>  
>  
> +/* Define 0/1 if -fhardened is supported */
> +#ifndef USED_FOR_TARGET
> +#undef HAVE_FHARDENED_SUPPORT
> +#endif
> +
> +
>  /* Define to 1 if you have the `fileno_unlocked' function. */
>  #ifndef USED_FOR_TARGET
>  #undef HAVE_FILENO_UNLOCKED
> @@ -1695,6 +1701,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 +1750,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 sections 
> into
>     a read-write section. */
>  #ifndef USED_FOR_TARGET
> diff --git a/gcc/config/bpf/bpf.cc b/gcc/config/bpf/bpf.cc
> index 63637ece78e..804f6f3304a 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 = 0;
>      }
>  
> diff --git a/gcc/config/i386/i386-options.cc b/gcc/config/i386/i386-options.cc
> index df7d24352d1..76adba672b9 100644
> --- a/gcc/config/i386/i386-options.cc
> +++ b/gcc/config/i386/i386-options.cc
> @@ -3072,10 +3072,25 @@ ix86_option_override_internal (bool main_args_p,
>          = build_target_option_node (opts, opts_set);
>      }
>  
> +  const bool cf_okay_p = (TARGET_64BIT || TARGET_CMOV);
> +  /* When -fhardened, enable -fcf-protection=full, 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 == CF_NONE)
> +     opts->x_flag_cf_protection = CF_FULL;
> +      else if (opts->x_flag_cf_protection != CF_FULL)
> +     warning_at (UNKNOWN_LOCATION, OPT_Whardened,
> +                 "%<-fcf-protection=full%> is not enabled by "
> +                 "%<-fhardened%> because it was specified on the command "
> +                 "line");
> +    }
> +
>    if (opts->x_flag_cf_protection != CF_NONE)
>      {
>        if ((opts->x_flag_cf_protection & CF_BRANCH) == 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 d4ad988000f..e701f6be063 100755
> --- a/gcc/configure
> +++ b/gcc/configure
> @@ -20000,7 +20000,7 @@ else
>    lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
>    lt_status=$lt_dlunknown
>    cat > conftest.$ac_ext <<_LT_EOF
> -#line 19995 "configure"
> +#line 20003 "configure"
>  #include "confdefs.h"
>  
>  #if HAVE_DLFCN_H
> @@ -20106,7 +20106,7 @@ else
>    lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
>    lt_status=$lt_dlunknown
>    cat > conftest.$ac_ext <<_LT_EOF
> -#line 20101 "configure"
> +#line 20109 "configure"
>  #include "confdefs.h"
>  
>  #if HAVE_DLFCN_H
> @@ -32903,7 +32903,7 @@ if test x"$ld_is_gold" = xno; then
>        ld_bndplt_support=yes
>      fi
>    elif test x$gcc_cv_ld != 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=yes
>      fi
> @@ -33032,6 +33032,72 @@ $as_echo "#define ENABLE_S390_EXCESS_FLOAT_PRECISION 
> 1" >>confdefs.h
>    ;;
>  esac
>  
> +# Check if the linker supports '-z now'
> +ld_now_support=no
> +{ $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" = xyes; then
> +  ld_now_support=yes
> +elif test $in_tree_ld = yes ; then
> +  if test "$gcc_cv_gld_major_version" -eq 2 -a "$gcc_cv_gld_minor_version" 
> -ge 14 -o "$gcc_cv_gld_major_version" -gt 2; then
> +    ld_now_support=yes
> +  fi
> +elif test x$gcc_cv_ld != x; then
> +  # Check if linker supports -z now
> +  if $gcc_cv_ld --help 2>&1 | grep -- '-z now' > /dev/null; then
> +    ld_now_support=yes
> +  fi
> +fi
> +
> +cat >>confdefs.h <<_ACEOF
> +#define HAVE_LD_NOW_SUPPORT `if test x"$ld_now_support" = xyes; then echo 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=no
> +{ $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" = xyes; then
> +  ld_relro_support=yes
> +elif test $in_tree_ld = yes ; then
> +  if test "$gcc_cv_gld_major_version" -eq 2 -a "$gcc_cv_gld_minor_version" 
> -ge 15 -o "$gcc_cv_gld_major_version" -gt 2; then
> +    ld_relro_support=yes
> +  fi
> +elif test x$gcc_cv_ld != x; then
> +  # Check if linker supports -z relro
> +  if $gcc_cv_ld --help 2>&1 | grep -- '-z relro' > /dev/null; then
> +    ld_relro_support=yes
> +  fi
> +fi
> +
> +cat >>confdefs.h <<_ACEOF
> +#define HAVE_LD_RELRO_SUPPORT `if test x"$ld_relro_support" = xyes; then 
> 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; }
> +
> +case $target_os in
> +linux* | gnu*)
> +  # -fhardened is only supported on GNU/Linux.
> +  fhardened_support=yes
> +  ;;
> +*)
> +  fhardened_support=no
> +  ;;
> +esac
> +
> +
> +cat >>confdefs.h <<_ACEOF
> +#define HAVE_FHARDENED_SUPPORT `if test x"$fhardened_support" = xyes; then 
> echo 1; else echo 0; fi`
> +_ACEOF
> +
> +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $fhardened_support" >&5
> +$as_echo "$fhardened_support" >&6; }
> +
>  # Configure the subdirectories
>  # AC_CONFIG_SUBDIRS($subdirs)
>  
> diff --git a/gcc/configure.ac b/gcc/configure.ac
> index dc8cb6a33de..feb81b114b4 100644
> --- a/gcc/configure.ac
> +++ b/gcc/configure.ac
> @@ -7714,7 +7714,7 @@ if test x"$ld_is_gold" = xno; then
>        ld_bndplt_support=yes
>      fi
>    elif test x$gcc_cv_ld != 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=yes
>      fi
> @@ -7815,6 +7815,61 @@ standards-compatible mode on s390 targets.])
>    ;;
>  esac
>  
> +# Check if the linker supports '-z now'
> +ld_now_support=no
> +AC_MSG_CHECKING(linker -z now option)
> +if test x"$ld_is_gold" = xyes; then
> +  ld_now_support=yes
> +elif test $in_tree_ld = yes ; then
> +  if test "$gcc_cv_gld_major_version" -eq 2 -a "$gcc_cv_gld_minor_version" 
> -ge 14 -o "$gcc_cv_gld_major_version" -gt 2; then
> +    ld_now_support=yes
> +  fi
> +elif test x$gcc_cv_ld != x; then
> +  # Check if linker supports -z now
> +  if $gcc_cv_ld --help 2>&1 | grep -- '-z now' > /dev/null; then
> +    ld_now_support=yes
> +  fi
> +fi
> +AC_DEFINE_UNQUOTED(HAVE_LD_NOW_SUPPORT,
> +  [`if test x"$ld_now_support" = 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=no
> +AC_MSG_CHECKING(linker -z relro option)
> +if test x"$ld_is_gold" = xyes; then
> +  ld_relro_support=yes
> +elif test $in_tree_ld = yes ; then
> +  if test "$gcc_cv_gld_major_version" -eq 2 -a "$gcc_cv_gld_minor_version" 
> -ge 15 -o "$gcc_cv_gld_major_version" -gt 2; then
> +    ld_relro_support=yes
> +  fi
> +elif test x$gcc_cv_ld != x; then
> +  # Check if linker supports -z relro
> +  if $gcc_cv_ld --help 2>&1 | grep -- '-z relro' > /dev/null; then
> +    ld_relro_support=yes
> +  fi
> +fi
> +AC_DEFINE_UNQUOTED(HAVE_LD_RELRO_SUPPORT,
> +  [`if test x"$ld_relro_support" = xyes; then echo 1; else echo 0; fi`],
> +  [Define 0/1 if your linker supports -z relro])
> +AC_MSG_RESULT($ld_relro_support)
> +
> +case $target_os in
> +linux* | gnu*)
> +  # -fhardened is only supported on GNU/Linux.
> +  fhardened_support=yes
> +  ;;
> +*)
> +  fhardened_support=no
> +  ;;
> +esac
> +
> +AC_DEFINE_UNQUOTED(HAVE_FHARDENED_SUPPORT,
> +  [`if test x"$fhardened_support" = xyes; then echo 1; else echo 0; fi`],
> +  [Define 0/1 if -fhardened is supported])
> +AC_MSG_RESULT($fhardened_support)
> +
>  # Configure the subdirectories
>  # AC_CONFIG_SUBDIRS($subdirs)
>  
> diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
> index 6e776a0faa1..7f145468950 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=@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=@var{n}
>  -Wno-implicit-function-declaration  -Wno-implicit-int
>  -Winfinite-recursion
> @@ -641,7 +641,7 @@ Objective-C and Objective-C++ Dialects}.
>  -fasan-shadow-offset=@var{number}  -fsanitize-sections=@var{s1},@var{s2},...
>  -fsanitize-undefined-trap-on-error  -fbounds-check
>  -fcf-protection=@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=@r{[}always@r{|}no-xthrow@r{|}nothrow@r{|}never@r{]}
> @@ -6860,6 +6860,18 @@ This warning is upgraded to an error by 
> @option{-pedantic-errors}.
>  Same as @option{-Wimplicit-int} and @option{-Wimplicit-function-declaration}.
>  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 causes
> +@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{-fhardened}
> +is enabled.
> +
>  @opindex Wimplicit-fallthrough
>  @opindex Wno-implicit-fallthrough
>  @item -Wimplicit-fallthrough
> @@ -17552,6 +17564,39 @@ 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=3
> +-D_GLIBCXX_ASSERTIONS
> +-ftrivial-auto-var-init=zero
> +-fPIE  -pie  -Wl,-z,relro,-z,now
> +-fstack-protector-strong
> +-fstack-clash-protection
> +-fcf-protection=full @r{(x86 GNU/Linux only)}
> +}
> +
> +The list of options enabled by @option{-fhardened} can be generated using
> +the @option{--help=hardened} option.
> +
> +When the system glibc is older than 2.35, @option{-D_FORTIFY_SOURCE=2}
> +is used instead.
> +
> +This option is intended to be used in production builds, not merely
> +in debug builds.
> +
> +Currently, @option{-fhardened} is only supported on GNU/Linux targets.
> +
> +@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 = 0;
>     driver added to dumpdir after dumpbase or linker output name.  */
>  static bool dumpdir_trailing_dash_added = 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 = true;
>  #endif
> +    case OPT_r:
> +    case OPT_shared:
> +    case OPT_no_pie:
> +      any_link_options_p = true;
> +      break;
> +
> +    case OPT_static:
> +      static_p = true;
> +      break;
>  
>      case OPT_static_libgcc:
>      case OPT_shared_libgcc:
> @@ -4985,6 +5002,35 @@ process_command (unsigned int decoded_options_count,
>  #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=*/true, 
> /*known=*/false);
> +#endif
> +       /* These are passed straight down to collect2 so we have to break
> +          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 command "
> +                 "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 f54cf8305ca..787f3f47db3 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 
> gcc_options *opts_set,
>        opts->x_flag_section_anchors = 0;
>      }
>  
> +  if (opts->x_flag_hardened)
> +    {
> +      if (!opts_set->x_flag_auto_var_init)
> +     opts->x_flag_auto_var_init = AUTO_INIT_ZERO;
> +      else if (opts->x_flag_auto_var_init != AUTO_INIT_ZERO)
> +     warning_at (loc, OPT_Whardened,
> +                 "%<-ftrivial-auto-var-init=zero%> is not enabled by "
> +                 "%<-fhardened%> because it was specified on the command "
> +                 "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 
> gcc_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 == -1)
> -         opts->x_flag_pie = DEFAULT_FLAG_PIE;
> +         opts->x_flag_pie = (opts->x_flag_hardened
> +                             ? /*-fPIE*/ 2 : DEFAULT_FLAG_PIE);
>         else
>           opts->x_flag_pie = 0;
>       }
> @@ -1117,9 +1133,29 @@ finish_options (struct gcc_options *opts, struct 
> gcc_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 == -1)
> -    opts->x_flag_stack_protect = 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 remember
> +      that flag_stack_protect was set at the behest of -fhardened.  */
> +      if (opts->x_flag_hardened)
> +     {
> +       opts->x_flag_stack_protect = SPCT_FLAG_STRONG;
> +       flag_stack_protector_set_by_fhardened_p = true;
> +     }
> +      else
> +     opts->x_flag_stack_protect = DEFAULT_FLAG_SSP;
> +    }
> +  else if (opts->x_flag_hardened
> +        && opts->x_flag_stack_protect != 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 == 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 manual!  
> */
> +
> +static void
> +print_help_hardened ()
> +{
> +  printf ("%s\n", "The following options are enabled by -fhardened:");
> +  printf ("  %s=%d\n", "-D_FORTIFY_SOURCE",
> +       (TARGET_GLIBC_MAJOR == 2 && TARGET_GLIBC_MINOR >= 35) ? 3 : 2);
> +  printf ("  %s\n", "-D_GLIBCXX_ASSERTIONS");
> +  printf ("  %s\n", "-ftrivial-auto-var-init=zero");
> +#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=full");
> +  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 != 0)
>       *pflags |= lang_flag;
> +      else if (strncasecmp (a, "hardened", len) == 0)
> +     print_help_hardened ();
>        else
>       warning (0,
>                "unrecognized argument to %<--help=%> 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..9d0a5772d9e
> --- /dev/null
> +++ b/gcc/testsuite/c-c++-common/fhardened-1.S
> @@ -0,0 +1,6 @@
> +/* { dg-do preprocess { target { { *-*-linux* *-*-gnu* } && pie } } } */
> +/* { dg-options "-fhardened -O" } */
> +
> +#if __PIE__ != 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..7e6740655fe
> --- /dev/null
> +++ b/gcc/testsuite/c-c++-common/fhardened-1.c
> @@ -0,0 +1,14 @@
> +/* { dg-do compile { target *-*-linux* *-*-gnu* } } */
> +/* { 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..badebc56440
> --- /dev/null
> +++ b/gcc/testsuite/c-c++-common/fhardened-10.c
> @@ -0,0 +1,12 @@
> +/* { dg-do compile { target *-*-linux* *-*-gnu* } } */
> +/* { dg-options "-fhardened -D_FORTIFY_SOURCE=1" } */
> +
> +#if _FORTIFY_SOURCE != 1
> +# error "_FORTIFY_SOURCE != 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..d1a973d177a
> --- /dev/null
> +++ b/gcc/testsuite/c-c++-common/fhardened-11.c
> @@ -0,0 +1,10 @@
> +/* { dg-do compile { target *-*-linux* *-*-gnu* } } */
> +/* { 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..eb128f61ba3
> --- /dev/null
> +++ b/gcc/testsuite/c-c++-common/fhardened-12.c
> @@ -0,0 +1,11 @@
> +/* { dg-do compile { target *-*-linux* *-*-gnu* } } */
> +/* { 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..8722e6d4b1a
> --- /dev/null
> +++ b/gcc/testsuite/c-c++-common/fhardened-13.c
> @@ -0,0 +1,6 @@
> +/* { dg-do compile { target { { *-*-linux* *-*-gnu* } && pie } } } */
> +/* { dg-options "-fhardened -O" } */
> +
> +#if __PIE__ != 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..04d6c8ff954
> --- /dev/null
> +++ b/gcc/testsuite/c-c++-common/fhardened-14.c
> @@ -0,0 +1,6 @@
> +/* { dg-do compile { target { { *-*-linux* *-*-gnu* } && 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..86dc5220159
> --- /dev/null
> +++ b/gcc/testsuite/c-c++-common/fhardened-15.c
> @@ -0,0 +1,5 @@
> +/* { dg-do compile { target *-*-linux* *-*-gnu* } } */
> +/* { dg-require-stack-check "specific" } */
> +/* { dg-options "-fhardened -O -fstack-check" } */
> +
> +/* { dg-warning ".-fstack-clash-protection. is not enabled by .-fhardened. 
> 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..280ff96eb15
> --- /dev/null
> +++ b/gcc/testsuite/c-c++-common/fhardened-2.c
> @@ -0,0 +1,12 @@
> +/* { dg-do compile { target *-*-linux* *-*-gnu* } } */
> +/* { 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..f2306ca5d33
> --- /dev/null
> +++ b/gcc/testsuite/c-c++-common/fhardened-3.c
> @@ -0,0 +1,14 @@
> +/* { dg-do compile { target *-*-linux* *-*-gnu* } } */
> +/* { dg-options "-fhardened -O0" } */
> +/* Test that we don't get any diagnostic coming from libc headers.  */
> +
> +#include <stdio.h>
> +
> +/* 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..312fabb95a5
> --- /dev/null
> +++ b/gcc/testsuite/c-c++-common/fhardened-4.c
> @@ -0,0 +1,4 @@
> +/* { dg-do compile { target *-*-linux* *-*-gnu* } } */
> +/* { 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..eb128f61ba3
> --- /dev/null
> +++ b/gcc/testsuite/c-c++-common/fhardened-5.c
> @@ -0,0 +1,11 @@
> +/* { dg-do compile { target *-*-linux* *-*-gnu* } } */
> +/* { 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..d3cb7c8b353
> --- /dev/null
> +++ b/gcc/testsuite/c-c++-common/fhardened-6.c
> @@ -0,0 +1,12 @@
> +/* { dg-do compile { target *-*-linux* *-*-gnu* } } */
> +/* { dg-options "-fhardened -O -ftrivial-auto-var-init=uninitialized 
> -fdump-tree-gimple" } */
> +
> +int
> +foo ()
> +{
> +  int i;
> +  return i;
> +}
> +
> +/* { dg-final { scan-tree-dump-not ".DEFERRED_INIT" "gimple" } } */
> +/* { dg-warning ".-ftrivial-auto-var-init=zero. is not enabled" "" { target 
> *-*-* } 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..b47bf43f360
> --- /dev/null
> +++ b/gcc/testsuite/c-c++-common/fhardened-7.c
> @@ -0,0 +1,7 @@
> +/* { dg-do compile { target { { *-*-linux* *-*-gnu* } && pie } } } */
> +/* { dg-options "-fhardened -O -fpie" } */
> +
> +/* -fpie takes precedence over -fhardened */
> +#if __PIE__ != 1
> +# error "__PIE__ != 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..85c9ad9103f
> --- /dev/null
> +++ b/gcc/testsuite/c-c++-common/fhardened-8.c
> @@ -0,0 +1,7 @@
> +/* { dg-do compile { target { { *-*-linux* *-*-gnu* } && 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..4e4131f0bdd
> --- /dev/null
> +++ b/gcc/testsuite/c-c++-common/fhardened-9.c
> @@ -0,0 +1,9 @@
> +/* { dg-do compile { target *-*-linux* *-*-gnu* } } */
> +/* { 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.misc-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=^joined,^separate" "" "" ""
>  
> +check_for_options c "--help=hardened" "The following options are enabled 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/gcc.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 9a734890a18..841444d545c 100644
> --- a/gcc/toplev.cc
> +++ b/gcc/toplev.cc
> @@ -1567,6 +1567,13 @@ process_options ()
>        flag_associative_math = 0;
>      }
>  
> +  if (flag_hardened && !HAVE_FHARDENED_SUPPORT)
> +    {
> +      warning_at (UNKNOWN_LOCATION, 0,
> +               "%<-fhardened%> not supported for this target");
> +      flag_hardened = 0;
> +    }
> +
>    /* -fstack-clash-protection is not currently supported on targets
>       where the stack grows up.  */
>    if (flag_stack_clash_protection && !STACK_GROWS_DOWNWARD)
> @@ -1576,6 +1583,19 @@ process_options ()
>                 "where the stack grows from lower to higher addresses");
>        flag_stack_clash_protection = 0;
>      }
> +  else if (flag_hardened)
> +    {
> +      if (!flag_stack_clash_protection
> +        /* Don't enable -fstack-clash-protection when -fstack-check=
> +           is used: it would result in confusing errors.  */
> +        && flag_stack_check == NO_STACK_CHECK)
> +     flag_stack_clash_protection = 1;
> +      else if (flag_stack_check != 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= and -fstack-clash-protection at
>       the same time.  */
> @@ -1591,8 +1611,9 @@ process_options ()
>       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 = 0;
>      }
>    if (!flag_stack_protect)
> 
> base-commit: ae8abcb81ed81456c0fe5ff8e0c060c9fb9c82d7
> -- 
> 2.41.0
> 

Marek

Reply via email to