mirror of
https://github.com/DrBeef/ioq3quest.git
synced 2024-11-23 12:32:09 +00:00
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.
This commit is contained in:
parent
b943d506bf
commit
c5af65fe5f
7 changed files with 43 additions and 53 deletions
|
@ -338,7 +338,7 @@ Dlls will call this directly
|
||||||
intptr_t QDECL VM_DllSyscall( intptr_t arg, ... ) {
|
intptr_t QDECL VM_DllSyscall( intptr_t arg, ... ) {
|
||||||
#if !id386 || defined __clang__
|
#if !id386 || defined __clang__
|
||||||
// rcg010206 - see commentary above
|
// rcg010206 - see commentary above
|
||||||
intptr_t args[16];
|
intptr_t args[MAX_VMSYSCALL_ARGS];
|
||||||
int i;
|
int i;
|
||||||
va_list ap;
|
va_list ap;
|
||||||
|
|
||||||
|
@ -823,7 +823,7 @@ intptr_t QDECL VM_Call( vm_t *vm, int callnum, ... )
|
||||||
// if we have a dll loaded, call it directly
|
// if we have a dll loaded, call it directly
|
||||||
if ( vm->entryPoint ) {
|
if ( vm->entryPoint ) {
|
||||||
//rcg010207 - see dissertation at top of VM_DllSyscall() in this file.
|
//rcg010207 - see dissertation at top of VM_DllSyscall() in this file.
|
||||||
int args[10];
|
int args[MAX_VMMAIN_ARGS-1];
|
||||||
va_list ap;
|
va_list ap;
|
||||||
va_start(ap, callnum);
|
va_start(ap, callnum);
|
||||||
for (i = 0; i < ARRAY_LEN(args); i++) {
|
for (i = 0; i < ARRAY_LEN(args); i++) {
|
||||||
|
@ -833,7 +833,7 @@ intptr_t QDECL VM_Call( vm_t *vm, int callnum, ... )
|
||||||
|
|
||||||
r = vm->entryPoint( callnum, args[0], args[1], args[2], args[3],
|
r = vm->entryPoint( callnum, args[0], args[1], args[2], args[3],
|
||||||
args[4], args[5], args[6], args[7],
|
args[4], args[5], args[6], args[7],
|
||||||
args[8], args[9]);
|
args[8], args[9], args[10], args[11]);
|
||||||
} else {
|
} else {
|
||||||
#if ( id386 || idsparc ) && !defined __clang__ // calling convention doesn't need conversion in some cases
|
#if ( id386 || idsparc ) && !defined __clang__ // calling convention doesn't need conversion in some cases
|
||||||
#ifndef NO_VM_COMPILED
|
#ifndef NO_VM_COMPILED
|
||||||
|
@ -845,7 +845,7 @@ intptr_t QDECL VM_Call( vm_t *vm, int callnum, ... )
|
||||||
#else
|
#else
|
||||||
struct {
|
struct {
|
||||||
int callnum;
|
int callnum;
|
||||||
int args[10];
|
int args[MAX_VMMAIN_ARGS-1];
|
||||||
} a;
|
} a;
|
||||||
va_list ap;
|
va_list ap;
|
||||||
|
|
||||||
|
|
|
@ -326,6 +326,7 @@ int VM_CallInterpreted( vm_t *vm, int *args ) {
|
||||||
int *codeImage;
|
int *codeImage;
|
||||||
int v1;
|
int v1;
|
||||||
int dataMask;
|
int dataMask;
|
||||||
|
int arg;
|
||||||
#ifdef DEBUG_VM
|
#ifdef DEBUG_VM
|
||||||
vmSymbol_t *profileSymbol;
|
vmSymbol_t *profileSymbol;
|
||||||
#endif
|
#endif
|
||||||
|
@ -349,18 +350,11 @@ int VM_CallInterpreted( vm_t *vm, int *args ) {
|
||||||
|
|
||||||
programCounter = 0;
|
programCounter = 0;
|
||||||
|
|
||||||
programStack -= 48;
|
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 + 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];
|
|
||||||
*(int *)&image[ programStack + 4 ] = 0; // return stack
|
*(int *)&image[ programStack + 4 ] = 0; // return stack
|
||||||
*(int *)&image[ programStack ] = -1; // will terminate the loop on return
|
*(int *)&image[ programStack ] = -1; // will terminate the loop on return
|
||||||
|
|
||||||
|
@ -508,10 +502,10 @@ nextInstruction2:
|
||||||
// the vm has ints on the stack, we expect
|
// the vm has ints on the stack, we expect
|
||||||
// pointers so we might have to convert it
|
// pointers so we might have to convert it
|
||||||
if (sizeof(intptr_t) != sizeof(int)) {
|
if (sizeof(intptr_t) != sizeof(int)) {
|
||||||
intptr_t argarr[16];
|
intptr_t argarr[ MAX_VMSYSCALL_ARGS ];
|
||||||
int *imagePtr = (int *)&image[programStack];
|
int *imagePtr = (int *)&image[ programStack ];
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < 16; ++i) {
|
for (i = 0; i < ARRAY_LEN(argarr); ++i) {
|
||||||
argarr[i] = *(++imagePtr);
|
argarr[i] = *(++imagePtr);
|
||||||
}
|
}
|
||||||
r = vm->systemCall( argarr );
|
r = vm->systemCall( argarr );
|
||||||
|
|
|
@ -22,6 +22,14 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
#include "q_shared.h"
|
#include "q_shared.h"
|
||||||
#include "qcommon.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
|
// don't change, this is hardcoded into x86 VMs, opStack protection relies
|
||||||
// on this
|
// on this
|
||||||
#define OPSTACK_SIZE 1024
|
#define OPSTACK_SIZE 1024
|
||||||
|
|
|
@ -367,13 +367,13 @@ VM_AsmCall( int callSyscallInvNum, int callProgramStack )
|
||||||
|
|
||||||
ret = currentVM->systemCall( argPosition );
|
ret = currentVM->systemCall( argPosition );
|
||||||
} else {
|
} else {
|
||||||
intptr_t args[11];
|
intptr_t args[MAX_VMSYSCALL_ARGS];
|
||||||
|
|
||||||
// generated code does not invert syscall number
|
// generated code does not invert syscall number
|
||||||
args[0] = -1 - callSyscallInvNum;
|
args[0] = -1 - callSyscallInvNum;
|
||||||
|
|
||||||
int *argPosition = (int *)((byte *)currentVM->dataBase + callProgramStack + 4);
|
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 ];
|
args[ i ] = argPosition[ i ];
|
||||||
|
|
||||||
ret = currentVM->systemCall( args );
|
ret = currentVM->systemCall( args );
|
||||||
|
@ -2105,9 +2105,9 @@ VM_CallCompiled( vm_t *vm, int *args )
|
||||||
|
|
||||||
vm->currentlyInterpreting = qtrue;
|
vm->currentlyInterpreting = qtrue;
|
||||||
|
|
||||||
programStack -= 48;
|
programStack -= ( 8 + 4 * MAX_VMMAIN_ARGS );
|
||||||
argPointer = (int *)&image[ programStack + 8 ];
|
argPointer = (int *)&image[ programStack + 8 ];
|
||||||
memcpy( argPointer, args, 4 * 9 );
|
memcpy( argPointer, args, 4 * MAX_VMMAIN_ARGS );
|
||||||
argPointer[ -1 ] = 0;
|
argPointer[ -1 ] = 0;
|
||||||
argPointer[ -2 ] = -1;
|
argPointer[ -2 ] = -1;
|
||||||
|
|
||||||
|
|
|
@ -808,11 +808,11 @@ static int asmcall(int call, int pstack)
|
||||||
argPosition[0] = -1 - call;
|
argPosition[0] = -1 - call;
|
||||||
ret = currentVM->systemCall(argPosition);
|
ret = currentVM->systemCall(argPosition);
|
||||||
} else {
|
} else {
|
||||||
intptr_t args[11];
|
intptr_t args[MAX_VMSYSCALL_ARGS];
|
||||||
|
|
||||||
args[0] = -1 - call;
|
args[0] = -1 - call;
|
||||||
int *argPosition = (int *)((byte *)currentVM->dataBase + pstack + 4);
|
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];
|
args[i] = argPosition[i];
|
||||||
|
|
||||||
ret = currentVM->systemCall(args);
|
ret = currentVM->systemCall(args);
|
||||||
|
@ -1650,9 +1650,9 @@ int VM_CallCompiled(vm_t *vm, int *args)
|
||||||
|
|
||||||
vm->currentlyInterpreting = qtrue;
|
vm->currentlyInterpreting = qtrue;
|
||||||
|
|
||||||
programStack -= 48;
|
programStack -= ( 8 + 4 * MAX_VMMAIN_ARGS );
|
||||||
argPointer = (int *)&image[ programStack + 8 ];
|
argPointer = (int *)&image[ programStack + 8 ];
|
||||||
memcpy( argPointer, args, 4 * 9 );
|
memcpy( argPointer, args, 4 * MAX_VMMAIN_ARGS );
|
||||||
argPointer[-1] = 0;
|
argPointer[-1] = 0;
|
||||||
argPointer[-2] = -1;
|
argPointer[-2] = -1;
|
||||||
|
|
||||||
|
|
|
@ -416,7 +416,7 @@ static void DoSyscall(void)
|
||||||
int *data;
|
int *data;
|
||||||
#if idx64
|
#if idx64
|
||||||
int index;
|
int index;
|
||||||
intptr_t args[16];
|
intptr_t args[MAX_VMSYSCALL_ARGS];
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
data = (int *) (savedVM->dataBase + vm_programStack + 4);
|
data = (int *) (savedVM->dataBase + vm_programStack + 4);
|
||||||
|
@ -1714,6 +1714,7 @@ int VM_CallCompiled(vm_t *vm, int *args)
|
||||||
byte *image;
|
byte *image;
|
||||||
int *opStack;
|
int *opStack;
|
||||||
int opStackOfs;
|
int opStackOfs;
|
||||||
|
int arg;
|
||||||
|
|
||||||
currentVM = vm;
|
currentVM = vm;
|
||||||
|
|
||||||
|
@ -1726,18 +1727,11 @@ int VM_CallCompiled(vm_t *vm, int *args)
|
||||||
// set up the stack frame
|
// set up the stack frame
|
||||||
image = vm->dataBase;
|
image = vm->dataBase;
|
||||||
|
|
||||||
programStack -= 48;
|
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 + 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];
|
|
||||||
*(int *)&image[ programStack + 4 ] = 0; // return stack
|
*(int *)&image[ programStack + 4 ] = 0; // return stack
|
||||||
*(int *)&image[ programStack ] = -1; // will terminate the loop on return
|
*(int *)&image[ programStack ] = -1; // will terminate the loop on return
|
||||||
|
|
||||||
|
@ -1799,7 +1793,7 @@ int VM_CallCompiled(vm_t *vm, int *args)
|
||||||
{
|
{
|
||||||
Com_Error(ERR_DROP, "opStack corrupted in compiled code");
|
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");
|
Com_Error(ERR_DROP, "programStack corrupted in compiled code");
|
||||||
|
|
||||||
vm->programStack = stackOnEntry;
|
vm->programStack = stackOnEntry;
|
||||||
|
|
|
@ -86,8 +86,8 @@ static intptr_t CROSSCALL callAsmCall(intptr_t callProgramStack, int64_t callSys
|
||||||
{
|
{
|
||||||
vm_t *savedVM;
|
vm_t *savedVM;
|
||||||
intptr_t ret = 0x77;
|
intptr_t ret = 0x77;
|
||||||
intptr_t args[16];
|
intptr_t args[MAX_VMSYSCALL_ARGS];
|
||||||
// int iargs[16];
|
// int iargs[MAX_VMSYSCALL_ARGS];
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
// Dfprintf(stderr, "callAsmCall(%ld, %ld)\n", callProgramStack, callSyscallNum);
|
// Dfprintf(stderr, "callAsmCall(%ld, %ld)\n", callProgramStack, callSyscallNum);
|
||||||
|
@ -1024,6 +1024,7 @@ int VM_CallCompiled(vm_t *vm, int *args)
|
||||||
byte *image;
|
byte *image;
|
||||||
void *entryPoint;
|
void *entryPoint;
|
||||||
int *opStack;
|
int *opStack;
|
||||||
|
int arg;
|
||||||
|
|
||||||
currentVM = vm;
|
currentVM = vm;
|
||||||
|
|
||||||
|
@ -1046,18 +1047,11 @@ int VM_CallCompiled(vm_t *vm, int *args)
|
||||||
|
|
||||||
programCounter = 0;
|
programCounter = 0;
|
||||||
|
|
||||||
programStack -= 48;
|
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 + 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];
|
|
||||||
*(int *)&image[ programStack + 4 ] = 0x77777777; // return stack
|
*(int *)&image[ programStack + 4 ] = 0x77777777; // return stack
|
||||||
*(int *)&image[ programStack ] = -1; // will terminate the loop on return
|
*(int *)&image[ programStack ] = -1; // will terminate the loop on return
|
||||||
|
|
||||||
|
@ -1091,7 +1085,7 @@ int VM_CallCompiled(vm_t *vm, int *args)
|
||||||
if(opStackRet != 1 || *opStack != 0xDEADBEEF)
|
if(opStackRet != 1 || *opStack != 0xDEADBEEF)
|
||||||
Com_Error(ERR_DROP, "opStack corrupted in compiled code (offset %ld)", opStackRet);
|
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" );
|
Com_Error( ERR_DROP, "programStack corrupted in compiled code" );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue