test: lib: add initjmp() test
authorJerome Forissier <jerome.forissier@linaro.org>
Fri, 18 Apr 2025 14:09:33 +0000 (16:09 +0200)
committerTom Rini <trini@konsulko.com>
Wed, 23 Apr 2025 19:19:44 +0000 (13:19 -0600)
Test the initjmp() function when HAVE_INITJMP is set. Use the test as an
example in the API documentation.

Signed-off-by: Jerome Forissier <jerome.forissier@linaro.org>
Reviewed-by: Ilias Apalodimas <ilias.apalodimas@linaro.org>
doc/api/setjmp.rst
test/lib/Makefile
test/lib/initjmp.c [new file with mode: 0644]

index 7718047..c30e51c 100644 (file)
@@ -8,3 +8,13 @@ Long jump API
 
 .. kernel-doc:: include/setjmp.h
    :internal:
+
+Example
+-------
+
+Here is an example showing how to use the a long jump functions and
+initjmp() in particular:
+
+.. literalinclude:: ../../test/lib/initjmp.c
+   :language: c
+   :linenos:
index 97ab71b..9db563f 100644 (file)
@@ -15,6 +15,7 @@ obj-$(CONFIG_SANDBOX) += kconfig.o
 obj-y += lmb.o
 obj-$(CONFIG_HAVE_SETJMP) += longjmp.o
 obj-$(CONFIG_SANDBOX) += membuf.o
+obj-$(CONFIG_HAVE_INITJMP) += initjmp.o
 obj-$(CONFIG_CONSOLE_RECORD) += test_print.o
 obj-$(CONFIG_SSCANF) += sscanf.o
 obj-$(CONFIG_$(PHASE_)STRTO) += str.o
diff --git a/test/lib/initjmp.c b/test/lib/initjmp.c
new file mode 100644 (file)
index 0000000..5b4b50b
--- /dev/null
@@ -0,0 +1,73 @@
+// 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);