I have been testing a patch from Zack Middleton since last week. He
replied to my bug report.

https://bugzilla.icculus.org/show_bug.cgi?id=4893

Unfortunately the server still crashes from time to time. I'm attaching
the patch and the debdiff against the actual version in unstable,
perhaps someone else is able to complete it.



Index: code/qcommon/vm_local.h
===================================================================
--- code/qcommon/vm_local.h	(revision 2287)
+++ code/qcommon/vm_local.h	(working copy)
@@ -22,6 +22,14 @@
 #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
Index: code/qcommon/vm_sparc.c
===================================================================
--- code/qcommon/vm_sparc.c	(revision 2287)
+++ code/qcommon/vm_sparc.c	(working copy)
@@ -808,11 +808,11 @@
 		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 @@
 
 	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;
 
Index: code/qcommon/vm_x86.c
===================================================================
--- code/qcommon/vm_x86.c	(revision 2287)
+++ code/qcommon/vm_x86.c	(working copy)
@@ -443,7 +443,7 @@
 		int *data;
 #if idx64
 		int index;
-		intptr_t args[16];
+		intptr_t args[MAX_VMSYSCALL_ARGS];
 #endif
 		
 		data = (int *) (savedVM->dataBase + programStack + 4);
@@ -1721,6 +1721,7 @@
 	byte	*image;
 	int	*opStack;
 	int		opStackOfs;
+	int		arg;
 
 	currentVM = vm;
 
@@ -1733,18 +1734,11 @@
 	// set up the stack frame 
 	image = vm->dataBase;
 
-	programStack -= 48;
+	programStack -= ( 8 + 4 * MAX_VMMAIN_ARGS );
 
-	*(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];
+	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
 
@@ -1806,7 +1800,7 @@
 	{
 		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;
Index: code/qcommon/vm_x86_64.c
===================================================================
--- code/qcommon/vm_x86_64.c	(revision 2287)
+++ code/qcommon/vm_x86_64.c	(working copy)
@@ -86,8 +86,8 @@
 {
 	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);
@@ -1024,6 +1024,7 @@
 	byte	*image;
 	void	*entryPoint;
 	int	*opStack;
+	int		arg;
 
 	currentVM = vm;
 	
@@ -1046,18 +1047,11 @@
 
 	programCounter = 0;
 
-	programStack -= 48;
+	programStack -= ( 8 + 4 * MAX_VMMAIN_ARGS );
 
-	*(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];
+	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
 
@@ -1091,7 +1085,7 @@
 	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" );
 	}
 
Index: code/qcommon/vm_powerpc.c
===================================================================
--- code/qcommon/vm_powerpc.c	(revision 2287)
+++ code/qcommon/vm_powerpc.c	(working copy)
@@ -367,13 +367,13 @@
 
 		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->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;
 
Index: code/qcommon/vm.c
===================================================================
--- code/qcommon/vm.c	(revision 2287)
+++ code/qcommon/vm.c	(working copy)
@@ -338,7 +338,7 @@
 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;
   
@@ -823,7 +823,7 @@
 	// 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++) {
@@ -833,7 +833,7 @@
 
 		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
@@ -845,7 +845,7 @@
 #else
 		struct {
 			int callnum;
-			int args[10];
+			int args[MAX_VMMAIN_ARGS-1];
 		} a;
 		va_list ap;
 
Index: code/qcommon/vm_interpreted.c
===================================================================
--- code/qcommon/vm_interpreted.c	(revision 2287)
+++ code/qcommon/vm_interpreted.c	(working copy)
@@ -326,6 +326,7 @@
 	int		*codeImage;
 	int		v1;
 	int		dataMask;
+	int		arg;
 #ifdef DEBUG_VM
 	vmSymbol_t	*profileSymbol;
 #endif
@@ -349,18 +350,11 @@
 	
 	programCounter = 0;
 
-	programStack -= 48;
+	programStack -= ( 8 + 4 * MAX_VMMAIN_ARGS );
 
-	*(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];
+	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
 
@@ -508,10 +502,10 @@
 					// 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 -Nru ioquake3-1.36+svn2287/debian/changelog 
