py/nlraarch64: Fix dangerous use of input register.

Starting with 2757acf6, the `top` variable in `nlr_jump()` in
`nlraarch64.c` was assigned to register `x19` by the compiler.  However,
the assembly code writes over that register with

    ldp x19, x20, [%0,  #32]

since `%0` is now `x19`. This causes the next line

    ldp lr,  x9,  [%0,  #16]

to load the wrong values.

To fix the issue, we move the value of the `top` variable from an unknown
register to a known register at the beginning of the asm code then only use
known/hard-coded registers after that.

Fixes issue #11754.

Signed-off-by: David Lechner <david@pybricks.com>
This commit is contained in:
David Lechner 2023-06-11 14:53:15 -05:00 committed by Damien George
parent 8cf9898dd3
commit b02a5fa10a
1 changed files with 8 additions and 7 deletions

View File

@ -62,13 +62,14 @@ NORETURN void nlr_jump(void *val) {
MP_STATIC_ASSERT(offsetof(nlr_buf_t, regs) == 16); // asm assumes it
__asm volatile (
"ldr x29, [%0, #112]\n"
"ldp x27, x28, [%0, #96]\n"
"ldp x25, x26, [%0, #80]\n"
"ldp x23, x24, [%0, #64]\n"
"ldp x21, x22, [%0, #48]\n"
"ldp x19, x20, [%0, #32]\n"
"ldp lr, x9, [%0, #16]\n" // 16 == offsetof(nlr_buf_t, regs)
"mov x0, %0 \n"
"ldr x29, [x0, #112]\n"
"ldp x27, x28, [x0, #96]\n"
"ldp x25, x26, [x0, #80]\n"
"ldp x23, x24, [x0, #64]\n"
"ldp x21, x22, [x0, #48]\n"
"ldp x19, x20, [x0, #32]\n"
"ldp lr, x9, [x0, #16]\n" // 16 == offsetof(nlr_buf_t, regs)
"mov sp, x9 \n"
"mov x0, #1 \n" // non-local return
"ret \n"