x86; 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.

From-SVN: r267154
This commit is contained in:
H.J. Lu 2018-12-14 21:35:36 +00:00 committed by H.J. Lu
parent c759830b29
commit 06553c89f5
11 changed files with 96 additions and 1 deletions

View 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> 2018-12-14 Thomas Schwinge <thomas@codesourcery.com>
Cesar Philippidis <cesar@codesourcery.com> Cesar Philippidis <cesar@codesourcery.com>

View File

@ -2640,6 +2640,9 @@ rest_of_insert_endbranch (void)
if (!lookup_attribute ("nocf_check", if (!lookup_attribute ("nocf_check",
TYPE_ATTRIBUTES (TREE_TYPE (cfun->decl))) 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 ()) && !cgraph_node::get (cfun->decl)->only_called_directly_p ())
{ {
/* Queue ENDBR insertion to x86_function_profiler. */ /* Queue ENDBR insertion to x86_function_profiler. */
@ -45260,6 +45263,9 @@ static const struct attribute_spec ix86_attribute_table[] =
ix86_handle_fentry_name, NULL }, ix86_handle_fentry_name, NULL },
{ "fentry_section", 1, 1, true, false, false, false, { "fentry_section", 1, 1, true, false, false, false,
ix86_handle_fentry_name, NULL }, ix86_handle_fentry_name, NULL },
{ "cf_check", 0, 0, true, false, false, false,
ix86_handle_fndecl_attribute, NULL },
/* End element. */ /* End element. */
{ NULL, 0, 0, false, false, false, false, NULL, NULL } { NULL, 0, 0, false, false, false, false, NULL, NULL }
}; };

View 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 Turn on CET instrumentation for switch statements that use a jump table and
an indirect jump. 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 mforce-indirect-call
Target Report Var(flag_force_indirect_call) Init(0) Target Report Var(flag_force_indirect_call) Init(0)
Make all function calls indirect. Make all function calls indirect.

View File

@ -6095,6 +6095,13 @@ foo (void)
@} @}
@end smallexample @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 @item indirect_return
@cindex @code{indirect_return} function attribute, x86 @cindex @code{indirect_return} function attribute, x86

View File

@ -1263,7 +1263,7 @@ See RS/6000 and PowerPC Options.
-msse4a -m3dnow -m3dnowa -mpopcnt -mabm -mbmi -mtbm -mfma4 -mxop @gol -msse4a -m3dnow -m3dnowa -mpopcnt -mabm -mbmi -mtbm -mfma4 -mxop @gol
-mlzcnt -mbmi2 -mfxsr -mxsave -mxsaveopt -mrtm -mlwp @gol -mlzcnt -mbmi2 -mfxsr -mxsave -mxsaveopt -mrtm -mlwp @gol
-mmwaitx -mclzero -mpku -mthreads -mgfni -mvaes -mwaitpkg @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 -mvpclmulqdq -mavx512bitalg -mmovdiri -mmovdir64b -mavx512vpopcntdq @gol
-mcldemote -mms-bitfields -mno-align-stringops -minline-all-stringops @gol -mcldemote -mms-bitfields -mno-align-stringops -minline-all-stringops @gol
-minline-stringops-dynamically -mstringop-strategy=@var{alg} @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 when using Intel Processor Trace where it generates more precise timing
information for function calls. 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 @item -mcall-ms2sysv-xlogues
@opindex mcall-ms2sysv-xlogues @opindex mcall-ms2sysv-xlogues
@opindex mno-call-ms2sysv-xlogues @opindex mno-call-ms2sysv-xlogues

View 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> 2018-12-14 Thomas Schwinge <thomas@codesourcery.com>
Cesar Philippidis <cesar@codesourcery.com> Cesar Philippidis <cesar@codesourcery.com>

View File

@ -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 ();
}

View File

@ -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 ();
}

View File

@ -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 ();
}

View File

@ -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)
{
}

View File

@ -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)
{
}