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).
This commit is contained in:
/dev/humancontroller 2015-03-23 20:16:11 -05:00 committed by Zack Middleton
parent 33efe82de9
commit 1ce8ba0cdb

View file

@ -412,23 +412,24 @@ static void DoSyscall(void)
if(vm_syscallNum < 0) if(vm_syscallNum < 0)
{ {
int *data; int *data, *ret;
#if idx64 #if idx64
int index; int index;
intptr_t args[MAX_VMSYSCALL_ARGS]; intptr_t args[MAX_VMSYSCALL_ARGS];
#endif #endif
data = (int *) (savedVM->dataBase + vm_programStack + 4); data = (int *) (savedVM->dataBase + vm_programStack + 4);
ret = &vm_opStackBase[vm_opStackOfs + 1];
#if idx64 #if idx64
args[0] = ~vm_syscallNum; args[0] = ~vm_syscallNum;
for(index = 1; index < ARRAY_LEN(args); index++) for(index = 1; index < ARRAY_LEN(args); index++)
args[index] = data[index]; args[index] = data[index];
vm_opStackBase[vm_opStackOfs + 1] = savedVM->systemCall(args); *ret = savedVM->systemCall(args);
#else #else
data[0] = ~vm_syscallNum; data[0] = ~vm_syscallNum;
vm_opStackBase[vm_opStackOfs + 1] = savedVM->systemCall((intptr_t *) data); *ret = savedVM->systemCall((intptr_t *) data);
#endif #endif
} }
else else