tests: Add lib/stack-test test case
Signed-off-by: Jakub Czapiga <jacz@semihalf.com> Change-Id: Icf0cceac290618a50ecc4e65f1f9551dbf31bd32 Reviewed-on: https://review.coreboot.org/c/coreboot/+/50305 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Paul Fagerburg <pfagerburg@chromium.org>
This commit is contained in:
		
				
					committed by
					
						
						Patrick Georgi
					
				
			
			
				
	
			
			
			
						parent
						
							e22eef7c51
						
					
				
				
					commit
					b3a7c84b43
				
			@@ -13,6 +13,7 @@ tests-y += fmap-test
 | 
			
		||||
tests-y += imd_cbmem-romstage-test
 | 
			
		||||
tests-y += imd_cbmem-ramstage-test
 | 
			
		||||
tests-y += region_file-test
 | 
			
		||||
tests-y += stack-test
 | 
			
		||||
 | 
			
		||||
string-test-srcs += tests/lib/string-test.c
 | 
			
		||||
string-test-srcs += src/lib/string.c
 | 
			
		||||
@@ -71,3 +72,7 @@ imd_cbmem-romstage-test-mocks += cbmem_top_chipset
 | 
			
		||||
region_file-test-srcs += tests/lib/region_file-test.c
 | 
			
		||||
region_file-test-srcs += src/commonlib/region.c
 | 
			
		||||
region_file-test-srcs += tests/stubs/console.c
 | 
			
		||||
 | 
			
		||||
stack-test-srcs += tests/lib/stack-test.c
 | 
			
		||||
stack-test-srcs += src/lib/stack.c
 | 
			
		||||
stack-test-srcs += tests/stubs/console.c
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										133
									
								
								tests/lib/stack-test.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										133
									
								
								tests/lib/stack-test.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,133 @@
 | 
			
		||||
/* SPDX-License-Identifier: GPL-2.0-only */
 | 
			
		||||
 | 
			
		||||
#include <tests/test.h>
 | 
			
		||||
#include <lib.h>
 | 
			
		||||
#include <symbols.h>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#if CONFIG_STACK_SIZE == 0
 | 
			
		||||
# define STACK_SIZE 0x1000
 | 
			
		||||
#else
 | 
			
		||||
# define STACK_SIZE CONFIG_STACK_SIZE
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* Value used for stack initialization. Change if implementation changes. */
 | 
			
		||||
#define STACK_GUARD_VALUE 0xDEADBEEF
 | 
			
		||||
 | 
			
		||||
__weak extern u8 _stack[];
 | 
			
		||||
__weak extern u8 _estack[];
 | 
			
		||||
