diff --git a/py/mpconfig.h b/py/mpconfig.h index af2480266bca..1aa3e06994d3 100644 --- a/py/mpconfig.h +++ b/py/mpconfig.h @@ -587,6 +587,12 @@ /*****************************************************************************/ /* Python internal features */ +// Use a special long jump in nlrthumb.c, which may be necessary if nlr.o and +// nlrthumb.o are linked far apart from each other. +#ifndef MICROPY_NLR_THUMB_USE_LONG_JUMP +#define MICROPY_NLR_THUMB_USE_LONG_JUMP (0) +#endif + // Whether to enable import of external modules // When disabled, only importing of built-in modules is supported // When enabled, a port must implement mp_import_stat (among other things) diff --git a/py/nlrthumb.c b/py/nlrthumb.c index a22c5df5b941..e7b24f242bc5 100644 --- a/py/nlrthumb.c +++ b/py/nlrthumb.c @@ -38,6 +38,14 @@ __attribute__((naked)) unsigned int nlr_push(nlr_buf_t *nlr) { + // If you get a linker error here, indicating that a relocation doesn't + // fit, try the following (in that order): + // + // 1. Ensure that nlr.o nlrthumb.o are linked closely together, i.e. + // there aren't too many other files between them in the linker list + // (PY_CORE_O_BASENAME in py/py.mk) + // 2. Set -DMICROPY_NLR_THUMB_USE_LONG_JUMP=1 during the build + // __asm volatile ( "str r4, [r0, #12] \n" // store r4 into nlr_buf "str r5, [r0, #16] \n" // store r5 into nlr_buf @@ -71,7 +79,7 @@ __attribute__((naked)) unsigned int nlr_push(nlr_buf_t *nlr) { "str lr, [r0, #8] \n" // store lr into nlr_buf #endif - #if !defined(__thumb2__) + #if MICROPY_NLR_THUMB_USE_LONG_JUMP "ldr r1, nlr_push_tail_var \n" "bx r1 \n" // do the rest in C ".align 2 \n"