Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions common/inc/tx_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@
* SPDX-License-Identifier: MIT
**************************************************************************/

/* Portions of this file were generated with AI assistance. */


/**************************************************************************/
/**************************************************************************/
Expand Down Expand Up @@ -1962,7 +1960,11 @@ VOID _tx_misra_thread_entry_exit_notify_not_used(VOID (*threa
#define TX_TIMER_POINTER_DIF(a,b) _tx_misra_timer_pointer_dif((TX_TIMER_INTERNAL **) (a), (TX_TIMER_INTERNAL **) (b))
#define TX_TIMER_POINTER_ADD(a,b) _tx_misra_timer_pointer_add((TX_TIMER_INTERNAL **) (a), (ULONG) (b))
#define TX_USER_TIMER_POINTER_GET(a,b) _tx_misra_user_timer_pointer_get((TX_TIMER_INTERNAL *) (a), (TX_TIMER **) &(b));
#if defined(TXM_MODULE_MANAGER) && defined(TX_ENABLE_STACK_CHECKING)
#define TX_THREAD_STACK_CHECK(a) _tx_misra_thread_stack_check((a), (((a) && ((a)->tx_thread_module_instance_ptr != TX_NULL) && ((a)->tx_thread_module_kernel_stack_start != TX_NULL) && (((a)->tx_thread_module_current_user_mode == 0) || ((a)->tx_thread_stack_start == (a)->tx_thread_module_kernel_stack_start))) ? &((a)->tx_thread_module_kernel_stack_highest_ptr) : &((a)->tx_thread_stack_highest_ptr)));
#else
#define TX_THREAD_STACK_CHECK(a) _tx_misra_thread_stack_check((a), &((a)->tx_thread_stack_highest_ptr));
#endif
#ifdef TX_ENABLE_EVENT_TRACE
#define TX_TRACE_IN_LINE_INSERT(i,a,b,c,d,e) _tx_misra_trace_event_insert((ULONG) (i), (VOID *) (a), (ULONG) (b), (ULONG) (c), (ULONG) (d), (ULONG) (e), ((ULONG) TX_TRACE_TIME_SOURCE));
#endif
Expand Down
56 changes: 55 additions & 1 deletion common/inc/tx_thread.h
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,59 @@
low address to high address (the default logic is for stacks that
grow from high address to low address. */

#ifndef tx_thread_module_kernel_stack_highest_ptr
#define tx_thread_module_kernel_stack_highest_ptr tx_thread_module_reserved
#endif

#ifndef TX_THREAD_STACK_CHECK
#if defined(TXM_MODULE_MANAGER) && defined(TX_ENABLE_STACK_CHECKING)
#define TX_THREAD_STACK_CHECK(thread_ptr) \
{ \
TX_INTERRUPT_SAVE_AREA \
TX_DISABLE \
if (((thread_ptr)) && ((thread_ptr) -> tx_thread_id == TX_THREAD_ID)) \
{ \
VOID **_tx_highest_ptr_ref; \
VOID *_tx_guard_ptr; \
VOID *_tx_stack_start; \
if (((thread_ptr) -> tx_thread_module_instance_ptr != TX_NULL) && \
((thread_ptr) -> tx_thread_module_kernel_stack_start != TX_NULL) && \
(((thread_ptr) -> tx_thread_module_current_user_mode == 0) || \
((thread_ptr) -> tx_thread_stack_start == (thread_ptr) -> tx_thread_module_kernel_stack_start))) \
{ \
_tx_stack_start = (thread_ptr) -> tx_thread_module_kernel_stack_start; \
_tx_highest_ptr_ref = &((thread_ptr) -> tx_thread_module_kernel_stack_highest_ptr); \
_tx_guard_ptr = (VOID *) (((ALIGN_TYPE) (thread_ptr) -> tx_thread_module_kernel_stack_end) + sizeof(ULONG)); \
} \
else \
{ \
_tx_stack_start = (thread_ptr) -> tx_thread_stack_start; \
_tx_highest_ptr_ref = &((thread_ptr) -> tx_thread_stack_highest_ptr); \
_tx_guard_ptr = (VOID *) (((UCHAR *) (thread_ptr) -> tx_thread_stack_end) + 1); \
} \
if (((ULONG *) (thread_ptr) -> tx_thread_stack_ptr) < ((ULONG *) *_tx_highest_ptr_ref)) \
{ \
*_tx_highest_ptr_ref = (thread_ptr) -> tx_thread_stack_ptr; \
} \
if ((*((ULONG *) _tx_stack_start) != TX_STACK_FILL) || \
(*((ULONG *) _tx_guard_ptr) != TX_STACK_FILL) || \
(((ULONG *) *_tx_highest_ptr_ref) < ((ULONG *) _tx_stack_start))) \
{ \
TX_RESTORE \
_tx_thread_stack_error_handler((thread_ptr)); \
TX_DISABLE \
} \
else if ((((ULONG *) *_tx_highest_ptr_ref) > ((ULONG *) _tx_stack_start)) && \
(*(((ULONG *) *_tx_highest_ptr_ref) - 1) != TX_STACK_FILL)) \
{ \
TX_RESTORE \
_tx_thread_stack_analyze((thread_ptr)); \
TX_DISABLE \
} \
} \
TX_RESTORE \
}
#else
#define TX_THREAD_STACK_CHECK(thread_ptr) \
{ \
TX_INTERRUPT_SAVE_AREA \
Expand All @@ -225,7 +277,8 @@
_tx_thread_stack_error_handler((thread_ptr)); \
TX_DISABLE \
} \
else if (*(((ULONG *) (thread_ptr) -> tx_thread_stack_highest_ptr) - 1) != TX_STACK_FILL) \
else if ((((ULONG *) (thread_ptr) -> tx_thread_stack_highest_ptr) > ((ULONG *) (thread_ptr) -> tx_thread_stack_start)) && \
(*(((ULONG *) (thread_ptr) -> tx_thread_stack_highest_ptr) - 1) != TX_STACK_FILL)) \
{ \
TX_RESTORE \
_tx_thread_stack_analyze((thread_ptr)); \
Expand All @@ -235,6 +288,7 @@
TX_RESTORE \
}
#endif
#endif


/* Define default post thread delete macro to whitespace, if it hasn't been defined previously (typically in tx_port.h). */
Expand Down
45 changes: 44 additions & 1 deletion common/src/tx_misra.c
Original file line number Diff line number Diff line change
Expand Up @@ -276,10 +276,51 @@ VOID _tx_misra_thread_stack_check(TX_THREAD *thread_ptr, VOID **highest_stack)
{

TX_INTERRUPT_SAVE_AREA
#if defined(TXM_MODULE_MANAGER) && defined(TX_ENABLE_STACK_CHECKING)
VOID *_tx_guard_ptr;
VOID *_tx_stack_start;
VOID **_tx_highest_ptr_ref;
#endif

TX_DISABLE
if (((thread_ptr)) && ((thread_ptr) -> tx_thread_id == TX_THREAD_ID))
{
#if defined(TXM_MODULE_MANAGER) && defined(TX_ENABLE_STACK_CHECKING)
if (((thread_ptr) -> tx_thread_module_instance_ptr != TX_NULL) &&
((thread_ptr) -> tx_thread_module_kernel_stack_start != TX_NULL) &&
(((thread_ptr) -> tx_thread_module_current_user_mode == 0) ||
((thread_ptr) -> tx_thread_stack_start == (thread_ptr) -> tx_thread_module_kernel_stack_start)))
{
_tx_stack_start = (thread_ptr) -> tx_thread_module_kernel_stack_start;
_tx_highest_ptr_ref = &((thread_ptr) -> tx_thread_module_kernel_stack_highest_ptr);
_tx_guard_ptr = (VOID *) (((ALIGN_TYPE) (thread_ptr) -> tx_thread_module_kernel_stack_end) + sizeof(ULONG));
}
else
{
_tx_stack_start = (thread_ptr) -> tx_thread_stack_start;
_tx_highest_ptr_ref = highest_stack;
_tx_guard_ptr = (VOID *) (((UCHAR *) (thread_ptr) -> tx_thread_stack_end) + 1);
}
if (((ULONG *) (thread_ptr) -> tx_thread_stack_ptr) < ((ULONG *) *_tx_highest_ptr_ref))
{
*_tx_highest_ptr_ref = (thread_ptr) -> tx_thread_stack_ptr;
}
if ((*((ULONG *) _tx_stack_start) != TX_STACK_FILL) ||
(*((ULONG *) _tx_guard_ptr) != TX_STACK_FILL) ||
(((ULONG *) *_tx_highest_ptr_ref) < ((ULONG *) _tx_stack_start)))
{
TX_RESTORE
_tx_thread_stack_error_handler((thread_ptr));
TX_DISABLE
}
else if ((((ULONG *) *_tx_highest_ptr_ref) > ((ULONG *) _tx_stack_start)) &&
(*(((ULONG *) *_tx_highest_ptr_ref) - 1) != TX_STACK_FILL))
{
TX_RESTORE
_tx_thread_stack_analyze((thread_ptr));
TX_DISABLE
}
#else
if (((ULONG *) (thread_ptr) -> tx_thread_stack_ptr) < ((ULONG *) *highest_stack))
{
*highest_stack = (thread_ptr) -> tx_thread_stack_ptr;
Expand All @@ -292,12 +333,14 @@ TX_INTERRUPT_SAVE_AREA
_tx_thread_stack_error_handler((thread_ptr));
TX_DISABLE
}
if (*(((ULONG *) *highest_stack) - 1) != TX_STACK_FILL)
else if ((((ULONG *) *highest_stack) > ((ULONG *) (thread_ptr) -> tx_thread_stack_start)) &&
(*(((ULONG *) *highest_stack) - 1) != TX_STACK_FILL))
{
TX_RESTORE
_tx_thread_stack_analyze((thread_ptr));
TX_DISABLE
}
#endif
}
TX_RESTORE
}
Expand Down
51 changes: 49 additions & 2 deletions common/src/tx_thread_stack_analyze.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@
* SPDX-License-Identifier: MIT
**************************************************************************/

// Portions of this file were generated with AI assistance.


/**************************************************************************/
/**************************************************************************/
Expand Down Expand Up @@ -77,6 +75,9 @@ ULONG *stack_limit;
ULONG probe_count;
UINT fill_present;
ULONG size;
#if defined(TXM_MODULE_MANAGER) && defined(TX_ENABLE_STACK_CHECKING)
UINT analyzing_kernel_stack;
#endif


/* Disable interrupts. */
Expand All @@ -97,8 +98,25 @@ ULONG size;
if (stack_lowest != TX_NULL)
{

#if defined(TXM_MODULE_MANAGER) && defined(TX_ENABLE_STACK_CHECKING)
/* Determine if this thread is currently on the module kernel stack. */
if (((thread_ptr -> tx_thread_module_kernel_stack_start) != TX_NULL) &&
(((thread_ptr -> tx_thread_module_current_user_mode) == 0) ||
((thread_ptr -> tx_thread_stack_start) == (thread_ptr -> tx_thread_module_kernel_stack_start))))
{
analyzing_kernel_stack = TX_TRUE;
stack_lowest = TX_VOID_TO_ULONG_POINTER_CONVERT(thread_ptr -> tx_thread_module_kernel_stack_start);
stack_highest = TX_VOID_TO_ULONG_POINTER_CONVERT(thread_ptr -> tx_thread_module_kernel_stack_highest_ptr);
}
else
{
analyzing_kernel_stack = TX_FALSE;
stack_highest = TX_VOID_TO_ULONG_POINTER_CONVERT(thread_ptr -> tx_thread_stack_highest_ptr);
}
#else
/* Pickup the highest stack pointer. */
stack_highest = TX_VOID_TO_ULONG_POINTER_CONVERT(thread_ptr -> tx_thread_stack_highest_ptr);
#endif

/* Determine if the pointer is null or if the highest stack pointer is not above the
start of the stack. The latter indicates a stack overflow or a corrupted thread
Expand Down Expand Up @@ -199,6 +217,34 @@ ULONG size;

/* Yes, thread is still created. */

#if defined(TXM_MODULE_MANAGER) && defined(TX_ENABLE_STACK_CHECKING)
if (analyzing_kernel_stack == TX_TRUE)
{
if (stack_ptr > (TX_VOID_TO_ULONG_POINTER_CONVERT(thread_ptr -> tx_thread_module_kernel_stack_start)))
{
if (stack_ptr < (TX_VOID_TO_ULONG_POINTER_CONVERT(thread_ptr -> tx_thread_module_kernel_stack_highest_ptr)))
{
if (*stack_ptr != TX_STACK_FILL)
{
thread_ptr -> tx_thread_module_kernel_stack_highest_ptr = (VOID *) stack_ptr;
}
}
}
}
else
{
if (stack_ptr > (TX_VOID_TO_ULONG_POINTER_CONVERT(thread_ptr -> tx_thread_stack_start)))
{
if (stack_ptr < (TX_VOID_TO_ULONG_POINTER_CONVERT(thread_ptr -> tx_thread_stack_highest_ptr)))
{
if (*stack_ptr != TX_STACK_FILL)
{
thread_ptr -> tx_thread_stack_highest_ptr = stack_ptr;
}
}
}
}
#else
/* Now check the new highest stack pointer is past the stack start. */
if (stack_ptr > (TX_VOID_TO_ULONG_POINTER_CONVERT(thread_ptr -> tx_thread_stack_start)))
{
Expand All @@ -216,6 +262,7 @@ ULONG size;
}
}
}
#endif
}
}
}
Expand Down
5 changes: 5 additions & 0 deletions common_modules/inc/txm_module.h
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,11 @@ extern "C" {
#endif


/* Define alias for kernel stack highest pointer used when stack checking is enabled. */

#define tx_thread_module_kernel_stack_highest_ptr tx_thread_module_reserved


/* Define object types for object search requests. */

#define TXM_BLOCK_POOL_OBJECT 1
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@
* SPDX-License-Identifier: MIT
**************************************************************************/

// Portions of this file were generated with AI assistance.


/**************************************************************************/
/**************************************************************************/
Expand Down Expand Up @@ -327,13 +325,6 @@ ULONG i;
thread_ptr -> tx_thread_stack_fill_value = stack_fill_value;
#endif

/* Note that TX_ENABLE_STACK_CHECKING is not supported for module threads. A user mode
module thread owns two stacks and the scheduler swaps tx_thread_stack_start,
tx_thread_stack_end and tx_thread_stack_size over to the kernel stack whenever the
thread enters the module manager. Neither tx_thread_stack_highest_ptr nor the guard
pattern beyond the end of the stack is maintained across that switch, so
TX_THREAD_STACK_CHECK may report spurious stack errors for module threads. */

/* If the thread runs on user mode, allocate the kernel stack for syscall. */
if((module_instance -> txm_module_instance_property_flags) & TXM_MODULE_USER_MODE)
{
Expand All @@ -354,12 +345,21 @@ ULONG i;
#endif

/* Align kernel stack pointer. */
#ifdef TX_ENABLE_STACK_CHECKING
thread_ptr -> tx_thread_module_kernel_stack_end = (VOID *) (((ALIGN_TYPE)(thread_ptr -> tx_thread_module_kernel_stack_start) + TXM_MODULE_KERNEL_STACK_SIZE - (sizeof(ULONG) * 2)) & ~0x07);
#else
thread_ptr -> tx_thread_module_kernel_stack_end = (VOID *) (((ALIGN_TYPE)(thread_ptr -> tx_thread_module_kernel_stack_start) + TXM_MODULE_KERNEL_STACK_SIZE) & ~0x07);
#endif

/* Set kernel stack size. Aligning the end of the kernel stack downwards can consume
up to seven bytes of the block returned by the allocator, so the usable size must be
derived from the aligned range instead of from TXM_MODULE_KERNEL_STACK_SIZE. */
thread_ptr -> tx_thread_module_kernel_stack_size = (ULONG) ((ALIGN_TYPE) (thread_ptr -> tx_thread_module_kernel_stack_end) - (ALIGN_TYPE) (thread_ptr -> tx_thread_module_kernel_stack_start));

#ifdef TX_ENABLE_STACK_CHECKING
/* Setup the highest usage pointer for the kernel stack. */
thread_ptr -> tx_thread_module_kernel_stack_highest_ptr = thread_ptr -> tx_thread_module_kernel_stack_end;
#endif
}

#if TXM_MODULE_MEMORY_PROTECTION
Expand Down
Loading