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
6c61ea6a
Commit
6c61ea6a
authored
Nov 30, 2017
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ntdll: Suspend a thread with its start context explicitly before attaching dlls.
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
0d3ebfc4
Hide whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
81 additions
and
14 deletions
+81
-14
ntdll_misc.h
dlls/ntdll/ntdll_misc.h
+2
-2
server.c
dlls/ntdll/server.c
+2
-1
signal_arm.c
dlls/ntdll/signal_arm.c
+11
-1
signal_arm64.c
dlls/ntdll/signal_arm64.c
+11
-1
signal_i386.c
dlls/ntdll/signal_i386.c
+19
-1
signal_powerpc.c
dlls/ntdll/signal_powerpc.c
+11
-1
signal_x86_64.c
dlls/ntdll/signal_x86_64.c
+14
-1
thread.c
dlls/ntdll/thread.c
+5
-3
server_protocol.h
include/wine/server_protocol.h
+2
-2
protocol.def
server/protocol.def
+1
-0
request.h
server/request.h
+1
-0
thread.c
server/thread.c
+1
-1
trace.c
server/trace.c
+1
-0
No files found.
dlls/ntdll/ntdll_misc.h
View file @
6c61ea6a
...
...
@@ -68,7 +68,7 @@ extern NTSTATUS signal_alloc_thread( TEB **teb ) DECLSPEC_HIDDEN;
extern
void
signal_free_thread
(
TEB
*
teb
)
DECLSPEC_HIDDEN
;
extern
void
signal_init_thread
(
TEB
*
teb
)
DECLSPEC_HIDDEN
;
extern
void
signal_init_process
(
void
)
DECLSPEC_HIDDEN
;
extern
NTSTATUS
signal_start_thread
(
LPTHREAD_START_ROUTINE
entry
,
void
*
arg
)
DECLSPEC_HIDDEN
;
extern
NTSTATUS
signal_start_thread
(
LPTHREAD_START_ROUTINE
entry
,
void
*
arg
,
BOOL
suspend
)
DECLSPEC_HIDDEN
;
extern
NTSTATUS
signal_start_process
(
LPTHREAD_START_ROUTINE
entry
,
BOOL
suspend
)
DECLSPEC_HIDDEN
;
extern
void
version_init
(
const
WCHAR
*
appname
)
DECLSPEC_HIDDEN
;
extern
void
debug_init
(
void
)
DECLSPEC_HIDDEN
;
...
...
@@ -85,7 +85,7 @@ extern unsigned int server_cpus DECLSPEC_HIDDEN;
extern
BOOL
is_wow64
DECLSPEC_HIDDEN
;
extern
void
server_init_process
(
void
)
DECLSPEC_HIDDEN
;
extern
NTSTATUS
server_init_process_done
(
void
)
DECLSPEC_HIDDEN
;
extern
size_t
server_init_thread
(
void
*
entry_point
)
DECLSPEC_HIDDEN
;
extern
size_t
server_init_thread
(
void
*
entry_point
,
BOOL
*
suspend
)
DECLSPEC_HIDDEN
;
extern
void
DECLSPEC_NORETURN
abort_thread
(
int
status
)
DECLSPEC_HIDDEN
;
extern
void
DECLSPEC_NORETURN
terminate_thread
(
int
status
)
DECLSPEC_HIDDEN
;
extern
void
DECLSPEC_NORETURN
exit_thread
(
int
status
)
DECLSPEC_HIDDEN
;
...
...
dlls/ntdll/server.c
View file @
6c61ea6a
...
...
@@ -1470,7 +1470,7 @@ NTSTATUS server_init_process_done(void)
*
* Send an init thread request. Return 0 if OK.
*/
size_t
server_init_thread
(
void
*
entry_point
)
size_t
server_init_thread
(
void
*
entry_point
,
BOOL
*
suspend
)
{
static
const
char
*
cpu_names
[]
=
{
"x86"
,
"x86_64"
,
"PowerPC"
,
"ARM"
,
"ARM64"
};
static
const
BOOL
is_win64
=
(
sizeof
(
void
*
)
>
sizeof
(
int
));
...
...
@@ -1511,6 +1511,7 @@ size_t server_init_thread( void *entry_point )
info_size
=
reply
->
info_size
;
server_start_time
=
reply
->
server_start
;
server_cpus
=
reply
->
all_cpus
;
*
suspend
=
reply
->
suspend
;
}
SERVER_END_REQ
;
...
...
dlls/ntdll/signal_arm.c
View file @
6c61ea6a
...
...
@@ -1029,11 +1029,21 @@ static void thread_startup( void *param )
/***********************************************************************
* signal_start_thread
*/
NTSTATUS
signal_start_thread
(
LPTHREAD_START_ROUTINE
entry
,
void
*
arg
)
NTSTATUS
signal_start_thread
(
LPTHREAD_START_ROUTINE
entry
,
void
*
arg
,
BOOL
suspend
)
{
NTSTATUS
status
;
CONTEXT
context
=
{
0
};
struct
startup_info
info
=
{
entry
,
arg
};
/* build the initial context */
context
.
ContextFlags
=
CONTEXT_FULL
;
context
.
R0
=
(
DWORD
)
entry
;
context
.
R1
=
(
DWORD
)
arg
;
context
.
Sp
=
(
DWORD
)
NtCurrentTeb
()
->
Tib
.
StackBase
;
context
.
Pc
=
(
DWORD
)
call_thread_entry_point
;
if
(
suspend
)
wait_suspend
(
&
context
);
if
(
!
(
status
=
wine_call_on_stack
(
attach_dlls
,
(
void
*
)
1
,
NtCurrentTeb
()
->
Tib
.
StackBase
)))
{
TRACE_
(
relay
)(
"
\1
Starting thread proc %p (arg=%p)
\n
"
,
entry
,
arg
);
...
...
dlls/ntdll/signal_arm64.c
View file @
6c61ea6a
...
...
@@ -900,11 +900,21 @@ static void thread_startup( void *param )
/***********************************************************************
* signal_start_thread
*/
NTSTATUS
signal_start_thread
(
LPTHREAD_START_ROUTINE
entry
,
void
*
arg
)
NTSTATUS
signal_start_thread
(
LPTHREAD_START_ROUTINE
entry
,
void
*
arg
,
BOOL
suspend
)
{
NTSTATUS
status
;
CONTEXT
context
=
{
0
};
struct
startup_info
info
=
{
entry
,
arg
};
/* build the initial context */
context
.
ContextFlags
=
CONTEXT_FULL
;
context
.
X0
=
(
DWORD_PTR
)
entry
;
context
.
X1
=
(
DWORD_PTR
)
arg
;
context
.
Sp
=
(
DWORD_PTR
)
NtCurrentTeb
()
->
Tib
.
StackBase
;
context
.
Pc
=
(
DWORD_PTR
)
call_thread_entry_point
;
if
(
suspend
)
wait_suspend
(
&
context
);
if
(
!
(
status
=
wine_call_on_stack
(
attach_dlls
,
(
void
*
)
1
,
NtCurrentTeb
()
->
Tib
.
StackBase
)))
{
TRACE_
(
relay
)(
"
\1
Starting thread proc %p (arg=%p)
\n
"
,
entry
,
arg
);
...
...
dlls/ntdll/signal_i386.c
View file @
6c61ea6a
...
...
@@ -2618,11 +2618,29 @@ static void thread_startup( void *param )
/***********************************************************************
* signal_start_thread
*/
NTSTATUS
signal_start_thread
(
LPTHREAD_START_ROUTINE
entry
,
void
*
arg
)
NTSTATUS
signal_start_thread
(
LPTHREAD_START_ROUTINE
entry
,
void
*
arg
,
BOOL
suspend
)
{
NTSTATUS
status
;
CONTEXT
context
=
{
0
};
struct
startup_info
info
=
{
entry
,
arg
};
/* build the initial context */
context
.
ContextFlags
=
CONTEXT_FULL
;
context
.
SegCs
=
wine_get_cs
();
context
.
SegDs
=
wine_get_ds
();
context
.
SegEs
=
wine_get_es
();
context
.
SegFs
=
wine_get_fs
();
context
.
SegGs
=
wine_get_gs
();
context
.
SegSs
=
wine_get_ss
();
context
.
Eax
=
(
DWORD
)
entry
;
context
.
Ebx
=
(
DWORD
)
arg
;
context
.
Esp
=
(
DWORD
)
NtCurrentTeb
()
->
Tib
.
StackBase
-
16
;
context
.
Eip
=
(
DWORD
)
call_thread_entry_point
;
((
void
**
)
context
.
Esp
)[
1
]
=
entry
;
((
void
**
)
context
.
Esp
)[
2
]
=
arg
;
if
(
suspend
)
wait_suspend
(
&
context
);
if
(
!
(
status
=
wine_call_on_stack
(
attach_dlls
,
(
void
*
)
1
,
NtCurrentTeb
()
->
Tib
.
StackBase
)))
{
TRACE_
(
relay
)(
"
\1
Starting thread proc %p (arg=%p)
\n
"
,
entry
,
arg
);
...
...
dlls/ntdll/signal_powerpc.c
View file @
6c61ea6a
...
...
@@ -1102,11 +1102,21 @@ static void thread_startup( void *param )
/***********************************************************************
* signal_start_thread
*/
NTSTATUS
signal_start_thread
(
LPTHREAD_START_ROUTINE
entry
,
void
*
arg
)
NTSTATUS
signal_start_thread
(
LPTHREAD_START_ROUTINE
entry
,
void
*
arg
,
BOOL
suspend
)
{
NTSTATUS
status
;
CONTEXT
context
=
{
0
};
struct
startup_info
info
=
{
entry
,
arg
};
/* build the initial context */
context
.
ContextFlags
=
CONTEXT_FULL
;
context
.
Gpr1
=
(
DWORD
)
NtCurrentTeb
()
->
Tib
.
StackBase
;
context
.
Gpr3
=
(
DWORD
)
entry
;
context
.
Gpr4
=
(
DWORD
)
arg
;
context
.
Iar
=
(
DWORD
)
call_thread_entry_point
;
if
(
suspend
)
wait_suspend
(
&
context
);
if
(
!
(
status
=
wine_call_on_stack
(
attach_dlls
,
(
void
*
)
1
,
NtCurrentTeb
()
->
Tib
.
StackBase
)))
{
TRACE_
(
relay
)(
"
\1
Starting thread proc %p (arg=%p)
\n
"
,
entry
,
arg
);
...
...
dlls/ntdll/signal_x86_64.c
View file @
6c61ea6a
...
...
@@ -3160,11 +3160,24 @@ static void thread_startup( void *param )
/***********************************************************************
* signal_start_thread
*/
NTSTATUS
signal_start_thread
(
LPTHREAD_START_ROUTINE
entry
,
void
*
arg
)
NTSTATUS
signal_start_thread
(
LPTHREAD_START_ROUTINE
entry
,
void
*
arg
,
BOOL
suspend
)
{
NTSTATUS
status
;
CONTEXT
context
=
{
0
};
struct
startup_info
info
=
{
entry
,
arg
};
/* build the initial context */
context
.
ContextFlags
=
CONTEXT_FULL
;
__asm__
(
"movw %%cs,%0"
:
"=m"
(
context
.
SegCs
)
);
__asm__
(
"movw %%ss,%0"
:
"=m"
(
context
.
SegSs
)
);
__asm__
(
"fxsave %0"
:
"=m"
(
context
.
u
.
FltSave
)
);
context
.
Rcx
=
(
ULONG_PTR
)
entry
;
context
.
Rdx
=
(
ULONG_PTR
)
arg
;
context
.
Rsp
=
(
ULONG_PTR
)
NtCurrentTeb
()
->
Tib
.
StackBase
-
0x28
;
context
.
Rip
=
(
ULONG_PTR
)
call_thread_entry_point
;
if
(
suspend
)
wait_suspend
(
&
context
);
if
(
!
(
status
=
wine_call_on_stack
(
attach_dlls
,
(
void
*
)
1
,
NtCurrentTeb
()
->
Tib
.
StackBase
)))
{
TRACE_
(
relay
)(
"
\1
Starting thread proc %p (arg=%p)
\n
"
,
entry
,
arg
);
...
...
dlls/ntdll/thread.c
View file @
6c61ea6a
...
...
@@ -272,6 +272,7 @@ HANDLE thread_init(void)
{
TEB
*
teb
;
void
*
addr
;
BOOL
suspend
;
SIZE_T
size
,
info_size
;
HANDLE
exe_file
=
0
;
LARGE_INTEGER
now
;
...
...
@@ -359,7 +360,7 @@ HANDLE thread_init(void)
/* setup the server connection */
server_init_process
();
info_size
=
server_init_thread
(
peb
);
info_size
=
server_init_thread
(
peb
,
&
suspend
);
/* create the process heap */
if
(
!
(
peb
->
ProcessHeap
=
RtlCreateHeap
(
HEAP_GROWABLE
,
NULL
,
0
,
0
,
NULL
,
NULL
)))
...
...
@@ -496,6 +497,7 @@ void exit_thread( int status )
*/
static
void
start_thread
(
struct
startup_info
*
info
)
{
BOOL
suspend
;
NTSTATUS
status
;
TEB
*
teb
=
info
->
teb
;
struct
ntdll_thread_data
*
thread_data
=
(
struct
ntdll_thread_data
*
)
&
teb
->
GdiTebBatch
;
...
...
@@ -507,8 +509,8 @@ static void start_thread( struct startup_info *info )
thread_data
->
pthread_id
=
pthread_self
();
signal_init_thread
(
teb
);
server_init_thread
(
info
->
entry_point
);
status
=
signal_start_thread
(
(
LPTHREAD_START_ROUTINE
)
info
->
entry_point
,
info
->
entry_arg
);
server_init_thread
(
info
->
entry_point
,
&
suspend
);
status
=
signal_start_thread
(
(
LPTHREAD_START_ROUTINE
)
info
->
entry_point
,
info
->
entry_arg
,
suspend
);
NtTerminateThread
(
GetCurrentThread
(),
status
);
}
...
...
include/wine/server_protocol.h
View file @
6c61ea6a
...
...
@@ -827,7 +827,7 @@ struct init_thread_reply
data_size_t
info_size
;
int
version
;
unsigned
int
all_cpus
;
char
__pad_36
[
4
]
;
int
suspend
;
};
...
...
@@ -6475,6 +6475,6 @@ union generic_reply
struct
terminate_job_reply
terminate_job_reply
;
};
#define SERVER_PROTOCOL_VERSION 54
3
#define SERVER_PROTOCOL_VERSION 54
4
#endif
/* __WINE_WINE_SERVER_PROTOCOL_H */
server/protocol.def
View file @
6c61ea6a
...
...
@@ -807,6 +807,7 @@ struct rawinput_device
data_size_t info_size; /* total size of startup info */
int version; /* protocol version */
unsigned int all_cpus; /* bitset of supported CPUs */
int suspend; /* is thread suspended? */
@END
...
...
server/request.h
View file @
6c61ea6a
...
...
@@ -782,6 +782,7 @@ C_ASSERT( FIELD_OFFSET(struct init_thread_reply, server_start) == 16 );
C_ASSERT
(
FIELD_OFFSET
(
struct
init_thread_reply
,
info_size
)
==
24
);
C_ASSERT
(
FIELD_OFFSET
(
struct
init_thread_reply
,
version
)
==
28
);
C_ASSERT
(
FIELD_OFFSET
(
struct
init_thread_reply
,
all_cpus
)
==
32
);
C_ASSERT
(
FIELD_OFFSET
(
struct
init_thread_reply
,
suspend
)
==
36
);
C_ASSERT
(
sizeof
(
struct
init_thread_reply
)
==
40
);
C_ASSERT
(
FIELD_OFFSET
(
struct
terminate_process_request
,
handle
)
==
12
);
C_ASSERT
(
FIELD_OFFSET
(
struct
terminate_process_request
,
exit_code
)
==
16
);
...
...
server/thread.c
View file @
6c61ea6a
...
...
@@ -1323,7 +1323,6 @@ DECL_HANDLER(init_thread)
if
(
process
->
unix_pid
!=
current
->
unix_pid
)
process
->
unix_pid
=
-
1
;
/* can happen with linuxthreads */
init_thread_context
(
current
);
stop_thread_if_suspended
(
current
);
generate_debug_event
(
current
,
CREATE_THREAD_DEBUG_EVENT
,
&
req
->
entry
);
set_thread_affinity
(
current
,
current
->
affinity
);
}
...
...
@@ -1334,6 +1333,7 @@ DECL_HANDLER(init_thread)
reply
->
version
=
SERVER_PROTOCOL_VERSION
;
reply
->
server_start
=
server_start_time
;
reply
->
all_cpus
=
supported_cpus
&
get_prefix_cpu_mask
();
reply
->
suspend
=
(
current
->
suspend
||
process
->
suspend
);
return
;
error
:
...
...
server/trace.c
View file @
6c61ea6a
...
...
@@ -1306,6 +1306,7 @@ static void dump_init_thread_reply( const struct init_thread_reply *req )
fprintf
(
stderr
,
", info_size=%u"
,
req
->
info_size
);
fprintf
(
stderr
,
", version=%d"
,
req
->
version
);
fprintf
(
stderr
,
", all_cpus=%08x"
,
req
->
all_cpus
);
fprintf
(
stderr
,
", suspend=%d"
,
req
->
suspend
);
}
static
void
dump_terminate_process_request
(
const
struct
terminate_process_request
*
req
)
...
...
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