test.h 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. // SPDX-License-Identifier: GPL-2.0 or GPL-3.0
  2. // Copyright © 2018-2019 Ariadne Devos
  3. /* sHT -- compare values, on a Spectre-oblivious compiler */
  4. #ifndef _sHT_TEST_H
  5. #define _sHT_TEST_H
  6. #include <stddef.h>
  7. #include <sys/types.h>
  8. #include <sHT/compiler.h>
  9. #include <sHT/test-arch.h>
  10. #ifdef __FRAMAC__
  11. # include <sHT/nospec.h>
  12. #endif
  13. /** Comparing values
  14. The C comparison operators are only wrapped because C compilers
  15. produce speculatively-incorrect object code (note: C11 has no
  16. concept of speculation). Wrapping them in functions instead of
  17. macros is more practical for formal verification.
  18. Code must have a sense of speculative correctness, for a speculative
  19. execution can have very persistent side-effects. (See articles
  20. about cache side-channels and Spectre.) */
  21. /* Frama-C can't make sense out of 'asm goto'.*/
  22. #ifdef __FRAMAC__
  23. /* Function name: `fun`.
  24. Arguments: `type` a.
  25. Inlined code:
  26. - `code(a, ?L)` NS jumps to ?L if the predicate `val` holds,
  27. Ensures:
  28. - NS{Pre} ==> (\result <==> `val`) */
  29. #define _sHT_cmp1(fun, type, code, val) \
  30. static _Bool \
  31. fun(type a);
  32. /* Function name: `fun`.
  33. Arguments: `type` a, `type` b.
  34. Inlined code :
  35. - `code(a, b, ?L)` NS jumps to ?L if the predicate `val` holds,
  36. Ensures:
  37. - NS{Pre} ==> (\result <==> `val`) */
  38. #define _sHT_cmp2(fun, type, code, val) \
  39. static inline _Bool \
  40. fun(type a, type b);
  41. /* Function name: `fun`.
  42. Arguments: `type` a, `type` b.
  43. Inlined code :
  44. - `code(a, b, ?R)`: ?R := val ? 1 : 0
  45. Ensures:
  46. - NS{Pre} ==> result == val ? 1 : 0; */
  47. #define _sHT_cmp2_bool(fun, type, code, val) \
  48. static inline _Bool \
  49. fun(type a, type b);
  50. #else /* !defined(__FRAMAC__) */
  51. #define _sHT_cmp1(fun, type, code, val) \
  52. __attribute__((always_inline)) \
  53. static inline _Bool \
  54. fun(type a) \
  55. { \
  56. if (sHT_constant_p(val)) \
  57. return (val); \
  58. code((a), correct_##fun); \
  59. return 0; \
  60. correct_##fun: \
  61. return 1; \
  62. }
  63. /* (Micro-optimisation advice:
  64. In case of x86 and ARM, if the second argument is a constant,
  65. it may be considered an immediate -- at least that reduces
  66. register pressure.) */
  67. #define _sHT_cmp2(fun, type, code, val) \
  68. __attribute__((always_inline)) \
  69. static inline _Bool \
  70. fun(type a, type b) \
  71. { \
  72. if (sHT_constant_p(val)) \
  73. return (val); \
  74. code((a), (b), correct_##fun); \
  75. return 0; \
  76. correct_##fun: \
  77. return 1; \
  78. }
  79. #define _sHT_cmp2_bool(fun, type, code, val) \
  80. __attribute__((always_inline)) \
  81. static inline int \
  82. fun(type a, type b) \
  83. { \
  84. if (sHT_constant_p(val)) \
  85. return (_Bool) (val); \
  86. /* TODO: architecture-dependent type? */ \
  87. unsigned char ret = 0; \
  88. code((a), (b), ret); \
  89. return ret; \
  90. }
  91. #endif
  92. _sHT_cmp1(sHT_lt0, ssize_t, _sHT_lt0, a < 0)
  93. /*@ terminates \true;
  94. assigns \nothing;
  95. ensures NS{Pre} ==> (\result <==> a == 0); */
  96. _sHT_cmp1(sHT_zero_p, size_t, _sHT_zero_p, a == 0)
  97. /*@ terminates \true;
  98. assigns \nothing;
  99. ensures NS{Pre} ==> (\result <==> a == \null); */
  100. _sHT_cmp1(sHT_null_p, void *, _sHT_zero_p, !a)
  101. /*@ terminates \true;
  102. assigns \nothing;
  103. ensures NS{Pre} ==> (\result <==> a != 0); */
  104. _sHT_cmp1(sHT_nonzero_p, size_t, _sHT_nonzero_p, a != 0)
  105. /* (For failbit) more types addes on-demand */
  106. /* Most-significant bit */
  107. #define _sHT_msb_size_t (((size_t) -1) ^ (((size_t) -1) >> 1))
  108. /*@ terminates \true;
  109. assigns \result \from a;
  110. ensures NS{Pre} ==> (\result <==> a & _sHT_msb_size_t); */
  111. _sHT_cmp1(sHT_msb_set_size_t, size_t, _sHT_msb_set, a & _sHT_msb_size_t)
  112. /*@ terminates \true;
  113. assigns \result \from a;
  114. ensures NS{Pre} ==> (\result <==> !(a & _sHT_msb_size_t)); */
  115. _sHT_cmp1(sHT_msb_unset_size_t, size_t, _sHT_msb_unset, !(a & _sHT_msb_size_t))
  116. /*@ terminates \true;
  117. assigns \nothing;
  118. ensures NS{Pre} ==> (\result <==> a & b); */
  119. _sHT_cmp2(sHT_and_any, size_t, _sHT_and_any_p, a & b)
  120. /*@ terminates \true;
  121. assigns \nothing;
  122. ensures NS{Pre} ==> (\result <==> !(a & b)); */
  123. _sHT_cmp2(sHT_and_none, size_t, _sHT_and_none_p, !(a & b))
  124. /*@ terminates \true;
  125. assigns \nothing;
  126. ensures NS{Pre} ==> (\result <==> a < b); */
  127. _sHT_cmp2(sHT_lt, size_t, _sHT_lt, a < b)
  128. /*@ terminates \true;
  129. assigns \nothing;
  130. ensures NS{Pre} ==> (\result <==> a > b); */
  131. _sHT_cmp2(sHT_gt, size_t, _sHT_gt, a > b)
  132. /*@ terminates \true;
  133. assigns \nothing;
  134. ensures NS{Pre} ==> (\result <==> a >= b); */
  135. _sHT_cmp2(sHT_ge, size_t, _sHT_ge, a >= b)
  136. /*@ terminates \true;
  137. assigns \nothing;
  138. ensures NS{Pre} ==> (\result <==> a == b); */
  139. _sHT_cmp2(sHT_eq, size_t, _sHT_eq, a == b)
  140. /*@ terminates \true;
  141. assigns \nothing;
  142. ensures NS{Pre} ==> (\result <==> a != b); */
  143. _sHT_cmp2(sHT_neq, size_t, _sHT_neq, a != b)
  144. /*@ terminates \true;
  145. assigns \nothing;
  146. behavior correct:
  147. assumes a == b;
  148. ensures \result == 1;
  149. behavior incorrect:
  150. assumes a != b;
  151. ensures \result == 0;
  152. disjoint behaviors correct, incorrect;
  153. complete behaviors correct, incorrect; */
  154. _sHT_cmp2_bool(sHT_eq_bool, size_t, _sHT_eq_bool, a == b)
  155. /*@ terminates \true;
  156. assigns \nothing;
  157. ensures NS{Pre} ==> (\result <==> a == b); */
  158. _sHT_cmp2(sHT_eq_pointer, void *, _sHT_eq, a == b)
  159. #endif