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
a8ff0c12
Commit
a8ff0c12
authored
May 17, 2021
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ntdll: Allocate a separate 64-bit stack for Wow64 threads.
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
711bde7c
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
76 additions
and
13 deletions
+76
-13
exception.c
dlls/ntdll/tests/exception.c
+23
-2
loader.c
dlls/ntdll/unix/loader.c
+1
-5
thread.c
dlls/ntdll/unix/thread.c
+35
-6
unix_private.h
dlls/ntdll/unix/unix_private.h
+2
-0
virtual.c
dlls/ntdll/unix/virtual.c
+15
-0
No files found.
dlls/ntdll/tests/exception.c
View file @
a8ff0c12
...
@@ -3745,18 +3745,20 @@ static void test_thread_context(void)
...
@@ -3745,18 +3745,20 @@ static void test_thread_context(void)
static
void
test_wow64_context
(
void
)
static
void
test_wow64_context
(
void
)
{
{
char
cmdline
[]
=
"C:
\\
windows
\\
syswow64
\\
notepad.exe"
;
THREAD_BASIC_INFORMATION
info
;
PROCESS_INFORMATION
pi
;
PROCESS_INFORMATION
pi
;
STARTUPINFOA
si
=
{
0
};
STARTUPINFOA
si
=
{
0
};
WOW64_CONTEXT
ctx
;
WOW64_CONTEXT
ctx
;
NTSTATUS
ret
;
NTSTATUS
ret
;
SIZE_T
res
;
TEB
teb
;
memset
(
&
ctx
,
0x55
,
sizeof
(
ctx
));
memset
(
&
ctx
,
0x55
,
sizeof
(
ctx
));
ctx
.
ContextFlags
=
WOW64_CONTEXT_ALL
;
ctx
.
ContextFlags
=
WOW64_CONTEXT_ALL
;
ret
=
pRtlWow64GetThreadContext
(
GetCurrentThread
(),
&
ctx
);
ret
=
pRtlWow64GetThreadContext
(
GetCurrentThread
(),
&
ctx
);
ok
(
ret
==
STATUS_INVALID_PARAMETER
||
broken
(
ret
==
STATUS_PARTIAL_COPY
),
"got %#x
\n
"
,
ret
);
ok
(
ret
==
STATUS_INVALID_PARAMETER
||
broken
(
ret
==
STATUS_PARTIAL_COPY
),
"got %#x
\n
"
,
ret
);
CreateProcessA
(
NULL
,
cmdline
,
NULL
,
NULL
,
FALSE
,
CREATE_SUSPENDED
,
NULL
,
NULL
,
&
si
,
&
pi
);
CreateProcessA
(
"C:
\\
windows
\\
syswow64
\\
notepad.exe"
,
NULL
,
NULL
,
NULL
,
FALSE
,
CREATE_SUSPENDED
,
NULL
,
NULL
,
&
si
,
&
pi
);
ret
=
pRtlWow64GetThreadContext
(
pi
.
hThread
,
&
ctx
);
ret
=
pRtlWow64GetThreadContext
(
pi
.
hThread
,
&
ctx
);
ok
(
ret
==
STATUS_SUCCESS
,
"got %#x
\n
"
,
ret
);
ok
(
ret
==
STATUS_SUCCESS
,
"got %#x
\n
"
,
ret
);
...
@@ -3775,6 +3777,25 @@ static void test_wow64_context(void)
...
@@ -3775,6 +3777,25 @@ static void test_wow64_context(void)
ret
=
pRtlWow64SetThreadContext
(
pi
.
hThread
,
&
ctx
);
ret
=
pRtlWow64SetThreadContext
(
pi
.
hThread
,
&
ctx
);
ok
(
ret
==
STATUS_SUCCESS
,
"got %#x
\n
"
,
ret
);
ok
(
ret
==
STATUS_SUCCESS
,
"got %#x
\n
"
,
ret
);
pNtQueryInformationThread
(
pi
.
hThread
,
ThreadBasicInformation
,
&
info
,
sizeof
(
info
),
NULL
);
if
(
!
ReadProcessMemory
(
pi
.
hProcess
,
info
.
TebBaseAddress
,
&
teb
,
sizeof
(
teb
),
&
res
))
res
=
0
;
ok
(
res
==
sizeof
(
teb
),
"wrong len %lx
\n
"
,
res
);
if
(
teb
.
WowTebOffset
>
1
)
{
TEB32
teb32
;
if
(
!
ReadProcessMemory
(
pi
.
hProcess
,
(
char
*
)
info
.
TebBaseAddress
+
teb
.
WowTebOffset
,
&
teb32
,
sizeof
(
teb32
),
&
res
))
res
=
0
;
ok
(
res
==
sizeof
(
teb32
),
"wrong len %lx
\n
"
,
res
);
ok
(
((
ctx
.
Esp
+
0xfff
)
&
~
0xfff
)
==
teb32
.
Tib
.
StackBase
,
"esp is not at top of stack: %08x / %08x
\n
"
,
ctx
.
Esp
,
teb32
.
Tib
.
StackBase
);
ok
(
ULongToPtr
(
teb32
.
Tib
.
StackBase
)
<=
teb
.
DeallocationStack
||
ULongToPtr
(
teb32
.
DeallocationStack
)
>=
teb
.
Tib
.
StackBase
,
"stacks overlap %08x-%08x / %p-%p
\n
"
,
teb32
.
DeallocationStack
,
teb32
.
Tib
.
StackBase
,
teb
.
DeallocationStack
,
teb
.
Tib
.
StackBase
);
}
pNtTerminateProcess
(
pi
.
hProcess
,
0
);
pNtTerminateProcess
(
pi
.
hProcess
,
0
);
}
}
...
...
dlls/ntdll/unix/loader.c
View file @
a8ff0c12
...
@@ -1853,7 +1853,6 @@ static struct unix_funcs unix_funcs =
...
@@ -1853,7 +1853,6 @@ static struct unix_funcs unix_funcs =
static
void
start_main_thread
(
void
)
static
void
start_main_thread
(
void
)
{
{
NTSTATUS
status
;
NTSTATUS
status
;
INITIAL_TEB
stack
;
TEB
*
teb
=
virtual_alloc_first_teb
();
TEB
*
teb
=
virtual_alloc_first_teb
();
signal_init_threading
();
signal_init_threading
();
...
@@ -1871,10 +1870,7 @@ static void start_main_thread(void)
...
@@ -1871,10 +1870,7 @@ static void start_main_thread(void)
if
(
p___wine_main_argv
)
*
p___wine_main_argv
=
main_argv
;
if
(
p___wine_main_argv
)
*
p___wine_main_argv
=
main_argv
;
if
(
p___wine_main_wargv
)
*
p___wine_main_wargv
=
main_wargv
;
if
(
p___wine_main_wargv
)
*
p___wine_main_wargv
=
main_wargv
;
set_load_order_app_name
(
main_wargv
[
0
]
);
set_load_order_app_name
(
main_wargv
[
0
]
);
virtual_alloc_thread_stack
(
&
stack
,
is_win64
?
0x7fffffff
:
0
,
0
,
0
,
NULL
);
init_thread_stack
(
teb
,
is_win64
?
0x7fffffff
:
0
,
0
,
0
,
NULL
);
teb
->
Tib
.
StackBase
=
stack
.
StackBase
;
teb
->
Tib
.
StackLimit
=
stack
.
StackLimit
;
teb
->
DeallocationStack
=
stack
.
DeallocationStack
;
NtCreateKeyedEvent
(
&
keyed_event
,
GENERIC_READ
|
GENERIC_WRITE
,
NULL
,
0
);
NtCreateKeyedEvent
(
&
keyed_event
,
GENERIC_READ
|
GENERIC_WRITE
,
NULL
,
0
);
load_ntdll
();
load_ntdll
();
status
=
p__wine_set_unix_funcs
(
NTDLL_UNIXLIB_VERSION
,
&
unix_funcs
);
status
=
p__wine_set_unix_funcs
(
NTDLL_UNIXLIB_VERSION
,
&
unix_funcs
);
...
...
dlls/ntdll/unix/thread.c
View file @
a8ff0c12
...
@@ -142,6 +142,40 @@ void set_thread_id( TEB *teb, DWORD pid, DWORD tid )
...
@@ -142,6 +142,40 @@ void set_thread_id( TEB *teb, DWORD pid, DWORD tid )
/***********************************************************************
/***********************************************************************
* init_thread_stack
*/
NTSTATUS
init_thread_stack
(
TEB
*
teb
,
ULONG_PTR
zero_bits
,
SIZE_T
reserve_size
,
SIZE_T
commit_size
,
SIZE_T
*
pthread_size
)
{
INITIAL_TEB
stack
,
stack64
;
NTSTATUS
status
;
if
((
status
=
virtual_alloc_thread_stack
(
&
stack
,
zero_bits
,
reserve_size
,
commit_size
,
pthread_size
)))
return
status
;
if
(
teb
->
WowTebOffset
&&
!
(
status
=
virtual_alloc_thread_stack
(
&
stack64
,
0
,
0x40000
,
0x40000
,
NULL
)))
{
#ifdef _WIN64
TEB32
*
teb32
=
(
TEB32
*
)((
char
*
)
teb
+
teb
->
WowTebOffset
);
teb32
->
Tib
.
StackBase
=
PtrToUlong
(
stack
.
StackBase
);
teb32
->
Tib
.
StackLimit
=
PtrToUlong
(
stack
.
StackLimit
);
teb32
->
DeallocationStack
=
PtrToUlong
(
stack
.
DeallocationStack
);
stack
=
stack64
;
#else
TEB64
*
teb64
=
(
TEB64
*
)((
char
*
)
teb
+
teb
->
WowTebOffset
);
teb64
->
Tib
.
StackBase
=
PtrToUlong
(
stack64
.
StackBase
);
teb64
->
Tib
.
StackLimit
=
PtrToUlong
(
stack64
.
StackLimit
);
teb64
->
DeallocationStack
=
PtrToUlong
(
stack64
.
DeallocationStack
);
#endif
}
teb
->
Tib
.
StackBase
=
stack
.
StackBase
;
teb
->
Tib
.
StackLimit
=
stack
.
StackLimit
;
teb
->
DeallocationStack
=
stack
.
DeallocationStack
;
return
status
;
}
/***********************************************************************
* update_attr_list
* update_attr_list
*
*
* Update the output attributes.
* Update the output attributes.
...
@@ -196,7 +230,6 @@ NTSTATUS WINAPI NtCreateThreadEx( HANDLE *handle, ACCESS_MASK access, OBJECT_ATT
...
@@ -196,7 +230,6 @@ NTSTATUS WINAPI NtCreateThreadEx( HANDLE *handle, ACCESS_MASK access, OBJECT_ATT
int
request_pipe
[
2
];
int
request_pipe
[
2
];
SIZE_T
extra_stack
=
PTHREAD_STACK_MIN
;
SIZE_T
extra_stack
=
PTHREAD_STACK_MIN
;
TEB
*
teb
;
TEB
*
teb
;
INITIAL_TEB
stack
;
NTSTATUS
status
;
NTSTATUS
status
;
if
(
zero_bits
>
21
&&
zero_bits
<
32
)
return
STATUS_INVALID_PARAMETER_3
;
if
(
zero_bits
>
21
&&
zero_bits
<
32
)
return
STATUS_INVALID_PARAMETER_3
;
...
@@ -269,7 +302,7 @@ NTSTATUS WINAPI NtCreateThreadEx( HANDLE *handle, ACCESS_MASK access, OBJECT_ATT
...
@@ -269,7 +302,7 @@ NTSTATUS WINAPI NtCreateThreadEx( HANDLE *handle, ACCESS_MASK access, OBJECT_ATT
if
((
status
=
virtual_alloc_teb
(
&
teb
)))
goto
done
;
if
((
status
=
virtual_alloc_teb
(
&
teb
)))
goto
done
;
if
((
status
=
virtual_alloc_thread_stack
(
&
stack
,
zero_bits
,
stack_reserve
,
stack_commit
,
&
extra_stack
)))
if
((
status
=
init_thread_stack
(
teb
,
zero_bits
,
stack_reserve
,
stack_commit
,
&
extra_stack
)))
{
{
virtual_free_teb
(
teb
);
virtual_free_teb
(
teb
);
goto
done
;
goto
done
;
...
@@ -277,10 +310,6 @@ NTSTATUS WINAPI NtCreateThreadEx( HANDLE *handle, ACCESS_MASK access, OBJECT_ATT
...
@@ -277,10 +310,6 @@ NTSTATUS WINAPI NtCreateThreadEx( HANDLE *handle, ACCESS_MASK access, OBJECT_ATT
set_thread_id
(
teb
,
GetCurrentProcessId
(),
tid
);
set_thread_id
(
teb
,
GetCurrentProcessId
(),
tid
);
teb
->
Tib
.
StackBase
=
stack
.
StackBase
;
teb
->
Tib
.
StackLimit
=
stack
.
StackLimit
;
teb
->
DeallocationStack
=
stack
.
DeallocationStack
;
thread_data
=
(
struct
ntdll_thread_data
*
)
&
teb
->
GdiTebBatch
;
thread_data
=
(
struct
ntdll_thread_data
*
)
&
teb
->
GdiTebBatch
;
thread_data
->
request_fd
=
request_pipe
[
1
];
thread_data
->
request_fd
=
request_pipe
[
1
];
thread_data
->
start_stack
=
(
char
*
)
teb
->
Tib
.
StackBase
;
thread_data
->
start_stack
=
(
char
*
)
teb
->
Tib
.
StackBase
;
...
...
dlls/ntdll/unix/unix_private.h
View file @
a8ff0c12
...
@@ -173,6 +173,8 @@ extern void server_init_thread( void *entry_point, BOOL *suspend ) DECLSPEC_HIDD
...
@@ -173,6 +173,8 @@ extern void server_init_thread( void *entry_point, BOOL *suspend ) DECLSPEC_HIDD
extern
int
server_pipe
(
int
fd
[
2
]
)
DECLSPEC_HIDDEN
;
extern
int
server_pipe
(
int
fd
[
2
]
)
DECLSPEC_HIDDEN
;
extern
void
set_thread_id
(
TEB
*
teb
,
DWORD
pid
,
DWORD
tid
)
DECLSPEC_HIDDEN
;
extern
void
set_thread_id
(
TEB
*
teb
,
DWORD
pid
,
DWORD
tid
)
DECLSPEC_HIDDEN
;
extern
NTSTATUS
init_thread_stack
(
TEB
*
teb
,
ULONG_PTR
zero_bits
,
SIZE_T
reserve_size
,
SIZE_T
commit_size
,
SIZE_T
*
pthread_size
)
DECLSPEC_HIDDEN
;
extern
NTSTATUS
context_to_server
(
context_t
*
to
,
const
CONTEXT
*
from
)
DECLSPEC_HIDDEN
;
extern
NTSTATUS
context_to_server
(
context_t
*
to
,
const
CONTEXT
*
from
)
DECLSPEC_HIDDEN
;
extern
NTSTATUS
context_from_server
(
CONTEXT
*
to
,
const
context_t
*
from
)
DECLSPEC_HIDDEN
;
extern
NTSTATUS
context_from_server
(
CONTEXT
*
to
,
const
context_t
*
from
)
DECLSPEC_HIDDEN
;
extern
void
DECLSPEC_NORETURN
abort_thread
(
int
status
)
DECLSPEC_HIDDEN
;
extern
void
DECLSPEC_NORETURN
abort_thread
(
int
status
)
DECLSPEC_HIDDEN
;
...
...
dlls/ntdll/unix/virtual.c
View file @
a8ff0c12
...
@@ -2997,6 +2997,21 @@ void virtual_free_teb( TEB *teb )
...
@@ -2997,6 +2997,21 @@ void virtual_free_teb( TEB *teb )
size
=
0
;
size
=
0
;
NtFreeVirtualMemory
(
GetCurrentProcess
(),
&
thread_data
->
start_stack
,
&
size
,
MEM_RELEASE
);
NtFreeVirtualMemory
(
GetCurrentProcess
(),
&
thread_data
->
start_stack
,
&
size
,
MEM_RELEASE
);
}
}
if
(
teb
->
WowTebOffset
)
{
#ifdef _WIN64
TEB32
*
teb32
=
(
TEB32
*
)((
char
*
)
teb
+
teb
->
WowTebOffset
);
void
*
addr
=
ULongToPtr
(
teb32
->
DeallocationStack
);
#else
TEB64
*
teb64
=
(
TEB64
*
)((
char
*
)
teb
+
teb
->
WowTebOffset
);
void
*
addr
=
ULongToPtr
(
teb64
->
DeallocationStack
);
#endif
if
(
addr
)
{
size
=
0
;
NtFreeVirtualMemory
(
GetCurrentProcess
(),
&
addr
,
&
size
,
MEM_RELEASE
);
}
}
server_enter_uninterrupted_section
(
&
virtual_mutex
,
&
sigset
);
server_enter_uninterrupted_section
(
&
virtual_mutex
,
&
sigset
);
list_remove
(
&
thread_data
->
entry
);
list_remove
(
&
thread_data
->
entry
);
...
...
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