diff options
| author | Dan Halbert <halbert@halwitz.org> | 2017-08-05 17:43:48 -0400 |
|---|---|---|
| committer | Scott Shawcroft <scott@tannewt.org> | 2017-08-05 17:48:16 -0700 |
| commit | 5d509ecace763d2e0fad357f4af7c5979cc228fa (patch) | |
| tree | d2ba0fee8c380d581f38322d88aebe083866a1d7 | |
| parent | 91d4cdb476c15df853f42e6b4bd3d117a42d2058 (diff) | |
Allow max stack checking to be used with -flto build by determining top
of stack in a different way.
| -rw-r--r-- | atmel-samd/Makefile | 1 | ||||
| -rw-r--r-- | py/stackctrl.c | 21 |
2 files changed, 18 insertions, 4 deletions
diff --git a/atmel-samd/Makefile b/atmel-samd/Makefile index 7111bee09..9e3a10bd8 100644 --- a/atmel-samd/Makefile +++ b/atmel-samd/Makefile @@ -132,6 +132,7 @@ CFLAGS = $(INC) -Wall -Werror -std=gnu11 -nostdlib $(CFLAGS_CORTEX_M0) $(CFLAGS_ ifeq ($(DEBUG), 1) # NDEBUG disables assert() statements. This reduces code size pretty dramatically, per tannewt. # Turn on Python modules useful for debugging (e.g. uheap, ustack). +# -DMICROPY_DEBUG_MODULES may also be added to an -flto build, if you wish. CFLAGS += -Os -ggdb -DNDEBUG -DENABLE_MICRO_TRACE_BUFFER -DMICROPY_DEBUG_MODULES else CFLAGS += -Os -DNDEBUG -flto diff --git a/py/stackctrl.c b/py/stackctrl.c index 202ae3d48..7f44ec45c 100644 --- a/py/stackctrl.c +++ b/py/stackctrl.c @@ -77,14 +77,27 @@ void mp_stack_set_bottom(void* stack_bottom) { MP_STATE_THREAD(stack_bottom) = stack_bottom; } +// Return the current frame pointer. This can be used as an +// approximation for the stack pointer of the _calling_ function. +// This routine must not be inlined. This method is +// architecture-independent, as opposed to using asm("sp") or similar. +// +// The stack_dummy approach used elsewhere in this file is not safe in +// all cases. That value may be below the actual top of the stack. +static void* approx_stack_pointer(void){ + __asm volatile (""); + return __builtin_frame_address(0); +} + // Fill stack space down toward the stack limit with a known unusual value. void mp_stack_fill_with_sentinel(void) { // Force routine to not be inlined. Better guarantee than MP_NOINLINE for -flto. __asm volatile (""); - volatile char* volatile p; - // Start filling stack just below the last variable in the current stack frame, which is p. - // Continue until we've hit the bottom of the stack (lowest address, logical "ceiling" of stack). - p = (char *) (&p - 1); + // Start filling stack just below the current stack frame. + // Continue until we've hit the bottom of the stack (lowest address, + // logical "ceiling" of stack). + char* p = (char *) approx_stack_pointer() - 1; + while(p >= MP_STATE_THREAD(stack_bottom)) { *p-- = MP_MAX_STACK_USAGE_SENTINEL_BYTE; } |
