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
419abd49
Commit
419abd49
authored
Oct 09, 2020
by
Paul Gofman
Committed by
Alexandre Julliard
Oct 13, 2020
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ntdll: Support AVX registers for other thread in Nt{Get|Set}ContextThread().
Signed-off-by:
Paul Gofman
<
pgofman@codeweavers.com
>
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
ec1ea1ea
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
148 additions
and
34 deletions
+148
-34
server.c
dlls/ntdll/unix/server.c
+7
-0
signal_i386.c
dlls/ntdll/unix/signal_i386.c
+19
-12
signal_x86_64.c
dlls/ntdll/unix/signal_x86_64.c
+24
-11
thread.c
dlls/ntdll/unix/thread.c
+32
-4
unix_private.h
dlls/ntdll/unix/unix_private.h
+49
-7
server_protocol.h
include/wine/server_protocol.h
+5
-0
protocol.def
server/protocol.def
+5
-0
thread.c
server/thread.c
+1
-0
trace.c
server/trace.c
+6
-0
No files found.
dlls/ntdll/unix/server.c
View file @
419abd49
...
@@ -631,8 +631,15 @@ unsigned int server_select( const select_op_t *select_op, data_size_t size, UINT
...
@@ -631,8 +631,15 @@ unsigned int server_select( const select_op_t *select_op, data_size_t size, UINT
if
(
wine_server_reply_size
(
reply
))
if
(
wine_server_reply_size
(
reply
))
{
{
DWORD
context_flags
=
context
->
ContextFlags
;
/* unchanged registers are still available */
DWORD
context_flags
=
context
->
ContextFlags
;
/* unchanged registers are still available */
XSTATE
*
xs
=
xstate_from_context
(
context
);
ULONG64
mask
;
if
(
xs
)
mask
=
xs
->
Mask
;
context_from_server
(
context
,
&
server_context
);
context_from_server
(
context
,
&
server_context
);
context
->
ContextFlags
|=
context_flags
;
context
->
ContextFlags
|=
context_flags
;
if
(
xs
)
xs
->
Mask
|=
mask
;
}
}
}
}
SERVER_END_REQ
;
SERVER_END_REQ
;
...
...
dlls/ntdll/unix/signal_i386.c
View file @
419abd49
...
@@ -886,14 +886,16 @@ static inline void save_context( struct xcontext *xcontext, const ucontext_t *si
...
@@ -886,14 +886,16 @@ static inline void save_context( struct xcontext *xcontext, const ucontext_t *si
}
}
if
(
fpux
)
if
(
fpux
)
{
{
XSTATE
*
xs
;
context
->
ContextFlags
|=
CONTEXT_FLOATING_POINT
|
CONTEXT_EXTENDED_REGISTERS
;
context
->
ContextFlags
|=
CONTEXT_FLOATING_POINT
|
CONTEXT_EXTENDED_REGISTERS
;
memcpy
(
context
->
ExtendedRegisters
,
fpux
,
sizeof
(
*
fpux
)
);
memcpy
(
context
->
ExtendedRegisters
,
fpux
,
sizeof
(
*
fpux
)
);
if
(
!
fpu
)
fpux_to_fpu
(
&
context
->
FloatSave
,
fpux
);
if
(
!
fpu
)
fpux_to_fpu
(
&
context
->
FloatSave
,
fpux
);
xcontext
->
xstate
=
XState_sig
(
fpux
);
if
((
xs
=
XState_sig
(
fpux
)))
}
{
else
context_init_xstate
(
context
,
xs
);
{
xcontext
->
host_compaction_mask
=
xs
->
CompactionMask
;
xcontext
->
xstate
=
NULL
;
}
}
}
if
(
!
fpu
&&
!
fpux
)
save_fpu
(
context
);
if
(
!
fpu
&&
!
fpux
)
save_fpu
(
context
);
}
}
...
@@ -944,6 +946,7 @@ static inline void restore_context( const struct xcontext *xcontext, ucontext_t
...
@@ -944,6 +946,7 @@ static inline void restore_context( const struct xcontext *xcontext, ucontext_t
{
{
memcpy
(
&
dst_xs
->
YmmContext
,
&
src_xs
->
YmmContext
,
sizeof
(
dst_xs
->
YmmContext
)
);
memcpy
(
&
dst_xs
->
YmmContext
,
&
src_xs
->
YmmContext
,
sizeof
(
dst_xs
->
YmmContext
)
);
dst_xs
->
Mask
|=
src_xs
->
Mask
;
dst_xs
->
Mask
|=
src_xs
->
Mask
;
dst_xs
->
CompactionMask
=
xcontext
->
host_compaction_mask
;
}
}
}
}
if
(
!
fpu
&&
!
fpux
)
restore_fpu
(
context
);
if
(
!
fpu
&&
!
fpux
)
restore_fpu
(
context
);
...
@@ -1023,6 +1026,7 @@ static unsigned int get_server_context_flags( DWORD flags )
...
@@ -1023,6 +1026,7 @@ static unsigned int get_server_context_flags( DWORD flags )
if
(
flags
&
CONTEXT_FLOATING_POINT
)
ret
|=
SERVER_CTX_FLOATING_POINT
;
if
(
flags
&
CONTEXT_FLOATING_POINT
)
ret
|=
SERVER_CTX_FLOATING_POINT
;
if
(
flags
&
CONTEXT_DEBUG_REGISTERS
)
ret
|=
SERVER_CTX_DEBUG_REGISTERS
;
if
(
flags
&
CONTEXT_DEBUG_REGISTERS
)
ret
|=
SERVER_CTX_DEBUG_REGISTERS
;
if
(
flags
&
CONTEXT_EXTENDED_REGISTERS
)
ret
|=
SERVER_CTX_EXTENDED_REGISTERS
;
if
(
flags
&
CONTEXT_EXTENDED_REGISTERS
)
ret
|=
SERVER_CTX_EXTENDED_REGISTERS
;
if
(
flags
&
CONTEXT_XSTATE
)
ret
|=
SERVER_CTX_YMM_REGISTERS
;
return
ret
;
return
ret
;
}
}
...
@@ -1095,6 +1099,7 @@ NTSTATUS context_to_server( context_t *to, const CONTEXT *from )
...
@@ -1095,6 +1099,7 @@ NTSTATUS context_to_server( context_t *to, const CONTEXT *from )
to
->
flags
|=
SERVER_CTX_EXTENDED_REGISTERS
;
to
->
flags
|=
SERVER_CTX_EXTENDED_REGISTERS
;
memcpy
(
to
->
ext
.
i386_regs
,
from
->
ExtendedRegisters
,
sizeof
(
to
->
ext
.
i386_regs
)
);
memcpy
(
to
->
ext
.
i386_regs
,
from
->
ExtendedRegisters
,
sizeof
(
to
->
ext
.
i386_regs
)
);
}
}
xstate_to_server
(
to
,
xstate_from_context
(
from
)
);
return
STATUS_SUCCESS
;
return
STATUS_SUCCESS
;
}
}
...
@@ -1108,7 +1113,7 @@ NTSTATUS context_from_server( CONTEXT *to, const context_t *from )
...
@@ -1108,7 +1113,7 @@ NTSTATUS context_from_server( CONTEXT *to, const context_t *from )
{
{
if
(
from
->
cpu
!=
CPU_x86
)
return
STATUS_INVALID_PARAMETER
;
if
(
from
->
cpu
!=
CPU_x86
)
return
STATUS_INVALID_PARAMETER
;
to
->
ContextFlags
=
CONTEXT_i386
;
to
->
ContextFlags
=
CONTEXT_i386
|
(
to
->
ContextFlags
&
0x40
)
;
if
(
from
->
flags
&
SERVER_CTX_CONTROL
)
if
(
from
->
flags
&
SERVER_CTX_CONTROL
)
{
{
to
->
ContextFlags
|=
CONTEXT_CONTROL
;
to
->
ContextFlags
|=
CONTEXT_CONTROL
;
...
@@ -1165,6 +1170,7 @@ NTSTATUS context_from_server( CONTEXT *to, const context_t *from )
...
@@ -1165,6 +1170,7 @@ NTSTATUS context_from_server( CONTEXT *to, const context_t *from )
to
->
ContextFlags
|=
CONTEXT_EXTENDED_REGISTERS
;
to
->
ContextFlags
|=
CONTEXT_EXTENDED_REGISTERS
;
memcpy
(
to
->
ExtendedRegisters
,
from
->
ext
.
i386_regs
,
sizeof
(
to
->
ExtendedRegisters
)
);
memcpy
(
to
->
ExtendedRegisters
,
from
->
ext
.
i386_regs
,
sizeof
(
to
->
ExtendedRegisters
)
);
}
}
xstate_from_server
(
xstate_from_context
(
to
),
from
);
return
STATUS_SUCCESS
;
return
STATUS_SUCCESS
;
}
}
...
@@ -1246,7 +1252,7 @@ NTSTATUS WINAPI NtGetContextThread( HANDLE handle, CONTEXT *context )
...
@@ -1246,7 +1252,7 @@ NTSTATUS WINAPI NtGetContextThread( HANDLE handle, CONTEXT *context )
/* Save xstate before any calls which can potentially change volatile ymm registers.
/* Save xstate before any calls which can potentially change volatile ymm registers.
* E. g., debug output will clobber ymm registers. */
* E. g., debug output will clobber ymm registers. */
xsave_status
=
self
?
save_xstate
(
context
)
:
STATUS_SUCCESS
;
/* FIXME: other thread. */
xsave_status
=
self
?
save_xstate
(
context
)
:
STATUS_SUCCESS
;
/* debug registers require a server call */
/* debug registers require a server call */
if
(
needed_flags
&
CONTEXT_DEBUG_REGISTERS
)
self
=
FALSE
;
if
(
needed_flags
&
CONTEXT_DEBUG_REGISTERS
)
self
=
FALSE
;
...
@@ -1293,7 +1299,6 @@ NTSTATUS WINAPI NtGetContextThread( HANDLE handle, CONTEXT *context )
...
@@ -1293,7 +1299,6 @@ NTSTATUS WINAPI NtGetContextThread( HANDLE handle, CONTEXT *context )
}
}
if
(
needed_flags
&
CONTEXT_FLOATING_POINT
)
save_fpu
(
context
);
if
(
needed_flags
&
CONTEXT_FLOATING_POINT
)
save_fpu
(
context
);
if
(
needed_flags
&
CONTEXT_EXTENDED_REGISTERS
)
save_fpux
(
context
);
if
(
needed_flags
&
CONTEXT_EXTENDED_REGISTERS
)
save_fpux
(
context
);
/* FIXME: xstate */
/* update the cached version of the debug registers */
/* update the cached version of the debug registers */
if
(
context
->
ContextFlags
&
(
CONTEXT_DEBUG_REGISTERS
&
~
CONTEXT_i386
))
if
(
context
->
ContextFlags
&
(
CONTEXT_DEBUG_REGISTERS
&
~
CONTEXT_i386
))
{
{
...
@@ -1579,6 +1584,7 @@ static void setup_raise_exception( ucontext_t *sigcontext, void *stack_ptr,
...
@@ -1579,6 +1584,7 @@ static void setup_raise_exception( ucontext_t *sigcontext, void *stack_ptr,
{
{
CONTEXT
*
context
=
&
xcontext
->
c
;
CONTEXT
*
context
=
&
xcontext
->
c
;
size_t
stack_size
;
size_t
stack_size
;
XSTATE
*
src_xs
;
struct
stack_layout
struct
stack_layout
{
{
...
@@ -1606,7 +1612,7 @@ C_ASSERT( (offsetof(struct stack_layout, xstate) == sizeof(struct stack_layout))
...
@@ -1606,7 +1612,7 @@ C_ASSERT( (offsetof(struct stack_layout, xstate) == sizeof(struct stack_layout))
if
(
rec
->
ExceptionCode
==
EXCEPTION_BREAKPOINT
)
context
->
Eip
--
;
if
(
rec
->
ExceptionCode
==
EXCEPTION_BREAKPOINT
)
context
->
Eip
--
;
stack_size
=
sizeof
(
*
stack
);
stack_size
=
sizeof
(
*
stack
);
if
(
xcontext
->
xstate
)
if
(
(
src_xs
=
xstate_from_context
(
context
))
)
{
{
stack_size
+=
(
ULONG_PTR
)
stack_ptr
-
(((
ULONG_PTR
)
stack_ptr
stack_size
+=
(
ULONG_PTR
)
stack_ptr
-
(((
ULONG_PTR
)
stack_ptr
-
sizeof
(
XSTATE
))
&
~
(
ULONG_PTR
)
63
);
-
sizeof
(
XSTATE
))
&
~
(
ULONG_PTR
)
63
);
...
@@ -1616,17 +1622,18 @@ C_ASSERT( (offsetof(struct stack_layout, xstate) == sizeof(struct stack_layout))
...
@@ -1616,17 +1622,18 @@ C_ASSERT( (offsetof(struct stack_layout, xstate) == sizeof(struct stack_layout))
stack
->
rec
=
*
rec
;
stack
->
rec
=
*
rec
;
stack
->
context
=
*
context
;
stack
->
context
=
*
context
;
if
(
xcontext
->
xstate
)
if
(
src_xs
)
{
{
XSTATE
*
dst_xs
=
(
XSTATE
*
)
stack
->
xstate
;
XSTATE
*
dst_xs
=
(
XSTATE
*
)
stack
->
xstate
;
assert
(
!
((
ULONG_PTR
)
dst_xs
&
63
));
assert
(
!
((
ULONG_PTR
)
dst_xs
&
63
));
context_init_xstate
(
&
stack
->
context
,
stack
->
xstate
);
context_init_xstate
(
&
stack
->
context
,
stack
->
xstate
);
memset
(
dst_xs
,
0
,
offsetof
(
XSTATE
,
YmmContext
)
);
dst_xs
->
CompactionMask
=
user_shared_data
->
XState
.
CompactionEnabled
?
0x8000000000000004
:
0
;
dst_xs
->
CompactionMask
=
user_shared_data
->
XState
.
CompactionEnabled
?
0x8000000000000004
:
0
;
if
(
xcontext
->
xstate
->
Mask
&
4
)
if
(
src_xs
->
Mask
&
4
)
{
{
dst_xs
->
Mask
=
4
;
dst_xs
->
Mask
=
4
;
memcpy
(
&
dst_xs
->
YmmContext
,
&
xcontext
->
xstate
->
YmmContext
,
sizeof
(
dst_xs
->
YmmContext
)
);
memcpy
(
&
dst_xs
->
YmmContext
,
&
src_xs
->
YmmContext
,
sizeof
(
dst_xs
->
YmmContext
)
);
}
}
}
}
...
...
dlls/ntdll/unix/signal_x86_64.c
View file @
419abd49
...
@@ -1461,14 +1461,19 @@ static void save_context( struct xcontext *xcontext, const ucontext_t *sigcontex
...
@@ -1461,14 +1461,19 @@ static void save_context( struct xcontext *xcontext, const ucontext_t *sigcontex
context
->
Dr7
=
amd64_thread_data
()
->
dr7
;
context
->
Dr7
=
amd64_thread_data
()
->
dr7
;
if
(
FPU_sig
(
sigcontext
))
if
(
FPU_sig
(
sigcontext
))
{
{
XSTATE
*
xs
;
context
->
ContextFlags
|=
CONTEXT_FLOATING_POINT
;
context
->
ContextFlags
|=
CONTEXT_FLOATING_POINT
;
context
->
u
.
FltSave
=
*
FPU_sig
(
sigcontext
);
context
->
u
.
FltSave
=
*
FPU_sig
(
sigcontext
);
context
->
MxCsr
=
context
->
u
.
FltSave
.
MxCsr
;
context
->
MxCsr
=
context
->
u
.
FltSave
.
MxCsr
;
xcontext
->
xstate
=
XState_sig
(
FPU_sig
(
sigcontext
));
if
((
xs
=
XState_sig
(
FPU_sig
(
sigcontext
))))
}
{
else
/* xcontext and sigcontext are both on the signal stack, so we can
{
* just reference sigcontext without overflowing 32 bit XState.Offset */
xcontext
->
xstate
=
NULL
;
context_init_xstate
(
context
,
xs
);
assert
(
xcontext
->
c_ex
.
XState
.
Offset
==
(
BYTE
*
)
xs
-
(
BYTE
*
)
&
xcontext
->
c_ex
);
xcontext
->
host_compaction_mask
=
xs
->
CompactionMask
;
}
}
}
}
}
...
@@ -1531,6 +1536,7 @@ static inline NTSTATUS save_xstate( CONTEXT *context )
...
@@ -1531,6 +1536,7 @@ static inline NTSTATUS save_xstate( CONTEXT *context )
static
void
restore_context
(
const
struct
xcontext
*
xcontext
,
ucontext_t
*
sigcontext
)
static
void
restore_context
(
const
struct
xcontext
*
xcontext
,
ucontext_t
*
sigcontext
)
{
{
const
CONTEXT
*
context
=
&
xcontext
->
c
;
const
CONTEXT
*
context
=
&
xcontext
->
c
;
XSTATE
*
xs
;
amd64_thread_data
()
->
dr0
=
context
->
Dr0
;
amd64_thread_data
()
->
dr0
=
context
->
Dr0
;
amd64_thread_data
()
->
dr1
=
context
->
Dr1
;
amd64_thread_data
()
->
dr1
=
context
->
Dr1
;
...
@@ -1540,6 +1546,8 @@ static void restore_context( const struct xcontext *xcontext, ucontext_t *sigcon
...
@@ -1540,6 +1546,8 @@ static void restore_context( const struct xcontext *xcontext, ucontext_t *sigcon
amd64_thread_data
()
->
dr7
=
context
->
Dr7
;
amd64_thread_data
()
->
dr7
=
context
->
Dr7
;
set_sigcontext
(
context
,
sigcontext
);
set_sigcontext
(
context
,
sigcontext
);
if
(
FPU_sig
(
sigcontext
))
*
FPU_sig
(
sigcontext
)
=
context
->
u
.
FltSave
;
if
(
FPU_sig
(
sigcontext
))
*
FPU_sig
(
sigcontext
)
=
context
->
u
.
FltSave
;
if
((
xs
=
XState_sig
(
FPU_sig
(
sigcontext
))))
xs
->
CompactionMask
=
xcontext
->
host_compaction_mask
;
}
}
...
@@ -1628,6 +1636,7 @@ static unsigned int get_server_context_flags( DWORD flags )
...
@@ -1628,6 +1636,7 @@ static unsigned int get_server_context_flags( DWORD flags )
if
(
flags
&
CONTEXT_SEGMENTS
)
ret
|=
SERVER_CTX_SEGMENTS
;
if
(
flags
&
CONTEXT_SEGMENTS
)
ret
|=
SERVER_CTX_SEGMENTS
;
if
(
flags
&
CONTEXT_FLOATING_POINT
)
ret
|=
SERVER_CTX_FLOATING_POINT
;
if
(
flags
&
CONTEXT_FLOATING_POINT
)
ret
|=
SERVER_CTX_FLOATING_POINT
;
if
(
flags
&
CONTEXT_DEBUG_REGISTERS
)
ret
|=
SERVER_CTX_DEBUG_REGISTERS
;
if
(
flags
&
CONTEXT_DEBUG_REGISTERS
)
ret
|=
SERVER_CTX_DEBUG_REGISTERS
;
if
(
flags
&
CONTEXT_XSTATE
)
ret
|=
SERVER_CTX_YMM_REGISTERS
;
return
ret
;
return
ret
;
}
}
...
@@ -1695,6 +1704,7 @@ NTSTATUS context_to_server( context_t *to, const CONTEXT *from )
...
@@ -1695,6 +1704,7 @@ NTSTATUS context_to_server( context_t *to, const CONTEXT *from )
to
->
debug
.
x86_64_regs
.
dr6
=
from
->
Dr6
;
to
->
debug
.
x86_64_regs
.
dr6
=
from
->
Dr6
;
to
->
debug
.
x86_64_regs
.
dr7
=
from
->
Dr7
;
to
->
debug
.
x86_64_regs
.
dr7
=
from
->
Dr7
;
}
}
xstate_to_server
(
to
,
xstate_from_context
(
from
)
);
return
STATUS_SUCCESS
;
return
STATUS_SUCCESS
;
}
}
...
@@ -1708,7 +1718,7 @@ NTSTATUS context_from_server( CONTEXT *to, const context_t *from )
...
@@ -1708,7 +1718,7 @@ NTSTATUS context_from_server( CONTEXT *to, const context_t *from )
{
{
if
(
from
->
cpu
!=
CPU_x86_64
)
return
STATUS_INVALID_PARAMETER
;
if
(
from
->
cpu
!=
CPU_x86_64
)
return
STATUS_INVALID_PARAMETER
;
to
->
ContextFlags
=
CONTEXT_AMD64
;
to
->
ContextFlags
=
CONTEXT_AMD64
|
(
to
->
ContextFlags
&
0x40
)
;
if
(
from
->
flags
&
SERVER_CTX_CONTROL
)
if
(
from
->
flags
&
SERVER_CTX_CONTROL
)
{
{
to
->
ContextFlags
|=
CONTEXT_CONTROL
;
to
->
ContextFlags
|=
CONTEXT_CONTROL
;
...
@@ -1762,6 +1772,7 @@ NTSTATUS context_from_server( CONTEXT *to, const context_t *from )
...
@@ -1762,6 +1772,7 @@ NTSTATUS context_from_server( CONTEXT *to, const context_t *from )
to
->
Dr6
=
from
->
debug
.
x86_64_regs
.
dr6
;
to
->
Dr6
=
from
->
debug
.
x86_64_regs
.
dr6
;
to
->
Dr7
=
from
->
debug
.
x86_64_regs
.
dr7
;
to
->
Dr7
=
from
->
debug
.
x86_64_regs
.
dr7
;
}
}
xstate_from_server
(
xstate_from_context
(
to
),
from
);
return
STATUS_SUCCESS
;
return
STATUS_SUCCESS
;
}
}
...
@@ -1831,7 +1842,7 @@ NTSTATUS WINAPI NtGetContextThread( HANDLE handle, CONTEXT *context )
...
@@ -1831,7 +1842,7 @@ NTSTATUS WINAPI NtGetContextThread( HANDLE handle, CONTEXT *context )
/* Save xstate before any calls which can potentially change volatile ymm registers.
/* Save xstate before any calls which can potentially change volatile ymm registers.
* E. g., debug output will clobber ymm registers. */
* E. g., debug output will clobber ymm registers. */
xsave_status
=
self
?
save_xstate
(
context
)
:
STATUS_SUCCESS
;
/* FIXME: other thread. */
xsave_status
=
self
?
save_xstate
(
context
)
:
STATUS_SUCCESS
;
needed_flags
=
context
->
ContextFlags
&
~
CONTEXT_AMD64
;
needed_flags
=
context
->
ContextFlags
&
~
CONTEXT_AMD64
;
...
@@ -1924,6 +1935,7 @@ static void setup_raise_exception( ucontext_t *sigcontext, EXCEPTION_RECORD *rec
...
@@ -1924,6 +1935,7 @@ static void setup_raise_exception( ucontext_t *sigcontext, EXCEPTION_RECORD *rec
struct
stack_layout
*
stack
;
struct
stack_layout
*
stack
;
size_t
stack_size
;
size_t
stack_size
;
NTSTATUS
status
;
NTSTATUS
status
;
XSTATE
*
src_xs
;
if
(
rec
->
ExceptionCode
==
EXCEPTION_SINGLE_STEP
)
if
(
rec
->
ExceptionCode
==
EXCEPTION_SINGLE_STEP
)
{
{
...
@@ -1953,7 +1965,7 @@ static void setup_raise_exception( ucontext_t *sigcontext, EXCEPTION_RECORD *rec
...
@@ -1953,7 +1965,7 @@ static void setup_raise_exception( ucontext_t *sigcontext, EXCEPTION_RECORD *rec
if
(
rec
->
ExceptionCode
==
EXCEPTION_BREAKPOINT
)
context
->
Rip
--
;
if
(
rec
->
ExceptionCode
==
EXCEPTION_BREAKPOINT
)
context
->
Rip
--
;
stack_size
=
sizeof
(
*
stack
);
stack_size
=
sizeof
(
*
stack
);
if
(
xcontext
->
xstate
)
if
(
(
src_xs
=
xstate_from_context
(
context
))
)
{
{
stack_size
+=
(
ULONG_PTR
)
stack_ptr
-
(((
ULONG_PTR
)
stack_ptr
stack_size
+=
(
ULONG_PTR
)
stack_ptr
-
(((
ULONG_PTR
)
stack_ptr
-
sizeof
(
XSTATE
))
&
~
(
ULONG_PTR
)
63
);
-
sizeof
(
XSTATE
))
&
~
(
ULONG_PTR
)
63
);
...
@@ -1962,17 +1974,18 @@ static void setup_raise_exception( ucontext_t *sigcontext, EXCEPTION_RECORD *rec
...
@@ -1962,17 +1974,18 @@ static void setup_raise_exception( ucontext_t *sigcontext, EXCEPTION_RECORD *rec
stack
=
virtual_setup_exception
(
stack_ptr
,
stack_size
,
rec
);
stack
=
virtual_setup_exception
(
stack_ptr
,
stack_size
,
rec
);
stack
->
rec
=
*
rec
;
stack
->
rec
=
*
rec
;
stack
->
context
=
*
context
;
stack
->
context
=
*
context
;
if
(
xcontext
->
xstate
)
if
(
src_xs
)
{
{
XSTATE
*
dst_xs
=
(
XSTATE
*
)
stack
->
xstate
;
XSTATE
*
dst_xs
=
(
XSTATE
*
)
stack
->
xstate
;
assert
(
!
((
ULONG_PTR
)
dst_xs
&
63
)
);
assert
(
!
((
ULONG_PTR
)
dst_xs
&
63
)
);
context_init_xstate
(
&
stack
->
context
,
stack
->
xstate
);
context_init_xstate
(
&
stack
->
context
,
stack
->
xstate
);
memset
(
dst_xs
,
0
,
offsetof
(
XSTATE
,
YmmContext
)
);
dst_xs
->
CompactionMask
=
user_shared_data
->
XState
.
CompactionEnabled
?
0x8000000000000004
:
0
;
dst_xs
->
CompactionMask
=
user_shared_data
->
XState
.
CompactionEnabled
?
0x8000000000000004
:
0
;
if
(
xcontext
->
xstate
->
Mask
&
4
)
if
(
src_xs
->
Mask
&
4
)
{
{
dst_xs
->
Mask
=
4
;
dst_xs
->
Mask
=
4
;
memcpy
(
&
dst_xs
->
YmmContext
,
&
xcontext
->
xstate
->
YmmContext
,
sizeof
(
dst_xs
->
YmmContext
)
);
memcpy
(
&
dst_xs
->
YmmContext
,
&
src_xs
->
YmmContext
,
sizeof
(
dst_xs
->
YmmContext
)
);
}
}
}
}
...
...
dlls/ntdll/unix/thread.c
View file @
419abd49
...
@@ -344,7 +344,6 @@ NTSTATUS send_debug_event( EXCEPTION_RECORD *rec, CONTEXT *context, BOOL first_c
...
@@ -344,7 +344,6 @@ NTSTATUS send_debug_event( EXCEPTION_RECORD *rec, CONTEXT *context, BOOL first_c
DWORD
i
;
DWORD
i
;
obj_handle_t
handle
=
0
;
obj_handle_t
handle
=
0
;
client_ptr_t
params
[
EXCEPTION_MAXIMUM_PARAMETERS
];
client_ptr_t
params
[
EXCEPTION_MAXIMUM_PARAMETERS
];
CONTEXT
exception_context
=
*
context
;
select_op_t
select_op
;
select_op_t
select_op
;
sigset_t
old_set
;
sigset_t
old_set
;
...
@@ -370,10 +369,22 @@ NTSTATUS send_debug_event( EXCEPTION_RECORD *rec, CONTEXT *context, BOOL first_c
...
@@ -370,10 +369,22 @@ NTSTATUS send_debug_event( EXCEPTION_RECORD *rec, CONTEXT *context, BOOL first_c
if
(
handle
)
if
(
handle
)
{
{
struct
xcontext
exception_context
;
DECLSPEC_ALIGN
(
64
)
XSTATE
xs
;
XSTATE
*
src_xs
;
select_op
.
wait
.
op
=
SELECT_WAIT
;
select_op
.
wait
.
op
=
SELECT_WAIT
;
select_op
.
wait
.
handles
[
0
]
=
handle
;
select_op
.
wait
.
handles
[
0
]
=
handle
;
exception_context
.
c
=
*
context
;
if
((
src_xs
=
xstate_from_context
(
context
)))
{
context_init_xstate
(
&
exception_context
.
c
,
&
xs
);
memcpy
(
&
xs
,
src_xs
,
sizeof
(
xs
)
);
}
server_select
(
&
select_op
,
offsetof
(
select_op_t
,
wait
.
handles
[
1
]
),
SELECT_INTERRUPTIBLE
,
server_select
(
&
select_op
,
offsetof
(
select_op_t
,
wait
.
handles
[
1
]
),
SELECT_INTERRUPTIBLE
,
TIMEOUT_INFINITE
,
&
exception_context
,
NULL
,
NULL
);
TIMEOUT_INFINITE
,
&
exception_context
.
c
,
NULL
,
NULL
);
SERVER_START_REQ
(
get_exception_status
)
SERVER_START_REQ
(
get_exception_status
)
{
{
...
@@ -381,7 +392,12 @@ NTSTATUS send_debug_event( EXCEPTION_RECORD *rec, CONTEXT *context, BOOL first_c
...
@@ -381,7 +392,12 @@ NTSTATUS send_debug_event( EXCEPTION_RECORD *rec, CONTEXT *context, BOOL first_c
ret
=
wine_server_call
(
req
);
ret
=
wine_server_call
(
req
);
}
}
SERVER_END_REQ
;
SERVER_END_REQ
;
if
(
ret
>=
0
)
*
context
=
exception_context
;
if
(
ret
>=
0
)
{
*
context
=
exception_context
.
c
;
if
(
src_xs
)
memcpy
(
src_xs
,
&
xs
,
sizeof
(
xs
)
);
}
}
}
pthread_sigmask
(
SIG_SETMASK
,
&
old_set
,
NULL
);
pthread_sigmask
(
SIG_SETMASK
,
&
old_set
,
NULL
);
...
@@ -632,7 +648,7 @@ static NTSTATUS wow64_context_from_server( WOW64_CONTEXT *to, const context_t *f
...
@@ -632,7 +648,7 @@ static NTSTATUS wow64_context_from_server( WOW64_CONTEXT *to, const context_t *f
{
{
if
(
from
->
cpu
!=
CPU_x86
)
return
STATUS_INVALID_PARAMETER
;
if
(
from
->
cpu
!=
CPU_x86
)
return
STATUS_INVALID_PARAMETER
;
to
->
ContextFlags
=
WOW64_CONTEXT_i386
;
to
->
ContextFlags
=
WOW64_CONTEXT_i386
|
(
to
->
ContextFlags
&
0x40
)
;
if
(
from
->
flags
&
SERVER_CTX_CONTROL
)
if
(
from
->
flags
&
SERVER_CTX_CONTROL
)
{
{
to
->
ContextFlags
|=
WOW64_CONTEXT_CONTROL
;
to
->
ContextFlags
|=
WOW64_CONTEXT_CONTROL
;
...
@@ -689,6 +705,12 @@ static NTSTATUS wow64_context_from_server( WOW64_CONTEXT *to, const context_t *f
...
@@ -689,6 +705,12 @@ static NTSTATUS wow64_context_from_server( WOW64_CONTEXT *to, const context_t *f
to
->
ContextFlags
|=
WOW64_CONTEXT_EXTENDED_REGISTERS
;
to
->
ContextFlags
|=
WOW64_CONTEXT_EXTENDED_REGISTERS
;
memcpy
(
to
->
ExtendedRegisters
,
from
->
ext
.
i386_regs
,
sizeof
(
to
->
ExtendedRegisters
)
);
memcpy
(
to
->
ExtendedRegisters
,
from
->
ext
.
i386_regs
,
sizeof
(
to
->
ExtendedRegisters
)
);
}
}
if
((
to
->
ContextFlags
&
WOW64_CONTEXT_XSTATE
)
==
WOW64_CONTEXT_XSTATE
)
{
CONTEXT_EX
*
c_ex
=
(
CONTEXT_EX
*
)(
to
+
1
);
xstate_from_server
(
(
XSTATE
*
)((
BYTE
*
)
c_ex
+
c_ex
->
XState
.
Offset
),
from
);
}
return
STATUS_SUCCESS
;
return
STATUS_SUCCESS
;
}
}
...
@@ -758,6 +780,12 @@ static void wow64_context_to_server( context_t *to, const WOW64_CONTEXT *from )
...
@@ -758,6 +780,12 @@ static void wow64_context_to_server( context_t *to, const WOW64_CONTEXT *from )
to
->
flags
|=
SERVER_CTX_EXTENDED_REGISTERS
;
to
->
flags
|=
SERVER_CTX_EXTENDED_REGISTERS
;
memcpy
(
to
->
ext
.
i386_regs
,
from
->
ExtendedRegisters
,
sizeof
(
to
->
ext
.
i386_regs
)
);
memcpy
(
to
->
ext
.
i386_regs
,
from
->
ExtendedRegisters
,
sizeof
(
to
->
ext
.
i386_regs
)
);
}
}
if
(
flags
&
WOW64_CONTEXT_XSTATE
)
{
CONTEXT_EX
*
c_ex
=
(
CONTEXT_EX
*
)(
from
+
1
);
xstate_to_server
(
to
,
(
XSTATE
*
)((
BYTE
*
)
c_ex
+
c_ex
->
XState
.
Offset
)
);
}
}
}
#endif
/* __x86_64__ */
#endif
/* __x86_64__ */
...
...
dlls/ntdll/unix/unix_private.h
View file @
419abd49
...
@@ -288,13 +288,14 @@ static inline void mutex_unlock( pthread_mutex_t *mutex )
...
@@ -288,13 +288,14 @@ static inline void mutex_unlock( pthread_mutex_t *mutex )
static
inline
TEB64
*
NtCurrentTeb64
(
void
)
{
return
(
TEB64
*
)
NtCurrentTeb
()
->
GdiBatchCount
;
}
static
inline
TEB64
*
NtCurrentTeb64
(
void
)
{
return
(
TEB64
*
)
NtCurrentTeb
()
->
GdiBatchCount
;
}
#endif
#endif
#if defined(__i386__) || defined(__x86_64__)
struct
xcontext
struct
xcontext
{
{
CONTEXT
c
;
CONTEXT
c
;
XSTATE
*
xstate
;
/* points to xstate in sigcontext */
CONTEXT_EX
c_ex
;
ULONG64
host_compaction_mask
;
};
};
#if defined(__i386__) || defined(__x86_64__)
static
inline
XSTATE
*
xstate_from_context
(
const
CONTEXT
*
context
)
static
inline
XSTATE
*
xstate_from_context
(
const
CONTEXT
*
context
)
{
{
CONTEXT_EX
*
xctx
=
(
CONTEXT_EX
*
)(
context
+
1
);
CONTEXT_EX
*
xctx
=
(
CONTEXT_EX
*
)(
context
+
1
);
...
@@ -308,21 +309,62 @@ static inline XSTATE *xstate_from_context( const CONTEXT *context )
...
@@ -308,21 +309,62 @@ static inline XSTATE *xstate_from_context( const CONTEXT *context )
static
inline
void
context_init_xstate
(
CONTEXT
*
context
,
void
*
xstate_buffer
)
static
inline
void
context_init_xstate
(
CONTEXT
*
context
,
void
*
xstate_buffer
)
{
{
CONTEXT_EX
*
xctx
;
CONTEXT_EX
*
xctx
;
XSTATE
*
xs
;
xctx
=
(
CONTEXT_EX
*
)(
context
+
1
);
xctx
=
(
CONTEXT_EX
*
)(
context
+
1
);
xctx
->
Legacy
.
Length
=
sizeof
(
CONTEXT
);
xctx
->
Legacy
.
Length
=
sizeof
(
CONTEXT
);
xctx
->
Legacy
.
Offset
=
-
(
LONG
)
sizeof
(
CONTEXT
);
xctx
->
Legacy
.
Offset
=
-
(
LONG
)
sizeof
(
CONTEXT
);
xctx
->
XState
.
Length
=
sizeof
(
XSTATE
);
xctx
->
XState
.
Length
=
sizeof
(
XSTATE
);
xctx
->
XState
.
Offset
=
xstate_buffer
?
(((
ULONG_PTR
)
xstate_buffer
+
63
)
&
~
63
)
-
(
ULONG_PTR
)
xctx
xctx
->
XState
.
Offset
=
(
BYTE
*
)
xstate_buffer
-
(
BYTE
*
)
xctx
;
:
(((
ULONG_PTR
)
context
+
sizeof
(
CONTEXT
)
+
sizeof
(
CONTEXT_EX
)
+
63
)
&
~
63
)
-
(
ULONG_PTR
)
xctx
;
xctx
->
All
.
Length
=
sizeof
(
CONTEXT
)
+
xctx
->
XState
.
Offset
+
xctx
->
XState
.
Length
;
xctx
->
All
.
Length
=
sizeof
(
CONTEXT
)
+
xctx
->
XState
.
Offset
+
xctx
->
XState
.
Length
;
xctx
->
All
.
Offset
=
-
(
LONG
)
sizeof
(
CONTEXT
);
xctx
->
All
.
Offset
=
-
(
LONG
)
sizeof
(
CONTEXT
);
context
->
ContextFlags
|=
0x40
;
context
->
ContextFlags
|=
0x40
;
}
xs
=
xstate_from_context
(
context
);
static
inline
void
xstate_to_server
(
context_t
*
to
,
const
XSTATE
*
xs
)
memset
(
xs
,
0
,
offsetof
(
XSTATE
,
YmmContext
)
);
{
if
(
!
xs
)
return
;
to
->
flags
|=
SERVER_CTX_YMM_REGISTERS
;
if
(
xs
->
Mask
&
4
)
memcpy
(
&
to
->
ymm
.
ymm_high_regs
.
ymm_high
,
&
xs
->
YmmContext
,
sizeof
(
xs
->
YmmContext
));
else
memset
(
&
to
->
ymm
.
ymm_high_regs
.
ymm_high
,
0
,
sizeof
(
xs
->
YmmContext
));
}
static
inline
void
xstate_from_server_
(
XSTATE
*
xs
,
const
context_t
*
from
,
BOOL
compaction_enabled
)
{
if
(
!
xs
)
return
;
xs
->
Mask
=
0
;
xs
->
CompactionMask
=
compaction_enabled
?
0x8000000000000004
:
0
;
if
(
from
->
flags
&
SERVER_CTX_YMM_REGISTERS
)
{
unsigned
long
*
src
=
(
unsigned
long
*
)
&
from
->
ymm
.
ymm_high_regs
.
ymm_high
;
unsigned
int
i
;
for
(
i
=
0
;
i
<
sizeof
(
xs
->
YmmContext
)
/
sizeof
(
unsigned
long
);
++
i
)
if
(
src
[
i
])
{
memcpy
(
&
xs
->
YmmContext
,
&
from
->
ymm
.
ymm_high_regs
.
ymm_high
,
sizeof
(
xs
->
YmmContext
)
);
xs
->
Mask
=
4
;
break
;
}
}
}
#define xstate_from_server( xs, from ) xstate_from_server_( xs, from, user_shared_data->XState.CompactionEnabled )
#else
static
inline
XSTATE
*
xstate_from_context
(
const
CONTEXT
*
context
)
{
return
NULL
;
}
static
inline
void
context_init_xstate
(
CONTEXT
*
context
,
void
*
xstate_buffer
)
{
}
}
#endif
#endif
...
...
include/wine/server_protocol.h
View file @
419abd49
...
@@ -170,6 +170,10 @@ typedef struct
...
@@ -170,6 +170,10 @@ typedef struct
{
{
unsigned
char
i386_regs
[
512
];
unsigned
char
i386_regs
[
512
];
}
ext
;
}
ext
;
union
{
struct
{
struct
{
unsigned
__int64
low
,
high
;
}
ymm_high
[
16
];
}
ymm_high_regs
;
}
ymm
;
}
context_t
;
}
context_t
;
#define SERVER_CTX_CONTROL 0x01
#define SERVER_CTX_CONTROL 0x01
...
@@ -178,6 +182,7 @@ typedef struct
...
@@ -178,6 +182,7 @@ typedef struct
#define SERVER_CTX_FLOATING_POINT 0x08
#define SERVER_CTX_FLOATING_POINT 0x08
#define SERVER_CTX_DEBUG_REGISTERS 0x10
#define SERVER_CTX_DEBUG_REGISTERS 0x10
#define SERVER_CTX_EXTENDED_REGISTERS 0x20
#define SERVER_CTX_EXTENDED_REGISTERS 0x20
#define SERVER_CTX_YMM_REGISTERS 0x40
struct
send_fd
struct
send_fd
...
...
server/protocol.def
View file @
419abd49
...
@@ -186,6 +186,10 @@ typedef struct
...
@@ -186,6 +186,10 @@ typedef struct
{
{
unsigned char i386_regs[512];
unsigned char i386_regs[512];
} ext; /* selected by SERVER_CTX_EXTENDED_REGISTERS */
} ext; /* selected by SERVER_CTX_EXTENDED_REGISTERS */
union
{
struct { struct { unsigned __int64 low, high; } ymm_high[16]; } ymm_high_regs;
} ymm; /* selected by SERVER_CTX_YMM_REGISTERS */
} context_t;
} context_t;
#define SERVER_CTX_CONTROL 0x01
#define SERVER_CTX_CONTROL 0x01
...
@@ -194,6 +198,7 @@ typedef struct
...
@@ -194,6 +198,7 @@ typedef struct
#define SERVER_CTX_FLOATING_POINT 0x08
#define SERVER_CTX_FLOATING_POINT 0x08
#define SERVER_CTX_DEBUG_REGISTERS 0x10
#define SERVER_CTX_DEBUG_REGISTERS 0x10
#define SERVER_CTX_EXTENDED_REGISTERS 0x20
#define SERVER_CTX_EXTENDED_REGISTERS 0x20
#define SERVER_CTX_YMM_REGISTERS 0x40
/* structure used in sending an fd from client to server */
/* structure used in sending an fd from client to server */
struct send_fd
struct send_fd
...
...
server/thread.c
View file @
419abd49
...
@@ -1285,6 +1285,7 @@ static void copy_context( context_t *to, const context_t *from, unsigned int fla
...
@@ -1285,6 +1285,7 @@ static void copy_context( context_t *to, const context_t *from, unsigned int fla
if
(
flags
&
SERVER_CTX_FLOATING_POINT
)
to
->
fp
=
from
->
fp
;
if
(
flags
&
SERVER_CTX_FLOATING_POINT
)
to
->
fp
=
from
->
fp
;
if
(
flags
&
SERVER_CTX_DEBUG_REGISTERS
)
to
->
debug
=
from
->
debug
;
if
(
flags
&
SERVER_CTX_DEBUG_REGISTERS
)
to
->
debug
=
from
->
debug
;
if
(
flags
&
SERVER_CTX_EXTENDED_REGISTERS
)
to
->
ext
=
from
->
ext
;
if
(
flags
&
SERVER_CTX_EXTENDED_REGISTERS
)
to
->
ext
=
from
->
ext
;
if
(
flags
&
SERVER_CTX_YMM_REGISTERS
)
to
->
ymm
=
from
->
ymm
;
}
}
/* return the context flags that correspond to system regs */
/* return the context flags that correspond to system regs */
...
...
server/trace.c
View file @
419abd49
...
@@ -620,6 +620,9 @@ static void dump_varargs_context( const char *prefix, data_size_t size )
...
@@ -620,6 +620,9 @@ static void dump_varargs_context( const char *prefix, data_size_t size )
if
(
ctx
.
flags
&
SERVER_CTX_EXTENDED_REGISTERS
)
if
(
ctx
.
flags
&
SERVER_CTX_EXTENDED_REGISTERS
)
dump_uints
(
",extended="
,
(
const
unsigned
int
*
)
ctx
.
ext
.
i386_regs
,
dump_uints
(
",extended="
,
(
const
unsigned
int
*
)
ctx
.
ext
.
i386_regs
,
sizeof
(
ctx
.
ext
.
i386_regs
)
/
sizeof
(
int
)
);
sizeof
(
ctx
.
ext
.
i386_regs
)
/
sizeof
(
int
)
);
if
(
ctx
.
flags
&
SERVER_CTX_YMM_REGISTERS
)
dump_uints
(
",ymm_high="
,
(
const
unsigned
int
*
)
ctx
.
ymm
.
ymm_high_regs
.
ymm_high
,
sizeof
(
ctx
.
ymm
.
ymm_high_regs
)
/
sizeof
(
int
)
);
break
;
break
;
case
CPU_x86_64
:
case
CPU_x86_64
:
if
(
ctx
.
flags
&
SERVER_CTX_CONTROL
)
if
(
ctx
.
flags
&
SERVER_CTX_CONTROL
)
...
@@ -669,6 +672,9 @@ static void dump_varargs_context( const char *prefix, data_size_t size )
...
@@ -669,6 +672,9 @@ static void dump_varargs_context( const char *prefix, data_size_t size )
(
unsigned
int
)(
ctx
.
fp
.
x86_64_regs
.
fpregs
[
i
].
low
>>
32
),
(
unsigned
int
)(
ctx
.
fp
.
x86_64_regs
.
fpregs
[
i
].
low
>>
32
),
(
unsigned
int
)
ctx
.
fp
.
x86_64_regs
.
fpregs
[
i
].
low
);
(
unsigned
int
)
ctx
.
fp
.
x86_64_regs
.
fpregs
[
i
].
low
);
}
}
if
(
ctx
.
flags
&
SERVER_CTX_YMM_REGISTERS
)
dump_uints
(
",ymm_high="
,
(
const
unsigned
int
*
)
ctx
.
ymm
.
ymm_high_regs
.
ymm_high
,
sizeof
(
ctx
.
ymm
.
ymm_high_regs
)
/
sizeof
(
int
)
);
break
;
break
;
case
CPU_POWERPC
:
case
CPU_POWERPC
:
if
(
ctx
.
flags
&
SERVER_CTX_CONTROL
)
if
(
ctx
.
flags
&
SERVER_CTX_CONTROL
)
...
...
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