blob: 583fe4954f2aeb3a3faeb2fb4326a8abde2d1344 [file] [log] [blame]
Jakub Czapigab3a7c842021-02-05 15:10:25 +01001/* SPDX-License-Identifier: GPL-2.0-only */
2
3#include <tests/test.h>
4#include <lib.h>
5#include <symbols.h>
6
7
8#if CONFIG_STACK_SIZE == 0
Jakub Czapigac08b6a72022-01-10 13:36:47 +00009#define STACK_SIZE 0x1000
Jakub Czapigab3a7c842021-02-05 15:10:25 +010010#else
Jakub Czapigac08b6a72022-01-10 13:36:47 +000011#define STACK_SIZE CONFIG_STACK_SIZE
Jakub Czapigab3a7c842021-02-05 15:10:25 +010012#endif
13
14/* Value used for stack initialization. Change if implementation changes. */
15#define STACK_GUARD_VALUE 0xDEADBEEF
16
17__weak extern u8 _stack[];
18__weak extern u8 _estack[];
19TEST_REGION(stack, STACK_SIZE);
20
21
22static void fill_stack(u32 value)
23{
24 u32 *stack = (u32 *)_stack;
25 for (size_t i = 0; i < STACK_SIZE / sizeof(u32); ++i)
26 stack[i] = value;
27}
28
29/* Fill stack region with guard value. */
30static void clean_stack(void)
31{
32 fill_stack(STACK_GUARD_VALUE);
33}
34
35static int setup_stack_test(void **state)
36{
37 void *top_of_stack = _stack + sizeof(_stack);
38
39 clean_stack();
40 *state = top_of_stack;
41
42 return 0;
43}
44
45static void test_empty_stack(void **state)
46{
47 void *top_of_stack = *state;
48
49 /* Expect success when checking empty stack. */
50 assert_int_equal(0, checkstack(top_of_stack, 0));
51}
52
53static void test_almost_full_stack(void **state)
54{
55 void *top_of_stack = *state;
56 u32 *stack = (u32 *)_stack;
57
58 /* Fill stack with random value except last word */
59 for (size_t i = 1; i < STACK_SIZE / sizeof(u32); ++i)
60 stack[i] = 0xAA11FF44;
61
62 /* Expect success when checking almost-full stack,
63 because last guard value is present */
64 assert_int_equal(0, checkstack(top_of_stack, 0));
65}
66
67static void test_full_stack(void **state)
68{
69 void *top_of_stack = *state;
70
71 /* Fill stack with value different than stack guard */
72 fill_stack(0x600DB015);
73
74 /* Expect failure when checking full stack as absence of guard value at the end of
75 the stack indicates stack overrun. */
Jakub Czapiga45d37d52021-03-25 14:28:29 +010076 expect_assert_failure(checkstack(top_of_stack, 0));
Jakub Czapigab3a7c842021-02-05 15:10:25 +010077}
78
79static void test_partialy_filled_stack(void **state)
80{
81 void *top_of_stack = *state;
82 u32 *stack = (u32 *)_stack;
83 size_t i = STACK_SIZE / sizeof(u32) / 2;
84
85 for (; i < STACK_SIZE / sizeof(u32); ++i)
86 stack[i] = 0x4321ABDC + i;
87
88 /* Expect success when checking partially-filled stack,
89 because only part of stack is filled with non-guard value. */
90 assert_int_equal(0, checkstack(top_of_stack, 0));
91}
92
93static void test_alternately_filled_stack(void **state)
94{
95 void *top_of_stack = *state;
96 u32 *stack = (u32 *)_stack;
97 size_t i;
98
99 for (i = 0; i < STACK_SIZE / sizeof(u32); i += 2)
100 stack[i] = STACK_GUARD_VALUE;
101
102 for (i = 1; i < STACK_SIZE / sizeof(u32); i += 2)
103 stack[i] = 0x42420707;
104
105 assert_int_equal(0, checkstack(top_of_stack, 0));
106}
107
108static void test_incorrectly_initialized_stack(void **state)
109{
110 void *top_of_stack = *state;
111 u32 *stack = (u32 *)_stack;
112
113 /* Remove last stack guard value */
114 stack[0] = 0xFF00FF11;
115
116 /* Expect failure when there is no last stack guard value even if no other value was
117 changed. */
Jakub Czapiga45d37d52021-03-25 14:28:29 +0100118 expect_assert_failure(checkstack(top_of_stack, 0));
Jakub Czapigab3a7c842021-02-05 15:10:25 +0100119}
120
121int main(void)
122{
123 const struct CMUnitTest tests[] = {
124 cmocka_unit_test_setup(test_empty_stack, setup_stack_test),
125 cmocka_unit_test_setup(test_almost_full_stack, setup_stack_test),
126 cmocka_unit_test_setup(test_full_stack, setup_stack_test),
127 cmocka_unit_test_setup(test_partialy_filled_stack, setup_stack_test),
128 cmocka_unit_test_setup(test_alternately_filled_stack, setup_stack_test),
129 cmocka_unit_test_setup(test_incorrectly_initialized_stack, setup_stack_test),
130 };
131
Jakub Czapiga7c6081e2021-08-25 16:27:35 +0200132 return cb_run_group_tests(tests, NULL, NULL);
Jakub Czapigab3a7c842021-02-05 15:10:25 +0100133}