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
42e42e90
Commit
42e42e90
authored
Jun 02, 2021
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ntdll: Use a single syscall dispatcher controlled by global flags on i386.
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
3d9cb5e4
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
66 additions
and
88 deletions
+66
-88
signal_i386.c
dlls/ntdll/unix/signal_i386.c
+10
-16
import.c
tools/winebuild/import.c
+56
-72
No files found.
dlls/ntdll/unix/signal_i386.c
View file @
42e42e90
...
...
@@ -520,7 +520,10 @@ C_ASSERT( offsetof( TEB, GdiTebBatch ) + offsetof( struct x86_thread_data, gs )
C_ASSERT
(
offsetof
(
TEB
,
GdiTebBatch
)
+
offsetof
(
struct
x86_thread_data
,
exit_frame
)
==
0x1f4
);
C_ASSERT
(
offsetof
(
TEB
,
GdiTebBatch
)
+
offsetof
(
struct
x86_thread_data
,
syscall_frame
)
==
0x1f8
);
static
void
*
syscall_dispatcher
;
/* flags to control the behavior of the syscall dispatcher */
#define SYSCALL_HAVE_XSAVE 1
#define SYSCALL_HAVE_XSAVEC 2
#define SYSCALL_HAVE_FXSAVE 4
static
inline
struct
x86_thread_data
*
x86_thread_data
(
void
)
{
...
...
@@ -2331,7 +2334,7 @@ NTSTATUS signal_alloc_thread( TEB *teb )
}
else
thread_data
->
fs
=
gdt_fs_sel
;
teb
->
WOW32Reserved
=
syscall_dispatcher
;
teb
->
WOW32Reserved
=
__wine_
syscall_dispatcher
;
return
STATUS_SUCCESS
;
}
...
...
@@ -2374,6 +2377,10 @@ void signal_init_process(void)
{
struct
sigaction
sig_act
;
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
;
if
(
xstate_compaction_enabled
)
__wine_syscall_flags
|=
SYSCALL_HAVE_XSAVEC
;
sig_act
.
sa_mask
=
server_block_set
;
sig_act
.
sa_flags
=
SA_SIGINFO
|
SA_RESTART
|
SA_ONSTACK
;
#ifdef __ANDROID__
...
...
@@ -2409,20 +2416,7 @@ void signal_init_process(void)
*/
void
*
signal_init_syscalls
(
void
)
{
extern
void
__wine_syscall_dispatcher_fxsave
(
void
)
DECLSPEC_HIDDEN
;
extern
void
__wine_syscall_dispatcher_xsave
(
void
)
DECLSPEC_HIDDEN
;
extern
void
__wine_syscall_dispatcher_xsavec
(
void
)
DECLSPEC_HIDDEN
;
if
(
xstate_compaction_enabled
)
syscall_dispatcher
=
__wine_syscall_dispatcher_xsavec
;
else
if
(
cpu_info
.
ProcessorFeatureBits
&
CPU_FEATURE_XSAVE
)
syscall_dispatcher
=
__wine_syscall_dispatcher_xsave
;
else
if
(
cpu_info
.
ProcessorFeatureBits
&
CPU_FEATURE_FXSR
)
syscall_dispatcher
=
__wine_syscall_dispatcher_fxsave
;
else
syscall_dispatcher
=
__wine_syscall_dispatcher
;
return
NtCurrentTeb
()
->
WOW32Reserved
=
syscall_dispatcher
;
return
NtCurrentTeb
()
->
WOW32Reserved
=
__wine_syscall_dispatcher
;
}
...
...
tools/winebuild/import.c
View file @
42e42e90
...
...
@@ -1421,15 +1421,14 @@ static int cmp_link_name( const void *e1, const void *e2 )
/* output dispatcher for system calls */
static
void
output_syscall_dispatcher
(
const
char
*
variant
)
static
void
output_syscall_dispatcher
(
void
)
{
const
unsigned
int
invalid_param
=
0xc000000d
;
/* STATUS_INVALID_PARAMETER */
const
char
*
symbol
=
strmake
(
"__wine_syscall_dispatcher%s"
,
variant
);
unsigned
int
i
;
output
(
"
\t
.align %d
\n
"
,
get_alignment
(
4
)
);
output
(
"
\t
%s
\n
"
,
func_declaration
(
symbol
)
);
output
(
"%s
\n
"
,
asm_globl
(
symbol
)
);
output
(
"
\t
%s
\n
"
,
func_declaration
(
"__wine_syscall_dispatcher"
)
);
output
(
"%s
\n
"
,
asm_globl
(
"__wine_syscall_dispatcher"
)
);
output_cfi
(
".cfi_startproc"
);
switch
(
target_cpu
)
{
...
...
@@ -1459,37 +1458,6 @@ static void output_syscall_dispatcher( const char *variant )
output
(
"
\t
movl %%ecx,-0x2c(%%ebp)
\n
"
);
/* frame->eip */
output
(
"
\t
subl $0x2c0,%%esp
\n
"
)
;
output
(
"
\t
andl $~63,%%esp
\n
"
);
if
(
!*
variant
)
{
output
(
"
\t
fnsave (%%esp)
\n
"
);
output
(
"
\t
fwait
\n
"
);
}
else
if
(
!
strcmp
(
variant
,
"_fxsave"
))
{
output
(
"
\t
fxsave (%%esp)
\n
"
);
}
else
if
(
!
strcmp
(
variant
,
"_xsave"
))
{
output
(
"
\t
movl %%eax,%%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(%%esp)
\n
"
,
0x200
+
i
*
4
);
output
(
"
\t
xsave (%%esp)
\n
"
);
output
(
"
\t
movl %%ecx,%%eax
\n
"
);
}
else
/* _xsavec */
{
output
(
"
\t
movl %%eax,%%ecx
\n
"
);
output
(
"
\t
movl $7,%%eax
\n
"
);
output
(
"
\t
xorl %%edx,%%edx
\n
"
);
for
(
i
=
0
;
i
<
16
;
i
++
)
output
(
"
\t
movl %%edx,0x%x(%%esp)
\n
"
,
0x200
+
i
*
4
);
output
(
"
\t
xsavec (%%esp)
\n
"
);
output
(
"
\t
movl %%ecx,%%eax
\n
"
);
}
output
(
"
\t
leal -0x30(%%ebp),%%ecx
\n
"
);
output
(
"
\t
movl %%ecx,%%fs:0x1f8
\n
"
);
/* x86_thread_data()->syscall_frame */
output
(
"
\t
movl %%eax,%%ecx
\n
"
);
output
(
"
\t
shrl $8,%%ecx
\n
"
);
output
(
"
\t
andl $0x30,%%ecx
\n
"
);
/* syscall table number */
...
...
@@ -1499,14 +1467,43 @@ static void output_syscall_dispatcher( const char *variant )
{
output
(
"
\t
call %s
\n
"
,
asm_name
(
"__wine_spec_get_pc_thunk_eax"
)
);
output
(
"1:
\t
leal %s-1b(%%eax,%%ecx),%%ebx
\n
"
,
asm_name
(
"KeServiceDescriptorTable"
)
);
output
(
"
\t
movl %s-1b(%%eax),%%esi
\n
"
,
asm_name
(
"__wine_syscall_flags"
)
);
needs_get_pc_thunk
=
1
;
}
else
output
(
"
\t
leal %s(%%ecx),%%ebx
\n
"
,
asm_name
(
"KeServiceDescriptorTable"
)
);
else
{
output
(
"
\t
leal %s(%%ecx),%%ebx
\n
"
,
asm_name
(
"KeServiceDescriptorTable"
)
);
output
(
"
\t
movl %s,%%esi
\n
"
,
asm_name
(
"__wine_syscall_flags"
)
);
}
output
(
"
\t
testl $3,%%esi
\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(%%esp)
\n
"
,
0x200
+
i
*
4
);
output
(
"
\t
testl $2,%%esi
\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
"
);
output
(
"
\t
jmp 4f
\n
"
);
output
(
"1:
\t
xsave (%%esp)
\n
"
);
output
(
"
\t
movl %%ecx,%%edx
\n
"
);
output
(
"
\t
jmp 4f
\n
"
);
output
(
"2:
\t
testl $4,%%esi
\n
"
);
/* SYSCALL_HAVE_FXSAVE */
output
(
"
\t
jz 3f
\n
"
);
output
(
"
\t
fxsave (%%esp)
\n
"
);
output
(
"
\t
jmp 4f
\n
"
);
output
(
"3:
\t
fnsave (%%esp)
\n
"
);
output
(
"
\t
fwait
\n
"
);
output
(
"4:
\t
leal -0x30(%%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
(
"
\t
jae
4
f
\n
"
);
output
(
"
\t
jae
6
f
\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 %%esi,%%ebx
\n
"
);
output
(
"
\t
subl %%ecx,%%esp
\n
"
);
output
(
"
\t
shrl $2,%%ecx
\n
"
);
output
(
"
\t
leal 12(%%ebp),%%esi
\n
"
);
...
...
@@ -1514,29 +1511,26 @@ static void output_syscall_dispatcher( const char *variant )
output
(
"
\t
movl %%esp,%%edi
\n
"
);
output
(
"
\t
cld
\n
"
);
output
(
"
\t
rep; movsl
\n
"
);
output
(
"
\t
movl
(%%ebx),%%eax
\n
"
);
/* table->ServiceTable */
output
(
"
\t
movl
%%ebx,%%esi
\n
"
);
output
(
"
\t
call *(%%eax,%%edx,4)
\n
"
);
output
(
"
2
:
\t
movl $0,%%fs:0x1f8
\n
"
);
output
(
"
5
:
\t
movl $0,%%fs:0x1f8
\n
"
);
output
(
"
\t
leal -0x2f0(%%ebp),%%ebx
\n
"
)
;
output
(
"
\t
andl $~63,%%ebx
\n
"
);
if
(
!*
variant
)
{
output
(
"
\t
frstor (%%ebx)
\n
"
);
output
(
"
\t
fwait
\n
"
);
}
else
if
(
!
strcmp
(
variant
,
"_fxsave"
))
{
output
(
"
\t
fxrstor (%%ebx)
\n
"
);
}
else
{
output
(
"
\t
movl %%eax,%%ecx
\n
"
);
output
(
"
\t
movl $7,%%eax
\n
"
);
output
(
"
\t
xorl %%edx,%%edx
\n
"
);
output
(
"
\t
xrstor (%%ebx)
\n
"
);
output
(
"
\t
movl %%ecx,%%eax
\n
"
);
}
output
(
"
\t
leal -0x30(%%ebp),%%ebx
\n
"
);
output
(
"
\t
testl $3,%%esi
\n
"
);
/* SYSCALL_HAVE_XSAVE | SYSCALL_HAVE_XSAVEC */
output
(
"
\t
jz 1f
\n
"
);
output
(
"
\t
movl %%eax,%%ecx
\n
"
);
output
(
"
\t
movl $7,%%eax
\n
"
);
output
(
"
\t
xorl %%edx,%%edx
\n
"
);
output
(
"
\t
xrstor (%%ebx)
\n
"
);
output
(
"
\t
movl %%ecx,%%eax
\n
"
);
output
(
"
\t
jmp 3f
\n
"
);
output
(
"1:
\t
testl $4,%%esi
\n
"
);
/* SYSCALL_HAVE_FXSAVE */
output
(
"
\t
jz 2f
\n
"
);
output
(
"
\t
fxrstor (%%ebx)
\n
"
);
output
(
"
\t
jmp 3f
\n
"
);
output
(
"2:
\t
frstor (%%ebx)
\n
"
);
output
(
"
\t
fwait
\n
"
);
output
(
"3:
\t
leal -0x30(%%ebp),%%ebx
\n
"
);
output_cfi
(
".cfi_def_cfa_register %%ebx"
);
output_cfi
(
".cfi_adjust_cfa_offset 0x30
\n
"
);
output
(
"
\t
movl %%eax,0x18(%%ebx)
\n
"
);
...
...
@@ -1583,8 +1577,8 @@ static void output_syscall_dispatcher( const char *variant )
output
(
"
\t
movl 0x1c(%%ebx),%%ebx
\n
"
);
output
(
"
\t
popl %%ds
\n
"
);
output
(
"
\t
iret
\n
"
);
output
(
"
4
:
\t
movl $0x%x,%%eax
\n
"
,
invalid_param
);
output
(
"
\t
jmp
2
b
\n
"
);
output
(
"
6
:
\t
movl $0x%x,%%eax
\n
"
,
invalid_param
);
output
(
"
\t
jmp
5
b
\n
"
);
break
;
case
CPU_x86_64
:
output
(
"
\t
pushq %%rbp
\n
"
);
...
...
@@ -1822,7 +1816,7 @@ static void output_syscall_dispatcher( const char *variant )
assert
(
0
);
}
output_cfi
(
".cfi_endproc"
);
output_function_size
(
symbol
);
output_function_size
(
"__wine_syscall_dispatcher"
);
}
...
...
@@ -1847,18 +1841,8 @@ void output_syscalls( DLLSPEC *spec )
if
(
unix_lib
)
{
output_syscall_dispatcher
(
""
);
output_syscall_dispatcher
();
switch
(
target_cpu
)
{
case
CPU_x86
:
output_syscall_dispatcher
(
"_fxsave"
);
output_syscall_dispatcher
(
"_xsave"
);
output_syscall_dispatcher
(
"_xsavec"
);
break
;
default:
break
;
}
output
(
"
\t
.data
\n
"
);
output
(
"
\t
.align %d
\n
"
,
get_alignment
(
get_ptr_size
()
)
);
output
(
"%s
\n
"
,
asm_globl
(
"KeServiceDescriptorTable"
)
);
...
...
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