TEST_REGION(stack, STACK_SIZE);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void fill_stack(u32 value)
 | 
			
		||||
{
 | 
			
		||||
	u32 *stack = (u32 *)_stack;
 | 
			
		||||
	for (size_t i = 0; i < STACK_SIZE / sizeof(u32); ++i)
 | 
			
		||||
		stack[i] = value;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Fill stack region with guard value.  */
 | 
			
		||||
static void clean_stack(void)
 | 
			
		||||
{
 | 
			
		||||
	fill_stack(STACK_GUARD_VALUE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int setup_stack_test(void **state)
 | 
			
		||||
{
 | 
			
		||||
	void *top_of_stack = _stack + sizeof(_stack);
 | 
			
		||||
 | 
			
		||||
	clean_stack();
 | 
			
		||||
	*state = top_of_stack;
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void test_empty_stack(void **state)
 | 
			
		||||
{
 | 
			
		||||
	void *top_of_stack = *state;
 | 
			
		||||
 | 
			
		||||
	/* Expect success when checking empty stack. */
 | 
			
		||||
	assert_int_equal(0, checkstack(top_of_stack, 0));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void test_almost_full_stack(void **state)
 | 
			
		||||
{
 | 
			
		||||
	void *top_of_stack = *state;
 | 
			
		||||
	u32 *stack = (u32 *)_stack;
 | 
			
		||||
 | 
			
		||||
	/* Fill stack with random value except last word */
 | 
			
		||||
	for (size_t i = 1; i < STACK_SIZE / sizeof(u32); ++i)
 | 
			
		||||
		stack[i] = 0xAA11FF44;
 | 
			
		||||
 | 
			
		||||
	/* Expect success when checking almost-full stack,
 | 
			
		||||
	   because last guard value is present */
 | 
			
		||||
	assert_int_equal(0, checkstack(top_of_stack, 0));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void test_full_stack(void **state)
 | 
			
		||||
{
 | 
			
		||||
	void *top_of_stack = *state;
 | 
			
		||||
 | 
			
		||||
	/* Fill stack with value different than stack guard */
 | 
			
		||||
	fill_stack(0x600DB015);
 | 
			
		||||
 | 
			
		||||
	/* Expect failure when checking full stack as absence of guard value at the end of
 | 
			
		||||
	   the stack indicates stack overrun. */
 | 
			
		||||
	assert_int_equal(-1, checkstack(top_of_stack, 0));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void test_partialy_filled_stack(void **state)
 | 
			
		||||
{
 | 
			
		||||
	void *top_of_stack = *state;
 | 
			
		||||
	u32 *stack = (u32 *)_stack;
 | 
			
		||||
	size_t i = STACK_SIZE / sizeof(u32) / 2;
 | 
			
		||||
 | 
			
		||||
	for (; i < STACK_SIZE / sizeof(u32); ++i)
 | 
			
		||||
		stack[i] = 0x4321ABDC + i;
 | 
			
		||||
 | 
			
		||||
	/* Expect success when checking partially-filled stack,
 | 
			
		||||
	   because only part of stack is filled with non-guard value. */
 | 
			
		||||
	assert_int_equal(0, checkstack(top_of_stack, 0));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void test_alternately_filled_stack(void **state)
 | 
			
		||||
{
 | 
			
		||||
	void *top_of_stack = *state;
 | 
			
		||||
	u32 *stack = (u32 *)_stack;
 | 
			
		||||
	size_t i;
 | 
			
		||||
 | 
			
		||||
	for (i = 0; i < STACK_SIZE / sizeof(u32); i += 2)
 | 
			
		||||
		stack[i] = STACK_GUARD_VALUE;
 | 
			
		||||
 | 
			
		||||
	for (i = 1; i < STACK_SIZE / sizeof(u32); i += 2)
 | 
			
		||||
		stack[i] = 0x42420707;
 | 
			
		||||
 | 
			
		||||
	assert_int_equal(0, checkstack(top_of_stack, 0));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void test_incorrectly_initialized_stack(void **state)
 | 
			
		||||
{
 | 
			
		||||
	void *top_of_stack = *state;
 | 
			
		||||
	u32 *stack = (u32 *)_stack;
 | 
			
		||||
 | 
			
		||||
	/* Remove last stack guard value */
 | 
			
		||||
	stack[0] = 0xFF00FF11;
 | 
			
		||||
 | 
			
		||||
	/* Expect failure when there is no last stack guard value even if no other value was
 | 
			
		||||
	   changed. */
 | 
			
		||||
	assert_int_equal(-1, checkstack(top_of_stack, 0));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int main(void)
 | 
			
		||||
{
 | 
			
		||||
	const struct CMUnitTest tests[] = {
 | 
			
		||||
		cmocka_unit_test_setup(test_empty_stack, setup_stack_test),
 | 
			
		||||
		cmocka_unit_test_setup(test_almost_full_stack, setup_stack_test),
 | 
			
		||||
		cmocka_unit_test_setup(test_full_stack, setup_stack_test),
 | 
			
		||||
		cmocka_unit_test_setup(test_partialy_filled_stack, setup_stack_test),
 | 
			
		||||
		cmocka_unit_test_setup(test_alternately_filled_stack, setup_stack_test),
 | 
			
		||||
		cmocka_unit_test_setup(test_incorrectly_initialized_stack, setup_stack_test),
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	return cmocka_run_group_tests(tests, NULL, NULL);
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user