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
050378d4
Commit
050378d4
authored
Jun 07, 2021
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ntdll: Only restore the modified parts of the syscall frame on i386.
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
32f1bfd0
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
85 additions
and
132 deletions
+85
-132
signal_i386.c
dlls/ntdll/unix/signal_i386.c
+28
-97
import.c
tools/winebuild/import.c
+57
-35
No files found.
dlls/ntdll/unix/signal_i386.c
View file @
050378d4
...
...
@@ -481,25 +481,26 @@ C_ASSERT( sizeof(struct syscall_xsave) == 0x2c0 );
struct
syscall_frame
{
DWORD
eflags
;
/* 00 */
DWORD
eip
;
/* 04 */
DWORD
esp
;
/* 08 */
WORD
cs
;
/* 0c */
WORD
ss
;
/* 0e */
WORD
ds
;
/* 10 */
WORD
es
;
/* 12 */
WORD
fs
;
/* 14 */
WORD
gs
;
/* 16 */
DWORD
eax
;
/* 18 */
DWORD
ebx
;
/* 1c */
DWORD
ecx
;
/* 20 */
DWORD
edx
;
/* 24 */
DWORD
edi
;
/* 28 */
DWORD
esi
;
/* 2c */
DWORD
ebp
;
/* 30 */
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 */
};
C_ASSERT
(
sizeof
(
struct
syscall_frame
)
==
0x3
4
);
C_ASSERT
(
sizeof
(
struct
syscall_frame
)
==
0x3
8
);
struct
x86_thread_data
{
...
...
@@ -903,84 +904,13 @@ static inline void restore_context( const struct xcontext *xcontext, ucontext_t
/***********************************************************************
* set_full_cpu_context
*
* Set the new CPU context.
*/
extern
void
set_full_cpu_context
(
void
)
DECLSPEC_HIDDEN
;
__ASM_GLOBAL_FUNC
(
set_full_cpu_context
,
"movl %fs:0x1f8,%ecx
\n\t
"
"movl $0,%fs:0x1f8
\n\t
"
/* x86_thread_data()->syscall_frame = NULL */
"movw 0x16(%ecx),%gs
\n\t
"
/* SegGs */
"movw 0x14(%ecx),%fs
\n\t
"
/* SegFs */
"movw 0x12(%ecx),%es
\n\t
"
/* SegEs */
"movl 0x1c(%ecx),%ebx
\n\t
"
/* Ebx */
"movl 0x28(%ecx),%edi
\n\t
"
/* Edi */
"movl 0x2c(%ecx),%esi
\n\t
"
/* Esi */
"movl 0x30(%ecx),%ebp
\n\t
"
/* Ebp */
"movw %ss,%ax
\n\t
"
"cmpw 0x0e(%ecx),%ax
\n\t
"
/* SegSs */
"jne 1f
\n\t
"
/* 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. */
"movl 0x08(%ecx),%eax
\n\t
"
/* Esp */
"leal -4*4(%eax),%eax
\n\t
"
"movl (%ecx),%edx
\n\t
"
/* EFlags */
"movl %edx,3*4(%eax)
\n\t
"
"movl 0x0c(%ecx),%edx
\n\t
"
/* SegCs */
"movl %edx,2*4(%eax)
\n\t
"
"movl 0x04(%ecx),%edx
\n\t
"
/* Eip */
"movl %edx,1*4(%eax)
\n\t
"
"movl 0x18(%ecx),%edx
\n\t
"
/* Eax */
"movl %edx,0*4(%eax)
\n\t
"
"pushl 0x10(%ecx)
\n\t
"
/* SegDs */
"movl 0x24(%ecx),%edx
\n\t
"
/* Edx */
"movl 0x20(%ecx),%ecx
\n\t
"
/* Ecx */
"popl %ds
\n\t
"
"movl %eax,%esp
\n\t
"
"popl %eax
\n\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. */
"1:
\n\t
"
"movl 0x24(%ecx),%edx
\n\t
"
/* Edx */
"movl 0x18(%ecx),%eax
\n\t
"
/* Eax */
"movw 0x0e(%ecx),%ss
\n\t
"
/* SegSs */
"movl 0x08(%ecx),%esp
\n\t
"
/* Esp */
"pushl 0x00(%ecx)
\n\t
"
/* EFlags */
"pushl 0x0c(%ecx)
\n\t
"
/* SegCs */
"pushl 0x04(%ecx)
\n\t
"
/* Eip */
"pushl 0x10(%ecx)
\n\t
"
/* SegDs */
"movl 0x20(%ecx),%ecx
\n\t
"
/* Ecx */
"popl %ds
\n\t
"
"iret"
)
/***********************************************************************
* signal_restore_full_cpu_context
*
* Restore full context from syscall frame
*/
void
signal_restore_full_cpu_context
(
void
)
{
struct
syscall_xsave
*
xsave
=
get_syscall_xsave
(
x86_thread_data
()
->
syscall_frame
);
if
(
cpu_info
.
ProcessorFeatureBits
&
CPU_FEATURE_XSAVE
)
{
__asm__
volatile
(
"xrstor %0"
:
:
"m"
(
*
xsave
),
"a"
(
7
),
"d"
(
0
)
);
}
else
if
(
cpu_info
.
ProcessorFeatureBits
&
CPU_FEATURE_FXSR
)
{
__asm__
volatile
(
"fxrstor %0"
:
:
"m"
(
xsave
->
u
.
xsave
)
);
}
else
{
__asm__
volatile
(
"frstor %0; fwait"
:
:
"m"
(
xsave
->
u
.
fsave
)
);
}
set_full_cpu_context
();
x86_thread_data
()
->
syscall_frame
->
restore_flags
|=
CONTEXT_INTEGER
;
}
...
...
@@ -1092,6 +1022,7 @@ NTSTATUS WINAPI NtSetContextThread( HANDLE handle, const CONTEXT *context )
else
xsave
->
xstate
.
mask
&=
~
XSTATE_MASK_GSSE
;
}
frame
->
restore_flags
|=
flags
&
~
CONTEXT_INTEGER
;
return
STATUS_SUCCESS
;
}
...
...
@@ -1660,7 +1591,7 @@ __ASM_GLOBAL_FUNC( call_user_apc_dispatcher,
"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 0x3
8
(%eax),%eax
\n\t
"
/* &x86_thread_data()->syscall_frame->ret_addr */
"leal 0x3
c
(%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
"
...
...
@@ -1700,15 +1631,15 @@ __ASM_GLOBAL_FUNC( call_user_exception_dispatcher,
"jne 1f
\n\t
"
"decl 0xb8(%ecx)
\n
"
/* context->Eip */
"1:
\t
movl %fs:0x1f8,%eax
\n\t
"
/* x86_thread_data()->syscall_frame */
"movl 0x
1c
(%eax),%ebx
\n\t
"
/* frame->ebx */
"movl 0x2
8
(%eax),%edi
\n\t
"
/* frame->edi */
"movl 0x
2c
(%eax),%esi
\n\t
"
/* frame->esi */
"movl 0x3
0
(%eax),%ebp
\n\t
"
/* frame->ebp */
"movl %edx,0x3
0
(%eax)
\n\t
"
"movl %ecx,0x3
4
(%eax)
\n\t
"
"movl 0x
20
(%eax),%ebx
\n\t
"
/* frame->ebx */
"movl 0x2
c
(%eax),%edi
\n\t
"
/* frame->edi */
"movl 0x
30
(%eax),%esi
\n\t
"
/* frame->esi */
"movl 0x3
4
(%eax),%ebp
\n\t
"
/* frame->ebp */
"movl %edx,0x3
4
(%eax)
\n\t
"
"movl %ecx,0x3
8
(%eax)
\n\t
"
"movl 12(%esp),%edx
\n\t
"
/* dispatcher */
"movl $0,%fs:0x1f8
\n\t
"
"leal 0x3
0
(%eax),%esp
\n\t
"
"leal 0x3
4
(%eax),%esp
\n\t
"
"jmp *%edx"
)
/**********************************************************************
...
...
tools/winebuild/import.c
View file @
050378d4
...
...
@@ -1446,6 +1446,7 @@ static void output_syscall_dispatcher(void)
output
(
"
\t
movl %%esi,-0x04(%%ebp)
\n
"
);
output_cfi
(
".cfi_rel_offset %%esi,-0x04
\n
"
);
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
"
);
...
...
@@ -1496,7 +1497,7 @@ static void output_syscall_dispatcher(void)
output
(
"
\t
jmp 4f
\n
"
);
output
(
"3:
\t
fnsave (%%esp)
\n
"
);
output
(
"
\t
fwait
\n
"
);
output
(
"4:
\t
leal -0x3
0
(%%ebp),%%ecx
\n
"
);
output
(
"4:
\t
leal -0x3
4
(%%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 6f
\n
"
);
...
...
@@ -1514,15 +1515,18 @@ static void output_syscall_dispatcher(void)
output
(
"
\t
movl %%ebx,%%esi
\n
"
);
output
(
"
\t
call *(%%eax,%%edx,4)
\n
"
);
output
(
"5:
\t
movl $0,%%fs:0x1f8
\n
"
);
output
(
"
\t
leal -0x2f0(%%ebp),%%ebx
\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
(
"
\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
jz 1f
\n
"
);
output
(
"
\t
movl %%eax,%%e
cx
\n
"
);
output
(
"
\t
movl %%eax,%%e
di
\n
"
);
output
(
"
\t
movl $7,%%eax
\n
"
);
output
(
"
\t
xorl %%edx,%%edx
\n
"
);
output
(
"
\t
xrstor (%%ebx)
\n
"
);
output
(
"
\t
movl %%e
cx
,%%eax
\n
"
);
output
(
"
\t
movl %%e
di
,%%eax
\n
"
);
output
(
"
\t
jmp 3f
\n
"
);
output
(
"1:
\t
testl $4,%%esi
\n
"
);
/* SYSCALL_HAVE_FXSAVE */
output
(
"
\t
jz 2f
\n
"
);
...
...
@@ -1530,51 +1534,69 @@ static void output_syscall_dispatcher(void)
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
"
);
output
(
"
\t
movw 0x16(%%ebx),%%gs
\n
"
);
output
(
"
\t
movw 0x14(%%ebx),%%fs
\n
"
);
output
(
"
\t
movw 0x12(%%ebx),%%es
\n
"
);
output
(
"
\t
movl 0x28(%%ebx),%%edi
\n
"
);
output
(
"3:
\t
movl -0x08(%%ebp),%%edi
\n
"
);
output_cfi
(
".cfi_same_value %%edi"
);
output
(
"
\t
movl
0x2c(%%ebx
),%%esi
\n
"
);
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
(
"
\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
movw %%ss,%%cx
\n
"
);
output
(
"
\t
cmpw 0x0e(%%ebx),%%cx
\n
"
);
output
(
"
\t
popl %%esp
\n
"
);
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 0x08(%%ebx),%%ecx
\n
"
);
output
(
"
\t
leal -3*4(%%ecx),%%ecx
\n
"
);
output
(
"
\t
movl (%%ebx),%%edx
\n
"
);
output
(
"
\t
movl %%edx,2*4(%%ecx)
\n
"
);
output
(
"
\t
movl 0x0c(%%ebx),%%edx
\n
"
);
output
(
"
\t
movl %%edx,1*4(%%ecx)
\n
"
);
output
(
"
\t
movl 0x04(%%ebx),%%edx
\n
"
);
output
(
"
\t
movl %%edx,0*4(%%ecx)
\n
"
);
output
(
"
\t
pushl 0x10(%%ebx)
\n
"
);
output
(
"
\t
movl 0x1c(%%ebx),%%ebx
\n
"
);
output_cfi
(
".cfi_same_value %%ebx"
);
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 %%ecx,%%esp
\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
(
"
\t
3:
\t
movl 0x18(%%ebx),%%ecx
\n
"
);
output
(
"
\t
movw 0x0e(%%ebx),%%ss
\n
"
);
output
(
"
\t
movl 0x08(%%ebx),%%esp
\n
"
);
output
(
"
\t
pushl 0x00(%%ebx)
\n
"
);
output
(
"
\t
pushl 0x0c(%%ebx)
\n
"
);
output
(
"
\t
pushl 0x04(%%ebx)
\n
"
);
output
(
"
\t
pushl 0x10(%%ebx)
\n
"
);
output
(
"
\t
movl 0x1c(%%ebx),%%ebx
\n
"
);
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
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