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

View file

@ -28,19 +28,35 @@
; Call to compiled code after setting up the register environment for the VM ; Call to compiled code after setting up the register environment for the VM
; prototype: ; prototype:
; uint8_t qvmcall64(int *programStack, int *opStack, intptr_t *instructionPointers, byte *dataBase); ; 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 push r12 ; push all non-volatile registers to stack
.pushreg r12
push r13 push r13
.pushreg r13
push r14 push r14
.pushreg r14
push r15 push r15
.pushreg r15
push rdi push rdi
.pushreg rdi
push rsi push rsi
.pushreg rsi
push rbx push rbx
.pushreg rbx
push rbp push rbp
.pushreg rbp
; need to save pointer in rcx so we can write back the programData value to caller ; need to save pointer in rcx so we can write back the programData value to caller
push rcx push rcx
.pushreg rcx
.endprolog ; custom unwind data ends here
; registers r8 and r9 have correct value already thanx to __fastcall ; registers r8 and r9 have correct value already thanx to __fastcall
xor rbx, rbx ; opStackOfs starts out being 0 xor rbx, rbx ; opStackOfs starts out being 0