From 91ae99ca4e1de95b54d9d3756f1c85a0abad4576 Mon Sep 17 00:00:00 2001 From: Zack Middleton Date: Sat, 15 Dec 2012 21:55:07 +0000 Subject: Fix passing arg9 (qvm only), arg10, and arg11 to vmMain for native libs and non-i386 compiled or interpated qvms. (Currently they aren't use in vmMain in game, cgame, or ui.) Fix passing args[11] to args[15] from vm to engine on ppc64 and sparc64. Some of the args are used by game bot prediction syscalls. May have been causing bugs. Note: This was fixed for x86_64 in r2163. --- src/qcommon/vm.c | 8 ++++---- src/qcommon/vm_interpreted.c | 24 +++++++++--------------- src/qcommon/vm_local.h | 8 ++++++++ src/qcommon/vm_powerpc.c | 8 ++++---- src/qcommon/vm_sparc.c | 8 ++++---- src/qcommon/vm_x86.c | 22 ++++++++-------------- src/qcommon/vm_x86_64.c | 24 +++++++++--------------- 7 files changed, 46 insertions(+), 56 deletions(-) diff --git a/src/qcommon/vm.c b/src/qcommon/vm.c index 8d959038..c1384972 100644 --- a/src/qcommon/vm.c +++ b/src/qcommon/vm.c @@ -339,7 +339,7 @@ Dlls will call this directly intptr_t QDECL VM_DllSyscall( intptr_t arg, ... ) { #if !id386 || defined __clang__ // rcg010206 - see commentary above - intptr_t args[16]; + intptr_t args[MAX_VMSYSCALL_ARGS]; int i; va_list ap; @@ -824,7 +824,7 @@ intptr_t QDECL VM_Call( vm_t *vm, int callnum, ... ) // if we have a dll loaded, call it directly if ( vm->entryPoint ) { //rcg010207 - see dissertation at top of VM_DllSyscall() in this file. - int args[10]; + int args[MAX_VMMAIN_ARGS-1]; va_list ap; va_start(ap, callnum); for (i = 0; i < ARRAY_LEN(args); i++) { @@ -834,7 +834,7 @@ intptr_t QDECL VM_Call( vm_t *vm, int callnum, ... ) r = vm->entryPoint( callnum, args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7], - args[8], args[9]); + args[8], args[9], args[10], args[11]); } else { #if ( id386 || idsparc ) && !defined __clang__ // calling convention doesn't need conversion in some cases #ifndef NO_VM_COMPILED @@ -846,7 +846,7 @@ intptr_t QDECL VM_Call( vm_t *vm, int callnum, ... ) #else struct { int callnum; - int args[10]; + int args[MAX_VMMAIN_ARGS-1]; } a; va_list ap; diff --git a/src/qcommon/vm_interpreted.c b/src/qcommon/vm_interpreted.c index cd126ef4..91a6d53d 100644 --- a/src/qcommon/vm_interpreted.c +++ b/src/qcommon/vm_interpreted.c @@ -327,6 +327,7 @@ int VM_CallInterpreted( vm_t *vm, int *args ) { int *codeImage; int v1; int dataMask; + int arg; #ifdef DEBUG_VM vmSymbol_t *profileSymbol; #endif @@ -350,18 +351,11 @@ int VM_CallInterpreted( vm_t *vm, int *args ) { programCounter = 0; - programStack -= 48; - - *(int *)&image[ programStack + 44] = args[9]; - *(int *)&image[ programStack + 40] = args[8]; - *(int *)&image[ programStack + 36] = args[7]; - *(int *)&image[ programStack + 32] = args[6]; - *(int *)&image[ programStack + 28] = args[5]; - *(int *)&image[ programStack + 24] = args[4]; - *(int *)&image[ programStack + 20] = args[3]; - *(int *)&image[ programStack + 16] = args[2]; - *(int *)&image[ programStack + 12] = args[1]; - *(int *)&image[ programStack + 8 ] = args[0]; + programStack -= ( 8 + 4 * MAX_VMMAIN_ARGS ); + + for ( arg = 0; arg < MAX_VMMAIN_ARGS; arg++ ) + *(int *)&image[ programStack + 8 + arg * 4 ] = args[ arg ]; + *(int *)&image[ programStack + 4 ] = 0; // return stack *(int *)&image[ programStack ] = -1; // will terminate the loop on return @@ -509,10 +503,10 @@ nextInstruction2: // the vm has ints on the stack, we expect // pointers so we might have to convert it if (sizeof(intptr_t) != sizeof(int)) { - intptr_t argarr[16]; - int *imagePtr = (int *)&image[programStack]; + intptr_t argarr[ MAX_VMSYSCALL_ARGS ]; + int *imagePtr = (int *)&image[ programStack ]; int i; - for (i = 0; i < 16; ++i) { + for (i = 0; i < ARRAY_LEN(argarr); ++i) { argarr[i] = *(++imagePtr); } r = vm->systemCall( argarr ); diff --git a/src/qcommon/vm_local.h b/src/qcommon/vm_local.h index 7560832c..5e00c0de 100644 --- a/src/qcommon/vm_local.h +++ b/src/qcommon/vm_local.h @@ -23,6 +23,14 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #include "q_shared.h" #include "qcommon.h" +// Max number of arguments to pass from engine to vm's vmMain function. +// command number + 12 arguments +#define MAX_VMMAIN_ARGS 13 + +// Max number of arguments to pass from a vm to engine's syscall handler function for the vm. +// syscall number + 15 arguments +#define MAX_VMSYSCALL_ARGS 16 + // don't change, this is hardcoded into x86 VMs, opStack protection relies // on this #define OPSTACK_SIZE 1024 diff --git a/src/qcommon/vm_powerpc.c b/src/qcommon/vm_powerpc.c index 604d844e..4bc3354e 100644 --- a/src/qcommon/vm_powerpc.c +++ b/src/qcommon/vm_powerpc.c @@ -367,13 +367,13 @@ VM_AsmCall( int callSyscallInvNum, int callProgramStack ) ret = currentVM->systemCall( argPosition ); } else { - intptr_t args[11]; + intptr_t args[MAX_VMSYSCALL_ARGS]; // generated code does not invert syscall number args[0] = -1 - callSyscallInvNum; int *argPosition = (int *)((byte *)currentVM->dataBase + callProgramStack + 4); - for( i = 1; i < 11; i++ ) + for( i = 1; i < ARRAY_LEN(args); i++ ) args[ i ] = argPosition[ i ]; ret = currentVM->systemCall( args ); @@ -2105,9 +2105,9 @@ VM_CallCompiled( vm_t *vm, int *args ) vm->currentlyInterpreting = qtrue; - programStack -= 48; + programStack -= ( 8 + 4 * MAX_VMMAIN_ARGS ); argPointer = (int *)&image[ programStack + 8 ]; - memcpy( argPointer, args, 4 * 9 ); + memcpy( argPointer, args, 4 * MAX_VMMAIN_ARGS ); argPointer[ -1 ] = 0; argPointer[ -2 ] = -1; diff --git a/src/qcommon/vm_sparc.c b/src/qcommon/vm_sparc.c index 1e8514b6..6d247179 100644 --- a/src/qcommon/vm_sparc.c +++ b/src/qcommon/vm_sparc.c @@ -808,11 +808,11 @@ static int asmcall(int call, int pstack) argPosition[0] = -1 - call; ret = currentVM->systemCall(argPosition); } else { - intptr_t args[11]; + intptr_t args[MAX_VMSYSCALL_ARGS]; args[0] = -1 - call; int *argPosition = (int *)((byte *)currentVM->dataBase + pstack + 4); - for( i = 1; i < 11; i++ ) + for( i = 1; i < ARRAY_LEN(args); i++ ) args[i] = argPosition[i]; ret = currentVM->systemCall(args); @@ -1650,9 +1650,9 @@ int VM_CallCompiled(vm_t *vm, int *args) vm->currentlyInterpreting = qtrue; - programStack -= 48; + programStack -= ( 8 + 4 * MAX_VMMAIN_ARGS ); argPointer = (int *)&image[ programStack + 8 ]; - memcpy( argPointer, args, 4 * 9 ); + memcpy( argPointer, args, 4 * MAX_VMMAIN_ARGS ); argPointer[-1] = 0; argPointer[-2] = -1; diff --git a/src/qcommon/vm_x86.c b/src/qcommon/vm_x86.c index 80b6e31b..a6bb0821 100644 --- a/src/qcommon/vm_x86.c +++ b/src/qcommon/vm_x86.c @@ -417,7 +417,7 @@ static void DoSyscall(void) int *data; #if idx64 int index; - intptr_t args[16]; + intptr_t args[MAX_VMSYSCALL_ARGS]; #endif data = (int *) (savedVM->dataBase + vm_programStack + 4); @@ -1715,6 +1715,7 @@ int VM_CallCompiled(vm_t *vm, int *args) byte *image; int *opStack; int opStackOfs; + int arg; currentVM = vm; @@ -1727,18 +1728,11 @@ int VM_CallCompiled(vm_t *vm, int *args) // set up the stack frame image = vm->dataBase; - programStack -= 48; - - *(int *)&image[ programStack + 44] = args[9]; - *(int *)&image[ programStack + 40] = args[8]; - *(int *)&image[ programStack + 36] = args[7]; - *(int *)&image[ programStack + 32] = args[6]; - *(int *)&image[ programStack + 28] = args[5]; - *(int *)&image[ programStack + 24] = args[4]; - *(int *)&image[ programStack + 20] = args[3]; - *(int *)&image[ programStack + 16] = args[2]; - *(int *)&image[ programStack + 12] = args[1]; - *(int *)&image[ programStack + 8 ] = args[0]; + programStack -= ( 8 + 4 * MAX_VMMAIN_ARGS ); + + for ( arg = 0; arg < MAX_VMMAIN_ARGS; arg++ ) + *(int *)&image[ programStack + 8 + arg * 4 ] = args[ arg ]; + *(int *)&image[ programStack + 4 ] = 0; // return stack *(int *)&image[ programStack ] = -1; // will terminate the loop on return @@ -1800,7 +1794,7 @@ int VM_CallCompiled(vm_t *vm, int *args) { Com_Error(ERR_DROP, "opStack corrupted in compiled code"); } - if(programStack != stackOnEntry - 48) + if(programStack != stackOnEntry - (8 + 4 * MAX_VMMAIN_ARGS)) Com_Error(ERR_DROP, "programStack corrupted in compiled code"); vm->programStack = stackOnEntry; diff --git a/src/qcommon/vm_x86_64.c b/src/qcommon/vm_x86_64.c index f2ede423..df39db44 100644 --- a/src/qcommon/vm_x86_64.c +++ b/src/qcommon/vm_x86_64.c @@ -87,8 +87,8 @@ static intptr_t CROSSCALL callAsmCall(intptr_t callProgramStack, int64_t callSys { vm_t *savedVM; intptr_t ret = 0x77; - intptr_t args[16]; -// int iargs[16]; + intptr_t args[MAX_VMSYSCALL_ARGS]; +// int iargs[MAX_VMSYSCALL_ARGS]; int i; // Dfprintf(stderr, "callAsmCall(%ld, %ld)\n", callProgramStack, callSyscallNum); @@ -1025,6 +1025,7 @@ int VM_CallCompiled(vm_t *vm, int *args) byte *image; void *entryPoint; int *opStack; + int arg; currentVM = vm; @@ -1047,18 +1048,11 @@ int VM_CallCompiled(vm_t *vm, int *args) programCounter = 0; - programStack -= 48; - - *(int *)&image[ programStack + 44] = args[9]; - *(int *)&image[ programStack + 40] = args[8]; - *(int *)&image[ programStack + 36] = args[7]; - *(int *)&image[ programStack + 32] = args[6]; - *(int *)&image[ programStack + 28] = args[5]; - *(int *)&image[ programStack + 24] = args[4]; - *(int *)&image[ programStack + 20] = args[3]; - *(int *)&image[ programStack + 16] = args[2]; - *(int *)&image[ programStack + 12] = args[1]; - *(int *)&image[ programStack + 8 ] = args[0]; + programStack -= ( 8 + 4 * MAX_VMMAIN_ARGS ); + + for ( arg = 0; arg < MAX_VMMAIN_ARGS; arg++ ) + *(int *)&image[ programStack + 8 + arg * 4 ] = args[ arg ]; + *(int *)&image[ programStack + 4 ] = 0x77777777; // return stack *(int *)&image[ programStack ] = -1; // will terminate the loop on return @@ -1092,7 +1086,7 @@ int VM_CallCompiled(vm_t *vm, int *args) if(opStackRet != 1 || *opStack != 0xDEADBEEF) Com_Error(ERR_DROP, "opStack corrupted in compiled code (offset %ld)", opStackRet); - if ( programStack != stackOnEntry - 48 ) { + if ( programStack != stackOnEntry - ( 8 + 4 * MAX_VMMAIN_ARGS ) ) { Com_Error( ERR_DROP, "programStack corrupted in compiled code" ); } -- cgit