| // SPDX-License-Identifier: GPL-2.0-or-later | |
| /* | |
| * Copyright 2025 Linaro Limited | |
| * | |
| * Unit test for initjmp() | |
| */ | |
| #include <compiler.h> | |
| #include <setjmp.h> | |
| #include <stdbool.h> | |
| #include <test/lib.h> | |
| #include <test/ut.h> | |
| #include <vsprintf.h> | |
| static bool ep_entered; | |
| static jmp_buf return_buf; | |
| static void __noreturn entrypoint(void) | |
| { | |
| ep_entered = true; | |
| /* Jump back to the main routine */ | |
| longjmp(return_buf, 1); | |
| /* Not reached */ | |
| panic("longjmp failed\n"); | |
| } | |
| static int lib_initjmp(struct unit_test_state *uts) | |
| { | |
| int ret; | |
| void *stack; | |
| jmp_buf buf; | |
| /* Arbitrary but smaller values (< page size?) fail on SANDBOX */ | |
| size_t stack_sz = 8192; | |
| (void)entrypoint; | |
| ep_entered = false; | |
| stack = malloc(stack_sz); | |
| ut_assertnonnull(stack); | |
| /* | |
| * Prepare return_buf so that entrypoint may jump back just after the | |
| * if() | |
| */ | |
| if (!setjmp(return_buf)) { | |
| /* return_buf initialized, entrypoint not yet called */ | |
| /* | |
| * Prepare another jump buffer to jump into entrypoint with the | |
| * given stack | |
| */ | |
| ret = initjmp(buf, entrypoint, stack, stack_sz); | |
| ut_assertok(ret); | |
| /* Jump into entrypoint */ | |
| longjmp(buf, 1); | |
| /* | |
| * Not reached since entrypoint is expected to branch after | |
| * the if() | |
| */ | |
| ut_assert(false); | |
| } | |
| ut_assert(ep_entered); | |
| free(stack); | |
| return 0; | |
| } | |
| LIB_TEST(lib_initjmp, 0); |