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
94f63ea2
Commit
94f63ea2
authored
Aug 17, 2021
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ntdll: Add support for user callbacks.
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
b56a4b3e
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
253 additions
and
41 deletions
+253
-41
signal_arm.c
dlls/ntdll/unix/signal_arm.c
+72
-22
signal_arm64.c
dlls/ntdll/unix/signal_arm64.c
+63
-11
signal_i386.c
dlls/ntdll/unix/signal_i386.c
+57
-3
signal_x86_64.c
dlls/ntdll/unix/signal_x86_64.c
+59
-3
unix_private.h
dlls/ntdll/unix/unix_private.h
+1
-0
import.c
tools/winebuild/import.c
+1
-2
No files found.
dlls/ntdll/unix/signal_arm.c
View file @
94f63ea2
...
...
@@ -172,27 +172,27 @@ enum arm_trap_code
struct
syscall_frame
{
DWORD
r0
;
/* 000 */
DWORD
r1
;
/* 004 */
DWORD
r2
;
/* 008 */
DWORD
r3
;
/* 00c */
DWORD
r4
;
/* 010 */
DWORD
r5
;
/* 014 */
DWORD
r6
;
/* 018 */
DWORD
r7
;
/* 01c */
DWORD
r8
;
/* 020 */
DWORD
r9
;
/* 024 */
DWORD
r10
;
/* 028 */
DWORD
r11
;
/* 02c */
DWORD
r12
;
/* 030 */
DWORD
pc
;
/* 034 */
DWORD
sp
;
/* 038 */
DWORD
lr
;
/* 03c */
DWORD
cpsr
;
/* 040 */
DWORD
restore_flags
;
/* 044 */
DWORD
fpscr
;
/* 048 */
DWORD
align
;
/* 04c */
ULONGLONG
d
[
32
];
/* 050 */
DWORD
r0
;
/* 000 */
DWORD
r1
;
/* 004 */
DWORD
r2
;
/* 008 */
DWORD
r3
;
/* 00c */
DWORD
r4
;
/* 010 */
DWORD
r5
;
/* 014 */
DWORD
r6
;
/* 018 */
DWORD
r7
;
/* 01c */
DWORD
r8
;
/* 020 */
DWORD
r9
;
/* 024 */
DWORD
r10
;
/* 028 */
DWORD
r11
;
/* 02c */
DWORD
r12
;
/* 030 */
DWORD
pc
;
/* 034 */
DWORD
sp
;
/* 038 */
DWORD
lr
;
/* 03c */
DWORD
cpsr
;
/* 040 */
DWORD
restore_flags
;
/* 044 */
DWORD
fpscr
;
/* 048 */
struct
syscall_frame
*
prev_frame
;
/* 04c */
ULONGLONG
d
[
32
];
/* 050 */
};
C_ASSERT
(
sizeof
(
struct
syscall_frame
)
==
0x150
);
...
...
@@ -575,12 +575,61 @@ NTSTATUS call_user_exception_dispatcher( EXCEPTION_RECORD *rec, CONTEXT *context
}
struct
user_callback_frame
{
struct
syscall_frame
frame
;
void
**
ret_ptr
;
ULONG
*
ret_len
;
__wine_jmp_buf
jmpbuf
;
NTSTATUS
status
;
};
/***********************************************************************
* KeUserModeCallback
*/
NTSTATUS
WINAPI
KeUserModeCallback
(
ULONG
id
,
const
void
*
args
,
ULONG
len
,
void
**
ret_ptr
,
ULONG
*
ret_len
)
{
struct
user_callback_frame
callback_frame
=
{
{
0
},
ret_ptr
,
ret_len
};
if
((
char
*
)
ntdll_get_thread_data
()
->
kernel_stack
+
min_kernel_stack
>
(
char
*
)
&
callback_frame
)
return
STATUS_STACK_OVERFLOW
;
if
(
!
__wine_setjmpex
(
&
callback_frame
.
jmpbuf
,
NULL
))
{
struct
syscall_frame
*
frame
=
arm_thread_data
()
->
syscall_frame
;
void
*
args_data
=
(
void
*
)((
frame
->
sp
-
len
)
&
~
15
);
memcpy
(
args_data
,
args
,
len
);
callback_frame
.
frame
.
r0
=
id
;
callback_frame
.
frame
.
r1
=
(
ULONG_PTR
)
args
;
callback_frame
.
frame
.
r2
=
len
;
callback_frame
.
frame
.
sp
=
(
ULONG_PTR
)
args_data
;
callback_frame
.
frame
.
pc
=
(
ULONG_PTR
)
pKiUserCallbackDispatcher
;
callback_frame
.
frame
.
restore_flags
=
CONTEXT_INTEGER
;
callback_frame
.
frame
.
prev_frame
=
frame
;
arm_thread_data
()
->
syscall_frame
=
&
callback_frame
.
frame
;
__wine_syscall_dispatcher_return
(
&
callback_frame
.
frame
,
0
);
}
return
callback_frame
.
status
;
}
/***********************************************************************
* NtCallbackReturn (NTDLL.@)
*/
NTSTATUS
WINAPI
NtCallbackReturn
(
void
*
ret_ptr
,
ULONG
ret_len
,
NTSTATUS
status
)
{
return
STATUS_NO_CALLBACK_ACTIVE
;
struct
user_callback_frame
*
frame
=
(
struct
user_callback_frame
*
)
arm_thread_data
()
->
syscall_frame
;
if
(
!
frame
->
frame
.
prev_frame
)
return
STATUS_NO_CALLBACK_ACTIVE
;
*
frame
->
ret_ptr
=
ret_ptr
;
*
frame
->
ret_len
=
ret_len
;
frame
->
status
=
status
;
arm_thread_data
()
->
syscall_frame
=
frame
->
frame
.
prev_frame
;
__wine_longjmp
(
&
frame
->
jmpbuf
,
1
);
}
...
...
@@ -942,6 +991,7 @@ void DECLSPEC_HIDDEN call_init_thunk( LPTHREAD_START_ROUTINE entry, void *arg, B
frame
->
sp
=
(
DWORD
)
ctx
;
frame
->
pc
=
(
DWORD
)
pLdrInitializeThunk
;
frame
->
r0
=
(
DWORD
)
ctx
;
frame
->
prev_frame
=
NULL
;
frame
->
restore_flags
|=
CONTEXT_INTEGER
;
pthread_sigmask
(
SIG_UNBLOCK
,
&
server_block_set
,
NULL
);
...
...
dlls/ntdll/unix/signal_arm64.c
View file @
94f63ea2
...
...
@@ -134,16 +134,17 @@ static pthread_key_t teb_key;
struct
syscall_frame
{
ULONG64
x
[
29
];
/* 000 */
ULONG64
fp
;
/* 0e8 */
ULONG64
lr
;
/* 0f0 */
ULONG64
sp
;
/* 0f8 */
ULONG64
pc
;
/* 100 */
ULONG64
cpsr
;
/* 108 */
ULONG64
restore_flags
;
/* 110 */
ULONG
fpcr
;
/* 118 */
ULONG
fpsr
;
/* 11c */
NEON128
v
[
32
];
/* 120 */
ULONG64
x
[
29
];
/* 000 */
ULONG64
fp
;
/* 0e8 */
ULONG64
lr
;
/* 0f0 */
ULONG64
sp
;
/* 0f8 */
ULONG64
pc
;
/* 100 */
ULONG
cpsr
;
/* 108 */
ULONG
restore_flags
;
/* 10c */
struct
syscall_frame
*
prev_frame
;
/* 110 */
ULONG
fpcr
;
/* 118 */
ULONG
fpsr
;
/* 11c */
NEON128
v
[
32
];
/* 120 */
};
C_ASSERT
(
sizeof
(
struct
syscall_frame
)
==
0x320
);
...
...
@@ -722,12 +723,62 @@ NTSTATUS call_user_exception_dispatcher( EXCEPTION_RECORD *rec, CONTEXT *context
}
struct
user_callback_frame
{
struct
syscall_frame
frame
;
void
**
ret_ptr
;
ULONG
*
ret_len
;
__wine_jmp_buf
jmpbuf
;
NTSTATUS
status
;
};
/***********************************************************************
* KeUserModeCallback
*/
NTSTATUS
WINAPI
KeUserModeCallback
(
ULONG
id
,
const
void
*
args
,
ULONG
len
,
void
**
ret_ptr
,
ULONG
*
ret_len
)
{
struct
user_callback_frame
callback_frame
=
{
{{
0
}},
ret_ptr
,
ret_len
};
if
((
char
*
)
ntdll_get_thread_data
()
->
kernel_stack
+
min_kernel_stack
>
(
char
*
)
&
callback_frame
)
return
STATUS_STACK_OVERFLOW
;
if
(
!
__wine_setjmpex
(
&
callback_frame
.
jmpbuf
,
NULL
))
{
struct
syscall_frame
*
frame
=
arm64_thread_data
()
->
syscall_frame
;
void
*
args_data
=
(
void
*
)((
frame
->
sp
-
len
)
&
~
15
);
memcpy
(
args_data
,
args
,
len
);
callback_frame
.
frame
.
x
[
0
]
=
id
;
callback_frame
.
frame
.
x
[
1
]
=
(
ULONG_PTR
)
args
;
callback_frame
.
frame
.
x
[
2
]
=
len
;
callback_frame
.
frame
.
x
[
18
]
=
frame
->
x
[
18
];
callback_frame
.
frame
.
sp
=
(
ULONG_PTR
)
args_data
;
callback_frame
.
frame
.
pc
=
(
ULONG_PTR
)
pKiUserCallbackDispatcher
;
callback_frame
.
frame
.
restore_flags
=
CONTEXT_INTEGER
;
callback_frame
.
frame
.
prev_frame
=
frame
;
arm64_thread_data
()
->
syscall_frame
=
&
callback_frame
.
frame
;
__wine_syscall_dispatcher_return
(
&
callback_frame
.
frame
,
0
);
}
return
callback_frame
.
status
;
}
/***********************************************************************
* NtCallbackReturn (NTDLL.@)
*/
NTSTATUS
WINAPI
NtCallbackReturn
(
void
*
ret_ptr
,
ULONG
ret_len
,
NTSTATUS
status
)
{
return
STATUS_NO_CALLBACK_ACTIVE
;
struct
user_callback_frame
*
frame
=
(
struct
user_callback_frame
*
)
arm64_thread_data
()
->
syscall_frame
;
if
(
!
frame
->
frame
.
prev_frame
)
return
STATUS_NO_CALLBACK_ACTIVE
;
*
frame
->
ret_ptr
=
ret_ptr
;
*
frame
->
ret_len
=
ret_len
;
frame
->
status
=
status
;
arm64_thread_data
()
->
syscall_frame
=
frame
->
frame
.
prev_frame
;
__wine_longjmp
(
&
frame
->
jmpbuf
,
1
);
}
...
...
@@ -1133,6 +1184,7 @@ void DECLSPEC_HIDDEN call_init_thunk( LPTHREAD_START_ROUTINE entry, void *arg, B
frame
->
pc
=
(
ULONG64
)
pLdrInitializeThunk
;
frame
->
x
[
0
]
=
(
ULONG64
)
ctx
;
frame
->
x
[
18
]
=
(
ULONG64
)
teb
;
frame
->
prev_frame
=
NULL
;
frame
->
restore_flags
|=
CONTEXT_INTEGER
;
pthread_sigmask
(
SIG_UNBLOCK
,
&
server_block_set
,
NULL
);
...
...
dlls/ntdll/unix/signal_i386.c
View file @
94f63ea2
...
...
@@ -481,7 +481,7 @@ struct syscall_frame
DWORD
esi
;
/* 030 */
DWORD
ebp
;
/* 034 */
DWORD
syscall_flags
;
/* 038 */
DWORD
align
;
/* 03c */
struct
syscall_frame
*
prev_frame
;
/* 03c */
union
/* 040 */
{
XSAVE_FORMAT
xsave
;
...
...
@@ -490,7 +490,7 @@ struct syscall_frame
/* Leave space for the whole set of YMM registers. They're not used in
* 32-bit mode, but some processors fault if they're not in writable memory.
*/
XSTATE
xstate
;
/* 240 */
DECLSPEC_ALIGN
(
64
)
XSTATE
xstate
;
/* 240 */
};
C_ASSERT
(
sizeof
(
struct
syscall_frame
)
==
0x380
);
...
...
@@ -1579,12 +1579,65 @@ NTSTATUS call_user_exception_dispatcher( EXCEPTION_RECORD *rec, CONTEXT *context
}
struct
user_callback_frame
{
struct
syscall_frame
frame
;
void
**
ret_ptr
;
ULONG
*
ret_len
;
__wine_jmp_buf
jmpbuf
;
NTSTATUS
status
;
};
/***********************************************************************
* KeUserModeCallback
*/
NTSTATUS
WINAPI
KeUserModeCallback
(
ULONG
id
,
const
void
*
args
,
ULONG
len
,
void
**
ret_ptr
,
ULONG
*
ret_len
)
{
struct
user_callback_frame
callback_frame
=
{
{
0
},
ret_ptr
,
ret_len
};
if
((
char
*
)
ntdll_get_thread_data
()
->
kernel_stack
+
min_kernel_stack
>
(
char
*
)
&
callback_frame
)
return
STATUS_STACK_OVERFLOW
;
if
(
!
__wine_setjmpex
(
&
callback_frame
.
jmpbuf
,
NULL
))
{
struct
syscall_frame
*
frame
=
x86_thread_data
()
->
syscall_frame
;
void
*
args_data
=
(
void
*
)((
frame
->
esp
-
len
)
&
~
15
);
ULONG_PTR
*
stack
=
args_data
;
memcpy
(
args_data
,
args
,
len
);
*
(
--
stack
)
=
0
;
*
(
--
stack
)
=
len
;
*
(
--
stack
)
=
(
ULONG_PTR
)
args_data
;
*
(
--
stack
)
=
id
;
*
(
--
stack
)
=
0xdeadbabe
;
callback_frame
.
frame
.
esp
=
(
ULONG_PTR
)
stack
;
callback_frame
.
frame
.
eip
=
(
ULONG_PTR
)
pKiUserCallbackDispatcher
;
callback_frame
.
frame
.
eflags
=
0x202
;
callback_frame
.
frame
.
syscall_flags
=
__wine_syscall_flags
;
callback_frame
.
frame
.
prev_frame
=
frame
;
x86_thread_data
()
->
syscall_frame
=
&
callback_frame
.
frame
;
__wine_syscall_dispatcher_return
(
&
callback_frame
.
frame
,
0
);
}
return
callback_frame
.
status
;
}
/***********************************************************************
* NtCallbackReturn (NTDLL.@)
*/
NTSTATUS
WINAPI
NtCallbackReturn
(
void
*
ret_ptr
,
ULONG
ret_len
,
NTSTATUS
status
)
{
return
STATUS_NO_CALLBACK_ACTIVE
;
struct
user_callback_frame
*
frame
=
(
struct
user_callback_frame
*
)
x86_thread_data
()
->
syscall_frame
;
if
(
!
frame
->
frame
.
prev_frame
)
return
STATUS_NO_CALLBACK_ACTIVE
;
*
frame
->
ret_ptr
=
ret_ptr
;
*
frame
->
ret_len
=
ret_len
;
frame
->
status
=
status
;
x86_thread_data
()
->
syscall_frame
=
frame
->
frame
.
prev_frame
;
__wine_longjmp
(
&
frame
->
jmpbuf
,
1
);
}
...
...
@@ -2364,6 +2417,7 @@ void DECLSPEC_HIDDEN call_init_thunk( LPTHREAD_START_ROUTINE entry, void *arg, B
*
(
--
stack
)
=
0xdeadbabe
;
frame
->
esp
=
(
DWORD
)
stack
;
frame
->
eip
=
(
DWORD
)
pLdrInitializeThunk
;
frame
->
prev_frame
=
NULL
;
frame
->
syscall_flags
=
__wine_syscall_flags
;
frame
->
restore_flags
|=
CONTEXT_INTEGER
;
...
...
dlls/ntdll/unix/signal_x86_64.c
View file @
94f63ea2
...
...
@@ -324,9 +324,10 @@ struct syscall_frame
WORD
gs
;
/* 0092 */
DWORD
restore_flags
;
/* 0094 */
ULONG64
rbp
;
/* 0098 */
ULONG64
align
[
4
];
/* 00a0 */
struct
syscall_frame
*
prev_frame
;
/* 00a0 */
ULONG64
align
[
3
];
/* 00a8 */
XMM_SAVE_AREA32
xsave
;
/* 00c0 */
XSTATE
xstate
;
/* 02c0 */
DECLSPEC_ALIGN
(
64
)
XSTATE
xstate
;
/* 02c0 */
};
C_ASSERT
(
sizeof
(
struct
syscall_frame
)
==
0x400
);
...
...
@@ -2275,12 +2276,66 @@ NTSTATUS call_user_exception_dispatcher( EXCEPTION_RECORD *rec, CONTEXT *context
}
struct
user_callback_frame
{
struct
syscall_frame
frame
;
void
**
ret_ptr
;
ULONG
*
ret_len
;
__wine_jmp_buf
jmpbuf
;
NTSTATUS
status
;
};
/***********************************************************************
* KeUserModeCallback
*/
NTSTATUS
WINAPI
KeUserModeCallback
(
ULONG
id
,
const
void
*
args
,
ULONG
len
,
void
**
ret_ptr
,
ULONG
*
ret_len
)
{
struct
user_callback_frame
callback_frame
=
{
{
0
},
ret_ptr
,
ret_len
};
if
((
char
*
)
ntdll_get_thread_data
()
->
kernel_stack
+
min_kernel_stack
>
(
char
*
)
&
callback_frame
)
return
STATUS_STACK_OVERFLOW
;
if
(
!
__wine_setjmpex
(
&
callback_frame
.
jmpbuf
,
NULL
))
{
struct
syscall_frame
*
frame
=
amd64_thread_data
()
->
syscall_frame
;
void
*
args_data
=
(
void
*
)((
frame
->
rsp
-
len
)
&
~
15
);
memcpy
(
args_data
,
args
,
len
);
callback_frame
.
frame
.
rcx
=
id
;
callback_frame
.
frame
.
rdx
=
(
ULONG_PTR
)
args
;
callback_frame
.
frame
.
r8
=
len
;
callback_frame
.
frame
.
cs
=
cs64_sel
;
callback_frame
.
frame
.
fs
=
fs32_sel
;
callback_frame
.
frame
.
gs
=
ds64_sel
;
callback_frame
.
frame
.
ss
=
ds64_sel
;
callback_frame
.
frame
.
rsp
=
(
ULONG_PTR
)
args_data
-
0x28
;
callback_frame
.
frame
.
rip
=
(
ULONG_PTR
)
pKiUserCallbackDispatcher
;
callback_frame
.
frame
.
eflags
=
0x200
;
callback_frame
.
frame
.
restore_flags
=
CONTEXT_CONTROL
|
CONTEXT_INTEGER
;
callback_frame
.
frame
.
prev_frame
=
frame
;
amd64_thread_data
()
->
syscall_frame
=
&
callback_frame
.
frame
;
__wine_syscall_dispatcher_return
(
&
callback_frame
.
frame
,
0
);
}
return
callback_frame
.
status
;
}
/***********************************************************************
* NtCallbackReturn (NTDLL.@)
*/
NTSTATUS
WINAPI
NtCallbackReturn
(
void
*
ret_ptr
,
ULONG
ret_len
,
NTSTATUS
status
)
{
return
STATUS_NO_CALLBACK_ACTIVE
;
struct
user_callback_frame
*
frame
=
(
struct
user_callback_frame
*
)
amd64_thread_data
()
->
syscall_frame
;
if
(
!
frame
->
frame
.
prev_frame
)
return
STATUS_NO_CALLBACK_ACTIVE
;
*
frame
->
ret_ptr
=
ret_ptr
;
*
frame
->
ret_len
=
ret_len
;
frame
->
status
=
status
;
amd64_thread_data
()
->
syscall_frame
=
frame
->
frame
.
prev_frame
;
__wine_longjmp
(
&
frame
->
jmpbuf
,
1
);
}
...
...
@@ -2966,6 +3021,7 @@ void DECLSPEC_HIDDEN call_init_thunk( LPTHREAD_START_ROUTINE entry, void *arg, B
frame
->
rsp
=
(
ULONG64
)
ctx
-
8
;
frame
->
rip
=
(
ULONG64
)
pLdrInitializeThunk
;
frame
->
rcx
=
(
ULONG64
)
ctx
;
frame
->
prev_frame
=
NULL
;
frame
->
restore_flags
|=
CONTEXT_INTEGER
;
pthread_sigmask
(
SIG_UNBLOCK
,
&
server_block_set
,
NULL
);
...
...
dlls/ntdll/unix/unix_private.h
View file @
94f63ea2
...
...
@@ -84,6 +84,7 @@ static const SIZE_T teb_size = 0x3800; /* TEB64 + TEB32 + debug info */
static
const
SIZE_T
signal_stack_mask
=
0xffff
;
static
const
SIZE_T
signal_stack_size
=
0x10000
-
0x3800
;
static
const
SIZE_T
kernel_stack_size
=
0x20000
;
static
const
SIZE_T
min_kernel_stack
=
0x2000
;
static
const
LONG
teb_offset
=
0x2000
;
#define FILE_WRITE_TO_END_OF_FILE ((LONGLONG)-1)
...
...
tools/winebuild/import.c
View file @
94f63ea2
...
...
@@ -1793,7 +1793,6 @@ static void output_syscall_dispatcher(void)
output
(
"
\t
stp x9, x19, [x10, #0xf0]
\n
"
);
output
(
"
\t
mrs x9, NZCV
\n
"
);
output
(
"
\t
stp x30, x9, [x10, #0x100]
\n
"
);
output
(
"
\t
str xzr, [x10, #0x110]
\n
"
);
/* frame->restore_flags */
output
(
"
\t
mrs x9, FPCR
\n
"
);
output
(
"
\t
str w9, [x10, #0x118]
\n
"
);
output
(
"
\t
mrs x9, FPSR
\n
"
);
...
...
@@ -1845,7 +1844,7 @@ static void output_syscall_dispatcher(void)
output
(
"
\t
ldp x24, x25, [sp, #0xc0]
\n
"
);
output
(
"
\t
ldp x26, x27, [sp, #0xd0]
\n
"
);
output
(
"
\t
ldp x28, x29, [sp, #0xe0]
\n
"
);
output
(
"
\t
ldr
x16, [sp, #0x110
]
\n
"
);
/* frame->restore_flags */
output
(
"
\t
ldr
w16, [sp, #0x10c
]
\n
"
);
/* frame->restore_flags */
output
(
"
\t
tbz x16, #2, 1f
\n
"
);
/* CONTEXT_FLOATING_POINT */
output
(
"
\t
ldp q0, q1, [sp, #0x120]
\n
"
);
output
(
"
\t
ldp q2, q3, [sp, #0x140]
\n
"
);
...
...
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