diff --git a/common/inc/tx_api.h b/common/inc/tx_api.h index 4ca0f3c8..f03ef042 100644 --- a/common/inc/tx_api.h +++ b/common/inc/tx_api.h @@ -26,7 +26,7 @@ /* APPLICATION INTERFACE DEFINITION RELEASE */ /* */ /* tx_api.h PORTABLE C */ -/* 6.2.1 */ +/* 6.x */ /* AUTHOR */ /* */ /* William E. Lamie, Microsoft Corporation */ @@ -97,6 +97,10 @@ /* 03-08-2023 Tiejun Zhou Modified comment(s), */ /* update patch number, */ /* resulting in version 6.2.1 */ +/* xx-xx-xxxx Xiuwen Cai Modified comment(s), */ +/* added option for random */ +/* number stack filling, */ +/* resulting in version 6.x */ /* */ /**************************************************************************/ @@ -171,7 +175,11 @@ extern "C" { #define TX_NO_MESSAGES ((UINT) 0) #define TX_EMPTY ((ULONG) 0) #define TX_CLEAR_ID ((ULONG) 0) +#if defined(TX_ENABLE_RANDOM_NUMBER_STACK_FILLING) && defined(TX_ENABLE_STACK_CHECKING) +#define TX_STACK_FILL (thread_ptr -> tx_thread_stack_fill_value) +#else #define TX_STACK_FILL ((ULONG) 0xEFEFEFEFUL) +#endif /* Thread execution state values. */ @@ -618,6 +626,12 @@ typedef struct TX_THREAD_STRUCT cleanup routine executes. */ ULONG tx_thread_suspension_sequence; +#if defined(TX_ENABLE_RANDOM_NUMBER_STACK_FILLING) && defined(TX_ENABLE_STACK_CHECKING) + + /* Define the random stack fill number. This can be used to detect stack overflow. */ + ULONG tx_thread_stack_fill_value; +#endif + /* Define the user extension field. This typically is defined to white space, but some ports of ThreadX may need to have additional fields in the thread control block. This is @@ -1892,6 +1906,21 @@ UINT _tx_trace_interrupt_control(UINT new_posture); #endif +/* Add a default macro that can be re-defined in tx_port.h to add processing to the initialize random number generator. + By default, this is simply defined as whitespace. */ + +#ifndef TX_INITIALIZE_RANDOM_GENERATOR_INITIALIZATION +#define TX_INITIALIZE_RANDOM_GENERATOR_INITIALIZATION +#endif + + +/* Define the TX_RAND macro to the standard library function, if not already defined. */ + +#ifndef TX_RAND +#define TX_RAND() rand() +#endif + + /* Check for MISRA compliance requirements. */ #ifdef TX_MISRA_ENABLE diff --git a/common/inc/tx_user_sample.h b/common/inc/tx_user_sample.h index d04d2dcb..e637346f 100644 --- a/common/inc/tx_user_sample.h +++ b/common/inc/tx_user_sample.h @@ -26,7 +26,7 @@ /* PORT SPECIFIC C INFORMATION RELEASE */ /* */ /* tx_user.h PORTABLE C */ -/* 6.1.11 */ +/* 6.x */ /* */ /* AUTHOR */ /* */ @@ -62,6 +62,10 @@ /* optimized the definition of */ /* TX_TIMER_TICKS_PER_SECOND, */ /* resulting in version 6.1.11 */ +/* xx-xx-xxxx Xiuwen Cai Modified comment(s), */ +/* added option for random */ +/* number stack filling, */ +/* resulting in version 6.x */ /* */ /**************************************************************************/ @@ -170,6 +174,14 @@ #define TX_ENABLE_STACK_CHECKING */ +/* Determine if random number is used for stack filling. By default, ThreadX uses a fixed + pattern for stack filling. When the following is defined, ThreadX uses a random number + for stack filling. This is effective only when TX_ENABLE_STACK_CHECKING is defined. */ + +/* +#define TX_ENABLE_RANDOM_NUMBER_STACK_FILLING +*/ + /* Determine if preemption-threshold should be disabled. By default, preemption-threshold is enabled. If the application does not use preemption-threshold, it may be disabled to reduce code size and improve performance. */ diff --git a/common/src/tx_initialize_kernel_enter.c b/common/src/tx_initialize_kernel_enter.c index 12e77dc5..c019a797 100644 --- a/common/src/tx_initialize_kernel_enter.c +++ b/common/src/tx_initialize_kernel_enter.c @@ -49,7 +49,7 @@ TX_SAFETY_CRITICAL_EXCEPTION_HANDLER /* FUNCTION RELEASE */ /* */ /* _tx_initialize_kernel_enter PORTABLE C */ -/* 6.1.11 */ +/* 6.x */ /* AUTHOR */ /* */ /* William E. Lamie, Microsoft Corporation */ @@ -93,6 +93,10 @@ TX_SAFETY_CRITICAL_EXCEPTION_HANDLER /* 04-25-2022 Scott Larson Modified comment(s), */ /* added EPK initialization, */ /* resulting in version 6.1.11 */ +/* xx-xx-xxxx Xiuwen Cai Modified comment(s), */ +/* added random generator */ +/* initialization, */ +/* resulting in version 6.x */ /* */ /**************************************************************************/ VOID _tx_initialize_kernel_enter(VOID) @@ -133,6 +137,9 @@ VOID _tx_initialize_kernel_enter(VOID) later used to represent interrupt nesting. */ _tx_thread_system_state = TX_INITIALIZE_IN_PROGRESS; + /* Optional random number generator initialization. */ + TX_INITIALIZE_RANDOM_GENERATOR_INITIALIZATION + /* Call the application provided initialization function. Pass the first available memory address to it. */ tx_application_define(_tx_initialize_unused_memory); diff --git a/common/src/tx_thread_create.c b/common/src/tx_thread_create.c index fc8873d4..d4ee0f49 100644 --- a/common/src/tx_thread_create.c +++ b/common/src/tx_thread_create.c @@ -36,7 +36,7 @@ /* FUNCTION RELEASE */ /* */ /* _tx_thread_create PORTABLE C */ -/* 6.1.8 */ +/* 6.x */ /* AUTHOR */ /* */ /* William E. Lamie, Microsoft Corporation */ @@ -88,6 +88,10 @@ /* supported TX_MISRA_ENABLE, */ /* 08-02-2021 Scott Larson Removed unneeded cast, */ /* resulting in version 6.1.8 */ +/* xx-xx-xxxx Xiuwen Cai Modified comment(s), */ +/* added option for random */ +/* number stack filling, */ +/* resulting in version 6.x */ /* */ /**************************************************************************/ UINT _tx_thread_create(TX_THREAD *thread_ptr, CHAR *name_ptr, VOID (*entry_function)(ULONG id), ULONG entry_input, @@ -109,6 +113,17 @@ ALIGN_TYPE updated_stack_start; #endif #ifndef TX_DISABLE_STACK_FILLING +#if defined(TX_ENABLE_RANDOM_NUMBER_STACK_FILLING) && defined(TX_ENABLE_STACK_CHECKING) + + /* Initialize the stack fill value to a 8-bit random value. */ + thread_ptr -> tx_thread_stack_fill_value = ((ULONG) TX_RAND()) & 0xFFUL; + + /* Duplicate the random value in each of the 4 bytes of the stack fill value. */ + thread_ptr -> tx_thread_stack_fill_value = thread_ptr -> tx_thread_stack_fill_value | + (thread_ptr -> tx_thread_stack_fill_value << 8) | + (thread_ptr -> tx_thread_stack_fill_value << 16) | + (thread_ptr -> tx_thread_stack_fill_value << 24); +#endif /* Set the thread stack to a pattern prior to creating the initial stack frame. This pattern is used by the stack checking routines diff --git a/common_modules/module_manager/src/txm_module_manager_thread_create.c b/common_modules/module_manager/src/txm_module_manager_thread_create.c index 95075bec..2f50cfd7 100644 --- a/common_modules/module_manager/src/txm_module_manager_thread_create.c +++ b/common_modules/module_manager/src/txm_module_manager_thread_create.c @@ -39,7 +39,7 @@ /* FUNCTION RELEASE */ /* */ /* _txm_module_manager_thread_create PORTABLE C */ -/* 6.2.1 */ +/* 6.x */ /* AUTHOR */ /* */ /* Scott Larson, Microsoft Corporation */ @@ -94,6 +94,10 @@ /* 03-08-2023 Scott Larson Check module stack for */ /* overlap, */ /* resulting in version 6.2.1 */ +/* xx-xx-xxxx Xiuwen Cai Modified comment(s), */ +/* added option for random */ +/* number stack filling, */ +/* resulting in version 6.x */ /* */ /**************************************************************************/ UINT _txm_module_manager_thread_create(TX_THREAD *thread_ptr, CHAR *name_ptr, @@ -272,6 +276,17 @@ ULONG i; } #ifndef TX_DISABLE_STACK_FILLING +#if defined(TX_ENABLE_RANDOM_NUMBER_STACK_FILLING) && defined(TX_ENABLE_STACK_CHECKING) + + /* Initialize the stack fill value to a 8-bit random value. */ + thread_ptr -> tx_thread_stack_fill_value = ((ULONG) TX_RAND()) & 0xFFUL; + + /* Duplicate the random value in each of the 4 bytes of the stack fill value. */ + thread_ptr -> tx_thread_stack_fill_value = thread_ptr -> tx_thread_stack_fill_value | + (thread_ptr -> tx_thread_stack_fill_value << 8) | + (thread_ptr -> tx_thread_stack_fill_value << 16) | + (thread_ptr -> tx_thread_stack_fill_value << 24); +#endif /* Set the thread stack to a pattern prior to creating the initial stack frame. This pattern is used by the stack checking routines diff --git a/common_smp/inc/tx_api.h b/common_smp/inc/tx_api.h index 568d48c9..cc88566c 100644 --- a/common_smp/inc/tx_api.h +++ b/common_smp/inc/tx_api.h @@ -26,7 +26,7 @@ /* APPLICATION INTERFACE DEFINITION RELEASE */ /* */ /* tx_api.h PORTABLE SMP */ -/* 6.2.1 */ +/* 6.x */ /* AUTHOR */ /* */ /* William E. Lamie, Microsoft Corporation */ @@ -85,6 +85,10 @@ /* 03-08-2023 Tiejun Zhou Modified comment(s), */ /* update patch number, */ /* resulting in version 6.2.1 */ +/* xx-xx-xxxx Xiuwen Cai Modified comment(s), */ +/* added option for random */ +/* number stack filling, */ +/* resulting in version 6.x */ /* */ /**************************************************************************/ @@ -172,7 +176,11 @@ extern "C" { #define TX_NO_MESSAGES ((UINT) 0) #define TX_EMPTY ((ULONG) 0) #define TX_CLEAR_ID ((ULONG) 0) +#if defined(TX_ENABLE_RANDOM_NUMBER_STACK_FILLING) && defined(TX_ENABLE_STACK_CHECKING) +#define TX_STACK_FILL (thread_ptr -> tx_thread_stack_fill_value) +#else #define TX_STACK_FILL ((ULONG) 0xEFEFEFEFUL) +#endif /* Thread execution state values. */ @@ -639,6 +647,12 @@ typedef struct TX_THREAD_STRUCT cleanup routine executes. */ ULONG tx_thread_suspension_sequence; +#if defined(TX_ENABLE_RANDOM_NUMBER_STACK_FILLING) && defined(TX_ENABLE_STACK_CHECKING) + + /* Define the random stack fill number. This can be used to detect stack overflow. */ + ULONG tx_thread_stack_fill_value; +#endif + /* Define the user extension field. This typically is defined to white space, but some ports of ThreadX may need to have additional fields in the thread control block. This is @@ -1886,6 +1900,21 @@ UINT _tx_trace_interrupt_control(UINT new_posture); #endif +/* Add a default macro that can be re-defined in tx_port.h to add processing to the initialize random number generator. + By default, this is simply defined as whitespace. */ + +#ifndef TX_INITIALIZE_RANDOM_GENERATOR_INITIALIZATION +#define TX_INITIALIZE_RANDOM_GENERATOR_INITIALIZATION +#endif + + +/* Define the TX_RAND macro to the standard library function, if not already defined. */ + +#ifndef TX_RAND +#define TX_RAND() rand() +#endif + + /* Check for MISRA compliance requirements. */ #ifdef TX_MISRA_ENABLE diff --git a/common_smp/inc/tx_user_sample.h b/common_smp/inc/tx_user_sample.h index d04d2dcb..e637346f 100644 --- a/common_smp/inc/tx_user_sample.h +++ b/common_smp/inc/tx_user_sample.h @@ -26,7 +26,7 @@ /* PORT SPECIFIC C INFORMATION RELEASE */ /* */ /* tx_user.h PORTABLE C */ -/* 6.1.11 */ +/* 6.x */ /* */ /* AUTHOR */ /* */ @@ -62,6 +62,10 @@ /* optimized the definition of */ /* TX_TIMER_TICKS_PER_SECOND, */ /* resulting in version 6.1.11 */ +/* xx-xx-xxxx Xiuwen Cai Modified comment(s), */ +/* added option for random */ +/* number stack filling, */ +/* resulting in version 6.x */ /* */ /**************************************************************************/ @@ -170,6 +174,14 @@ #define TX_ENABLE_STACK_CHECKING */ +/* Determine if random number is used for stack filling. By default, ThreadX uses a fixed + pattern for stack filling. When the following is defined, ThreadX uses a random number + for stack filling. This is effective only when TX_ENABLE_STACK_CHECKING is defined. */ + +/* +#define TX_ENABLE_RANDOM_NUMBER_STACK_FILLING +*/ + /* Determine if preemption-threshold should be disabled. By default, preemption-threshold is enabled. If the application does not use preemption-threshold, it may be disabled to reduce code size and improve performance. */ diff --git a/common_smp/src/tx_initialize_kernel_enter.c b/common_smp/src/tx_initialize_kernel_enter.c index 4f57da02..b35981b8 100644 --- a/common_smp/src/tx_initialize_kernel_enter.c +++ b/common_smp/src/tx_initialize_kernel_enter.c @@ -47,7 +47,7 @@ TX_SAFETY_CRITICAL_EXCEPTION_HANDLER /* FUNCTION RELEASE */ /* */ /* _tx_initialize_kernel_enter PORTABLE SMP */ -/* 6.1 */ +/* 6.x */ /* AUTHOR */ /* */ /* William E. Lamie, Microsoft Corporation */ @@ -87,7 +87,11 @@ TX_SAFETY_CRITICAL_EXCEPTION_HANDLER /* */ /* DATE NAME DESCRIPTION */ /* */ -/* 09-30-2020 William E. Lamie Initial Version 6.1 */ +/* 09-30-2020 William E. Lamie Initial Version 6.1 */ +/* xx-xx-xxxx Xiuwen Cai Modified comment(s), */ +/* added random generator */ +/* initialization, */ +/* resulting in version 6.x */ /* */ /**************************************************************************/ VOID _tx_initialize_kernel_enter(VOID) @@ -134,6 +138,9 @@ ULONG other_core_status, i; later used to represent interrupt nesting. */ _tx_thread_system_state[0] = TX_INITIALIZE_IN_PROGRESS; + /* Optional random number generator initialization. */ + TX_INITIALIZE_RANDOM_GENERATOR_INITIALIZATION + /* Call the application provided initialization function. Pass the first available memory address to it. */ tx_application_define(_tx_initialize_unused_memory); diff --git a/common_smp/src/tx_thread_create.c b/common_smp/src/tx_thread_create.c index 2c799a9b..ffb37132 100644 --- a/common_smp/src/tx_thread_create.c +++ b/common_smp/src/tx_thread_create.c @@ -37,7 +37,7 @@ /* FUNCTION RELEASE */ /* */ /* _tx_thread_create PORTABLE SMP */ -/* 6.2.0 */ +/* 6.x */ /* AUTHOR */ /* */ /* William E. Lamie, Microsoft Corporation */ @@ -89,6 +89,10 @@ /* restore interrupts at end */ /* of if block, */ /* resulting in version 6.2.0 */ +/* xx-xx-xxxx Xiuwen Cai Modified comment(s), */ +/* added option for random */ +/* number stack filling, */ +/* resulting in version 6.x */ /* */ /**************************************************************************/ UINT _tx_thread_create(TX_THREAD *thread_ptr, CHAR *name_ptr, @@ -110,6 +114,17 @@ ALIGN_TYPE updated_stack_start; #ifndef TX_DISABLE_STACK_FILLING +#if defined(TX_ENABLE_RANDOM_NUMBER_STACK_FILLING) && defined(TX_ENABLE_STACK_CHECKING) + + /* Initialize the stack fill value to a 8-bit random value. */ + thread_ptr -> tx_thread_stack_fill_value = ((ULONG) TX_RAND()) & 0xFFUL; + + /* Duplicate the random value in each of the 4 bytes of the stack fill value. */ + thread_ptr -> tx_thread_stack_fill_value = thread_ptr -> tx_thread_stack_fill_value | + (thread_ptr -> tx_thread_stack_fill_value << 8) | + (thread_ptr -> tx_thread_stack_fill_value << 16) | + (thread_ptr -> tx_thread_stack_fill_value << 24); +#endif /* Set the thread stack to a pattern prior to creating the initial stack frame. This pattern is used by the stack checking routines diff --git a/test/smp/cmake/CMakeLists.txt b/test/smp/cmake/CMakeLists.txt index f50c7861..04d15ef5 100644 --- a/test/smp/cmake/CMakeLists.txt +++ b/test/smp/cmake/CMakeLists.txt @@ -6,7 +6,7 @@ project(threadx_smp_test LANGUAGES C) # Set build configurations set(BUILD_CONFIGURATIONS default_build_coverage - disable_notify_callbacks_build stack_checking_build + disable_notify_callbacks_build stack_checking_build stack_checking_rand_fill_build trace_build) set(CMAKE_CONFIGURATION_TYPES ${BUILD_CONFIGURATIONS} @@ -26,6 +26,7 @@ message(STATUS "Using toolchain file: ${CMAKE_TOOLCHAIN_FILE}.") set(default_build_coverage "") set(disable_notify_callbacks_build -DTX_DISABLE_NOTIFY_CALLBACKS) set(stack_checking_build -DTX_ENABLE_STACK_CHECKING) +set(stack_checking_rand_fill_build -DTX_ENABLE_STACK_CHECKING -DTX_ENABLE_RANDOM_NUMBER_STACK_FILLING) set(trace_build -DTX_ENABLE_EVENT_TRACE) add_compile_options( diff --git a/test/smp/regression/testcontrol.c b/test/smp/regression/testcontrol.c index 1813d42f..8e3d872e 100644 --- a/test/smp/regression/testcontrol.c +++ b/test/smp/regression/testcontrol.c @@ -519,6 +519,9 @@ UINT status; ULONG flags; ULONG temp; UINT i, j; +#if defined(TX_ENABLE_RANDOM_NUMBER_STACK_FILLING) && defined(TX_ENABLE_STACK_CHECKING) +TX_THREAD *thread_ptr; +#endif /* Initialize the test error/success counters. */ @@ -1072,6 +1075,15 @@ UINT i, j; /* Make a fake thread with a fake stack. */ test_thread2.tx_thread_id = TX_THREAD_ID; +#if defined(TX_ENABLE_RANDOM_NUMBER_STACK_FILLING) && defined(TX_ENABLE_STACK_CHECKING) + + /* Set the thread pointer. */ + thread_ptr = &(test_thread2); + + /* Initialize the stack fill value. */ + thread_ptr -> tx_thread_stack_fill_value = (0xFEFEFEFEUL); + +#endif for (i = 0; i < (sizeof(test_thread2_stack)/sizeof(ULONG)); i++) { /* Set the fake thread stack to the fill pattern. */ diff --git a/test/tx/cmake/CMakeLists.txt b/test/tx/cmake/CMakeLists.txt index 02e2a41b..b440d2cf 100644 --- a/test/tx/cmake/CMakeLists.txt +++ b/test/tx/cmake/CMakeLists.txt @@ -6,7 +6,7 @@ project(threadx_test LANGUAGES C) # Set build configurations set(BUILD_CONFIGURATIONS default_build_coverage disable_notify_callbacks_build - stack_checking_build trace_build) + stack_checking_build stack_checking_rand_fill_build trace_build) set(CMAKE_CONFIGURATION_TYPES ${BUILD_CONFIGURATIONS} CACHE STRING "list of supported configuration types" FORCE) @@ -25,6 +25,7 @@ message(STATUS "Using toolchain file: ${CMAKE_TOOLCHAIN_FILE}.") set(default_build_coverage "") set(disable_notify_callbacks_build -DTX_DISABLE_NOTIFY_CALLBACKS) set(stack_checking_build -DTX_ENABLE_STACK_CHECKING) +set(stack_checking_rand_fill_build -DTX_ENABLE_STACK_CHECKING -DTX_ENABLE_RANDOM_NUMBER_STACK_FILLING) set(trace_build -DTX_ENABLE_EVENT_TRACE) add_compile_options( diff --git a/test/tx/regression/testcontrol.c b/test/tx/regression/testcontrol.c index ff257ca1..a53c50a5 100644 --- a/test/tx/regression/testcontrol.c +++ b/test/tx/regression/testcontrol.c @@ -477,6 +477,9 @@ UINT status; ULONG flags; ULONG temp; UINT i, j; +#if defined(TX_ENABLE_RANDOM_NUMBER_STACK_FILLING) && defined(TX_ENABLE_STACK_CHECKING) +TX_THREAD *thread_ptr; +#endif /* Initialize the test error/success counters. */ @@ -946,6 +949,15 @@ UINT i, j; /* Make a fake thread with a fake stack. */ test_thread2.tx_thread_id = TX_THREAD_ID; +#if defined(TX_ENABLE_RANDOM_NUMBER_STACK_FILLING) && defined(TX_ENABLE_STACK_CHECKING) + + /* Set the thread pointer. */ + thread_ptr = &(test_thread2); + + /* Initialize the stack fill value. */ + thread_ptr -> tx_thread_stack_fill_value = (0xFEFEFEFEUL); + +#endif for (i = 0; i < (sizeof(test_thread2_stack)/sizeof(ULONG)); i++) { /* Set the fake thread stack to the fill pattern. */