ioquake3-1.36+svn2287/debian/changelog
--- ioquake3-1.36+svn2287/debian/changelog      2012-06-23 01:06:28.000000000 
+0200
+++ ioquake3-1.36+svn2287/debian/changelog      2013-02-12 13:01:47.000000000 
+0100
@@ -1,3 +1,12 @@
+ioquake3 (1.36+svn2287-1.1) unstable; urgency=low
+
+  * Non-maintainer upload.
+  * Fix random ioquake3-server crashes if only bots or bots and human players
+    play on the server by applying 0010-Fix-AAS_PredicRoute-segfaults.patch.
+    (Closes: #664637)
+
+ -- Markus Koschany <a...@gambaru.de>  Tue, 12 Feb 2013 18:48:32 +0100
+
 ioquake3 (1.36+svn2287-1) unstable; urgency=low
 
   * New upstream snapshot
diff -Nru 
ioquake3-1.36+svn2287/debian/patches/0010-Fix-AAS_PredictRoute-segfaults.patch 
ioquake3-1.36+svn2287/debian/patches/0010-Fix-AAS_PredictRoute-segfaults.patch
--- 
ioquake3-1.36+svn2287/debian/patches/0010-Fix-AAS_PredictRoute-segfaults.patch  
    1970-01-01 01:00:00.000000000 +0100
+++ 
ioquake3-1.36+svn2287/debian/patches/0010-Fix-AAS_PredictRoute-segfaults.patch  
    2013-02-12 12:31:45.000000000 +0100
@@ -0,0 +1,295 @@
+From: Zack Middleton <zturtle...@gmail.com>
+Date: Tue, 12 Feb 2013 18:31:25 +0100
+Subject: Fix AAS_PredictRoute segfaults
+
+---
+ code/qcommon/vm.c             |    8 ++++----
+ code/qcommon/vm_interpreted.c |   24 +++++++++---------------
+ code/qcommon/vm_local.h       |    8 ++++++++
+ code/qcommon/vm_powerpc.c     |    8 ++++----
+ code/qcommon/vm_sparc.c       |    8 ++++----
+ code/qcommon/vm_x86.c         |   22 ++++++++--------------
+ code/qcommon/vm_x86_64.c      |   24 +++++++++---------------
+ 7 files changed, 46 insertions(+), 56 deletions(-)
+
+diff --git a/code/qcommon/vm.c b/code/qcommon/vm.c
+index b471c27..f1fc425 100644
+--- a/code/qcommon/vm.c
++++ b/code/qcommon/vm.c
+@@ -338,7 +338,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;
+   
+@@ -878,7 +878,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++) {
+@@ -888,7 +888,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
+@@ -900,7 +900,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/code/qcommon/vm_interpreted.c b/code/qcommon/vm_interpreted.c
+index 5eed5ed..aa45fde 100644
+--- a/code/qcommon/vm_interpreted.c
++++ b/code/qcommon/vm_interpreted.c
+@@ -326,6 +326,7 @@ int        VM_CallInterpreted( vm_t *vm, int *args ) {
+       int             *codeImage;
+       int             v1;
+       int             dataMask;
++      int             arg;
+ #ifdef DEBUG_VM
+       vmSymbol_t      *profileSymbol;
+ #endif
+@@ -349,18 +350,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
+ 
+@@ -508,10 +502,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/code/qcommon/vm_local.h b/code/qcommon/vm_local.h
+index 2c7d6f7..76b1a4b 100644
+--- a/code/qcommon/vm_local.h
++++ b/code/qcommon/vm_local.h
+@@ -22,6 +22,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/code/qcommon/vm_powerpc.c b/code/qcommon/vm_powerpc.c
+index eb66c5a..6ab2332 100644
+--- a/code/qcommon/vm_powerpc.c
++++ b/code/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/code/qcommon/vm_sparc.c b/code/qcommon/vm_sparc.c
+index 5756dc1..578294d 100644
+--- a/code/qcommon/vm_sparc.c
++++ b/code/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/code/qcommon/vm_x86.c b/code/qcommon/vm_x86.c
+index d19763e..b506c87 100644
+--- a/code/qcommon/vm_x86.c
++++ b/code/qcommon/vm_x86.c
+@@ -443,7 +443,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 + programStack + 4);
+@@ -1721,6 +1721,7 @@ int VM_CallCompiled(vm_t *vm, int *args)
+       byte    *image;
+       int     *opStack;
+       int             opStackOfs;
++      int             arg;
+ 
+       currentVM = vm;
+ 
+@@ -1733,18 +1734,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
+ 
+@@ -1806,7 +1800,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/code/qcommon/vm_x86_64.c b/code/qcommon/vm_x86_64.c
+index c140079..e91bf0e 100644
+--- a/code/qcommon/vm_x86_64.c
++++ b/code/qcommon/vm_x86_64.c
+@@ -86,8 +86,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);
+@@ -1024,6 +1024,7 @@ int VM_CallCompiled(vm_t *vm, int *args)
+       byte    *image;
+       void    *entryPoint;
+       int     *opStack;
++      int             arg;
+ 
+       currentVM = vm;
+       
+@@ -1046,18 +1047,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
+ 
+@@ -1091,7 +1085,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" 
);
+       }
+ 
diff -Nru ioquake3-1.36+svn2287/debian/patches/series 
ioquake3-1.36+svn2287/debian/patches/series
--- ioquake3-1.36+svn2287/debian/patches/series 2012-06-23 01:06:28.000000000 
+0200
+++ ioquake3-1.36+svn2287/debian/patches/series 2013-02-12 12:31:45.000000000 
+0100
@@ -7,3 +7,4 @@
 0007-Let-servers-set-sv_fps-too.patch
 0008-Only-emit-i486-instructions-on-x86-but-optimize-for-.patch
 0009-Run-in-a-window-by-default-on-new-installations.patch
+0010-Fix-AAS_PredictRoute-segfaults.patch

Attachment: signature.asc
Description: OpenPGP digital signature

Reply via email to