x86; Add -mmanual-endbr and cf_check function attribute
authorH.J. Lu <hongjiu.lu@intel.com>
Fri, 14 Dec 2018 21:35:36 +0000 (21:35 +0000)
committerH.J. Lu <hjl@gcc.gnu.org>
Fri, 14 Dec 2018 21:35:36 +0000 (13:35 -0800)
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.

From-SVN: r267154

gcc/ChangeLog
gcc/config/i386/i386.c
gcc/config/i386/i386.opt
gcc/doc/extend.texi
gcc/doc/invoke.texi
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/i386/cf_check-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/cf_check-2.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/cf_check-3.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/cf_check-4.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/cf_check-5.c [new file with mode: 0644]

index 7fb4958da485133fc1143122e7285980f3653e7f..a612dad682f22cef370cc43a0b419d3c8e451ed2 100644 (file)
@@ -1,3 +1,13 @@
+2018-12-14  H.J. Lu  <hongjiu.lu@intel.com>
+
+       * 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.
+
 2018-12-14  Thomas Schwinge  <thomas@codesourcery.com>
            Cesar Philippidis  <cesar@codesourcery.com>
 
index edc8f4f092eb14d5a71df54d76e7bfaae246677e..4599ca2a7d5932daf47bc16bb4ac8d7aaf8779f1 100644 (file)
@@ -2640,6 +2640,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.  */
@@ -45260,6 +45263,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 }
 };
index b30b55b782630115d678930fa8347b9a3f17cc88..007e88b57f9e48f085ceddd936442b9d914d677b 100644 (file)
@@ -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.
index 3889ecb543191650296884a2ae693091fa3312bf..8f3a21cfb271f16ef925c26d3166ccbe203518e2 100644 (file)
@@ -6095,6 +6095,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
 
index 44e1069de3b4c6904e9f494745cf8aaa0d29cd27..9a14170d084bd6c0e98783e4e9a7a5b256af2bfc 100644 (file)
@@ -1263,7 +1263,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
@@ -27968,6 +27968,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
index 6b035b34ecfd982fc1aa8b7a9119087a43d04035..a0879161104dc29ff11b9efeeb494499f7d18978 100644 (file)
@@ -1,3 +1,11 @@
+2018-12-14  H.J. Lu  <hongjiu.lu@intel.com>
+
+       * 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.
+
 2018-12-14  Thomas Schwinge  <thomas@codesourcery.com>
            Cesar Philippidis  <cesar@codesourcery.com>
 
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 (file)
index 0000000..c433eab
--- /dev/null
@@ -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 (file)
index 0000000..e2b9c4d
--- /dev/null
@@ -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 (file)
index 0000000..d835cc3
--- /dev/null
@@ -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 (file)
index 0000000..d6cb27c
--- /dev/null
@@ -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 (file)
index 0000000..f2c0c5c
--- /dev/null
@@ -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)
+{
+}