summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZack Middleton <zturtleman@gmail.com>2012-12-15 21:55:07 +0000
committerTim Angus <tim@ngus.net>2013-01-12 21:26:42 +0000
commit91ae99ca4e1de95b54d9d3756f1c85a0abad4576 (patch)
tree820e37bf8e5ab37dffb48288aad96c77b11cb90a
parentaf4982fd82a5de4ae80557460ea7e2f17e7cbda9 (diff)
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.
-rw-r--r--src/qcommon/vm.c8
-rw-r--r--src/qcommon/vm_interpreted.c24
-rw-r--r--src/qcommon/vm_local.h8
-rw-r--r--src/qcommon/vm_powerpc.c8
-rw-r--r--src/qcommon/vm_sparc.c8
-rw-r--r--src/qcommon/vm_x86.c22
-rw-r--r--src/qcommon/vm_x86_64.c24
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" );
}