compiler.h 3.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. /* s2 - architecture-independent compiler magic
  2. Copyright (C) 2018 Ariadne Devos
  3. This program is free software: you can redistribute it and/or modify
  4. it under the terms of the GNU General Public License as published by
  5. the Free Software Foundation, either version 3 of the License, or
  6. (at your option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with this program. If not, see <http://www.gnu.org/licenses/>. */
  13. #ifndef _sHT_COMPILER_H
  14. #define _sHT_COMPILER_H
  15. /* Clang or GCC is assumed, see Bug #3 */
  16. #define sHT_likely(b) (__builtin_expect(!!(b), 1))
  17. #define sHT_unlikely(b) (__builtin_expect(!!(b), 0))
  18. /* Let the compiler forget the value of the variable var.
  19. This does not avoid speculation by the processor.
  20. For Spectre mitigations, consider sHT_despeculate. */
  21. #define sHT_hide_var(var) \
  22. do { \
  23. __asm__("" : "=r" (var) : "0" (var)); \
  24. } while (0)
  25. /** Let the compiler believe that value of the variable @var{var} depends upon
  26. @var{dependency}.
  27. Afterwards, the value of @var{var} will be supposedly-dependant upon the
  28. value of @var{dependency}. */
  29. #define sHT_depend(var, dependency) \
  30. do { \
  31. __asm__("" : "=X" (var) : "X" (var), "X" (dependency)); \
  32. } while (0)
  33. /** Return @var{val} unchanged, supposedly-dependant upon the value of
  34. @var{dependency}.
  35. Afterwards, the value of @var{var} will be supposedly-dependant upon the
  36. value of @var{dependency}. */
  37. #define sHT_depending(val, dependency) \
  38. ({ __typeof__(val) _sHT_dep_val = (val); \
  39. sHT_depend(_sHT_dep_val, dependency); \
  40. _sHT_dep_val; })
  41. /** Evaluate the boolean expression @var{cond}.
  42. @var{cond}: a boolean expression variable in @var{var}
  43. @var{var}: a valid value to test
  44. In contrast to a plain C @code{if}, the compiler will not
  45. assume the correct branch is taken on a speculative execution.
  46. Its speculative value will be returned. */
  47. #define sHT_test_hidden(var, cond) \
  48. ((cond) ? ({ sHT_hide_var(var); (_Bool) 1; }) \
  49. : ({ sHT_hide_var(var); (_Bool) 0; }))
  50. /** Reverse taking a pointer to a member.
  51. @var{ptr}: a valid pointer, pointing to an instance of the member
  52. denoted by @var{member}.
  53. @var{type}: a C union or struct type, possibly as a typedef
  54. @var{member}: the name of a member of @var{type}
  55. This concept is taken from Linux.
  56. TODO: compatibility with Intel MMX and other pointer bounds checkers.
  57. Return a pointer to the @var{type} structure, of which a pointer to its
  58. field @var{member} is equal to @var{ptr}. */
  59. #define sHT_container_of(ptr, type, member) \
  60. ((type *) (((char *) ptr) - offsetof(type, member)))
  61. /** Something has gone wrong, stop the current process.
  62. This is only for catching bugs. In particular, it may speculatively
  63. be ignored. (Replacing a possibly repeating bug with a crashing
  64. speculation bug is, from a security perspective, probably fine.)
  65. @var{msg}: a literal string, describing what should have been the case. */
  66. #define sHT_halt(msg) __builtin_trap();
  67. #endif