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
58a00854
Commit
58a00854
authored
Nov 30, 2023
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ntdll: Fix stack layout for KiUserExceptionDispatcher on i386.
parent
b5cd47f5
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
91 additions
and
57 deletions
+91
-57
exception.c
dlls/ntdll/tests/exception.c
+14
-7
signal_i386.c
dlls/ntdll/unix/signal_i386.c
+49
-33
struct32.h
dlls/wow64/struct32.h
+7
-0
syscall.c
dlls/wow64/syscall.c
+21
-17
No files found.
dlls/ntdll/tests/exception.c
View file @
58a00854
...
...
@@ -1908,15 +1908,22 @@ static LONG WINAPI dbg_except_continue_vectored_handler(struct _EXCEPTION_POINTE
/* Use CDECL to leave arguments on stack. */
static
void
*
CDECL
hook_KiUserExceptionDispatcher
(
EXCEPTION_RECORD
*
rec
,
CONTEXT
*
context
)
{
trace
(
"rec %p, context %p.
\n
"
,
rec
,
context
);
trace
(
"context->Eip %#lx, context->Esp %#lx, ContextFlags %#lx.
\n
"
,
context
->
Eip
,
context
->
Esp
,
context
->
ContextFlags
);
CONTEXT_EX
*
xctx
=
(
CONTEXT_EX
*
)(
context
+
1
);
hook_called
=
TRUE
;
/* Broken on Win2008, probably rec offset in stack is different. */
ok
(
rec
->
ExceptionCode
==
0x80000003
||
broken
(
!
rec
->
ExceptionCode
),
"Got unexpected ExceptionCode %#lx.
\n
"
,
rec
->
ExceptionCode
);
trace
(
"rec %p context %p context->Eip %#lx, context->Esp %#lx (%x), ContextFlags %#lx.
\n
"
,
rec
,
context
,
context
->
Eip
,
context
->
Esp
,
(
char
*
)
context
->
Esp
-
(
char
*
)
&
rec
,
context
->
ContextFlags
);
trace
(
"xstate %lx = %p (%x) %lx
\n
"
,
xctx
->
XState
.
Offset
,
(
char
*
)
xctx
+
xctx
->
XState
.
Offset
,
(
char
*
)
xctx
+
xctx
->
XState
.
Offset
-
(
char
*
)
&
rec
,
xctx
->
XState
.
Length
);
ok
(
(
char
*
)
rec
->
ExceptionInformation
<=
(
char
*
)
context
&&
(
char
*
)(
rec
+
1
)
>=
(
char
*
)
context
,
"wrong ptrs %p / %p
\n
"
,
rec
,
context
);
ok
(
xctx
->
All
.
Offset
==
-
sizeof
(
CONTEXT
),
"wrong All.Offset %lx
\n
"
,
xctx
->
All
.
Offset
);
ok
(
xctx
->
All
.
Length
>=
sizeof
(
CONTEXT
)
+
sizeof
(
CONTEXT_EX
),
"wrong All.Length %lx
\n
"
,
xctx
->
All
.
Length
);
ok
(
xctx
->
Legacy
.
Offset
==
-
sizeof
(
CONTEXT
),
"wrong Legacy.Offset %lx
\n
"
,
xctx
->
All
.
Offset
);
ok
(
xctx
->
Legacy
.
Length
==
sizeof
(
CONTEXT
),
"wrong Legacy.Length %lx
\n
"
,
xctx
->
All
.
Length
);
hook_called
=
TRUE
;
hook_KiUserExceptionDispatcher_eip
=
(
void
*
)
context
->
Eip
;
hook_exception_address
=
rec
->
ExceptionAddress
;
memcpy
(
pKiUserExceptionDispatcher
,
saved_KiUserExceptionDispatcher_bytes
,
...
...
dlls/ntdll/unix/signal_i386.c
View file @
58a00854
...
...
@@ -435,6 +435,21 @@ enum i386_trap_code
#endif
};
/* stack layout when calling KiUserExceptionDispatcher */
struct
exc_stack_layout
{
EXCEPTION_RECORD
*
rec_ptr
;
/* 000 first arg for KiUserExceptionDispatcher */
CONTEXT
*
context_ptr
;
/* 004 second arg for KiUserExceptionDispatcher */
EXCEPTION_RECORD
rec
;
/* 008 */
CONTEXT
context
;
/* 058 */
CONTEXT_EX
context_ex
;
/* 324 */
BYTE
xstate
[
sizeof
(
XSTATE
)
+
64
];
/* 33c extra space to allow for 64-byte alignment */
DWORD
align
;
/* 4bc */
};
C_ASSERT
(
offsetof
(
struct
exc_stack_layout
,
context
)
==
0x58
);
C_ASSERT
(
offsetof
(
struct
exc_stack_layout
,
xstate
)
==
0x33c
);
C_ASSERT
(
sizeof
(
struct
exc_stack_layout
)
==
0x4c0
);
struct
syscall_frame
{
WORD
syscall_flags
;
/* 000 */
...
...
@@ -1417,23 +1432,8 @@ static void setup_raise_exception( ucontext_t *sigcontext, void *stack_ptr,
EXCEPTION_RECORD
*
rec
,
struct
xcontext
*
xcontext
)
{
CONTEXT
*
context
=
&
xcontext
->
c
;
size_t
stack_size
;
XSTATE
*
src_xs
;
struct
stack_layout
{
EXCEPTION_RECORD
*
rec_ptr
;
/* first arg for KiUserExceptionDispatcher */
CONTEXT
*
context_ptr
;
/* second arg for KiUserExceptionDispatcher */
CONTEXT
context
;
CONTEXT_EX
context_ex
;
EXCEPTION_RECORD
rec
;
DWORD
ebp
;
DWORD
eip
;
char
xstate
[
0
];
}
*
stack
;
C_ASSERT
(
(
offsetof
(
struct
stack_layout
,
xstate
)
==
sizeof
(
struct
stack_layout
))
);
struct
exc_stack_layout
*
stack
;
NTSTATUS
status
=
send_debug_event
(
rec
,
context
,
TRUE
);
if
(
status
==
DBG_CONTINUE
||
status
==
DBG_EXCEPTION_HANDLED
)
...
...
@@ -1445,23 +1445,17 @@ C_ASSERT( (offsetof(struct stack_layout, xstate) == sizeof(struct stack_layout))
/* fix up instruction pointer in context for EXCEPTION_BREAKPOINT */
if
(
rec
->
ExceptionCode
==
EXCEPTION_BREAKPOINT
)
context
->
Eip
--
;
stack_size
=
sizeof
(
*
stack
);
if
((
src_xs
=
xstate_from_context
(
context
)))
{
stack_size
+=
(
ULONG_PTR
)
stack_ptr
-
(((
ULONG_PTR
)
stack_ptr
-
sizeof
(
XSTATE
))
&
~
(
ULONG_PTR
)
63
);
}
stack
=
virtual_setup_exception
(
stack_ptr
,
stack_size
,
rec
);
stack
=
virtual_setup_exception
(
stack_ptr
,
sizeof
(
*
stack
),
rec
);
stack
->
rec_ptr
=
&
stack
->
rec
;
stack
->
context_ptr
=
&
stack
->
context
;
stack
->
rec
=
*
rec
;
stack
->
context
=
*
context
;
if
(
src_xs
)
if
(
(
src_xs
=
xstate_from_context
(
context
))
)
{
XSTATE
*
dst_xs
=
(
XSTATE
*
)
stack
->
xstate
;
XSTATE
*
dst_xs
=
(
XSTATE
*
)
(((
ULONG_PTR
)
stack
->
xstate
+
63
)
&
~
63
)
;
assert
(
!
((
ULONG_PTR
)
dst_xs
&
63
));
context_init_xstate
(
&
stack
->
context
,
stack
->
xstate
);
context_init_xstate
(
&
stack
->
context
,
dst_xs
);
memset
(
dst_xs
,
0
,
offsetof
(
XSTATE
,
YmmContext
)
);
dst_xs
->
CompactionMask
=
xstate_compaction_enabled
?
0x8000000000000004
:
0
;
if
(
src_xs
->
Mask
&
4
)
...
...
@@ -1475,8 +1469,6 @@ C_ASSERT( (offsetof(struct stack_layout, xstate) == sizeof(struct stack_layout))
context_init_xstate
(
&
stack
->
context
,
NULL
);
}
stack
->
rec_ptr
=
&
stack
->
rec
;
stack
->
context_ptr
=
&
stack
->
context
;
ESP_sig
(
sigcontext
)
=
(
DWORD
)
stack
;
EIP_sig
(
sigcontext
)
=
(
DWORD
)
pKiUserExceptionDispatcher
;
/* clear single-step, direction, and align check flag */
...
...
@@ -1560,11 +1552,35 @@ void call_raise_user_exception_dispatcher(void)
NTSTATUS
call_user_exception_dispatcher
(
EXCEPTION_RECORD
*
rec
,
CONTEXT
*
context
)
{
struct
syscall_frame
*
frame
=
x86_thread_data
()
->
syscall_frame
;
void
**
stack
=
(
void
**
)
frame
->
esp
;
ULONG
esp
=
(
frame
->
esp
-
sizeof
(
struct
exc_stack_layout
))
&
~
3
;
struct
exc_stack_layout
*
stack
=
(
struct
exc_stack_layout
*
)
esp
;
XSTATE
*
src_xs
;
if
(
rec
->
ExceptionCode
==
EXCEPTION_BREAKPOINT
)
context
->
Eip
--
;
*
(
--
stack
)
=
context
;
*
(
--
stack
)
=
rec
;
stack
->
rec_ptr
=
&
stack
->
rec
;
stack
->
context_ptr
=
&
stack
->
context
;
stack
->
rec
=
*
rec
;
stack
->
context
=
*
context
;
if
((
src_xs
=
xstate_from_context
(
context
)))
{
XSTATE
*
dst_xs
=
(
XSTATE
*
)(((
ULONG_PTR
)
stack
->
xstate
+
63
)
&
~
63
);
context_init_xstate
(
&
stack
->
context
,
dst_xs
);
memset
(
dst_xs
,
0
,
offsetof
(
XSTATE
,
YmmContext
)
);
dst_xs
->
CompactionMask
=
xstate_compaction_enabled
?
0x8000000000000004
:
0
;
if
(
src_xs
->
Mask
&
4
)
{
dst_xs
->
Mask
=
4
;
memcpy
(
&
dst_xs
->
YmmContext
,
&
src_xs
->
YmmContext
,
sizeof
(
dst_xs
->
YmmContext
)
);
}
}
else
{
context_init_xstate
(
&
stack
->
context
,
NULL
);
}
frame
->
esp
=
(
ULONG
)
stack
;
frame
->
eip
=
(
ULONG
)
pKiUserExceptionDispatcher
;
return
STATUS_SUCCESS
;
...
...
dlls/wow64/struct32.h
View file @
58a00854
...
...
@@ -75,6 +75,13 @@ typedef struct
typedef
struct
{
CONTEXT_CHUNK
All
;
CONTEXT_CHUNK
Legacy
;
CONTEXT_CHUNK
XState
;
}
CONTEXT_EX32
;
typedef
struct
{
UNICODE_STRING32
ObjectName
;
UNICODE_STRING32
ObjectTypeName
;
}
DIRECTORY_BASIC_INFORMATION32
;
...
...
dlls/wow64/syscall.c
View file @
58a00854
...
...
@@ -190,16 +190,24 @@ static void call_user_exception_dispatcher( EXCEPTION_RECORD32 *rec, void *ctx32
{
case
IMAGE_FILE_MACHINE_I386
:
{
struct
stack_layout
/* stack layout when calling 32-bit KiUserExceptionDispatcher */
struct
exc_stack_layout32
{
ULONG
rec_ptr
;
/* first arg for KiUserExceptionDispatcher */
ULONG
context_ptr
;
/* second arg for KiUserExceptionDispatcher */
EXCEPTION_RECORD32
rec
;
I386_CONTEXT
context
;
ULONG
rec_ptr
;
/* 000 */
ULONG
context_ptr
;
/* 004 */
EXCEPTION_RECORD32
rec
;
/* 008 */
I386_CONTEXT
context
;
/* 058 */
CONTEXT_EX32
context_ex
;
/* 324 */
BYTE
xstate
[
sizeof
(
XSTATE
)
+
64
];
/* 33c */
DWORD
align
;
/* 4bc */
}
*
stack
;
I386_CONTEXT
*
context
,
ctx
=
{
CONTEXT_I386_ALL
};
I386_CONTEXT
ctx
=
{
CONTEXT_I386_ALL
};
CONTEXT_EX
*
context_ex
,
*
src_ex
=
NULL
;
ULONG
size
,
flags
;
ULONG
flags
;
C_ASSERT
(
offsetof
(
struct
exc_stack_layout32
,
context
)
==
0x58
);
C_ASSERT
(
offsetof
(
struct
exc_stack_layout32
,
xstate
)
==
0x33c
);
C_ASSERT
(
sizeof
(
struct
exc_stack_layout32
)
==
0x4c0
);
pBTCpuGetContext
(
GetCurrentThread
(),
GetCurrentProcess
(),
NULL
,
&
ctx
);
...
...
@@ -222,20 +230,16 @@ static void call_user_exception_dispatcher( EXCEPTION_RECORD32 *rec, void *ctx32
flags
=
ctx
.
ContextFlags
;
if
(
src_ex
)
flags
|=
CONTEXT_I386_XSTATE
;
RtlGetExtendedContextLength
(
flags
,
&
size
);
size
=
((
size
+
15
)
&
~
15
)
+
offsetof
(
struct
stack_layout
,
context
);
stack
=
(
struct
stack_layout
*
)(
ULONG_PTR
)(
ctx
.
Esp
-
size
);
stack
->
rec_ptr
=
PtrToUlong
(
&
stack
->
rec
);
stack
->
rec
=
*
rec
;
stack
=
(
struct
exc_stack_layout32
*
)
ULongToPtr
(
ctx
.
Esp
&
~
3
)
-
1
;
stack
->
rec_ptr
=
PtrToUlong
(
&
stack
->
rec
);
stack
->
context_ptr
=
PtrToUlong
(
&
stack
->
context
);
stack
->
rec
=
*
rec
;
stack
->
context
=
ctx
;
RtlInitializeExtendedContext
(
&
stack
->
context
,
flags
,
&
context_ex
);
context
=
RtlLocateLegacyContext
(
context_ex
,
NULL
);
*
context
=
ctx
;
context
->
ContextFlags
=
flags
;
/* adjust Eip for breakpoints in software emulation (hardware exceptions already adjust Rip) */
if
(
rec
->
ExceptionCode
==
EXCEPTION_BREAKPOINT
&&
(
wow64info
->
CpuFlags
&
WOW64_CPUFLAGS_SOFTWARE
))
context
->
Eip
--
;
stack
->
context_ptr
=
PtrToUlong
(
context
);
stack
->
context
.
Eip
--
;
if
(
src_ex
)
{
...
...
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