[quake3-commits] r1724 - trunk/code/qcommon
DONOTREPLY at icculus.org
DONOTREPLY at icculus.org
Sun Nov 1 14:58:27 EST 2009
Author: ludwig
Date: 2009-11-01 14:58:27 -0500 (Sun, 01 Nov 2009)
New Revision: 1724
Modified:
trunk/code/qcommon/vm_x86_64.c
Log:
check all jumps (#4249)
Modified: trunk/code/qcommon/vm_x86_64.c
===================================================================
--- trunk/code/qcommon/vm_x86_64.c 2009-11-01 19:58:25 UTC (rev 1723)
+++ trunk/code/qcommon/vm_x86_64.c 2009-11-01 19:58:27 UTC (rev 1724)
@@ -228,14 +228,27 @@
assemble_line(line, strlen(line));
}
-#define CHECK_IARG \
- do { if(iarg < 0 || iarg >= header->instructionCount) { \
+#define CHECK_INSTR_REG(reg) \
+ emit("cmpl $%u, %%"#reg, header->instructionCount); \
+ emit("jb jmp_ok_i_%08x", instruction); \
+ emit("movq $%lu, %%rax", (unsigned long)jmpviolation); \
+ emit("callq *%%rax"); \
+ emit("jmp_ok_i_%08x:", instruction);
+
+#define PREPARE_JMP(reg) \
+ CHECK_INSTR_REG(reg) \
+ emit("movq $%lu, %%rbx", (unsigned long)vm->instructionPointers); \
+ emit("movl (%%rbx, %%rax, 4), %%eax"); \
+ emit("addq %%r10, %%rax");
+
+#define CHECK_INSTR(nr) \
+ do { if(nr < 0 || nr >= header->instructionCount) { \
Com_Error( ERR_DROP, \
- "%s: jump target out of range at offset %d", __func__, pc ); \
+ "%s: jump target 0x%x out of range at offset %d", __func__, nr, pc ); \
} } while(0)
#define JMPIARG \
- CHECK_IARG; \
+ CHECK_INSTR(iarg); \
emit("movq $%lu, %%rax", vm->codeBase+vm->instructionPointers[iarg]); \
emit("jmpq *%%rax");
@@ -371,6 +384,12 @@
exit(1);
}
+static void jmpviolation(void)
+{
+ Com_Error(ERR_DROP, "program tried to execute code outside VM\n");
+ exit(1);
+}
+
#ifdef DEBUG_VM
static void memviolation(void)
{
@@ -490,19 +509,35 @@
emit("ret");
break;
case OP_CALL:
- MAYBE_EMIT_CONST();
- emit("movl 0(%%rsi), %%eax"); // get instr from stack
- emit("subq $4, %%rsi");
RANGECHECK(edi, 4);
emit("movl $%d, 0(%%r8, %%rdi, 1)", instruction+1); // save next instruction
- emit("orl %%eax, %%eax");
- emit("jl callSyscall%d", instruction);
- emit("movq $%lu, %%rbx", (unsigned long)vm->instructionPointers);
- emit("movl (%%rbx, %%rax, 4), %%eax"); // load new relative jump address
- emit("addq %%r10, %%rax");
- emit("callq *%%rax");
- emit("jmp i_%08x", instruction+1);
- emit("callSyscall%d:", instruction);
+ if(got_const)
+ {
+ if ((int)const_value < 0)
+ goto emit_do_syscall;
+
+ CHECK_INSTR(const_value);
+ emit("movq $%lu, %%rax", vm->codeBase+vm->instructionPointers[const_value]);
+ emit("callq *%%rax");
+ got_const = 0;
+ break;
+ }
+ else
+ {
+ MAYBE_EMIT_CONST();
+ emit("movl 0(%%rsi), %%eax"); // get instr from stack
+ emit("subq $4, %%rsi");
+
+ emit("orl %%eax, %%eax");
+ emit("jl callSyscall%d", instruction);
+
+ PREPARE_JMP(eax);
+ emit("callq *%%rax");
+
+ emit("jmp i_%08x", instruction+1);
+ emit("callSyscall%d:", instruction);
+ }
+emit_do_syscall:
// emit("fnsave 4(%%rsi)");
emit("push %%rsi");
emit("push %%rdi");
@@ -514,10 +549,15 @@
emit("andq $127, %%rbx"); // |
emit("subq %%rbx, %%rsp"); // <-+
emit("push %%rbx");
- emit("negl %%eax"); // convert to actual number
- emit("decl %%eax");
- // first argument already in rdi
- emit("movq %%rax, %%rsi"); // second argument in rsi
+ if(got_const) {
+ got_const = 0;
+ emit("movq $%u, %%rsi", -1-const_value); // second argument in rsi
+ } else {
+ emit("negl %%eax"); // convert to actual number
+ emit("decl %%eax");
+ // first argument already in rdi
+ emit("movq %%rax, %%rsi"); // second argument in rsi
+ }
emit("movq $%lu, %%rax", (unsigned long)callAsmCall);
emit("callq *%%rax");
emit("pop %%rbx");
@@ -565,9 +605,8 @@
} else {
emit("movl 0(%%rsi), %%eax"); // get instr from stack
emit("subq $4, %%rsi");
- emit("movq $%lu, %%rbx", (unsigned long)vm->instructionPointers);
- emit("movl (%%rbx, %%rax, 4), %%eax"); // load new relative jump address
- emit("addq %%r10, %%rax");
+
+ PREPARE_JMP(eax);
emit("jmp *%%rax");
}
break;
More information about the quake3-commits
mailing list