Richard Biener <richard.guent...@gmail.com> writes:

> On Wed, Oct 11, 2023 at 10:48 PM Marek Polacek <pola...@redhat.com> 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 PM Marek Polacek via Gcc-patches
>> > > <gcc-patches@gcc.gnu.org> wrote:
>> > > >
>> > > > Bootstrapped/regtested on x86_64-pc-linux-gnu, 
>> > > > powerpc64le-unknown-linux-gnu,
>> > > > and aarch64-unknown-linux-gnu; ok for trunk?
>> > > >
>> > > > -- >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=pattern
>
> I think =zero is much better here given the overhead is way
> cheaper and pointers get a more reliable behavior.

Yes please, as I wouldn't want us to use =pattern distro-wide.

>
>> > > >   -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.
>> > > >
>> > > > 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 actually
>> > > > enables.
>> > >
>> > > I do think we need to find a solution here to solve asserting compliance.
>> >
>> > Fair enough.
>> >
>> > > Maybe we can have -Whardened that will diagnose any altering of
>> > > -fhardened by other options on the command-line or by missed target
>> > > implementations?  People might for example use -fstack-protector
>> > > but don't really want to make protection lower than requested with 
>> > > -fhardened.
>> > >
>> > > Any such conflict is much less appearant than when you use the
>> > > flags -fhardened composes.
>> >
>> > How about: --help=hardened 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=hardened probably doesn't even have to
>> > list -z now, likewise for -z relro.
>> >
>> > Unclear if -Whardened should be enabled by default, but probably yes?
>>
>> 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.  Can you see how our
> primary and secondary targets (+ host OS) behave here?  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?
>
> Thanks,
> Richard.
>
>>
>> -- >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=pattern
>>   -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.
>>
>> 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'.
>>         * 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=pattern 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.
>>
>> 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                        | 44 +++++++++++++-
>>  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, 503 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 = 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 f137a1f81ac..60c13b9ffd2 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.
>> @@ -1827,6 +1831,10 @@ fharden-conditional-branches
>>  Common Var(flag_harden_conditional_branches) Optimization
>>  Harden conditional branches by checking reversed conditions.
>>
>> +fhardened
>> +Common Driver Var(flag_hardened)
>> +Enable various security-relevant flags.
>> +
>>  ; Nonzero means ignore `#ident' directives.  0 means handle them.
>>  ; Generate position-independent code for executables if possible
>>  ; On SVR4 targets, it also controls whether or not to emit a
>> diff --git a/gcc/config.in b/gcc/config.in
>> index d04718ad128..faa941c1385 100644
>> --- a/gcc/config.in
>> +++ b/gcc/config.in
>> @@ -1676,6 +1676,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
>> @@ -1719,6 +1725,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 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 = 0;
>>      }
>>
>> diff --git a/gcc/config/i386/i386-options.cc 
>> b/gcc/config/i386/i386-options.cc
>> index 06af373ca57..22ede9e15b5 100644
>> --- a/gcc/config/i386/i386-options.cc
>> +++ b/gcc/config/i386/i386-options.cc
>> @@ -3061,10 +3061,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 c43bde8174b..e2aac56edf6 100755
>> --- a/gcc/configure
>> +++ b/gcc/configure
>> @@ -32713,7 +32713,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
>> @@ -32842,6 +32842,54 @@ $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; }
>> +
>>  # Configure the subdirectories
>>  # AC_CONFIG_SUBDIRS($subdirs)
>>
>> diff --git a/gcc/configure.ac b/gcc/configure.ac
>> index fb8e32f8ee5..6a090ccf3bd 100644
>> --- a/gcc/configure.ac
>> +++ b/gcc/configure.ac
>> @@ -7678,7 +7678,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
>> @@ -7779,6 +7779,46 @@ 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)
>> +
>>  # Configure the subdirectories
>>  # AC_CONFIG_SUBDIRS($subdirs)
>>
>> diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
>> index 7c5f81d9783..48e6a3f433c 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
>> @@ -640,7 +640,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
>>  -fstack-protector  -fstack-protector-all  -fstack-protector-strong
>>  -fstack-protector-explicit  -fstack-check
>>  -fstack-limit-register=@var{reg}  -fstack-limit-symbol=@var{sym}
>> @@ -6842,6 +6842,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
>> @@ -17427,6 +17439,34 @@ condition, and to call @code{__builtin_trap} if the 
>> result is
>>  unexpected.  Use with @samp{-fharden-compares} to cover all
>>  conditionals.
>>
>> +@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=pattern
>> +-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.
>> +
>> +@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 c6e600fa0d3..ed4e2400e91 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.  */
>> @@ -4601,10 +4608,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:
>> @@ -4980,6 +4997,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 573dcf8e497..8265c5b3c1b 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_PATTERN;
>> +      else if (opts->x_flag_auto_var_init != AUTO_INIT_PATTERN)
>> +       warning_at (loc, OPT_Whardened,
>> +                   "%<-ftrivial-auto-var-init=pattern%> 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=pattern");
>> +#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..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__ != 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=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..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__ != 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 .-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..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 <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..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..a757cbf0d12
>> --- /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=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=pattern. 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..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__ != 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..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.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 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 = 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.  */
>> @@ -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 = 0;
>>      }
>>    if (!flag_stack_protect)
>>
>> base-commit: e8d418df3dc609f27487deece796d4aa69004b8c
>> --
>> 2.41.0
>>


Reply via email to