| // Copyright Microsoft and CHERIoT Contributors. |
| // SPDX-License-Identifier: MIT |
| |
| #include "tests.hh" |
| #include <cdefs.h> |
| |
| __cheri_compartment("crash_recovery_inner") void *test_crash_recovery_inner( |
| int); |
| __cheri_compartment("crash_recovery_outer") void test_crash_recovery_outer(int); |
| |
| /** |
| * Checks that the stack is entirely full of zeroes below the current stack |
| * pointer. |
| */ |
| inline void check_stack(SourceLocation loc = SourceLocation::current()) |
| { |
| register char *cspRegister asm("csp"); |
| asm("" : "=C"(cspRegister)); |
| CHERI::Capability<char> csp{cspRegister}; |
| const ptraddr_t StackAddress = csp.address(); |
| const size_t Length = StackAddress - csp.base(); |
| csp.address() = csp.base(); |
| ptrdiff_t failAddress = -1; |
| // Scan the stack from the current stack pointer downwards and report the |
| // first non-zero value. We must not call any functions in this loop or we |
| // would move the stack pointer and write some non-zero values. |
| for (ptrdiff_t i = Length - 1; i > 0; i--) |
| { |
| if (csp[i] != 0) |
| { |
| if (failAddress != -1) |
| { |
| failAddress = csp.address() + i; |
| } |
| } |
| } |
| Test::Invariant<size_t, void *, size_t, unsigned>( |
| failAddress == -1, |
| "Byte at {} in {} (stack address: {}) is {}, not 0", |
| csp.address() + failAddress, |
| csp, |
| StackAddress, |
| csp[failAddress], |
| loc); |
| } |