[quake3-commits] r2031 - trunk/code/qcommon

DONOTREPLY at icculus.org DONOTREPLY at icculus.org
Wed Jun 15 21:11:46 EDT 2011


Author: thilo
Date: 2011-06-15 21:11:45 -0400 (Wed, 15 Jun 2011)
New Revision: 2031

Modified:
   trunk/code/qcommon/vm.c
   trunk/code/qcommon/vm_interpreted.c
   trunk/code/qcommon/vm_local.h
   trunk/code/qcommon/vm_x86.c
   trunk/code/qcommon/vm_x86_64.c
Log:
Various fixes to vm_interpreted.c:
- Add opStack protection
- Fix dataMask check for OP_BLOCK_COPY
- Add instruction number check for conditional jumps
- Make errors in VM_PrepareInterpreter nonfatal


Modified: trunk/code/qcommon/vm.c
===================================================================
--- trunk/code/qcommon/vm.c	2011-06-15 22:25:13 UTC (rev 2030)
+++ trunk/code/qcommon/vm.c	2011-06-16 01:11:45 UTC (rev 2031)
@@ -949,3 +949,25 @@
 	fprintf(f, "%i: %p (%i) = %i %i %i %i\n", callnum, (void*)(args - (int *)currentVM->dataBase),
 		args[0], args[1], args[2], args[3], args[4] );
 }
+
+/*
+=================
+VM_BlockCopy
+Executes a block copy operation within currentVM data space
+=================
+*/
+
+void VM_BlockCopy(unsigned int dest, unsigned int src, size_t n)
+{
+	unsigned int dataMask = currentVM->dataMask;
+
+	if ((dest & dataMask) != dest
+	|| (src & dataMask) != src
+	|| ((dest + n) & dataMask) != dest + n
+	|| ((src + n) & dataMask) != src + n)
+	{
+		Com_Error(ERR_DROP, "OP_BLOCK_COPY out of range!");
+	}
+
+	Com_Memcpy(currentVM->dataBase + dest, currentVM->dataBase + src, n);
+}

Modified: trunk/code/qcommon/vm_interpreted.c
===================================================================
--- trunk/code/qcommon/vm_interpreted.c	2011-06-15 22:25:13 UTC (rev 2030)
+++ trunk/code/qcommon/vm_interpreted.c	2011-06-16 01:11:45 UTC (rev 2031)
@@ -192,9 +192,8 @@
 
 		op = (int)code[ byte_pc ];
 		codeBase[int_pc] = op;
-		if ( byte_pc > header->codeLength ) {
-			Com_Error( ERR_FATAL, "VM_PrepareInterpreter: pc > header->codeLength" );
-		}
+		if(byte_pc > header->codeLength)
+			Com_Error(ERR_DROP, "VM_PrepareInterpreter: pc > header->codeLength");
 
 		byte_pc++;
 		int_pc++;
@@ -265,6 +264,9 @@
 		case OP_LEF:
 		case OP_GTF:
 		case OP_GEF:
+			if(codeBase[int_pc] < 0 || codeBase[int_pc] > vm->instructionCount)
+				Com_Error(ERR_DROP, "VM_PrepareInterpreter: Jump to invalid instruction number");
+
 			// codeBase[pc] is the instruction index. Convert that into an offset into
 			//the int-aligned codeBase[] by the lookup table.
 			codeBase[int_pc] = vm->instructionPointers[codeBase[int_pc]];
@@ -312,11 +314,12 @@
 ==============
 */
 
