Allow unwinding of qvmcall64 call-stub for msvc/masm

qvmcall64 has its own custom calling convention due to pushing all non-volatile registers to the stack. The game uses set/longjmp which on Windows uses "RtlUnwindEx" to unwind the callstack. qvmcall64 cannot be unwound by default due to the custom calling convention. To allow unwinding, we need to add custom SEH unwind data to the function.
This commit is contained in:
Ch40zz 2021-06-23 18:17:36 +02:00 committed by Tim Angus
parent 60a2000419
commit bc7842e301
1 changed files with 17 additions and 1 deletions

View File

@ -28,19 +28,35 @@
; Call to compiled code after setting up the register environment for the VM
; prototype:
; uint8_t qvmcall64(int *programStack, int *opStack, intptr_t *instructionPointers, byte *dataBase);
;
; This call-stub has its own custom calling convention due to pushing all non-volatile registers
; to the stack. The game uses set/longjmp which on Windows uses "RtlUnwindEx" to unwind the callstack.
; This function cannot be unwound by default due to the custom calling convention.
; To allow unwinding, we need to add custom SEH unwind data to the function.
qvmcall64 PROC
qvmcall64 PROC FRAME
push r12 ; push all non-volatile registers to stack
.pushreg r12
push r13
.pushreg r13
push r14
.pushreg r14
push r15
.pushreg r15
push rdi
.pushreg rdi
push rsi
.pushreg rsi
push rbx
.pushreg rbx
push rbp
.pushreg rbp
; need to save pointer in rcx so we can write back the programData value to caller
push rcx
.pushreg rcx
.endprolog ; custom unwind data ends here
; registers r8 and r9 have correct value already thanx to __fastcall
xor rbx, rbx ; opStackOfs starts out being 0