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
308a5e7c
Commit
308a5e7c
authored
Jun 11, 2021
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ntdll: Switch to the kernel stack for syscalls on i386.
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
6b277dc8
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
186 additions
and
256 deletions
+186
-256
signal_i386.c
dlls/ntdll/unix/signal_i386.c
+116
-134
import.c
tools/winebuild/import.c
+70
-122
No files found.
dlls/ntdll/unix/signal_i386.c
View file @
308a5e7c
...
...
@@ -481,26 +481,39 @@ C_ASSERT( sizeof(struct syscall_xsave) == 0x2c0 );
struct
syscall_frame
{
DWORD
restore_flags
;
/* 00 */
DWORD
eflags
;
/* 04 */
DWORD
eip
;
/* 08 */
DWORD
esp
;
/* 0c */
WORD
cs
;
/* 10 */
WORD
ss
;
/* 12 */
WORD
ds
;
/* 14 */
WORD
es
;
/* 16 */
WORD
fs
;
/* 18 */
WORD
gs
;
/* 1a */
DWORD
eax
;
/* 1c */
DWORD
ebx
;
/* 20 */
DWORD
ecx
;
/* 24 */
DWORD
edx
;
/* 28 */
DWORD
edi
;
/* 2c */
DWORD
esi
;
/* 30 */
DWORD
ebp
;
/* 34 */
DWORD
restore_flags
;
/* 000 */
DWORD
eflags
;
/* 004 */
DWORD
eip
;
/* 008 */
DWORD
esp
;
/* 00c */
WORD
cs
;
/* 010 */
WORD
ss
;
/* 012 */
WORD
ds
;
/* 014 */
WORD
es
;
/* 016 */
WORD
fs
;
/* 018 */
WORD
gs
;
/* 01a */
DWORD
eax
;
/* 01c */
DWORD
ebx
;
/* 020 */
DWORD
ecx
;
/* 024 */
DWORD
edx
;
/* 028 */
DWORD
edi
;
/* 02c */
DWORD
esi
;
/* 030 */
DWORD
ebp
;
/* 034 */
DWORD
align
[
2
];
/* 038 */
union
/* 040 */
{
XSAVE_FORMAT
xsave
;
FLOATING_SAVE_AREA
fsave
;
}
u
;
struct
/* 240 */
{
ULONG64
mask
;
ULONG64
compaction_mask
;
ULONG64
reserved
[
6
];
M128A
ymm_high
[
8
];
}
xstate
;
};
C_ASSERT
(
sizeof
(
struct
syscall_frame
)
==
0x3
8
);
C_ASSERT
(
sizeof
(
struct
syscall_frame
)
==
0x3
00
);
struct
x86_thread_data
{
...
...
@@ -531,11 +544,6 @@ static inline struct x86_thread_data *x86_thread_data(void)
return
(
struct
x86_thread_data
*
)
ntdll_get_thread_data
()
->
cpu_data
;
}
static
struct
syscall_xsave
*
get_syscall_xsave
(
struct
syscall_frame
*
frame
)
{
return
(
struct
syscall_xsave
*
)((
ULONG_PTR
)((
struct
syscall_xsave
*
)
frame
-
1
)
&
~
63
);
}
static
inline
WORD
get_cs
(
void
)
{
WORD
res
;
__asm__
(
"movw %%cs,%0"
:
"=r"
(
res
)
);
return
res
;
}
static
inline
WORD
get_ds
(
void
)
{
WORD
res
;
__asm__
(
"movw %%ds,%0"
:
"=r"
(
res
)
);
return
res
;
}
static
inline
WORD
get_fs
(
void
)
{
WORD
res
;
__asm__
(
"movw %%fs,%0"
:
"=r"
(
res
)
);
return
res
;
}
...
...
@@ -584,6 +592,15 @@ static inline TEB *get_current_teb(void)
}
/***********************************************************************
* is_inside_syscall
*/
static
BOOL
is_inside_syscall
(
ucontext_t
*
sigcontext
)
{
return
((
char
*
)
ESP_sig
(
sigcontext
)
>=
(
char
*
)
ntdll_get_thread_data
()
->
kernel_stack
&&
(
char
*
)
ESP_sig
(
sigcontext
)
<=
(
char
*
)
x86_thread_data
()
->
syscall_frame
);
}
#ifdef __sun
/* We have to workaround two Solaris breakages:
...
...
@@ -989,37 +1006,34 @@ NTSTATUS WINAPI NtSetContextThread( HANDLE handle, const CONTEXT *context )
}
if
(
flags
&
CONTEXT_EXTENDED_REGISTERS
)
{
struct
syscall_xsave
*
xsave
=
get_syscall_xsave
(
frame
);
memcpy
(
&
xsave
->
u
.
xsave
,
context
->
ExtendedRegisters
,
sizeof
(
xsave
->
u
.
xsave
)
);
memcpy
(
&
frame
->
u
.
xsave
,
context
->
ExtendedRegisters
,
sizeof
(
frame
->
u
.
xsave
)
);
/* reset the current interrupt status */
xsave
->
u
.
xsave
.
StatusWord
&=
xsav
e
->
u
.
xsave
.
ControlWord
|
0xff80
;
xsav
e
->
xstate
.
mask
|=
XSTATE_MASK_LEGACY
;
frame
->
u
.
xsave
.
StatusWord
&=
fram
e
->
u
.
xsave
.
ControlWord
|
0xff80
;
fram
e
->
xstate
.
mask
|=
XSTATE_MASK_LEGACY
;
}
else
if
(
flags
&
CONTEXT_FLOATING_POINT
)
{
struct
syscall_xsave
*
xsave
=
get_syscall_xsave
(
frame
);
if
(
cpu_info
.
ProcessorFeatureBits
&
CPU_FEATURE_FXSR
)
{
fpu_to_fpux
(
&
xsav
e
->
u
.
xsave
,
&
context
->
FloatSave
);
fpu_to_fpux
(
&
fram
e
->
u
.
xsave
,
&
context
->
FloatSave
);
}
else
{
xsav
e
->
u
.
fsave
=
context
->
FloatSave
;
fram
e
->
u
.
fsave
=
context
->
FloatSave
;
}
xsav
e
->
xstate
.
mask
|=
XSTATE_MASK_LEGACY_FLOATING_POINT
;
fram
e
->
xstate
.
mask
|=
XSTATE_MASK_LEGACY_FLOATING_POINT
;
}
if
(
flags
&
CONTEXT_XSTATE
)
{
struct
syscall_xsave
*
xsave
=
get_syscall_xsave
(
frame
);
CONTEXT_EX
*
context_ex
=
(
CONTEXT_EX
*
)(
context
+
1
);
XSTATE
*
xs
=
(
XSTATE
*
)((
char
*
)
context_ex
+
context_ex
->
XState
.
Offset
);
if
(
xs
->
Mask
&
XSTATE_MASK_GSSE
)
{
xsav
e
->
xstate
.
mask
|=
XSTATE_MASK_GSSE
;
memcpy
(
&
xsave
->
xstate
.
ymm_high
,
&
xs
->
YmmContext
,
sizeof
(
xsav
e
->
xstate
.
ymm_high
)
);
fram
e
->
xstate
.
mask
|=
XSTATE_MASK_GSSE
;
memcpy
(
&
frame
->
xstate
.
ymm_high
,
&
xs
->
YmmContext
,
sizeof
(
fram
e
->
xstate
.
ymm_high
)
);
}
else
xsav
e
->
xstate
.
mask
&=
~
XSTATE_MASK_GSSE
;
else
fram
e
->
xstate
.
mask
&=
~
XSTATE_MASK_GSSE
;
}
frame
->
restore_flags
|=
flags
&
~
CONTEXT_INTEGER
;
...
...
@@ -1052,7 +1066,6 @@ NTSTATUS WINAPI NtGetContextThread( HANDLE handle, CONTEXT *context )
if
(
self
)
{
struct
syscall_xsave
*
xsave
=
get_syscall_xsave
(
frame
);
XSTATE
*
xstate
;
if
(
needed_flags
&
CONTEXT_INTEGER
)
{
...
...
@@ -1086,12 +1099,12 @@ NTSTATUS WINAPI NtGetContextThread( HANDLE handle, CONTEXT *context )
{
if
(
!
(
cpu_info
.
ProcessorFeatureBits
&
CPU_FEATURE_FXSR
))
{
context
->
FloatSave
=
xsav
e
->
u
.
fsave
;
context
->
FloatSave
=
fram
e
->
u
.
fsave
;
}
else
if
(
!
xstate_compaction_enabled
||
(
xsav
e
->
xstate
.
mask
&
XSTATE_MASK_LEGACY_FLOATING_POINT
))
(
fram
e
->
xstate
.
mask
&
XSTATE_MASK_LEGACY_FLOATING_POINT
))
{
fpux_to_fpu
(
&
context
->
FloatSave
,
&
xsav
e
->
u
.
xsave
);
fpux_to_fpu
(
&
context
->
FloatSave
,
&
fram
e
->
u
.
xsave
);
}
else
{
...
...
@@ -1105,10 +1118,10 @@ NTSTATUS WINAPI NtGetContextThread( HANDLE handle, CONTEXT *context )
XSAVE_FORMAT
*
xs
=
(
XSAVE_FORMAT
*
)
context
->
ExtendedRegisters
;
if
(
!
xstate_compaction_enabled
||
(
xsav
e
->
xstate
.
mask
&
XSTATE_MASK_LEGACY_FLOATING_POINT
))
(
fram
e
->
xstate
.
mask
&
XSTATE_MASK_LEGACY_FLOATING_POINT
))
{
memcpy
(
xs
,
&
xsav
e
->
u
.
xsave
,
FIELD_OFFSET
(
XSAVE_FORMAT
,
MxCsr
));
memcpy
(
xs
->
FloatRegisters
,
xsav
e
->
u
.
xsave
.
FloatRegisters
,
memcpy
(
xs
,
&
fram
e
->
u
.
xsave
,
FIELD_OFFSET
(
XSAVE_FORMAT
,
MxCsr
));
memcpy
(
xs
->
FloatRegisters
,
fram
e
->
u
.
xsave
.
FloatRegisters
,
sizeof
(
xs
->
FloatRegisters
));
}
else
...
...
@@ -1118,11 +1131,11 @@ NTSTATUS WINAPI NtGetContextThread( HANDLE handle, CONTEXT *context )
xs
->
ControlWord
=
0x37f
;
}
if
(
!
xstate_compaction_enabled
||
(
xsav
e
->
xstate
.
mask
&
XSTATE_MASK_LEGACY_SSE
))
if
(
!
xstate_compaction_enabled
||
(
fram
e
->
xstate
.
mask
&
XSTATE_MASK_LEGACY_SSE
))
{
memcpy
(
xs
->
XmmRegisters
,
xsav
e
->
u
.
xsave
.
XmmRegisters
,
sizeof
(
xs
->
XmmRegisters
));
xs
->
MxCsr
=
xsav
e
->
u
.
xsave
.
MxCsr
;
xs
->
MxCsr_Mask
=
xsav
e
->
u
.
xsave
.
MxCsr_Mask
;
memcpy
(
xs
->
XmmRegisters
,
fram
e
->
u
.
xsave
.
XmmRegisters
,
sizeof
(
xs
->
XmmRegisters
));
xs
->
MxCsr
=
fram
e
->
u
.
xsave
.
MxCsr
;
xs
->
MxCsr_Mask
=
fram
e
->
u
.
xsave
.
MxCsr_Mask
;
}
else
{
...
...
@@ -1145,7 +1158,6 @@ NTSTATUS WINAPI NtGetContextThread( HANDLE handle, CONTEXT *context )
}
if
((
cpu_info
.
ProcessorFeatureBits
&
CPU_FEATURE_AVX
)
&&
(
xstate
=
xstate_from_context
(
context
)))
{
struct
syscall_xsave
*
xsave
=
get_syscall_xsave
(
frame
);
CONTEXT_EX
*
context_ex
=
(
CONTEXT_EX
*
)(
context
+
1
);
unsigned
int
mask
;
...
...
@@ -1154,7 +1166,7 @@ NTSTATUS WINAPI NtGetContextThread( HANDLE handle, CONTEXT *context )
return
STATUS_INVALID_PARAMETER
;
mask
=
(
xstate_compaction_enabled
?
xstate
->
CompactionMask
:
xstate
->
Mask
)
&
XSTATE_MASK_GSSE
;
xstate
->
Mask
=
xsav
e
->
xstate
.
mask
&
mask
;
xstate
->
Mask
=
fram
e
->
xstate
.
mask
&
mask
;
xstate
->
CompactionMask
=
xstate_compaction_enabled
?
(
0x8000000000000000
|
mask
)
:
0
;
memset
(
xstate
->
Reserved
,
0
,
sizeof
(
xstate
->
Reserved
)
);
if
(
xstate
->
Mask
)
...
...
@@ -1162,7 +1174,7 @@ NTSTATUS WINAPI NtGetContextThread( HANDLE handle, CONTEXT *context )
if
(
context_ex
->
XState
.
Length
<
sizeof
(
XSTATE
))
return
STATUS_BUFFER_OVERFLOW
;
memcpy
(
&
xstate
->
YmmContext
,
xsave
->
xstate
.
ymm_high
,
sizeof
(
xsav
e
->
xstate
.
ymm_high
)
);
memcpy
(
&
xstate
->
YmmContext
,
frame
->
xstate
.
ymm_high
,
sizeof
(
fram
e
->
xstate
.
ymm_high
)
);
}
}
}
...
...
@@ -1543,74 +1555,45 @@ static void setup_exception( ucontext_t *sigcontext, EXCEPTION_RECORD *rec )
* FIXME: match Windows ABI. */
struct
apc_stack_layout
{
void
*
context_ptr
;
void
*
arg1
;
void
*
arg2
;
void
*
arg3
;
void
*
func
;
CONTEXT
*
context_ptr
;
ULONG_PTR
arg1
;
ULONG_PTR
arg2
;
ULONG_PTR
arg3
;
PNTAPCFUNC
func
;
CONTEXT
context
;
};
struct
apc_stack_layout
*
WINAPI
setup_user_apc_dispatcher_stack
(
CONTEXT
*
context
,
struct
apc_stack_layout
*
stack
,
void
*
arg1
,
void
*
arg2
,
void
*
arg3
,
void
*
func
,
NTSTATUS
status
)
DECLSPEC_HIDDEN
;
struct
apc_stack_layout
*
WINAPI
setup_user_apc_dispatcher_stack
(
CONTEXT
*
context
,
struct
apc_stack_layout
*
stack
,
void
*
arg1
,
void
*
arg2
,
void
*
arg3
,
void
*
func
,
NTSTATUS
status
)
/***********************************************************************
* call_user_apc_dispatcher
*/
NTSTATUS
WINAPI
call_user_apc_dispatcher
(
CONTEXT
*
context
,
ULONG_PTR
arg1
,
ULONG_PTR
arg2
,
ULONG_PTR
arg3
,
PNTAPCFUNC
func
,
void
(
WINAPI
*
dispatcher
)(
CONTEXT
*
,
ULONG_PTR
,
ULONG_PTR
,
ULONG_PTR
,
PNTAPCFUNC
),
NTSTATUS
status
)
{
CONTEXT
c
;
struct
syscall_frame
*
frame
=
x86_thread_data
()
->
syscall_frame
;
ULONG
esp
=
context
?
context
->
Esp
:
frame
->
esp
;
struct
apc_stack_layout
*
stack
=
(
struct
apc_stack_layout
*
)
esp
-
1
;
if
(
!
context
)
{
c
.
ContextFlags
=
CONTEXT_FULL
;
NtGetContextThread
(
GetCurrentThread
(),
&
c
);
c
.
Eax
=
status
;
context
=
&
c
;
stack
->
context
.
ContextFlags
=
CONTEXT_FULL
;
NtGetContextThread
(
GetCurrentThread
(),
&
stack
->
context
);
stack
->
context
.
Eax
=
status
;
}
memmove
(
&
stack
->
context
,
context
,
sizeof
(
stack
->
context
)
);
else
memmove
(
&
stack
->
context
,
context
,
sizeof
(
stack
->
context
)
);
stack
->
context_ptr
=
&
stack
->
context
;
stack
->
arg1
=
arg1
;
stack
->
arg2
=
arg2
;
stack
->
arg3
=
arg3
;
stack
->
func
=
func
;
return
stack
;
frame
->
ebp
=
stack
->
context
.
Ebp
;
frame
->
esp
=
(
ULONG
)
stack
-
4
;
frame
->
eip
=
(
ULONG
)
dispatcher
;
return
status
;
}
C_ASSERT
(
sizeof
(
struct
apc_stack_layout
)
==
0x2e0
);
C_ASSERT
(
offsetof
(
struct
apc_stack_layout
,
context
)
==
20
);
/***********************************************************************
* call_user_apc_dispatcher
*/
__ASM_GLOBAL_FUNC
(
call_user_apc_dispatcher
,
"movl 4(%esp),%esi
\n\t
"
/* context_ptr */
"movl 24(%esp),%edi
\n\t
"
/* dispatcher */
"leal 4(%esp),%ebp
\n\t
"
"test %esi,%esi
\n\t
"
"jz 1f
\n\t
"
"movl 0xc4(%esi),%eax
\n\t
"
/* context_ptr->Esp */
"jmp 2f
\n\t
"
"1:
\t
movl %fs:0x1f8,%eax
\n\t
"
/* x86_thread_data()->syscall_frame */
"leal 0x3c(%eax),%eax
\n\t
"
/* &x86_thread_data()->syscall_frame->ret_addr */
"2:
\t
subl $0x2e0,%eax
\n\t
"
/* sizeof(struct apc_stack_layout) */
"movl %ebp,%esp
\n\t
"
/* pop return address */
"cmpl %esp,%eax
\n\t
"
"cmovbl %eax,%esp
\n\t
"
"pushl 24(%ebp)
\n\t
"
/* status */
"pushl 16(%ebp)
\n\t
"
/* func */
"pushl 12(%ebp)
\n\t
"
/* arg3 */
"pushl 8(%ebp)
\n\t
"
/* arg2 */
"pushl 4(%ebp)
\n\t
"
/* arg1 */
"pushl %eax
\n\t
"
"pushl %esi
\n\t
"
"call "
__ASM_STDCALL
(
"setup_user_apc_dispatcher_stack"
,
24
)
"
\n\t
"
"movl $0,%fs:0x1f8
\n\t
"
/* x86_thread_data()->syscall_frame = NULL */
"movl %eax,%esp
\n\t
"
"leal 20(%eax),%esi
\n\t
"
"movl 0xb4(%esi),%ebp
\n\t
"
/* context.Ebp */
"pushl 0xb8(%esi)
\n\t
"
/* context.Eip */
"jmp *%edi
\n
"
)
/***********************************************************************
* call_raise_user_exception_dispatcher
...
...
@@ -1624,23 +1607,20 @@ void WINAPI call_raise_user_exception_dispatcher( NTSTATUS (WINAPI *dispatcher)(
/***********************************************************************
* call_user_exception_dispatcher
*/
__ASM_GLOBAL_FUNC
(
call_user_exception_dispatcher
,
"movl 4(%esp),%edx
\n\t
"
/* rec */
"movl 8(%esp),%ecx
\n\t
"
/* context */
"cmpl $0x80000003,(%edx)
\n\t
"
/* rec->ExceptionCode */
"jne 1f
\n\t
"
"decl 0xb8(%ecx)
\n
"
/* context->Eip */
"1:
\t
movl %fs:0x1f8,%eax
\n\t
"
/* x86_thread_data()->syscall_frame */
"movl 0x20(%eax),%ebx
\n\t
"
/* frame->ebx */
"movl 0x2c(%eax),%edi
\n\t
"
/* frame->edi */
"movl 0x30(%eax),%esi
\n\t
"
/* frame->esi */
"movl 0x34(%eax),%ebp
\n\t
"
/* frame->ebp */
"movl %edx,0x34(%eax)
\n\t
"
"movl %ecx,0x38(%eax)
\n\t
"
"movl 12(%esp),%edx
\n\t
"
/* dispatcher */
"movl $0,%fs:0x1f8
\n\t
"
"leal 0x34(%eax),%esp
\n\t
"
"jmp *%edx"
)
NTSTATUS
WINAPI
call_user_exception_dispatcher
(
EXCEPTION_RECORD
*
rec
,
CONTEXT
*
context
,
NTSTATUS
(
WINAPI
*
dispatcher
)(
EXCEPTION_RECORD
*
,
CONTEXT
*
)
)
{
struct
syscall_frame
*
frame
=
x86_thread_data
()
->
syscall_frame
;
void
**
stack
=
(
void
**
)
frame
->
esp
;
if
(
rec
->
ExceptionCode
==
EXCEPTION_BREAKPOINT
)
context
->
Eip
--
;
*
(
--
stack
)
=
context
;
*
(
--
stack
)
=
rec
;
frame
->
esp
=
(
ULONG
)
stack
;
frame
->
eip
=
(
ULONG
)
dispatcher
;
return
STATUS_SUCCESS
;
}
/**********************************************************************
* get_fpu_code
...
...
@@ -1720,7 +1700,7 @@ static BOOL handle_syscall_fault( ucontext_t *sigcontext, void *stack_ptr,
struct
syscall_frame
*
frame
=
x86_thread_data
()
->
syscall_frame
;
DWORD
i
;
if
(
!
frame
)
return
FALSE
;
if
(
!
is_inside_syscall
(
sigcontext
)
)
return
FALSE
;
TRACE
(
"code=%x flags=%x addr=%p ip=%08x tid=%04x
\n
"
,
rec
->
ExceptionCode
,
rec
->
ExceptionFlags
,
rec
->
ExceptionAddress
,
...
...
@@ -1736,19 +1716,13 @@ static BOOL handle_syscall_fault( ucontext_t *sigcontext, void *stack_ptr,
if
(
ntdll_get_thread_data
()
->
jmp_buf
)
{
/* stack frame for calling __wine_longjmp */
struct
{
int
retval
;
__wine_jmp_buf
*
jmp
;
void
*
retaddr
;
}
*
stack
;
DWORD
*
stack
=
stack_ptr
;
TRACE
(
"returning to handler
\n
"
);
stack
=
virtual_setup_exception
(
stack_ptr
,
sizeof
(
*
stack
),
rec
);
stack
->
retval
=
1
;
stack
->
jmp
=
ntdll_get_thread_data
()
->
jmp_buf
;
stack
->
retaddr
=
(
void
*
)
0xdeadbabe
;
/* push stack frame for calling __wine_longjmp */
*
(
--
stack
)
=
1
;
*
(
--
stack
)
=
(
DWORD
)
ntdll_get_thread_data
()
->
jmp_buf
;
*
(
--
stack
)
=
0xdeadbabe
;
/* return address */
ESP_sig
(
sigcontext
)
=
(
DWORD
)
stack
;
EIP_sig
(
sigcontext
)
=
(
DWORD
)
__wine_longjmp
;
ntdll_get_thread_data
()
->
jmp_buf
=
NULL
;
...
...
@@ -1763,7 +1737,6 @@ static BOOL handle_syscall_fault( ucontext_t *sigcontext, void *stack_ptr,
EBP_sig
(
sigcontext
)
=
frame
->
ebp
;
ESP_sig
(
sigcontext
)
=
frame
->
esp
;
EIP_sig
(
sigcontext
)
=
frame
->
eip
;
x86_thread_data
()
->
syscall_frame
=
NULL
;
}
return
TRUE
;
}
...
...
@@ -2001,7 +1974,7 @@ static void usr1_handler( int signal, siginfo_t *siginfo, void *sigcontext )
struct
xcontext
xcontext
;
init_handler
(
sigcontext
);
if
(
x86_thread_data
()
->
syscall_frame
)
if
(
is_inside_syscall
(
sigcontext
)
)
{
DECLSPEC_ALIGN
(
64
)
XSTATE
xs
;
xcontext
.
c
.
ContextFlags
=
CONTEXT_FULL
;
...
...
@@ -2317,6 +2290,9 @@ void signal_init_thread( TEB *teb )
void
signal_init_process
(
void
)
{
struct
sigaction
sig_act
;
void
*
kernel_stack
=
(
char
*
)
ntdll_get_thread_data
()
->
kernel_stack
+
kernel_stack_size
;
x86_thread_data
()
->
syscall_frame
=
(
struct
syscall_frame
*
)
kernel_stack
-
1
;
if
(
cpu_info
.
ProcessorFeatureBits
&
CPU_FEATURE_FXSR
)
__wine_syscall_flags
|=
SYSCALL_HAVE_FXSAVE
;
if
(
cpu_info
.
ProcessorFeatureBits
&
CPU_FEATURE_XSAVE
)
__wine_syscall_flags
|=
SYSCALL_HAVE_XSAVE
;
...
...
@@ -2423,8 +2399,14 @@ __ASM_GLOBAL_FUNC( signal_start_thread,
__ASM_CFI
(
".cfi_rel_offset %edi,-12
\n\t
"
)
/* store exit frame */
"movl %ebp,%fs:0x1f4
\n\t
"
/* x86_thread_data()->exit_frame */
/* set syscall frame */
"cmpl $0,%fs:0x1f8
\n\t
"
/* x86_thread_data()->syscall_frame */
"jnz 1f
\n\t
"
"leal -0x300(%esp),%eax
\n\t
"
/* sizeof(struct syscall_frame) */
"andl $~63,%eax
\n\t
"
"movl %eax,%fs:0x1f8
\n
"
/* x86_thread_data()->syscall_frame */
/* switch to thread stack */
"
movl %fs:4,%eax
\n\t
"
/* NtCurrentTeb()->StackBase */
"
1:
\t
movl %fs:4,%eax
\n\t
"
/* NtCurrentTeb()->StackBase */
"leal -0x1004(%eax),%esp
\n\t
"
/* attach dlls */
"pushl 16(%ebp)
\n\t
"
/* suspend */
...
...
tools/winebuild/import.c
View file @
308a5e7c
...
...
@@ -1433,170 +1433,118 @@ static void output_syscall_dispatcher(void)
switch
(
target_cpu
)
{
case
CPU_x86
:
output
(
"
\t
pushl %%ebp
\n
"
);
output_cfi
(
".cfi_adjust_cfa_offset 4
\n
"
);
output_cfi
(
".cfi_rel_offset %%ebp,0
\n
"
);
output
(
"
\t
movl %%esp,%%ebp
\n
"
);
output_cfi
(
".cfi_def_cfa_register %%ebp
\n
"
);
output
(
"
\t
leal -0x2c(%%esp),%%esp
\n
"
);
output
(
"
\t
movl %%ebx,-0x14(%%ebp)
\n
"
);
output_cfi
(
".cfi_rel_offset %%ebx,-0x14
\n
"
);
output
(
"
\t
movl %%edi,-0x08(%%ebp)
\n
"
);
output_cfi
(
".cfi_rel_offset %%edi,-0x08
\n
"
);
output
(
"
\t
movl %%esi,-0x04(%%ebp)
\n
"
);
output_cfi
(
".cfi_rel_offset %%esi,-0x04
\n
"
);
output
(
"
\t
movl %%fs:0x1f8,%%ecx
\n
"
);
/* x86_thread_data()->syscall_frame */
output
(
"
\t
movl $0,0x00(%%ecx)
\n
"
);
/* frame->restore_flags */
output
(
"
\t
popl 0x08(%%ecx)
\n
"
);
/* frame->eip */
output
(
"
\t
movl %%esp,0x0c(%%ecx)
\n
"
);
/* frame->esp */
output
(
"
\t
pushfl
\n
"
);
output
(
"
\t
pushl $0
\n
"
);
output
(
"
\t
movw %%gs,-0x1a(%%ebp)
\n
"
);
output
(
"
\t
movw %%fs,-0x1c(%%ebp)
\n
"
);
output
(
"
\t
movw %%es,-0x1e(%%ebp)
\n
"
);
output
(
"
\t
movw %%ds,-0x20(%%ebp)
\n
"
);
output
(
"
\t
movw %%ss,-0x22(%%ebp)
\n
"
);
output
(
"
\t
movw %%cs,-0x24(%%ebp)
\n
"
);
output
(
"
\t
leal 8(%%ebp),%%ecx
\n
"
);
output
(
"
\t
movl %%ecx,-0x28(%%ebp)
\n
"
);
/* frame->esp */
output
(
"
\t
movl 4(%%ebp),%%ecx
\n
"
);
output
(
"
\t
movl %%ecx,-0x2c(%%ebp)
\n
"
);
/* frame->eip */
output
(
"
\t
subl $0x2c0,%%esp
\n
"
)
;
output
(
"
\t
andl $~63,%%esp
\n
"
);
output
(
"
\t
movl %%eax,%%ecx
\n
"
);
output
(
"
\t
shrl $8,%%ecx
\n
"
);
output
(
"
\t
andl $0x30,%%ecx
\n
"
);
/* syscall table number */
output
(
"
\t
popl 0x04(%%ecx)
\n
"
);
/* frame->eflags */
output
(
"
\t
movw %%cs,0x10(%%ecx)
\n
"
);
output
(
"
\t
movw %%ss,0x12(%%ecx)
\n
"
);
output
(
"
\t
movw %%ds,0x14(%%ecx)
\n
"
);
output
(
"
\t
movw %%es,0x16(%%ecx)
\n
"
);
output
(
"
\t
movw %%fs,0x18(%%ecx)
\n
"
);
output
(
"
\t
movw %%gs,0x1a(%%ecx)
\n
"
);
output
(
"
\t
movl %%eax,0x1c(%%ecx)
\n
"
);
output
(
"
\t
movl %%ebx,0x20(%%ecx)
\n
"
);
output
(
"
\t
movl %%edi,0x2c(%%ecx)
\n
"
);
output
(
"
\t
movl %%esi,0x30(%%ecx)
\n
"
);
output
(
"
\t
movl %%ebp,0x34(%%ecx)
\n
"
);
output
(
"
\t
leal 0x34(%%ecx),%%ebp
\n
"
);
output
(
"
\t
leal 4(%%esp),%%esi
\n
"
);
/* first argument */
output
(
"
\t
movl %%eax,%%edx
\n
"
);
output
(
"
\t
andl $0xfff,%%edx
\n
"
);
/* syscall number */
output
(
"
\t
shrl $8,%%edx
\n
"
);
output
(
"
\t
andl $0x30,%%edx
\n
"
);
/* syscall table number */
if
(
UsePIC
)
{
output
(
"
\t
call %s
\n
"
,
asm_name
(
"__wine_spec_get_pc_thunk_eax"
)
);
output
(
"1:
\t
leal %s-1b(%%eax,%%e
c
x),%%ebx
\n
"
,
asm_name
(
"KeServiceDescriptorTable"
)
);
output
(
"
\t
movl %s-1b(%%eax),%%e
s
i
\n
"
,
asm_name
(
"__wine_syscall_flags"
)
);
output
(
"1:
\t
leal %s-1b(%%eax,%%e
d
x),%%ebx
\n
"
,
asm_name
(
"KeServiceDescriptorTable"
)
);
output
(
"
\t
movl %s-1b(%%eax),%%e
d
i
\n
"
,
asm_name
(
"__wine_syscall_flags"
)
);
needs_get_pc_thunk
=
1
;
}
else
{
output
(
"
\t
leal %s(%%e
c
x),%%ebx
\n
"
,
asm_name
(
"KeServiceDescriptorTable"
)
);
output
(
"
\t
movl %s,%%e
s
i
\n
"
,
asm_name
(
"__wine_syscall_flags"
)
);
output
(
"
\t
leal %s(%%e
d
x),%%ebx
\n
"
,
asm_name
(
"KeServiceDescriptorTable"
)
);
output
(
"
\t
movl %s,%%e
d
i
\n
"
,
asm_name
(
"__wine_syscall_flags"
)
);
}
output
(
"
\t
testl $3,%%e
s
i
\n
"
);
/* SYSCALL_HAVE_XSAVE | SYSCALL_HAVE_XSAVEC */
output
(
"
\t
testl $3,%%e
d
i
\n
"
);
/* SYSCALL_HAVE_XSAVE | SYSCALL_HAVE_XSAVEC */
output
(
"
\t
jz 2f
\n
"
);
output
(
"
\t
movl %%edx,%%ecx
\n
"
);
output
(
"
\t
movl $7,%%eax
\n
"
);
output
(
"
\t
xorl %%edx,%%edx
\n
"
);
for
(
i
=
0
;
i
<
6
;
i
++
)
output
(
"
\t
movl %%edx,0x%x(%%e
sp)
\n
"
,
0x20
0
+
i
*
4
);
output
(
"
\t
testl $2,%%e
s
i
\n
"
);
/* SYSCALL_HAVE_XSAVEC */
for
(
i
=
0
;
i
<
6
;
i
++
)
output
(
"
\t
movl %%edx,0x%x(%%e
cx)
\n
"
,
0x24
0
+
i
*
4
);
output
(
"
\t
testl $2,%%e
d
i
\n
"
);
/* SYSCALL_HAVE_XSAVEC */
output
(
"
\t
jz 1f
\n
"
);
for
(
i
=
6
;
i
<
16
;
i
++
)
output
(
"
\t
movl %%edx,0x%x(%%esp)
\n
"
,
0x200
+
i
*
4
);
output
(
"
\t
xsavec (%%esp)
\n
"
);
output
(
"
\t
movl %%ecx,%%edx
\n
"
);
for
(
i
=
6
;
i
<
16
;
i
++
)
output
(
"
\t
movl %%edx,0x%x(%%ecx)
\n
"
,
0x240
+
i
*
4
);
output
(
"
\t
xsavec 0x40(%%ecx)
\n
"
);
output
(
"
\t
jmp 4f
\n
"
);
output
(
"1:
\t
xsave (%%esp)
\n
"
);
output
(
"
\t
movl %%ecx,%%edx
\n
"
);
output
(
"1:
\t
xsave 0x40(%%ecx)
\n
"
);
output
(
"
\t
jmp 4f
\n
"
);
output
(
"2:
\t
testl $4,%%e
s
i
\n
"
);
/* SYSCALL_HAVE_FXSAVE */
output
(
"2:
\t
testl $4,%%e
d
i
\n
"
);
/* SYSCALL_HAVE_FXSAVE */
output
(
"
\t
jz 3f
\n
"
);
output
(
"
\t
fxsave
(%%esp
)
\n
"
);
output
(
"
\t
fxsave
0x40(%%ecx
)
\n
"
);
output
(
"
\t
jmp 4f
\n
"
);
output
(
"3:
\t
fnsave
(%%esp
)
\n
"
);
output
(
"3:
\t
fnsave
0x40(%%ecx
)
\n
"
);
output
(
"
\t
fwait
\n
"
);
output
(
"4:
\t
leal -0x34(%%ebp),%%ecx
\n
"
);
output
(
"
\t
movl %%ecx,%%fs:0x1f8
\n
"
);
/* x86_thread_data()->syscall_frame */
output
(
"
\t
cmpl 8(%%ebx),%%edx
\n
"
);
/* table->ServiceLimit */
output
(
"4:
\t
movl %%ecx,%%esp
\n
"
);
output
(
"
\t
movl 0x1c(%%esp),%%edx
\n
"
);
/* frame->eax */
output
(
"
\t
andl $0xfff,%%edx
\n
"
);
/* syscall number */
output
(
"
\t
cmpl 8(%%ebx),%%edx
\n
"
);
/* table->ServiceLimit */
output
(
"
\t
jae 6f
\n
"
);
output
(
"
\t
movl 12(%%ebx),%%eax
\n
"
);
/* table->ArgumentTable */
output
(
"
\t
movzbl (%%eax,%%edx,1),%%ecx
\n
"
);
output
(
"
\t
movl (%%ebx),%%eax
\n
"
);
/* table->ServiceTable */
output
(
"
\t
movl %%e
s
i,%%ebx
\n
"
);
output
(
"
\t
movl %%e
d
i,%%ebx
\n
"
);
output
(
"
\t
subl %%ecx,%%esp
\n
"
);
output
(
"
\t
shrl $2,%%ecx
\n
"
);
output
(
"
\t
leal 12(%%ebp),%%esi
\n
"
);
output
(
"
\t
andl $~15,%%esp
\n
"
);
output
(
"
\t
movl %%esp,%%edi
\n
"
);
output
(
"
\t
cld
\n
"
);
output
(
"
\t
rep; movsl
\n
"
);
output
(
"
\t
movl %%ebx,%%e
s
i
\n
"
);
output
(
"
\t
movl %%ebx,%%e
d
i
\n
"
);
output
(
"
\t
call *(%%eax,%%edx,4)
\n
"
);
output
(
"5:
\t
movl $0,%%fs:0x1f8
\n
"
);
output
(
"
\t
movl
-0x34(%%ebp),%%ecx
\n
"
);
/* syscall_
frame->restore_flags */
output
(
"
\t
testl $0x68,%%ecx
\n
"
);
/* CONTEXT_FLOATING_POINT | CONTEXT_EXTENDED_REGISTERS | CONTEXT_XSAVE */
output
(
"5:
\t
leal -0x34(%%ebp),%%esp
\n
"
);
output
(
"
\t
movl
(%%esp),%%ecx
\n
"
);
/*
frame->restore_flags */
output
(
"
\t
testl $0x68,%%ecx
\n
"
);
/* CONTEXT_FLOATING_POINT | CONTEXT_EXTENDED_REGISTERS | CONTEXT_XSAVE */
output
(
"
\t
jz 3f
\n
"
);
output
(
"
\t
leal -0x2f4(%%ebp),%%ebx
\n
"
)
;
output
(
"
\t
andl $~63,%%ebx
\n
"
);
output
(
"
\t
testl $3,%%esi
\n
"
);
/* SYSCALL_HAVE_XSAVE | SYSCALL_HAVE_XSAVEC */
output
(
"
\t
testl $3,%%edi
\n
"
);
/* SYSCALL_HAVE_XSAVE | SYSCALL_HAVE_XSAVEC */
output
(
"
\t
jz 1f
\n
"
);
output
(
"
\t
movl %%eax,%%e
d
i
\n
"
);
output
(
"
\t
movl %%eax,%%e
s
i
\n
"
);
output
(
"
\t
movl $7,%%eax
\n
"
);
output
(
"
\t
xorl %%edx,%%edx
\n
"
);
output
(
"
\t
xrstor
(%%ebx
)
\n
"
);
output
(
"
\t
movl %%e
d
i,%%eax
\n
"
);
output
(
"
\t
xrstor
0x40(%%esp
)
\n
"
);
output
(
"
\t
movl %%e
s
i,%%eax
\n
"
);
output
(
"
\t
jmp 3f
\n
"
);
output
(
"1:
\t
testl $4,%%e
s
i
\n
"
);
/* SYSCALL_HAVE_FXSAVE */
output
(
"1:
\t
testl $4,%%e
d
i
\n
"
);
/* SYSCALL_HAVE_FXSAVE */
output
(
"
\t
jz 2f
\n
"
);
output
(
"
\t
fxrstor
(%%ebx
)
\n
"
);
output
(
"
\t
fxrstor
0x40(%%esp
)
\n
"
);
output
(
"
\t
jmp 3f
\n
"
);
output
(
"2:
\t
frstor
(%%ebx
)
\n
"
);
output
(
"2:
\t
frstor
0x40(%%esp
)
\n
"
);
output
(
"
\t
fwait
\n
"
);
output
(
"3:
\t
movl -0x08(%%ebp),%%edi
\n
"
);
output_cfi
(
".cfi_same_value %%edi"
);
output
(
"
\t
movl -0x04(%%ebp),%%esi
\n
"
);
output_cfi
(
".cfi_same_value %%esi"
);
output
(
"
\t
movl -0x14(%%ebp),%%ebx
\n
"
);
output_cfi
(
".cfi_same_value %%ebx"
);
output
(
"3:
\t
movl 0x2c(%%esp),%%edi
\n
"
);
output
(
"
\t
movl 0x30(%%esp),%%esi
\n
"
);
output
(
"
\t
movl 0x34(%%esp),%%ebp
\n
"
);
output
(
"
\t
testl $0x7,%%ecx
\n
"
);
/* CONTEXT_CONTROL | CONTEXT_SEGMENTS | CONTEXT_INTEGER */
output
(
"
\t
jnz 1f
\n
"
);
output
(
"
\t
movl -0x2c(%%ebp),%%ecx
\n
"
);
/* frame->eip */
output
(
"
\t
leal -0x28(%%ebp),%%esp
\n
"
);
/* frame->esp */
output
(
"
\t
movl (%%ebp),%%ebp
\n
"
);
output_cfi
(
".cfi_same_value %%ebp"
);
output
(
"
\t
popl %%esp
\n
"
);
output
(
"
\t
movl 0x20(%%esp),%%ebx
\n
"
);
output
(
"
\t
movl 0x08(%%esp),%%ecx
\n
"
);
/* frame->eip */
output
(
"
\t
movl 0x0c(%%esp),%%esp
\n
"
);
/* frame->esp */
output
(
"
\t
jmpl *%%ecx
\n
"
);
output
(
"1:
\t
testl $0x2,%%ecx
\n
"
);
/* CONTEXT_INTEGER */
output
(
"
\t
jnz 1f
\n
"
);
output
(
"
\t
movl %%eax,-0x18(%%ebp)
\n
"
);
output
(
"
\t
movl $0,-0x10(%%ebp)
\n
"
);
output
(
"
\t
movl $0,-0x0c(%%ebp)
\n
"
);
output
(
"1:
\t
movw -0x1a(%%ebp),%%gs
\n
"
);
output
(
"
\t
movw -0x1c(%%ebp),%%fs
\n
"
);
output
(
"
\t
movw -0x1e(%%ebp),%%es
\n
"
);
output
(
"
\t
leal -0x34(%%ebp),%%ecx
\n
"
);
output_cfi
(
".cfi_def_cfa_register %%ecx"
);
output_cfi
(
".cfi_adjust_cfa_offset 0x34
\n
"
);
output
(
"
\t
movl (%%ebp),%%ebp
\n
"
);
output_cfi
(
".cfi_same_value %%ebp"
);
output
(
"
\t
movw %%ss,%%ax
\n
"
);
output
(
"
\t
cmpw 0x12(%%ecx),%%ax
\n
"
);
output
(
"
\t
jne 3f
\n
"
);
/* As soon as we have switched stacks the context structure could
* be invalid (when signal handlers are executed for example). Copy
* values on the target stack before changing ESP. */
output
(
"
\t
movl 0x0c(%%ecx),%%eax
\n
"
);
output
(
"
\t
leal -4*4(%%eax),%%eax
\n
"
);
output
(
"
\t
movl 0x04(%%ecx),%%edx
\n
"
);
output
(
"
\t
movl %%edx,3*4(%%eax)
\n
"
);
output
(
"
\t
movl 0x10(%%ecx),%%edx
\n
"
);
output
(
"
\t
movl %%edx,2*4(%%eax)
\n
"
);
output
(
"
\t
movl 0x08(%%ecx),%%edx
\n
"
);
output
(
"
\t
movl %%edx,1*4(%%eax)
\n
"
);
output
(
"
\t
movl 0x1c(%%ecx),%%edx
\n
"
);
output
(
"
\t
movl %%edx,0*4(%%eax)
\n
"
);
output
(
"
\t
pushl 0x14(%%ecx)
\n
"
);
output
(
"
\t
movl 0x28(%%ecx),%%edx
\n
"
);
output
(
"
\t
movl 0x24(%%ecx),%%ecx
\n
"
);
output
(
"
\t
popl %%ds
\n
"
);
output
(
"
\t
movl %%eax,%%esp
\n
"
);
output
(
"
\t
popl %%eax
\n
"
);
output
(
"
\t
iret
\n
"
);
/* Restore the context when the stack segment changes. We can't use
* the same code as above because we do not know if the stack segment
* is 16 or 32 bit, and 'movl' will throw an exception when we try to
* access memory above the limit. */
output
(
"3:
\t
movl 0x28(%%ecx),%%edx
\n
"
);
output
(
"
\t
movl 0x1c(%%ecx),%%eax
\n
"
);
output
(
"
\t
movw 0x12(%%ecx),%%ss
\n
"
);
output
(
"
\t
movl 0x0c(%%ecx),%%esp
\n
"
);
output
(
"
\t
pushl 0x04(%%ecx)
\n
"
);
output
(
"
\t
pushl 0x10(%%ecx)
\n
"
);
output
(
"
\t
pushl 0x08(%%ecx)
\n
"
);
output
(
"
\t
pushl 0x14(%%ecx)
\n
"
);
output
(
"
\t
movl 0x24(%%ecx),%%ecx
\n
"
);
output
(
"
\t
jz 1f
\n
"
);
output
(
"
\t
movl 0x1c(%%esp),%%eax
\n
"
);
output
(
"
\t
movl 0x24(%%esp),%%ecx
\n
"
);
output
(
"
\t
movl 0x28(%%esp),%%edx
\n
"
);
output
(
"1:
\t
movl 0x0c(%%esp),%%ebx
\n
"
);
/* frame->esp */
output
(
"
\t
movw 0x12(%%esp),%%ss
\n
"
);
output
(
"
\t
xchgl %%ebx,%%esp
\n
"
);
output
(
"
\t
pushl 0x04(%%ebx)
\n
"
);
/* frame->eflags */
output
(
"
\t
pushl 0x10(%%ebx)
\n
"
);
/* frame->cs */
output
(
"
\t
pushl 0x08(%%ebx)
\n
"
);
/* frame->eip */
output
(
"
\t
pushl 0x14(%%ebx)
\n
"
);
/* frame->ds */
output
(
"
\t
movw 0x16(%%ebx),%%es
\n
"
);
output
(
"
\t
movw 0x18(%%ebx),%%fs
\n
"
);
output
(
"
\t
movw 0x1a(%%ebx),%%gs
\n
"
);
output
(
"
\t
movl 0x20(%%ebx),%%ebx
\n
"
);
output
(
"
\t
popl %%ds
\n
"
);
output
(
"
\t
iret
\n
"
);
output
(
"6:
\t
movl $0x%x,%%eax
\n
"
,
invalid_param
);
...
...
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