Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-cw
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-cw
Commits
be0eb9c9
Commit
be0eb9c9
authored
Jun 03, 2020
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ntdll: Move the thread startup code to the Unix library.
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
11217ee6
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
19 changed files
with
467 additions
and
536 deletions
+467
-536
ntdll_misc.h
dlls/ntdll/ntdll_misc.h
+0
-26
process.c
dlls/ntdll/process.c
+1
-1
server.c
dlls/ntdll/server.c
+1
-1
signal_arm.c
dlls/ntdll/signal_arm.c
+0
-106
signal_arm64.c
dlls/ntdll/signal_arm64.c
+0
-144
signal_i386.c
dlls/ntdll/signal_i386.c
+0
-0
signal_powerpc.c
dlls/ntdll/signal_powerpc.c
+0
-90
signal_x86_64.c
dlls/ntdll/signal_x86_64.c
+0
-130
thread.c
dlls/ntdll/thread.c
+69
-5
loader.c
dlls/ntdll/unix/loader.c
+2
-1
signal_arm.c
dlls/ntdll/unix/signal_arm.c
+63
-0
signal_arm64.c
dlls/ntdll/unix/signal_arm64.c
+103
-0
signal_i386.c
dlls/ntdll/unix/signal_i386.c
+88
-0
signal_x86_64.c
dlls/ntdll/unix/signal_x86_64.c
+84
-0
thread.c
dlls/ntdll/unix/thread.c
+31
-2
unix_private.h
dlls/ntdll/unix/unix_private.h
+7
-1
virtual.c
dlls/ntdll/unix/virtual.c
+15
-0
unixlib.h
dlls/ntdll/unixlib.h
+3
-2
virtual.c
dlls/ntdll/virtual.c
+0
-27
No files found.
dlls/ntdll/ntdll_misc.h
View file @
be0eb9c9
...
...
@@ -78,8 +78,6 @@ extern LPCSTR debugstr_ObjectAttributes(const OBJECT_ATTRIBUTES *oa) DECLSPEC_HI
extern
SIZE_T
signal_stack_size
DECLSPEC_HIDDEN
;
extern
SIZE_T
signal_stack_mask
DECLSPEC_HIDDEN
;
extern
void
signal_init_process
(
void
)
DECLSPEC_HIDDEN
;
extern
void
signal_start_thread
(
LPTHREAD_START_ROUTINE
entry
,
void
*
arg
,
BOOL
suspend
)
DECLSPEC_HIDDEN
;
extern
void
signal_start_process
(
LPTHREAD_START_ROUTINE
entry
,
BOOL
suspend
)
DECLSPEC_HIDDEN
;
extern
void
version_init
(
void
)
DECLSPEC_HIDDEN
;
extern
void
debug_init
(
void
)
DECLSPEC_HIDDEN
;
extern
TEB
*
thread_init
(
void
)
DECLSPEC_HIDDEN
;
...
...
@@ -175,30 +173,6 @@ extern NTSTATUS nt_to_unix_file_name_attr( const OBJECT_ATTRIBUTES *attr, ANSI_S
UINT
disposition
)
DECLSPEC_HIDDEN
;
/* virtual memory */
extern
NTSTATUS
virtual_map_section
(
HANDLE
handle
,
PVOID
*
addr_ptr
,
unsigned
short
zero_bits_64
,
SIZE_T
commit_size
,
const
LARGE_INTEGER
*
offset_ptr
,
SIZE_T
*
size_ptr
,
ULONG
alloc_type
,
ULONG
protect
,
pe_image_info_t
*
image_info
)
DECLSPEC_HIDDEN
;
extern
void
virtual_get_system_info
(
SYSTEM_BASIC_INFORMATION
*
info
)
DECLSPEC_HIDDEN
;
extern
NTSTATUS
virtual_create_builtin_view
(
void
*
base
)
DECLSPEC_HIDDEN
;
extern
TEB
*
virtual_alloc_first_teb
(
void
)
DECLSPEC_HIDDEN
;
extern
NTSTATUS
virtual_alloc_teb
(
TEB
**
teb
)
DECLSPEC_HIDDEN
;
extern
void
virtual_free_teb
(
TEB
*
teb
)
DECLSPEC_HIDDEN
;
extern
NTSTATUS
virtual_alloc_thread_stack
(
INITIAL_TEB
*
stack
,
SIZE_T
reserve_size
,
SIZE_T
commit_size
,
SIZE_T
*
pthread_size
)
DECLSPEC_HIDDEN
;
extern
void
virtual_clear_thread_stack
(
void
*
stack_end
)
DECLSPEC_HIDDEN
;
extern
int
virtual_handle_stack_fault
(
void
*
addr
)
DECLSPEC_HIDDEN
;
extern
BOOL
virtual_is_valid_code_address
(
const
void
*
addr
,
SIZE_T
size
)
DECLSPEC_HIDDEN
;
extern
NTSTATUS
virtual_handle_fault
(
LPCVOID
addr
,
DWORD
err
,
BOOL
on_signal_stack
)
DECLSPEC_HIDDEN
;
extern
unsigned
int
virtual_locked_server_call
(
void
*
req_ptr
)
DECLSPEC_HIDDEN
;
extern
ssize_t
virtual_locked_read
(
int
fd
,
void
*
addr
,
size_t
size
)
DECLSPEC_HIDDEN
;
extern
ssize_t
virtual_locked_pread
(
int
fd
,
void
*
addr
,
size_t
size
,
off_t
offset
)
DECLSPEC_HIDDEN
;
extern
BOOL
virtual_check_buffer_for_read
(
const
void
*
ptr
,
SIZE_T
size
)
DECLSPEC_HIDDEN
;
extern
BOOL
virtual_check_buffer_for_write
(
void
*
ptr
,
SIZE_T
size
)
DECLSPEC_HIDDEN
;
extern
SIZE_T
virtual_uninterrupted_read_memory
(
const
void
*
addr
,
void
*
buffer
,
SIZE_T
size
)
DECLSPEC_HIDDEN
;
extern
NTSTATUS
virtual_uninterrupted_write_memory
(
void
*
addr
,
const
void
*
buffer
,
SIZE_T
size
)
DECLSPEC_HIDDEN
;
extern
void
VIRTUAL_SetForceExec
(
BOOL
enable
)
DECLSPEC_HIDDEN
;
extern
void
virtual_release_address_space
(
void
)
DECLSPEC_HIDDEN
;
extern
void
virtual_set_large_address_space
(
void
)
DECLSPEC_HIDDEN
;
extern
void
virtual_fill_image_information
(
const
pe_image_info_t
*
pe_info
,
SECTION_IMAGE_INFORMATION
*
info
)
DECLSPEC_HIDDEN
;
extern
struct
_KUSER_SHARED_DATA
*
user_shared_data
DECLSPEC_HIDDEN
;
...
...
dlls/ntdll/process.c
View file @
be0eb9c9
...
...
@@ -734,7 +734,7 @@ NTSTATUS WINAPI NtSetInformationProcess(
return
STATUS_INVALID_PARAMETER
;
}
execute_flags
=
*
(
ULONG
*
)
ProcessInformation
;
VIRTUAL_SetForceE
xec
(
enable
);
unix_funcs
->
virtual_set_force_e
xec
(
enable
);
}
break
;
...
...
dlls/ntdll/server.c
View file @
be0eb9c9
...
...
@@ -299,5 +299,5 @@ void server_init_process_done(void)
SERVER_END_REQ
;
assert
(
!
status
);
signal_start_process
(
entry
,
suspend
);
unix_funcs
->
start_process
(
entry
,
suspend
,
kernel32_start_process
);
}
dlls/ntdll/signal_arm.c
View file @
be0eb9c9
...
...
@@ -61,7 +61,6 @@
#include "winnt.h"
WINE_DEFAULT_DEBUG_CHANNEL
(
seh
);
WINE_DECLARE_DEBUG_CHANNEL
(
relay
);
/***********************************************************************
* signal context platform-specific definitions
...
...
@@ -867,111 +866,6 @@ USHORT WINAPI RtlCaptureStackBackTrace( ULONG skip, ULONG count, PVOID *buffer,
return
0
;
}
/***********************************************************************
* call_thread_entry_point
*/
static
void
call_thread_entry_point
(
LPTHREAD_START_ROUTINE
entry
,
void
*
arg
)
{
__TRY
{
TRACE_
(
relay
)(
"
\1
Starting thread proc %p (arg=%p)
\n
"
,
entry
,
arg
);
RtlExitUserThread
(
entry
(
arg
));
}
__EXCEPT
(
call_unhandled_exception_filter
)
{
NtTerminateThread
(
GetCurrentThread
(),
GetExceptionCode
()
);
}
__ENDTRY
abort
();
/* should not be reached */
}
extern
void
DECLSPEC_NORETURN
start_thread
(
LPTHREAD_START_ROUTINE
entry
,
void
*
arg
,
BOOL
suspend
,
void
*
relay
,
TEB
*
teb
);
__ASM_GLOBAL_FUNC
(
start_thread
,
".arm
\n\t
"
"push {r4-r12,lr}
\n\t
"
/* store exit frame */
"ldr r4, [sp, #40]
\n\t
"
/* teb */
"str sp, [r4, #0x1d4]
\n\t
"
/* teb->SystemReserved2 */
/* switch to thread stack */
"ldr r4, [r4, #4]
\n\t
"
/* teb->Tib.StackBase */
"sub sp, r4, #0x1000
\n\t
"
/* attach dlls */
"bl "
__ASM_NAME
(
"attach_thread"
)
"
\n\t
"
"mov sp, r0
\n\t
"
/* clear the stack */
"and r0, #~0xff0
\n\t
"
/* round down to page size */
"bl "
__ASM_NAME
(
"virtual_clear_thread_stack"
)
"
\n\t
"
/* switch to the initial context */
"mov r0, sp
\n\t
"
"b "
__ASM_NAME
(
"set_cpu_context"
)
)
/***********************************************************************
* init_thread_context
*/
static
void
init_thread_context
(
CONTEXT
*
context
,
LPTHREAD_START_ROUTINE
entry
,
void
*
arg
,
void
*
relay
)
{
context
->
R0
=
(
DWORD
)
entry
;
context
->
R1
=
(
DWORD
)
arg
;
context
->
Sp
=
(
DWORD
)
NtCurrentTeb
()
->
Tib
.
StackBase
;
context
->
Pc
=
(
DWORD
)
relay
;
}
/***********************************************************************
* attach_thread
*/
PCONTEXT
DECLSPEC_HIDDEN
attach_thread
(
LPTHREAD_START_ROUTINE
entry
,
void
*
arg
,
BOOL
suspend
,
void
*
relay
)
{
CONTEXT
*
ctx
;
if
(
suspend
)
{
CONTEXT
context
=
{
CONTEXT_ALL
};
init_thread_context
(
&
context
,
entry
,
arg
,
relay
);
wait_suspend
(
&
context
);
ctx
=
(
CONTEXT
*
)((
ULONG_PTR
)
context
.
Sp
&
~
15
)
-
1
;
*
ctx
=
context
;
}
else
{
ctx
=
(
CONTEXT
*
)
NtCurrentTeb
()
->
Tib
.
StackBase
-
1
;
init_thread_context
(
ctx
,
entry
,
arg
,
relay
);
}
ctx
->
ContextFlags
=
CONTEXT_FULL
;
LdrInitializeThunk
(
ctx
,
(
void
**
)
&
ctx
->
R0
,
0
,
0
);
return
ctx
;
}
/***********************************************************************
* signal_start_thread
*
* Thread startup sequence:
* signal_start_thread()
* -> thread_startup()
* -> call_thread_entry_point()
*/
void
signal_start_thread
(
LPTHREAD_START_ROUTINE
entry
,
void
*
arg
,
BOOL
suspend
)
{
start_thread
(
entry
,
arg
,
suspend
,
call_thread_entry_point
,
NtCurrentTeb
()
);
}
/**********************************************************************
* signal_start_process
*
* Process startup sequence:
* signal_start_process()
* -> thread_startup()
* -> kernel32_start_process()
*/
void
signal_start_process
(
LPTHREAD_START_ROUTINE
entry
,
BOOL
suspend
)
{
start_thread
(
entry
,
NtCurrentTeb
()
->
Peb
,
suspend
,
kernel32_start_process
,
NtCurrentTeb
()
);
}
/**********************************************************************
* DbgBreakPoint (NTDLL.@)
*/
...
...
dlls/ntdll/signal_arm64.c
View file @
be0eb9c9
...
...
@@ -64,7 +64,6 @@
#include "winnt.h"
WINE_DEFAULT_DEBUG_CHANNEL
(
seh
);
WINE_DECLARE_DEBUG_CHANNEL
(
relay
);
/* layering violation: the setjmp buffer is defined in msvcrt, but used by RtlUnwindEx */
struct
MSVCRT_JUMP_BUFFER
...
...
@@ -1880,149 +1879,6 @@ USHORT WINAPI RtlCaptureStackBackTrace( ULONG skip, ULONG count, PVOID *buffer,
return
0
;
}
/***********************************************************************
* call_thread_entry_point
*/
static
void
WINAPI
call_thread_entry_point
(
LPTHREAD_START_ROUTINE
entry
,
void
*
arg
)
{
__TRY
{
TRACE_
(
relay
)(
"
\1
Starting thread proc %p (arg=%p)
\n
"
,
entry
,
arg
);
RtlExitUserThread
(
entry
(
arg
));
}
__EXCEPT
(
call_unhandled_exception_filter
)
{
NtTerminateThread
(
GetCurrentThread
(),
GetExceptionCode
()
);
}
__ENDTRY
abort
();
/* should not be reached */
}
extern
void
DECLSPEC_NORETURN
start_thread
(
LPTHREAD_START_ROUTINE
entry
,
void
*
arg
,
BOOL
suspend
,
void
*
relay
,
TEB
*
teb
);
__ASM_GLOBAL_FUNC
(
start_thread
,
"stp x29, x30, [sp,#-16]!
\n\t
"
"mov x18, x4
\n\t
"
/* teb */
/* store exit frame */
"mov x29, sp
\n\t
"
"str x29, [x4, #0x300]
\n\t
"
/* arm64_thread_data()->exit_frame */
/* switch to thread stack */
"ldr x5, [x4, #8]
\n\t
"
/* teb->Tib.StackBase */
"sub sp, x5, #0x1000
\n\t
"
/* attach dlls */
"bl "
__ASM_NAME
(
"attach_thread"
)
"
\n\t
"
"mov sp, x0
\n\t
"
/* clear the stack */
"and x0, x0, #~0xfff
\n\t
"
/* round down to page size */
"bl "
__ASM_NAME
(
"virtual_clear_thread_stack"
)
"
\n\t
"
/* switch to the initial context */
"mov x0, sp
\n\t
"
"ldp q0, q1, [x0, #0x110]
\n\t
"
/* context->V[0,1] */
"ldp q2, q3, [x0, #0x130]
\n\t
"
/* context->V[2,3] */
"ldp q4, q5, [x0, #0x150]
\n\t
"
/* context->V[4,5] */
"ldp q6, q7, [x0, #0x170]
\n\t
"
/* context->V[6,7] */
"ldp q8, q9, [x0, #0x190]
\n\t
"
/* context->V[8,9] */
"ldp q10, q11, [x0, #0x1b0]
\n\t
"
/* context->V[10,11] */
"ldp q12, q13, [x0, #0x1d0]
\n\t
"
/* context->V[12,13] */
"ldp q14, q15, [x0, #0x1f0]
\n\t
"
/* context->V[14,15] */
"ldp q16, q17, [x0, #0x210]
\n\t
"
/* context->V[16,17] */
"ldp q18, q19, [x0, #0x230]
\n\t
"
/* context->V[18,19] */
"ldp q20, q21, [x0, #0x250]
\n\t
"
/* context->V[20,21] */
"ldp q22, q23, [x0, #0x270]
\n\t
"
/* context->V[22,23] */
"ldp q24, q25, [x0, #0x290]
\n\t
"
/* context->V[24,25] */
"ldp q26, q27, [x0, #0x2b0]
\n\t
"
/* context->V[26,27] */
"ldp q28, q29, [x0, #0x2d0]
\n\t
"
/* context->V[28,29] */
"ldp q30, q31, [x0, #0x2f0]
\n\t
"
/* context->V[30,31] */
"ldr w1, [x0, #0x310]
\n\t
"
/* context->Fpcr */
"msr fpcr, x1
\n\t
"
"ldr w1, [x0, #0x314]
\n\t
"
/* context->Fpsr */
"msr fpsr, x1
\n\t
"
"ldp x1, x2, [x0, #0x10]
\n\t
"
/* context->X1,2 */
"ldp x3, x4, [x0, #0x20]
\n\t
"
/* context->X3,4 */
"ldp x5, x6, [x0, #0x30]
\n\t
"
/* context->X5,6 */
"ldp x7, x8, [x0, #0x40]
\n\t
"
/* context->X7,8 */
"ldp x9, x10, [x0, #0x50]
\n\t
"
/* context->X9,10 */
"ldp x11, x12, [x0, #0x60]
\n\t
"
/* context->X11,12 */
"ldp x13, x14, [x0, #0x70]
\n\t
"
/* context->X13,14 */
"ldp x15, x16, [x0, #0x80]
\n\t
"
/* context->X15,16 */
"ldp x17, x18, [x0, #0x90]
\n\t
"
/* context->X17,18 */
"ldp x19, x20, [x0, #0xa0]
\n\t
"
/* context->X19,20 */
"ldp x21, x22, [x0, #0xb0]
\n\t
"
/* context->X21,22 */
"ldp x23, x24, [x0, #0xc0]
\n\t
"
/* context->X23,24 */
"ldp x25, x26, [x0, #0xd0]
\n\t
"
/* context->X25,26 */
"ldp x27, x28, [x0, #0xe0]
\n\t
"
/* context->X27,28 */
"ldp x29, x30, [x0, #0xf0]
\n\t
"
/* context->Fp,Lr */
"ldr x17, [x0, #0x100]
\n\t
"
/* context->Sp */
"mov sp, x17
\n\t
"
"ldr x17, [x0, #0x108]
\n\t
"
/* context->Pc */
"ldr x0, [x0, #0x8]
\n\t
"
/* context->X0 */
"br x17"
)
/***********************************************************************
* init_thread_context
*/
static
void
init_thread_context
(
CONTEXT
*
context
,
LPTHREAD_START_ROUTINE
entry
,
void
*
arg
,
void
*
relay
)
{
context
->
u
.
s
.
X0
=
(
DWORD64
)
entry
;
context
->
u
.
s
.
X1
=
(
DWORD64
)
arg
;
context
->
u
.
s
.
X18
=
(
DWORD64
)
NtCurrentTeb
();
context
->
Sp
=
(
DWORD64
)
NtCurrentTeb
()
->
Tib
.
StackBase
;
context
->
Pc
=
(
DWORD64
)
relay
;
}
/***********************************************************************
* attach_thread
*/
PCONTEXT
DECLSPEC_HIDDEN
attach_thread
(
LPTHREAD_START_ROUTINE
entry
,
void
*
arg
,
BOOL
suspend
,
void
*
relay
)
{
CONTEXT
*
ctx
;
if
(
suspend
)
{
CONTEXT
context
=
{
CONTEXT_ALL
};
init_thread_context
(
&
context
,
entry
,
arg
,
relay
);
wait_suspend
(
&
context
);
ctx
=
(
CONTEXT
*
)((
ULONG_PTR
)
context
.
Sp
&
~
15
)
-
1
;
*
ctx
=
context
;
}
else
{
ctx
=
(
CONTEXT
*
)
NtCurrentTeb
()
->
Tib
.
StackBase
-
1
;
init_thread_context
(
ctx
,
entry
,
arg
,
relay
);
}
ctx
->
ContextFlags
=
CONTEXT_FULL
;
LdrInitializeThunk
(
ctx
,
(
void
**
)
&
ctx
->
u
.
s
.
X0
,
0
,
0
);
return
ctx
;
}
/***********************************************************************
* signal_start_thread
*
* Thread startup sequence:
* signal_start_thread()
* -> start_thread()
* -> call_thread_func()
*/
void
signal_start_thread
(
LPTHREAD_START_ROUTINE
entry
,
void
*
arg
,
BOOL
suspend
)
{
start_thread
(
entry
,
arg
,
suspend
,
call_thread_entry_point
,
NtCurrentTeb
()
);
}
/**********************************************************************
* signal_start_process
*
* Process startup sequence:
* signal_start_process()
* -> start_thread()
* -> kernel32_start_process()
*/
void
signal_start_process
(
LPTHREAD_START_ROUTINE
entry
,
BOOL
suspend
)
{
start_thread
(
entry
,
NtCurrentTeb
()
->
Peb
,
suspend
,
kernel32_start_process
,
NtCurrentTeb
()
);
}
/**********************************************************************
* DbgBreakPoint (NTDLL.@)
*/
...
...
dlls/ntdll/signal_i386.c
View file @
be0eb9c9
This diff is collapsed.
Click to expand it.
dlls/ntdll/signal_powerpc.c
View file @
be0eb9c9
...
...
@@ -58,7 +58,6 @@
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL
(
seh
);
WINE_DECLARE_DEBUG_CHANNEL
(
relay
);
/***********************************************************************
* signal context platform-specific definitions
...
...
@@ -720,95 +719,6 @@ USHORT WINAPI RtlCaptureStackBackTrace( ULONG skip, ULONG count, PVOID *buffer,
return
0
;
}
/***********************************************************************
* call_thread_entry_point
*/
static
void
WINAPI
call_thread_entry_point
(
LPTHREAD_START_ROUTINE
entry
,
void
*
arg
)
{
__TRY
{
TRACE_
(
relay
)(
"
\1
Starting thread proc %p (arg=%p)
\n
"
,
entry
,
arg
);
RtlExitUserThread
(
entry
(
arg
));
}
__EXCEPT
(
call_unhandled_exception_filter
)
{
NtTerminateThread
(
GetCurrentThread
(),
GetExceptionCode
()
);
}
__ENDTRY
abort
();
/* should not be reached */
}
typedef
void
(
WINAPI
*
thread_start_func
)(
LPTHREAD_START_ROUTINE
,
void
*
);
struct
startup_info
{
thread_start_func
start
;
LPTHREAD_START_ROUTINE
entry
;
void
*
arg
;
BOOL
suspend
;
};
/* FIXME: should set the full context instead */
extern
void
DECLSPEC_NORETURN
switch_to_stack
(
void
(
*
func
)(
void
*
),
void
*
arg
,
void
*
stack
);
__ASM_GLOBAL_FUNC
(
switch_to_stack
,
"subi 5, 5, 16
\n\t
"
/* reserve space on new stack */
"mtctr 3
\n\t
"
/* func -> ctr */
"mr 3,4
\n\t
"
/* args -> function param 1 (r3) */
"mr 1,5
\n\t
"
/* stack */
"li 0, 0
\n\t
"
/* zero */
"stw 0, 0(1)
\n\t
"
/* bottom of stack */
"stwu 1, -16(1)
\n\t
"
/* create a frame for this function */
"bctrl"
)
/* call ctr */
/***********************************************************************
* thread_startup
*/
static
void
thread_startup
(
void
*
param
)
{
CONTEXT
context
=
{
0
};
struct
startup_info
*
info
=
param
;
/* build the initial context */
context
.
ContextFlags
=
CONTEXT_FULL
;
context
.
Gpr1
=
(
DWORD
)
NtCurrentTeb
()
->
Tib
.
StackBase
;
context
.
Gpr3
=
(
DWORD
)
info
->
entry
;
context
.
Gpr4
=
(
DWORD
)
info
->
arg
;
context
.
Iar
=
(
DWORD
)
info
->
start
;
if
(
info
->
suspend
)
wait_suspend
(
&
context
);
LdrInitializeThunk
(
&
context
,
(
void
**
)
&
context
.
Gpr3
,
0
,
0
);
((
thread_start_func
)
context
.
Iar
)(
(
LPTHREAD_START_ROUTINE
)
context
.
Gpr3
,
(
void
*
)
context
.
Gpr4
);
}
/***********************************************************************
* signal_start_thread
*
* Thread startup sequence:
* signal_start_thread()
* -> thread_startup()
* -> call_thread_entry_point()
*/
void
signal_start_thread
(
LPTHREAD_START_ROUTINE
entry
,
void
*
arg
,
BOOL
suspend
)
{
struct
startup_info
info
=
{
call_thread_entry_point
,
entry
,
arg
,
suspend
};
switch_to_stack
(
thread_startup
,
&
info
,
NtCurrentTeb
()
->
Tib
.
StackBase
);
}
/**********************************************************************
* signal_start_process
*
* Process startup sequence:
* signal_start_process()
* -> thread_startup()
* -> kernel32_start_process()
*/
void
signal_start_process
(
LPTHREAD_START_ROUTINE
entry
,
BOOL
suspend
)
{
struct
startup_info
info
=
{
kernel32_start_process
,
entry
,
NtCurrentTeb
()
->
Peb
,
suspend
};
switch_to_stack
(
thread_startup
,
&
info
,
NtCurrentTeb
()
->
Tib
.
StackBase
);
}
/**********************************************************************
* DbgBreakPoint (NTDLL.@)
*/
...
...
dlls/ntdll/signal_x86_64.c
View file @
be0eb9c9
...
...
@@ -75,7 +75,6 @@
#endif
WINE_DEFAULT_DEBUG_CHANNEL
(
seh
);
WINE_DECLARE_DEBUG_CHANNEL
(
relay
);
typedef
struct
_SCOPE_TABLE
{
...
...
@@ -3661,135 +3660,6 @@ USHORT WINAPI RtlCaptureStackBackTrace( ULONG skip, ULONG count, PVOID *buffer,
}
/***********************************************************************
* call_thread_func
*/
static
void
WINAPI
call_thread_func
(
LPTHREAD_START_ROUTINE
entry
,
void
*
arg
)
{
__TRY
{
TRACE_
(
relay
)(
"
\1
Starting thread proc %p (arg=%p)
\n
"
,
entry
,
arg
);
RtlExitUserThread
(
entry
(
arg
));
}
__EXCEPT
(
call_unhandled_exception_filter
)
{
NtTerminateThread
(
GetCurrentThread
(),
GetExceptionCode
()
);
}
__ENDTRY
abort
();
/* should not be reached */
}
extern
void
DECLSPEC_NORETURN
start_thread
(
LPTHREAD_START_ROUTINE
entry
,
void
*
arg
,
BOOL
suspend
,
void
*
relay
);
__ASM_GLOBAL_FUNC
(
start_thread
,
"subq $56,%rsp
\n\t
"
__ASM_SEH
(
".seh_stackalloc 56
\n\t
"
)
__ASM_SEH
(
".seh_endprologue
\n\t
"
)
__ASM_CFI
(
".cfi_adjust_cfa_offset 56
\n\t
"
)
"movq %rbp,48(%rsp)
\n\t
"
__ASM_CFI
(
".cfi_rel_offset %rbp,48
\n\t
"
)
"movq %rbx,40(%rsp)
\n\t
"
__ASM_CFI
(
".cfi_rel_offset %rbx,40
\n\t
"
)
"movq %r12,32(%rsp)
\n\t
"
__ASM_CFI
(
".cfi_rel_offset %r12,32
\n\t
"
)
"movq %r13,24(%rsp)
\n\t
"
__ASM_CFI
(
".cfi_rel_offset %r13,24
\n\t
"
)
"movq %r14,16(%rsp)
\n\t
"
__ASM_CFI
(
".cfi_rel_offset %r14,16
\n\t
"
)
"movq %r15,8(%rsp)
\n\t
"
__ASM_CFI
(
".cfi_rel_offset %r15,8
\n\t
"
)
/* store exit frame */
"movq %gs:0x30,%rax
\n\t
"
"movq %rsp,0x330(%rax)
\n\t
"
/* amd64_thread_data()->exit_frame */
/* switch to thread stack */
"movq 8(%rax),%rax
\n\t
"
/* NtCurrentTeb()->Tib.StackBase */
"leaq -0x1000(%rax),%rsp
\n\t
"
/* attach dlls */
"call "
__ASM_NAME
(
"attach_thread"
)
"
\n\t
"
"movq %rax,%rsp
\n\t
"
/* clear the stack */
"andq $~0xfff,%rax
\n\t
"
/* round down to page size */
"movq %rax,%rdi
\n\t
"
"call "
__ASM_NAME
(
"virtual_clear_thread_stack"
)
"
\n\t
"
/* switch to the initial context */
"movq %rsp,%rdi
\n\t
"
"call "
__ASM_NAME
(
"set_cpu_context"
)
)
/***********************************************************************
* init_thread_context
*/
static
void
init_thread_context
(
CONTEXT
*
context
,
LPTHREAD_START_ROUTINE
entry
,
void
*
arg
,
void
*
relay
)
{
__asm__
(
"movw %%cs,%0"
:
"=m"
(
context
->
SegCs
)
);
__asm__
(
"movw %%ss,%0"
:
"=m"
(
context
->
SegSs
)
);
context
->
Rcx
=
(
ULONG_PTR
)
entry
;
context
->
Rdx
=
(
ULONG_PTR
)
arg
;
context
->
Rsp
=
(
ULONG_PTR
)
NtCurrentTeb
()
->
Tib
.
StackBase
-
0x28
;
context
->
Rip
=
(
ULONG_PTR
)
relay
;
context
->
EFlags
=
0x200
;
context
->
u
.
FltSave
.
ControlWord
=
0x27f
;
context
->
u
.
FltSave
.
MxCsr
=
context
->
MxCsr
=
0x1f80
;
}
/***********************************************************************
* attach_thread
*/
PCONTEXT
DECLSPEC_HIDDEN
attach_thread
(
LPTHREAD_START_ROUTINE
entry
,
void
*
arg
,
BOOL
suspend
,
void
*
relay
)
{
CONTEXT
*
ctx
;
if
(
suspend
)
{
CONTEXT
context
=
{
0
};
context
.
ContextFlags
=
CONTEXT_ALL
;
init_thread_context
(
&
context
,
entry
,
arg
,
relay
);
wait_suspend
(
&
context
);
ctx
=
(
CONTEXT
*
)((
ULONG_PTR
)
context
.
Rsp
&
~
15
)
-
1
;
*
ctx
=
context
;
}
else
{
ctx
=
(
CONTEXT
*
)((
char
*
)
NtCurrentTeb
()
->
Tib
.
StackBase
-
0x30
)
-
1
;
init_thread_context
(
ctx
,
entry
,
arg
,
relay
);
}
ctx
->
ContextFlags
=
CONTEXT_FULL
;
LdrInitializeThunk
(
ctx
,
(
void
**
)
&
ctx
->
Rcx
,
0
,
0
);
return
ctx
;
}
/***********************************************************************
* signal_start_thread
*
* Thread startup sequence:
* signal_start_thread()
* -> start_thread()
* -> call_thread_func()
*/
void
signal_start_thread
(
LPTHREAD_START_ROUTINE
entry
,
void
*
arg
,
BOOL
suspend
)
{
start_thread
(
entry
,
arg
,
suspend
,
call_thread_func
);
}
/**********************************************************************
* signal_start_process
*
* Process startup sequence:
* signal_start_process()
* -> start_thread()
* -> kernel32_start_process()
*/
void
signal_start_process
(
LPTHREAD_START_ROUTINE
entry
,
BOOL
suspend
)
{
start_thread
(
entry
,
NtCurrentTeb
()
->
Peb
,
suspend
,
kernel32_start_process
);
}
/**********************************************************************
* DbgBreakPoint (NTDLL.@)
*/
...
...
dlls/ntdll/thread.c
View file @
be0eb9c9
...
...
@@ -47,6 +47,7 @@
#include "wine/exception.h"
WINE_DEFAULT_DEBUG_CHANNEL
(
thread
);
WINE_DECLARE_DEBUG_CHANNEL
(
relay
);
#ifndef PTHREAD_STACK_MIN
#define PTHREAD_STACK_MIN 16384
...
...
@@ -336,13 +337,79 @@ void WINAPI RtlExitUserThread( ULONG status )
/***********************************************************************
* call_thread_entry_point
*/
#ifdef __i386__
extern
void
call_thread_entry_point
(
void
)
DECLSPEC_HIDDEN
;
__ASM_GLOBAL_FUNC
(
call_thread_entry_point
,
"pushl %ebp
\n\t
"
__ASM_CFI
(
".cfi_adjust_cfa_offset 4
\n\t
"
)
__ASM_CFI
(
".cfi_rel_offset %ebp,0
\n\t
"
)
"movl %esp,%ebp
\n\t
"
__ASM_CFI
(
".cfi_def_cfa_register %ebp
\n\t
"
)
"pushl %ebx
\n\t
"
/* arg */
"pushl %eax
\n\t
"
/* entry */
"call "
__ASM_NAME
(
"call_thread_func"
)
)
/* wrapper for apps that don't declare the thread function correctly */
extern
DWORD
call_thread_func_wrapper
(
LPTHREAD_START_ROUTINE
entry
,
void
*
arg
);
__ASM_GLOBAL_FUNC
(
call_thread_func_wrapper
,
"pushl %ebp
\n\t
"
__ASM_CFI
(
".cfi_adjust_cfa_offset 4
\n\t
"
)
__ASM_CFI
(
".cfi_rel_offset %ebp,0
\n\t
"
)
"movl %esp,%ebp
\n\t
"
__ASM_CFI
(
".cfi_def_cfa_register %ebp
\n\t
"
)
"subl $4,%esp
\n\t
"
"pushl 12(%ebp)
\n\t
"
"call *8(%ebp)
\n\t
"
"leave
\n\t
"
__ASM_CFI
(
".cfi_def_cfa %esp,4
\n\t
"
)
__ASM_CFI
(
".cfi_same_value %ebp
\n\t
"
)
"ret"
)
void
DECLSPEC_HIDDEN
call_thread_func
(
LPTHREAD_START_ROUTINE
entry
,
void
*
arg
)
{
__TRY
{
TRACE_
(
relay
)(
"
\1
Starting thread proc %p (arg=%p)
\n
"
,
entry
,
arg
);
RtlExitUserThread
(
call_thread_func_wrapper
(
entry
,
arg
));
}
__EXCEPT
(
call_unhandled_exception_filter
)
{
NtTerminateThread
(
GetCurrentThread
(),
GetExceptionCode
()
);
}
__ENDTRY
abort
();
/* should not be reached */
}
#else
/* __i386__ */
static
void
WINAPI
call_thread_entry_point
(
LPTHREAD_START_ROUTINE
entry
,
void
*
arg
)
{
__TRY
{
TRACE_
(
relay
)(
"
\1
Starting thread proc %p (arg=%p)
\n
"
,
entry
,
arg
);
RtlExitUserThread
(
entry
(
arg
));
}
__EXCEPT
(
call_unhandled_exception_filter
)
{
NtTerminateThread
(
GetCurrentThread
(),
GetExceptionCode
()
);
}
__ENDTRY
abort
();
/* should not be reached */
}
#endif
/* __i386__ */
/***********************************************************************
* start_thread
*
* Startup routine for a newly created thread.
*/
static
void
start_thread
(
struct
startup_info
*
info
)
{
BOOL
suspend
;
TEB
*
teb
=
info
->
teb
;
struct
ntdll_thread_data
*
thread_data
=
(
struct
ntdll_thread_data
*
)
&
teb
->
GdiTebBatch
;
struct
debug_info
debug_info
;
...
...
@@ -350,10 +417,7 @@ static void start_thread( struct startup_info *info )
debug_info
.
str_pos
=
debug_info
.
out_pos
=
0
;
thread_data
->
debug_info
=
&
debug_info
;
thread_data
->
pthread_id
=
pthread_self
();
unix_funcs
->
init_thread
(
teb
);
unix_funcs
->
server_init_thread
(
info
->
entry_point
,
&
suspend
,
NULL
,
NULL
,
NULL
);
signal_start_thread
(
(
LPTHREAD_START_ROUTINE
)
info
->
entry_point
,
info
->
entry_arg
,
suspend
);
unix_funcs
->
start_thread
(
info
->
entry_point
,
info
->
entry_arg
,
call_thread_entry_point
,
teb
);
}
...
...
dlls/ntdll/unix/loader.c
View file @
be0eb9c9
...
...
@@ -1035,7 +1035,8 @@ static struct unix_funcs unix_funcs =
virtual_release_address_space
,
virtual_set_large_address_space
,
init_threading
,
init_thread
,
start_thread
,
start_process
,
abort_thread
,
exit_thread
,
exit_process
,
...
...
dlls/ntdll/unix/signal_arm.c
View file @
be0eb9c9
...
...
@@ -363,6 +363,69 @@ void signal_init_thread( TEB *teb )
}
/***********************************************************************
* init_thread_context
*/
static
void
init_thread_context
(
CONTEXT
*
context
,
LPTHREAD_START_ROUTINE
entry
,
void
*
arg
,
void
*
relay
)
{
context
->
R0
=
(
DWORD
)
entry
;
context
->
R1
=
(
DWORD
)
arg
;
context
->
Sp
=
(
DWORD
)
NtCurrentTeb
()
->
Tib
.
StackBase
;
context
->
Pc
=
(
DWORD
)
relay
;
}
/***********************************************************************
* attach_thread
*/
PCONTEXT
DECLSPEC_HIDDEN
attach_thread
(
LPTHREAD_START_ROUTINE
entry
,
void
*
arg
,
BOOL
suspend
,
void
*
relay
)
{
CONTEXT
*
ctx
;
if
(
suspend
)
{
CONTEXT
context
=
{
CONTEXT_ALL
};
init_thread_context
(
&
context
,
entry
,
arg
,
relay
);
wait_suspend
(
&
context
);
ctx
=
(
CONTEXT
*
)((
ULONG_PTR
)
context
.
Sp
&
~
15
)
-
1
;
*
ctx
=
context
;
}
else
{
ctx
=
(
CONTEXT
*
)
NtCurrentTeb
()
->
Tib
.
StackBase
-
1
;
init_thread_context
(
ctx
,
entry
,
arg
,
relay
);
}
ctx
->
ContextFlags
=
CONTEXT_FULL
;
LdrInitializeThunk
(
ctx
,
(
void
**
)
&
ctx
->
R0
,
0
,
0
);
return
ctx
;
}
/***********************************************************************
* signal_start_thread
*/
__ASM_GLOBAL_FUNC
(
signal_start_thread
,
".arm
\n\t
"
"push {r4-r12,lr}
\n\t
"
/* store exit frame */
"ldr r4, [sp, #40]
\n\t
"
/* teb */
"str sp, [r4, #0x1d4]
\n\t
"
/* teb->SystemReserved2 */
/* switch to thread stack */
"ldr r4, [r4, #4]
\n\t
"
/* teb->Tib.StackBase */
"sub sp, r4, #0x1000
\n\t
"
/* attach dlls */
"bl "
__ASM_NAME
(
"attach_thread"
)
"
\n\t
"
"mov sp, r0
\n\t
"
/* clear the stack */
"and r0, #~0xff0
\n\t
"
/* round down to page size */
"bl "
__ASM_NAME
(
"virtual_clear_thread_stack"
)
"
\n\t
"
/* switch to the initial context */
"mov r0, sp
\n\t
"
"b "
__ASM_NAME
(
"set_cpu_context"
)
)
extern
void
DECLSPEC_NORETURN
call_thread_exit_func
(
int
status
,
void
(
*
func
)(
int
),
TEB
*
teb
);
__ASM_GLOBAL_FUNC
(
call_thread_exit_func
,
".arm
\n\t
"
...
...
dlls/ntdll/unix/signal_arm64.c
View file @
be0eb9c9
...
...
@@ -370,6 +370,109 @@ void signal_init_thread( TEB *teb )
}
/***********************************************************************
* init_thread_context
*/
static
void
init_thread_context
(
CONTEXT
*
context
,
LPTHREAD_START_ROUTINE
entry
,
void
*
arg
,
void
*
relay
)
{
context
->
u
.
s
.
X0
=
(
DWORD64
)
entry
;
context
->
u
.
s
.
X1
=
(
DWORD64
)
arg
;
context
->
u
.
s
.
X18
=
(
DWORD64
)
NtCurrentTeb
();
context
->
Sp
=
(
DWORD64
)
NtCurrentTeb
()
->
Tib
.
StackBase
;
context
->
Pc
=
(
DWORD64
)
relay
;
}
/***********************************************************************
* attach_thread
*/
PCONTEXT
DECLSPEC_HIDDEN
attach_thread
(
LPTHREAD_START_ROUTINE
entry
,
void
*
arg
,
BOOL
suspend
,
void
*
relay
)
{
CONTEXT
*
ctx
;
if
(
suspend
)
{
CONTEXT
context
=
{
CONTEXT_ALL
};
init_thread_context
(
&
context
,
entry
,
arg
,
relay
);
wait_suspend
(
&
context
);
ctx
=
(
CONTEXT
*
)((
ULONG_PTR
)
context
.
Sp
&
~
15
)
-
1
;
*
ctx
=
context
;
}
else
{
ctx
=
(
CONTEXT
*
)
NtCurrentTeb
()
->
Tib
.
StackBase
-
1
;
init_thread_context
(
ctx
,
entry
,
arg
,
relay
);
}
ctx
->
ContextFlags
=
CONTEXT_FULL
;
LdrInitializeThunk
(
ctx
,
(
void
**
)
&
ctx
->
u
.
s
.
X0
,
0
,
0
);
return
ctx
;
}
/***********************************************************************
* signal_start_thread
*/
__ASM_GLOBAL_FUNC
(
signal_start_thread
,
"stp x29, x30, [sp,#-16]!
\n\t
"
"mov x18, x4
\n\t
"
/* teb */
/* store exit frame */
"mov x29, sp
\n\t
"
"str x29, [x4, #0x300]
\n\t
"
/* arm64_thread_data()->exit_frame */
/* switch to thread stack */
"ldr x5, [x4, #8]
\n\t
"
/* teb->Tib.StackBase */
"sub sp, x5, #0x1000
\n\t
"
/* attach dlls */
"bl "
__ASM_NAME
(
"attach_thread"
)
"
\n\t
"
"mov sp, x0
\n\t
"
/* clear the stack */
"and x0, x0, #~0xfff
\n\t
"
/* round down to page size */
"bl "
__ASM_NAME
(
"virtual_clear_thread_stack"
)
"
\n\t
"
/* switch to the initial context */
"mov x0, sp
\n\t
"
"ldp q0, q1, [x0, #0x110]
\n\t
"
/* context->V[0,1] */
"ldp q2, q3, [x0, #0x130]
\n\t
"
/* context->V[2,3] */
"ldp q4, q5, [x0, #0x150]
\n\t
"
/* context->V[4,5] */
"ldp q6, q7, [x0, #0x170]
\n\t
"
/* context->V[6,7] */
"ldp q8, q9, [x0, #0x190]
\n\t
"
/* context->V[8,9] */
"ldp q10, q11, [x0, #0x1b0]
\n\t
"
/* context->V[10,11] */
"ldp q12, q13, [x0, #0x1d0]
\n\t
"
/* context->V[12,13] */
"ldp q14, q15, [x0, #0x1f0]
\n\t
"
/* context->V[14,15] */
"ldp q16, q17, [x0, #0x210]
\n\t
"
/* context->V[16,17] */
"ldp q18, q19, [x0, #0x230]
\n\t
"
/* context->V[18,19] */
"ldp q20, q21, [x0, #0x250]
\n\t
"
/* context->V[20,21] */
"ldp q22, q23, [x0, #0x270]
\n\t
"
/* context->V[22,23] */
"ldp q24, q25, [x0, #0x290]
\n\t
"
/* context->V[24,25] */
"ldp q26, q27, [x0, #0x2b0]
\n\t
"
/* context->V[26,27] */
"ldp q28, q29, [x0, #0x2d0]
\n\t
"
/* context->V[28,29] */
"ldp q30, q31, [x0, #0x2f0]
\n\t
"
/* context->V[30,31] */
"ldr w1, [x0, #0x310]
\n\t
"
/* context->Fpcr */
"msr fpcr, x1
\n\t
"
"ldr w1, [x0, #0x314]
\n\t
"
/* context->Fpsr */
"msr fpsr, x1
\n\t
"
"ldp x1, x2, [x0, #0x10]
\n\t
"
/* context->X1,2 */
"ldp x3, x4, [x0, #0x20]
\n\t
"
/* context->X3,4 */
"ldp x5, x6, [x0, #0x30]
\n\t
"
/* context->X5,6 */
"ldp x7, x8, [x0, #0x40]
\n\t
"
/* context->X7,8 */
"ldp x9, x10, [x0, #0x50]
\n\t
"
/* context->X9,10 */
"ldp x11, x12, [x0, #0x60]
\n\t
"
/* context->X11,12 */
"ldp x13, x14, [x0, #0x70]
\n\t
"
/* context->X13,14 */
"ldp x15, x16, [x0, #0x80]
\n\t
"
/* context->X15,16 */
"ldp x17, x18, [x0, #0x90]
\n\t
"
/* context->X17,18 */
"ldp x19, x20, [x0, #0xa0]
\n\t
"
/* context->X19,20 */
"ldp x21, x22, [x0, #0xb0]
\n\t
"
/* context->X21,22 */
"ldp x23, x24, [x0, #0xc0]
\n\t
"
/* context->X23,24 */
"ldp x25, x26, [x0, #0xd0]
\n\t
"
/* context->X25,26 */
"ldp x27, x28, [x0, #0xe0]
\n\t
"
/* context->X27,28 */
"ldp x29, x30, [x0, #0xf0]
\n\t
"
/* context->Fp,Lr */
"ldr x17, [x0, #0x100]
\n\t
"
/* context->Sp */
"mov sp, x17
\n\t
"
"ldr x17, [x0, #0x108]
\n\t
"
/* context->Pc */
"ldr x0, [x0, #0x8]
\n\t
"
/* context->X0 */
"br x17"
)
extern
void
DECLSPEC_NORETURN
call_thread_exit_func
(
int
status
,
void
(
*
func
)(
int
),
TEB
*
teb
);
__ASM_GLOBAL_FUNC
(
call_thread_exit_func
,
"stp x29, x30, [sp,#-16]!
\n\t
"
...
...
dlls/ntdll/unix/signal_i386.c
View file @
be0eb9c9
...
...
@@ -961,6 +961,94 @@ void signal_init_thread( TEB *teb )
/***********************************************************************
* init_thread_context
*/
static
void
init_thread_context
(
CONTEXT
*
context
,
LPTHREAD_START_ROUTINE
entry
,
void
*
arg
,
void
*
relay
)
{
context
->
SegCs
=
get_cs
();
context
->
SegDs
=
get_ds
();
context
->
SegEs
=
get_ds
();
context
->
SegFs
=
get_fs
();
context
->
SegGs
=
get_gs
();
context
->
SegSs
=
get_ds
();
context
->
EFlags
=
0x202
;
context
->
Eax
=
(
DWORD
)
entry
;
context
->
Ebx
=
(
DWORD
)
arg
;
context
->
Esp
=
(
DWORD
)
NtCurrentTeb
()
->
Tib
.
StackBase
-
16
;
context
->
Eip
=
(
DWORD
)
relay
;
context
->
FloatSave
.
ControlWord
=
0x27f
;
((
XMM_SAVE_AREA32
*
)
context
->
ExtendedRegisters
)
->
ControlWord
=
0x27f
;
((
XMM_SAVE_AREA32
*
)
context
->
ExtendedRegisters
)
->
MxCsr
=
0x1f80
;
}
/***********************************************************************
* attach_thread
*/
PCONTEXT
DECLSPEC_HIDDEN
attach_thread
(
LPTHREAD_START_ROUTINE
entry
,
void
*
arg
,
BOOL
suspend
,
void
*
relay
)
{
CONTEXT
*
ctx
;
if
(
suspend
)
{
CONTEXT
context
=
{
CONTEXT_ALL
};
init_thread_context
(
&
context
,
entry
,
arg
,
relay
);
wait_suspend
(
&
context
);
ctx
=
(
CONTEXT
*
)((
ULONG_PTR
)
context
.
Esp
&
~
15
)
-
1
;
*
ctx
=
context
;
}
else
{
ctx
=
(
CONTEXT
*
)((
char
*
)
NtCurrentTeb
()
->
Tib
.
StackBase
-
16
)
-
1
;
init_thread_context
(
ctx
,
entry
,
arg
,
relay
);
}
ctx
->
ContextFlags
=
CONTEXT_FULL
|
CONTEXT_FLOATING_POINT
|
CONTEXT_EXTENDED_REGISTERS
;
LdrInitializeThunk
(
ctx
,
(
void
**
)
&
ctx
->
Eax
,
0
,
0
);
return
ctx
;
}
/***********************************************************************
* signal_start_thread
*/
__ASM_GLOBAL_FUNC
(
signal_start_thread
,
"pushl %ebp
\n\t
"
__ASM_CFI
(
".cfi_adjust_cfa_offset 4
\n\t
"
)
__ASM_CFI
(
".cfi_rel_offset %ebp,0
\n\t
"
)
"movl %esp,%ebp
\n\t
"
__ASM_CFI
(
".cfi_def_cfa_register %ebp
\n\t
"
)
"pushl %ebx
\n\t
"
__ASM_CFI
(
".cfi_rel_offset %ebx,-4
\n\t
"
)
"pushl %esi
\n\t
"
__ASM_CFI
(
".cfi_rel_offset %esi,-8
\n\t
"
)
"pushl %edi
\n\t
"
__ASM_CFI
(
".cfi_rel_offset %edi,-12
\n\t
"
)
/* store exit frame */
"movl %ebp,%fs:0x1f4
\n\t
"
/* x86_thread_data()->exit_frame */
/* switch to thread stack */
"movl %fs:4,%eax
\n\t
"
/* NtCurrentTeb()->StackBase */
"leal -0x1000(%eax),%esp
\n\t
"
/* attach dlls */
"pushl 20(%ebp)
\n\t
"
/* relay */
"pushl 16(%ebp)
\n\t
"
/* suspend */
"pushl 12(%ebp)
\n\t
"
/* arg */
"pushl 8(%ebp)
\n\t
"
/* entry */
"xorl %ebp,%ebp
\n\t
"
"call "
__ASM_NAME
(
"attach_thread"
)
"
\n\t
"
"movl %eax,%esi
\n\t
"
"leal -12(%eax),%esp
\n\t
"
/* clear the stack */
"andl $~0xfff,%eax
\n\t
"
/* round down to page size */
"movl %eax,(%esp)
\n\t
"
"call "
__ASM_NAME
(
"virtual_clear_thread_stack"
)
"
\n\t
"
/* switch to the initial context */
"movl %esi,(%esp)
\n\t
"
"call "
__ASM_NAME
(
"set_cpu_context"
)
)
/***********************************************************************
* signal_exit_thread
*/
__ASM_GLOBAL_FUNC
(
signal_exit_thread
,
...
...
dlls/ntdll/unix/signal_x86_64.c
View file @
be0eb9c9
...
...
@@ -651,6 +651,90 @@ void signal_init_thread( TEB *teb )
/***********************************************************************
* init_thread_context
*/
static
void
init_thread_context
(
CONTEXT
*
context
,
LPTHREAD_START_ROUTINE
entry
,
void
*
arg
,
void
*
relay
)
{
__asm__
(
"movw %%cs,%0"
:
"=m"
(
context
->
SegCs
)
);
__asm__
(
"movw %%ss,%0"
:
"=m"
(
context
->
SegSs
)
);
context
->
Rcx
=
(
ULONG_PTR
)
entry
;
context
->
Rdx
=
(
ULONG_PTR
)
arg
;
context
->
Rsp
=
(
ULONG_PTR
)
NtCurrentTeb
()
->
Tib
.
StackBase
-
0x28
;
context
->
Rip
=
(
ULONG_PTR
)
relay
;
context
->
EFlags
=
0x200
;
context
->
u
.
FltSave
.
ControlWord
=
0x27f
;
context
->
u
.
FltSave
.
MxCsr
=
context
->
MxCsr
=
0x1f80
;
}
/***********************************************************************
* attach_thread
*/
PCONTEXT
DECLSPEC_HIDDEN
attach_thread
(
LPTHREAD_START_ROUTINE
entry
,
void
*
arg
,
BOOL
suspend
,
void
*
relay
)
{
CONTEXT
*
ctx
;
if
(
suspend
)
{
CONTEXT
context
=
{
0
};
context
.
ContextFlags
=
CONTEXT_ALL
;
init_thread_context
(
&
context
,
entry
,
arg
,
relay
);
wait_suspend
(
&
context
);
ctx
=
(
CONTEXT
*
)((
ULONG_PTR
)
context
.
Rsp
&
~
15
)
-
1
;
*
ctx
=
context
;
}
else
{
ctx
=
(
CONTEXT
*
)((
char
*
)
NtCurrentTeb
()
->
Tib
.
StackBase
-
0x30
)
-
1
;
init_thread_context
(
ctx
,
entry
,
arg
,
relay
);
}
ctx
->
ContextFlags
=
CONTEXT_FULL
;
LdrInitializeThunk
(
ctx
,
(
void
**
)
&
ctx
->
Rcx
,
0
,
0
);
return
ctx
;
}
/***********************************************************************
* signal_start_thread
*/
__ASM_GLOBAL_FUNC
(
signal_start_thread
,
"subq $56,%rsp
\n\t
"
__ASM_SEH
(
".seh_stackalloc 56
\n\t
"
)
__ASM_SEH
(
".seh_endprologue
\n\t
"
)
__ASM_CFI
(
".cfi_adjust_cfa_offset 56
\n\t
"
)
"movq %rbp,48(%rsp)
\n\t
"
__ASM_CFI
(
".cfi_rel_offset %rbp,48
\n\t
"
)
"movq %rbx,40(%rsp)
\n\t
"
__ASM_CFI
(
".cfi_rel_offset %rbx,40
\n\t
"
)
"movq %r12,32(%rsp)
\n\t
"
__ASM_CFI
(
".cfi_rel_offset %r12,32
\n\t
"
)
"movq %r13,24(%rsp)
\n\t
"
__ASM_CFI
(
".cfi_rel_offset %r13,24
\n\t
"
)
"movq %r14,16(%rsp)
\n\t
"
__ASM_CFI
(
".cfi_rel_offset %r14,16
\n\t
"
)
"movq %r15,8(%rsp)
\n\t
"
__ASM_CFI
(
".cfi_rel_offset %r15,8
\n\t
"
)
/* store exit frame */
"movq %gs:0x30,%rax
\n\t
"
"movq %rsp,0x330(%rax)
\n\t
"
/* amd64_thread_data()->exit_frame */
/* switch to thread stack */
"movq 8(%rax),%rax
\n\t
"
/* NtCurrentTeb()->Tib.StackBase */
"leaq -0x1000(%rax),%rsp
\n\t
"
/* attach dlls */
"call "
__ASM_NAME
(
"attach_thread"
)
"
\n\t
"
"movq %rax,%rsp
\n\t
"
/* clear the stack */
"andq $~0xfff,%rax
\n\t
"
/* round down to page size */
"movq %rax,%rdi
\n\t
"
"call "
__ASM_NAME
(
"virtual_clear_thread_stack"
)
"
\n\t
"
/* switch to the initial context */
"movq %rsp,%rdi
\n\t
"
"call "
__ASM_NAME
(
"set_cpu_context"
)
)
/***********************************************************************
* signal_exit_thread
*/
__ASM_GLOBAL_FUNC
(
signal_exit_thread
,
...
...
dlls/ntdll/unix/thread.c
View file @
be0eb9c9
...
...
@@ -26,6 +26,7 @@
#include "wine/port.h"
#include <assert.h>
#include <errno.h>
#include <limits.h>
#include <stdarg.h>
#include <pthread.h>
...
...
@@ -92,11 +93,24 @@ void CDECL init_threading( int *nb_threads_ptr, struct ldt_copy **ldt_copy )
/***********************************************************************
*
ini
t_thread
*
star
t_thread
*/
void
CDECL
init_thread
(
TEB
*
teb
)
void
CDECL
start_thread
(
PRTL_THREAD_START_ROUTINE
entry
,
void
*
arg
,
void
*
relay
,
TEB
*
teb
)
{
BOOL
suspend
;
signal_init_thread
(
teb
);
server_init_thread
(
entry
,
&
suspend
,
NULL
,
NULL
,
NULL
);
signal_start_thread
(
entry
,
arg
,
suspend
,
relay
,
teb
);
}
/***********************************************************************
* start_process
*/
void
CDECL
start_process
(
PRTL_THREAD_START_ROUTINE
entry
,
BOOL
suspend
,
void
*
relay
)
{
signal_start_thread
(
entry
,
NtCurrentTeb
()
->
Peb
,
suspend
,
relay
,
NtCurrentTeb
()
);
}
...
...
@@ -131,6 +145,21 @@ void CDECL exit_process( int status )
}
/**********************************************************************
* wait_suspend
*
* Wait until the thread is no longer suspended.
*/
void
wait_suspend
(
CONTEXT
*
context
)
{
int
saved_errno
=
errno
;
/* wait with 0 timeout, will only return once the thread is no longer suspended */
server_select
(
NULL
,
0
,
SELECT_INTERRUPTIBLE
,
0
,
context
,
NULL
,
NULL
);
errno
=
saved_errno
;
}
/***********************************************************************
* set_thread_context
*/
...
...
dlls/ntdll/unix/unix_private.h
View file @
be0eb9c9
...
...
@@ -50,6 +50,8 @@ static inline struct ntdll_thread_data *ntdll_get_thread_data(void)
return
(
struct
ntdll_thread_data
*
)
&
NtCurrentTeb
()
->
GdiTebBatch
;
}
void
WINAPI
LdrInitializeThunk
(
CONTEXT
*
,
void
**
,
ULONG_PTR
,
ULONG_PTR
);
void
CDECL
mmap_add_reserved_area
(
void
*
addr
,
SIZE_T
size
)
DECLSPEC_HIDDEN
;
void
CDECL
mmap_remove_reserved_area
(
void
*
addr
,
SIZE_T
size
)
DECLSPEC_HIDDEN
;
int
CDECL
mmap_is_in_reserved_area
(
void
*
addr
,
SIZE_T
size
)
DECLSPEC_HIDDEN
;
...
...
@@ -104,7 +106,8 @@ extern void CDECL server_init_process_done(void) DECLSPEC_HIDDEN;
extern
size_t
CDECL
server_init_thread
(
void
*
entry_point
,
BOOL
*
suspend
,
unsigned
int
*
cpus
,
BOOL
*
wow64
,
timeout_t
*
start_time
)
DECLSPEC_HIDDEN
;
extern
void
CDECL
init_threading
(
int
*
nb_threads
,
struct
ldt_copy
**
ldt_copy
)
DECLSPEC_HIDDEN
;
extern
void
CDECL
init_thread
(
TEB
*
teb
)
DECLSPEC_HIDDEN
;
extern
void
CDECL
DECLSPEC_NORETURN
start_thread
(
PRTL_THREAD_START_ROUTINE
entry
,
void
*
arg
,
void
*
relay
,
TEB
*
teb
)
DECLSPEC_HIDDEN
;
extern
void
CDECL
DECLSPEC_NORETURN
start_process
(
PRTL_THREAD_START_ROUTINE
entry
,
BOOL
suspend
,
void
*
relay
)
DECLSPEC_HIDDEN
;
extern
void
CDECL
DECLSPEC_NORETURN
abort_thread
(
int
status
)
DECLSPEC_HIDDEN
;
extern
void
CDECL
DECLSPEC_NORETURN
exit_thread
(
int
status
)
DECLSPEC_HIDDEN
;
extern
void
CDECL
DECLSPEC_NORETURN
exit_process
(
int
status
)
DECLSPEC_HIDDEN
;
...
...
@@ -125,6 +128,7 @@ extern void start_server( BOOL debug ) 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
void
wait_suspend
(
CONTEXT
*
context
)
DECLSPEC_HIDDEN
;
extern
NTSTATUS
set_thread_context
(
HANDLE
handle
,
const
context_t
*
context
,
BOOL
*
self
)
DECLSPEC_HIDDEN
;
extern
NTSTATUS
get_thread_context
(
HANDLE
handle
,
context_t
*
context
,
unsigned
int
flags
,
BOOL
*
self
)
DECLSPEC_HIDDEN
;
...
...
@@ -132,6 +136,8 @@ extern void signal_init_threading(void) DECLSPEC_HIDDEN;
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
DECLSPEC_NORETURN
signal_start_thread
(
PRTL_THREAD_START_ROUTINE
entry
,
void
*
arg
,
BOOL
suspend
,
void
*
relay
,
TEB
*
teb
)
DECLSPEC_HIDDEN
;
extern
void
DECLSPEC_NORETURN
signal_exit_thread
(
int
status
,
void
(
*
func
)(
int
)
)
DECLSPEC_HIDDEN
;
#endif
/* __NTDLL_UNIX_PRIVATE_H */
dlls/ntdll/unix/virtual.c
View file @
be0eb9c9
...
...
@@ -2722,6 +2722,21 @@ done:
/***********************************************************************
* virtual_clear_thread_stack
*
* Clear the stack contents before calling the main entry point, some broken apps need that.
*/
void
virtual_clear_thread_stack
(
void
*
stack_end
)
{
void
*
stack
=
NtCurrentTeb
()
->
Tib
.
StackLimit
;
size_t
size
=
(
char
*
)
stack_end
-
(
char
*
)
stack
;
wine_anon_mmap
(
stack
,
size
,
PROT_READ
|
PROT_WRITE
,
MAP_FIXED
);
if
(
force_exec_prot
)
mprotect
(
stack
,
size
,
PROT_READ
|
PROT_WRITE
|
PROT_EXEC
);
}
/***********************************************************************
* virtual_handle_fault
*/
NTSTATUS
CDECL
virtual_handle_fault
(
LPCVOID
addr
,
DWORD
err
,
BOOL
on_signal_stack
)
...
...
dlls/ntdll/unixlib.h
View file @
be0eb9c9
...
...
@@ -28,7 +28,7 @@ struct ldt_copy;
struct
msghdr
;
/* increment this when you change the function table */
#define NTDLL_UNIXLIB_VERSION 1
6
#define NTDLL_UNIXLIB_VERSION 1
7
struct
unix_funcs
{
...
...
@@ -112,7 +112,8 @@ struct unix_funcs
/* thread/process functions */
void
(
CDECL
*
init_threading
)(
int
*
nb_threads
,
struct
ldt_copy
**
ldt_copy
);
void
(
CDECL
*
init_thread
)(
TEB
*
teb
);
void
(
CDECL
*
start_thread
)(
PRTL_THREAD_START_ROUTINE
entry
,
void
*
arg
,
void
*
relay
,
TEB
*
teb
);
void
(
CDECL
*
start_process
)(
PRTL_THREAD_START_ROUTINE
entry
,
BOOL
suspend
,
void
*
relay
);
void
(
CDECL
*
abort_thread
)(
int
status
);
void
(
CDECL
*
exit_thread
)(
int
status
);
void
(
CDECL
*
exit_process
)(
int
status
);
...
...
dlls/ntdll/virtual.c
View file @
be0eb9c9
...
...
@@ -84,8 +84,6 @@ static SIZE_T signal_stack_align;
#define ROUND_SIZE(addr,size) \
(((SIZE_T)(size) + ((UINT_PTR)(addr) & page_mask) + page_mask) & ~page_mask)
static
BOOL
force_exec_prot
;
/* whether to force PROT_EXEC on all PROT_READ mmaps */
/***********************************************************************
* get_vprot_flags
*
...
...
@@ -139,31 +137,6 @@ static NTSTATUS get_vprot_flags( DWORD protect, unsigned int *vprot, BOOL image
}
/***********************************************************************
* virtual_clear_thread_stack
*
* Clear the stack contents before calling the main entry point, some broken apps need that.
*/
void
virtual_clear_thread_stack
(
void
*
stack_end
)
{
void
*
stack
=
NtCurrentTeb
()
->
Tib
.
StackLimit
;
size_t
size
=
(
char
*
)
stack_end
-
(
char
*
)
stack
;
wine_anon_mmap
(
stack
,
size
,
PROT_READ
|
PROT_WRITE
,
MAP_FIXED
);
if
(
force_exec_prot
)
mprotect
(
stack
,
size
,
PROT_READ
|
PROT_WRITE
|
PROT_EXEC
);
}
/***********************************************************************
* VIRTUAL_SetForceExec
*
* Whether to force exec prot on all views.
*/
void
VIRTUAL_SetForceExec
(
BOOL
enable
)
{
force_exec_prot
=
enable
;
unix_funcs
->
virtual_set_force_exec
(
enable
);
}
/**********************************************************************
* RtlCreateUserStack (NTDLL.@)
*/
...
...
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