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
dfe2b717
Commit
dfe2b717
authored
Jan 31, 2024
by
Paul Gofman
Committed by
Alexandre Julliard
Feb 16, 2024
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ntdll: Don't hardcode xstate size in exception stack layout.
parent
7ae488a2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
53 additions
and
57 deletions
+53
-57
signal_i386.c
dlls/ntdll/unix/signal_i386.c
+29
-34
signal_x86_64.c
dlls/ntdll/unix/signal_x86_64.c
+24
-23
No files found.
dlls/ntdll/unix/signal_i386.c
View file @
dfe2b717
...
...
@@ -151,7 +151,7 @@ typedef struct ucontext
#define FPU_sig(context) ((FLOATING_SAVE_AREA*)((context)->uc_mcontext.fpregs))
#define FPUX_sig(context) (FPU_sig(context) && !((context)->uc_mcontext.fpregs->status >> 16) ? (XSAVE_FORMAT *)(FPU_sig(context) + 1) : NULL)
#define XState_sig(fpu) (((unsigned int *)fpu->Reserved4)[12] == FP_XSTATE_MAGIC1 ? (XS
TATE
*)(fpu + 1) : NULL)
#define XState_sig(fpu) (((unsigned int *)fpu->Reserved4)[12] == FP_XSTATE_MAGIC1 ? (XS
AVE_AREA_HEADER
*)(fpu + 1) : NULL)
#ifdef __ANDROID__
/* custom signal restorer since we may have unmapped the one in vdso, and bionic doesn't check for that */
...
...
@@ -443,12 +443,10 @@ struct exc_stack_layout
EXCEPTION_RECORD
rec
;
/* 008 */
CONTEXT
context
;
/* 058 */
CONTEXT_EX
context_ex
;
/* 324 */
BYTE
xstate
[
sizeof
(
XSTATE
)
+
64
];
/* 33c extra space to allow for 64-byte alignment */
DWORD
align
;
/* 4bc */
DWORD
align
;
/* 33c */
};
C_ASSERT
(
offsetof
(
struct
exc_stack_layout
,
context
)
==
0x58
);
C_ASSERT
(
offsetof
(
struct
exc_stack_layout
,
xstate
)
==
0x33c
);
C_ASSERT
(
sizeof
(
struct
exc_stack_layout
)
==
0x4c0
);
C_ASSERT
(
sizeof
(
struct
exc_stack_layout
)
==
0x340
);
/* stack layout when calling KiUserApcDispatcher */
struct
apc_stack_layout
...
...
@@ -612,12 +610,12 @@ struct xcontext
ULONG64
host_compaction_mask
;
};
static
inline
XS
TATE
*
xstate_from_context
(
const
CONTEXT
*
context
)
static
inline
XS
AVE_AREA_HEADER
*
xstate_from_context
(
const
CONTEXT
*
context
)
{
CONTEXT_EX
*
xctx
=
(
CONTEXT_EX
*
)(
context
+
1
);
if
((
context
->
ContextFlags
&
CONTEXT_XSTATE
)
!=
CONTEXT_XSTATE
)
return
NULL
;
return
(
XS
TATE
*
)((
char
*
)
xctx
+
xctx
->
XState
.
Offset
);
return
(
XS
AVE_AREA_HEADER
*
)((
char
*
)
xctx
+
xctx
->
XState
.
Offset
);
}
static
inline
void
context_init_xstate
(
CONTEXT
*
context
,
void
*
xstate_buffer
)
...
...
@@ -630,7 +628,7 @@ static inline void context_init_xstate( CONTEXT *context, void *xstate_buffer )
if
(
xstate_buffer
)
{
xctx
->
XState
.
Length
=
sizeof
(
XS
TATE
)
;
xctx
->
XState
.
Length
=
sizeof
(
XS
AVE_AREA_HEADER
)
+
xstate_features_size
;
xctx
->
XState
.
Offset
=
(
BYTE
*
)
xstate_buffer
-
(
BYTE
*
)
xctx
;
context
->
ContextFlags
|=
CONTEXT_XSTATE
;
...
...
@@ -828,7 +826,7 @@ static inline void save_context( struct xcontext *xcontext, const ucontext_t *si
}
if
(
fpux
)
{
XS
TATE
*
xs
;
XS
AVE_AREA_HEADER
*
xs
;
context
->
ContextFlags
|=
CONTEXT_FLOATING_POINT
|
CONTEXT_EXTENDED_REGISTERS
;
memcpy
(
context
->
ExtendedRegisters
,
fpux
,
sizeof
(
*
fpux
)
);
...
...
@@ -880,16 +878,12 @@ static inline void restore_context( const struct xcontext *xcontext, ucontext_t
if
(
fpu
)
*
fpu
=
context
->
FloatSave
;
if
(
fpux
)
{
XS
TATE
*
src_xs
,
*
dst_
xs
;
XS
AVE_AREA_HEADER
*
xs
;
memcpy
(
fpux
,
context
->
ExtendedRegisters
,
sizeof
(
*
fpux
)
);
if
((
dst_xs
=
XState_sig
(
fpux
))
&&
(
src_xs
=
xstate_from_context
(
context
)))
{
memcpy
(
&
dst_xs
->
YmmContext
,
&
src_xs
->
YmmContext
,
sizeof
(
dst_xs
->
YmmContext
)
);
dst_xs
->
Mask
|=
src_xs
->
Mask
;
dst_xs
->
CompactionMask
=
xcontext
->
host_compaction_mask
;
}
if
(
xstate_extended_features
()
&&
(
xs
=
XState_sig
(
fpux
)))
xs
->
CompactionMask
=
xcontext
->
host_compaction_mask
;
}
if
(
!
fpu
&&
!
fpux
)
restore_fpu
(
context
);
}
...
...
@@ -1458,8 +1452,10 @@ static void setup_raise_exception( ucontext_t *sigcontext, void *stack_ptr,
EXCEPTION_RECORD
*
rec
,
struct
xcontext
*
xcontext
)
{
CONTEXT
*
context
=
&
xcontext
->
c
;
XS
TATE
*
src_xs
;
XS
AVE_AREA_HEADER
*
src_xs
;
struct
exc_stack_layout
*
stack
;
size_t
stack_size
;
unsigned
int
xstate_size
;
NTSTATUS
status
=
send_debug_event
(
rec
,
context
,
TRUE
);
if
(
status
==
DBG_CONTINUE
||
status
==
DBG_EXCEPTION_HANDLED
)
...
...
@@ -1471,7 +1467,9 @@ static void setup_raise_exception( ucontext_t *sigcontext, void *stack_ptr,
/* fix up instruction pointer in context for EXCEPTION_BREAKPOINT */
if
(
rec
->
ExceptionCode
==
EXCEPTION_BREAKPOINT
)
context
->
Eip
--
;
stack
=
virtual_setup_exception
(
stack_ptr
,
sizeof
(
*
stack
),
rec
);
xstate_size
=
sizeof
(
XSAVE_AREA_HEADER
)
+
xstate_features_size
;
stack_size
=
(
ULONG_PTR
)
stack_ptr
-
(((
ULONG_PTR
)
stack_ptr
-
sizeof
(
*
stack
)
-
xstate_size
)
&
~
(
ULONG_PTR
)
63
);
stack
=
virtual_setup_exception
(
stack_ptr
,
stack_size
,
rec
);
stack
->
rec_ptr
=
&
stack
->
rec
;
stack
->
context_ptr
=
&
stack
->
context
;
stack
->
rec
=
*
rec
;
...
...
@@ -1479,16 +1477,13 @@ static void setup_raise_exception( ucontext_t *sigcontext, void *stack_ptr,
if
((
src_xs
=
xstate_from_context
(
context
)))
{
XS
TATE
*
dst_xs
=
(
XSTATE
*
)(((
ULONG_PTR
)
stack
->
xstate
+
63
)
&
~
63
);
XS
AVE_AREA_HEADER
*
dst_xs
=
(
XSAVE_AREA_HEADER
*
)(
stack
+
1
);
assert
(
!
((
ULONG_PTR
)
dst_xs
&
63
)
);
context_init_xstate
(
&
stack
->
context
,
dst_xs
);
memset
(
dst_xs
,
0
,
sizeof
(
XSAVE_AREA_HEADER
)
);
memset
(
dst_xs
,
0
,
sizeof
(
*
dst_xs
)
);
dst_xs
->
CompactionMask
=
xstate_compaction_enabled
?
0x8000000000000000
|
xstate_extended_features
()
:
0
;
if
(
src_xs
->
Mask
&
4
)
{
dst_xs
->
Mask
=
4
;
memcpy
(
&
dst_xs
->
YmmContext
,
&
src_xs
->
YmmContext
,
sizeof
(
dst_xs
->
YmmContext
)
);
}
copy_xstate
(
dst_xs
,
src_xs
,
src_xs
->
Mask
);
}
else
{
...
...
@@ -1569,11 +1564,14 @@ NTSTATUS call_user_exception_dispatcher( EXCEPTION_RECORD *rec, CONTEXT *context
{
struct
syscall_frame
*
frame
=
x86_thread_data
()
->
syscall_frame
;
ULONG
esp
=
(
frame
->
esp
-
sizeof
(
struct
exc_stack_layout
))
&
~
3
;
struct
exc_stack_layout
*
stack
=
(
struct
exc_stack_layout
*
)
esp
;
XSTATE
*
src_xs
;
struct
exc_stack_layout
*
stack
;
XSAVE_AREA_HEADER
*
src_xs
;
unsigned
int
xstate_size
;
if
(
rec
->
ExceptionCode
==
EXCEPTION_BREAKPOINT
)
context
->
Eip
--
;
xstate_size
=
sizeof
(
XSAVE_AREA_HEADER
)
+
xstate_features_size
;
stack
=
(
struct
exc_stack_layout
*
)((
esp
-
sizeof
(
*
stack
)
-
xstate_size
)
&
~
(
ULONG_PTR
)
63
);
stack
->
rec_ptr
=
&
stack
->
rec
;
stack
->
context_ptr
=
&
stack
->
context
;
stack
->
rec
=
*
rec
;
...
...
@@ -1581,16 +1579,13 @@ NTSTATUS call_user_exception_dispatcher( EXCEPTION_RECORD *rec, CONTEXT *context
if
((
src_xs
=
xstate_from_context
(
context
)))
{
XS
TATE
*
dst_xs
=
(
XSTATE
*
)(((
ULONG_PTR
)
stack
->
xstate
+
63
)
&
~
63
);
XS
AVE_AREA_HEADER
*
dst_xs
=
(
XSAVE_AREA_HEADER
*
)(
stack
+
1
);
context_init_xstate
(
&
stack
->
context
,
dst_xs
);
memset
(
dst_xs
,
0
,
offsetof
(
XSTATE
,
YmmContext
)
);
assert
(
!
((
ULONG_PTR
)
dst_xs
&
63
)
);
memset
(
dst_xs
,
0
,
sizeof
(
*
dst_xs
)
);
dst_xs
->
CompactionMask
=
xstate_compaction_enabled
?
0x8000000000000000
|
xstate_extended_features
()
:
0
;
if
(
src_xs
->
Mask
&
4
)
{
dst_xs
->
Mask
=
4
;
memcpy
(
&
dst_xs
->
YmmContext
,
&
src_xs
->
YmmContext
,
sizeof
(
dst_xs
->
YmmContext
)
);
}
copy_xstate
(
dst_xs
,
src_xs
,
src_xs
->
Mask
);
}
else
{
...
...
dlls/ntdll/unix/signal_x86_64.c
View file @
dfe2b717
...
...
@@ -140,7 +140,7 @@ __ASM_GLOBAL_FUNC( alloc_fs_sel,
#define TRAP_sig(context) ((context)->uc_mcontext.gregs[REG_TRAPNO])
#define ERROR_sig(context) ((context)->uc_mcontext.gregs[REG_ERR])
#define FPU_sig(context) ((XMM_SAVE_AREA32 *)((context)->uc_mcontext.fpregs))
#define XState_sig(fpu) (((unsigned int *)fpu->Reserved4)[12] == FP_XSTATE_MAGIC1 ? (XS
TATE
*)(fpu + 1) : NULL)
#define XState_sig(fpu) (((unsigned int *)fpu->Reserved4)[12] == FP_XSTATE_MAGIC1 ? (XS
AVE_AREA_HEADER
*)(fpu + 1) : NULL)
#elif defined(__FreeBSD__) || defined (__FreeBSD_kernel__)
...
...
@@ -359,11 +359,10 @@ struct exc_stack_layout
ULONG64
align
;
/* 588 */
struct
machine_frame
machine_frame
;
/* 590 */
ULONG64
align2
;
/* 5b8 */
XSTATE
xstate
;
/* 5c0 */
};
C_ASSERT
(
offsetof
(
struct
exc_stack_layout
,
rec
)
==
0x4f0
);
C_ASSERT
(
offsetof
(
struct
exc_stack_layout
,
machine_frame
)
==
0x590
);
C_ASSERT
(
sizeof
(
struct
exc_stack_layout
)
==
0x
70
0
);
C_ASSERT
(
sizeof
(
struct
exc_stack_layout
)
==
0x
5c
0
);
/* stack layout when calling KiUserApcDispatcher */
struct
apc_stack_layout
...
...
@@ -483,12 +482,12 @@ struct xcontext
ULONG64
host_compaction_mask
;
};
static
inline
XS
TATE
*
xstate_from_context
(
const
CONTEXT
*
context
)
static
inline
XS
AVE_AREA_HEADER
*
xstate_from_context
(
const
CONTEXT
*
context
)
{
CONTEXT_EX
*
xctx
=
(
CONTEXT_EX
*
)(
context
+
1
);
if
((
context
->
ContextFlags
&
CONTEXT_XSTATE
)
!=
CONTEXT_XSTATE
)
return
NULL
;
return
(
XS
TATE
*
)((
char
*
)
xctx
+
xctx
->
XState
.
Offset
);
return
(
XS
AVE_AREA_HEADER
*
)((
char
*
)
xctx
+
xctx
->
XState
.
Offset
);
}
static
inline
void
context_init_xstate
(
CONTEXT
*
context
,
void
*
xstate_buffer
)
...
...
@@ -501,7 +500,7 @@ static inline void context_init_xstate( CONTEXT *context, void *xstate_buffer )
if
(
xstate_buffer
)
{
xctx
->
XState
.
Length
=
sizeof
(
XS
TATE
)
;
xctx
->
XState
.
Length
=
sizeof
(
XS
AVE_AREA_HEADER
)
+
xstate_features_size
;
xctx
->
XState
.
Offset
=
(
BYTE
*
)
xstate_buffer
-
(
BYTE
*
)
xctx
;
context
->
ContextFlags
|=
CONTEXT_XSTATE
;
...
...
@@ -897,7 +896,7 @@ static void save_context( struct xcontext *xcontext, const ucontext_t *sigcontex
context
->
Dr7
=
amd64_thread_data
()
->
dr7
;
if
(
FPU_sig
(
sigcontext
))
{
XS
TATE
*
xs
;
XS
AVE_AREA_HEADER
*
xs
;
context
->
ContextFlags
|=
CONTEXT_FLOATING_POINT
;
context
->
FltSave
=
*
FPU_sig
(
sigcontext
);
...
...
@@ -922,7 +921,7 @@ static void save_context( struct xcontext *xcontext, const ucontext_t *sigcontex
static
void
restore_context
(
const
struct
xcontext
*
xcontext
,
ucontext_t
*
sigcontext
)
{
const
CONTEXT
*
context
=
&
xcontext
->
c
;
XS
TATE
*
xs
;
XS
AVE_AREA_HEADER
*
xs
;
amd64_thread_data
()
->
dr0
=
context
->
Dr0
;
amd64_thread_data
()
->
dr1
=
context
->
Dr1
;
...
...
@@ -1398,7 +1397,8 @@ static void setup_raise_exception( ucontext_t *sigcontext, EXCEPTION_RECORD *rec
struct
exc_stack_layout
*
stack
;
size_t
stack_size
;
NTSTATUS
status
;
XSTATE
*
src_xs
;
XSAVE_AREA_HEADER
*
src_xs
;
unsigned
int
xstate_size
;
if
(
rec
->
ExceptionCode
==
EXCEPTION_SINGLE_STEP
)
{
...
...
@@ -1427,7 +1427,8 @@ static void setup_raise_exception( ucontext_t *sigcontext, EXCEPTION_RECORD *rec
/* fix up instruction pointer in context for EXCEPTION_BREAKPOINT */
if
(
rec
->
ExceptionCode
==
EXCEPTION_BREAKPOINT
)
context
->
Rip
--
;
stack_size
=
(
ULONG_PTR
)
stack_ptr
-
(((
ULONG_PTR
)
stack_ptr
-
sizeof
(
*
stack
))
&
~
(
ULONG_PTR
)
63
);
xstate_size
=
sizeof
(
XSAVE_AREA_HEADER
)
+
xstate_features_size
;
stack_size
=
(
ULONG_PTR
)
stack_ptr
-
(((
ULONG_PTR
)
stack_ptr
-
sizeof
(
*
stack
)
-
xstate_size
)
&
~
(
ULONG_PTR
)
63
);
stack
=
virtual_setup_exception
(
stack_ptr
,
stack_size
,
rec
);
stack
->
rec
=
*
rec
;
stack
->
context
=
*
context
;
...
...
@@ -1436,15 +1437,12 @@ static void setup_raise_exception( ucontext_t *sigcontext, EXCEPTION_RECORD *rec
if
((
src_xs
=
xstate_from_context
(
context
)))
{
assert
(
!
((
ULONG_PTR
)
&
stack
->
xstate
&
63
)
);
context_init_xstate
(
&
stack
->
context
,
&
stack
->
xstate
);
memset
(
&
stack
->
xstate
,
0
,
offsetof
(
XSTATE
,
YmmContext
)
);
stack
->
xstate
.
CompactionMask
=
xstate_compaction_enabled
?
0x8000000000000000
|
xstate_extended_features
()
:
0
;
if
(
src_xs
->
Mask
&
4
)
{
stack
->
xstate
.
Mask
=
4
;
memcpy
(
&
stack
->
xstate
.
YmmContext
,
&
src_xs
->
YmmContext
,
sizeof
(
stack
->
xstate
.
YmmContext
)
);
}
XSAVE_AREA_HEADER
*
dst_xs
=
(
XSAVE_AREA_HEADER
*
)(
stack
+
1
);
assert
(
!
((
ULONG_PTR
)
dst_xs
&
63
)
);
context_init_xstate
(
&
stack
->
context
,
dst_xs
);
memset
(
dst_xs
,
0
,
sizeof
(
*
dst_xs
)
);
dst_xs
->
CompactionMask
=
xstate_compaction_enabled
?
0x8000000000000000
|
xstate_extended_features
()
:
0
;
copy_xstate
(
dst_xs
,
src_xs
,
src_xs
->
Mask
);
}
else
{
...
...
@@ -1531,16 +1529,19 @@ NTSTATUS call_user_exception_dispatcher( EXCEPTION_RECORD *rec, CONTEXT *context
struct
syscall_frame
*
frame
=
amd64_thread_data
()
->
syscall_frame
;
struct
exc_stack_layout
*
stack
;
NTSTATUS
status
=
NtSetContextThread
(
GetCurrentThread
(),
context
);
unsigned
int
xstate_size
;
if
(
status
)
return
status
;
stack
=
(
struct
exc_stack_layout
*
)((
context
->
Rsp
-
sizeof
(
*
stack
))
&
~
(
ULONG_PTR
)
63
);
xstate_size
=
sizeof
(
XSAVE_AREA_HEADER
)
+
xstate_features_size
;
stack
=
(
struct
exc_stack_layout
*
)((
context
->
Rsp
-
sizeof
(
*
stack
)
-
xstate_size
)
&
~
(
ULONG_PTR
)
63
);
memmove
(
&
stack
->
context
,
context
,
sizeof
(
*
context
)
);
if
((
context
->
ContextFlags
&
CONTEXT_XSTATE
)
==
CONTEXT_XSTATE
)
{
assert
(
!
((
ULONG_PTR
)
&
stack
->
xstate
&
63
)
);
context_init_xstate
(
&
stack
->
context
,
&
stack
->
xstate
);
memcpy
(
&
stack
->
xstate
,
&
frame
->
xstate
,
sizeof
(
XSAVE_AREA_HEADER
)
+
xstate_features_size
);
XSAVE_AREA_HEADER
*
dst_xs
=
(
XSAVE_AREA_HEADER
*
)(
stack
+
1
);
assert
(
!
((
ULONG_PTR
)
dst_xs
&
63
)
);
context_init_xstate
(
&
stack
->
context
,
dst_xs
);
memcpy
(
dst_xs
,
&
frame
->
xstate
,
sizeof
(
XSAVE_AREA_HEADER
)
+
xstate_features_size
);
}
else
context_init_xstate
(
&
stack
->
context
,
NULL
);
...
...
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