xref: /aosp_15_r20/external/boringssl/src/crypto/test/abi_test.h (revision 8fb009dc861624b67b6cdb62ea21f0f22d0c584b)
1 /* Copyright (c) 2018, Google Inc.
2  *
3  * Permission to use, copy, modify, and/or distribute this software for any
4  * purpose with or without fee is hereby granted, provided that the above
5  * copyright notice and this permission notice appear in all copies.
6  *
7  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
10  * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
12  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
13  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
14 
15 #ifndef OPENSSL_HEADER_ABI_TEST_H
16 #define OPENSSL_HEADER_ABI_TEST_H
17 
18 #include <gtest/gtest.h>
19 
20 #include <string>
21 #include <type_traits>
22 #include <vector>
23 
24 #include <openssl/base.h>
25 
26 #include "../internal.h"
27 
28 
29 // abi_test provides routines for verifying that functions satisfy platform ABI
30 // requirements.
31 namespace abi_test {
32 
33 // Result stores the result of an ABI test.
34 struct Result {
okResult35   bool ok() const { return errors.empty(); }
36 
37   std::vector<std::string> errors;
38 };
39 
40 namespace internal {
41 
42 // DeductionGuard wraps |T| in a template, so that template argument deduction
43 // does not apply to it. This may be used to force C++ to deduce template
44 // arguments from another parameter.
45 template <typename T>
46 struct DeductionGuard {
47   using Type = T;
48 };
49 
50 // Reg128 contains storage space for a 128-bit register.
51 struct alignas(16) Reg128 {
52   bool operator==(const Reg128 &x) const { return x.lo == lo && x.hi == hi; }
53   bool operator!=(const Reg128 &x) const { return !((*this) == x); }
54   uint64_t lo, hi;
55 };
56 
57 // LOOP_CALLER_STATE_REGISTERS is a macro that iterates over all registers the
58 // callee is expected to save for the caller, with the exception of the stack
59 // pointer. The stack pointer is tested implicitly by the function successfully
60 // returning at all.
61 #if defined(OPENSSL_X86_64)
62 
63 // References:
64 // SysV64: https://github.com/hjl-tools/x86-psABI/wiki/x86-64-psABI-1.0.pdf
65 // Win64: https://docs.microsoft.com/en-us/cpp/build/x64-software-conventions?view=vs-2017#register-usage
66 #if defined(OPENSSL_WINDOWS)
67 #define LOOP_CALLER_STATE_REGISTERS()  \
68   CALLER_STATE_REGISTER(uint64_t, rbx) \
69   CALLER_STATE_REGISTER(uint64_t, rbp) \
70   CALLER_STATE_REGISTER(uint64_t, rdi) \
71   CALLER_STATE_REGISTER(uint64_t, rsi) \
72   CALLER_STATE_REGISTER(uint64_t, r12) \
73   CALLER_STATE_REGISTER(uint64_t, r13) \
74   CALLER_STATE_REGISTER(uint64_t, r14) \
75   CALLER_STATE_REGISTER(uint64_t, r15) \
76   CALLER_STATE_REGISTER(Reg128, xmm6)  \
77   CALLER_STATE_REGISTER(Reg128, xmm7)  \
78   CALLER_STATE_REGISTER(Reg128, xmm8)  \
79   CALLER_STATE_REGISTER(Reg128, xmm9)  \
80   CALLER_STATE_REGISTER(Reg128, xmm10) \
81   CALLER_STATE_REGISTER(Reg128, xmm11) \
82   CALLER_STATE_REGISTER(Reg128, xmm12) \
83   CALLER_STATE_REGISTER(Reg128, xmm13) \
84   CALLER_STATE_REGISTER(Reg128, xmm14) \
85   CALLER_STATE_REGISTER(Reg128, xmm15)
86 #else
87 #define LOOP_CALLER_STATE_REGISTERS()  \
88   CALLER_STATE_REGISTER(uint64_t, rbx) \
89   CALLER_STATE_REGISTER(uint64_t, rbp) \
90   CALLER_STATE_REGISTER(uint64_t, r12) \
91   CALLER_STATE_REGISTER(uint64_t, r13) \
92   CALLER_STATE_REGISTER(uint64_t, r14) \
93   CALLER_STATE_REGISTER(uint64_t, r15)
94 #endif  // OPENSSL_WINDOWS
95 
96 #elif defined(OPENSSL_X86)
97 
98 // References:
99 // SysV32: https://uclibc.org/docs/psABI-i386.pdf and
100 // Win32: https://docs.microsoft.com/en-us/cpp/cpp/argument-passing-and-naming-conventions?view=vs-2017
101 #define LOOP_CALLER_STATE_REGISTERS()  \
102   CALLER_STATE_REGISTER(uint32_t, esi) \
103   CALLER_STATE_REGISTER(uint32_t, edi) \
104   CALLER_STATE_REGISTER(uint32_t, ebx) \
105   CALLER_STATE_REGISTER(uint32_t, ebp)
106 
107 #elif defined(OPENSSL_ARM)
108 
109 // References:
110 // AAPCS: https://developer.arm.com/docs/ihi0042/latest
111 // iOS32: https://developer.apple.com/library/archive/documentation/Xcode/Conceptual/iPhoneOSABIReference/Articles/ARMv6FunctionCallingConventions.html
112 // Linux: http://sourcery.mentor.com/sgpp/lite/arm/portal/kbattach142/arm_gnu_linux_%20abi.pdf
113 //
114 // ARM specifies a common calling convention, except r9 is left to the platform.
115 // Linux treats r9 as callee-saved, while iOS 3+ treats it as caller-saved. Most
116 // of our assembly treats it as callee-saved to be uniform, but we match the
117 // platform to avoid false positives when testing compiler-generated output.
118 #define LOOP_CALLER_STATE_REGISTERS_PRE_R9() \
119   CALLER_STATE_REGISTER(uint64_t, d8)        \
120   CALLER_STATE_REGISTER(uint64_t, d9)        \
121   CALLER_STATE_REGISTER(uint64_t, d10)       \
122   CALLER_STATE_REGISTER(uint64_t, d11)       \
123   CALLER_STATE_REGISTER(uint64_t, d12)       \
124   CALLER_STATE_REGISTER(uint64_t, d13)       \
125   CALLER_STATE_REGISTER(uint64_t, d14)       \
126   CALLER_STATE_REGISTER(uint64_t, d15)       \
127   CALLER_STATE_REGISTER(uint32_t, r4)        \
128   CALLER_STATE_REGISTER(uint32_t, r5)        \
129   CALLER_STATE_REGISTER(uint32_t, r6)        \
130   CALLER_STATE_REGISTER(uint32_t, r7)        \
131   CALLER_STATE_REGISTER(uint32_t, r8)
132 #define LOOP_CALLER_STATE_REGISTERS_POST_R9() \
133   CALLER_STATE_REGISTER(uint32_t, r10)        \
134   CALLER_STATE_REGISTER(uint32_t, r11)
135 #if defined(OPENSSL_APPLE)
136 #define LOOP_CALLER_STATE_REGISTERS()  \
137   LOOP_CALLER_STATE_REGISTERS_PRE_R9() \
138   LOOP_CALLER_STATE_REGISTERS_POST_R9()
139 #else  // !OPENSSL_APPLE
140 #define LOOP_CALLER_STATE_REGISTERS()  \
141   LOOP_CALLER_STATE_REGISTERS_PRE_R9() \
142   CALLER_STATE_REGISTER(uint32_t, r9)  \
143   LOOP_CALLER_STATE_REGISTERS_POST_R9()
144 #endif  // OPENSSL_APPLE
145 
146 #elif defined(OPENSSL_AARCH64)
147 
148 // References:
149 // AAPCS64: https://developer.arm.com/docs/ihi0055/latest
150 // iOS64: https://developer.apple.com/library/archive/documentation/Xcode/Conceptual/iPhoneOSABIReference/Articles/ARM64FunctionCallingConventions.html
151 //
152 // In aarch64, r18 (accessed as w18 or x18 in a 64-bit context) is the platform
153 // register. iOS says user code may not touch it. We found no clear reference
154 // for Linux. The iOS behavior implies portable assembly cannot use it, and
155 // aarch64 has many registers. Thus this framework ignores register's existence.
156 // We test r18 violations in arm-xlate.pl.
157 #define LOOP_CALLER_STATE_REGISTERS()                                \
158   /* Per AAPCS64, section 5.1.2, only the bottom 64 bits of v8-v15 */ \
159   /* are preserved. These are accessed as dN. */                     \
160   CALLER_STATE_REGISTER(uint64_t, d8)                                \
161   CALLER_STATE_REGISTER(uint64_t, d9)                                \
162   CALLER_STATE_REGISTER(uint64_t, d10)                               \
163   CALLER_STATE_REGISTER(uint64_t, d11)                               \
164   CALLER_STATE_REGISTER(uint64_t, d12)                               \
165   CALLER_STATE_REGISTER(uint64_t, d13)                               \
166   CALLER_STATE_REGISTER(uint64_t, d14)                               \
167   CALLER_STATE_REGISTER(uint64_t, d15)                               \
168   /* For consistency with dN, use the 64-bit name xN, rather than */ \
169   /* the generic rN. */                                              \
170   CALLER_STATE_REGISTER(uint64_t, x19)                               \
171   CALLER_STATE_REGISTER(uint64_t, x20)                               \
172   CALLER_STATE_REGISTER(uint64_t, x21)                               \
173   CALLER_STATE_REGISTER(uint64_t, x22)                               \
174   CALLER_STATE_REGISTER(uint64_t, x23)                               \
175   CALLER_STATE_REGISTER(uint64_t, x24)                               \
176   CALLER_STATE_REGISTER(uint64_t, x25)                               \
177   CALLER_STATE_REGISTER(uint64_t, x26)                               \
178   CALLER_STATE_REGISTER(uint64_t, x27)                               \
179   CALLER_STATE_REGISTER(uint64_t, x28)                               \
180   CALLER_STATE_REGISTER(uint64_t, x29)
181 
182 #endif  // X86_64 || X86 || ARM || AARCH64
183 
184 // Enable ABI testing if all of the following are true.
185 //
186 // - We have CallerState and trampoline support for the architecture.
187 //
188 // - Assembly is enabled.
189 //
190 // - This is not a shared library build. Assembly functions are not reachable
191 //   from tests in shared library builds.
192 #if defined(LOOP_CALLER_STATE_REGISTERS) && !defined(OPENSSL_NO_ASM) && \
193     !defined(BORINGSSL_SHARED_LIBRARY)
194 #define SUPPORTS_ABI_TEST
195 
196 // CallerState contains all caller state that the callee is expected to
197 // preserve.
198 struct CallerState {
199 #define CALLER_STATE_REGISTER(type, name) type name;
200   LOOP_CALLER_STATE_REGISTERS()
201 #undef CALLER_STATE_REGISTER
202 };
203 
204 // RunTrampoline runs |func| on |argv|, recording ABI errors in |out|. It does
205 // not perform any type-checking. If |unwind| is true and unwind tests have been
206 // enabled, |func| is single-stepped under an unwind test.
207 crypto_word_t RunTrampoline(Result *out, crypto_word_t func,
208                             const crypto_word_t *argv, size_t argc,
209                             bool unwind);
210 
211 template <typename T>
ToWord(T t)212 inline crypto_word_t ToWord(T t) {
213   // ABIs typically pass floats and structs differently from integers and
214   // pointers. We only need to support the latter.
215   static_assert(std::is_integral<T>::value || std::is_pointer<T>::value,
216                 "parameter types must be integral or pointer types");
217   // We only support types which fit in registers.
218   static_assert(sizeof(T) <= sizeof(crypto_word_t),
219                 "parameter types must be at most word-sized");
220 
221   // ABIs are complex around arguments that are smaller than native words.
222   // Parameters passed in memory are sometimes packed and sometimes padded to a
223   // word. When parameters are padded in memory or passed in a larger register,
224   // the unused bits may be undefined or sign- or zero-extended.
225   //
226   // We could simply cast to |crypto_word_t| everywhere but, on platforms where
227   // padding is undefined, we perturb the bits to test the function accounts for
228   // for this.
229 #if defined(OPENSSL_32_BIT)
230   // We never pass parameters smaller than int, so require word-sized parameters
231   // on 32-bit architectures for simplicity.
232   static_assert(sizeof(T) == 4, "parameter types must be word-sized");
233   return (crypto_word_t)t;
234 #elif defined(OPENSSL_X86_64) || defined(OPENSSL_AARCH64)
235   // AAPCS64, section 5.4.2, clauses C.7 and C.14 says any remaining bits in
236   // aarch are unspecified. iOS64 contradicts this and says the callee extends
237   // arguments up to 32 bits, and only the upper 32 bits are unspecified.
238   //
239   // On x86_64, Win64 leaves all unused bits unspecified. SysV also leaves
240   // unused bits in stack parameters unspecified, but it behaves like iOS64 for
241   // register parameters. This was determined via experimentation.
242   //
243   // We limit to 32-bit and 64-bit parameters, the subset where the above all
244   // align, and then test that functions tolerate arbitrary unused bits.
245   //
246   // TODO(davidben): Find authoritative citations for x86_64. For x86_64, I
247   // observed the behavior of Clang, GCC, and MSVC. ABI rules here may be
248   // inferred from two kinds of experiments:
249   //
250   // 1. When passing a value to a small-argument-taking function, does the
251   //    compiler ensure unused bits are cleared, sign-extended, etc.? Tests for
252   //    register parameters are confounded by x86_64's implicit clearing of
253   //    registers' upper halves, but passing some_u64 >> 1 usually clears this.
254   //
255   // 2. When compiling a small-argument-taking function, does the compiler make
256   //    assumptions about unused bits of arguments?
257   //
258   // MSVC was observed to tolerate and produce arbitrary values for unused bits,
259   // which is conclusive. GCC and Clang, targeting Linux, were similarly
260   // conclusive on stack parameters. Clang was also conclusive for register
261   // parameters. Callers only extended parameters up to 32 bits, and callees
262   // took advantage of the 32-bit extension. GCC only exhibited the callee
263   // behavior.
264   static_assert(sizeof(T) >= 4, "parameters must be at least 32 bits wide");
265   crypto_word_t ret;
266   // Filling extra bits with 0xaa will be vastly out of bounds for code
267   // expecting either sign- or zero-extension. (0xaa is 0b10101010.)
268   OPENSSL_memset(&ret, 0xaa, sizeof(ret));
269   OPENSSL_memcpy(&ret, &t, sizeof(t));
270   return ret;
271 #else
272 #error "unknown architecture"
273 #endif
274 }
275 
276 // CheckImpl runs |func| on |args|, recording ABI errors in |out|. If |unwind|
277 // is true and unwind tests have been enabled, |func| is single-stepped under an
278 // unwind test.
279 //
280 // It returns the value as a |crypto_word_t| to work around problems when |R| is
281 // void. |args| is wrapped in a |DeductionGuard| so |func| determines the
282 // template arguments. Otherwise, |args| may deduce |Args| incorrectly. For
283 // instance, if |func| takes const int *, and the caller passes an int *, the
284 // compiler will complain the deduced types do not match.
285 template <typename R, typename... Args>
CheckImpl(Result * out,bool unwind,R (* func)(Args...),typename DeductionGuard<Args>::Type...args)286 inline crypto_word_t CheckImpl(Result *out, bool unwind, R (*func)(Args...),
287                                typename DeductionGuard<Args>::Type... args) {
288   // We only support up to 8 arguments, so all arguments on aarch64 are passed
289   // in registers. This is simpler and avoids the iOS discrepancy around packing
290   // small arguments on the stack. (See the iOS64 reference.)
291   static_assert(sizeof...(args) <= 8,
292                 "too many arguments for abi_test_trampoline");
293 
294   // Allocate one extra entry so MSVC does not complain about zero-size arrays.
295   crypto_word_t argv[sizeof...(args) + 1] = {
296       ToWord(args)...,
297   };
298   return RunTrampoline(out, reinterpret_cast<crypto_word_t>(func), argv,
299                        sizeof...(args), unwind);
300 }
301 #else
302 // To simplify callers when ABI testing support is unavoidable, provide a backup
303 // CheckImpl implementation. It must be specialized for void returns because we
304 // call |func| directly.
305 template <typename R, typename... Args>
CheckImpl(Result * out,bool,R (* func)(Args...),typename DeductionGuard<Args>::Type...args)306 inline std::enable_if_t<!std::is_void<R>::value, crypto_word_t> CheckImpl(
307     Result *out, bool /* unwind */, R (*func)(Args...),
308     typename DeductionGuard<Args>::Type... args) {
309   *out = Result();
310   return func(args...);
311 }
312 
313 template <typename... Args>
CheckImpl(Result * out,bool,void (* func)(Args...),typename DeductionGuard<Args>::Type...args)314 inline crypto_word_t CheckImpl(Result *out, bool /* unwind */,
315                                void (*func)(Args...),
316                                typename DeductionGuard<Args>::Type... args) {
317   *out = Result();
318   func(args...);
319   return 0;
320 }
321 #endif  // SUPPORTS_ABI_TEST
322 
323 // FixVAArgsString takes a string like "f, 1, 2" and returns a string like
324 // "f(1, 2)".
325 //
326 // This is needed because the |CHECK_ABI| macro below cannot be defined as
327 // CHECK_ABI(func, ...). The C specification requires that variadic macros bind
328 // at least one variadic argument. Clang, GCC, and MSVC all ignore this, but
329 // there are issues with trailing commas and different behaviors across
330 // compilers.
331 std::string FixVAArgsString(const char *str);
332 
333 // CheckGTest behaves like |CheckImpl|, but it returns the correct type and
334 // raises GTest assertions on failure. If |unwind| is true and unwind tests are
335 // enabled, |func| is single-stepped under an unwind test.
336 template <typename R, typename... Args>
CheckGTest(const char * va_args_str,const char * file,int line,bool unwind,R (* func)(Args...),typename DeductionGuard<Args>::Type...args)337 inline R CheckGTest(const char *va_args_str, const char *file, int line,
338                     bool unwind, R (*func)(Args...),
339                     typename DeductionGuard<Args>::Type... args) {
340   Result result;
341   crypto_word_t ret = CheckImpl(&result, unwind, func, args...);
342   if (!result.ok()) {
343     testing::Message msg;
344     msg << "ABI failures in " << FixVAArgsString(va_args_str) << ":\n";
345     for (const auto &error : result.errors) {
346       msg << "    " << error << "\n";
347     }
348     ADD_FAILURE_AT(file, line) << msg;
349   }
350   return (R)ret;
351 }
352 
353 }  // namespace internal
354 
355 // Check runs |func| on |args| and returns the result. If ABI-testing is
356 // supported in this build configuration, it writes any ABI failures to |out|.
357 // Otherwise, it runs the function transparently.
358 template <typename R, typename... Args>
Check(Result * out,R (* func)(Args...),typename internal::DeductionGuard<Args>::Type...args)359 inline R Check(Result *out, R (*func)(Args...),
360                typename internal::DeductionGuard<Args>::Type... args) {
361   return (R)internal::CheckImpl(out, false, func, args...);
362 }
363 
364 // EnableUnwindTests enables unwind tests, if supported. If not supported, it
365 // does nothing.
366 void EnableUnwindTests();
367 
368 // UnwindTestsEnabled returns true if unwind tests are enabled and false
369 // otherwise.
370 bool UnwindTestsEnabled();
371 
372 }  // namespace abi_test
373 
374 // CHECK_ABI calls the first argument on the remaining arguments and returns the
375 // result. If ABI-testing is supported in this build configuration, it adds a
376 // non-fatal GTest failure if the call did not satisfy ABI requirements.
377 //
378 // |CHECK_ABI| does return the value and thus may replace any function call,
379 // provided it takes only simple parameters. However, it is recommended to test
380 // ABI separately from functional tests of assembly. Fully instrumenting a
381 // function for ABI checking requires single-stepping the function, which is
382 // inefficient.
383 //
384 // Functional testing requires coverage of input values, while ABI testing only
385 // requires branch coverage. Most of our assembly is constant-time, so usually
386 // only a few instrumented calls are necessary.
387 //
388 // TODO(https://crbug.com/boringssl/259): Most of Windows assembly currently
389 // fails SEH testing. For now, |CHECK_ABI| behaves like |CHECK_ABI_NO_UNWIND|
390 // on Windows. Functions which work with unwind testing on Windows should use
391 // |CHECK_ABI_SEH|.
392 #if defined(OPENSSL_WINDOWS)
393 #define CHECK_ABI(...) CHECK_ABI_NO_UNWIND(__VA_ARGS__)
394 #else
395 #define CHECK_ABI(...) CHECK_ABI_SEH(__VA_ARGS__)
396 #endif
397 
398 // CHECK_ABI_SEH behaves like |CHECK_ABI| but enables unwind testing on Windows.
399 #define CHECK_ABI_SEH(...)                                               \
400   abi_test::internal::CheckGTest(#__VA_ARGS__, __FILE__, __LINE__, true, \
401                                  __VA_ARGS__)
402 
403 // CHECK_ABI_NO_UNWIND behaves like |CHECK_ABI| but disables unwind testing.
404 #define CHECK_ABI_NO_UNWIND(...)                                          \
405   abi_test::internal::CheckGTest(#__VA_ARGS__, __FILE__, __LINE__, false, \
406                                  __VA_ARGS__)
407 
408 
409 // Internal functions.
410 
411 #if defined(SUPPORTS_ABI_TEST)
412 struct Uncallable {
413   Uncallable() = delete;
414 };
415 
416 extern "C" {
417 
418 // abi_test_trampoline loads callee-saved registers from |state|, calls |func|
419 // with |argv|, then saves the callee-saved registers into |state|. It returns
420 // the result of |func|. If |unwind| is non-zero, this function triggers unwind
421 // instrumentation.
422 //
423 // We give |func| type |crypto_word_t| to avoid tripping MSVC's warning 4191.
424 crypto_word_t abi_test_trampoline(crypto_word_t func,
425                                   abi_test::internal::CallerState *state,
426                                   const crypto_word_t *argv, size_t argc,
427                                   crypto_word_t unwind);
428 
429 #if defined(OPENSSL_X86_64)
430 // abi_test_unwind_start points at the instruction that starts unwind testing in
431 // |abi_test_trampoline|. This is the value of the instruction pointer at the
432 // first |SIGTRAP| during unwind testing.
433 //
434 // This symbol is not a function and should not be called.
435 void abi_test_unwind_start(Uncallable);
436 
437 // abi_test_unwind_return points at the instruction immediately after the call in
438 // |abi_test_trampoline|. When unwinding the function under test, this is the
439 // expected address in the |abi_test_trampoline| frame. After this address, the
440 // unwind tester should ignore |SIGTRAP| until |abi_test_unwind_stop|.
441 //
442 // This symbol is not a function and should not be called.
443 void abi_test_unwind_return(Uncallable);
444 
445 // abi_test_unwind_stop is the value of the instruction pointer at the final
446 // |SIGTRAP| during unwind testing.
447 //
448 // This symbol is not a function and should not be called.
449 void abi_test_unwind_stop(Uncallable);
450 
451 // abi_test_bad_unwind_wrong_register preserves the ABI, but annotates the wrong
452 // register in unwind metadata.
453 void abi_test_bad_unwind_wrong_register(void);
454 
455 // abi_test_bad_unwind_temporary preserves the ABI, but temporarily corrupts the
456 // storage space for a saved register, breaking unwind.
457 void abi_test_bad_unwind_temporary(void);
458 
459 #if defined(OPENSSL_WINDOWS)
460 // abi_test_bad_unwind_epilog preserves the ABI, and correctly annotates the
461 // prolog, but the epilog does not match Win64's rules, breaking unwind during
462 // the epilog.
463 void abi_test_bad_unwind_epilog(void);
464 #endif
465 #endif  // OPENSSL_X86_64
466 
467 #if defined(OPENSSL_X86_64) || defined(OPENSSL_X86)
468 // abi_test_get_and_clear_direction_flag clears the direction flag. If the flag
469 // was previously set, it returns one. Otherwise, it returns zero.
470 int abi_test_get_and_clear_direction_flag(void);
471 
472 // abi_test_set_direction_flag sets the direction flag. This does not conform to
473 // ABI requirements and must only be called within a |CHECK_ABI| guard to avoid
474 // errors later in the program.
475 int abi_test_set_direction_flag(void);
476 #endif  // OPENSSL_X86_64 || OPENSSL_X86
477 
478 }  // extern "C"
479 #endif  // SUPPORTS_ABI_TEST
480 
481 
482 #endif  // OPENSSL_HEADER_ABI_TEST_H
483