py/nlrx64: Mark nlr_push() as naked function when possible.
Supported from GCC 8 and up, and Compiler Explorer suggests it works as expected with Clang since 3.6 (2014). - Fixes situation where building embedded MicroPython with -O0 and MICROPY_NLR_X64 crashes at runtime (due to nlr_push pushing the frame pointer register EBP). Closes #12421. - Allows removing the macOS tweak to undo pushing EBP onto the stack in the generated function prelude. Signed-off-by: Angus Gratton <angus@redyak.com.au>
This commit is contained in:
parent
00930b213e
commit
fa68523968
24
py/nlrx64.c
24
py/nlrx64.c
@ -35,8 +35,27 @@
|
|||||||
|
|
||||||
__attribute__((used)) unsigned int nlr_push_tail(nlr_buf_t *nlr);
|
__attribute__((used)) unsigned int nlr_push_tail(nlr_buf_t *nlr);
|
||||||
|
|
||||||
|
#if !MICROPY_NLR_OS_WINDOWS
|
||||||
|
#if defined(__clang__) || (defined(__GNUC__) && __GNUC__ >= 8)
|
||||||
|
#define USE_NAKED 1
|
||||||
|
#else
|
||||||
|
// On older gcc the equivalent here is to force omit-frame-pointer
|
||||||
|
__attribute__((optimize("omit-frame-pointer")))
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(USE_NAKED)
|
||||||
|
#define USE_NAKED 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if USE_NAKED
|
||||||
|
// nlr_push prelude should never push frame pointer register ebp onto the stack
|
||||||
|
__attribute__((naked))
|
||||||
|
#endif
|
||||||
unsigned int nlr_push(nlr_buf_t *nlr) {
|
unsigned int nlr_push(nlr_buf_t *nlr) {
|
||||||
|
#if !USE_NAKED
|
||||||
(void)nlr;
|
(void)nlr;
|
||||||
|
#endif
|
||||||
|
|
||||||
#if MICROPY_NLR_OS_WINDOWS
|
#if MICROPY_NLR_OS_WINDOWS
|
||||||
|
|
||||||
@ -58,9 +77,6 @@ unsigned int nlr_push(nlr_buf_t *nlr) {
|
|||||||
#else
|
#else
|
||||||
|
|
||||||
__asm volatile (
|
__asm volatile (
|
||||||
#if defined(__APPLE__) && defined(__MACH__)
|
|
||||||
"pop %rbp \n" // undo function's prelude
|
|
||||||
#endif
|
|
||||||
"movq (%rsp), %rax \n" // load return %rip
|
"movq (%rsp), %rax \n" // load return %rip
|
||||||
"movq %rax, 16(%rdi) \n" // store %rip into nlr_buf
|
"movq %rax, 16(%rdi) \n" // store %rip into nlr_buf
|
||||||
"movq %rbp, 24(%rdi) \n" // store %rbp into nlr_buf
|
"movq %rbp, 24(%rdi) \n" // store %rbp into nlr_buf
|
||||||
@ -79,7 +95,9 @@ unsigned int nlr_push(nlr_buf_t *nlr) {
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if !USE_NAKED
|
||||||
return 0; // needed to silence compiler warning
|
return 0; // needed to silence compiler warning
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
NORETURN void nlr_jump(void *val) {
|
NORETURN void nlr_jump(void *val) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user