https://bugs.gentoo.org/822036
https://salsa.debian.org/toolchain-team/gcc/-/blob/master/debian/patches/gcc-distro-specs.diff

From: Sam James <sam@gentoo.org>
Subject: [PATCH] Enable CET (-fcf-protection=full) by default

Needs:
- CET to be enabled for GCC
- -DEXTRA_OPTIONS_CF to be passed during build (via toolchain.eclass).

  Only supported on amd64.
--- a/gcc/cp/lang-specs.h
+++ b/gcc/cp/lang-specs.h
@@ -51,7 +51,7 @@ along with GCC; see the file COPYING3.  If not see
       " 	   %{save-temps*:%b.ii} %{!save-temps*:%g.ii}}"
       "  %{!save-temps*:%{!no-integrated-cpp:%(cpp_unique_options)}}"
       "  %{fmodules-ts:-fmodule-header %{fpreprocessed:-fdirectives-only}}"
-      "  %(cc1_options) %2"
+      "  %(cc1_options) %(default_flag_cf_spec) %2"
       "  %{!fsyntax-only:"
       "    %{!S:-o %g.s%V}"
       "    %{!fmodule-*:%{!fmodules-*:%{!fdump-ada-spec*:"
@@ -72,7 +72,7 @@ along with GCC; see the file COPYING3.  If not see
       "  %{!save-temps*:%{!no-integrated-cpp:%(cpp_unique_options)}}"
       "  %{fmodules-ts:-fmodule-header=system"
       "    %{fpreprocessed:-fdirectives-only}}"
-      "  %(cc1_options) %2"
+      "  %(cc1_options) %(default_flag_cf_spec) %2"
       "  %{!fsyntax-only:"
       "    %{!S:-o %g.s%V}"
       "    %{!fmodule-*:%{!fmodules-*:%{!fdump-ada-spec*:"
@@ -92,7 +92,7 @@ along with GCC; see the file COPYING3.  If not see
       " 	   %{save-temps*:%b.ii} %{!save-temps*:%g.ii}}"
       "  %{!save-temps*:%{!no-integrated-cpp:%(cpp_unique_options)}}"
       "  %{fmodules-ts:-fmodule-header=user %{fpreprocessed:-fdirectives-only}}"
-      "  %(cc1_options) %2"
+      "  %(cc1_options) %(default_flag_cf_spec) %2"
       "  %{!fsyntax-only:"
       "    %{!S:-o %g.s%V}"
       "    %{!fmodule-*:%{!fmodules-*:%{!fdump-ada-spec*:"
@@ -107,7 +107,7 @@ along with GCC; see the file COPYING3.  If not see
       "  cc1plus %{save-temps*|no-integrated-cpp:-fpreprocessed"
       " 	   %{save-temps*:%b.ii} %{!save-temps*:%g.ii}}"
       "  %{!save-temps*:%{!no-integrated-cpp:%(cpp_unique_options)}}"
-      "  %(cc1_options) %2"
+      "  %(cc1_options) %(default_flag_cf_spec) %2"
       "  %{!fsyntax-only:"
       "    %{fmodule-only:%{!S:-o %g.s%V}}"
       "    %{!fmodule-only:%(invoke_as)}}"
