[quake3-commits] r2004 - trunk/code/qcommon
DONOTREPLY at icculus.org
DONOTREPLY at icculus.org
Mon Jun 6 10:29:45 EDT 2011
Author: thilo
Date: 2011-06-06 10:29:45 -0400 (Mon, 06 Jun 2011)
New Revision: 2004
Modified:
trunk/code/qcommon/vm_x86.c
Log:
- Use EmitCallDoSyscall() to call the jump violations function which guarantees 16-byte stack alignment
- Add x64 code for MSVC _asm() blocks, not tested yet.
Modified: trunk/code/qcommon/vm_x86.c
===================================================================
--- trunk/code/qcommon/vm_x86.c 2011-06-01 15:17:18 UTC (rev 2003)
+++ trunk/code/qcommon/vm_x86.c 2011-06-06 14:29:45 UTC (rev 2004)
@@ -105,7 +105,8 @@
typedef enum
{
- VM_BLOCK_COPY = 0,
+ VM_JMP_VIOLATION = 0,
+ VM_BLOCK_COPY = 1
} ESysCallType;
static ELastCommand LastCommand;
@@ -392,17 +393,20 @@
#define SET_JMPOFS(x) do { buf[(x)] = compiledOfs - ((x) + 1); } while(0)
+
+/*
+=================
+ErrJump
+Error handler for jump/call to invalid instruction number
+=================
+*/
+
static void ErrJump(void)
{
Com_Error(ERR_DROP, "program tried to execute code outside VM");
exit(1);
}
-#define ERRJUMP() \
- EmitRexString(0x48, "B8"); \
- EmitPtr(ErrJump); \
- EmitRexString(0x48, "FF D0")
-
/*
=================
DoBlockCopy
@@ -445,11 +449,16 @@
#ifdef _MSC_VER
__asm
{
- mov dword ptr syscallNum, eax
- mov dword ptr programStack, esi
- mov dword ptr opStackBase, edi
- mov dword ptr opStackOfs, ebx
- mov dword ptr arg, ecx
+ mov dword ptr syscallNum, eax
+ mov dword ptr programStack, esi
+ mov dword ptr opStackOfs, ebx
+#ifdef idx64
+ mov qword ptr opStackBase, rdi
+ mov qword ptr arg, rcx
+#else
+ mov dword ptr opStackBase, edi
+ mov dword ptr arg, ecx
+#endif
}
#else
__asm__ volatile(
@@ -491,6 +500,9 @@
{
switch(syscallNum)
{
+ case VM_JMP_VIOLATION:
+ ErrJump();
+ break;
case VM_BLOCK_COPY:
if(opStackOfs < 1)
Com_Error(ERR_DROP, "VM_BLOCK_COPY failed due to corrupted opStack");
@@ -506,6 +518,19 @@
/*
=================
+EmitCallRel
+Relative call to vm->codeBase + callOfs
+=================
+*/
+
+void EmitCallRel(vm_t *vm, int callOfs)
+{
+ EmitString("E8"); // call 0x12345678
+ Emit4(callOfs - compiledOfs - 4);
+}
+
+/*
+=================
EmitCallDoSyscall
Call to DoSyscall()
=================
@@ -532,7 +557,7 @@
EmitRexString(0x48, "89 E5"); // mov ebp, esp
EmitRexString(0x48, "83 E4 F0"); // and esp, 0xFFFFFFF0
- // call the syscall wrapper function
+ // call the syscall wrapper function DoSyscall()
EmitString("FF D2"); // call edx
@@ -555,15 +580,17 @@
/*
=================
-EmitCallRel
-Relative call to vm->codeBase + callOfs
+EmitCallErrJump
+Emit the code that triggers execution of the jump violation handler
=================
*/
-void EmitCallRel(vm_t *vm, int callOfs)
+static void EmitCallErrJump(vm_t *vm, int sysCallOfs)
{
- EmitString("E8"); // call 0x12345678
- Emit4(callOfs - compiledOfs - 4);
+ EmitString("B8"); // mov eax, 0x12345678
+ Emit4(VM_JMP_VIOLATION);
+
+ EmitCallRel(vm, sysCallOfs);
}
/*
@@ -582,7 +609,7 @@
STACK_POP(1); // sub bl, 1
EmitString("85 C0"); // test eax, eax
- // Jump to syscall code
+ // Jump to syscall code, 1 byte offset should suffice
EmitString("7C"); // jl systemCall
jmpSystemCall = compiledOfs++;
@@ -606,7 +633,7 @@
// badAddr:
SET_JMPOFS(jmpBadAddr);
- ERRJUMP();
+ EmitCallErrJump(vm, sysCallOfs);
/************ System Call ************/
@@ -657,7 +684,7 @@
EmitString("E8"); // call 0x12345678
// we only know all the jump addresses in the third pass
- if(pass)
+ if(pass == 2)
Emit4(vm->instructionPointers[cdest] - compiledOfs - 4);
else
compiledOfs += 4;
@@ -1081,7 +1108,7 @@
int maxLength;
int v;
int i;
- int callProcOfsSyscall, callProcOfs;
+ int callProcOfsSyscall, callProcOfs, callDoSyscallOfs;
jusedSize = header->instructionCount + 2;
@@ -1108,8 +1135,10 @@
// Start buffer with x86-VM specific procedures
compiledOfs = 0;
+
+ callDoSyscallOfs = compiledOfs;
callProcOfs = EmitCallDoSyscall(vm);
- callProcOfsSyscall = EmitCallProcedure(vm, 0);
+ callProcOfsSyscall = EmitCallProcedure(vm, callDoSyscallOfs);
vm->entryOfs = compiledOfs;
for(pass=0; pass < 3; pass++) {
@@ -1622,7 +1651,7 @@
EmitString("B9"); // mov ecx, 0x12345678
Emit4(Constant4());
- EmitCallRel(vm, 0);
+ EmitCallRel(vm, callDoSyscallOfs);
EmitCommand(LAST_COMMAND_SUB_BL_2); // sub bl, 2
break;
@@ -1640,7 +1669,7 @@
EmitString("FF 24 85"); // jmp dword ptr [instructionPointers + eax * 4]
Emit4((intptr_t) vm->instructionPointers);
#endif
- ERRJUMP();
+ EmitCallErrJump(vm, callDoSyscallOfs);
break;
default:
VMFREE_BUFFERS();
@@ -1720,7 +1749,7 @@
int stack[OPSTACK_SIZE + 7];
void *entryPoint;
int programCounter;
- intptr_t programStack, stackOnEntry;
+ int programStack, stackOnEntry;
byte *image;
int *opStack, *opStackOnEntry;
int opStackOfs;
@@ -1762,24 +1791,42 @@
#ifdef _MSC_VER
__asm
{
-#ifndef idx64
+#ifdef idx64
+ // non-volatile registers according to x64 calling convention
+ push rsi
+ push rdi
+ push rbx
+
+ mov esi, dword ptr programStack
+ mov rdi, qword ptr opStack
+ mov ebx, dword ptr opStackOfs
+ mov r8, qword ptr vm->instructionPointers
+ mov r9, qword ptr vm->dataBase
+
+ call entryPoint
+
+ mov dword ptr opStackOfs, ebx
+ mov qword ptr opStack, rdi
+ mov dword ptr programStack, esi
+
+ pop rbx
+ pop rdi
+ pop rsi
+#else
pushad
-#endif
- mov esi, programStack
- mov edi, opStack
- mov ebx, opStackOfs
-#ifdef idx64
-#warning look up calling conventions and push/pop if necessary
- mov r8, vm->instructionPointers
- mov r9, vm->dataBase
-#endif
- call entryPoint
- mov opStackOfs, ebx
- mov opStack, edi
- mov programStack, esi
-#ifndef idx64
+
+ mov esi, dword ptr programStack
+ mov edi, dword ptr opStack
+ mov ebx, dword ptr opStackOfs
+
+ call entryPoint
+
+ mov dword ptr opStackOfs, ebx
+ mov dword ptr opStack, edi
+ mov dword ptr programStack, esi
+
popad
-#endif
+#endif
}
#elif defined(idx64)
__asm__ volatile(
@@ -1797,7 +1844,7 @@
"pop %%r15\r\n"
: "+S" (programStack), "+D" (opStack), "+b" (opStackOfs)
: "g" (vm->instructionPointers), "g" (vm->dataBase), "g" (entryPoint)
- : "cc", "memory", "%rax", "%rcx", "%rdx", "%r8", "%r9", "%r10", "%r11", "%xmm0"
+ : "cc", "memory", "%rax", "%rcx", "%rdx", "%r8", "%r9", "%r10", "%r11"
);
#else
__asm__ volatile(
More information about the quake3-commits
mailing list