mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2026-01-10 17:41:54 +00:00
Stack overflow detection
Use guard value to detect stack overflow Signed-off-by: Vic Yang <victoryang@google.com> BUG=chrome-os-partner:8069 TEST=Compile with detection enabled. Cause a task to overflow and see device halted. Hook gdb and see it stopped at the assertion. Change-Id: I3417cca8edf4e1291ccb7848bd564b631a9ce463
This commit is contained in:
@@ -27,6 +27,7 @@ typedef union {
|
||||
struct {
|
||||
uint32_t sp; /* saved stack pointer for context switch */
|
||||
uint32_t events; /* bitmaps of received events */
|
||||
uint32_t guard; /* Guard value to detect stack overflow */
|
||||
uint8_t stack[0]; /* task stack */
|
||||
};
|
||||
uint32_t context[TASK_SIZE/4];
|
||||
@@ -72,10 +73,12 @@ static void task_exit_trap(void)
|
||||
}
|
||||
|
||||
|
||||
#define GUARD_VALUE 0x12345678
|
||||
|
||||
/* declare and fill the contexts for all the tasks */
|
||||
#define TASK(n, r, d) { \
|
||||
.context[0] = (uint32_t)(tasks + TASK_ID_##n + 1) - 64, \
|
||||
.context[2] = GUARD_VALUE, \
|
||||
.context[TASK_SIZE/4 - 8/*r0*/] = (uint32_t)d, \
|
||||
.context[TASK_SIZE/4 - 3/*lr*/] = (uint32_t)task_exit_trap, \
|
||||
.context[TASK_SIZE/4 - 2/*pc*/] = (uint32_t)r, \
|
||||
@@ -87,8 +90,13 @@ static task_ tasks[] __attribute__((section(".data.tasks")))
|
||||
CONFIG_TASK_LIST
|
||||
};
|
||||
#undef TASK
|
||||
/* reserve space to discard context on first context switch */
|
||||
uint32_t scratchpad[17] __attribute__((section(".data.tasks")));
|
||||
/* Reserve space to discard context on first context switch.
|
||||
* Fill in guard value to prevent overflow detection failure at first
|
||||
* context switch. Modify this if the position of guard value changes.
|
||||
* TODO: come up with a better way than hardcoding the position of guard value.
|
||||
*/
|
||||
uint32_t scratchpad[17] __attribute__((section(".data.tasks"))) =
|
||||
{0, 0, GUARD_VALUE};
|
||||
|
||||
/* context switch at the next exception exit if needed */
|
||||
/* TODO: who sets this back to 0 after it's set to 1? */
|
||||
@@ -181,6 +189,10 @@ void svc_handler(int desched, task_id_t resched)
|
||||
asm volatile("cpsid f\n"
|
||||
"isb\n");
|
||||
current = __get_task_scheduled();
|
||||
#ifdef CONFIG_OVERFLOW_DETECT
|
||||
ASSERT(current->guard == GUARD_VALUE);
|
||||
#endif
|
||||
|
||||
if (desched && !current->events) {
|
||||
/* Remove our own ready bit */
|
||||
tasks_ready &= ~(1 << (current-tasks));
|
||||
|
||||
Reference in New Issue
Block a user