Simulate other ARM CPUs when running tests.
We test all Intel variants via SDE. For ARM, we can do the next best
thing and tweak with OPENSSL_armcap_P. If the host CPU does not support
the instructions we wish to test, skip it, but print something so we
know whether we need a more featureful test device.
Also fix the "CRASHED" status to "CRASH", to match
https://chromium.googlesource.com/chromium/src/+/master/docs/testing/json_test_results_format.md
(It's unclear if anything actually parses that JSON very carefully...)
Bug: 19
Change-Id: I811cc00a0d210a454287ac79c06f18fbc54f96dd
Reviewed-on: https://boringssl-review.googlesource.com/c/33204
Commit-Queue: David Benjamin <davidben@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
Reviewed-by: Adam Langley <agl@google.com>
diff --git a/crypto/crypto.c b/crypto/crypto.c
index 5f1a69a..f7ac255 100644
--- a/crypto/crypto.c
+++ b/crypto/crypto.c
@@ -102,6 +102,10 @@
#else
HIDDEN uint32_t OPENSSL_armcap_P = 0;
+
+uint32_t *OPENSSL_get_armcap_pointer_for_test(void) {
+ return &OPENSSL_armcap_P;
+}
#endif
#endif
diff --git a/crypto/internal.h b/crypto/internal.h
index a251b95..b98b556 100644
--- a/crypto/internal.h
+++ b/crypto/internal.h
@@ -150,6 +150,14 @@
void OPENSSL_cpuid_setup(void);
#endif
+#if (defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64)) && \
+ !defined(OPENSSL_STATIC_ARMCAP)
+// OPENSSL_get_armcap_pointer_for_test returns a pointer to |OPENSSL_armcap_P|
+// for unit tests. Any modifications to the value must be made after
+// |CRYPTO_library_init| but before any other function call in BoringSSL.
+OPENSSL_EXPORT uint32_t *OPENSSL_get_armcap_pointer_for_test(void);
+#endif
+
#if (!defined(_MSC_VER) || defined(__clang__)) && defined(OPENSSL_64_BIT)
#define BORINGSSL_HAS_UINT128
diff --git a/crypto/test/gtest_main.cc b/crypto/test/gtest_main.cc
index 5dc8b23..4501bbb 100644
--- a/crypto/test/gtest_main.cc
+++ b/crypto/test/gtest_main.cc
@@ -12,13 +12,22 @@
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
+#include <stdio.h>
#include <string.h>
#include <gtest/gtest.h>
+#include <openssl/cpu.h>
#include <openssl/rand.h>
#include "gtest_main.h"
+#include "../internal.h"
+
+#if (defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64)) && \
+ !defined(OPENSSL_STATIC_ARMCAP)
+#include <openssl/arm_arch.h>
+#define TEST_ARM_CPUS
+#endif
int main(int argc, char **argv) {
@@ -33,5 +42,33 @@
}
#endif
+#if defined(TEST_ARM_CPUS)
+ for (int i = 1; i < argc; i++) {
+ if (strncmp(argv[i], "--cpu=", 6) == 0) {
+ const char *cpu = argv[i] + 6;
+ uint32_t armcap;
+ if (strcmp(cpu, "none") == 0) {
+ armcap = 0;
+ } else if (strcmp(cpu, "neon") == 0) {
+ armcap = ARMV7_NEON;
+ } else if (strcmp(cpu, "crypto") == 0) {
+ armcap = ARMV7_NEON | ARMV8_AES | ARMV8_SHA1 | ARMV8_SHA256 | ARMV8_PMULL;
+ } else {
+ fprintf(stderr, "Unknown CPU: %s\n", cpu);
+ exit(1);
+ }
+
+ uint32_t *armcap_ptr = OPENSSL_get_armcap_pointer_for_test();
+ if ((armcap & *armcap_ptr) != armcap) {
+ fprintf(stderr,
+ "Host CPU does not support features for testing CPU '%s'.\n",
+ cpu);
+ exit(89);
+ }
+ *armcap_ptr = armcap;
+ }
+ }
+#endif // TEST_ARM_CPUS
+
return RUN_ALL_TESTS();
}