aboutsummaryrefslogtreecommitdiff
path: root/gcc/doc
diff options
context:
space:
mode:
authorRichard Earnshaw <rearnsha@arm.com>2018-07-31 17:35:32 +0000
committerRichard Earnshaw <rearnsha@gcc.gnu.org>2018-07-31 17:35:32 +0000
commit425fc685dd59c07316a0c9112595331aa77ba112 (patch)
tree2d22b78c91baba7c56447d6b82253d85e3503bfd /gcc/doc
parent1d8693a0ce9e805acadc11072579e94b913eb1d8 (diff)
downloadgcc-425fc685dd59c07316a0c9112595331aa77ba112.zip
gcc-425fc685dd59c07316a0c9112595331aa77ba112.tar.gz
gcc-425fc685dd59c07316a0c9112595331aa77ba112.tar.bz2
Add __builtin_speculation_safe_value
This patch defines a new intrinsic function __builtin_speculation_safe_value. A generic default implementation is defined which will attempt to use the backend pattern "speculation_safe_barrier". If this pattern is not defined, or if it is not available, then the compiler will emit a warning, but compilation will continue. Note that the test spec-barrier-1.c will currently fail on all targets. This is deliberate, the failure will go away when appropriate action is taken for each target backend. gcc: * builtin-types.def (BT_FN_PTR_PTR_VAR): New function type. (BT_FN_I1_I1_VAR, BT_FN_I2_I2_VAR, BT_FN_I4_I4_VAR): Likewise. (BT_FN_I8_I8_VAR, BT_FN_I16_I16_VAR): Likewise. * builtin-attrs.def (ATTR_NOVOPS_NOTHROW_LEAF_LIST): New attribute list. * builtins.def (BUILT_IN_SPECULATION_SAFE_VALUE_N): New builtin. (BUILT_IN_SPECULATION_SAFE_VALUE_PTR): New internal builtin. (BUILT_IN_SPECULATION_SAFE_VALUE_1): Likewise. (BUILT_IN_SPECULATION_SAFE_VALUE_2): Likewise. (BUILT_IN_SPECULATION_SAFE_VALUE_4): Likewise. (BUILT_IN_SPECULATION_SAFE_VALUE_8): Likewise. (BUILT_IN_SPECULATION_SAFE_VALUE_16): Likewise. * builtins.c (expand_speculation_safe_value): New function. (expand_builtin): Call it. * doc/cpp.texi: Document predefine __HAVE_SPECULATION_SAFE_VALUE. * doc/extend.texi: Document __builtin_speculation_safe_value. * doc/md.texi: Document "speculation_barrier" pattern. * doc/tm.texi.in: Pull in TARGET_SPECULATION_SAFE_VALUE and TARGET_HAVE_SPECULATION_SAFE_VALUE. * doc/tm.texi: Regenerated. * target.def (have_speculation_safe_value, speculation_safe_value): New hooks. * targhooks.c (default_have_speculation_safe_value): New function. (default_speculation_safe_value): New function. * targhooks.h (default_have_speculation_safe_value): Add prototype. (default_speculation_safe_value): Add prototype. c-family: * c-common.c (speculation_safe_resolve_call): New function. (speculation_safe_resolve_params): New function. (speculation_safe_resolve_return): New function. (resolve_overloaded_builtin): Handle __builtin_speculation_safe_value. * c-cppbuiltin.c (c_cpp_builtins): Add pre-define for __HAVE_SPECULATION_SAFE_VALUE. testsuite: * c-c++-common/spec-barrier-1.c: New test. * c-c++-common/spec-barrier-2.c: New test. * gcc.dg/spec-barrier-3.c: New test. From-SVN: r263168
Diffstat (limited to 'gcc/doc')
-rw-r--r--gcc/doc/cpp.texi4
-rw-r--r--gcc/doc/extend.texi91
-rw-r--r--gcc/doc/md.texi15
-rw-r--r--gcc/doc/tm.texi31
-rw-r--r--gcc/doc/tm.texi.in4
5 files changed, 145 insertions, 0 deletions
diff --git a/gcc/doc/cpp.texi b/gcc/doc/cpp.texi
index 3f7a8fc..efad2c8 100644
--- a/gcc/doc/cpp.texi
+++ b/gcc/doc/cpp.texi
@@ -2381,6 +2381,10 @@ If GCC cannot determine the current date, it will emit a warning message
These macros are defined when the target processor supports atomic compare
and swap operations on operands 1, 2, 4, 8 or 16 bytes in length, respectively.
+@item __HAVE_SPECULATION_SAFE_VALUE
+This macro is defined with the value 1 to show that this version of GCC
+supports @code{__builtin_speculation_safe_value}.
+
@item __GCC_HAVE_DWARF2_CFI_ASM
This macro is defined when the compiler is emitting DWARF CFI directives
to the assembler. When this is defined, it is possible to emit those same
diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index 63ef39a..bf465d7 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -10960,6 +10960,7 @@ is called and the @var{flag} argument passed to it.
@findex __builtin_powi
@findex __builtin_powif
@findex __builtin_powil
+@findex __builtin_speculation_safe_value
@findex _Exit
@findex _exit
@findex abort
@@ -11604,6 +11605,96 @@ check its compatibility with @var{size}.
@end deftypefn
+@deftypefn {Built-in Function} @var{type} __builtin_speculation_safe_value (@var{type} val, @var{type} failval)
+
+This built-in function can be used to help mitigate against unsafe
+speculative execution. @var{type} may be any integral type or any
+pointer type.
+
+@enumerate
+@item
+If the CPU is not speculatively executing the code, then @var{val}
+is returned.
+@item
+If the CPU is executing speculatively then either:
+@itemize
+@item
+The function may cause execution to pause until it is known that the
+code is no-longer being executed speculatively (in which case
+@var{val} can be returned, as above); or
+@item
+The function may use target-dependent speculation tracking state to cause
+@var{failval} to be returned when it is known that speculative
+execution has incorrectly predicted a conditional branch operation.
+@end itemize
+@end enumerate
+
+The second argument, @var{failval}, is optional and defaults to zero
+if omitted.
+
+GCC defines the preprocessor macro
+@code{__HAVE_BUILTIN_SPECULATION_SAFE_VALUE} for targets that have been
+updated to support this builtin.
+
+The built-in function can be used where a variable appears to be used in a
+safe way, but the CPU, due to speculative execution may temporarily ignore
+the bounds checks. Consider, for example, the following function:
+
+@smallexample
+int array[500];
+int f (unsigned untrusted_index)
+@{
+ if (untrusted_index < 500)
+ return array[untrusted_index];
+ return 0;
+@}
+@end smallexample
+
+If the function is called repeatedly with @code{untrusted_index} less
+than the limit of 500, then a branch predictor will learn that the
+block of code that returns a value stored in @code{array} will be
+executed. If the function is subsequently called with an
+out-of-range value it will still try to execute that block of code
+first until the CPU determines that the prediction was incorrect
+(the CPU will unwind any incorrect operations at that point).
+However, depending on how the result of the function is used, it might be
+possible to leave traces in the cache that can reveal what was stored
+at the out-of-bounds location. The built-in function can be used to
+provide some protection against leaking data in this way by changing
+the code to:
+
+@smallexample
+int array[500];
+int f (unsigned untrusted_index)
+@{
+ if (untrusted_index < 500)
+ return array[__builtin_speculation_safe_value (untrusted_index)];
+ return 0;
+@}
+@end smallexample
+
+The built-in function will either cause execution to stall until the
+conditional branch has been fully resolved, or it may permit
+speculative execution to continue, but using 0 instead of
+@code{untrusted_value} if that exceeds the limit.
+
+If accessing any memory location is potentially unsafe when speculative
+execution is incorrect, then the code can be rewritten as
+
+@smallexample
+int array[500];
+int f (unsigned untrusted_index)
+@{
+ if (untrusted_index < 500)
+ return *__builtin_speculation_safe_value (&array[untrusted_index], NULL);
+ return 0;
+@}
+@end smallexample
+
+which will cause a @code{NULL} pointer to be used for the unsafe case.
+
+@end deftypefn
+
@deftypefn {Built-in Function} int __builtin_types_compatible_p (@var{type1}, @var{type2})
You can use the built-in function @code{__builtin_types_compatible_p} to
diff --git a/gcc/doc/md.texi b/gcc/doc/md.texi
index 734bc76..00c1239 100644
--- a/gcc/doc/md.texi
+++ b/gcc/doc/md.texi
@@ -7032,6 +7032,21 @@ should be defined to an instruction that orders both loads and stores
before the instruction with respect to loads and stores after the instruction.
This pattern has no operands.
+@cindex @code{speculation_barrier} instruction pattern
+@item @samp{speculation_barrier}
+If the target can support speculative execution, then this pattern should
+be defined to an instruction that will block subsequent execution until
+any prior speculation conditions has been resolved. The pattern must also
+ensure that the compiler cannot move memory operations past the barrier,
+so it needs to be an UNSPEC_VOLATILE pattern. The pattern has no
+operands.
+
+If this pattern is not defined then the default expansion of
+@code{__builtin_speculation_safe_value} will emit a warning. You can
+suppress this warning by defining this pattern with a final condition
+of @code{0} (zero), which tells the compiler that a speculation
+barrier is not needed for this target.
+
@cindex @code{sync_compare_and_swap@var{mode}} instruction pattern
@item @samp{sync_compare_and_swap@var{mode}}
This pattern, if defined, emits code for an atomic compare-and-swap
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index 0ddcd1a..351f0b3 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -11924,6 +11924,37 @@ maintainer is familiar with.
@end defmac
+@deftypefn {Target Hook} bool TARGET_HAVE_SPECULATION_SAFE_VALUE (bool @var{active})
+This hook is used to determine the level of target support for
+ @code{__builtin_speculation_safe_value}. If called with an argument
+ of false, it returns true if the target has been modified to support
+ this builtin. If called with an argument of true, it returns true
+ if the target requires active mitigation execution might be speculative.
+
+ The default implementation returns false if the target does not define
+ a pattern named @code{speculation_barrier}. Else it returns true
+ for the first case and whether the pattern is enabled for the current
+ compilation for the second case.
+@end deftypefn
+
+@deftypefn {Target Hook} rtx TARGET_SPECULATION_SAFE_VALUE (machine_mode @var{mode}, rtx @var{result}, rtx @var{val}, rtx @var{failval})
+This target hook can be used to generate a target-specific code
+ sequence that implements the @code{__builtin_speculation_safe_value}
+ built-in function. The function must always return @var{val} in
+ @var{result} in mode @var{mode} when the cpu is not executing
+ speculatively, but must never return that when speculating until it
+ is known that the speculation will not be unwound. The hook supports
+ two primary mechanisms for implementing the requirements. The first
+ is to emit a speculation barrier which forces the processor to wait
+ until all prior speculative operations have been resolved; the second
+ is to use a target-specific mechanism that can track the speculation
+ state and to return @var{failval} if it can determine that
+ speculation must be unwound at a later time.
+
+ The default implementation simply copies @var{val} to @var{result} and
+ emits a @code{speculation_barrier} instruction if that is defined.
+@end deftypefn
+
@deftypefn {Target Hook} void TARGET_RUN_TARGET_SELFTESTS (void)
If selftests are enabled, run any selftests for this target.
@end deftypefn
diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in
index e275aca..39a214e 100644
--- a/gcc/doc/tm.texi.in
+++ b/gcc/doc/tm.texi.in
@@ -8101,4 +8101,8 @@ maintainer is familiar with.
@end defmac
+@hook TARGET_HAVE_SPECULATION_SAFE_VALUE
+
+@hook TARGET_SPECULATION_SAFE_VALUE
+
@hook TARGET_RUN_TARGET_SELFTESTS