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
3ecd43dc
Commit
3ecd43dc
authored
Feb 22, 2021
by
Jacek Caban
Committed by
Alexandre Julliard
Feb 22, 2021
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ntdll: Use syscall frames in x86_64 NtSetContextThread implementation.
Signed-off-by:
Jacek Caban
<
jacek@codeweavers.com
>
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
e162e7ea
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
97 additions
and
66 deletions
+97
-66
signal_x86_64.c
dlls/ntdll/unix/signal_x86_64.c
+97
-66
No files found.
dlls/ntdll/unix/signal_x86_64.c
View file @
3ecd43dc
...
...
@@ -1568,71 +1568,47 @@ static void restore_context( const struct xcontext *xcontext, ucontext_t *sigcon
*
* Set the new CPU context.
*/
extern
void
set_full_cpu_context
(
const
CONTEXT
*
context
);
extern
void
set_full_cpu_context
(
void
);
__ASM_GLOBAL_FUNC
(
set_full_cpu_context
,
"subq $40,%rsp
\n\t
"
__ASM_SEH
(
".seh_stackalloc 0x40
\n\t
"
)
__ASM_SEH
(
".seh_endprologue
\n\t
"
)
__ASM_CFI
(
".cfi_adjust_cfa_offset 40
\n\t
"
)
"movq %gs:0x30,%rdx
\n\t
"
"movw 0x38(%rdi),%ax
\n\t
"
/* context->SegCs */
"movq %rax,8(%rsp)
\n\t
"
"movw 0x42(%rdi),%ax
\n\t
"
/* context->SegSs */
"movq %rax,32(%rsp)
\n\t
"
"movq 0x44(%rdi),%rax
\n\t
"
/* context->Eflags */
"movq %rax,16(%rsp)
\n\t
"
"movq $0,0x328(%rdx)
\n\t
"
/* amd64_thread_data()->syscall_frame */
"movq 0x80(%rdi),%rcx
\n\t
"
/* context->Rcx */
"movq 0x88(%rdi),%rdx
\n\t
"
/* context->Rdx */
"movq 0x90(%rdi),%rbx
\n\t
"
/* context->Rbx */
"movq 0x98(%rdi),%rax
\n\t
"
/* context->Rsp */
"movq %rax,24(%rsp)
\n\t
"
"movq 0xa0(%rdi),%rbp
\n\t
"
/* context->Rbp */
"movq 0xa8(%rdi),%rsi
\n\t
"
/* context->Rsi */
"movq 0xb8(%rdi),%r8
\n\t
"
/* context->R8 */
"movq 0xc0(%rdi),%r9
\n\t
"
/* context->R9 */
"movq 0xc8(%rdi),%r10
\n\t
"
/* context->R10 */
"movq 0xd0(%rdi),%r11
\n\t
"
/* context->R11 */
"movq 0xd8(%rdi),%r12
\n\t
"
/* context->R12 */
"movq 0xe0(%rdi),%r13
\n\t
"
/* context->R13 */
"movq 0xe8(%rdi),%r14
\n\t
"
/* context->R14 */
"movq 0xf0(%rdi),%r15
\n\t
"
/* context->R15 */
"movq 0xf8(%rdi),%rax
\n\t
"
/* context->Rip */
"movq %rax,(%rsp)
\n\t
"
"fxrstor 0x100(%rdi)
\n\t
"
/* context->FltSave */
"movq 0x78(%rdi),%rax
\n\t
"
/* context->Rax */
"movq 0xb0(%rdi),%rdi
\n\t
"
/* context->Rdi */
"iretq"
);
/***********************************************************************
* restore_xstate
*
* Restore the XState context.
*/
static
void
restore_xstate
(
const
CONTEXT
*
context
)
{
XSAVE_FORMAT
*
xrstor_base
;
XSTATE
*
xs
;
if
(
!
(
user_shared_data
->
XState
.
EnabledFeatures
&&
(
xs
=
xstate_from_context
(
context
))))
return
;
xrstor_base
=
(
XSAVE_FORMAT
*
)
xs
-
1
;
"movq 0x328(%rdx),%rsp
\n\t
"
/* amd64_thread_data()->syscall_frame */
"movq $0,0x328(%rdx)
\n\t
"
"movq 0x00(%rsp),%rax
\n\t
"
"movq 0x08(%rsp),%rbx
\n\t
"
"movq 0x10(%rsp),%rcx
\n\t
"
"movq 0x18(%rsp),%rdx
\n\t
"
"movq 0x20(%rsp),%rsi
\n\t
"
"movq 0x28(%rsp),%rdi
\n\t
"
"movq 0x30(%rsp),%r8
\n\t
"
"movq 0x38(%rsp),%r9
\n\t
"
"movq 0x40(%rsp),%r10
\n\t
"
"movq 0x48(%rsp),%r11
\n\t
"
"movq 0x50(%rsp),%r12
\n\t
"
"movq 0x58(%rsp),%r13
\n\t
"
"movq 0x60(%rsp),%r14
\n\t
"
"movq 0x68(%rsp),%r15
\n\t
"
"movq 0x98(%rsp),%rbp
\n\t
"
"leaq 0x70(%rsp),%rsp
\n\t
"
"iretq"
)
static
void
signal_restore_full_cpu_context
(
void
)
{
struct
syscall_xsave
*
xsave
=
get_syscall_xsave
(
get_syscall_frame
()
);
SYSTEM_CPU_INFORMATION
cpu_info
;
if
(
!
(
xs
->
CompactionMask
&
((
ULONG64
)
1
<<
63
)))
NtQuerySystemInformation
(
SystemCpuInformation
,
&
cpu_info
,
sizeof
(
cpu_info
),
NULL
);
if
(
cpu_info
.
FeatureSet
&
CPU_FEATURE_XSAVE
)
{
/* Non-compacted xrstor will load Mxcsr regardless of the specified mask. Loading garbage there
* may lead to fault. We have only padding, no more used EXCEPTION_RECORD or unused context fields
* at the MxCsr restore location, so just put it there. */
assert
(
(
void
*
)
&
xrstor_base
->
MxCsr
>
(
void
*
)
context
->
VectorRegister
);
xrstor_base
->
MxCsr
=
context
->
u
.
FltSave
.
MxCsr
;
xrstor_base
->
MxCsr_Mask
=
context
->
u
.
FltSave
.
MxCsr_Mask
;
__asm__
volatile
(
"xrstor64 %0"
:
:
"m"
(
xsave
->
xsave
),
"a"
(
7
),
"d"
(
0
)
);
}
__asm__
volatile
(
"xrstor64 %0"
:
:
"m"
(
*
xrstor_base
),
"a"
(
4
),
"d"
(
0
)
);
else
{
__asm__
volatile
(
"fxrstor64 %0"
:
:
"m"
(
xsave
->
xsave
)
);
}
set_full_cpu_context
();
}
/***********************************************************************
* get_server_context_flags
*
...
...
@@ -1798,6 +1774,9 @@ NTSTATUS WINAPI NtSetContextThread( HANDLE handle, const CONTEXT *context )
NTSTATUS
ret
=
STATUS_SUCCESS
;
DWORD
flags
=
context
->
ContextFlags
&
~
CONTEXT_AMD64
;
BOOL
self
=
(
handle
==
GetCurrentThread
());
struct
syscall_frame
*
frame
;
struct
syscall_xsave
*
xsave
;
XSTATE
*
xs
;
/* debug registers require a server call */
if
(
self
&&
(
flags
&
CONTEXT_DEBUG_REGISTERS
))
...
...
@@ -1826,16 +1805,68 @@ NTSTATUS WINAPI NtSetContextThread( HANDLE handle, const CONTEXT *context )
}
}
restore_xstate
(
context
)
;
if
(
flags
&
CONTEXT_
FULL
)
frame
=
amd64_thread_data
()
->
syscall_frame
;
xsave
=
get_syscall_xsave
(
frame
);
if
(
flags
&
CONTEXT_
INTEGER
)
{
if
(
!
(
flags
&
CONTEXT_CONTROL
))
FIXME
(
"setting partial context (%x) not supported
\n
"
,
flags
);
else
set_full_cpu_context
(
context
);
frame
->
rax
=
context
->
Rax
;
frame
->
rbx
=
context
->
Rbx
;
frame
->
rcx
=
context
->
Rcx
;
frame
->
rdx
=
context
->
Rdx
;
frame
->
rsi
=
context
->
Rsi
;
frame
->
rdi
=
context
->
Rdi
;
frame
->
r8
=
context
->
R8
;
frame
->
r9
=
context
->
R9
;
frame
->
r10
=
context
->
R10
;
frame
->
r11
=
context
->
R11
;
frame
->
r12
=
context
->
R12
;
frame
->
r13
=
context
->
R13
;
frame
->
r14
=
context
->
R14
;
frame
->
r15
=
context
->
R15
;
}
return
ret
;
if
(
flags
&
CONTEXT_CONTROL
)
{
frame
->
rsp
=
context
->
Rsp
;
frame
->
rbp
=
context
->
Rbp
;
frame
->
rip
=
context
->
Rip
;
frame
->
eflags
=
context
->
EFlags
;
frame
->
cs
=
context
->
SegCs
;
frame
->
ss
=
context
->
SegSs
;
}
if
(
flags
&
CONTEXT_SEGMENTS
)
{
frame
->
ds
=
context
->
SegDs
;
frame
->
es
=
context
->
SegEs
;
frame
->
fs
=
context
->
SegFs
;
frame
->
gs
=
context
->
SegGs
;
}
if
(
flags
&
CONTEXT_FLOATING_POINT
)
{
xsave
->
xsave
=
context
->
u
.
FltSave
;
}
if
(
user_shared_data
->
XState
.
EnabledFeatures
&&
(
xs
=
xstate_from_context
(
context
)))
{
CONTEXT_EX
*
context_ex
=
(
CONTEXT_EX
*
)(
context
+
1
);
if
(
context_ex
->
XState
.
Length
<
offsetof
(
XSTATE
,
YmmContext
)
||
context_ex
->
XState
.
Length
>
sizeof
(
XSTATE
))
return
STATUS_INVALID_PARAMETER
;
if
(
xs
->
Mask
&
XSTATE_MASK_GSSE
)
{
if
(
context_ex
->
XState
.
Length
<
sizeof
(
XSTATE
))
return
STATUS_BUFFER_OVERFLOW
;
xsave
->
xstate
.
Mask
|=
XSTATE_MASK_GSSE
;
memcpy
(
&
xsave
->
xstate
.
YmmContext
,
&
xs
->
YmmContext
,
sizeof
(
xs
->
YmmContext
)
);
}
else
if
(
xs
->
CompactionMask
&
XSTATE_MASK_GSSE
)
xsave
->
xstate
.
Mask
&=
~
XSTATE_MASK_GSSE
;
}
if
(
!
(
flags
&
CONTEXT_INTEGER
))
frame
->
rax
=
STATUS_SUCCESS
;
signal_restore_full_cpu_context
();
return
STATUS_SUCCESS
;
}
...
...
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