@@ -116,7 +116,7 @@ along with GCC; see the file COPYING3.  If not see
   {".ii", "@c++-cpp-output", 0, 0, 0},
   {"@c++-cpp-output",
       "%{!E:%{!M:%{!MM:"
-      "  cc1plus -fpreprocessed %i %(cc1_options) %2"
+      "  cc1plus -fpreprocessed %i %(cc1_options) %(default_flag_cf_spec) %2"
       "  %{!fsyntax-only:"
       "    %{fmodule-only:%{!S:-o %g.s%V}}"
       "    %{!fmodule-only:%{!fmodule-header*:%(invoke_as)}}}"
--- a/gcc/gcc.cc
+++ b/gcc/gcc.cc
@@ -1007,6 +1007,18 @@ proper position among the other output files.  */
 #define LINK_NOW_SPEC ""
 #endif
 
+/* Default value for flag_cf_protection when flag_cf_protection is
+   initialized to CF_FULL.
+
+   We use a new option (EXTRA_OPTIONS_CF) here to avoid turning
+   this on accidentally for other arches. */
+#ifdef EXTRA_OPTIONS_CF
+#define DEFAULT_FLAG_CF_SPEC " %{!m16:%{!m32:%{!fcf-protection*:%{!fno-cf-protection:-fcf-protection}}}}"
+#endif
+#ifndef DEFAULT_FLAG_CF_SPEC
+#define DEFAULT_FLAG_CF_SPEC ""
+#endif
+
 #ifdef ENABLE_DEFAULT_PIE
 #define PIE_SPEC		"!no-pie"
 #define NO_FPIE1_SPEC		"fno-pie"
@@ -1209,6 +1221,7 @@ static const char *cpp_spec = CPP_SPEC;
 static const char *cc1_spec = CC1_SPEC;
 static const char *cc1plus_spec = CC1PLUS_SPEC;
 static const char *link_gcc_c_sequence_spec = LINK_GCC_C_SEQUENCE_SPEC;
+static const char *default_flag_cf_spec = DEFAULT_FLAG_CF_SPEC;
 static const char *link_ssp_spec = LINK_SSP_SPEC;
 static const char *asm_spec = ASM_SPEC;
 static const char *asm_final_spec = ASM_FINAL_SPEC;
@@ -1267,7 +1280,7 @@ static const char *cpp_options =
 "%(cpp_unique_options) %1 %{m*} %{std*&ansi&trigraphs} %{W*&pedantic*} %{w}\
  %{f*} %{g*:%{%:debug-level-gt(0):%{g*}\
  %{!fno-working-directory:-fworking-directory}}} %{O*}\
- %{undef} %{save-temps*:-fpch-preprocess}";
+ %{undef} %{save-temps*:-fpch-preprocess} %(default_flag_cf_spec)";
 
 /* Pass -d* flags, possibly modifying -dumpdir, -dumpbase et al.
 
@@ -1456,9 +1469,9 @@ static const struct compiler default_compilers[] =
       %{save-temps*|traditional-cpp|no-integrated-cpp:%(trad_capable_cpp) \
 	  %(cpp_options) -o %{save-temps*:%b.i} %{!save-temps*:%g.i} \n\
 	    cc1 -fpreprocessed %{save-temps*:%b.i} %{!save-temps*:%g.i} \
-	  %(cc1_options)}\
+	  %(cc1_options)%(default_flag_cf_spec)}\
       %{!save-temps*:%{!traditional-cpp:%{!no-integrated-cpp:\
-	  cc1 %(cpp_unique_options) %(cc1_options)}}}\
+	  cc1 %(cpp_unique_options) %(cc1_options) %(default_flag_cf_spec)}}}\
       %{!fsyntax-only:%(invoke_as)}}}}", 0, 0, 1},
   {"-",
    "%{!E:%e-E or -x required when input is from standard input}\
@@ -1472,18 +1485,18 @@ static const struct compiler default_compilers[] =
 	  %{save-temps*|traditional-cpp|no-integrated-cpp:%(trad_capable_cpp) \
 		%(cpp_options) -o %{save-temps*:%b.i} %{!save-temps*:%g.i} \n\
 		    cc1 -fpreprocessed %{save-temps*:%b.i} %{!save-temps*:%g.i} \
-			%(cc1_options)\
+			%(cc1_options) %(default_flag_cf_spec)\
 			%{!fsyntax-only:%{!S:-o %g.s} \
 			    %{!fdump-ada-spec*:%{!o*:--output-pch=%i.gch}\
 					       %W{o*:--output-pch=%*}}%V}}\
 	  %{!save-temps*:%{!traditional-cpp:%{!no-integrated-cpp:\
-		cc1 %(cpp_unique_options) %(cc1_options)\
+		cc1 %(cpp_unique_options) %(cc1_options) %(default_flag_cf_spec)\
 		    %{!fsyntax-only:%{!S:-o %g.s} \
 		        %{!fdump-ada-spec*:%{!o*:--output-pch=%i.gch}\
 					   %W{o*:--output-pch=%*}}%V}}}}}}}", 0, 0, 0},
   {".i", "@cpp-output", 0, 0, 0},
   {"@cpp-output",
-   "%{!M:%{!MM:%{!E:cc1 -fpreprocessed %i %(cc1_options) %{!fsyntax-only:%(invoke_as)}}}}", 0, 0, 0},
+   "%{!M:%{!MM:%{!E:cc1 -fpreprocessed %i %(cc1_options) %(default_flag_cf_spec) %{!fsyntax-only:%(invoke_as)}}}}", 0, 0, 0},
   {".s", "@assembler", 0, 0, 0},
   {"@assembler",
    "%{!M:%{!MM:%{!E:%{!S:as %(asm_debug) %(asm_options) %i %A }}}}", 0, 0, 0},
@@ -1715,6 +1728,7 @@ static struct spec_list static_specs[] =
   INIT_STATIC_SPEC ("cc1_options",		&cc1_options),
   INIT_STATIC_SPEC ("cc1plus",			&cc1plus_spec),
   INIT_STATIC_SPEC ("link_gcc_c_sequence",	&link_gcc_c_sequence_spec),
+  INIT_STATIC_SPEC ("default_flag_cf_spec",     &default_flag_cf_spec),
   INIT_STATIC_SPEC ("link_ssp",			&link_ssp_spec),
   INIT_STATIC_SPEC ("endfile",			&endfile_spec),
   INIT_STATIC_SPEC ("link",			&link_spec),
--- a/gcc/objc/lang-specs.h
+++ b/gcc/objc/lang-specs.h
@@ -29,9 +29,9 @@ along with GCC; see the file COPYING3.  If not see
 	%{traditional|traditional-cpp:\
 %eGNU Objective C no longer supports traditional compilation}\
 	%{save-temps*|no-integrated-cpp:cc1obj -E %(cpp_options) -o %{save-temps*:%b.mi} %{!save-temps*:%g.mi} \n\
-	    cc1obj -fpreprocessed %{save-temps*:%b.mi} %{!save-temps*:%g.mi} %(cc1_options) %{print-objc-runtime-info} %{gen-decls}}\
+	    cc1obj -fpreprocessed %{save-temps*:%b.mi} %{!save-temps*:%g.mi} %(cc1_options) %(default_flag_cf_spec) %{print-objc-runtime-info} %{gen-decls}}\
 	%{!save-temps*:%{!no-integrated-cpp:\
-	    cc1obj %(cpp_unique_options) %(cc1_options) %{print-objc-runtime-info} %{gen-decls}}}\
+	    cc1obj %(cpp_unique_options) %(cc1_options) %(default_flag_cf_spec) %{print-objc-runtime-info} %{gen-decls}}}\
         %{!fsyntax-only:%(invoke_as)}}}}", 0, 0, 0},
   {"@objective-c-header",
      "%{E|M|MM:cc1obj -E %{traditional|traditional-cpp:-traditional-cpp}\
@@ -40,18 +40,18 @@ along with GCC; see the file COPYING3.  If not see
 	%{traditional|traditional-cpp:\
 %eGNU Objective C no longer supports traditional compilation}\
 	%{save-temps*|no-integrated-cpp:cc1obj -E %(cpp_options) -o %{save-temps*:%b.mi} %{!save-temps*:%g.mi} \n\
-	    cc1obj -fpreprocessed %b.mi %(cc1_options) %{print-objc-runtime-info} %{gen-decls}\
+	    cc1obj -fpreprocessed %b.mi %(cc1_options) %(default_flag_cf_spec) %{print-objc-runtime-info} %{gen-decls}\
                         -o %g.s %{!o*:--output-pch=%i.gch}\
                         %W{o*:--output-pch=%*}%V}\
 	%{!save-temps*:%{!no-integrated-cpp:\
-	    cc1obj %(cpp_unique_options) %(cc1_options) %{print-objc-runtime-info} %{gen-decls}\
+	    cc1obj %(cpp_unique_options) %(cc1_options) %(default_flag_cf_spec) %{print-objc-runtime-info} %{gen-decls}\
                         -o %g.s %{!o*:--output-pch=%i.gch}\
                         %W{o*:--output-pch=%*}%V}}}}}", 0, 0, 0},
   {".mi", "@objective-c-cpp-output", 0, 0, 0},
   {"@objective-c-cpp-output",
-     "%{!M:%{!MM:%{!E:cc1obj -fpreprocessed %i %(cc1_options) %{print-objc-runtime-info} %{gen-decls}\
+     "%{!M:%{!MM:%{!E:cc1obj -fpreprocessed %i %(cc1_options) %(default_flag_cf_spec) %{print-objc-runtime-info} %{gen-decls}\
 			     %{!fsyntax-only:%(invoke_as)}}}}", 0, 0, 0},
   {"@objc-cpp-output",
       "%nobjc-cpp-output is deprecated; please use objective-c-cpp-output instead\n\
-       %{!M:%{!MM:%{!E:cc1obj -fpreprocessed %i %(cc1_options) %{print-objc-runtime-info} %{gen-decls}\
+       %{!M:%{!MM:%{!E:cc1obj -fpreprocessed %i %(cc1_options) %(default_flag_cf_spec) %{print-objc-runtime-info} %{gen-decls}\
 			     %{!fsyntax-only:%(invoke_as)}}}}", 0, 0, 0},
--- a/gcc/objcp/lang-specs.h
+++ b/gcc/objcp/lang-specs.h
@@ -36,7 +36,7 @@ along with GCC; see the file COPYING3.  If not see
 		%(cpp_options) %2 -o %{save-temps*:%b.mii} %{!save-temps*:%g.mii} \n}\
       cc1objplus %{save-temps*|no-integrated-cpp:-fpreprocessed %{save-temps*:%b.mii} %{!save-temps*:%g.mii}}\
 	      %{!save-temps*:%{!no-integrated-cpp:%(cpp_unique_options)}}\
-	%(cc1_options) %2\
+	%(cc1_options) %(default_flag_cf_spec) %2\
         -o %g.s %{!o*:--output-pch=%i.gch} %W{o*:--output-pch=%*}%V}}}",
      CPLUSPLUS_CPP_SPEC, 0, 0},
   {"@objective-c++",
@@ -46,16 +46,16 @@ along with GCC; see the file COPYING3.  If not see
 		%(cpp_options) %2 -o %{save-temps*:%b.mii} %{!save-temps*:%g.mii} \n}\
       cc1objplus %{save-temps*|no-integrated-cpp:-fpreprocessed %{save-temps*:%b.mii} %{!save-temps*:%g.mii}}\
 	      %{!save-temps*:%{!no-integrated-cpp:%(cpp_unique_options)}}\
-	%(cc1_options) %2\
+	%(cc1_options) %(default_flag_cf_spec) %2\
        %{!fsyntax-only:%(invoke_as)}}}}",
      CPLUSPLUS_CPP_SPEC, 0, 0},
   {".mii", "@objective-c++-cpp-output", 0, 0, 0},
   {"@objective-c++-cpp-output",
    "%{!M:%{!MM:%{!E:\
-    cc1objplus -fpreprocessed %i %(cc1_options) %2\
+    cc1objplus -fpreprocessed %i %(cc1_options) %(default_flag_cf_spec) %2\
     %{!fsyntax-only:%(invoke_as)}}}}", 0, 0, 0},
   {"@objc++-cpp-output",
    "%nobjc++-cpp-output is deprecated; please use objective-c++-cpp-output instead\n\
     %{!M:%{!MM:%{!E:\
-    cc1objplus -fpreprocessed %i %(cc1_options) %2\
+    cc1objplus -fpreprocessed %i %(cc1_options) %(default_flag_cf_spec) %2\
     %{!fsyntax-only:%(invoke_as)}}}}", 0, 0, 0},
