Save trampoline state in unwind tests more straightforwardly
Rather than sample it from the UnwindCursor, we can just save it
immediately before starting the test.
Change-Id: Ica1eaa215755b0b772eaa08e03c5885aacec4f70
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/62866
Auto-Submit: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
Commit-Queue: Adam Langley <agl@google.com>
diff --git a/crypto/test/abi_test.cc b/crypto/test/abi_test.cc
index 536be3c..2338258 100644
--- a/crypto/test/abi_test.cc
+++ b/crypto/test/abi_test.cc
@@ -87,43 +87,6 @@
LOOP_CALLER_STATE_REGISTERS()
#undef CALLER_STATE_REGISTER
}
-
-// ReadUnwindResult adds the results of the most recent unwind test to |out|.
-static void ReadUnwindResult(Result *out);
-
-crypto_word_t RunTrampoline(Result *out, crypto_word_t func,
- const crypto_word_t *argv, size_t argc,
- bool unwind) {
- CallerState state;
- RAND_bytes(reinterpret_cast<uint8_t *>(&state), sizeof(state));
-
- unwind &= g_unwind_tests_enabled;
- CallerState state2 = state;
- crypto_word_t ret = abi_test_trampoline(func, &state2, argv, argc, unwind);
-#if defined(OPENSSL_X86_64) || defined(OPENSSL_X86)
- // Query and clear the direction flag early, so negative tests do not
- // interfere with |malloc|.
- bool direction_flag = abi_test_get_and_clear_direction_flag();
-#endif // OPENSSL_X86_64 || OPENSSL_X86
-
- *out = Result();
- ForEachMismatch(state, state2, [&](const char *reg) {
- out->errors.push_back(std::string(reg) + " was not restored after return");
- });
-#if defined(OPENSSL_X86_64) || defined(OPENSSL_X86)
- // Linux and Windows ABIs for x86 require the direction flag be cleared on
- // return. (Some OpenSSL assembly preserves it, which is stronger, but we only
- // require what is specified by the ABI so |CHECK_ABI| works with C compiler
- // output.)
- if (direction_flag) {
- out->errors.emplace_back("Direction flag set after return");
- }
-#endif // OPENSSL_X86_64 || OPENSSL_X86
- if (unwind) {
- ReadUnwindResult(out);
- }
- return ret;
-}
#endif // SUPPORTS_ABI_TEST
#if defined(SUPPORTS_UNWIND_TEST)
@@ -474,8 +437,8 @@
// g_unwind_function_done, if |g_in_trampoline| is true, is whether the function
// under test has returned. It is undefined otherwise.
static bool g_unwind_function_done;
-// g_trampoline_state, if |g_in_trampoline| is true, is the state the function
-// under test must preserve. It is undefined otherwise.
+// g_trampoline_state, during an unwind-enabled ABI test, is the state the
+// function under test must preserve. It is undefined otherwise.
static CallerState g_trampoline_state;
// g_trampoline_sp, if |g_in_trampoline| is true, is the stack pointer of the
// trampoline frame. It is undefined otherwise.
@@ -536,8 +499,6 @@
g_in_trampoline = true;
g_unwind_function_done = false;
g_trampoline_sp = sp;
- g_trampoline_state = cursor->GetCallerState().ValueOrDie(
- "Error getting initial caller state");
} else {
if (sp == g_trampoline_sp || g_unwind_function_done) {
// |g_unwind_function_done| should imply |sp| is |g_trampoline_sp|, but
@@ -608,6 +569,7 @@
}
}
+// ReadUnwindResult adds the results of the most recent unwind test to |out|.
static void ReadUnwindResult(Result *out) {
for (size_t i = 0; i < g_num_unwind_errors; i++) {
#if defined(OPENSSL_WINDOWS)
@@ -784,6 +746,48 @@
#endif // SUPPORTS_UNWIND_TEST
+#if defined(SUPPORTS_ABI_TEST)
+crypto_word_t RunTrampoline(Result *out, crypto_word_t func,
+ const crypto_word_t *argv, size_t argc,
+ bool unwind) {
+ CallerState state;
+ RAND_bytes(reinterpret_cast<uint8_t *>(&state), sizeof(state));
+
+ unwind &= g_unwind_tests_enabled;
+#if defined(SUPPORTS_UNWIND_TEST)
+ if (unwind) {
+ // Save the caller state for the unwind tester to check for.
+ g_trampoline_state = state;
+ }
+#endif
+ CallerState state2 = state;
+ crypto_word_t ret = abi_test_trampoline(func, &state2, argv, argc, unwind);
+#if defined(OPENSSL_X86_64) || defined(OPENSSL_X86)
+ // Query and clear the direction flag early, so negative tests do not
+ // interfere with |malloc|.
+ bool direction_flag = abi_test_get_and_clear_direction_flag();
+#endif // OPENSSL_X86_64 || OPENSSL_X86
+
+ *out = Result();
+ ForEachMismatch(state, state2, [&](const char *reg) {
+ out->errors.push_back(std::string(reg) + " was not restored after return");
+ });
+#if defined(OPENSSL_X86_64) || defined(OPENSSL_X86)
+ // Linux and Windows ABIs for x86 require the direction flag be cleared on
+ // return. (Some OpenSSL assembly preserves it, which is stronger, but we only
+ // require what is specified by the ABI so |CHECK_ABI| works with C compiler
+ // output.)
+ if (direction_flag) {
+ out->errors.emplace_back("Direction flag set after return");
+ }
+#endif // OPENSSL_X86_64 || OPENSSL_X86
+ if (unwind) {
+ ReadUnwindResult(out);
+ }
+ return ret;
+}
+#endif // SUPPORTS_ABI_TEST
+
} // namespace internal
void EnableUnwindTests() { internal::EnableUnwindTestsImpl(); }