Alexandre Julliard : ntoskrnl.exe: More general implementation of the CRn and DRn registers.
Alexandre Julliard
julliard at winehq.org
Thu Mar 1 13:34:44 CST 2018
Module: wine
Branch: master
Commit: 9f103a9e78e4e337026828f15cf835a5ac222bf9
URL: https://source.winehq.org/git/wine.git/?a=commit;h=9f103a9e78e4e337026828f15cf835a5ac222bf9
Author: Alexandre Julliard <julliard at winehq.org>
Date: Thu Mar 1 17:11:34 2018 +0100
ntoskrnl.exe: More general implementation of the CRn and DRn registers.
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/ntoskrnl.exe/instr.c | 138 ++++++++++++++++++++--------------------------
1 file changed, 60 insertions(+), 78 deletions(-)
diff --git a/dlls/ntoskrnl.exe/instr.c b/dlls/ntoskrnl.exe/instr.c
index 2822aac..fdbe8bd 100644
--- a/dlls/ntoskrnl.exe/instr.c
+++ b/dlls/ntoskrnl.exe/instr.c
@@ -271,6 +271,7 @@ static void *INSTR_GetOperandAddr( CONTEXT *context, BYTE *instr,
*/
static DWORD emulate_instruction( EXCEPTION_RECORD *rec, CONTEXT *context )
{
+ static const char *reg_names[8] = { "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi" };
int prefix, segprefix, prefixlen, len, long_op, long_addr;
BYTE *instr;
@@ -335,97 +336,78 @@ static DWORD emulate_instruction( EXCEPTION_RECORD *rec, CONTEXT *context )
case 0x0f: /* extended instruction */
switch(instr[1])
{
- case 0x22: /* mov eax, crX */
- switch (instr[2])
+ case 0x20: /* mov crX, Rd */
{
- case 0xc0:
- TRACE("mov eax,cr0 at 0x%08x, EAX=0x%08x\n", context->Eip,context->Eax );
- context->Eip += prefixlen+3;
+ int reg = (instr[2] >> 3) & 7;
+ DWORD *data = get_reg_address( context, instr[2] );
+ TRACE( "mov cr%u,%s at 0x%08x\n", reg, reg_names[instr[2] & 7], context->Eip );
+ switch (reg)
+ {
+ case 0: *data = 0x10; break; /* FIXME: set more bits ? */
+ case 2: *data = 0; break;
+ case 3: *data = 0; break;
+ case 4: *data = 0; break;
+ default: return ExceptionContinueSearch;
+ }
+ context->Eip += prefixlen + 3;
return ExceptionContinueExecution;
- case 0xe0:
- TRACE("mov eax,cr4 at 0x%08x, EAX=0x%08x\n", context->Eip,context->Eax );
- context->Eip += prefixlen+3;
- return ExceptionContinueExecution;
- default:
- break; /*fallthrough to bad instruction handling */
}
- ERR("Unsupported EAX -> CR register, eip+2 is %02x\n", instr[2]);
- break; /*fallthrough to bad instruction handling */
- case 0x20: /* mov crX, eax */
- switch (instr[2])
+ case 0x21: /* mov drX, Rd */
{
- case 0xe0: /* mov cr4, eax */
- /* CR4 register . See linux/arch/i386/mm/init.c, X86_CR4_ defs
- * bit 0: VME Virtual Mode Exception ?
- * bit 1: PVI Protected mode Virtual Interrupt
- * bit 2: TSD Timestamp disable
- * bit 3: DE Debugging extensions
- * bit 4: PSE Page size extensions
- * bit 5: PAE Physical address extension
- * bit 6: MCE Machine check enable
- * bit 7: PGE Enable global pages
- * bit 8: PCE Enable performance counters at IPL3
- */
- TRACE("mov cr4,eax at 0x%08x\n",context->Eip);
- context->Eax = 0;
- context->Eip += prefixlen+3;
- return ExceptionContinueExecution;
- case 0xc0: /* mov cr0, eax */
- TRACE("mov cr0,eax at 0x%08x\n",context->Eip);
- context->Eax = 0x10; /* FIXME: set more bits ? */
- context->Eip += prefixlen+3;
+ int reg = (instr[2] >> 3) & 7;
+ DWORD *data = get_reg_address( context, instr[2] );
+ TRACE( "mov dr%u,%s at 0x%08x\n", reg, reg_names[instr[2] & 7], context->Eip );
+ switch (reg)
+ {
+ case 0: *data = context->Dr0; break;
+ case 1: *data = context->Dr1; break;
+ case 2: *data = context->Dr2; break;
+ case 3: *data = context->Dr3; break;
+ case 6: *data = context->Dr6; break;
+ case 7: *data = 0x400; break;
+ default: return ExceptionContinueSearch;
+ }
+ context->Eip += prefixlen + 3;
return ExceptionContinueExecution;
- default: /* fallthrough to illegal instruction */
- break;
}
- /* fallthrough to illegal instruction */
- break;
- case 0x21: /* mov drX, eax */
- switch (instr[2])
+ case 0x22: /* mov Rd, crX */
{
- case 0xc8: /* mov dr1, eax */
- TRACE("mov dr1,eax at 0x%08x\n",context->Eip);
- context->Eax = context->Dr1;
- context->Eip += prefixlen+3;
- return ExceptionContinueExecution;
- case 0xf8: /* mov dr7, eax */
- TRACE("mov dr7,eax at 0x%08x\n",context->Eip);
- context->Eax = 0x400;
- context->Eip += prefixlen+3;
+ int reg = (instr[2] >> 3) & 7;
+ DWORD *data = get_reg_address( context, instr[2] );
+ TRACE( "mov %s,cr%u at 0x%08x, %s=%08x\n", reg_names[instr[2] & 7],
+ reg, context->Eip, reg_names[instr[2] & 7], *data );
+ switch (reg)
+ {
+ case 0: break;
+ case 2: break;
+ case 3: break;
+ case 4: break;
+ default: return ExceptionContinueSearch;
+ }
+ context->Eip += prefixlen + 3;
return ExceptionContinueExecution;
}
- ERR("Unsupported DR register -> EAX, eip+2 is %02x\n", instr[2]);
- /* fallthrough to illegal instruction */
- break;
- case 0x23: /* mov eax drX */
- switch (instr[2])
+ case 0x23: /* mov Rd, drX */
{
- case 0xc0: /* mov eax, dr0 */
- context->Dr0 = context->Eax;
- context->Eip += prefixlen+3;
- return ExceptionContinueExecution;
- case 0xc8: /* mov eax, dr1 */
- context->Dr1 = context->Eax;
- context->Eip += prefixlen+3;
- return ExceptionContinueExecution;
- case 0xd0: /* mov eax, dr2 */
- context->Dr2 = context->Eax;
- context->Eip += prefixlen+3;
- return ExceptionContinueExecution;
- case 0xd8: /* mov eax, dr3 */
- context->Dr3 = context->Eax;
- context->Eip += prefixlen+3;
- return ExceptionContinueExecution;
- case 0xf8: /* mov eax, dr7 */
- context->Dr7 = context->Eax;
- context->Eip += prefixlen+3;
+ int reg = (instr[2] >> 3) & 7;
+ DWORD *data = get_reg_address( context, instr[2] );
+ TRACE( "mov %s,dr%u at 0x%08x %s=%08x\n", reg_names[instr[2] & 7],
+ reg, context->Eip, reg_names[instr[2] & 7], *data );
+ switch (reg)
+ {
+ case 0: context->Dr0 = *data; break;
+ case 1: context->Dr1 = *data; break;
+ case 2: context->Dr2 = *data; break;
+ case 3: context->Dr3 = *data; break;
+ case 6: context->Dr6 = *data; break;
+ case 7: context->Dr7 = *data; break;
+ default: return ExceptionContinueSearch;
+ }
+ context->Eip += prefixlen + 3;
return ExceptionContinueExecution;
}
- ERR("Unsupported EAX -> DR register, eip+2 is %02x\n", instr[2]);
- /* fallthrough to illegal instruction */
- break;
}
- break; /* Unable to emulate it */
+ break;
case 0x8a: /* mov Eb, Gb */
case 0x8b: /* mov Ev, Gv */
More information about the wine-cvs
mailing list