When -fcf-protection=branch is used, the compiler will generate jump
tables where the indirect jump is prefixed with the NOTRACK prefix, so
it can jump to non-ENDBR targets. Yet, for NOTRACK prefixes to work, the
NOTRACK specific enable bit must be set, what renders the binary broken
on any environment where this is not the case. In fact, having NOTRACK
disabled was a design choice for the Linux kernel CET support.

Generate jump tables with ENDBR and skip the NOTRACK prefix for indirect
jump.  Document -mno-cet-switch to turn off CET instrumentation on jump
tables for switch statements.

gcc/

        PR target/104816
        * config/i386/i386.opt: Turn on -mcet-switch by default.
        * doc/invoke.texi: Document -mno-cet-switch.

gcc/testsuite/

        * gcc.target/i386/cet-switch-1.c: Add -mno-cet-switch.
        * gcc.target/i386/cet-switch-2.c: Remove -mcet-switch.
        * gcc.target/i386/cet-switch-3.c: Likewise.
---
 gcc/config/i386/i386.opt                     | 2 +-
 gcc/doc/invoke.texi                          | 9 ++++++++-
 gcc/testsuite/gcc.target/i386/cet-switch-1.c | 2 +-
 gcc/testsuite/gcc.target/i386/cet-switch-2.c | 2 +-
 gcc/testsuite/gcc.target/i386/cet-switch-3.c | 2 +-
 5 files changed, 12 insertions(+), 5 deletions(-)

diff --git a/gcc/config/i386/i386.opt b/gcc/config/i386/i386.opt
index a6b0e28f238..96b4a433e44 100644
--- a/gcc/config/i386/i386.opt
+++ b/gcc/config/i386/i386.opt
@@ -1047,7 +1047,7 @@ Enable shadow stack built-in functions from Control-flow 
Enforcement
 Technology (CET).
 
 mcet-switch
-Target Undocumented Var(flag_cet_switch) Init(0)
+Target Var(flag_cet_switch) Init(1)
 Turn on CET instrumentation for switch statements that use a jump table and
 an indirect jump.
 
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 7a35d9613a4..8bb96c5938a 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -1420,7 +1420,8 @@ See RS/6000 and PowerPC Options.
 -msse4a  -m3dnow  -m3dnowa  -mpopcnt  -mabm  -mbmi  -mtbm  -mfma4  -mxop @gol
 -madx  -mlzcnt  -mbmi2  -mfxsr  -mxsave  -mxsaveopt  -mrtm  -mhle  -mlwp @gol
 -mmwaitx  -mclzero  -mpku  -mthreads  -mgfni  -mvaes  -mwaitpkg @gol
--mshstk -mmanual-endbr -mforce-indirect-call  -mavx512vbmi2 -mavx512bf16 
-menqcmd @gol
+-mshstk -mmanual-endbr -mno-cet-switch -mforce-indirect-call @gol
+-mavx512vbmi2 -mavx512bf16 -menqcmd @gol
 -mvpclmulqdq  -mavx512bitalg  -mmovdiri  -mmovdir64b  -mavx512vpopcntdq @gol
 -mavx5124fmaps  -mavx512vnni  -mavx5124vnniw  -mprfchw  -mrdpid @gol
 -mrdseed  -msgx -mavx512vp2intersect -mserialize -mtsxldtrk@gol
@@ -32641,6 +32642,12 @@ function attribute. This is useful when used with the 
option
 @option{-fcf-protection=branch} to control ENDBR insertion at the
 function entry.
 
+@item -mno-cet-switch
+@opindex mno-cet-switch
+@opindex mcet-switch
+Turn off CET instrumentation for switch statements that use a jump table
+and an indirect jump.  The default is @option{mcet-switch}.
+
 @item -mcall-ms2sysv-xlogues
 @opindex mcall-ms2sysv-xlogues
 @opindex mno-call-ms2sysv-xlogues
diff --git a/gcc/testsuite/gcc.target/i386/cet-switch-1.c 
b/gcc/testsuite/gcc.target/i386/cet-switch-1.c
index afe5adc2f3d..4931c3ad1d2 100644
--- a/gcc/testsuite/gcc.target/i386/cet-switch-1.c
+++ b/gcc/testsuite/gcc.target/i386/cet-switch-1.c
@@ -1,6 +1,6 @@
 /* Verify that CET works.  */
 /* { dg-do compile } */
-/* { dg-options "-O -fcf-protection" } */
+/* { dg-options "-O -fcf-protection -mno-cet-switch" } */
 /* { dg-final { scan-assembler-times "endbr32" 1 { target ia32 } } } */
 /* { dg-final { scan-assembler-times "endbr64" 1 { target { ! ia32 } } } } */
 /* { dg-final { scan-assembler-times "notrack jmp\[ \t]+\[*]" 1 } } */
diff --git a/gcc/testsuite/gcc.target/i386/cet-switch-2.c 
b/gcc/testsuite/gcc.target/i386/cet-switch-2.c
index 69ddc6fd5b7..11578d1a30c 100644
--- a/gcc/testsuite/gcc.target/i386/cet-switch-2.c
+++ b/gcc/testsuite/gcc.target/i386/cet-switch-2.c
@@ -1,6 +1,6 @@
 /* Verify that CET works.  */
 /* { dg-do compile } */
-/* { dg-options "-O -fcf-protection -mcet-switch" } */
+/* { dg-options "-O -fcf-protection" } */
 /* { dg-final { scan-assembler-times "endbr32" 12 { target ia32 } } } */
 /* { dg-final { scan-assembler-times "endbr64" 12 { target { ! ia32 } } } } */
 /* { dg-final { scan-assembler-times "\[ \t]+jmp\[ \t]+\[*]" 1 } } */
diff --git a/gcc/testsuite/gcc.target/i386/cet-switch-3.c 
b/gcc/testsuite/gcc.target/i386/cet-switch-3.c
index 0d9ed4488dd..a4e2e4dfc16 100644
--- a/gcc/testsuite/gcc.target/i386/cet-switch-3.c
+++ b/gcc/testsuite/gcc.target/i386/cet-switch-3.c
@@ -1,6 +1,6 @@
 /* Verify that CET works.  */
 /* { dg-do compile } */
-/* { dg-options "-O -fcf-protection -mcet-switch" } */
+/* { dg-options "-O -fcf-protection" } */
 /* { dg-final { scan-assembler-times "endbr32" 12 { target ia32 } } } */
 /* { dg-final { scan-assembler-times "endbr64" 12 { target { ! ia32 } } } } */
 /* { dg-final { scan-assembler-times "\[ \t]+jmp\[ \t]+\[*]" 1 } } */
-- 
2.35.1

Reply via email to