From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-ed1-x541.google.com (mail-ed1-x541.google.com [IPv6:2a00:1450:4864:20::541]) by sourceware.org (Postfix) with ESMTPS id E259A3858D35 for ; Mon, 27 Jul 2020 07:08:34 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org E259A3858D35 Received: by mail-ed1-x541.google.com with SMTP id c2so5469525edx.8 for ; Mon, 27 Jul 2020 00:08:34 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=tUg8YD+w7EYDxCkqnKWVXpDPhpnZd26CTN4RAJxsMBU=; b=StIS1DN8YMUMN/SBimI6bPehLi8pKiu4zUU2gbXRr14CdnTIYtChnXUhK1oowNrYIe aAqsoWZkQWxpT4JZFi093PLjD0S6C82e1LfpO9n08uza7Qc19jJvABnkPhMcvDQyz/Al WG6Rp3SZeUkSICLC5Ae/zVWZka9wu2wbAGRk9qAaQgZdvt+++K28q7skbJqpnoet/2i6 RVVhCb4EkE3TeRA6JER5C9kLyXuDIBZ1eqeuMJ3rbA9hed8s5KH2eJSHXTqguez/lpJb PdVJzHXlA47xdFivxsa/oRPm19H1TfEV1Y6N6ro416LnW9Qv8eFrWEFBRGBvGeSBGGmL voEQ== X-Gm-Message-State: AOAM533qR6SV/v3aXH+3zWJo7LMbHARxwLJYEUFAFQe2K6pLOkv56BtP zUPAlnC/H9OKIeT9gJK2GQRL6aF5pDeOu6RzLhGI01FK X-Google-Smtp-Source: ABdhPJx5s9fHHc+qRDTr5OyydQQsTKSEEnZInzRceps4LXM4/QkIquYrIOVSrnEm6T4wbmJ9mLh65raQrmO8QqUbA1E= X-Received: by 2002:aa7:c31a:: with SMTP id l26mr19264654edq.61.1595833713874; Mon, 27 Jul 2020 00:08:33 -0700 (PDT) MIME-Version: 1.0 References: <20200724211500.27499-1-hjl.tools@gmail.com> In-Reply-To: <20200724211500.27499-1-hjl.tools@gmail.com> From: Richard Biener Date: Mon, 27 Jul 2020 09:08:22 +0200 Message-ID: Subject: Re: [PATCH] LTO: Add -fcf-protection=check To: "H.J. Lu" Cc: GCC Patches Content-Type: text/plain; charset="UTF-8" X-Spam-Status: No, score=-7.3 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_FROM, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 27 Jul 2020 07:08:36 -0000 On Fri, Jul 24, 2020 at 11:15 PM H.J. Lu via Gcc-patches wrote: > > Mixing -fcf-protection and -fcf-protection=none objects are allowed. > Linker just merges -fcf-protection values from all input objects. > > Add -fcf-protection=check for the final link with LTO. An error is > issued if LTO object files are compiled with different -fcf-protection > values. Otherwise, -fcf-protection=check is ignored at the compile > time. Without explicit -fcf-protection at link time, -fcf-protection > values from LTO object files are merged at the final link. OK. Thanks, Richard. > gcc/ > > PR bootstrap/96203 > * common.opt: Add -fcf-protection=check. > * flag-types.h (cf_protection_level): Add CF_CHECK. > * lto-wrapper.c (merge_and_complain): Issue an error for > mismatching -fcf-protection values with -fcf-protection=check. > Otherwise, merge -fcf-protection values. > * doc/invoke.texi: Document -fcf-protection=check. > > gcc/testsuite/ > > PR bootstrap/96203 > * gcc.target/i386/pr96203-1.c: New test. > * gcc.target/i386/pr96203-2.c: Likewise. > --- > gcc/common.opt | 5 ++- > gcc/doc/invoke.texi | 9 ++++-- > gcc/flag-types.h | 3 +- > gcc/lto-wrapper.c | 39 +++++++++++++++++++---- > gcc/testsuite/gcc.target/i386/pr96203-1.c | 18 +++++++++++ > gcc/testsuite/gcc.target/i386/pr96203-2.c | 11 +++++++ > 6 files changed, 74 insertions(+), 11 deletions(-) > create mode 100644 gcc/testsuite/gcc.target/i386/pr96203-1.c > create mode 100644 gcc/testsuite/gcc.target/i386/pr96203-2.c > > diff --git a/gcc/common.opt b/gcc/common.opt > index a3893a4725e..47f42615bfa 100644 > --- a/gcc/common.opt > +++ b/gcc/common.opt > @@ -1776,7 +1776,7 @@ Common RejectNegative Alias(fcf-protection=,full) > > fcf-protection= > Common Report Joined RejectNegative Enum(cf_protection_level) Var(flag_cf_protection) Init(CF_NONE) > --fcf-protection=[full|branch|return|none] Instrument functions with checks to verify jump/call/return control-flow transfer > +-fcf-protection=[full|branch|return|none|check] Instrument functions with checks to verify jump/call/return control-flow transfer > instructions have valid targets. > > Enum > @@ -1791,6 +1791,9 @@ Enum(cf_protection_level) String(branch) Value(CF_BRANCH) > EnumValue > Enum(cf_protection_level) String(return) Value(CF_RETURN) > > +EnumValue > +Enum(cf_protection_level) String(check) Value(CF_CHECK) > + > EnumValue > Enum(cf_protection_level) String(none) Value(CF_NONE) > > diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi > index ba18e05fb1a..df84bce3a56 100644 > --- a/gcc/doc/invoke.texi > +++ b/gcc/doc/invoke.texi > @@ -559,7 +559,7 @@ Objective-C and Objective-C++ Dialects}. > -fsanitize=@var{style} -fsanitize-recover -fsanitize-recover=@var{style} @gol > -fasan-shadow-offset=@var{number} -fsanitize-sections=@var{s1},@var{s2},... @gol > -fsanitize-undefined-trap-on-error -fbounds-check @gol > --fcf-protection=@r{[}full@r{|}branch@r{|}return@r{|}none@r{]} @gol > +-fcf-protection=@r{[}full@r{|}branch@r{|}return@r{|}none@r{|}check@r{]} @gol > -fstack-protector -fstack-protector-all -fstack-protector-strong @gol > -fstack-protector-explicit -fstack-check @gol > -fstack-limit-register=@var{reg} -fstack-limit-symbol=@var{sym} @gol > @@ -14210,7 +14210,7 @@ operand constant, @code{__sanitizer_cov_trace_cmpf} or > @code{__sanitizer_cov_trace_cmpd} for float or double comparisons and > @code{__sanitizer_cov_trace_switch} for switch statements. > > -@item -fcf-protection=@r{[}full@r{|}branch@r{|}return@r{|}none@r{]} > +@item -fcf-protection=@r{[}full@r{|}branch@r{|}return@r{|}none@r{|}check@r{]} > @opindex fcf-protection > Enable code instrumentation of control-flow transfers to increase > program security by checking that target addresses of control-flow > @@ -14228,6 +14228,11 @@ function. The value @code{full} is an alias for specifying both > @code{branch} and @code{return}. The value @code{none} turns off > instrumentation. > > +The value @code{check} is used for the final link with link-time > +optimization (LTO). An error is issued if LTO object files are > +compiled with different @option{-fcf-protection} values. The > +value @code{check} is ignored at the compile time. > + > The macro @code{__CET__} is defined when @option{-fcf-protection} is > used. The first bit of @code{__CET__} is set to 1 for the value > @code{branch} and the second bit of @code{__CET__} is set to 1 for > diff --git a/gcc/flag-types.h b/gcc/flag-types.h > index b092c563f3d..852ea76eaa2 100644 > --- a/gcc/flag-types.h > +++ b/gcc/flag-types.h > @@ -368,7 +368,8 @@ enum cf_protection_level > CF_BRANCH = 1 << 0, > CF_RETURN = 1 << 1, > CF_FULL = CF_BRANCH | CF_RETURN, > - CF_SET = 1 << 2 > + CF_SET = 1 << 2, > + CF_CHECK = 1 << 3 > }; > > /* Parloops schedule type. */ > diff --git a/gcc/lto-wrapper.c b/gcc/lto-wrapper.c > index 5578b6d3200..e3b5cb2407a 100644 > --- a/gcc/lto-wrapper.c > +++ b/gcc/lto-wrapper.c > @@ -310,20 +310,45 @@ merge_and_complain (struct cl_decoded_option **decoded_options, > > case OPT_fcf_protection_: > /* Default to link-time option, else append or check identical. */ > - if (!cf_protection_option) > + if (!cf_protection_option > + || cf_protection_option->value == CF_CHECK) > { > for (j = 0; j < *decoded_options_count; ++j) > if ((*decoded_options)[j].opt_index == foption->opt_index) > break; > if (j == *decoded_options_count) > append_option (decoded_options, decoded_options_count, foption); > - else if (strcmp ((*decoded_options)[j].arg, foption->arg)) > - fatal_error (input_location, > - "option -fcf-protection with mismatching values" > - " (%s, %s)", > - (*decoded_options)[j].arg, foption->arg); > + else if ((*decoded_options)[j].value != foption->value) > + { > + if (cf_protection_option > + && cf_protection_option->value == CF_CHECK) > + fatal_error (input_location, > + "option -fcf-protection with mismatching values" > + " (%s, %s)", > + (*decoded_options)[j].arg, foption->arg); > + else > + { > + /* Merge and update the -fcf-protection option. */ > + (*decoded_options)[j].value &= (foption->value > + & CF_FULL); > + switch ((*decoded_options)[j].value) > + { > + case CF_NONE: > + (*decoded_options)[j].arg = "none"; > + break; > + case CF_BRANCH: > + (*decoded_options)[j].arg = "branch"; > + break; > + case CF_RETURN: > + (*decoded_options)[j].arg = "return"; > + break; > + default: > + gcc_unreachable (); > + } > + } > + } > } > - break; > + break; > > case OPT_O: > case OPT_Ofast: > diff --git a/gcc/testsuite/gcc.target/i386/pr96203-1.c b/gcc/testsuite/gcc.target/i386/pr96203-1.c > new file mode 100644 > index 00000000000..332911fc931 > --- /dev/null > +++ b/gcc/testsuite/gcc.target/i386/pr96203-1.c > @@ -0,0 +1,18 @@ > +/* { dg-do compile } */ > +/* { dg-options "-O2 -fcf-protection=check" } */ > +/* { dg-final { scan-assembler-not "endbr" } } */ > + > +extern int x; > + > +static void > +__attribute__ ((noinline, noclone)) > +test (int i) > +{ > + x = i; > +} > + > +void > +bar (int i) > +{ > + test (i); > +} > diff --git a/gcc/testsuite/gcc.target/i386/pr96203-2.c b/gcc/testsuite/gcc.target/i386/pr96203-2.c > new file mode 100644 > index 00000000000..1141cf2b51f > --- /dev/null > +++ b/gcc/testsuite/gcc.target/i386/pr96203-2.c > @@ -0,0 +1,11 @@ > +/* { dg-do compile } */ > +/* { dg-options "-O2 -fcf-protection=check -mmanual-endbr" } */ > +/* { dg-final { scan-assembler-not "endbr" } } */ > + > +extern void bar (void) __attribute__((__cf_check__)); > + > +void > +foo (void) > +{ > + bar (); > +} > -- > 2.26.2 >