This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
PING^2: [PATCH] i386; Add -mmanual-endbr and cf_check function attribute
- From: "H.J. Lu" <hjl dot tools at gmail dot com>
- To: Richard Guenther <richard dot guenther at gmail dot com>
- Cc: GCC Patches <gcc-patches at gcc dot gnu dot org>, Jakub Jelinek <jakub at redhat dot com>, Jeffrey Law <law at redhat dot com>, Jan Hubicka <hubicka at ucw dot cz>
- Date: Tue, 11 Dec 2018 08:03:00 -0800
- Subject: PING^2: [PATCH] i386; Add -mmanual-endbr and cf_check function attribute
- References: <20180615125949.GA114203@intel.com> <CAFiYyc28GR1ngBUqODN=Fs4gtu9sAWCVRaY+8e7GrNaeggqTRw@mail.gmail.com> <CAMe9rOp_feO7f_pODhSVcZa9AcQdY_LJAu4=PEzpTH8qPU66LA@mail.gmail.com>
On Mon, Dec 3, 2018 at 5:45 AM H.J. Lu <hjl.tools@gmail.com> wrote:
>
> On Mon, Jun 18, 2018 at 2:20 AM Richard Biener
> <richard.guenther@gmail.com> wrote:
> >
> > On Fri, Jun 15, 2018 at 2:59 PM H.J. Lu <hongjiu.lu@intel.com> wrote:
> > >
> > > Currently GCC inserts ENDBR instruction at entries of all non-static
> > > functions, unless LTO compilation is used. Marking all functions,
> > > which are not called indirectly with nocf_check attribute, is not
> > > ideal since 99% of functions in a program may be of this kind.
> > >
> > > This patch adds -mmanual-endbr and cf_check function attribute. They
> > > can be used together with -fcf-protection such that ENDBR instruction
> > > is inserted only at entries of functions with cf_check attribute. It
> > > can limit number of ENDBR instructions to reduce program size.
> > >
> > > OK for trubk?
> >
> > I wonder if the linker could assist with ENDBR creation by
> > redirecting all non-direct call relocs to a linker-generated
> > stub with ENBR and a direct branch?
> >
>
> The goal of this patch is to add as few as ENDBR as possible
> to reduce program size as much as possible. Also there is no
> relocation for indirect branch via register.
>
Hi Honza, Jakub, Jeff, Richard,
Here is the rebased patch. Can you guys take a look?
Thanks.
--
H.J.
From 5934c6be6495b2d6f278646e25f9e684f6610e2b Mon Sep 17 00:00:00 2001
From: "H.J. Lu" <hjl.tools@gmail.com>
Date: Thu, 14 Jun 2018 09:19:27 -0700
Subject: [PATCH] i386; Add -mmanual-endbr and cf_check function attribute
Currently GCC inserts ENDBR instruction at entries of all non-static
functions, unless LTO compilation is used. Marking all functions,
which are not called indirectly with nocf_check attribute, is not
ideal since 99% of functions in a program may be of this kind.
This patch adds -mmanual-endbr and cf_check function attribute. They
can be used together with -fcf-protection such that ENDBR instruction
is inserted only at entries of functions with cf_check attribute. It
can limit number of ENDBR instructions to reduce program size.
gcc/
* config/i386/i386.c (rest_of_insert_endbranch): Insert ENDBR
at the function entry only when -mmanual-endbr isn't used or
there is cf_check function attribute.
(ix86_attribute_table): Add cf_check.
* config/i386/i386.opt: Add -mmanual-endbr.
* doc/extend.texi: Document cf_check attribute.
* doc/invoke.texi: Document -mmanual-endbr.
gcc/testsuite/
* gcc.target/i386/cf_check-1.c: New test.
* gcc.target/i386/cf_check-2.c: Likewise.
* gcc.target/i386/cf_check-3.c: Likewise.
* gcc.target/i386/cf_check-4.c: Likewise.
* gcc.target/i386/cf_check-5.c: Likewise.
---
gcc/config/i386/i386.c | 6 ++++++
gcc/config/i386/i386.opt | 5 +++++
gcc/doc/extend.texi | 7 +++++++
gcc/doc/invoke.texi | 9 ++++++++-
gcc/testsuite/gcc.target/i386/cf_check-1.c | 11 +++++++++++
gcc/testsuite/gcc.target/i386/cf_check-2.c | 11 +++++++++++
gcc/testsuite/gcc.target/i386/cf_check-3.c | 11 +++++++++++
gcc/testsuite/gcc.target/i386/cf_check-4.c | 10 ++++++++++
gcc/testsuite/gcc.target/i386/cf_check-5.c | 9 +++++++++
9 files changed, 78 insertions(+), 1 deletion(-)
create mode 100644 gcc/testsuite/gcc.target/i386/cf_check-1.c
create mode 100644 gcc/testsuite/gcc.target/i386/cf_check-2.c
create mode 100644 gcc/testsuite/gcc.target/i386/cf_check-3.c
create mode 100644 gcc/testsuite/gcc.target/i386/cf_check-4.c
create mode 100644 gcc/testsuite/gcc.target/i386/cf_check-5.c
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 3e2fdfa86ff..b05c538c097 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -2638,6 +2638,9 @@ rest_of_insert_endbranch (void)
if (!lookup_attribute ("nocf_check",
TYPE_ATTRIBUTES (TREE_TYPE (cfun->decl)))
+ && (!flag_manual_endbr
+ || lookup_attribute ("cf_check",
+ DECL_ATTRIBUTES (cfun->decl)))
&& !cgraph_node::get (cfun->decl)->only_called_directly_p ())
{
/* Queue ENDBR insertion to x86_function_profiler. */
@@ -45246,6 +45249,9 @@ static const struct attribute_spec ix86_attribute_table[] =
ix86_handle_fentry_name, NULL },
{ "fentry_section", 1, 1, true, false, false, false,
ix86_handle_fentry_name, NULL },
+ { "cf_check", 0, 0, true, false, false, false,
+ ix86_handle_fndecl_attribute, NULL },
+
/* End element. */
{ NULL, 0, 0, false, false, false, false, NULL, NULL }
};
diff --git a/gcc/config/i386/i386.opt b/gcc/config/i386/i386.opt
index b30b55b7826..007e88b57f9 100644
--- a/gcc/config/i386/i386.opt
+++ b/gcc/config/i386/i386.opt
@@ -1028,6 +1028,11 @@ Target Report Undocumented Var(flag_cet_switch) Init(0)
Turn on CET instrumentation for switch statements that use a jump table and
an indirect jump.
+mmanual-endbr
+Target Report Var(flag_manual_endbr) Init(0)
+Insert ENDBR instruction at function entry only via cf_check attribute
+for CET instrumentation.
+
mforce-indirect-call
Target Report Var(flag_force_indirect_call) Init(0)
Make all function calls indirect.
diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index 8c9e0fa544b..9523626e4f7 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -6019,6 +6019,13 @@ foo (void)
@}
@end smallexample
+@item cf_check
+@cindex @code{cf_check} function attribute, x86
+
+The @code{cf_check} attribute on a function is used to inform the
+compiler that ENDBR instruction should be placed at the function
+entry when @option{-fcf-protection=branch} is enabled.
+
@item indirect_return
@cindex @code{indirect_return} function attribute, x86
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 3b6912ea1cc..089e5125520 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -1302,7 +1302,7 @@ See RS/6000 and PowerPC Options.
-msse4a -m3dnow -m3dnowa -mpopcnt -mabm -mbmi -mtbm -mfma4 -mxop @gol
-mlzcnt -mbmi2 -mfxsr -mxsave -mxsaveopt -mrtm -mlwp @gol
-mmwaitx -mclzero -mpku -mthreads -mgfni -mvaes -mwaitpkg @gol
--mshstk -mforce-indirect-call -mavx512vbmi2 @gol
+-mshstk -mmanual-endbr -mforce-indirect-call -mavx512vbmi2 @gol
-mvpclmulqdq -mavx512bitalg -mmovdiri -mmovdir64b -mavx512vpopcntdq @gol
-mcldemote -mms-bitfields -mno-align-stringops -minline-all-stringops @gol
-minline-stringops-dynamically -mstringop-strategy=@var{alg} @gol
@@ -28792,6 +28792,13 @@ Force all calls to functions to be indirect. This is useful
when using Intel Processor Trace where it generates more precise timing
information for function calls.
+@item -mmanual-endbr
+@opindex mmanual-endbr
+Insert ENDBR instruction at function entry only via the @code{cf_check}
+function attribute. This is useful when used with the option
+@option{-fcf-protection=branch} to control ENDBR insertion at the
+function entry.
+
@item -mcall-ms2sysv-xlogues
@opindex mcall-ms2sysv-xlogues
@opindex mno-call-ms2sysv-xlogues
diff --git a/gcc/testsuite/gcc.target/i386/cf_check-1.c b/gcc/testsuite/gcc.target/i386/cf_check-1.c
new file mode 100644
index 00000000000..c433eab854a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/cf_check-1.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fcf-protection -mmanual-endbr" } */
+/* { dg-final { scan-assembler-not {\mendbr} } } */
+
+extern void bar (void) __attribute__((__cf_check__));
+
+void
+foo (void)
+{
+ bar ();
+}
diff --git a/gcc/testsuite/gcc.target/i386/cf_check-2.c b/gcc/testsuite/gcc.target/i386/cf_check-2.c
new file mode 100644
index 00000000000..e2b9c4dbcb2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/cf_check-2.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fcf-protection -mno-manual-endbr" } */
+/* { dg-final { scan-assembler-times {\mendbr} 1 } } */
+
+extern void bar (void) __attribute__((__cf_check__));
+
+void
+foo (void)
+{
+ bar ();
+}
diff --git a/gcc/testsuite/gcc.target/i386/cf_check-3.c b/gcc/testsuite/gcc.target/i386/cf_check-3.c
new file mode 100644
index 00000000000..d835cc3a21b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/cf_check-3.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fcf-protection=none" } */
+/* { dg-final { scan-assembler-not {\mendbr} } } */
+
+extern void bar (void) __attribute__((__cf_check__));
+
+void
+foo (void)
+{
+ bar ();
+}
diff --git a/gcc/testsuite/gcc.target/i386/cf_check-4.c b/gcc/testsuite/gcc.target/i386/cf_check-4.c
new file mode 100644
index 00000000000..d6cb27cf20b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/cf_check-4.c
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fcf-protection -mmanual-endbr" } */
+/* { dg-final { scan-assembler-times {\mendbr} 1 } } */
+
+extern void foo (void) __attribute__((__cf_check__));
+
+void
+foo (void)
+{
+}
diff --git a/gcc/testsuite/gcc.target/i386/cf_check-5.c b/gcc/testsuite/gcc.target/i386/cf_check-5.c
new file mode 100644
index 00000000000..f2c0c5c2c09
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/cf_check-5.c
@@ -0,0 +1,9 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fcf-protection -mmanual-endbr" } */
+/* { dg-final { scan-assembler-times {\mendbr} 1 } } */
+
+__attribute__((__cf_check__))
+void
+foo (void)
+{
+}
--
2.19.2