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
b59627c8
Commit
b59627c8
authored
Sep 24, 2000
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Added support for exception handling while in vm86 mode.
Fixed a couple of bugs in vm86 support.
parent
1b490b42
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
122 additions
and
69 deletions
+122
-69
signal_i386.c
dlls/ntdll/signal_i386.c
+113
-68
signal_sparc.c
dlls/ntdll/signal_sparc.c
+8
-0
exception.h
include/wine/exception.h
+1
-1
No files found.
dlls/ntdll/signal_i386.c
View file @
b59627c8
...
@@ -29,6 +29,7 @@
...
@@ -29,6 +29,7 @@
# include <sys/vm86.h>
# include <sys/vm86.h>
#endif
#endif
#include "winnt.h"
#include "selectors.h"
#include "selectors.h"
/***********************************************************************
/***********************************************************************
...
@@ -108,21 +109,26 @@ static inline int wine_sigaltstack( const struct sigaltstack *new,
...
@@ -108,21 +109,26 @@ static inline int wine_sigaltstack( const struct sigaltstack *new,
}
}
#endif
#endif
static
inline
int
wine_vm86plus
(
int
func
,
struct
vm86plus_struct
*
ptr
)
int
vm86_enter
(
struct
vm86plus_struct
*
ptr
);
{
void
vm86_return
();
int
res
;
__ASM_GLOBAL_FUNC
(
vm86_enter
,
__asm__
__volatile__
(
"pushl %%fs
\n\t
"
"pushl %ebp
\n\t
"
"pushl %%ebx
\n\t
"
"movl %esp, %ebp
\n\t
"
"movl %2,%%ebx
\n\t
"
"movl $166,%eax
\n\t
"
/*SYS_vm86*/
"int $0x80
\n\t
"
"pushl %fs
\n\t
"
"popl %%ebx
\n\t
"
"movl 8(%ebp),%ecx
\n\t
"
"popl %%fs"
"pushl %ebx
\n\t
"
:
"=a"
(
res
)
"movl $1,%ebx
\n\t
"
/*VM86_ENTER*/
:
"0"
(
166
/*SYS_vm86*/
),
"g"
(
func
),
"c"
(
ptr
)
);
"pushl %ecx
\n\t
"
/* put vm86plus_struct ptr somewhere we can find it */
if
(
res
>=
0
)
return
res
;
"int $0x80
\n
"
errno
=
-
res
;
".globl "
__ASM_NAME
(
"vm86_return"
)
"
\n\t
"
return
-
1
;
".type "
__ASM_NAME
(
"vm86_return"
)
",@function
\n
"
}
__ASM_NAME
(
"vm86_return"
)
":
\n\t
"
"popl %ecx
\n\t
"
"popl %ebx
\n\t
"
"popl %fs
\n\t
"
"popl %ebp
\n\t
"
"ret"
);
#endif
/* linux */
#endif
/* linux */
...
@@ -331,35 +337,10 @@ typedef struct
...
@@ -331,35 +337,10 @@ typedef struct
#include "syslevel.h"
#include "syslevel.h"
#include "debugtools.h"
#include "debugtools.h"
DEFAULT_DEBUG_CHANNEL
(
seh
)
DEFAULT_DEBUG_CHANNEL
(
seh
);
/***********************************************************************
/***********************************************************************
* handler_init
*
* Initialization code for a signal handler.
* Restores the proper %fs value for the current thread.
*/
static
inline
void
handler_init
(
CONTEXT
*
context
,
const
SIGCONTEXT
*
sigcontext
)
{
WORD
fs
;
/* get %fs at time of the fault */
#ifdef FS_sig
fs
=
FS_sig
(
sigcontext
);
#else
fs
=
__get_fs
();
#endif
context
->
SegFs
=
fs
;
/* now restore a proper %fs for the fault handler */
if
((
EFL_sig
(
sigcontext
)
&
0x00020000
)
||
/* vm86 mode */
!
IS_SELECTOR_SYSTEM
(
CS_sig
(
sigcontext
)))
/* 16-bit mode */
fs
=
SYSLEVEL_Win16CurrentTeb
;
if
(
!
fs
)
fs
=
SYSLEVEL_EmergencyTeb
;
__set_fs
(
fs
);
}
/***********************************************************************
* get_trap_code
* get_trap_code
*
*
* Get the trap code for a signal.
* Get the trap code for a signal.
...
@@ -408,6 +389,57 @@ static inline void *get_cr2_value( const SIGCONTEXT *sigcontext )
...
@@ -408,6 +389,57 @@ static inline void *get_cr2_value( const SIGCONTEXT *sigcontext )
*/
*/
static
void
save_context
(
CONTEXT
*
context
,
const
SIGCONTEXT
*
sigcontext
)
static
void
save_context
(
CONTEXT
*
context
,
const
SIGCONTEXT
*
sigcontext
)
{
{
WORD
fs
;
/* get %fs at time of the fault */
#ifdef FS_sig
fs
=
FS_sig
(
sigcontext
);
#else
fs
=
__get_fs
();
#endif
context
->
SegFs
=
fs
;
/* now restore a proper %fs for the fault handler */
if
(
!
IS_SELECTOR_SYSTEM
(
CS_sig
(
sigcontext
)))
/* 16-bit mode */
{
fs
=
SYSLEVEL_Win16CurrentTeb
;
}
#ifdef linux
else
if
((
void
*
)
EIP_sig
(
sigcontext
)
==
vm86_return
)
/* vm86 mode */
{
/* retrieve pointer to vm86plus struct that was stored in vm86_enter */
struct
vm86plus_struct
*
vm86
=
*
(
struct
vm86plus_struct
**
)
ESP_sig
(
sigcontext
);
/* fetch the saved %fs on the stack */
fs
=
*
((
unsigned
int
*
)
ESP_sig
(
sigcontext
)
+
2
);
__set_fs
(
fs
);
/* get context from vm86 struct */
context
->
Eax
=
vm86
->
regs
.
eax
;
context
->
Ebx
=
vm86
->
regs
.
ebx
;
context
->
Ecx
=
vm86
->
regs
.
ecx
;
context
->
Edx
=
vm86
->
regs
.
edx
;
context
->
Esi
=
vm86
->
regs
.
esi
;
context
->
Edi
=
vm86
->
regs
.
edi
;
context
->
Esp
=
vm86
->
regs
.
esp
;
context
->
Ebp
=
vm86
->
regs
.
ebp
;
context
->
Eip
=
vm86
->
regs
.
eip
;
context
->
SegCs
=
vm86
->
regs
.
cs
;
context
->
SegDs
=
vm86
->
regs
.
ds
;
context
->
SegEs
=
vm86
->
regs
.
es
;
context
->
SegFs
=
vm86
->
regs
.
fs
;
context
->
SegGs
=
vm86
->
regs
.
gs
;
context
->
SegSs
=
vm86
->
regs
.
ss
;
context
->
EFlags
=
vm86
->
regs
.
eflags
;
return
;
}
#endif
/* linux */
if
(
!
fs
)
{
fs
=
SYSLEVEL_EmergencyTeb
;
__set_fs
(
fs
);
ERR
(
"fallback to emergency TEB
\n
"
);
}
__set_fs
(
fs
);
context
->
Eax
=
EAX_sig
(
sigcontext
);
context
->
Eax
=
EAX_sig
(
sigcontext
);
context
->
Ebx
=
EBX_sig
(
sigcontext
);
context
->
Ebx
=
EBX_sig
(
sigcontext
);
context
->
Ecx
=
ECX_sig
(
sigcontext
);
context
->
Ecx
=
ECX_sig
(
sigcontext
);
...
@@ -422,7 +454,6 @@ static void save_context( CONTEXT *context, const SIGCONTEXT *sigcontext )
...
@@ -422,7 +454,6 @@ static void save_context( CONTEXT *context, const SIGCONTEXT *sigcontext )
context
->
SegDs
=
LOWORD
(
DS_sig
(
sigcontext
));
context
->
SegDs
=
LOWORD
(
DS_sig
(
sigcontext
));
context
->
SegEs
=
LOWORD
(
ES_sig
(
sigcontext
));
context
->
SegEs
=
LOWORD
(
ES_sig
(
sigcontext
));
context
->
SegSs
=
LOWORD
(
SS_sig
(
sigcontext
));
context
->
SegSs
=
LOWORD
(
SS_sig
(
sigcontext
));
/* %fs already handled in handler_init */
#ifdef GS_sig
#ifdef GS_sig
context
->
SegGs
=
LOWORD
(
GS_sig
(
sigcontext
));
context
->
SegGs
=
LOWORD
(
GS_sig
(
sigcontext
));
#else
#else
...
@@ -438,6 +469,33 @@ static void save_context( CONTEXT *context, const SIGCONTEXT *sigcontext )
...
@@ -438,6 +469,33 @@ static void save_context( CONTEXT *context, const SIGCONTEXT *sigcontext )
*/
*/
static
void
restore_context
(
const
CONTEXT
*
context
,
SIGCONTEXT
*
sigcontext
)
static
void
restore_context
(
const
CONTEXT
*
context
,
SIGCONTEXT
*
sigcontext
)
{
{
#ifdef linux
/* check if exception occurred in vm86 mode */
if
((
void
*
)
EIP_sig
(
sigcontext
)
==
vm86_return
&&
IS_SELECTOR_SYSTEM
(
CS_sig
(
sigcontext
)))
{
/* retrieve pointer to vm86plus struct that was stored in vm86_enter */
struct
vm86plus_struct
*
vm86
=
*
(
struct
vm86plus_struct
**
)
ESP_sig
(
sigcontext
);
vm86
->
regs
.
eax
=
context
->
Eax
;
vm86
->
regs
.
ebx
=
context
->
Ebx
;
vm86
->
regs
.
ecx
=
context
->
Ecx
;
vm86
->
regs
.
edx
=
context
->
Edx
;
vm86
->
regs
.
esi
=
context
->
Esi
;
vm86
->
regs
.
edi
=
context
->
Edi
;
vm86
->
regs
.
esp
=
context
->
Esp
;
vm86
->
regs
.
ebp
=
context
->
Ebp
;
vm86
->
regs
.
eip
=
context
->
Eip
;
vm86
->
regs
.
cs
=
context
->
SegCs
;
vm86
->
regs
.
ds
=
context
->
SegDs
;
vm86
->
regs
.
es
=
context
->
SegEs
;
vm86
->
regs
.
fs
=
context
->
SegFs
;
vm86
->
regs
.
gs
=
context
->
SegGs
;
vm86
->
regs
.
ss
=
context
->
SegSs
;
vm86
->
regs
.
eflags
=
context
->
EFlags
;
return
;
}
#endif
/* linux */
EAX_sig
(
sigcontext
)
=
context
->
Eax
;
EAX_sig
(
sigcontext
)
=
context
->
Eax
;
EBX_sig
(
sigcontext
)
=
context
->
Ebx
;
EBX_sig
(
sigcontext
)
=
context
->
Ebx
;
ECX_sig
(
sigcontext
)
=
context
->
Ecx
;
ECX_sig
(
sigcontext
)
=
context
->
Ecx
;
...
@@ -685,7 +743,6 @@ static void do_fpe( CONTEXT *context, int trap_code )
...
@@ -685,7 +743,6 @@ static void do_fpe( CONTEXT *context, int trap_code )
static
HANDLER_DEF
(
segv_handler
)
static
HANDLER_DEF
(
segv_handler
)
{
{
CONTEXT
context
;
CONTEXT
context
;
handler_init
(
&
context
,
HANDLER_CONTEXT
);
save_context
(
&
context
,
HANDLER_CONTEXT
);
save_context
(
&
context
,
HANDLER_CONTEXT
);
do_segv
(
&
context
,
get_trap_code
(
HANDLER_CONTEXT
),
do_segv
(
&
context
,
get_trap_code
(
HANDLER_CONTEXT
),
get_cr2_value
(
HANDLER_CONTEXT
),
get_error_code
(
HANDLER_CONTEXT
)
);
get_cr2_value
(
HANDLER_CONTEXT
),
get_error_code
(
HANDLER_CONTEXT
)
);
...
@@ -701,7 +758,6 @@ static HANDLER_DEF(segv_handler)
...
@@ -701,7 +758,6 @@ static HANDLER_DEF(segv_handler)
static
HANDLER_DEF
(
trap_handler
)
static
HANDLER_DEF
(
trap_handler
)
{
{
CONTEXT
context
;
CONTEXT
context
;
handler_init
(
&
context
,
HANDLER_CONTEXT
);
save_context
(
&
context
,
HANDLER_CONTEXT
);
save_context
(
&
context
,
HANDLER_CONTEXT
);
do_trap
(
&
context
,
get_trap_code
(
HANDLER_CONTEXT
)
);
do_trap
(
&
context
,
get_trap_code
(
HANDLER_CONTEXT
)
);
restore_context
(
&
context
,
HANDLER_CONTEXT
);
restore_context
(
&
context
,
HANDLER_CONTEXT
);
...
@@ -716,7 +772,6 @@ static HANDLER_DEF(trap_handler)
...
@@ -716,7 +772,6 @@ static HANDLER_DEF(trap_handler)
static
HANDLER_DEF
(
fpe_handler
)
static
HANDLER_DEF
(
fpe_handler
)
{
{
CONTEXT
context
;
CONTEXT
context
;
handler_init
(
&
context
,
HANDLER_CONTEXT
);
save_fpu
(
&
context
,
HANDLER_CONTEXT
);
save_fpu
(
&
context
,
HANDLER_CONTEXT
);
save_context
(
&
context
,
HANDLER_CONTEXT
);
save_context
(
&
context
,
HANDLER_CONTEXT
);
do_fpe
(
&
context
,
get_trap_code
(
HANDLER_CONTEXT
)
);
do_fpe
(
&
context
,
get_trap_code
(
HANDLER_CONTEXT
)
);
...
@@ -735,7 +790,6 @@ static HANDLER_DEF(int_handler)
...
@@ -735,7 +790,6 @@ static HANDLER_DEF(int_handler)
EXCEPTION_RECORD
rec
;
EXCEPTION_RECORD
rec
;
CONTEXT
context
;
CONTEXT
context
;
handler_init
(
&
context
,
HANDLER_CONTEXT
);
save_context
(
&
context
,
HANDLER_CONTEXT
);
save_context
(
&
context
,
HANDLER_CONTEXT
);
rec
.
ExceptionCode
=
CONTROL_C_EXIT
;
rec
.
ExceptionCode
=
CONTROL_C_EXIT
;
rec
.
ExceptionFlags
=
EXCEPTION_CONTINUABLE
;
rec
.
ExceptionFlags
=
EXCEPTION_CONTINUABLE
;
...
@@ -842,6 +896,7 @@ void __wine_enter_vm86( CONTEXT *context )
...
@@ -842,6 +896,7 @@ void __wine_enter_vm86( CONTEXT *context )
int
res
;
int
res
;
struct
vm86plus_struct
vm86
;
struct
vm86plus_struct
vm86
;
memset
(
&
vm86
,
0
,
sizeof
(
vm86
)
);
for
(;;)
for
(;;)
{
{
vm86
.
regs
.
eax
=
context
->
Eax
;
vm86
.
regs
.
eax
=
context
->
Eax
;
...
@@ -858,10 +913,18 @@ void __wine_enter_vm86( CONTEXT *context )
...
@@ -858,10 +913,18 @@ void __wine_enter_vm86( CONTEXT *context )
vm86
.
regs
.
es
=
context
->
SegEs
;
vm86
.
regs
.
es
=
context
->
SegEs
;
vm86
.
regs
.
fs
=
context
->
SegFs
;
vm86
.
regs
.
fs
=
context
->
SegFs
;
vm86
.
regs
.
gs
=
context
->
SegGs
;
vm86
.
regs
.
gs
=
context
->
SegGs
;
vm86
.
regs
.
ss
=
context
->
SegSs
;
vm86
.
regs
.
eflags
=
context
->
EFlags
;
vm86
.
regs
.
eflags
=
context
->
EFlags
;
if
(
vm86
.
regs
.
eflags
&
IF_MASK
)
vm86
.
regs
.
eflags
|=
VIF_MASK
;
res
=
wine_vm86plus
(
VM86_ENTER
,
&
vm86
);
do
{
res
=
vm86_enter
(
&
vm86
);
if
(
res
<
0
)
{
errno
=
-
res
;
return
;
}
}
while
(
VM86_TYPE
(
res
)
==
VM86_SIGNAL
);
context
->
Eax
=
vm86
.
regs
.
eax
;
context
->
Eax
=
vm86
.
regs
.
eax
;
context
->
Ebx
=
vm86
.
regs
.
ebx
;
context
->
Ebx
=
vm86
.
regs
.
ebx
;
...
@@ -877,34 +940,16 @@ void __wine_enter_vm86( CONTEXT *context )
...
@@ -877,34 +940,16 @@ void __wine_enter_vm86( CONTEXT *context )
context
->
SegEs
=
vm86
.
regs
.
es
;
context
->
SegEs
=
vm86
.
regs
.
es
;
context
->
SegFs
=
vm86
.
regs
.
fs
;
context
->
SegFs
=
vm86
.
regs
.
fs
;
context
->
SegGs
=
vm86
.
regs
.
gs
;
context
->
SegGs
=
vm86
.
regs
.
gs
;
context
->
SegSs
=
vm86
.
regs
.
ss
;
context
->
EFlags
=
vm86
.
regs
.
eflags
;
context
->
EFlags
=
vm86
.
regs
.
eflags
;
switch
(
VM86_TYPE
(
res
))
switch
(
VM86_TYPE
(
res
))
{
{
case
VM86_SIGNAL
:
/* return due to signal */
switch
(
VM86_ARG
(
res
))
{
case
SIGILL
:
case
SIGSEGV
:
#ifdef SIGBUS
case
SIGBUS
:
#endif
do_segv
(
context
,
T_UNKNOWN
,
0
,
0
);
continue
;
case
SIGTRAP
:
do_trap
(
context
,
T_UNKNOWN
);
continue
;
case
SIGFPE
:
do_fpe
(
context
,
T_UNKNOWN
);
continue
;
}
rec
.
ExceptionCode
=
EXCEPTION_VM86_SIGNAL
;
break
;
case
VM86_UNKNOWN
:
/* unhandled GP fault - IO-instruction or similar */
case
VM86_UNKNOWN
:
/* unhandled GP fault - IO-instruction or similar */
do_segv
(
context
,
T_PROTFLT
,
0
,
0
);
do_segv
(
context
,
T_PROTFLT
,
0
,
0
);
continue
;
continue
;
case
VM86_TRAP
:
/* return due to DOS-debugger request */
case
VM86_TRAP
:
/* return due to DOS-debugger request */
do_trap
(
context
,
T_UNKNOWN
);
do_trap
(
context
,
VM86_ARG
(
res
)
);
continue
;
continue
;
case
VM86_INTx
:
/* int3/int x instruction (ARG = x) */
case
VM86_INTx
:
/* int3/int x instruction (ARG = x) */
rec
.
ExceptionCode
=
EXCEPTION_VM86_INTx
;
rec
.
ExceptionCode
=
EXCEPTION_VM86_INTx
;
...
...
dlls/ntdll/signal_sparc.c
View file @
b59627c8
...
@@ -349,6 +349,14 @@ BOOL SIGNAL_Init(void)
...
@@ -349,6 +349,14 @@ BOOL SIGNAL_Init(void)
}
}
/**********************************************************************
/**********************************************************************
* __wine_enter_vm86
*/
void
__wine_enter_vm86
(
CONTEXT
*
context
)
{
MESSAGE
(
"vm86 mode not supported on this platform
\n
"
);
}
/**********************************************************************
* DbgBreakPoint (NTDLL)
* DbgBreakPoint (NTDLL)
*/
*/
void
WINAPI
DbgBreakPoint
(
void
)
void
WINAPI
DbgBreakPoint
(
void
)
...
...
include/wine/exception.h
View file @
b59627c8
...
@@ -169,11 +169,11 @@ static inline EXCEPTION_FRAME * WINE_UNUSED __wine_pop_frame( EXCEPTION_FRAME *f
...
@@ -169,11 +169,11 @@ static inline EXCEPTION_FRAME * WINE_UNUSED __wine_pop_frame( EXCEPTION_FRAME *f
/* Wine-specific exceptions codes */
/* Wine-specific exceptions codes */
/* unhandled return status from vm86 mode */
/* unhandled return status from vm86 mode */
#define EXCEPTION_VM86_SIGNAL 0x80000100
#define EXCEPTION_VM86_INTx 0x80000101
#define EXCEPTION_VM86_INTx 0x80000101
#define EXCEPTION_VM86_STI 0x80000102
#define EXCEPTION_VM86_STI 0x80000102
#define EXCEPTION_VM86_PICRETURN 0x80000103
#define EXCEPTION_VM86_PICRETURN 0x80000103
extern
void
__wine_enter_vm86
(
CONTEXT
*
context
);
#ifdef __WINE__
#ifdef __WINE__
extern
void
WINAPI
EXC_RtlRaiseException
(
PEXCEPTION_RECORD
,
PCONTEXT
);
extern
void
WINAPI
EXC_RtlRaiseException
(
PEXCEPTION_RECORD
,
PCONTEXT
);
...
...
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