-#define	DEBUGSTR va("%s%i", VM_Indent(vm), opStack-stack )
+#define	DEBUGSTR va("%s%i", VM_Indent(vm), opStackOfs)
 
 int	VM_CallInterpreted( vm_t *vm, int *args ) {
-	int		stack[OPSTACK_SIZE];
-	int		*opStack;
+	byte		stack[OPSTACK_SIZE + 15];
+	register int		*opStack;
+	register uint8_t 	opStackOfs;
 	int		programCounter;
 	int		programStack;
 	int		stackOnEntry;
@@ -345,10 +348,6 @@
 	codeImage = (int *)vm->codeBase;
 	dataMask = vm->dataMask;
 	
-	// leave a free spot at start of stack so
-	// that as long as opStack is valid, opStack-1 will
-	// not corrupt anything
-	opStack = stack;
 	programCounter = 0;
 
 	programStack -= 48;
@@ -368,6 +367,13 @@
 
 	VM_Debug(0);
 
+	// leave a free spot at start of stack so
+	// that as long as opStack is valid, opStack-1 will
+	// not corrupt anything
+	opStack = PADP(stack, 16);
+	*opStack = 0xDEADBEEF;
+	opStackOfs = 0;
+
 //	vm_debugLevel=2;
 	// main interpreter loop, will exit when a LEAVE instruction
 	// grabs the -1 program counter
@@ -379,27 +385,23 @@
 //		unsigned int	r2;
 
 nextInstruction:
-		r0 = ((int *)opStack)[0];
-		r1 = ((int *)opStack)[-1];
+		r0 = opStack[opStackOfs];
+		r1 = opStack[(uint8_t) (opStackOfs - 1)];
 nextInstruction2:
 #ifdef DEBUG_VM
 		if ( (unsigned)programCounter >= vm->codeLength ) {
 			Com_Error( ERR_DROP, "VM pc out of range" );
+			return 0;
 		}
 
-		if ( opStack < stack ) {
-			Com_Error( ERR_DROP, "VM opStack underflow" );
-		}
-		if ( opStack >= stack+OPSTACK_SIZE ) {
-			Com_Error( ERR_DROP, "VM opStack overflow" );
-		}
-
 		if ( programStack <= vm->stackBottom ) {
 			Com_Error( ERR_DROP, "VM stack overflow" );
+			return 0;
 		}
 
 		if ( programStack & 3 ) {
 			Com_Error( ERR_DROP, "VM program stack misaligned" );
+			return 0;
 		}
 
 		if ( vm_debugLevel > 1 ) {
@@ -413,79 +415,67 @@
 #ifdef DEBUG_VM
 		default:
 			Com_Error( ERR_DROP, "Bad VM instruction" );  // this should be scanned on load!
+			return 0;
 #endif
 		case OP_BREAK:
 			vm->breakCount++;
 			goto nextInstruction2;
 		case OP_CONST:
-			opStack++;
+			opStackOfs++;
 			r1 = r0;
-			r0 = *opStack = r2;
+			r0 = opStack[opStackOfs] = r2;
 			
 			programCounter += 1;
 			goto nextInstruction2;
 		case OP_LOCAL:
-			opStack++;
+			opStackOfs++;
 			r1 = r0;
-			r0 = *opStack = r2+programStack;
+			r0 = opStack[opStackOfs] = r2+programStack;
 
 			programCounter += 1;
 			goto nextInstruction2;
 
 		case OP_LOAD4:
 #ifdef DEBUG_VM
-			if ( *opStack & 3 ) {
+			if(opStack[opStackOfs] & 3)
+			{
 				Com_Error( ERR_DROP, "OP_LOAD4 misaligned" );
+				return 0;
 			}
 #endif
-			r0 = *opStack = *(int *)&image[ r0&dataMask&~3 ];
+			r0 = opStack[opStackOfs] = *(int *) &image[r0 & dataMask & ~3 ];
 			goto nextInstruction2;
 		case OP_LOAD2:
-			r0 = *opStack = *(unsigned short *)&image[ r0&dataMask&~1 ];
+			r0 = opStack[opStackOfs] = *(unsigned short *)&image[ r0&dataMask&~1 ];
 			goto nextInstruction2;
 		case OP_LOAD1:
-			r0 = *opStack = image[ r0&dataMask ];
+			r0 = opStack[opStackOfs] = image[ r0&dataMask ];
 			goto nextInstruction2;
 
 		case OP_STORE4:
 			*(int *)&image[ r1&(dataMask & ~3) ] = r0;
-			opStack -= 2;
+			opStackOfs -= 2;
 			goto nextInstruction;
 		case OP_STORE2:
 			*(short *)&image[ r1&(dataMask & ~1) ] = r0;
-			opStack -= 2;
+			opStackOfs -= 2;
 			goto nextInstruction;
 		case OP_STORE1:
 			image[ r1&dataMask ] = r0;
-			opStack -= 2;
+			opStackOfs -= 2;
 			goto nextInstruction;
 
 		case OP_ARG:
 			// single byte offset from programStack
 			*(int *)&image[ (codeImage[programCounter] + programStack)&dataMask&~3 ] = r0;
-			opStack--;
+			opStackOfs--;
 			programCounter += 1;
 			goto nextInstruction;
 
 		case OP_BLOCK_COPY:
-			{
-				int		*src, *dest;
-				int		count, srci, desti;
-
-				count = r2;
-				// MrE: copy range check
-				srci = r0 & dataMask;
-				desti = r1 & dataMask;
-				count = ((srci + count) & dataMask) - srci;
-				count = ((desti + count) & dataMask) - desti;
-
-				src = (int *)&image[ srci ];
-				dest = (int *)&image[ desti ];
-				
-				memcpy(dest, src, count);
-				programCounter += 1;
-				opStack -= 2;
-			}
+			VM_BlockCopy(r1, r0, r2);
+			programCounter += 1;
+			opStackOfs -= 2;
 			goto nextInstruction;
 
 		case OP_CALL:
@@ -494,7 +484,7 @@
 			
 			// jump to the location on the stack
 			programCounter = r0;
-			opStack--;
+			opStackOfs--;
 			if ( programCounter < 0 ) {
 				// system call
 				int		r;
@@ -539,8 +529,8 @@
 #endif
 
 				// save return value
-				opStack++;
-				*opStack = r;
+				opStackOfs++;
+				opStack[opStackOfs] = r;
 				programCounter = *(int *)&image[ programStack ];
 //				vm->callLevel = temp;
 #ifdef DEBUG_VM
@@ -550,6 +540,7 @@
 #endif
 			} else if ( (unsigned)programCounter >= vm->instructionCount ) {
 				Com_Error( ERR_DROP, "VM program counter out of range in OP_CALL" );
+				return 0;
 			} else {
 				programCounter = vm->instructionPointers[ programCounter ];
 			}
@@ -557,10 +548,10 @@
 
 		// push and pop are only needed for discarded or bad function return values
 		case OP_PUSH:
-			opStack++;
+			opStackOfs++;
 			goto nextInstruction;
 		case OP_POP:
-			opStack--;
+			opStackOfs--;
 			goto nextInstruction;
 
 		case OP_ENTER:
@@ -607,6 +598,7 @@
 				goto done;
 			} else if ( (unsigned)programCounter >= vm->codeLength ) {
 				Com_Error( ERR_DROP, "VM program counter out of range in OP_LEAVE" );
+				return 0;
 			}
 			goto nextInstruction;
 
@@ -618,15 +610,18 @@
 
 		case OP_JUMP:
 			if ( (unsigned)r0 >= vm->instructionCount )
+			{
 				Com_Error( ERR_DROP, "VM program counter out of range in OP_JUMP" );
+				return 0;
+			}
 
 			programCounter = vm->instructionPointers[ r0 ];
 
-			opStack--;
+			opStackOfs--;
 			goto nextInstruction;
 
 		case OP_EQ:
-			opStack -= 2;
+			opStackOfs -= 2;
 			if ( r1 == r0 ) {
 				programCounter = r2;	//vm->instructionPointers[r2];
 				goto nextInstruction;
@@ -636,7 +631,7 @@
 			}
 
 		case OP_NE:
-			opStack -= 2;
+			opStackOfs -= 2;
 			if ( r1 != r0 ) {
 				programCounter = r2;	//vm->instructionPointers[r2];
 				goto nextInstruction;
@@ -646,7 +641,7 @@
 			}
 
 		case OP_LTI:
-			opStack -= 2;
+			opStackOfs -= 2;
 			if ( r1 < r0 ) {
 				programCounter = r2;	//vm->instructionPointers[r2];
 				goto nextInstruction;
@@ -656,7 +651,7 @@
 			}
 
 		case OP_LEI:
-			opStack -= 2;
+			opStackOfs -= 2;
 			if ( r1 <= r0 ) {
 				programCounter = r2;	//vm->instructionPointers[r2];
 				goto nextInstruction;
@@ -666,7 +661,7 @@
 			}
 
 		case OP_GTI:
-			opStack -= 2;
+			opStackOfs -= 2;
 			if ( r1 > r0 ) {
 				programCounter = r2;	//vm->instructionPointers[r2];
 				goto nextInstruction;
@@ -676,7 +671,7 @@
 			}
 
 		case OP_GEI:
-			opStack -= 2;
+			opStackOfs -= 2;
 			if ( r1 >= r0 ) {
 				programCounter = r2;	//vm->instructionPointers[r2];
 				goto nextInstruction;
@@ -686,7 +681,7 @@
 			}
 
 		case OP_LTU:
-			opStack -= 2;
+			opStackOfs -= 2;
 			if ( ((unsigned)r1) < ((unsigned)r0) ) {
 				programCounter = r2;	//vm->instructionPointers[r2];
 				goto nextInstruction;
@@ -696,7 +691,7 @@
 			}
 
 		case OP_LEU:
-			opStack -= 2;
+			opStackOfs -= 2;
 			if ( ((unsigned)r1) <= ((unsigned)r0) ) {
 				programCounter = r2;	//vm->instructionPointers[r2];
 				goto nextInstruction;
@@ -706,7 +701,7 @@
 			}
 
 		case OP_GTU:
-			opStack -= 2;
+			opStackOfs -= 2;
 			if ( ((unsigned)r1) > ((unsigned)r0) ) {
 				programCounter = r2;	//vm->instructionPointers[r2];
 				goto nextInstruction;
@@ -716,7 +711,7 @@
 			}
 
 		case OP_GEU:
-			opStack -= 2;
+			opStackOfs -= 2;
 			if ( ((unsigned)r1) >= ((unsigned)r0) ) {
 				programCounter = r2;	//vm->instructionPointers[r2];
 				goto nextInstruction;
@@ -726,68 +721,74 @@
 			}
 
 		case OP_EQF:
-			if ( ((float *)opStack)[-1] == *(float *)opStack ) {
+			opStackOfs -= 2;
+			
+			if(((float *) opStack)[(uint8_t) (opStackOfs + 1)] == ((float *) opStack)[(uint8_t) (opStackOfs + 2)])
+			{
 				programCounter = r2;	//vm->instructionPointers[r2];
-				opStack -= 2;
 				goto nextInstruction;
 			} else {
 				programCounter += 1;
-				opStack -= 2;
 				goto nextInstruction;
 			}
 
 		case OP_NEF:
-			if ( ((float *)opStack)[-1] != *(float *)opStack ) {
+			opStackOfs -= 2;
+
+			if(((float *) opStack)[(uint8_t) (opStackOfs + 1)] != ((float *) opStack)[(uint8_t) (opStackOfs + 2)])
+			{
 				programCounter = r2;	//vm->instructionPointers[r2];
-				opStack -= 2;
 				goto nextInstruction;
 			} else {
 				programCounter += 1;
-				opStack -= 2;
 				goto nextInstruction;
 			}
 
 		case OP_LTF:
-			if ( ((float *)opStack)[-1] < *(float *)opStack ) {
+			opStackOfs -= 2;
+
+			if(((float *) opStack)[(uint8_t) (opStackOfs + 1)] < ((float *) opStack)[(uint8_t) (opStackOfs + 2)])
+			{
 				programCounter = r2;	//vm->instructionPointers[r2];
-				opStack -= 2;
 				goto nextInstruction;
 			} else {
 				programCounter += 1;
-				opStack -= 2;
 				goto nextInstruction;
 			}
 
 		case OP_LEF:
-			if ( ((float *)opStack)[-1] <= *(float *)opStack ) {
+			opStackOfs -= 2;
+
+			if(((float *) opStack)[(uint8_t) ((uint8_t) (opStackOfs + 1))] <= ((float *) opStack)[(uint8_t) ((uint8_t) (opStackOfs + 2))])
+			{
 				programCounter = r2;	//vm->instructionPointers[r2];
-				opStack -= 2;
 				goto nextInstruction;
 			} else {
 				programCounter += 1;
-				opStack -= 2;
 				goto nextInstruction;
 			}
 
 		case OP_GTF:
-			if ( ((float *)opStack)[-1] > *(float *)opStack ) {
+			opStackOfs -= 2;
+
+			if(((float *) opStack)[(uint8_t) (opStackOfs + 1)] > ((float *) opStack)[(uint8_t) (opStackOfs + 2)])
+			{
 				programCounter = r2;	//vm->instructionPointers[r2];
-				opStack -= 2;
 				goto nextInstruction;
 			} else {
 				programCounter += 1;
-				opStack -= 2;
 				goto nextInstruction;
 			}
 
 		case OP_GEF:
-			if ( ((float *)opStack)[-1] >= *(float *)opStack ) {
+			opStackOfs -= 2;
+
+			if(((float *) opStack)[(uint8_t) (opStackOfs + 1)] >= ((float *) opStack)[(uint8_t) (opStackOfs + 2)])
+			{
 				programCounter = r2;	//vm->instructionPointers[r2];
-				opStack -= 2;
 				goto nextInstruction;
 			} else {
 				programCounter += 1;
-				opStack -= 2;
 				goto nextInstruction;
 			}
 
@@ -795,101 +796,101 @@
 		//===================================================================
 
 		case OP_NEGI:
-			*opStack = -r0;
+			opStack[opStackOfs] = -r0;
 			goto nextInstruction;
 		case OP_ADD:
-			opStack[-1] = r1 + r0;
-			opStack--;
+			opStackOfs--;
+			opStack[opStackOfs] = r1 + r0;
 			goto nextInstruction;
 		case OP_SUB:
-			opStack[-1] = r1 - r0;
-			opStack--;
+			opStackOfs--;
+			opStack[opStackOfs] = r1 - r0;
 			goto nextInstruction;
 		case OP_DIVI:
-			opStack[-1] = r1 / r0;
-			opStack--;
+			opStackOfs--;
+			opStack[opStackOfs] = r1 / r0;
 			goto nextInstruction;
 		case OP_DIVU:
-			opStack[-1] = ((unsigned)r1) / ((unsigned)r0);
-			opStack--;
+			opStackOfs--;
+			opStack[opStackOfs] = ((unsigned) r1) / ((unsigned) r0);
 			goto nextInstruction;
 		case OP_MODI:
-			opStack[-1] = r1 % r0;
-			opStack--;
+			opStackOfs--;
+			opStack[opStackOfs] = r1 % r0;
 			goto nextInstruction;
 		case OP_MODU:
-			opStack[-1] = ((unsigned)r1) % (unsigned)r0;
-			opStack--;
+			opStackOfs--;
+			opStack[opStackOfs] = ((unsigned) r1) % ((unsigned) r0);
 			goto nextInstruction;
 		case OP_MULI:
-			opStack[-1] = r1 * r0;
-			opStack--;
+			opStackOfs--;
+			opStack[opStackOfs] = r1 * r0;
 			goto nextInstruction;
 		case OP_MULU:
-			opStack[-1] = ((unsigned)r1) * ((unsigned)r0);
-			opStack--;
+			opStackOfs--;
+			opStack[opStackOfs] = ((unsigned) r1) * ((unsigned) r0);
 			goto nextInstruction;
 
 		case OP_BAND:
-			opStack[-1] = ((unsigned)r1) & ((unsigned)r0);
-			opStack--;
+			opStackOfs--;
+			opStack[opStackOfs] = ((unsigned) r1) & ((unsigned) r0);
 			goto nextInstruction;
 		case OP_BOR:
-			opStack[-1] = ((unsigned)r1) | ((unsigned)r0);
-			opStack--;
+			opStackOfs--;
+			opStack[opStackOfs] = ((unsigned) r1) | ((unsigned) r0);
 			goto nextInstruction;
 		case OP_BXOR:
-			opStack[-1] = ((unsigned)r1) ^ ((unsigned)r0);
-			opStack--;
+			opStackOfs--;
+			opStack[opStackOfs] = ((unsigned) r1) ^ ((unsigned) r0);
 			goto nextInstruction;
 		case OP_BCOM:
-			*opStack = ~ ((unsigned)r0);
+			opStack[opStackOfs] = ~((unsigned) r0);
 			goto nextInstruction;
 
 		case OP_LSH:
-			opStack[-1] = r1 << r0;
-			opStack--;
+			opStackOfs--;
+			opStack[opStackOfs] = r1 << r0;
 			goto nextInstruction;
 		case OP_RSHI:
-			opStack[-1] = r1 >> r0;
-			opStack--;
+			opStackOfs--;
+			opStack[opStackOfs] = r1 >> r0;
 			goto nextInstruction;
 		case OP_RSHU:
-			opStack[-1] = ((unsigned)r1) >> r0;
-			opStack--;
+			opStackOfs--;
+			opStack[opStackOfs] = ((unsigned) r1) >> r0;
 			goto nextInstruction;
 
 		case OP_NEGF:
-			*(float *)opStack =  -*(float *)opStack;
+			((float *) opStack)[opStackOfs] =  -((float *) opStack)[opStackOfs];
 			goto nextInstruction;
 		case OP_ADDF:
-			*(float *)(opStack-1) = *(float *)(opStack-1) + *(float *)opStack;
-			opStack--;
+			opStackOfs--;
+			((float *) opStack)[opStackOfs] = ((float *) opStack)[opStackOfs] + ((float *) opStack)[(uint8_t) (opStackOfs + 1)];
 			goto nextInstruction;
 		case OP_SUBF:
-			*(float *)(opStack-1) = *(float *)(opStack-1) - *(float *)opStack;
-			opStack--;
+			opStackOfs--;
+			((float *) opStack)[opStackOfs] = ((float *) opStack)[opStackOfs] - ((float *) opStack)[(uint8_t) (opStackOfs + 1)];
 			goto nextInstruction;
 		case OP_DIVF:
-			*(float *)(opStack-1) = *(float *)(opStack-1) / *(float *)opStack;
-			opStack--;
+			opStackOfs--;
+			((float *) opStack)[opStackOfs] = ((float *) opStack)[opStackOfs] / ((float *) opStack)[(uint8_t) (opStackOfs + 1)];
 			goto nextInstruction;
 		case OP_MULF:
-			*(float *)(opStack-1) = *(float *)(opStack-1) * *(float *)opStack;
-			opStack--;
+			opStackOfs--;
+			((float *) opStack)[opStackOfs] = ((float *) opStack)[opStackOfs] * ((float *) opStack)[(uint8_t) (opStackOfs + 1)];
 			goto nextInstruction;
 
 		case OP_CVIF:
-			*(float *)opStack =  (float)*opStack;
+			((float *) opStack)[opStackOfs] = (float) opStack[opStackOfs];
 			goto nextInstruction;
 		case OP_CVFI:
-			*opStack = (int) *(float *)opStack;
+			opStack[opStackOfs] = (int) ((float *) opStack)[opStackOfs];
 			goto nextInstruction;
 		case OP_SEX8:
-			*opStack = (signed char)*opStack;
+			opStack[opStackOfs] = (signed char) opStack[opStackOfs];
 			goto nextInstruction;
 		case OP_SEX16:
-			*opStack = (short)*opStack;
+			opStack[opStackOfs] = (short) opStack[opStackOfs];
 			goto nextInstruction;
 		}
 	}
@@ -897,12 +898,11 @@
 done:
 	vm->currentlyInterpreting = qfalse;
 
-	if ( opStack != &stack[1] ) {
-		Com_Error( ERR_DROP, "Interpreter error: opStack = %ld", (long int) (opStack - stack) );
-	}
+	if (opStackOfs != 1 || *opStack != 0xDEADBEEF)
+		Com_Error(ERR_DROP, "Interpreter error: opStack[0] = %X, opStackOfs = %d", opStack[0], opStackOfs);
 
 	vm->programStack = stackOnEntry;
 
 	// return the result
-	return *opStack;
+	return opStack[opStackOfs];
 }

Modified: trunk/code/qcommon/vm_local.h
===================================================================
--- trunk/code/qcommon/vm_local.h	2011-06-15 22:25:13 UTC (rev 2030)
+++ trunk/code/qcommon/vm_local.h	2011-06-16 01:11:45 UTC (rev 2031)
@@ -190,3 +190,5 @@
 int VM_SymbolToValue( vm_t *vm, const char *symbol );
 const char *VM_ValueToSymbol( vm_t *vm, int value );
 void VM_LogSyscalls( int *args );
+
+void VM_BlockCopy(unsigned int dest, unsigned int src, size_t n);

Modified: trunk/code/qcommon/vm_x86.c
===================================================================
--- trunk/code/qcommon/vm_x86.c	2011-06-15 22:25:13 UTC (rev 2030)
+++ trunk/code/qcommon/vm_x86.c	2011-06-16 01:11:45 UTC (rev 2031)
@@ -388,28 +388,6 @@
 
 /*
 =================
-DoBlockCopy
-Executes OP_BLOCK_COPY
-=================
-*/
-
-void DoBlockCopy(unsigned int dest, unsigned int src, size_t n)
-{
-	unsigned int dataMask = currentVM->dataMask;
-
-	if ((dest & dataMask) != dest
-	|| (src & dataMask) != src
-	|| ((dest + n) & dataMask) != dest + n
-	|| ((src + n) & dataMask) != src + n)
-	{
-		Com_Error(ERR_DROP, "OP_BLOCK_COPY out of range!");
-	}
-
-	memcpy(currentVM->dataBase + dest, currentVM->dataBase + src, n);
-}
-
-/*
-=================
 DoSyscall
 Uses asm to retrieve arguments from registers to work around different calling conventions
 =================
@@ -493,7 +471,7 @@
 			if(opStackOfs < 1)
 				Com_Error(ERR_DROP, "VM_BLOCK_COPY failed due to corrupted opStack");
 			
-			DoBlockCopy(opStackBase[opStackOfs - 1], opStackBase[opStackOfs], arg);
+			VM_BlockCopy(opStackBase[(opStackOfs - 1)], opStackBase[opStackOfs], arg);
 		break;
 		default:
 			Com_Error(ERR_DROP, "Unknown VM operation %d", syscallNum);

Modified: trunk/code/qcommon/vm_x86_64.c
===================================================================
--- trunk/code/qcommon/vm_x86_64.c	2011-06-15 22:25:13 UTC (rev 2030)
+++ trunk/code/qcommon/vm_x86_64.c	2011-06-16 01:11:45 UTC (rev 2031)
@@ -381,21 +381,6 @@
        return vm->codeBase;
 }
 
-static void CROSSCALL block_copy_vm(unsigned dest, unsigned src, unsigned count)
-{
-	unsigned dataMask = currentVM->dataMask;
-
-	if ((dest & dataMask) != dest
-	|| (src & dataMask) != src
-	|| ((dest+count) & dataMask) != dest + count
-	|| ((src+count) & dataMask) != src + count)
-	{
-		Com_Error(ERR_DROP, "OP_BLOCK_COPY out of range!");
-	}
-
-	memcpy(currentVM->dataBase+dest, currentVM->dataBase+src, count);
-}
-
 static void CROSSCALL eop(void)
 {
 	Com_Error(ERR_DROP, "End of program reached without return!");
@@ -782,7 +767,7 @@
 				emit("movl 4(%%r9, %%rbx, 4), %%edi");  // 1st argument dest
 				emit("movl 8(%%r9, %%rbx, 4), %%rsi");  // 2nd argument src
 				emit("movl $%d, %%edx", iarg); // 3rd argument count
-				emit("movq $%"PRIu64", %%rax", (intptr_t) block_copy_vm);
+				emit("movq $%"PRIu64", %%rax", (intptr_t) VM_BlockCopy);
 				emit("callq *%%rax");
 				emit("pop %%rsi");
 				emit("addq %%rsi, %%rsp");



More information about the quake3-commits mailing list