From c05d9c9f0c4e85ad14be116831039e25b19c39fb Mon Sep 17 00:00:00 2001 From: Thilo Schulz Date: Fri, 23 Oct 2009 03:02:08 +0000 Subject: [PATCH] Fix uninitialized words in VM interpreter, reported by Patrick Baggett (4281) --- code/qcommon/vm_interpreted.c | 122 ++++++++++++++++------------------ 1 file changed, 57 insertions(+), 65 deletions(-) diff --git a/code/qcommon/vm_interpreted.c b/code/qcommon/vm_interpreted.c index 6b303d85..d348ee6b 100644 --- a/code/qcommon/vm_interpreted.c +++ b/code/qcommon/vm_interpreted.c @@ -169,7 +169,8 @@ VM_PrepareInterpreter */ void VM_PrepareInterpreter( vm_t *vm, vmHeader_t *header ) { int op; - int pc; + int byte_pc; + int int_pc; byte *code; int instruction; int *codeBase; @@ -179,22 +180,24 @@ void VM_PrepareInterpreter( vm_t *vm, vmHeader_t *header ) { // we don't need to translate the instructions, but we still need // to find each instructions starting point for jumps - pc = 0; + int_pc = byte_pc = 0; instruction = 0; code = (byte *)header + header->codeOffset; codeBase = (int *)vm->codeBase; + // Copy and expand instructions to words while building instruction table while ( instruction < header->instructionCount ) { - vm->instructionPointers[ instruction ] = pc; + vm->instructionPointers[ instruction ] = int_pc; instruction++; - op = code[ pc ]; - codeBase[pc] = op; - if ( pc > header->codeLength ) { + op = (int)code[ byte_pc ]; + codeBase[int_pc] = op; + if ( byte_pc > header->codeLength ) { Com_Error( ERR_FATAL, "VM_PrepareInterpreter: pc > header->codeLength" ); } - pc++; + byte_pc++; + int_pc++; // these are the only opcodes that aren't a single byte switch ( op ) { @@ -219,32 +222,33 @@ void VM_PrepareInterpreter( vm_t *vm, vmHeader_t *header ) { case OP_GTF: case OP_GEF: case OP_BLOCK_COPY: - codeBase[pc+0] = loadWord(&code[pc]); - pc += 4; + codeBase[int_pc] = loadWord(&code[byte_pc]); + byte_pc += 4; + int_pc++; break; case OP_ARG: - codeBase[pc+0] = code[pc]; - pc += 1; + codeBase[int_pc] = (int)code[byte_pc]; + byte_pc++; + int_pc++; break; default: break; } } - pc = 0; + int_pc = 0; instruction = 0; code = (byte *)header + header->codeOffset; - codeBase = (int *)vm->codeBase; - + + // Now that the code has been expanded to int-sized opcodes, we'll translate instruction index + //into an index into codeBase[], which contains opcodes and operands. while ( instruction < header->instructionCount ) { - op = code[ pc ]; + op = codeBase[ int_pc ]; instruction++; - pc++; + int_pc++; + switch ( op ) { - case OP_ENTER: - case OP_CONST: - case OP_LOCAL: - case OP_LEAVE: + // These ops need to translate addresses in jumps from instruction index to int index case OP_EQ: case OP_NE: case OP_LTI: @@ -261,34 +265,22 @@ void VM_PrepareInterpreter( vm_t *vm, vmHeader_t *header ) { case OP_LEF: case OP_GTF: case OP_GEF: + // 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]]; + int_pc++; + break; + + // These opcodes have an operand that isn't an instruction index + case OP_ENTER: + case OP_CONST: + case OP_LOCAL: + case OP_LEAVE: case OP_BLOCK_COPY: - switch(op) { - case OP_EQ: - case OP_NE: - case OP_LTI: - case OP_LEI: - case OP_GTI: - case OP_GEI: - case OP_LTU: - case OP_LEU: - case OP_GTU: - case OP_GEU: - case OP_EQF: - case OP_NEF: - case OP_LTF: - case OP_LEF: - case OP_GTF: - case OP_GEF: - codeBase[pc] = vm->instructionPointers[codeBase[pc]]; - break; - default: - break; - } - pc += 4; - break; case OP_ARG: - pc += 1; + int_pc++; break; + default: break; } @@ -432,14 +424,14 @@ nextInstruction2: r1 = r0; r0 = *opStack = r2; - programCounter += 4; + programCounter += 1; goto nextInstruction2; case OP_LOCAL: opStack++; r1 = r0; r0 = *opStack = r2+programStack; - programCounter += 4; + programCounter += 1; goto nextInstruction2; case OP_LOAD4: @@ -493,7 +485,7 @@ nextInstruction2: dest = (int *)&image[ desti ]; memcpy(dest, src, count); - programCounter += 4; + programCounter += 1; opStack -= 2; } goto nextInstruction; @@ -578,7 +570,7 @@ nextInstruction2: // get size of stack frame v1 = r2; - programCounter += 4; + programCounter += 1; programStack -= v1; #ifdef DEBUG_VM // save old stack frame for debugging traces @@ -636,7 +628,7 @@ nextInstruction2: programCounter = r2; //vm->instructionPointers[r2]; goto nextInstruction; } else { - programCounter += 4; + programCounter += 1; goto nextInstruction; } @@ -646,7 +638,7 @@ nextInstruction2: programCounter = r2; //vm->instructionPointers[r2]; goto nextInstruction; } else { - programCounter += 4; + programCounter += 1; goto nextInstruction; } @@ -656,7 +648,7 @@ nextInstruction2: programCounter = r2; //vm->instructionPointers[r2]; goto nextInstruction; } else { - programCounter += 4; + programCounter += 1; goto nextInstruction; } @@ -666,7 +658,7 @@ nextInstruction2: programCounter = r2; //vm->instructionPointers[r2]; goto nextInstruction; } else { - programCounter += 4; + programCounter += 1; goto nextInstruction; } @@ -676,7 +668,7 @@ nextInstruction2: programCounter = r2; //vm->instructionPointers[r2]; goto nextInstruction; } else { - programCounter += 4; + programCounter += 1; goto nextInstruction; } @@ -686,7 +678,7 @@ nextInstruction2: programCounter = r2; //vm->instructionPointers[r2]; goto nextInstruction; } else { - programCounter += 4; + programCounter += 1; goto nextInstruction; } @@ -696,7 +688,7 @@ nextInstruction2: programCounter = r2; //vm->instructionPointers[r2]; goto nextInstruction; } else { - programCounter += 4; + programCounter += 1; goto nextInstruction; } @@ -706,7 +698,7 @@ nextInstruction2: programCounter = r2; //vm->instructionPointers[r2]; goto nextInstruction; } else { - programCounter += 4; + programCounter += 1; goto nextInstruction; } @@ -716,7 +708,7 @@ nextInstruction2: programCounter = r2; //vm->instructionPointers[r2]; goto nextInstruction; } else { - programCounter += 4; + programCounter += 1; goto nextInstruction; } @@ -726,7 +718,7 @@ nextInstruction2: programCounter = r2; //vm->instructionPointers[r2]; goto nextInstruction; } else { - programCounter += 4; + programCounter += 1; goto nextInstruction; } @@ -736,7 +728,7 @@ nextInstruction2: opStack -= 2; goto nextInstruction; } else { - programCounter += 4; + programCounter += 1; opStack -= 2; goto nextInstruction; } @@ -747,7 +739,7 @@ nextInstruction2: opStack -= 2; goto nextInstruction; } else { - programCounter += 4; + programCounter += 1; opStack -= 2; goto nextInstruction; } @@ -758,7 +750,7 @@ nextInstruction2: opStack -= 2; goto nextInstruction; } else { - programCounter += 4; + programCounter += 1; opStack -= 2; goto nextInstruction; } @@ -769,7 +761,7 @@ nextInstruction2: opStack -= 2; goto nextInstruction; } else { - programCounter += 4; + programCounter += 1; opStack -= 2; goto nextInstruction; } @@ -780,7 +772,7 @@ nextInstruction2: opStack -= 2; goto nextInstruction; } else { - programCounter += 4; + programCounter += 1; opStack -= 2; goto nextInstruction; } @@ -791,7 +783,7 @@ nextInstruction2: opStack -= 2; goto nextInstruction; } else { - programCounter += 4; + programCounter += 1; opStack -= 2; goto nextInstruction; }