1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Copyright 2025 Linaro Limited
4  *
5  * Unit test for initjmp()
6  */
7 
8 #include <compiler.h>
9 #include <setjmp.h>
10 #include <stdbool.h>
11 #include <test/lib.h>
12 #include <test/ut.h>
13 #include <vsprintf.h>
14 
15 static bool ep_entered;
16 static jmp_buf return_buf;
17 
entrypoint(void)18 static void __noreturn entrypoint(void)
19 {
20 	ep_entered = true;
21 
22 	/* Jump back to the main routine */
23 	longjmp(return_buf, 1);
24 
25 	/* Not reached */
26 	panic("longjmp failed\n");
27 }
28 
lib_initjmp(struct unit_test_state * uts)29 static int lib_initjmp(struct unit_test_state *uts)
30 {
31 	int ret;
32 	void *stack;
33 	jmp_buf buf;
34 	/* Arbitrary but smaller values (< page size?) fail on SANDBOX */
35 	size_t stack_sz = 8192;
36 
37 	(void)entrypoint;
38 
39 	ep_entered = false;
40 
41 	stack = malloc(stack_sz);
42 	ut_assertnonnull(stack);
43 
44 	/*
45 	 * Prepare return_buf so that entrypoint may jump back just after the
46 	 * if()
47 	 */
48 	if (!setjmp(return_buf)) {
49 		/* return_buf initialized, entrypoint not yet called */
50 
51 		/*
52 		 * Prepare another jump buffer to jump into entrypoint with the
53 		 * given stack
54 		 */
55 		ret = initjmp(buf, entrypoint, stack, stack_sz);
56 		ut_assertok(ret);
57 
58 		/* Jump into entrypoint */
59 		longjmp(buf, 1);
60 		/*
61 		 * Not reached since entrypoint is expected to branch after
62 		 * the if()
63 		 */
64 		ut_assert(false);
65 	}
66 
67 	ut_assert(ep_entered);
68 
69 	free(stack);
70 
71 	return 0;
72 }
73 LIB_TEST(lib_initjmp, 0);
74