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

DONOTREPLY at icculus.org DONOTREPLY at icculus.org
Tue May 24 15:46:52 EDT 2011


Author: thilo
Date: 2011-05-24 15:46:52 -0400 (Tue, 24 May 2011)
New Revision: 2000

Modified:
   trunk/code/qcommon/vm_sparc.c
Log:
Add instruction number checks to jumps and calls to SPARC VM, patch by David Miller


Modified: trunk/code/qcommon/vm_sparc.c
===================================================================
--- trunk/code/qcommon/vm_sparc.c	2011-05-23 00:46:46 UTC (rev 1999)
+++ trunk/code/qcommon/vm_sparc.c	2011-05-24 19:46:52 UTC (rev 2000)
@@ -511,6 +511,7 @@
 	int (*AsmCall)(int, int);
 	void (*BlockCopy)(unsigned int, unsigned int, unsigned int);
 	unsigned int *iPointers;
+	void (*ErrJump)(void);
 	unsigned int data[0];
 } vm_data_t;
 
@@ -698,11 +699,20 @@
 	fp->insn_index = 0;
 }
 
-static void jump_insn_append(struct func_info * const fp, enum sparc_iname iname, int dest)
+static void ErrJump(void)
+{ 
+	Com_Error(ERR_DROP, "program tried to execute code outside VM\n");
+	exit(1);
+}
+
+static void jump_insn_append(vm_t *vm, struct func_info * const fp, enum sparc_iname iname, int dest)
 {
 	struct jump_insn *jp = Z_Malloc(sizeof(*jp));
 	struct dst_insn *dp;
 
+	if (dest < 0 || dest >= vm->instructionCount)
+		ErrJump();
+
 	dp = dst_new(fp, 2, jp, 0);
 
 	jp->jump_iname = iname;
@@ -734,10 +744,10 @@
 		dst_insn_append(fp);
 }
 
-static void emit_jump(struct func_info * const fp, enum sparc_iname iname, int dest)
+static void emit_jump(vm_t *vm, struct func_info * const fp, enum sparc_iname iname, int dest)
 {
 	end_emit(fp);
-	jump_insn_append(fp, iname, dest);
+	jump_insn_append(vm, fp, iname, dest);
 }
 
 static void analyze_function(struct func_info * const fp)
@@ -860,7 +870,7 @@
 	(fp)->saved_icount = saved_i_count;			\
 } while (0)
 
-static void compile_one_insn(struct func_info * const fp, struct src_insn *sp)
+static void compile_one_insn(vm_t *vm, struct func_info * const fp, struct src_insn *sp)
 {
 	start_emit(fp, sp->i_count);
 
@@ -928,11 +938,17 @@
 	case OP_JUMP:
 		if (fp->cached_const) {
 			EMIT_FALSE_CONST(fp);
-			emit_jump(fp, BA, fp->cached_const->arg.i);
+			emit_jump(vm, fp, BA, fp->cached_const->arg.i);
 		} else {
 			MAYBE_EMIT_CONST(fp);
+			in(SETHI, vm->instructionCount >> 10, rTMP);
+			in(ORI, rTMP, vm->instructionCount & 0x3ff, rTMP);
+			in(SUBCC, rTMP, rFIRST(fp), G0);
+			in(BLEU, +4*5);
+			in(LDLI, rVMDATA, VM_Data_Offset(ErrJump), rTMP);
+
+			in(SLLI, rFIRST(fp), 2, rFIRST(fp));
 			in(LDLI, rVMDATA, VM_Data_Offset(iPointers), rTMP);
-			in(SLLI, rFIRST(fp), 2, rFIRST(fp));
 			in(LDL, rTMP, rFIRST(fp), rTMP);
 			in(JMPL, rTMP, G0, G0);
 			in(NOP);
@@ -943,7 +959,7 @@
 		if (fp->cached_const) {
 			EMIT_FALSE_CONST(fp);
 			if (fp->cached_const->arg.si >= 0) {
-				emit_jump(fp, CALL, fp->cached_const->arg.i);
+				emit_jump(vm, fp, CALL, fp->cached_const->arg.i);
 			} else {
 				in(LDLI, rVMDATA, VM_Data_Offset(CallThunk), rTMP);
 				in(LDLI, rVMDATA, VM_Data_Offset(AsmCall), O3);
@@ -959,6 +975,11 @@
 			in(NOP);
 
 			/* normal call */
+			in(SETHI, vm->instructionCount >> 10, rTMP);
+			in(ORI, rTMP, vm->instructionCount & 0x3ff, rTMP);
+			in(SUBCC, rTMP, rFIRST(fp), G0);
+			in(BLEU, +4*9);
+			in(LDLI, rVMDATA, VM_Data_Offset(ErrJump), rTMP);
 			in(LDLI, rVMDATA, VM_Data_Offset(iPointers), O5);
 			in(SLLI, rFIRST(fp), 2, rFIRST(fp));
 			in(LDL, O5, rFIRST(fp), rTMP);
@@ -1124,7 +1145,7 @@
 		case OP_GTU: iname = BGU; break;
 		case OP_LEU: iname = BLEU; break;
 		}
-		emit_jump(fp, iname, sp->arg.i);
+		emit_jump(vm, fp, iname, sp->arg.i);
 		POP_GPR(fp);
 		POP_GPR(fp);
 		break;
@@ -1297,7 +1318,7 @@
 		case OP_GTF: iname = FBG; break;
 		case OP_LEF: iname = FBLE; break;
 		}
-		emit_jump(fp, iname, sp->arg.i);
+		emit_jump(vm, fp, iname, sp->arg.i);
 		POP_FPR(fp);
 		POP_FPR(fp);
 		break;
@@ -1344,7 +1365,7 @@
 	}
 }
 
-static void compile_function(struct func_info * const fp)
+static void compile_function(vm_t *vm, struct func_info * const fp)
 {
 	struct src_insn *sp;
 
@@ -1359,7 +1380,7 @@
 
 	sp = fp->first;
 	while ((sp = sp->next) != NULL)
-		compile_one_insn(fp, sp);
+		compile_one_insn(vm, fp, sp);
 
 	free_source_insns(fp);
 }
@@ -1478,6 +1499,7 @@
 	data->iPointers = (unsigned int *) vm->instructionPointers;
 	data->dataLength = VM_Data_Offset(data[fp->data_num]);
 	data->codeLength = (code_now - code_begin) * sizeof(unsigned int);
+	data->ErrJump = ErrJump;
 
 #if 0
 	{
@@ -1564,7 +1586,7 @@
 
 		if (op == OP_ENTER) {
 			if (fi.first->next)
-				compile_function(&fi);
+				compile_function(vm, &fi);
 			fi.first->next = NULL;
 			fi.last = fi.first;
 			fi.has_call = fi.need_float_tmp = 0;
@@ -1592,7 +1614,7 @@
 		fi.last->next = sp;
 		fi.last = sp;
 	}
-	compile_function(&fi);
+	compile_function(vm, &fi);
 
 	Z_Free(fi.first);
 



More information about the quake3-commits mailing list