12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091 |
- /* s2 - architecture-independent compiler magic
- Copyright (C) 2018 Ariadne Devos
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>. */
- #ifndef _sHT_COMPILER_H
- #define _sHT_COMPILER_H
- /* Clang or GCC is assumed, see Bug #3 */
- #define sHT_likely(b) (__builtin_expect(!!(b), 1))
- #define sHT_unlikely(b) (__builtin_expect(!!(b), 0))
- /* Let the compiler forget the value of the variable var.
- This does not avoid speculation by the processor.
- For Spectre mitigations, consider sHT_despeculate. */
- #define sHT_hide_var(var) \
- do { \
- __asm__("" : "=r" (var) : "0" (var)); \
- } while (0)
- /** Let the compiler believe that value of the variable @var{var} depends upon
- @var{dependency}.
- Afterwards, the value of @var{var} will be supposedly-dependant upon the
- value of @var{dependency}. */
- #define sHT_depend(var, dependency) \
- do { \
- __asm__("" : "=X" (var) : "X" (var), "X" (dependency)); \
- } while (0)
- /** Return @var{val} unchanged, supposedly-dependant upon the value of
- @var{dependency}.
- Afterwards, the value of @var{var} will be supposedly-dependant upon the
- value of @var{dependency}. */
- #define sHT_depending(val, dependency) \
- ({ __typeof__(val) _sHT_dep_val = (val); \
- sHT_depend(_sHT_dep_val, dependency); \
- _sHT_dep_val; })
- /** Evaluate the boolean expression @var{cond}.
- @var{cond}: a boolean expression variable in @var{var}
- @var{var}: a valid value to test
- In contrast to a plain C @code{if}, the compiler will not
- assume the correct branch is taken on a speculative execution.
- Its speculative value will be returned. */
- #define sHT_test_hidden(var, cond) \
- ((cond) ? ({ sHT_hide_var(var); (_Bool) 1; }) \
- : ({ sHT_hide_var(var); (_Bool) 0; }))
- /** Reverse taking a pointer to a member.
- @var{ptr}: a valid pointer, pointing to an instance of the member
- denoted by @var{member}.
- @var{type}: a C union or struct type, possibly as a typedef
- @var{member}: the name of a member of @var{type}
- This concept is taken from Linux.
- TODO: compatibility with Intel MMX and other pointer bounds checkers.
- Return a pointer to the @var{type} structure, of which a pointer to its
- field @var{member} is equal to @var{ptr}. */
- #define sHT_container_of(ptr, type, member) \
- ((type *) (((char *) ptr) - offsetof(type, member)))
- /** Something has gone wrong, stop the current process.
- This is only for catching bugs. In particular, it may speculatively
- be ignored. (Replacing a possibly repeating bug with a crashing
- speculation bug is, from a security perspective, probably fine.)
- @var{msg}: a literal string, describing what should have been the case. */
- #define sHT_halt(msg) __builtin_trap();
- #endif
|