Add stack check to pcall/xpcall.

Analyzed by Peter Cawley. #1048
This commit is contained in:
Mike Pall 2023-11-12 14:42:24 +01:00
parent 65c8493907
commit a4c1640432
5 changed files with 38 additions and 1 deletions

View File

@ -1155,8 +1155,11 @@ static void build_subroutines(BuildCtx *ctx)
|//-- Base library: catch errors ---------------------------------------- |//-- Base library: catch errors ----------------------------------------
| |
|.ffunc pcall |.ffunc pcall
| ldr RB, L->maxstack
| add INS, BASE, NARGS8:RC
| ldrb RA, [DISPATCH, #DISPATCH_GL(hookmask)] | ldrb RA, [DISPATCH, #DISPATCH_GL(hookmask)]
| cmp NARGS8:RC, #8 | cmp NARGS8:RC, #8
| cmphs RB, INS
| blo ->fff_fallback | blo ->fff_fallback
| tst RA, #HOOK_ACTIVE // Remember active hook before pcall. | tst RA, #HOOK_ACTIVE // Remember active hook before pcall.
| mov RB, BASE | mov RB, BASE
@ -1167,7 +1170,11 @@ static void build_subroutines(BuildCtx *ctx)
| b ->vm_call_dispatch | b ->vm_call_dispatch
| |
|.ffunc_2 xpcall |.ffunc_2 xpcall
| ldr RB, L->maxstack
| add INS, BASE, NARGS8:RC
| ldrb RA, [DISPATCH, #DISPATCH_GL(hookmask)] | ldrb RA, [DISPATCH, #DISPATCH_GL(hookmask)]
| cmp RB, INS
| blo ->fff_fallback
| checkfunc CARG4, ->fff_fallback // Traceback must be a function. | checkfunc CARG4, ->fff_fallback // Traceback must be a function.
| mov RB, BASE | mov RB, BASE
| strd CARG12, [BASE, #8] // Swap function and traceback. | strd CARG12, [BASE, #8] // Swap function and traceback.

View File

@ -1244,9 +1244,13 @@ static void build_subroutines(BuildCtx *ctx)
|//-- Base library: catch errors ---------------------------------------- |//-- Base library: catch errors ----------------------------------------
| |
|.ffunc pcall |.ffunc pcall
| lw TMP1, L->maxstack
| addu TMP2, BASE, NARGS8:RC
| lbu TMP3, DISPATCH_GL(hookmask)(DISPATCH) | lbu TMP3, DISPATCH_GL(hookmask)(DISPATCH)
| beqz NARGS8:RC, ->fff_fallback | beqz NARGS8:RC, ->fff_fallback
| move TMP2, BASE |. sltu AT, TMP1, TMP2
| bnez AT, ->fff_fallback
|. move TMP2, BASE
| addiu BASE, BASE, 8 | addiu BASE, BASE, 8
| // Remember active hook before pcall. | // Remember active hook before pcall.
| srl TMP3, TMP3, HOOK_ACTIVE_SHIFT | srl TMP3, TMP3, HOOK_ACTIVE_SHIFT
@ -1256,8 +1260,12 @@ static void build_subroutines(BuildCtx *ctx)
|. addiu NARGS8:RC, NARGS8:RC, -8 |. addiu NARGS8:RC, NARGS8:RC, -8
| |
|.ffunc xpcall |.ffunc xpcall
| lw TMP1, L->maxstack
| addu TMP2, BASE, NARGS8:RC
| sltiu AT, NARGS8:RC, 16 | sltiu AT, NARGS8:RC, 16
| lw CARG4, 8+HI(BASE) | lw CARG4, 8+HI(BASE)
| sltu TMP1, TMP1, TMP2
| or AT, AT, TMP1
| bnez AT, ->fff_fallback | bnez AT, ->fff_fallback
|. ldc1 FARG2, 8(BASE) |. ldc1 FARG2, 8(BASE)
| ldc1 FARG1, 0(BASE) | ldc1 FARG1, 0(BASE)

View File

@ -1537,8 +1537,12 @@ static void build_subroutines(BuildCtx *ctx)
|//-- Base library: catch errors ---------------------------------------- |//-- Base library: catch errors ----------------------------------------
| |
|.ffunc pcall |.ffunc pcall
| lwz TMP1, L->maxstack
| add TMP2, BASE, NARGS8:RC
| cmplwi NARGS8:RC, 8 | cmplwi NARGS8:RC, 8
| lbz TMP3, DISPATCH_GL(hookmask)(DISPATCH) | lbz TMP3, DISPATCH_GL(hookmask)(DISPATCH)
| cmplw cr1, TMP1, TMP2
| cror 4*cr0+lt, 4*cr0+lt, 4*cr1+lt
| blt ->fff_fallback | blt ->fff_fallback
| mr TMP2, BASE | mr TMP2, BASE
| la BASE, 8(BASE) | la BASE, 8(BASE)
@ -1549,9 +1553,13 @@ static void build_subroutines(BuildCtx *ctx)
| b ->vm_call_dispatch | b ->vm_call_dispatch
| |
|.ffunc xpcall |.ffunc xpcall
| lwz TMP1, L->maxstack
| add TMP2, BASE, NARGS8:RC
| cmplwi NARGS8:RC, 16 | cmplwi NARGS8:RC, 16
| lwz CARG4, 8(BASE) | lwz CARG4, 8(BASE)
| cmplw cr1, TMP1, TMP2
| lfd FARG2, 8(BASE) | lfd FARG2, 8(BASE)
| cror 4*cr0+lt, 4*cr0+lt, 4*cr1+lt
| lfd FARG1, 0(BASE) | lfd FARG1, 0(BASE)
| blt ->fff_fallback | blt ->fff_fallback
| lbz TMP1, DISPATCH_GL(hookmask)(DISPATCH) | lbz TMP1, DISPATCH_GL(hookmask)(DISPATCH)

View File

@ -1184,8 +1184,12 @@ static void build_subroutines(BuildCtx *ctx)
|//-- Base library: catch errors ---------------------------------------- |//-- Base library: catch errors ----------------------------------------
| |
|.ffunc pcall |.ffunc pcall
| lwz TMP1, L->maxstack
| add TMP2, BASE, NARGS8:RC
| cmplwi NARGS8:RC, 8 | cmplwi NARGS8:RC, 8
| lbz TMP3, DISPATCH_GL(hookmask)(DISPATCH) | lbz TMP3, DISPATCH_GL(hookmask)(DISPATCH)
| cmplw cr1, TMP1, TMP2
| cror 4*cr0+lt, 4*cr0+lt, 4*cr1+lt
| blt ->fff_fallback | blt ->fff_fallback
| mr TMP2, BASE | mr TMP2, BASE
| la BASE, 8(BASE) | la BASE, 8(BASE)
@ -1196,8 +1200,12 @@ static void build_subroutines(BuildCtx *ctx)
| b ->vm_call_dispatch | b ->vm_call_dispatch
| |
|.ffunc_2 xpcall |.ffunc_2 xpcall
| lwz TMP1, L->maxstack
| add TMP2, BASE, NARGS8:RC
| lbz TMP3, DISPATCH_GL(hookmask)(DISPATCH) | lbz TMP3, DISPATCH_GL(hookmask)(DISPATCH)
| mr TMP2, BASE | mr TMP2, BASE
| cmplw TMP1, TMP2
| blt ->fff_fallback
| checkfunc CARG2 // Traceback must be a function. | checkfunc CARG2 // Traceback must be a function.
| checkfail ->fff_fallback | checkfail ->fff_fallback
| la BASE, 16(BASE) | la BASE, 16(BASE)

View File

@ -1720,6 +1720,9 @@ static void build_subroutines(BuildCtx *ctx)
|//-- Base library: catch errors ---------------------------------------- |//-- Base library: catch errors ----------------------------------------
| |
|.ffunc_1 pcall |.ffunc_1 pcall
| mov L:RB, SAVE_L
| lea RA, [BASE+NARGS:RD*8]
| cmp RA, L:RB->maxstack; ja ->fff_fallback
| lea RA, [BASE+8] | lea RA, [BASE+8]
| sub NARGS:RD, 1 | sub NARGS:RD, 1
| mov PC, 8+FRAME_PCALL | mov PC, 8+FRAME_PCALL
@ -1731,6 +1734,9 @@ static void build_subroutines(BuildCtx *ctx)
| jmp ->vm_call_dispatch | jmp ->vm_call_dispatch
| |
|.ffunc_2 xpcall |.ffunc_2 xpcall
| mov L:RB, SAVE_L
| lea RA, [BASE+NARGS:RD*8]
| cmp RA, L:RB->maxstack; ja ->fff_fallback
| cmp dword [BASE+12], LJ_TFUNC; jne ->fff_fallback | cmp dword [BASE+12], LJ_TFUNC; jne ->fff_fallback
| mov RB, [BASE+4] // Swap function and traceback. | mov RB, [BASE+4] // Swap function and traceback.
| mov [BASE+12], RB | mov [BASE+12], RB