1 /*
2 * Copyright (c) 2024 Arduino SA
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 /*
8 * This test checks for proper support of ELF init arrays. This processing is
9 * performed by llext_bootstrap(), which gets the array of function pointers
10 * from LLEXT via the llext_get_fn_table() syscall.
11 *
12 * Each function in this test shifts the number left by 4 bits and sets the
13 * lower 4 bits to a specific value. The proper init sequence (preinit_fn_1,
14 * preinit_fn_2, init_fn) would leave number set to 0x123; the termination
15 * function will further shift the number to 0x1234. If a different result is
16 * detected, then either not all routines were executed, or their order was not
17 * correct.
18 */
19
20 #include <stdint.h>
21 #include <zephyr/llext/symbol.h>
22 #include <zephyr/toolchain.h>
23 #include <zephyr/sys/printk.h>
24 #include <zephyr/ztest_assert.h>
25
26 static int number;
27 EXPORT_SYMBOL(number);
28
preinit_fn_1(void)29 static void preinit_fn_1(void)
30 {
31 number = 1;
32 }
33
preinit_fn_2(void)34 static void preinit_fn_2(void)
35 {
36 number <<= 4;
37 number |= 2;
38 }
39
init_fn(void)40 static void init_fn(void)
41 {
42 number <<= 4;
43 number |= 3;
44 }
45
fini_fn(void)46 static void fini_fn(void)
47 {
48 number <<= 4;
49 number |= 4;
50 }
51
52 static const void *const preinit_fn_ptrs[] __used Z_GENERIC_SECTION(".preinit_array") = {
53 preinit_fn_1,
54 preinit_fn_2
55 };
56 static const void *const init_fn_ptrs[] __used Z_GENERIC_SECTION(".init_array") = {
57 init_fn
58 };
59 static const void *const fini_fn_ptrs[] __used Z_GENERIC_SECTION(".fini_array") = {
60 fini_fn
61 };
62
test_entry(void)63 void test_entry(void)
64 {
65 /* fini_fn() is not called yet, so we expect 0x123 here */
66 const int expected = (((1 << 4) | 2) << 4) | 3;
67
68 zassert_equal(number, expected, "got 0x%x instead of 0x%x during test",
69 number, expected);
70 }
71 EXPORT_SYMBOL(test_entry);
72