stack-test.c
1 /* 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 9 #define STACK_SIZE 0x1000 10 #else 11 #define STACK_SIZE CONFIG_STACK_SIZE 12 #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[]; 19 TEST_REGION(stack, STACK_SIZE); 20 21 22 static 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. */ 30 static void clean_stack(void) 31 { 32 fill_stack(STACK_GUARD_VALUE); 33 } 34 35 static 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 45 static 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 53 static 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 67 static 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. */ 76 expect_assert_failure(checkstack(top_of_stack, 0)); 77 } 78 79 static 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 93 static 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 108 static 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. */ 118 expect_assert_failure(checkstack(top_of_stack, 0)); 119 } 120 121 int 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 132 return cb_run_group_tests(tests, NULL, NULL); 133 }