You've already forked wine-staging
mirror of
https://gitlab.winehq.org/wine/wine-staging.git
synced 2025-09-12 18:50:20 -07:00
Added patch to emulate 'mov Eb, Gb' instruction on x86 processor architecture.
This commit is contained in:
@@ -0,0 +1,79 @@
|
||||
From 4fa4d95330e47ca48ea7bfc0297c782374d55a4e Mon Sep 17 00:00:00 2001
|
||||
From: Sebastian Lackner <sebastian@fds-team.de>
|
||||
Date: Mon, 10 Nov 2014 07:14:48 +0100
|
||||
Subject: ntoskrnl: Emulate 'mov Eb, Gb' instruction on x86 processor
|
||||
architecture.
|
||||
|
||||
---
|
||||
dlls/ntoskrnl.exe/instr.c | 30 +++++++++++++++++++++++++++---
|
||||
1 file changed, 27 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/dlls/ntoskrnl.exe/instr.c b/dlls/ntoskrnl.exe/instr.c
|
||||
index fe35686..38492f0 100644
|
||||
--- a/dlls/ntoskrnl.exe/instr.c
|
||||
+++ b/dlls/ntoskrnl.exe/instr.c
|
||||
@@ -59,7 +59,7 @@ static inline struct idtr get_idtr(void)
|
||||
}
|
||||
|
||||
/* store an operand into a register */
|
||||
-static void store_reg( CONTEXT *context, BYTE regmodrm, const BYTE *addr, int long_op )
|
||||
+static void store_reg_word( CONTEXT *context, BYTE regmodrm, const BYTE *addr, int long_op )
|
||||
{
|
||||
switch((regmodrm >> 3) & 7)
|
||||
{
|
||||
@@ -98,6 +98,22 @@ static void store_reg( CONTEXT *context, BYTE regmodrm, const BYTE *addr, int lo
|
||||
}
|
||||
}
|
||||
|
||||
+/* store an operand into a byte register */
|
||||
+static void store_reg_byte( CONTEXT *context, BYTE regmodrm, const BYTE *addr )
|
||||
+{
|
||||
+ switch((regmodrm >> 3) & 7)
|
||||
+ {
|
||||
+ case 0: context->Eax = (context->Eax & 0xffffff00) | *addr; break;
|
||||
+ case 1: context->Ecx = (context->Ecx & 0xffffff00) | *addr; break;
|
||||
+ case 2: context->Edx = (context->Edx & 0xffffff00) | *addr; break;
|
||||
+ case 3: context->Ebx = (context->Ebx & 0xffffff00) | *addr; break;
|
||||
+ case 4: context->Eax = (context->Eax & 0xffff00ff) | (*addr << 8); break;
|
||||
+ case 5: context->Ecx = (context->Ecx & 0xffff00ff) | (*addr << 8); break;
|
||||
+ case 6: context->Edx = (context->Edx & 0xffff00ff) | (*addr << 8); break;
|
||||
+ case 7: context->Ebx = (context->Ebx & 0xffff00ff) | (*addr << 8); break;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
/***********************************************************************
|
||||
* INSTR_GetOperandAddr
|
||||
*
|
||||
@@ -399,19 +415,27 @@ static DWORD emulate_instruction( EXCEPTION_RECORD *rec, CONTEXT *context )
|
||||
}
|
||||
break; /* Unable to emulate it */
|
||||
|
||||
+ case 0x8a: /* mov Eb, Gb */
|
||||
case 0x8b: /* mov Ev, Gv */
|
||||
{
|
||||
BYTE *addr = INSTR_GetOperandAddr(context, instr + 1, long_addr,
|
||||
segprefix, &len);
|
||||
struct idtr idtr = get_idtr();
|
||||
unsigned int offset = addr - idtr.base;
|
||||
+ unsigned int size = (*instr == 0x8b) ? (long_op ? 4 : 2) : 1;
|
||||
|
||||
- if (offset <= idtr.limit + 1 - (long_op ? 4 : 2))
|
||||
+ if (offset <= idtr.limit + 1 - size)
|
||||
{
|
||||
idt[1].LimitLow = 0x100; /* FIXME */
|
||||
idt[2].LimitLow = 0x11E; /* FIXME */
|
||||
idt[3].LimitLow = 0x500; /* FIXME */
|
||||
- store_reg( context, instr[1], (BYTE *)idt + offset, long_op );
|
||||
+
|
||||
+ switch (*instr)
|
||||
+ {
|
||||
+ case 0x8a: store_reg_byte( context, instr[1], (BYTE *)idt + offset ); break;
|
||||
+ case 0x8b: store_reg_word( context, instr[1], (BYTE *)idt + offset, long_op ); break;
|
||||
+ }
|
||||
+
|
||||
context->Eip += prefixlen + len + 1;
|
||||
return ExceptionContinueExecution;
|
||||
}
|
||||
--
|
||||
2.1.3
|
||||
|
3
patches/ntoskrnl-Emulator/definition
Normal file
3
patches/ntoskrnl-Emulator/definition
Normal file
@@ -0,0 +1,3 @@
|
||||
Author: Sebastian Lackner
|
||||
Subject: Emulate 'mov Eb, Gb' instruction on x86 processor architecture.
|
||||
Revision: 1
|
Reference in New Issue
Block a user