From c3456c9e5eca93fbdcce6494aa9759c481e6a1ea Mon Sep 17 00:00:00 2001 From: /dev/humancontroller Date: Mon, 23 Mar 2015 20:16:11 -0500 Subject: Fix return values in nested system calls from QVMs When the engine is compiled with Clang it appears that the return value is being written to the WRONG address, either due to the vm_ variables being changed (unexpectedly) elsewhere, or as a result of bad assembly assumptions; having a stack variable pointing to where to write the return value seems to do the trick. This fixes the case where, for a trap_Register()-like call, weird numbers are being returned when, during the process, an error message is printed (which in Tremulous results in a QVM call and (nested) system call). --- src/qcommon/vm_x86.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/qcommon/vm_x86.c b/src/qcommon/vm_x86.c index b6fc6a63..2056785d 100644 --- a/src/qcommon/vm_x86.c +++ b/src/qcommon/vm_x86.c @@ -413,23 +413,24 @@ static void DoSyscall(void) if(vm_syscallNum < 0) { - int *data; + int *data, *ret; #if idx64 int index; intptr_t args[MAX_VMSYSCALL_ARGS]; #endif data = (int *) (savedVM->dataBase + vm_programStack + 4); + ret = &vm_opStackBase[vm_opStackOfs + 1]; #if idx64 args[0] = ~vm_syscallNum; for(index = 1; index < ARRAY_LEN(args); index++) args[index] = data[index]; - vm_opStackBase[vm_opStackOfs + 1] = savedVM->systemCall(args); + *ret = savedVM->systemCall(args); #else data[0] = ~vm_syscallNum; - vm_opStackBase[vm_opStackOfs + 1] = savedVM->systemCall((intptr_t *) data); + *ret = savedVM->systemCall((intptr_t *) data); #endif } else -- cgit