Add an ABI testing framework.
Dear reader, I must apologize in advance. This CL contains the following:
- A new 256-line perlasm file with non-trivial perl bits and a dual-ABI
variadic function caller.
- C preprocessor gymnastics, with variadic macros and fun facts about
__VA_ARGS__'s behavior on empty argument lists.
- C++ template gymnastics, including variadic arguments, template
specialization, std::enable_if, and machinery to control template argument
deduction.
Enjoy.
This tests that our assembly functions correctly honor platform ABI
conventions. Right now this only tests callee-saved registers, but it should be
extendable to SEH/CFI unwind testing with single-step debugging APIs.
Register-checking does not involve anything funny and should be compatible with
SDE. (The future unwind testing is unlikely to be compatible.)
This CL adds support for x86_64 SysV and Win64 ABIs. ARM, AArch64, and x86 can
be added in the future. The testing is injected in two places. First, all the
assembly tests in p256-x86_64-test.cc are now instrumented. This is the
intended workflow and should capture all registers.
However, we currently do not unit-test our assembly much directly. We should do
that as follow-up work[0] but, in the meantime, I've also wrapped all of the GTest
main function in an ABI test. This is imperfect as ABI failures may be masked
by other stack frames, but it costs nothing[1] and is pretty reliable at
catching Win64 xmm register failures.
[0] An alternate strategy would be, in debug builds, unconditionally instrument
every assembly call in libcrypto. But the CHECK_ABI macro would be difficult to
replicate in pure C, and unwind testing may be too invasive for this. Still,
something to consider when we C++ libcrypto.
[1] When single-stepped unwind testing exists, it won't cost nothing. The
gtest_main.cc call will turn unwind testing off.
Change-Id: I6643b26445891fd46abfacac52bc024024c8d7f6
Reviewed-on: https://boringssl-review.googlesource.com/c/33764
Reviewed-by: Adam Langley <agl@google.com>
Reviewed-by: Adam Langley <alangley@gmail.com>
Commit-Queue: David Benjamin <davidben@google.com>
2018-12-16 00:58:43 +00:00
|
|
|
/* Copyright (c) 2018, Google Inc.
|
|
|
|
*
|
|
|
|
* Permission to use, copy, modify, and/or distribute this software for any
|
|
|
|
* purpose with or without fee is hereby granted, provided that the above
|
|
|
|
* copyright notice and this permission notice appear in all copies.
|
|
|
|
*
|
|
|
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
|
|
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
|
|
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
|
|
|
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
|
|
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
|
|
|
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
|
|
|
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
|
|
|
|
|
|
|
|
#include <gtest/gtest.h>
|
|
|
|
#include <gtest/gtest-spi.h>
|
|
|
|
|
|
|
|
#include <openssl/rand.h>
|
|
|
|
|
|
|
|
#include "test/abi_test.h"
|
|
|
|
|
|
|
|
|
Add a CFI tester to CHECK_ABI.
This uses the x86 trap flag and libunwind to test CFI works at each
instruction. For now, it just uses the system one out of pkg-config and
disables unwind tests if unavailable. We'll probably want to stick a
copy into //third_party and perhaps try the LLVM one later.
This tester caught two bugs in P-256 CFI annotations already:
I47b5f9798b3bcee1748e537b21c173d312a14b42 and
I9f576d868850312d6c14d1386f8fbfa85021b347
An earlier design used PTRACE_SINGLESTEP with libunwind's remote
unwinding features. ptrace is a mess around stop signals (see group-stop
discussion in ptrace(2)) and this is 10x faster, so I went with it. The
question of which is more future-proof is complex:
- There are two libunwinds with the same API,
https://www.nongnu.org/libunwind/ and LLVM's. This currently uses the
system nongnu.org for convenience. In future, LLVM's should be easier
to bundle (less complex build) and appears to even support Windows,
but I haven't tested this. Moreover, setting the trap flag keeps the
test single-process, which is less complex on Windows. That suggests
the trap flag design and switching to LLVM later. However...
- Not all architectures have a trap flag settable by userspace. As far
as I can tell, ARMv8's PSTATE.SS can only be set from the kernel. If
we stick with nongnu.org libunwind, we can use PTRACE_SINGLESTEP and
remote unwinding. Or we implement it for LLVM. Another thought is for
the ptracer to bounce SIGTRAP back into the process, to share the
local unwinding code.
- ARMv7 has no trap flag at all and PTRACE_SINGLESTEP fails. Debuggers
single-step by injecting breakpoints instead. However, ARMv8's trap
flag seems to work in both AArch32 and AArch64 modes, so we may be
able to condition it on a 64-bit kernel.
Sadly, neither strategy works with Intel SDE. Adding flags to cpucap
vectors as we do with ARM would help, but it would not emulate CPUs
newer than the host CPU. For now, I've just had SDE tests disable these.
Annoyingly, CMake does not allow object libraries to have dependencies,
so make test_support a proper static library. Rename the target to
test_support_lib to avoid
https://gitlab.kitware.com/cmake/cmake/issues/17785
Update-Note: This adds a new optional test dependency, but it's disabled
by default (define BORINGSSL_HAVE_LIBUNWIND), so consumers do not need
to do anything. We'll probably want to adjust this in the future.
Bug: 181
Change-Id: I817263d7907aff0904a9cee83f8b26747262cc0c
Reviewed-on: https://boringssl-review.googlesource.com/c/33966
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
2018-12-21 23:58:36 +00:00
|
|
|
static bool test_function_ok;
|
|
|
|
static int TestFunction(int a1, int a2, int a3, int a4, int a5, int a6, int a7,
|
|
|
|
int a8, int a9, int a10) {
|
|
|
|
test_function_ok = a1 == 1 || a2 == 2 || a3 == 3 || a4 == 4 || a5 == 5 ||
|
|
|
|
a6 == 6 || a7 == 7 || a8 == 8 || a9 == 9 || a10 == 10;
|
|
|
|
return 42;
|
Add an ABI testing framework.
Dear reader, I must apologize in advance. This CL contains the following:
- A new 256-line perlasm file with non-trivial perl bits and a dual-ABI
variadic function caller.
- C preprocessor gymnastics, with variadic macros and fun facts about
__VA_ARGS__'s behavior on empty argument lists.
- C++ template gymnastics, including variadic arguments, template
specialization, std::enable_if, and machinery to control template argument
deduction.
Enjoy.
This tests that our assembly functions correctly honor platform ABI
conventions. Right now this only tests callee-saved registers, but it should be
extendable to SEH/CFI unwind testing with single-step debugging APIs.
Register-checking does not involve anything funny and should be compatible with
SDE. (The future unwind testing is unlikely to be compatible.)
This CL adds support for x86_64 SysV and Win64 ABIs. ARM, AArch64, and x86 can
be added in the future. The testing is injected in two places. First, all the
assembly tests in p256-x86_64-test.cc are now instrumented. This is the
intended workflow and should capture all registers.
However, we currently do not unit-test our assembly much directly. We should do
that as follow-up work[0] but, in the meantime, I've also wrapped all of the GTest
main function in an ABI test. This is imperfect as ABI failures may be masked
by other stack frames, but it costs nothing[1] and is pretty reliable at
catching Win64 xmm register failures.
[0] An alternate strategy would be, in debug builds, unconditionally instrument
every assembly call in libcrypto. But the CHECK_ABI macro would be difficult to
replicate in pure C, and unwind testing may be too invasive for this. Still,
something to consider when we C++ libcrypto.
[1] When single-stepped unwind testing exists, it won't cost nothing. The
gtest_main.cc call will turn unwind testing off.
Change-Id: I6643b26445891fd46abfacac52bc024024c8d7f6
Reviewed-on: https://boringssl-review.googlesource.com/c/33764
Reviewed-by: Adam Langley <agl@google.com>
Reviewed-by: Adam Langley <alangley@gmail.com>
Commit-Queue: David Benjamin <davidben@google.com>
2018-12-16 00:58:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
TEST(ABITest, SanityCheck) {
|
2019-01-22 03:42:25 +00:00
|
|
|
EXPECT_NE(0, CHECK_ABI_NO_UNWIND(strcmp, "hello", "world"));
|
Add an ABI testing framework.
Dear reader, I must apologize in advance. This CL contains the following:
- A new 256-line perlasm file with non-trivial perl bits and a dual-ABI
variadic function caller.
- C preprocessor gymnastics, with variadic macros and fun facts about
__VA_ARGS__'s behavior on empty argument lists.
- C++ template gymnastics, including variadic arguments, template
specialization, std::enable_if, and machinery to control template argument
deduction.
Enjoy.
This tests that our assembly functions correctly honor platform ABI
conventions. Right now this only tests callee-saved registers, but it should be
extendable to SEH/CFI unwind testing with single-step debugging APIs.
Register-checking does not involve anything funny and should be compatible with
SDE. (The future unwind testing is unlikely to be compatible.)
This CL adds support for x86_64 SysV and Win64 ABIs. ARM, AArch64, and x86 can
be added in the future. The testing is injected in two places. First, all the
assembly tests in p256-x86_64-test.cc are now instrumented. This is the
intended workflow and should capture all registers.
However, we currently do not unit-test our assembly much directly. We should do
that as follow-up work[0] but, in the meantime, I've also wrapped all of the GTest
main function in an ABI test. This is imperfect as ABI failures may be masked
by other stack frames, but it costs nothing[1] and is pretty reliable at
catching Win64 xmm register failures.
[0] An alternate strategy would be, in debug builds, unconditionally instrument
every assembly call in libcrypto. But the CHECK_ABI macro would be difficult to
replicate in pure C, and unwind testing may be too invasive for this. Still,
something to consider when we C++ libcrypto.
[1] When single-stepped unwind testing exists, it won't cost nothing. The
gtest_main.cc call will turn unwind testing off.
Change-Id: I6643b26445891fd46abfacac52bc024024c8d7f6
Reviewed-on: https://boringssl-review.googlesource.com/c/33764
Reviewed-by: Adam Langley <agl@google.com>
Reviewed-by: Adam Langley <alangley@gmail.com>
Commit-Queue: David Benjamin <davidben@google.com>
2018-12-16 00:58:43 +00:00
|
|
|
|
Add a CFI tester to CHECK_ABI.
This uses the x86 trap flag and libunwind to test CFI works at each
instruction. For now, it just uses the system one out of pkg-config and
disables unwind tests if unavailable. We'll probably want to stick a
copy into //third_party and perhaps try the LLVM one later.
This tester caught two bugs in P-256 CFI annotations already:
I47b5f9798b3bcee1748e537b21c173d312a14b42 and
I9f576d868850312d6c14d1386f8fbfa85021b347
An earlier design used PTRACE_SINGLESTEP with libunwind's remote
unwinding features. ptrace is a mess around stop signals (see group-stop
discussion in ptrace(2)) and this is 10x faster, so I went with it. The
question of which is more future-proof is complex:
- There are two libunwinds with the same API,
https://www.nongnu.org/libunwind/ and LLVM's. This currently uses the
system nongnu.org for convenience. In future, LLVM's should be easier
to bundle (less complex build) and appears to even support Windows,
but I haven't tested this. Moreover, setting the trap flag keeps the
test single-process, which is less complex on Windows. That suggests
the trap flag design and switching to LLVM later. However...
- Not all architectures have a trap flag settable by userspace. As far
as I can tell, ARMv8's PSTATE.SS can only be set from the kernel. If
we stick with nongnu.org libunwind, we can use PTRACE_SINGLESTEP and
remote unwinding. Or we implement it for LLVM. Another thought is for
the ptracer to bounce SIGTRAP back into the process, to share the
local unwinding code.
- ARMv7 has no trap flag at all and PTRACE_SINGLESTEP fails. Debuggers
single-step by injecting breakpoints instead. However, ARMv8's trap
flag seems to work in both AArch32 and AArch64 modes, so we may be
able to condition it on a 64-bit kernel.
Sadly, neither strategy works with Intel SDE. Adding flags to cpucap
vectors as we do with ARM would help, but it would not emulate CPUs
newer than the host CPU. For now, I've just had SDE tests disable these.
Annoyingly, CMake does not allow object libraries to have dependencies,
so make test_support a proper static library. Rename the target to
test_support_lib to avoid
https://gitlab.kitware.com/cmake/cmake/issues/17785
Update-Note: This adds a new optional test dependency, but it's disabled
by default (define BORINGSSL_HAVE_LIBUNWIND), so consumers do not need
to do anything. We'll probably want to adjust this in the future.
Bug: 181
Change-Id: I817263d7907aff0904a9cee83f8b26747262cc0c
Reviewed-on: https://boringssl-review.googlesource.com/c/33966
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
2018-12-21 23:58:36 +00:00
|
|
|
test_function_ok = false;
|
2019-02-03 03:29:58 +00:00
|
|
|
EXPECT_EQ(42, CHECK_ABI_SEH(TestFunction, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10));
|
Add a CFI tester to CHECK_ABI.
This uses the x86 trap flag and libunwind to test CFI works at each
instruction. For now, it just uses the system one out of pkg-config and
disables unwind tests if unavailable. We'll probably want to stick a
copy into //third_party and perhaps try the LLVM one later.
This tester caught two bugs in P-256 CFI annotations already:
I47b5f9798b3bcee1748e537b21c173d312a14b42 and
I9f576d868850312d6c14d1386f8fbfa85021b347
An earlier design used PTRACE_SINGLESTEP with libunwind's remote
unwinding features. ptrace is a mess around stop signals (see group-stop
discussion in ptrace(2)) and this is 10x faster, so I went with it. The
question of which is more future-proof is complex:
- There are two libunwinds with the same API,
https://www.nongnu.org/libunwind/ and LLVM's. This currently uses the
system nongnu.org for convenience. In future, LLVM's should be easier
to bundle (less complex build) and appears to even support Windows,
but I haven't tested this. Moreover, setting the trap flag keeps the
test single-process, which is less complex on Windows. That suggests
the trap flag design and switching to LLVM later. However...
- Not all architectures have a trap flag settable by userspace. As far
as I can tell, ARMv8's PSTATE.SS can only be set from the kernel. If
we stick with nongnu.org libunwind, we can use PTRACE_SINGLESTEP and
remote unwinding. Or we implement it for LLVM. Another thought is for
the ptracer to bounce SIGTRAP back into the process, to share the
local unwinding code.
- ARMv7 has no trap flag at all and PTRACE_SINGLESTEP fails. Debuggers
single-step by injecting breakpoints instead. However, ARMv8's trap
flag seems to work in both AArch32 and AArch64 modes, so we may be
able to condition it on a 64-bit kernel.
Sadly, neither strategy works with Intel SDE. Adding flags to cpucap
vectors as we do with ARM would help, but it would not emulate CPUs
newer than the host CPU. For now, I've just had SDE tests disable these.
Annoyingly, CMake does not allow object libraries to have dependencies,
so make test_support a proper static library. Rename the target to
test_support_lib to avoid
https://gitlab.kitware.com/cmake/cmake/issues/17785
Update-Note: This adds a new optional test dependency, but it's disabled
by default (define BORINGSSL_HAVE_LIBUNWIND), so consumers do not need
to do anything. We'll probably want to adjust this in the future.
Bug: 181
Change-Id: I817263d7907aff0904a9cee83f8b26747262cc0c
Reviewed-on: https://boringssl-review.googlesource.com/c/33966
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
2018-12-21 23:58:36 +00:00
|
|
|
EXPECT_TRUE(test_function_ok);
|
Add an ABI testing framework.
Dear reader, I must apologize in advance. This CL contains the following:
- A new 256-line perlasm file with non-trivial perl bits and a dual-ABI
variadic function caller.
- C preprocessor gymnastics, with variadic macros and fun facts about
__VA_ARGS__'s behavior on empty argument lists.
- C++ template gymnastics, including variadic arguments, template
specialization, std::enable_if, and machinery to control template argument
deduction.
Enjoy.
This tests that our assembly functions correctly honor platform ABI
conventions. Right now this only tests callee-saved registers, but it should be
extendable to SEH/CFI unwind testing with single-step debugging APIs.
Register-checking does not involve anything funny and should be compatible with
SDE. (The future unwind testing is unlikely to be compatible.)
This CL adds support for x86_64 SysV and Win64 ABIs. ARM, AArch64, and x86 can
be added in the future. The testing is injected in two places. First, all the
assembly tests in p256-x86_64-test.cc are now instrumented. This is the
intended workflow and should capture all registers.
However, we currently do not unit-test our assembly much directly. We should do
that as follow-up work[0] but, in the meantime, I've also wrapped all of the GTest
main function in an ABI test. This is imperfect as ABI failures may be masked
by other stack frames, but it costs nothing[1] and is pretty reliable at
catching Win64 xmm register failures.
[0] An alternate strategy would be, in debug builds, unconditionally instrument
every assembly call in libcrypto. But the CHECK_ABI macro would be difficult to
replicate in pure C, and unwind testing may be too invasive for this. Still,
something to consider when we C++ libcrypto.
[1] When single-stepped unwind testing exists, it won't cost nothing. The
gtest_main.cc call will turn unwind testing off.
Change-Id: I6643b26445891fd46abfacac52bc024024c8d7f6
Reviewed-on: https://boringssl-review.googlesource.com/c/33764
Reviewed-by: Adam Langley <agl@google.com>
Reviewed-by: Adam Langley <alangley@gmail.com>
Commit-Queue: David Benjamin <davidben@google.com>
2018-12-16 00:58:43 +00:00
|
|
|
|
|
|
|
#if defined(SUPPORTS_ABI_TEST)
|
|
|
|
abi_test::internal::CallerState state;
|
|
|
|
RAND_bytes(reinterpret_cast<uint8_t *>(&state), sizeof(state));
|
2019-01-22 03:42:25 +00:00
|
|
|
crypto_word_t argv[] = {
|
|
|
|
1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
|
Add an ABI testing framework.
Dear reader, I must apologize in advance. This CL contains the following:
- A new 256-line perlasm file with non-trivial perl bits and a dual-ABI
variadic function caller.
- C preprocessor gymnastics, with variadic macros and fun facts about
__VA_ARGS__'s behavior on empty argument lists.
- C++ template gymnastics, including variadic arguments, template
specialization, std::enable_if, and machinery to control template argument
deduction.
Enjoy.
This tests that our assembly functions correctly honor platform ABI
conventions. Right now this only tests callee-saved registers, but it should be
extendable to SEH/CFI unwind testing with single-step debugging APIs.
Register-checking does not involve anything funny and should be compatible with
SDE. (The future unwind testing is unlikely to be compatible.)
This CL adds support for x86_64 SysV and Win64 ABIs. ARM, AArch64, and x86 can
be added in the future. The testing is injected in two places. First, all the
assembly tests in p256-x86_64-test.cc are now instrumented. This is the
intended workflow and should capture all registers.
However, we currently do not unit-test our assembly much directly. We should do
that as follow-up work[0] but, in the meantime, I've also wrapped all of the GTest
main function in an ABI test. This is imperfect as ABI failures may be masked
by other stack frames, but it costs nothing[1] and is pretty reliable at
catching Win64 xmm register failures.
[0] An alternate strategy would be, in debug builds, unconditionally instrument
every assembly call in libcrypto. But the CHECK_ABI macro would be difficult to
replicate in pure C, and unwind testing may be too invasive for this. Still,
something to consider when we C++ libcrypto.
[1] When single-stepped unwind testing exists, it won't cost nothing. The
gtest_main.cc call will turn unwind testing off.
Change-Id: I6643b26445891fd46abfacac52bc024024c8d7f6
Reviewed-on: https://boringssl-review.googlesource.com/c/33764
Reviewed-by: Adam Langley <agl@google.com>
Reviewed-by: Adam Langley <alangley@gmail.com>
Commit-Queue: David Benjamin <davidben@google.com>
2018-12-16 00:58:43 +00:00
|
|
|
};
|
2019-02-03 03:29:58 +00:00
|
|
|
CHECK_ABI_SEH(abi_test_trampoline,
|
|
|
|
reinterpret_cast<crypto_word_t>(TestFunction), &state, argv, 10,
|
|
|
|
0 /* no breakpoint */);
|
Add a CFI tester to CHECK_ABI.
This uses the x86 trap flag and libunwind to test CFI works at each
instruction. For now, it just uses the system one out of pkg-config and
disables unwind tests if unavailable. We'll probably want to stick a
copy into //third_party and perhaps try the LLVM one later.
This tester caught two bugs in P-256 CFI annotations already:
I47b5f9798b3bcee1748e537b21c173d312a14b42 and
I9f576d868850312d6c14d1386f8fbfa85021b347
An earlier design used PTRACE_SINGLESTEP with libunwind's remote
unwinding features. ptrace is a mess around stop signals (see group-stop
discussion in ptrace(2)) and this is 10x faster, so I went with it. The
question of which is more future-proof is complex:
- There are two libunwinds with the same API,
https://www.nongnu.org/libunwind/ and LLVM's. This currently uses the
system nongnu.org for convenience. In future, LLVM's should be easier
to bundle (less complex build) and appears to even support Windows,
but I haven't tested this. Moreover, setting the trap flag keeps the
test single-process, which is less complex on Windows. That suggests
the trap flag design and switching to LLVM later. However...
- Not all architectures have a trap flag settable by userspace. As far
as I can tell, ARMv8's PSTATE.SS can only be set from the kernel. If
we stick with nongnu.org libunwind, we can use PTRACE_SINGLESTEP and
remote unwinding. Or we implement it for LLVM. Another thought is for
the ptracer to bounce SIGTRAP back into the process, to share the
local unwinding code.
- ARMv7 has no trap flag at all and PTRACE_SINGLESTEP fails. Debuggers
single-step by injecting breakpoints instead. However, ARMv8's trap
flag seems to work in both AArch32 and AArch64 modes, so we may be
able to condition it on a 64-bit kernel.
Sadly, neither strategy works with Intel SDE. Adding flags to cpucap
vectors as we do with ARM would help, but it would not emulate CPUs
newer than the host CPU. For now, I've just had SDE tests disable these.
Annoyingly, CMake does not allow object libraries to have dependencies,
so make test_support a proper static library. Rename the target to
test_support_lib to avoid
https://gitlab.kitware.com/cmake/cmake/issues/17785
Update-Note: This adds a new optional test dependency, but it's disabled
by default (define BORINGSSL_HAVE_LIBUNWIND), so consumers do not need
to do anything. We'll probably want to adjust this in the future.
Bug: 181
Change-Id: I817263d7907aff0904a9cee83f8b26747262cc0c
Reviewed-on: https://boringssl-review.googlesource.com/c/33966
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
2018-12-21 23:58:36 +00:00
|
|
|
|
2019-01-26 17:29:08 +00:00
|
|
|
#if defined(OPENSSL_X86_64)
|
Add a CFI tester to CHECK_ABI.
This uses the x86 trap flag and libunwind to test CFI works at each
instruction. For now, it just uses the system one out of pkg-config and
disables unwind tests if unavailable. We'll probably want to stick a
copy into //third_party and perhaps try the LLVM one later.
This tester caught two bugs in P-256 CFI annotations already:
I47b5f9798b3bcee1748e537b21c173d312a14b42 and
I9f576d868850312d6c14d1386f8fbfa85021b347
An earlier design used PTRACE_SINGLESTEP with libunwind's remote
unwinding features. ptrace is a mess around stop signals (see group-stop
discussion in ptrace(2)) and this is 10x faster, so I went with it. The
question of which is more future-proof is complex:
- There are two libunwinds with the same API,
https://www.nongnu.org/libunwind/ and LLVM's. This currently uses the
system nongnu.org for convenience. In future, LLVM's should be easier
to bundle (less complex build) and appears to even support Windows,
but I haven't tested this. Moreover, setting the trap flag keeps the
test single-process, which is less complex on Windows. That suggests
the trap flag design and switching to LLVM later. However...
- Not all architectures have a trap flag settable by userspace. As far
as I can tell, ARMv8's PSTATE.SS can only be set from the kernel. If
we stick with nongnu.org libunwind, we can use PTRACE_SINGLESTEP and
remote unwinding. Or we implement it for LLVM. Another thought is for
the ptracer to bounce SIGTRAP back into the process, to share the
local unwinding code.
- ARMv7 has no trap flag at all and PTRACE_SINGLESTEP fails. Debuggers
single-step by injecting breakpoints instead. However, ARMv8's trap
flag seems to work in both AArch32 and AArch64 modes, so we may be
able to condition it on a 64-bit kernel.
Sadly, neither strategy works with Intel SDE. Adding flags to cpucap
vectors as we do with ARM would help, but it would not emulate CPUs
newer than the host CPU. For now, I've just had SDE tests disable these.
Annoyingly, CMake does not allow object libraries to have dependencies,
so make test_support a proper static library. Rename the target to
test_support_lib to avoid
https://gitlab.kitware.com/cmake/cmake/issues/17785
Update-Note: This adds a new optional test dependency, but it's disabled
by default (define BORINGSSL_HAVE_LIBUNWIND), so consumers do not need
to do anything. We'll probably want to adjust this in the future.
Bug: 181
Change-Id: I817263d7907aff0904a9cee83f8b26747262cc0c
Reviewed-on: https://boringssl-review.googlesource.com/c/33966
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
2018-12-21 23:58:36 +00:00
|
|
|
if (abi_test::UnwindTestsEnabled()) {
|
2019-02-03 03:29:58 +00:00
|
|
|
EXPECT_NONFATAL_FAILURE(CHECK_ABI_SEH(abi_test_bad_unwind_wrong_register),
|
Add a CFI tester to CHECK_ABI.
This uses the x86 trap flag and libunwind to test CFI works at each
instruction. For now, it just uses the system one out of pkg-config and
disables unwind tests if unavailable. We'll probably want to stick a
copy into //third_party and perhaps try the LLVM one later.
This tester caught two bugs in P-256 CFI annotations already:
I47b5f9798b3bcee1748e537b21c173d312a14b42 and
I9f576d868850312d6c14d1386f8fbfa85021b347
An earlier design used PTRACE_SINGLESTEP with libunwind's remote
unwinding features. ptrace is a mess around stop signals (see group-stop
discussion in ptrace(2)) and this is 10x faster, so I went with it. The
question of which is more future-proof is complex:
- There are two libunwinds with the same API,
https://www.nongnu.org/libunwind/ and LLVM's. This currently uses the
system nongnu.org for convenience. In future, LLVM's should be easier
to bundle (less complex build) and appears to even support Windows,
but I haven't tested this. Moreover, setting the trap flag keeps the
test single-process, which is less complex on Windows. That suggests
the trap flag design and switching to LLVM later. However...
- Not all architectures have a trap flag settable by userspace. As far
as I can tell, ARMv8's PSTATE.SS can only be set from the kernel. If
we stick with nongnu.org libunwind, we can use PTRACE_SINGLESTEP and
remote unwinding. Or we implement it for LLVM. Another thought is for
the ptracer to bounce SIGTRAP back into the process, to share the
local unwinding code.
- ARMv7 has no trap flag at all and PTRACE_SINGLESTEP fails. Debuggers
single-step by injecting breakpoints instead. However, ARMv8's trap
flag seems to work in both AArch32 and AArch64 modes, so we may be
able to condition it on a 64-bit kernel.
Sadly, neither strategy works with Intel SDE. Adding flags to cpucap
vectors as we do with ARM would help, but it would not emulate CPUs
newer than the host CPU. For now, I've just had SDE tests disable these.
Annoyingly, CMake does not allow object libraries to have dependencies,
so make test_support a proper static library. Rename the target to
test_support_lib to avoid
https://gitlab.kitware.com/cmake/cmake/issues/17785
Update-Note: This adds a new optional test dependency, but it's disabled
by default (define BORINGSSL_HAVE_LIBUNWIND), so consumers do not need
to do anything. We'll probably want to adjust this in the future.
Bug: 181
Change-Id: I817263d7907aff0904a9cee83f8b26747262cc0c
Reviewed-on: https://boringssl-review.googlesource.com/c/33966
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
2018-12-21 23:58:36 +00:00
|
|
|
"was not recovered unwinding");
|
2019-02-03 03:29:58 +00:00
|
|
|
EXPECT_NONFATAL_FAILURE(CHECK_ABI_SEH(abi_test_bad_unwind_temporary),
|
Add a CFI tester to CHECK_ABI.
This uses the x86 trap flag and libunwind to test CFI works at each
instruction. For now, it just uses the system one out of pkg-config and
disables unwind tests if unavailable. We'll probably want to stick a
copy into //third_party and perhaps try the LLVM one later.
This tester caught two bugs in P-256 CFI annotations already:
I47b5f9798b3bcee1748e537b21c173d312a14b42 and
I9f576d868850312d6c14d1386f8fbfa85021b347
An earlier design used PTRACE_SINGLESTEP with libunwind's remote
unwinding features. ptrace is a mess around stop signals (see group-stop
discussion in ptrace(2)) and this is 10x faster, so I went with it. The
question of which is more future-proof is complex:
- There are two libunwinds with the same API,
https://www.nongnu.org/libunwind/ and LLVM's. This currently uses the
system nongnu.org for convenience. In future, LLVM's should be easier
to bundle (less complex build) and appears to even support Windows,
but I haven't tested this. Moreover, setting the trap flag keeps the
test single-process, which is less complex on Windows. That suggests
the trap flag design and switching to LLVM later. However...
- Not all architectures have a trap flag settable by userspace. As far
as I can tell, ARMv8's PSTATE.SS can only be set from the kernel. If
we stick with nongnu.org libunwind, we can use PTRACE_SINGLESTEP and
remote unwinding. Or we implement it for LLVM. Another thought is for
the ptracer to bounce SIGTRAP back into the process, to share the
local unwinding code.
- ARMv7 has no trap flag at all and PTRACE_SINGLESTEP fails. Debuggers
single-step by injecting breakpoints instead. However, ARMv8's trap
flag seems to work in both AArch32 and AArch64 modes, so we may be
able to condition it on a 64-bit kernel.
Sadly, neither strategy works with Intel SDE. Adding flags to cpucap
vectors as we do with ARM would help, but it would not emulate CPUs
newer than the host CPU. For now, I've just had SDE tests disable these.
Annoyingly, CMake does not allow object libraries to have dependencies,
so make test_support a proper static library. Rename the target to
test_support_lib to avoid
https://gitlab.kitware.com/cmake/cmake/issues/17785
Update-Note: This adds a new optional test dependency, but it's disabled
by default (define BORINGSSL_HAVE_LIBUNWIND), so consumers do not need
to do anything. We'll probably want to adjust this in the future.
Bug: 181
Change-Id: I817263d7907aff0904a9cee83f8b26747262cc0c
Reviewed-on: https://boringssl-review.googlesource.com/c/33966
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
2018-12-21 23:58:36 +00:00
|
|
|
"was not recovered unwinding");
|
|
|
|
|
|
|
|
CHECK_ABI_NO_UNWIND(abi_test_bad_unwind_wrong_register);
|
|
|
|
CHECK_ABI_NO_UNWIND(abi_test_bad_unwind_temporary);
|
2019-02-03 03:29:58 +00:00
|
|
|
|
|
|
|
#if defined(OPENSSL_WINDOWS)
|
|
|
|
// The invalid epilog makes Windows believe the epilog starts later than it
|
|
|
|
// actually does. As a result, immediately after the popq, it does not
|
|
|
|
// realize the stack has been unwound and repeats the work.
|
|
|
|
EXPECT_NONFATAL_FAILURE(CHECK_ABI_SEH(abi_test_bad_unwind_epilog),
|
|
|
|
"unwound past starting frame");
|
|
|
|
CHECK_ABI_NO_UNWIND(abi_test_bad_unwind_epilog);
|
|
|
|
#endif // OPENSSL_WINDOWS
|
Add a CFI tester to CHECK_ABI.
This uses the x86 trap flag and libunwind to test CFI works at each
instruction. For now, it just uses the system one out of pkg-config and
disables unwind tests if unavailable. We'll probably want to stick a
copy into //third_party and perhaps try the LLVM one later.
This tester caught two bugs in P-256 CFI annotations already:
I47b5f9798b3bcee1748e537b21c173d312a14b42 and
I9f576d868850312d6c14d1386f8fbfa85021b347
An earlier design used PTRACE_SINGLESTEP with libunwind's remote
unwinding features. ptrace is a mess around stop signals (see group-stop
discussion in ptrace(2)) and this is 10x faster, so I went with it. The
question of which is more future-proof is complex:
- There are two libunwinds with the same API,
https://www.nongnu.org/libunwind/ and LLVM's. This currently uses the
system nongnu.org for convenience. In future, LLVM's should be easier
to bundle (less complex build) and appears to even support Windows,
but I haven't tested this. Moreover, setting the trap flag keeps the
test single-process, which is less complex on Windows. That suggests
the trap flag design and switching to LLVM later. However...
- Not all architectures have a trap flag settable by userspace. As far
as I can tell, ARMv8's PSTATE.SS can only be set from the kernel. If
we stick with nongnu.org libunwind, we can use PTRACE_SINGLESTEP and
remote unwinding. Or we implement it for LLVM. Another thought is for
the ptracer to bounce SIGTRAP back into the process, to share the
local unwinding code.
- ARMv7 has no trap flag at all and PTRACE_SINGLESTEP fails. Debuggers
single-step by injecting breakpoints instead. However, ARMv8's trap
flag seems to work in both AArch32 and AArch64 modes, so we may be
able to condition it on a 64-bit kernel.
Sadly, neither strategy works with Intel SDE. Adding flags to cpucap
vectors as we do with ARM would help, but it would not emulate CPUs
newer than the host CPU. For now, I've just had SDE tests disable these.
Annoyingly, CMake does not allow object libraries to have dependencies,
so make test_support a proper static library. Rename the target to
test_support_lib to avoid
https://gitlab.kitware.com/cmake/cmake/issues/17785
Update-Note: This adds a new optional test dependency, but it's disabled
by default (define BORINGSSL_HAVE_LIBUNWIND), so consumers do not need
to do anything. We'll probably want to adjust this in the future.
Bug: 181
Change-Id: I817263d7907aff0904a9cee83f8b26747262cc0c
Reviewed-on: https://boringssl-review.googlesource.com/c/33966
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
2018-12-21 23:58:36 +00:00
|
|
|
}
|
2019-01-26 17:29:08 +00:00
|
|
|
#endif // OPENSSL_X86_64
|
Add an ABI testing framework.
Dear reader, I must apologize in advance. This CL contains the following:
- A new 256-line perlasm file with non-trivial perl bits and a dual-ABI
variadic function caller.
- C preprocessor gymnastics, with variadic macros and fun facts about
__VA_ARGS__'s behavior on empty argument lists.
- C++ template gymnastics, including variadic arguments, template
specialization, std::enable_if, and machinery to control template argument
deduction.
Enjoy.
This tests that our assembly functions correctly honor platform ABI
conventions. Right now this only tests callee-saved registers, but it should be
extendable to SEH/CFI unwind testing with single-step debugging APIs.
Register-checking does not involve anything funny and should be compatible with
SDE. (The future unwind testing is unlikely to be compatible.)
This CL adds support for x86_64 SysV and Win64 ABIs. ARM, AArch64, and x86 can
be added in the future. The testing is injected in two places. First, all the
assembly tests in p256-x86_64-test.cc are now instrumented. This is the
intended workflow and should capture all registers.
However, we currently do not unit-test our assembly much directly. We should do
that as follow-up work[0] but, in the meantime, I've also wrapped all of the GTest
main function in an ABI test. This is imperfect as ABI failures may be masked
by other stack frames, but it costs nothing[1] and is pretty reliable at
catching Win64 xmm register failures.
[0] An alternate strategy would be, in debug builds, unconditionally instrument
every assembly call in libcrypto. But the CHECK_ABI macro would be difficult to
replicate in pure C, and unwind testing may be too invasive for this. Still,
something to consider when we C++ libcrypto.
[1] When single-stepped unwind testing exists, it won't cost nothing. The
gtest_main.cc call will turn unwind testing off.
Change-Id: I6643b26445891fd46abfacac52bc024024c8d7f6
Reviewed-on: https://boringssl-review.googlesource.com/c/33764
Reviewed-by: Adam Langley <agl@google.com>
Reviewed-by: Adam Langley <alangley@gmail.com>
Commit-Queue: David Benjamin <davidben@google.com>
2018-12-16 00:58:43 +00:00
|
|
|
#endif // SUPPORTS_ABI_TEST
|
|
|
|
}
|
|
|
|
|
|
|
|
#if defined(OPENSSL_X86_64) && defined(SUPPORTS_ABI_TEST)
|
|
|
|
extern "C" {
|
|
|
|
void abi_test_clobber_rax(void);
|
|
|
|
void abi_test_clobber_rbx(void);
|
|
|
|
void abi_test_clobber_rcx(void);
|
|
|
|
void abi_test_clobber_rdx(void);
|
|
|
|
void abi_test_clobber_rsi(void);
|
|
|
|
void abi_test_clobber_rdi(void);
|
|
|
|
void abi_test_clobber_rbp(void);
|
|
|
|
void abi_test_clobber_r8(void);
|
|
|
|
void abi_test_clobber_r9(void);
|
|
|
|
void abi_test_clobber_r10(void);
|
|
|
|
void abi_test_clobber_r11(void);
|
|
|
|
void abi_test_clobber_r12(void);
|
|
|
|
void abi_test_clobber_r13(void);
|
|
|
|
void abi_test_clobber_r14(void);
|
|
|
|
void abi_test_clobber_r15(void);
|
|
|
|
void abi_test_clobber_xmm0(void);
|
|
|
|
void abi_test_clobber_xmm1(void);
|
|
|
|
void abi_test_clobber_xmm2(void);
|
|
|
|
void abi_test_clobber_xmm3(void);
|
|
|
|
void abi_test_clobber_xmm4(void);
|
|
|
|
void abi_test_clobber_xmm5(void);
|
|
|
|
void abi_test_clobber_xmm6(void);
|
|
|
|
void abi_test_clobber_xmm7(void);
|
|
|
|
void abi_test_clobber_xmm8(void);
|
|
|
|
void abi_test_clobber_xmm9(void);
|
|
|
|
void abi_test_clobber_xmm10(void);
|
|
|
|
void abi_test_clobber_xmm11(void);
|
|
|
|
void abi_test_clobber_xmm12(void);
|
|
|
|
void abi_test_clobber_xmm13(void);
|
|
|
|
void abi_test_clobber_xmm14(void);
|
|
|
|
void abi_test_clobber_xmm15(void);
|
|
|
|
} // extern "C"
|
|
|
|
|
|
|
|
TEST(ABITest, X86_64) {
|
|
|
|
// abi_test_trampoline hides unsaved registers from the caller, so we can
|
|
|
|
// safely call the abi_test_clobber_* functions below.
|
|
|
|
abi_test::internal::CallerState state;
|
|
|
|
RAND_bytes(reinterpret_cast<uint8_t *>(&state), sizeof(state));
|
Add a CFI tester to CHECK_ABI.
This uses the x86 trap flag and libunwind to test CFI works at each
instruction. For now, it just uses the system one out of pkg-config and
disables unwind tests if unavailable. We'll probably want to stick a
copy into //third_party and perhaps try the LLVM one later.
This tester caught two bugs in P-256 CFI annotations already:
I47b5f9798b3bcee1748e537b21c173d312a14b42 and
I9f576d868850312d6c14d1386f8fbfa85021b347
An earlier design used PTRACE_SINGLESTEP with libunwind's remote
unwinding features. ptrace is a mess around stop signals (see group-stop
discussion in ptrace(2)) and this is 10x faster, so I went with it. The
question of which is more future-proof is complex:
- There are two libunwinds with the same API,
https://www.nongnu.org/libunwind/ and LLVM's. This currently uses the
system nongnu.org for convenience. In future, LLVM's should be easier
to bundle (less complex build) and appears to even support Windows,
but I haven't tested this. Moreover, setting the trap flag keeps the
test single-process, which is less complex on Windows. That suggests
the trap flag design and switching to LLVM later. However...
- Not all architectures have a trap flag settable by userspace. As far
as I can tell, ARMv8's PSTATE.SS can only be set from the kernel. If
we stick with nongnu.org libunwind, we can use PTRACE_SINGLESTEP and
remote unwinding. Or we implement it for LLVM. Another thought is for
the ptracer to bounce SIGTRAP back into the process, to share the
local unwinding code.
- ARMv7 has no trap flag at all and PTRACE_SINGLESTEP fails. Debuggers
single-step by injecting breakpoints instead. However, ARMv8's trap
flag seems to work in both AArch32 and AArch64 modes, so we may be
able to condition it on a 64-bit kernel.
Sadly, neither strategy works with Intel SDE. Adding flags to cpucap
vectors as we do with ARM would help, but it would not emulate CPUs
newer than the host CPU. For now, I've just had SDE tests disable these.
Annoyingly, CMake does not allow object libraries to have dependencies,
so make test_support a proper static library. Rename the target to
test_support_lib to avoid
https://gitlab.kitware.com/cmake/cmake/issues/17785
Update-Note: This adds a new optional test dependency, but it's disabled
by default (define BORINGSSL_HAVE_LIBUNWIND), so consumers do not need
to do anything. We'll probably want to adjust this in the future.
Bug: 181
Change-Id: I817263d7907aff0904a9cee83f8b26747262cc0c
Reviewed-on: https://boringssl-review.googlesource.com/c/33966
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
2018-12-21 23:58:36 +00:00
|
|
|
CHECK_ABI_NO_UNWIND(abi_test_trampoline,
|
|
|
|
reinterpret_cast<crypto_word_t>(abi_test_clobber_rbx),
|
|
|
|
&state, nullptr, 0, 0 /* no breakpoint */);
|
|
|
|
|
|
|
|
CHECK_ABI_NO_UNWIND(abi_test_clobber_rax);
|
|
|
|
EXPECT_NONFATAL_FAILURE(CHECK_ABI_NO_UNWIND(abi_test_clobber_rbx),
|
|
|
|
"rbx was not restored after return");
|
|
|
|
CHECK_ABI_NO_UNWIND(abi_test_clobber_rcx);
|
|
|
|
CHECK_ABI_NO_UNWIND(abi_test_clobber_rdx);
|
Add an ABI testing framework.
Dear reader, I must apologize in advance. This CL contains the following:
- A new 256-line perlasm file with non-trivial perl bits and a dual-ABI
variadic function caller.
- C preprocessor gymnastics, with variadic macros and fun facts about
__VA_ARGS__'s behavior on empty argument lists.
- C++ template gymnastics, including variadic arguments, template
specialization, std::enable_if, and machinery to control template argument
deduction.
Enjoy.
This tests that our assembly functions correctly honor platform ABI
conventions. Right now this only tests callee-saved registers, but it should be
extendable to SEH/CFI unwind testing with single-step debugging APIs.
Register-checking does not involve anything funny and should be compatible with
SDE. (The future unwind testing is unlikely to be compatible.)
This CL adds support for x86_64 SysV and Win64 ABIs. ARM, AArch64, and x86 can
be added in the future. The testing is injected in two places. First, all the
assembly tests in p256-x86_64-test.cc are now instrumented. This is the
intended workflow and should capture all registers.
However, we currently do not unit-test our assembly much directly. We should do
that as follow-up work[0] but, in the meantime, I've also wrapped all of the GTest
main function in an ABI test. This is imperfect as ABI failures may be masked
by other stack frames, but it costs nothing[1] and is pretty reliable at
catching Win64 xmm register failures.
[0] An alternate strategy would be, in debug builds, unconditionally instrument
every assembly call in libcrypto. But the CHECK_ABI macro would be difficult to
replicate in pure C, and unwind testing may be too invasive for this. Still,
something to consider when we C++ libcrypto.
[1] When single-stepped unwind testing exists, it won't cost nothing. The
gtest_main.cc call will turn unwind testing off.
Change-Id: I6643b26445891fd46abfacac52bc024024c8d7f6
Reviewed-on: https://boringssl-review.googlesource.com/c/33764
Reviewed-by: Adam Langley <agl@google.com>
Reviewed-by: Adam Langley <alangley@gmail.com>
Commit-Queue: David Benjamin <davidben@google.com>
2018-12-16 00:58:43 +00:00
|
|
|
#if defined(OPENSSL_WINDOWS)
|
Add a CFI tester to CHECK_ABI.
This uses the x86 trap flag and libunwind to test CFI works at each
instruction. For now, it just uses the system one out of pkg-config and
disables unwind tests if unavailable. We'll probably want to stick a
copy into //third_party and perhaps try the LLVM one later.
This tester caught two bugs in P-256 CFI annotations already:
I47b5f9798b3bcee1748e537b21c173d312a14b42 and
I9f576d868850312d6c14d1386f8fbfa85021b347
An earlier design used PTRACE_SINGLESTEP with libunwind's remote
unwinding features. ptrace is a mess around stop signals (see group-stop
discussion in ptrace(2)) and this is 10x faster, so I went with it. The
question of which is more future-proof is complex:
- There are two libunwinds with the same API,
https://www.nongnu.org/libunwind/ and LLVM's. This currently uses the
system nongnu.org for convenience. In future, LLVM's should be easier
to bundle (less complex build) and appears to even support Windows,
but I haven't tested this. Moreover, setting the trap flag keeps the
test single-process, which is less complex on Windows. That suggests
the trap flag design and switching to LLVM later. However...
- Not all architectures have a trap flag settable by userspace. As far
as I can tell, ARMv8's PSTATE.SS can only be set from the kernel. If
we stick with nongnu.org libunwind, we can use PTRACE_SINGLESTEP and
remote unwinding. Or we implement it for LLVM. Another thought is for
the ptracer to bounce SIGTRAP back into the process, to share the
local unwinding code.
- ARMv7 has no trap flag at all and PTRACE_SINGLESTEP fails. Debuggers
single-step by injecting breakpoints instead. However, ARMv8's trap
flag seems to work in both AArch32 and AArch64 modes, so we may be
able to condition it on a 64-bit kernel.
Sadly, neither strategy works with Intel SDE. Adding flags to cpucap
vectors as we do with ARM would help, but it would not emulate CPUs
newer than the host CPU. For now, I've just had SDE tests disable these.
Annoyingly, CMake does not allow object libraries to have dependencies,
so make test_support a proper static library. Rename the target to
test_support_lib to avoid
https://gitlab.kitware.com/cmake/cmake/issues/17785
Update-Note: This adds a new optional test dependency, but it's disabled
by default (define BORINGSSL_HAVE_LIBUNWIND), so consumers do not need
to do anything. We'll probably want to adjust this in the future.
Bug: 181
Change-Id: I817263d7907aff0904a9cee83f8b26747262cc0c
Reviewed-on: https://boringssl-review.googlesource.com/c/33966
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
2018-12-21 23:58:36 +00:00
|
|
|
EXPECT_NONFATAL_FAILURE(CHECK_ABI_NO_UNWIND(abi_test_clobber_rdi),
|
|
|
|
"rdi was not restored after return");
|
|
|
|
EXPECT_NONFATAL_FAILURE(CHECK_ABI_NO_UNWIND(abi_test_clobber_rsi),
|
|
|
|
"rsi was not restored after return");
|
Add an ABI testing framework.
Dear reader, I must apologize in advance. This CL contains the following:
- A new 256-line perlasm file with non-trivial perl bits and a dual-ABI
variadic function caller.
- C preprocessor gymnastics, with variadic macros and fun facts about
__VA_ARGS__'s behavior on empty argument lists.
- C++ template gymnastics, including variadic arguments, template
specialization, std::enable_if, and machinery to control template argument
deduction.
Enjoy.
This tests that our assembly functions correctly honor platform ABI
conventions. Right now this only tests callee-saved registers, but it should be
extendable to SEH/CFI unwind testing with single-step debugging APIs.
Register-checking does not involve anything funny and should be compatible with
SDE. (The future unwind testing is unlikely to be compatible.)
This CL adds support for x86_64 SysV and Win64 ABIs. ARM, AArch64, and x86 can
be added in the future. The testing is injected in two places. First, all the
assembly tests in p256-x86_64-test.cc are now instrumented. This is the
intended workflow and should capture all registers.
However, we currently do not unit-test our assembly much directly. We should do
that as follow-up work[0] but, in the meantime, I've also wrapped all of the GTest
main function in an ABI test. This is imperfect as ABI failures may be masked
by other stack frames, but it costs nothing[1] and is pretty reliable at
catching Win64 xmm register failures.
[0] An alternate strategy would be, in debug builds, unconditionally instrument
every assembly call in libcrypto. But the CHECK_ABI macro would be difficult to
replicate in pure C, and unwind testing may be too invasive for this. Still,
something to consider when we C++ libcrypto.
[1] When single-stepped unwind testing exists, it won't cost nothing. The
gtest_main.cc call will turn unwind testing off.
Change-Id: I6643b26445891fd46abfacac52bc024024c8d7f6
Reviewed-on: https://boringssl-review.googlesource.com/c/33764
Reviewed-by: Adam Langley <agl@google.com>
Reviewed-by: Adam Langley <alangley@gmail.com>
Commit-Queue: David Benjamin <davidben@google.com>
2018-12-16 00:58:43 +00:00
|
|
|
#else
|
Add a CFI tester to CHECK_ABI.
This uses the x86 trap flag and libunwind to test CFI works at each
instruction. For now, it just uses the system one out of pkg-config and
disables unwind tests if unavailable. We'll probably want to stick a
copy into //third_party and perhaps try the LLVM one later.
This tester caught two bugs in P-256 CFI annotations already:
I47b5f9798b3bcee1748e537b21c173d312a14b42 and
I9f576d868850312d6c14d1386f8fbfa85021b347
An earlier design used PTRACE_SINGLESTEP with libunwind's remote
unwinding features. ptrace is a mess around stop signals (see group-stop
discussion in ptrace(2)) and this is 10x faster, so I went with it. The
question of which is more future-proof is complex:
- There are two libunwinds with the same API,
https://www.nongnu.org/libunwind/ and LLVM's. This currently uses the
system nongnu.org for convenience. In future, LLVM's should be easier
to bundle (less complex build) and appears to even support Windows,
but I haven't tested this. Moreover, setting the trap flag keeps the
test single-process, which is less complex on Windows. That suggests
the trap flag design and switching to LLVM later. However...
- Not all architectures have a trap flag settable by userspace. As far
as I can tell, ARMv8's PSTATE.SS can only be set from the kernel. If
we stick with nongnu.org libunwind, we can use PTRACE_SINGLESTEP and
remote unwinding. Or we implement it for LLVM. Another thought is for
the ptracer to bounce SIGTRAP back into the process, to share the
local unwinding code.
- ARMv7 has no trap flag at all and PTRACE_SINGLESTEP fails. Debuggers
single-step by injecting breakpoints instead. However, ARMv8's trap
flag seems to work in both AArch32 and AArch64 modes, so we may be
able to condition it on a 64-bit kernel.
Sadly, neither strategy works with Intel SDE. Adding flags to cpucap
vectors as we do with ARM would help, but it would not emulate CPUs
newer than the host CPU. For now, I've just had SDE tests disable these.
Annoyingly, CMake does not allow object libraries to have dependencies,
so make test_support a proper static library. Rename the target to
test_support_lib to avoid
https://gitlab.kitware.com/cmake/cmake/issues/17785
Update-Note: This adds a new optional test dependency, but it's disabled
by default (define BORINGSSL_HAVE_LIBUNWIND), so consumers do not need
to do anything. We'll probably want to adjust this in the future.
Bug: 181
Change-Id: I817263d7907aff0904a9cee83f8b26747262cc0c
Reviewed-on: https://boringssl-review.googlesource.com/c/33966
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
2018-12-21 23:58:36 +00:00
|
|
|
CHECK_ABI_NO_UNWIND(abi_test_clobber_rdi);
|
|
|
|
CHECK_ABI_NO_UNWIND(abi_test_clobber_rsi);
|
Add an ABI testing framework.
Dear reader, I must apologize in advance. This CL contains the following:
- A new 256-line perlasm file with non-trivial perl bits and a dual-ABI
variadic function caller.
- C preprocessor gymnastics, with variadic macros and fun facts about
__VA_ARGS__'s behavior on empty argument lists.
- C++ template gymnastics, including variadic arguments, template
specialization, std::enable_if, and machinery to control template argument
deduction.
Enjoy.
This tests that our assembly functions correctly honor platform ABI
conventions. Right now this only tests callee-saved registers, but it should be
extendable to SEH/CFI unwind testing with single-step debugging APIs.
Register-checking does not involve anything funny and should be compatible with
SDE. (The future unwind testing is unlikely to be compatible.)
This CL adds support for x86_64 SysV and Win64 ABIs. ARM, AArch64, and x86 can
be added in the future. The testing is injected in two places. First, all the
assembly tests in p256-x86_64-test.cc are now instrumented. This is the
intended workflow and should capture all registers.
However, we currently do not unit-test our assembly much directly. We should do
that as follow-up work[0] but, in the meantime, I've also wrapped all of the GTest
main function in an ABI test. This is imperfect as ABI failures may be masked
by other stack frames, but it costs nothing[1] and is pretty reliable at
catching Win64 xmm register failures.
[0] An alternate strategy would be, in debug builds, unconditionally instrument
every assembly call in libcrypto. But the CHECK_ABI macro would be difficult to
replicate in pure C, and unwind testing may be too invasive for this. Still,
something to consider when we C++ libcrypto.
[1] When single-stepped unwind testing exists, it won't cost nothing. The
gtest_main.cc call will turn unwind testing off.
Change-Id: I6643b26445891fd46abfacac52bc024024c8d7f6
Reviewed-on: https://boringssl-review.googlesource.com/c/33764
Reviewed-by: Adam Langley <agl@google.com>
Reviewed-by: Adam Langley <alangley@gmail.com>
Commit-Queue: David Benjamin <davidben@google.com>
2018-12-16 00:58:43 +00:00
|
|
|
#endif
|
Add a CFI tester to CHECK_ABI.
This uses the x86 trap flag and libunwind to test CFI works at each
instruction. For now, it just uses the system one out of pkg-config and
disables unwind tests if unavailable. We'll probably want to stick a
copy into //third_party and perhaps try the LLVM one later.
This tester caught two bugs in P-256 CFI annotations already:
I47b5f9798b3bcee1748e537b21c173d312a14b42 and
I9f576d868850312d6c14d1386f8fbfa85021b347
An earlier design used PTRACE_SINGLESTEP with libunwind's remote
unwinding features. ptrace is a mess around stop signals (see group-stop
discussion in ptrace(2)) and this is 10x faster, so I went with it. The
question of which is more future-proof is complex:
- There are two libunwinds with the same API,
https://www.nongnu.org/libunwind/ and LLVM's. This currently uses the
system nongnu.org for convenience. In future, LLVM's should be easier
to bundle (less complex build) and appears to even support Windows,
but I haven't tested this. Moreover, setting the trap flag keeps the
test single-process, which is less complex on Windows. That suggests
the trap flag design and switching to LLVM later. However...
- Not all architectures have a trap flag settable by userspace. As far
as I can tell, ARMv8's PSTATE.SS can only be set from the kernel. If
we stick with nongnu.org libunwind, we can use PTRACE_SINGLESTEP and
remote unwinding. Or we implement it for LLVM. Another thought is for
the ptracer to bounce SIGTRAP back into the process, to share the
local unwinding code.
- ARMv7 has no trap flag at all and PTRACE_SINGLESTEP fails. Debuggers
single-step by injecting breakpoints instead. However, ARMv8's trap
flag seems to work in both AArch32 and AArch64 modes, so we may be
able to condition it on a 64-bit kernel.
Sadly, neither strategy works with Intel SDE. Adding flags to cpucap
vectors as we do with ARM would help, but it would not emulate CPUs
newer than the host CPU. For now, I've just had SDE tests disable these.
Annoyingly, CMake does not allow object libraries to have dependencies,
so make test_support a proper static library. Rename the target to
test_support_lib to avoid
https://gitlab.kitware.com/cmake/cmake/issues/17785
Update-Note: This adds a new optional test dependency, but it's disabled
by default (define BORINGSSL_HAVE_LIBUNWIND), so consumers do not need
to do anything. We'll probably want to adjust this in the future.
Bug: 181
Change-Id: I817263d7907aff0904a9cee83f8b26747262cc0c
Reviewed-on: https://boringssl-review.googlesource.com/c/33966
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
2018-12-21 23:58:36 +00:00
|
|
|
EXPECT_NONFATAL_FAILURE(CHECK_ABI_NO_UNWIND(abi_test_clobber_rbp),
|
|
|
|
"rbp was not restored after return");
|
|
|
|
CHECK_ABI_NO_UNWIND(abi_test_clobber_r8);
|
|
|
|
CHECK_ABI_NO_UNWIND(abi_test_clobber_r9);
|
|
|
|
CHECK_ABI_NO_UNWIND(abi_test_clobber_r10);
|
|
|
|
CHECK_ABI_NO_UNWIND(abi_test_clobber_r11);
|
|
|
|
EXPECT_NONFATAL_FAILURE(CHECK_ABI_NO_UNWIND(abi_test_clobber_r12),
|
|
|
|
"r12 was not restored after return");
|
|
|
|
EXPECT_NONFATAL_FAILURE(CHECK_ABI_NO_UNWIND(abi_test_clobber_r13),
|
|
|
|
"r13 was not restored after return");
|
|
|
|
EXPECT_NONFATAL_FAILURE(CHECK_ABI_NO_UNWIND(abi_test_clobber_r14),
|
|
|
|
"r14 was not restored after return");
|
|
|
|
EXPECT_NONFATAL_FAILURE(CHECK_ABI_NO_UNWIND(abi_test_clobber_r15),
|
|
|
|
"r15 was not restored after return");
|
|
|
|
|
|
|
|
CHECK_ABI_NO_UNWIND(abi_test_clobber_xmm0);
|
|
|
|
CHECK_ABI_NO_UNWIND(abi_test_clobber_xmm1);
|
|
|
|
CHECK_ABI_NO_UNWIND(abi_test_clobber_xmm2);
|
|
|
|
CHECK_ABI_NO_UNWIND(abi_test_clobber_xmm3);
|
|
|
|
CHECK_ABI_NO_UNWIND(abi_test_clobber_xmm4);
|
|
|
|
CHECK_ABI_NO_UNWIND(abi_test_clobber_xmm5);
|
Add an ABI testing framework.
Dear reader, I must apologize in advance. This CL contains the following:
- A new 256-line perlasm file with non-trivial perl bits and a dual-ABI
variadic function caller.
- C preprocessor gymnastics, with variadic macros and fun facts about
__VA_ARGS__'s behavior on empty argument lists.
- C++ template gymnastics, including variadic arguments, template
specialization, std::enable_if, and machinery to control template argument
deduction.
Enjoy.
This tests that our assembly functions correctly honor platform ABI
conventions. Right now this only tests callee-saved registers, but it should be
extendable to SEH/CFI unwind testing with single-step debugging APIs.
Register-checking does not involve anything funny and should be compatible with
SDE. (The future unwind testing is unlikely to be compatible.)
This CL adds support for x86_64 SysV and Win64 ABIs. ARM, AArch64, and x86 can
be added in the future. The testing is injected in two places. First, all the
assembly tests in p256-x86_64-test.cc are now instrumented. This is the
intended workflow and should capture all registers.
However, we currently do not unit-test our assembly much directly. We should do
that as follow-up work[0] but, in the meantime, I've also wrapped all of the GTest
main function in an ABI test. This is imperfect as ABI failures may be masked
by other stack frames, but it costs nothing[1] and is pretty reliable at
catching Win64 xmm register failures.
[0] An alternate strategy would be, in debug builds, unconditionally instrument
every assembly call in libcrypto. But the CHECK_ABI macro would be difficult to
replicate in pure C, and unwind testing may be too invasive for this. Still,
something to consider when we C++ libcrypto.
[1] When single-stepped unwind testing exists, it won't cost nothing. The
gtest_main.cc call will turn unwind testing off.
Change-Id: I6643b26445891fd46abfacac52bc024024c8d7f6
Reviewed-on: https://boringssl-review.googlesource.com/c/33764
Reviewed-by: Adam Langley <agl@google.com>
Reviewed-by: Adam Langley <alangley@gmail.com>
Commit-Queue: David Benjamin <davidben@google.com>
2018-12-16 00:58:43 +00:00
|
|
|
#if defined(OPENSSL_WINDOWS)
|
Add a CFI tester to CHECK_ABI.
This uses the x86 trap flag and libunwind to test CFI works at each
instruction. For now, it just uses the system one out of pkg-config and
disables unwind tests if unavailable. We'll probably want to stick a
copy into //third_party and perhaps try the LLVM one later.
This tester caught two bugs in P-256 CFI annotations already:
I47b5f9798b3bcee1748e537b21c173d312a14b42 and
I9f576d868850312d6c14d1386f8fbfa85021b347
An earlier design used PTRACE_SINGLESTEP with libunwind's remote
unwinding features. ptrace is a mess around stop signals (see group-stop
discussion in ptrace(2)) and this is 10x faster, so I went with it. The
question of which is more future-proof is complex:
- There are two libunwinds with the same API,
https://www.nongnu.org/libunwind/ and LLVM's. This currently uses the
system nongnu.org for convenience. In future, LLVM's should be easier
to bundle (less complex build) and appears to even support Windows,
but I haven't tested this. Moreover, setting the trap flag keeps the
test single-process, which is less complex on Windows. That suggests
the trap flag design and switching to LLVM later. However...
- Not all architectures have a trap flag settable by userspace. As far
as I can tell, ARMv8's PSTATE.SS can only be set from the kernel. If
we stick with nongnu.org libunwind, we can use PTRACE_SINGLESTEP and
remote unwinding. Or we implement it for LLVM. Another thought is for
the ptracer to bounce SIGTRAP back into the process, to share the
local unwinding code.
- ARMv7 has no trap flag at all and PTRACE_SINGLESTEP fails. Debuggers
single-step by injecting breakpoints instead. However, ARMv8's trap
flag seems to work in both AArch32 and AArch64 modes, so we may be
able to condition it on a 64-bit kernel.
Sadly, neither strategy works with Intel SDE. Adding flags to cpucap
vectors as we do with ARM would help, but it would not emulate CPUs
newer than the host CPU. For now, I've just had SDE tests disable these.
Annoyingly, CMake does not allow object libraries to have dependencies,
so make test_support a proper static library. Rename the target to
test_support_lib to avoid
https://gitlab.kitware.com/cmake/cmake/issues/17785
Update-Note: This adds a new optional test dependency, but it's disabled
by default (define BORINGSSL_HAVE_LIBUNWIND), so consumers do not need
to do anything. We'll probably want to adjust this in the future.
Bug: 181
Change-Id: I817263d7907aff0904a9cee83f8b26747262cc0c
Reviewed-on: https://boringssl-review.googlesource.com/c/33966
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
2018-12-21 23:58:36 +00:00
|
|
|
EXPECT_NONFATAL_FAILURE(CHECK_ABI_NO_UNWIND(abi_test_clobber_xmm6),
|
|
|
|
"xmm6 was not restored after return");
|
|
|
|
EXPECT_NONFATAL_FAILURE(CHECK_ABI_NO_UNWIND(abi_test_clobber_xmm7),
|
|
|
|
"xmm7 was not restored after return");
|
|
|
|
EXPECT_NONFATAL_FAILURE(CHECK_ABI_NO_UNWIND(abi_test_clobber_xmm8),
|
|
|
|
"xmm8 was not restored after return");
|
|
|
|
EXPECT_NONFATAL_FAILURE(CHECK_ABI_NO_UNWIND(abi_test_clobber_xmm9),
|
|
|
|
"xmm9 was not restored after return");
|
|
|
|
EXPECT_NONFATAL_FAILURE(CHECK_ABI_NO_UNWIND(abi_test_clobber_xmm10),
|
|
|
|
"xmm10 was not restored after return");
|
|
|
|
EXPECT_NONFATAL_FAILURE(CHECK_ABI_NO_UNWIND(abi_test_clobber_xmm11),
|
|
|
|
"xmm11 was not restored after return");
|
|
|
|
EXPECT_NONFATAL_FAILURE(CHECK_ABI_NO_UNWIND(abi_test_clobber_xmm12),
|
|
|
|
"xmm12 was not restored after return");
|
|
|
|
EXPECT_NONFATAL_FAILURE(CHECK_ABI_NO_UNWIND(abi_test_clobber_xmm13),
|
|
|
|
"xmm13 was not restored after return");
|
|
|
|
EXPECT_NONFATAL_FAILURE(CHECK_ABI_NO_UNWIND(abi_test_clobber_xmm14),
|
|
|
|
"xmm14 was not restored after return");
|
|
|
|
EXPECT_NONFATAL_FAILURE(CHECK_ABI_NO_UNWIND(abi_test_clobber_xmm15),
|
|
|
|
"xmm15 was not restored after return");
|
Add an ABI testing framework.
Dear reader, I must apologize in advance. This CL contains the following:
- A new 256-line perlasm file with non-trivial perl bits and a dual-ABI
variadic function caller.
- C preprocessor gymnastics, with variadic macros and fun facts about
__VA_ARGS__'s behavior on empty argument lists.
- C++ template gymnastics, including variadic arguments, template
specialization, std::enable_if, and machinery to control template argument
deduction.
Enjoy.
This tests that our assembly functions correctly honor platform ABI
conventions. Right now this only tests callee-saved registers, but it should be
extendable to SEH/CFI unwind testing with single-step debugging APIs.
Register-checking does not involve anything funny and should be compatible with
SDE. (The future unwind testing is unlikely to be compatible.)
This CL adds support for x86_64 SysV and Win64 ABIs. ARM, AArch64, and x86 can
be added in the future. The testing is injected in two places. First, all the
assembly tests in p256-x86_64-test.cc are now instrumented. This is the
intended workflow and should capture all registers.
However, we currently do not unit-test our assembly much directly. We should do
that as follow-up work[0] but, in the meantime, I've also wrapped all of the GTest
main function in an ABI test. This is imperfect as ABI failures may be masked
by other stack frames, but it costs nothing[1] and is pretty reliable at
catching Win64 xmm register failures.
[0] An alternate strategy would be, in debug builds, unconditionally instrument
every assembly call in libcrypto. But the CHECK_ABI macro would be difficult to
replicate in pure C, and unwind testing may be too invasive for this. Still,
something to consider when we C++ libcrypto.
[1] When single-stepped unwind testing exists, it won't cost nothing. The
gtest_main.cc call will turn unwind testing off.
Change-Id: I6643b26445891fd46abfacac52bc024024c8d7f6
Reviewed-on: https://boringssl-review.googlesource.com/c/33764
Reviewed-by: Adam Langley <agl@google.com>
Reviewed-by: Adam Langley <alangley@gmail.com>
Commit-Queue: David Benjamin <davidben@google.com>
2018-12-16 00:58:43 +00:00
|
|
|
#else
|
Add a CFI tester to CHECK_ABI.
This uses the x86 trap flag and libunwind to test CFI works at each
instruction. For now, it just uses the system one out of pkg-config and
disables unwind tests if unavailable. We'll probably want to stick a
copy into //third_party and perhaps try the LLVM one later.
This tester caught two bugs in P-256 CFI annotations already:
I47b5f9798b3bcee1748e537b21c173d312a14b42 and
I9f576d868850312d6c14d1386f8fbfa85021b347
An earlier design used PTRACE_SINGLESTEP with libunwind's remote
unwinding features. ptrace is a mess around stop signals (see group-stop
discussion in ptrace(2)) and this is 10x faster, so I went with it. The
question of which is more future-proof is complex:
- There are two libunwinds with the same API,
https://www.nongnu.org/libunwind/ and LLVM's. This currently uses the
system nongnu.org for convenience. In future, LLVM's should be easier
to bundle (less complex build) and appears to even support Windows,
but I haven't tested this. Moreover, setting the trap flag keeps the
test single-process, which is less complex on Windows. That suggests
the trap flag design and switching to LLVM later. However...
- Not all architectures have a trap flag settable by userspace. As far
as I can tell, ARMv8's PSTATE.SS can only be set from the kernel. If
we stick with nongnu.org libunwind, we can use PTRACE_SINGLESTEP and
remote unwinding. Or we implement it for LLVM. Another thought is for
the ptracer to bounce SIGTRAP back into the process, to share the
local unwinding code.
- ARMv7 has no trap flag at all and PTRACE_SINGLESTEP fails. Debuggers
single-step by injecting breakpoints instead. However, ARMv8's trap
flag seems to work in both AArch32 and AArch64 modes, so we may be
able to condition it on a 64-bit kernel.
Sadly, neither strategy works with Intel SDE. Adding flags to cpucap
vectors as we do with ARM would help, but it would not emulate CPUs
newer than the host CPU. For now, I've just had SDE tests disable these.
Annoyingly, CMake does not allow object libraries to have dependencies,
so make test_support a proper static library. Rename the target to
test_support_lib to avoid
https://gitlab.kitware.com/cmake/cmake/issues/17785
Update-Note: This adds a new optional test dependency, but it's disabled
by default (define BORINGSSL_HAVE_LIBUNWIND), so consumers do not need
to do anything. We'll probably want to adjust this in the future.
Bug: 181
Change-Id: I817263d7907aff0904a9cee83f8b26747262cc0c
Reviewed-on: https://boringssl-review.googlesource.com/c/33966
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
2018-12-21 23:58:36 +00:00
|
|
|
CHECK_ABI_NO_UNWIND(abi_test_clobber_xmm6);
|
|
|
|
CHECK_ABI_NO_UNWIND(abi_test_clobber_xmm7);
|
|
|
|
CHECK_ABI_NO_UNWIND(abi_test_clobber_xmm8);
|
|
|
|
CHECK_ABI_NO_UNWIND(abi_test_clobber_xmm9);
|
|
|
|
CHECK_ABI_NO_UNWIND(abi_test_clobber_xmm10);
|
|
|
|
CHECK_ABI_NO_UNWIND(abi_test_clobber_xmm11);
|
|
|
|
CHECK_ABI_NO_UNWIND(abi_test_clobber_xmm12);
|
|
|
|
CHECK_ABI_NO_UNWIND(abi_test_clobber_xmm13);
|
|
|
|
CHECK_ABI_NO_UNWIND(abi_test_clobber_xmm14);
|
|
|
|
CHECK_ABI_NO_UNWIND(abi_test_clobber_xmm15);
|
Add an ABI testing framework.
Dear reader, I must apologize in advance. This CL contains the following:
- A new 256-line perlasm file with non-trivial perl bits and a dual-ABI
variadic function caller.
- C preprocessor gymnastics, with variadic macros and fun facts about
__VA_ARGS__'s behavior on empty argument lists.
- C++ template gymnastics, including variadic arguments, template
specialization, std::enable_if, and machinery to control template argument
deduction.
Enjoy.
This tests that our assembly functions correctly honor platform ABI
conventions. Right now this only tests callee-saved registers, but it should be
extendable to SEH/CFI unwind testing with single-step debugging APIs.
Register-checking does not involve anything funny and should be compatible with
SDE. (The future unwind testing is unlikely to be compatible.)
This CL adds support for x86_64 SysV and Win64 ABIs. ARM, AArch64, and x86 can
be added in the future. The testing is injected in two places. First, all the
assembly tests in p256-x86_64-test.cc are now instrumented. This is the
intended workflow and should capture all registers.
However, we currently do not unit-test our assembly much directly. We should do
that as follow-up work[0] but, in the meantime, I've also wrapped all of the GTest
main function in an ABI test. This is imperfect as ABI failures may be masked
by other stack frames, but it costs nothing[1] and is pretty reliable at
catching Win64 xmm register failures.
[0] An alternate strategy would be, in debug builds, unconditionally instrument
every assembly call in libcrypto. But the CHECK_ABI macro would be difficult to
replicate in pure C, and unwind testing may be too invasive for this. Still,
something to consider when we C++ libcrypto.
[1] When single-stepped unwind testing exists, it won't cost nothing. The
gtest_main.cc call will turn unwind testing off.
Change-Id: I6643b26445891fd46abfacac52bc024024c8d7f6
Reviewed-on: https://boringssl-review.googlesource.com/c/33764
Reviewed-by: Adam Langley <agl@google.com>
Reviewed-by: Adam Langley <alangley@gmail.com>
Commit-Queue: David Benjamin <davidben@google.com>
2018-12-16 00:58:43 +00:00
|
|
|
#endif
|
2019-01-07 02:05:52 +00:00
|
|
|
|
|
|
|
EXPECT_NONFATAL_FAILURE(CHECK_ABI_NO_UNWIND(abi_test_set_direction_flag),
|
|
|
|
"Direction flag set after return");
|
|
|
|
EXPECT_EQ(0, abi_test_get_and_clear_direction_flag())
|
|
|
|
<< "CHECK_ABI did not insulate the caller from direction flag errors";
|
Add an ABI testing framework.
Dear reader, I must apologize in advance. This CL contains the following:
- A new 256-line perlasm file with non-trivial perl bits and a dual-ABI
variadic function caller.
- C preprocessor gymnastics, with variadic macros and fun facts about
__VA_ARGS__'s behavior on empty argument lists.
- C++ template gymnastics, including variadic arguments, template
specialization, std::enable_if, and machinery to control template argument
deduction.
Enjoy.
This tests that our assembly functions correctly honor platform ABI
conventions. Right now this only tests callee-saved registers, but it should be
extendable to SEH/CFI unwind testing with single-step debugging APIs.
Register-checking does not involve anything funny and should be compatible with
SDE. (The future unwind testing is unlikely to be compatible.)
This CL adds support for x86_64 SysV and Win64 ABIs. ARM, AArch64, and x86 can
be added in the future. The testing is injected in two places. First, all the
assembly tests in p256-x86_64-test.cc are now instrumented. This is the
intended workflow and should capture all registers.
However, we currently do not unit-test our assembly much directly. We should do
that as follow-up work[0] but, in the meantime, I've also wrapped all of the GTest
main function in an ABI test. This is imperfect as ABI failures may be masked
by other stack frames, but it costs nothing[1] and is pretty reliable at
catching Win64 xmm register failures.
[0] An alternate strategy would be, in debug builds, unconditionally instrument
every assembly call in libcrypto. But the CHECK_ABI macro would be difficult to
replicate in pure C, and unwind testing may be too invasive for this. Still,
something to consider when we C++ libcrypto.
[1] When single-stepped unwind testing exists, it won't cost nothing. The
gtest_main.cc call will turn unwind testing off.
Change-Id: I6643b26445891fd46abfacac52bc024024c8d7f6
Reviewed-on: https://boringssl-review.googlesource.com/c/33764
Reviewed-by: Adam Langley <agl@google.com>
Reviewed-by: Adam Langley <alangley@gmail.com>
Commit-Queue: David Benjamin <davidben@google.com>
2018-12-16 00:58:43 +00:00
|
|
|
}
|
|
|
|
#endif // OPENSSL_X86_64 && SUPPORTS_ABI_TEST
|
2019-01-26 17:29:08 +00:00
|
|
|
|
|
|
|
#if defined(OPENSSL_X86) && defined(SUPPORTS_ABI_TEST)
|
|
|
|
extern "C" {
|
|
|
|
void abi_test_clobber_eax(void);
|
|
|
|
void abi_test_clobber_ebx(void);
|
|
|
|
void abi_test_clobber_ecx(void);
|
|
|
|
void abi_test_clobber_edx(void);
|
|
|
|
void abi_test_clobber_esi(void);
|
|
|
|
void abi_test_clobber_edi(void);
|
|
|
|
void abi_test_clobber_ebp(void);
|
|
|
|
void abi_test_clobber_xmm0(void);
|
|
|
|
void abi_test_clobber_xmm1(void);
|
|
|
|
void abi_test_clobber_xmm2(void);
|
|
|
|
void abi_test_clobber_xmm3(void);
|
|
|
|
void abi_test_clobber_xmm4(void);
|
|
|
|
void abi_test_clobber_xmm5(void);
|
|
|
|
void abi_test_clobber_xmm6(void);
|
|
|
|
void abi_test_clobber_xmm7(void);
|
|
|
|
} // extern "C"
|
|
|
|
|
|
|
|
TEST(ABITest, X86) {
|
|
|
|
// abi_test_trampoline hides unsaved registers from the caller, so we can
|
|
|
|
// safely call the abi_test_clobber_* functions below.
|
|
|
|
abi_test::internal::CallerState state;
|
|
|
|
RAND_bytes(reinterpret_cast<uint8_t *>(&state), sizeof(state));
|
|
|
|
CHECK_ABI_NO_UNWIND(abi_test_trampoline,
|
|
|
|
reinterpret_cast<crypto_word_t>(abi_test_clobber_ebx),
|
|
|
|
&state, nullptr, 0, 0 /* no breakpoint */);
|
|
|
|
|
|
|
|
CHECK_ABI_NO_UNWIND(abi_test_clobber_eax);
|
|
|
|
EXPECT_NONFATAL_FAILURE(CHECK_ABI_NO_UNWIND(abi_test_clobber_ebx),
|
|
|
|
"ebx was not restored after return");
|
|
|
|
CHECK_ABI_NO_UNWIND(abi_test_clobber_ecx);
|
|
|
|
CHECK_ABI_NO_UNWIND(abi_test_clobber_edx);
|
|
|
|
EXPECT_NONFATAL_FAILURE(CHECK_ABI_NO_UNWIND(abi_test_clobber_edi),
|
|
|
|
"edi was not restored after return");
|
|
|
|
EXPECT_NONFATAL_FAILURE(CHECK_ABI_NO_UNWIND(abi_test_clobber_esi),
|
|
|
|
"esi was not restored after return");
|
|
|
|
EXPECT_NONFATAL_FAILURE(CHECK_ABI_NO_UNWIND(abi_test_clobber_ebp),
|
|
|
|
"ebp was not restored after return");
|
|
|
|
|
|
|
|
CHECK_ABI_NO_UNWIND(abi_test_clobber_xmm0);
|
|
|
|
CHECK_ABI_NO_UNWIND(abi_test_clobber_xmm1);
|
|
|
|
CHECK_ABI_NO_UNWIND(abi_test_clobber_xmm2);
|
|
|
|
CHECK_ABI_NO_UNWIND(abi_test_clobber_xmm3);
|
|
|
|
CHECK_ABI_NO_UNWIND(abi_test_clobber_xmm4);
|
|
|
|
CHECK_ABI_NO_UNWIND(abi_test_clobber_xmm5);
|
|
|
|
CHECK_ABI_NO_UNWIND(abi_test_clobber_xmm6);
|
|
|
|
CHECK_ABI_NO_UNWIND(abi_test_clobber_xmm7);
|
|
|
|
|
|
|
|
EXPECT_NONFATAL_FAILURE(CHECK_ABI_NO_UNWIND(abi_test_set_direction_flag),
|
|
|
|
"Direction flag set after return");
|
|
|
|
EXPECT_EQ(0, abi_test_get_and_clear_direction_flag())
|
|
|
|
<< "CHECK_ABI did not insulate the caller from direction flag errors";
|
|
|
|
}
|
|
|
|
#endif // OPENSSL_X86 && SUPPORTS_ABI_TEST
|