Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
add0c585
Commit
add0c585
authored
Sep 17, 2003
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Use WOWCallback16Ex to switch to vm86 mode so that we can setup a
proper exception handler and handle instruction emulation.
parent
f5cb3dde
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
71 additions
and
35 deletions
+71
-35
instr.c
dlls/kernel/instr.c
+33
-32
wowthunk.c
dlls/kernel/wowthunk.c
+35
-1
dosvm.c
dlls/winedos/dosvm.c
+2
-1
miscemu.h
include/miscemu.h
+1
-1
No files found.
dlls/kernel/instr.c
View file @
add0c585
...
...
@@ -25,6 +25,7 @@
#include "winbase.h"
#include "wingdi.h"
#include "wine/winuser16.h"
#include "excpt.h"
#include "module.h"
#include "miscemu.h"
#include "selectors.h"
...
...
@@ -392,17 +393,16 @@ static void INSTR_outport( WORD port, int size, DWORD val, CONTEXT86 *context )
* INSTR_EmulateInstruction
*
* Emulate a privileged instruction.
* Returns exception co
de, or 0 if emulation successful
.
* Returns exception co
ntinuation status
.
*/
DWORD
INSTR_EmulateInstruction
(
CONTEXT86
*
context
)
DWORD
INSTR_EmulateInstruction
(
EXCEPTION_RECORD
*
rec
,
CONTEXT86
*
context
)
{
int
prefix
,
segprefix
,
prefixlen
,
len
,
repX
,
long_op
,
long_addr
;
BYTE
*
instr
;
DWORD
ret
=
EXCEPTION_PRIV_INSTRUCTION
;
long_op
=
long_addr
=
(
!
ISV86
(
context
)
&&
IS_SELECTOR_32BIT
(
context
->
SegCs
));
instr
=
make_ptr
(
context
,
context
->
SegCs
,
context
->
Eip
,
TRUE
);
if
(
!
instr
)
return
ret
;
if
(
!
instr
)
return
ExceptionContinueSearch
;
/* First handle any possible prefix */
...
...
@@ -476,7 +476,7 @@ DWORD INSTR_EmulateInstruction( CONTEXT86 *context )
}
add_stack
(
context
,
long_op
?
4
:
2
);
context
->
Eip
+=
prefixlen
+
1
;
return
0
;
return
ExceptionContinueExecution
;
}
}
break
;
/* Unable to emulate it */
...
...
@@ -491,7 +491,7 @@ DWORD INSTR_EmulateInstruction( CONTEXT86 *context )
ERR
(
"mov eax,cr0 at 0x%08lx, EAX=0x%08lx
\n
"
,
context
->
Eip
,
context
->
Eax
);
context
->
Eip
+=
prefixlen
+
3
;
return
0
;
return
ExceptionContinueExecution
;
default:
break
;
/*fallthrough to bad instruction handling */
}
...
...
@@ -514,12 +514,12 @@ DWORD INSTR_EmulateInstruction( CONTEXT86 *context )
ERR
(
"mov cr4,eax at 0x%08lx
\n
"
,
context
->
Eip
);
context
->
Eax
=
0
;
context
->
Eip
+=
prefixlen
+
3
;
return
0
;
return
ExceptionContinueExecution
;
case
0xc0
:
/* mov cr0, eax */
ERR
(
"mov cr0,eax at 0x%08lx
\n
"
,
context
->
Eip
);
context
->
Eax
=
0x10
;
/* FIXME: set more bits ? */
context
->
Eip
+=
prefixlen
+
3
;
return
0
;
return
ExceptionContinueExecution
;
default:
/* fallthrough to illegal instruction */
break
;
}
...
...
@@ -533,7 +533,7 @@ DWORD INSTR_EmulateInstruction( CONTEXT86 *context )
context
->
SegFs
=
seg
;
add_stack
(
context
,
long_op
?
4
:
2
);
context
->
Eip
+=
prefixlen
+
2
;
return
0
;
return
ExceptionContinueExecution
;
}
}
break
;
...
...
@@ -545,7 +545,7 @@ DWORD INSTR_EmulateInstruction( CONTEXT86 *context )
context
->
SegGs
=
seg
;
add_stack
(
context
,
long_op
?
4
:
2
);
context
->
Eip
+=
prefixlen
+
2
;
return
0
;
return
ExceptionContinueExecution
;
}
}
break
;
...
...
@@ -556,7 +556,7 @@ DWORD INSTR_EmulateInstruction( CONTEXT86 *context )
long_addr
,
segprefix
,
&
len
))
{
context
->
Eip
+=
prefixlen
+
len
;
return
0
;
return
ExceptionContinueExecution
;
}
break
;
}
...
...
@@ -629,7 +629,7 @@ DWORD INSTR_EmulateInstruction( CONTEXT86 *context )
}
context
->
Eip
+=
prefixlen
+
1
;
}
return
0
;
return
ExceptionContinueExecution
;
case
0x8e
:
/* mov XX,segment_reg */
{
...
...
@@ -647,25 +647,25 @@ DWORD INSTR_EmulateInstruction( CONTEXT86 *context )
case
0
:
context
->
SegEs
=
seg
;
context
->
Eip
+=
prefixlen
+
len
+
1
;
return
0
;
return
ExceptionContinueExecution
;
case
1
:
/* cs */
break
;
case
2
:
context
->
SegSs
=
seg
;
context
->
Eip
+=
prefixlen
+
len
+
1
;
return
0
;
return
ExceptionContinueExecution
;
case
3
:
context
->
SegDs
=
seg
;
context
->
Eip
+=
prefixlen
+
len
+
1
;
return
0
;
return
ExceptionContinueExecution
;
case
4
:
context
->
SegFs
=
seg
;
context
->
Eip
+=
prefixlen
+
len
+
1
;
return
0
;
return
ExceptionContinueExecution
;
case
5
:
context
->
SegGs
=
seg
;
context
->
Eip
+=
prefixlen
+
len
+
1
;
return
0
;
return
ExceptionContinueExecution
;
case
6
:
/* unused */
case
7
:
/* unused */
break
;
...
...
@@ -679,7 +679,7 @@ DWORD INSTR_EmulateInstruction( CONTEXT86 *context )
long_addr
,
segprefix
,
&
len
))
{
context
->
Eip
+=
prefixlen
+
len
;
return
0
;
return
ExceptionContinueExecution
;
}
break
;
/* Unable to emulate it */
...
...
@@ -692,7 +692,7 @@ DWORD INSTR_EmulateInstruction( CONTEXT86 *context )
{
context
->
Eip
+=
prefixlen
+
2
;
Dosvm
.
EmulateInterruptPM
(
context
,
instr
[
1
]
);
return
0
;
return
ExceptionContinueExecution
;
}
break
;
/* Unable to emulate it */
...
...
@@ -713,12 +713,12 @@ DWORD INSTR_EmulateInstruction( CONTEXT86 *context )
SET_LOWORD
(
context
->
EFlags
,
*
stack
);
add_stack
(
context
,
3
*
sizeof
(
WORD
));
/* Pop the return address and flags */
}
return
0
;
return
ExceptionContinueExecution
;
case
0xe4
:
/* inb al,XX */
SET_LOBYTE
(
context
->
Eax
,
INSTR_inport
(
instr
[
1
],
1
,
context
));
context
->
Eip
+=
prefixlen
+
2
;
return
0
;
return
ExceptionContinueExecution
;
case
0xe5
:
/* in (e)ax,XX */
if
(
long_op
)
...
...
@@ -726,12 +726,12 @@ DWORD INSTR_EmulateInstruction( CONTEXT86 *context )
else
SET_LOWORD
(
context
->
Eax
,
INSTR_inport
(
instr
[
1
],
2
,
context
));
context
->
Eip
+=
prefixlen
+
2
;
return
0
;
return
ExceptionContinueExecution
;
case
0xe6
:
/* outb XX,al */
INSTR_outport
(
instr
[
1
],
1
,
LOBYTE
(
context
->
Eax
),
context
);
context
->
Eip
+=
prefixlen
+
2
;
return
0
;
return
ExceptionContinueExecution
;
case
0xe7
:
/* out XX,(e)ax */
if
(
long_op
)
...
...
@@ -739,12 +739,12 @@ DWORD INSTR_EmulateInstruction( CONTEXT86 *context )
else
INSTR_outport
(
instr
[
1
],
2
,
LOWORD
(
context
->
Eax
),
context
);
context
->
Eip
+=
prefixlen
+
2
;
return
0
;
return
ExceptionContinueExecution
;
case
0xec
:
/* inb al,dx */
SET_LOBYTE
(
context
->
Eax
,
INSTR_inport
(
LOWORD
(
context
->
Edx
),
1
,
context
)
);
context
->
Eip
+=
prefixlen
+
1
;
return
0
;
return
ExceptionContinueExecution
;
case
0xed
:
/* in (e)ax,dx */
if
(
long_op
)
...
...
@@ -752,12 +752,12 @@ DWORD INSTR_EmulateInstruction( CONTEXT86 *context )
else
SET_LOWORD
(
context
->
Eax
,
INSTR_inport
(
LOWORD
(
context
->
Edx
),
2
,
context
));
context
->
Eip
+=
prefixlen
+
1
;
return
0
;
return
ExceptionContinueExecution
;
case
0xee
:
/* outb dx,al */
INSTR_outport
(
LOWORD
(
context
->
Edx
),
1
,
LOBYTE
(
context
->
Eax
),
context
);
context
->
Eip
+=
prefixlen
+
1
;
return
0
;
return
ExceptionContinueExecution
;
case
0xef
:
/* out dx,(e)ax */
if
(
long_op
)
...
...
@@ -765,12 +765,12 @@ DWORD INSTR_EmulateInstruction( CONTEXT86 *context )
else
INSTR_outport
(
LOWORD
(
context
->
Edx
),
2
,
LOWORD
(
context
->
Eax
),
context
);
context
->
Eip
+=
prefixlen
+
1
;
return
0
;
return
ExceptionContinueExecution
;
case
0xfa
:
/* cli */
NtCurrentTeb
()
->
dpmi_vif
=
0
;
context
->
Eip
+=
prefixlen
+
1
;
return
0
;
return
ExceptionContinueExecution
;
case
0xfb
:
/* sti */
NtCurrentTeb
()
->
dpmi_vif
=
1
;
...
...
@@ -778,11 +778,12 @@ DWORD INSTR_EmulateInstruction( CONTEXT86 *context )
if
(
NtCurrentTeb
()
->
vm86_pending
)
{
NtCurrentTeb
()
->
vm86_pending
=
0
;
return
EXCEPTION_VM86_STI
;
rec
->
ExceptionCode
=
EXCEPTION_VM86_STI
;
return
ExceptionContinueSearch
;
}
return
0
;
return
ExceptionContinueExecution
;
}
return
ret
;
/* Unable to emulate it */
return
ExceptionContinueSearch
;
/* Unable to emulate it */
}
#endif
/* __i386__ */
dlls/kernel/wowthunk.c
View file @
add0c585
...
...
@@ -180,8 +180,9 @@ static DWORD call16_handler( EXCEPTION_RECORD *record, EXCEPTION_REGISTRATION_RE
else
{
SEGPTR
gpHandler
;
DWORD
ret
=
INSTR_EmulateInstruction
(
record
,
context
);
if
(
!
INSTR_EmulateInstruction
(
context
))
return
ExceptionContinueExecution
;
if
(
ret
!=
ExceptionContinueSearch
)
return
ret
;
/* check for Win16 __GP handler */
if
((
gpHandler
=
HasGPHandler16
(
MAKESEGPTR
(
context
->
SegCs
,
context
->
Eip
)
)))
...
...
@@ -205,6 +206,28 @@ static DWORD call16_handler( EXCEPTION_RECORD *record, EXCEPTION_REGISTRATION_RE
return
ExceptionContinueSearch
;
}
/*************************************************************
* vm86_handler
*
* Handler for exceptions occurring in vm86 code.
*/
static
DWORD
vm86_handler
(
EXCEPTION_RECORD
*
record
,
EXCEPTION_REGISTRATION_RECORD
*
frame
,
CONTEXT
*
context
,
EXCEPTION_REGISTRATION_RECORD
**
pdispatcher
)
{
if
(
record
->
ExceptionFlags
&
(
EH_UNWINDING
|
EH_EXIT_UNWIND
))
return
ExceptionContinueSearch
;
if
(
record
->
ExceptionCode
==
EXCEPTION_ACCESS_VIOLATION
||
record
->
ExceptionCode
==
EXCEPTION_PRIV_INSTRUCTION
)
{
return
INSTR_EmulateInstruction
(
record
,
context
);
}
return
ExceptionContinueSearch
;
}
#else
/* __i386__ */
BOOL
WOWTHUNK_Init
(
void
)
...
...
@@ -470,6 +493,16 @@ BOOL WINAPI K32WOWCallback16Ex( DWORD vpfn16, DWORD dwFlags,
SYSLEVEL_CheckNotLevel
(
2
);
}
if
(
ISV86
(
context
))
{
EXCEPTION_REGISTRATION_RECORD
frame
;
frame
.
Handler
=
vm86_handler
;
__wine_push_frame
(
&
frame
);
__wine_enter_vm86
(
context
);
__wine_pop_frame
(
&
frame
);
}
else
{
/* push return address */
if
(
dwFlags
&
WCB16_REGS_LONG
)
{
...
...
@@ -486,6 +519,7 @@ BOOL WINAPI K32WOWCallback16Ex( DWORD vpfn16, DWORD dwFlags,
_EnterWin16Lock
();
wine_call_to_16_regs
(
context
,
cbArgs
,
call16_handler
);
_LeaveWin16Lock
();
}
if
(
TRACE_ON
(
relay
))
{
...
...
dlls/winedos/dosvm.c
View file @
add0c585
...
...
@@ -43,6 +43,7 @@
#include "winbase.h"
#include "wingdi.h"
#include "winuser.h"
#include "wownt32.h"
#include "winnt.h"
#include "wincon.h"
...
...
@@ -583,7 +584,7 @@ int WINAPI DOSVM_Enter( CONTEXT86 *context )
__TRY
{
__wine_enter_vm86
(
context
);
WOWCallback16Ex
(
0
,
WCB16_REGS
,
0
,
NULL
,
(
DWORD
*
)
context
);
TRACE_
(
module
)(
"vm86 returned: %s
\n
"
,
strerror
(
errno
)
);
}
__EXCEPT
(
exception_handler
)
...
...
include/miscemu.h
View file @
add0c585
...
...
@@ -105,7 +105,7 @@ extern LPVOID DOSMEM_MapDosToLinear(UINT); /* linear DOS to Wine */
extern
UINT
DOSMEM_MapLinearToDos
(
LPVOID
);
/* linear Wine to DOS */
/* memory/instr.c */
extern
DWORD
INSTR_EmulateInstruction
(
CONTEXT86
*
context
);
extern
DWORD
INSTR_EmulateInstruction
(
EXCEPTION_RECORD
*
rec
,
CONTEXT86
*
context
);
/* msdos/ioports.c */
extern
DWORD
IO_inport
(
int
port
,
int
count
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment