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
ac90898f
Commit
ac90898f
authored
Jun 02, 2020
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ntdll: Move NtSetContextThread() implementation to the Unix library.
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
b4310a19
Hide whitespace changes
Inline
Side-by-side
Showing
16 changed files
with
474 additions
and
474 deletions
+474
-474
ntdll_misc.h
dlls/ntdll/ntdll_misc.h
+0
-1
signal_arm.c
dlls/ntdll/signal_arm.c
+0
-72
signal_arm64.c
dlls/ntdll/signal_arm64.c
+0
-72
signal_i386.c
dlls/ntdll/signal_i386.c
+0
-102
signal_powerpc.c
dlls/ntdll/signal_powerpc.c
+0
-130
signal_x86_64.c
dlls/ntdll/signal_x86_64.c
+0
-96
thread.c
dlls/ntdll/thread.c
+10
-0
loader.c
dlls/ntdll/unix/loader.c
+1
-0
signal_arm.c
dlls/ntdll/unix/signal_arm.c
+38
-0
signal_arm64.c
dlls/ntdll/unix/signal_arm64.c
+48
-0
signal_i386.c
dlls/ntdll/unix/signal_i386.c
+191
-0
signal_powerpc.c
dlls/ntdll/unix/signal_powerpc.c
+28
-0
signal_x86_64.c
dlls/ntdll/unix/signal_x86_64.c
+135
-0
thread.c
dlls/ntdll/unix/thread.c
+20
-0
unix_private.h
dlls/ntdll/unix/unix_private.h
+1
-0
unixlib.h
dlls/ntdll/unixlib.h
+2
-1
No files found.
dlls/ntdll/ntdll_misc.h
View file @
ac90898f
...
...
@@ -62,7 +62,6 @@ extern void wait_suspend( CONTEXT *context ) DECLSPEC_HIDDEN;
extern
NTSTATUS
send_debug_event
(
EXCEPTION_RECORD
*
rec
,
int
first_chance
,
CONTEXT
*
context
)
DECLSPEC_HIDDEN
;
extern
LONG
call_vectored_handlers
(
EXCEPTION_RECORD
*
rec
,
CONTEXT
*
context
)
DECLSPEC_HIDDEN
;
extern
void
DECLSPEC_NORETURN
raise_status
(
NTSTATUS
status
,
EXCEPTION_RECORD
*
rec
)
DECLSPEC_HIDDEN
;
extern
NTSTATUS
context_to_server
(
context_t
*
to
,
const
CONTEXT
*
from
)
DECLSPEC_HIDDEN
;
extern
NTSTATUS
context_from_server
(
CONTEXT
*
to
,
const
context_t
*
from
)
DECLSPEC_HIDDEN
;
extern
NTSTATUS
set_thread_context
(
HANDLE
handle
,
const
context_t
*
context
,
BOOL
*
self
)
DECLSPEC_HIDDEN
;
extern
NTSTATUS
get_thread_context
(
HANDLE
handle
,
context_t
*
context
,
unsigned
int
flags
,
BOOL
*
self
)
DECLSPEC_HIDDEN
;
...
...
dlls/ntdll/signal_arm.c
View file @
ac90898f
...
...
@@ -354,61 +354,6 @@ static void copy_context( CONTEXT *to, const CONTEXT *from, DWORD flags )
/***********************************************************************
* context_to_server
*
* Convert a register context to the server format.
*/
NTSTATUS
context_to_server
(
context_t
*
to
,
const
CONTEXT
*
from
)
{
DWORD
i
,
flags
=
from
->
ContextFlags
&
~
CONTEXT_ARM
;
/* get rid of CPU id */
memset
(
to
,
0
,
sizeof
(
*
to
)
);
to
->
cpu
=
CPU_ARM
;
if
(
flags
&
CONTEXT_CONTROL
)
{
to
->
flags
|=
SERVER_CTX_CONTROL
;
to
->
ctl
.
arm_regs
.
sp
=
from
->
Sp
;
to
->
ctl
.
arm_regs
.
lr
=
from
->
Lr
;
to
->
ctl
.
arm_regs
.
pc
=
from
->
Pc
;
to
->
ctl
.
arm_regs
.
cpsr
=
from
->
Cpsr
;
}
if
(
flags
&
CONTEXT_INTEGER
)
{
to
->
flags
|=
SERVER_CTX_INTEGER
;
to
->
integer
.
arm_regs
.
r
[
0
]
=
from
->
R0
;
to
->
integer
.
arm_regs
.
r
[
1
]
=
from
->
R1
;
to
->
integer
.
arm_regs
.
r
[
2
]
=
from
->
R2
;
to
->
integer
.
arm_regs
.
r
[
3
]
=
from
->
R3
;
to
->
integer
.
arm_regs
.
r
[
4
]
=
from
->
R4
;
to
->
integer
.
arm_regs
.
r
[
5
]
=
from
->
R5
;
to
->
integer
.
arm_regs
.
r
[
6
]
=
from
->
R6
;
to
->
integer
.
arm_regs
.
r
[
7
]
=
from
->
R7
;
to
->
integer
.
arm_regs
.
r
[
8
]
=
from
->
R8
;
to
->
integer
.
arm_regs
.
r
[
9
]
=
from
->
R9
;
to
->
integer
.
arm_regs
.
r
[
10
]
=
from
->
R10
;
to
->
integer
.
arm_regs
.
r
[
11
]
=
from
->
R11
;
to
->
integer
.
arm_regs
.
r
[
12
]
=
from
->
R12
;
}
if
(
flags
&
CONTEXT_FLOATING_POINT
)
{
to
->
flags
|=
SERVER_CTX_FLOATING_POINT
;
for
(
i
=
0
;
i
<
32
;
i
++
)
to
->
fp
.
arm_regs
.
d
[
i
]
=
from
->
u
.
D
[
i
];
to
->
fp
.
arm_regs
.
fpscr
=
from
->
Fpscr
;
}
if
(
flags
&
CONTEXT_DEBUG_REGISTERS
)
{
to
->
flags
|=
SERVER_CTX_DEBUG_REGISTERS
;
for
(
i
=
0
;
i
<
ARM_MAX_BREAKPOINTS
;
i
++
)
to
->
debug
.
arm_regs
.
bvr
[
i
]
=
from
->
Bvr
[
i
];
for
(
i
=
0
;
i
<
ARM_MAX_BREAKPOINTS
;
i
++
)
to
->
debug
.
arm_regs
.
bcr
[
i
]
=
from
->
Bcr
[
i
];
for
(
i
=
0
;
i
<
ARM_MAX_WATCHPOINTS
;
i
++
)
to
->
debug
.
arm_regs
.
wvr
[
i
]
=
from
->
Wvr
[
i
];
for
(
i
=
0
;
i
<
ARM_MAX_WATCHPOINTS
;
i
++
)
to
->
debug
.
arm_regs
.
wcr
[
i
]
=
from
->
Wcr
[
i
];
}
return
STATUS_SUCCESS
;
}
/***********************************************************************
* context_from_server
*
* Convert a register context from the server format.
...
...
@@ -463,23 +408,6 @@ NTSTATUS context_from_server( CONTEXT *to, const context_t *from )
}
/***********************************************************************
* NtSetContextThread (NTDLL.@)
* ZwSetContextThread (NTDLL.@)
*/
NTSTATUS
WINAPI
NtSetContextThread
(
HANDLE
handle
,
const
CONTEXT
*
context
)
{
NTSTATUS
ret
;
BOOL
self
;
context_t
server_context
;
context_to_server
(
&
server_context
,
context
);
ret
=
set_thread_context
(
handle
,
&
server_context
,
&
self
);
if
(
self
&&
ret
==
STATUS_SUCCESS
)
set_cpu_context
(
context
);
return
ret
;
}
/***********************************************************************
* NtGetContextThread (NTDLL.@)
* ZwGetContextThread (NTDLL.@)
*/
...
...
dlls/ntdll/signal_arm64.c
View file @
ac90898f
...
...
@@ -361,55 +361,6 @@ static void copy_context( CONTEXT *to, const CONTEXT *from, DWORD flags )
}
/***********************************************************************
* context_to_server
*
* Convert a register context to the server format.
*/
NTSTATUS
context_to_server
(
context_t
*
to
,
const
CONTEXT
*
from
)
{
DWORD
i
,
flags
=
from
->
ContextFlags
&
~
CONTEXT_ARM64
;
/* get rid of CPU id */
memset
(
to
,
0
,
sizeof
(
*
to
)
);
to
->
cpu
=
CPU_ARM64
;
if
(
flags
&
CONTEXT_CONTROL
)
{
to
->
flags
|=
SERVER_CTX_CONTROL
;
to
->
integer
.
arm64_regs
.
x
[
29
]
=
from
->
u
.
s
.
Fp
;
to
->
integer
.
arm64_regs
.
x
[
30
]
=
from
->
u
.
s
.
Lr
;
to
->
ctl
.
arm64_regs
.
sp
=
from
->
Sp
;
to
->
ctl
.
arm64_regs
.
pc
=
from
->
Pc
;
to
->
ctl
.
arm64_regs
.
pstate
=
from
->
Cpsr
;
}
if
(
flags
&
CONTEXT_INTEGER
)
{
to
->
flags
|=
SERVER_CTX_INTEGER
;
for
(
i
=
0
;
i
<=
28
;
i
++
)
to
->
integer
.
arm64_regs
.
x
[
i
]
=
from
->
u
.
X
[
i
];
}
if
(
flags
&
CONTEXT_FLOATING_POINT
)
{
to
->
flags
|=
SERVER_CTX_FLOATING_POINT
;
for
(
i
=
0
;
i
<
32
;
i
++
)
{
to
->
fp
.
arm64_regs
.
q
[
i
].
low
=
from
->
V
[
i
].
s
.
Low
;
to
->
fp
.
arm64_regs
.
q
[
i
].
high
=
from
->
V
[
i
].
s
.
High
;
}
to
->
fp
.
arm64_regs
.
fpcr
=
from
->
Fpcr
;
to
->
fp
.
arm64_regs
.
fpsr
=
from
->
Fpsr
;
}
if
(
flags
&
CONTEXT_DEBUG_REGISTERS
)
{
to
->
flags
|=
SERVER_CTX_DEBUG_REGISTERS
;
for
(
i
=
0
;
i
<
ARM64_MAX_BREAKPOINTS
;
i
++
)
to
->
debug
.
arm64_regs
.
bcr
[
i
]
=
from
->
Bcr
[
i
];
for
(
i
=
0
;
i
<
ARM64_MAX_BREAKPOINTS
;
i
++
)
to
->
debug
.
arm64_regs
.
bvr
[
i
]
=
from
->
Bvr
[
i
];
for
(
i
=
0
;
i
<
ARM64_MAX_WATCHPOINTS
;
i
++
)
to
->
debug
.
arm64_regs
.
wcr
[
i
]
=
from
->
Wcr
[
i
];
for
(
i
=
0
;
i
<
ARM64_MAX_WATCHPOINTS
;
i
++
)
to
->
debug
.
arm64_regs
.
wvr
[
i
]
=
from
->
Wvr
[
i
];
}
return
STATUS_SUCCESS
;
}
/***********************************************************************
* context_from_server
*
* Convert a register context from the server format.
...
...
@@ -458,29 +409,6 @@ NTSTATUS context_from_server( CONTEXT *to, const context_t *from )
}
/***********************************************************************
* NtSetContextThread (NTDLL.@)
* ZwSetContextThread (NTDLL.@)
*/
NTSTATUS
WINAPI
NtSetContextThread
(
HANDLE
handle
,
const
CONTEXT
*
context
)
{
NTSTATUS
ret
=
STATUS_SUCCESS
;
BOOL
self
=
(
handle
==
GetCurrentThread
());
if
(
self
&&
(
context
->
ContextFlags
&
(
CONTEXT_DEBUG_REGISTERS
&
~
CONTEXT_ARM64
)))
self
=
FALSE
;
if
(
!
self
)
{
context_t
server_context
;
context_to_server
(
&
server_context
,
context
);
ret
=
set_thread_context
(
handle
,
&
server_context
,
&
self
);
}
if
(
self
&&
ret
==
STATUS_SUCCESS
)
set_cpu_context
(
context
);
return
ret
;
}
/***********************************************************************
* NtGetContextThread (NTDLL.@)
* ZwGetContextThread (NTDLL.@)
*/
...
...
dlls/ntdll/signal_i386.c
View file @
ac90898f
...
...
@@ -1272,78 +1272,6 @@ static unsigned int get_server_context_flags( DWORD flags )
/***********************************************************************
* context_to_server
*
* Convert a register context to the server format.
*/
NTSTATUS
context_to_server
(
context_t
*
to
,
const
CONTEXT
*
from
)
{
DWORD
flags
=
from
->
ContextFlags
&
~
CONTEXT_i386
;
/* get rid of CPU id */
memset
(
to
,
0
,
sizeof
(
*
to
)
);
to
->
cpu
=
CPU_x86
;
if
(
flags
&
CONTEXT_CONTROL
)
{
to
->
flags
|=
SERVER_CTX_CONTROL
;
to
->
ctl
.
i386_regs
.
ebp
=
from
->
Ebp
;
to
->
ctl
.
i386_regs
.
esp
=
from
->
Esp
;
to
->
ctl
.
i386_regs
.
eip
=
from
->
Eip
;
to
->
ctl
.
i386_regs
.
cs
=
from
->
SegCs
;
to
->
ctl
.
i386_regs
.
ss
=
from
->
SegSs
;
to
->
ctl
.
i386_regs
.
eflags
=
from
->
EFlags
;
}
if
(
flags
&
CONTEXT_INTEGER
)
{
to
->
flags
|=
SERVER_CTX_INTEGER
;
to
->
integer
.
i386_regs
.
eax
=
from
->
Eax
;
to
->
integer
.
i386_regs
.
ebx
=
from
->
Ebx
;
to
->
integer
.
i386_regs
.
ecx
=
from
->
Ecx
;
to
->
integer
.
i386_regs
.
edx
=
from
->
Edx
;
to
->
integer
.
i386_regs
.
esi
=
from
->
Esi
;
to
->
integer
.
i386_regs
.
edi
=
from
->
Edi
;
}
if
(
flags
&
CONTEXT_SEGMENTS
)
{
to
->
flags
|=
SERVER_CTX_SEGMENTS
;
to
->
seg
.
i386_regs
.
ds
=
from
->
SegDs
;
to
->
seg
.
i386_regs
.
es
=
from
->
SegEs
;
to
->
seg
.
i386_regs
.
fs
=
from
->
SegFs
;
to
->
seg
.
i386_regs
.
gs
=
from
->
SegGs
;
}
if
(
flags
&
CONTEXT_FLOATING_POINT
)
{
to
->
flags
|=
SERVER_CTX_FLOATING_POINT
;
to
->
fp
.
i386_regs
.
ctrl
=
from
->
FloatSave
.
ControlWord
;
to
->
fp
.
i386_regs
.
status
=
from
->
FloatSave
.
StatusWord
;
to
->
fp
.
i386_regs
.
tag
=
from
->
FloatSave
.
TagWord
;
to
->
fp
.
i386_regs
.
err_off
=
from
->
FloatSave
.
ErrorOffset
;
to
->
fp
.
i386_regs
.
err_sel
=
from
->
FloatSave
.
ErrorSelector
;
to
->
fp
.
i386_regs
.
data_off
=
from
->
FloatSave
.
DataOffset
;
to
->
fp
.
i386_regs
.
data_sel
=
from
->
FloatSave
.
DataSelector
;
to
->
fp
.
i386_regs
.
cr0npx
=
from
->
FloatSave
.
Cr0NpxState
;
memcpy
(
to
->
fp
.
i386_regs
.
regs
,
from
->
FloatSave
.
RegisterArea
,
sizeof
(
to
->
fp
.
i386_regs
.
regs
)
);
}
if
(
flags
&
CONTEXT_DEBUG_REGISTERS
)
{
to
->
flags
|=
SERVER_CTX_DEBUG_REGISTERS
;
to
->
debug
.
i386_regs
.
dr0
=
from
->
Dr0
;
to
->
debug
.
i386_regs
.
dr1
=
from
->
Dr1
;
to
->
debug
.
i386_regs
.
dr2
=
from
->
Dr2
;
to
->
debug
.
i386_regs
.
dr3
=
from
->
Dr3
;
to
->
debug
.
i386_regs
.
dr6
=
from
->
Dr6
;
to
->
debug
.
i386_regs
.
dr7
=
from
->
Dr7
;
}
if
(
flags
&
CONTEXT_EXTENDED_REGISTERS
)
{
to
->
flags
|=
SERVER_CTX_EXTENDED_REGISTERS
;
memcpy
(
to
->
ext
.
i386_regs
,
from
->
ExtendedRegisters
,
sizeof
(
to
->
ext
.
i386_regs
)
);
}
return
STATUS_SUCCESS
;
}
/***********************************************************************
* context_from_server
*
* Convert a register context from the server format.
...
...
@@ -1414,36 +1342,6 @@ NTSTATUS context_from_server( CONTEXT *to, const context_t *from )
/***********************************************************************
* NtSetContextThread (NTDLL.@)
* ZwSetContextThread (NTDLL.@)
*/
NTSTATUS
WINAPI
NtSetContextThread
(
HANDLE
handle
,
const
CONTEXT
*
context
)
{
NTSTATUS
ret
=
STATUS_SUCCESS
;
BOOL
self
=
(
handle
==
GetCurrentThread
());
/* debug registers require a server call */
if
(
self
&&
(
context
->
ContextFlags
&
(
CONTEXT_DEBUG_REGISTERS
&
~
CONTEXT_i386
)))
self
=
(
x86_thread_data
()
->
dr0
==
context
->
Dr0
&&
x86_thread_data
()
->
dr1
==
context
->
Dr1
&&
x86_thread_data
()
->
dr2
==
context
->
Dr2
&&
x86_thread_data
()
->
dr3
==
context
->
Dr3
&&
x86_thread_data
()
->
dr6
==
context
->
Dr6
&&
x86_thread_data
()
->
dr7
==
context
->
Dr7
);
if
(
!
self
)
{
context_t
server_context
;
context_to_server
(
&
server_context
,
context
);
ret
=
set_thread_context
(
handle
,
&
server_context
,
&
self
);
}
if
(
self
&&
ret
==
STATUS_SUCCESS
)
set_cpu_context
(
context
);
return
ret
;
}
/***********************************************************************
* NtGetContextThread (NTDLL.@)
* ZwGetContextThread (NTDLL.@)
*
...
...
dlls/ntdll/signal_powerpc.c
View file @
ac90898f
...
...
@@ -261,17 +261,6 @@ void WINAPI RtlCaptureContext( CONTEXT *context )
/***********************************************************************
* set_cpu_context
*
* Set the new CPU context.
*/
static
void
set_cpu_context
(
const
CONTEXT
*
context
)
{
FIXME
(
"not implemented
\n
"
);
}
/***********************************************************************
* get_server_context_flags
*
* Convert CPU-specific flags to generic server flags
...
...
@@ -382,108 +371,6 @@ static void copy_context( CONTEXT *to, const CONTEXT *from, DWORD flags )
/***********************************************************************
* context_to_server
*
* Convert a register context to the server format.
*/
NTSTATUS
context_to_server
(
context_t
*
to
,
const
CONTEXT
*
from
)
{
DWORD
flags
=
from
->
ContextFlags
;
/* no CPU id? */
memset
(
to
,
0
,
sizeof
(
*
to
)
);
to
->
cpu
=
CPU_POWERPC
;
if
(
flags
&
CONTEXT_CONTROL
)
{
to
->
flags
|=
SERVER_CTX_CONTROL
;
to
->
ctl
.
powerpc_regs
.
iar
=
from
->
Iar
;
to
->
ctl
.
powerpc_regs
.
msr
=
from
->
Msr
;
to
->
ctl
.
powerpc_regs
.
ctr
=
from
->
Ctr
;
to
->
ctl
.
powerpc_regs
.
lr
=
from
->
Lr
;
to
->
ctl
.
powerpc_regs
.
dar
=
from
->
Dar
;
to
->
ctl
.
powerpc_regs
.
dsisr
=
from
->
Dsisr
;
to
->
ctl
.
powerpc_regs
.
trap
=
from
->
Trap
;
}
if
(
flags
&
CONTEXT_INTEGER
)
{
to
->
flags
|=
SERVER_CTX_INTEGER
;
to
->
integer
.
powerpc_regs
.
gpr
[
0
]
=
from
->
Gpr0
;
to
->
integer
.
powerpc_regs
.
gpr
[
1
]
=
from
->
Gpr1
;
to
->
integer
.
powerpc_regs
.
gpr
[
2
]
=
from
->
Gpr2
;
to
->
integer
.
powerpc_regs
.
gpr
[
3
]
=
from
->
Gpr3
;
to
->
integer
.
powerpc_regs
.
gpr
[
4
]
=
from
->
Gpr4
;
to
->
integer
.
powerpc_regs
.
gpr
[
5
]
=
from
->
Gpr5
;
to
->
integer
.
powerpc_regs
.
gpr
[
6
]
=
from
->
Gpr6
;
to
->
integer
.
powerpc_regs
.
gpr
[
7
]
=
from
->
Gpr7
;
to
->
integer
.
powerpc_regs
.
gpr
[
8
]
=
from
->
Gpr8
;
to
->
integer
.
powerpc_regs
.
gpr
[
9
]
=
from
->
Gpr9
;
to
->
integer
.
powerpc_regs
.
gpr
[
10
]
=
from
->
Gpr10
;
to
->
integer
.
powerpc_regs
.
gpr
[
11
]
=
from
->
Gpr11
;
to
->
integer
.
powerpc_regs
.
gpr
[
12
]
=
from
->
Gpr12
;
to
->
integer
.
powerpc_regs
.
gpr
[
13
]
=
from
->
Gpr13
;
to
->
integer
.
powerpc_regs
.
gpr
[
14
]
=
from
->
Gpr14
;
to
->
integer
.
powerpc_regs
.
gpr
[
15
]
=
from
->
Gpr15
;
to
->
integer
.
powerpc_regs
.
gpr
[
16
]
=
from
->
Gpr16
;
to
->
integer
.
powerpc_regs
.
gpr
[
17
]
=
from
->
Gpr17
;
to
->
integer
.
powerpc_regs
.
gpr
[
18
]
=
from
->
Gpr18
;
to
->
integer
.
powerpc_regs
.
gpr
[
19
]
=
from
->
Gpr19
;
to
->
integer
.
powerpc_regs
.
gpr
[
20
]
=
from
->
Gpr20
;
to
->
integer
.
powerpc_regs
.
gpr
[
21
]
=
from
->
Gpr21
;
to
->
integer
.
powerpc_regs
.
gpr
[
22
]
=
from
->
Gpr22
;
to
->
integer
.
powerpc_regs
.
gpr
[
23
]
=
from
->
Gpr23
;
to
->
integer
.
powerpc_regs
.
gpr
[
24
]
=
from
->
Gpr24
;
to
->
integer
.
powerpc_regs
.
gpr
[
25
]
=
from
->
Gpr25
;
to
->
integer
.
powerpc_regs
.
gpr
[
26
]
=
from
->
Gpr26
;
to
->
integer
.
powerpc_regs
.
gpr
[
27
]
=
from
->
Gpr27
;
to
->
integer
.
powerpc_regs
.
gpr
[
28
]
=
from
->
Gpr28
;
to
->
integer
.
powerpc_regs
.
gpr
[
29
]
=
from
->
Gpr29
;
to
->
integer
.
powerpc_regs
.
gpr
[
30
]
=
from
->
Gpr30
;
to
->
integer
.
powerpc_regs
.
gpr
[
31
]
=
from
->
Gpr31
;
to
->
integer
.
powerpc_regs
.
xer
=
from
->
Xer
;
to
->
integer
.
powerpc_regs
.
cr
=
from
->
Cr
;
}
if
(
flags
&
CONTEXT_FLOATING_POINT
)
{
to
->
flags
|=
SERVER_CTX_FLOATING_POINT
;
to
->
fp
.
powerpc_regs
.
fpr
[
0
]
=
from
->
Fpr0
;
to
->
fp
.
powerpc_regs
.
fpr
[
1
]
=
from
->
Fpr1
;
to
->
fp
.
powerpc_regs
.
fpr
[
2
]
=
from
->
Fpr2
;
to
->
fp
.
powerpc_regs
.
fpr
[
3
]
=
from
->
Fpr3
;
to
->
fp
.
powerpc_regs
.
fpr
[
4
]
=
from
->
Fpr4
;
to
->
fp
.
powerpc_regs
.
fpr
[
5
]
=
from
->
Fpr5
;
to
->
fp
.
powerpc_regs
.
fpr
[
6
]
=
from
->
Fpr6
;
to
->
fp
.
powerpc_regs
.
fpr
[
7
]
=
from
->
Fpr7
;
to
->
fp
.
powerpc_regs
.
fpr
[
8
]
=
from
->
Fpr8
;
to
->
fp
.
powerpc_regs
.
fpr
[
9
]
=
from
->
Fpr9
;
to
->
fp
.
powerpc_regs
.
fpr
[
10
]
=
from
->
Fpr10
;
to
->
fp
.
powerpc_regs
.
fpr
[
11
]
=
from
->
Fpr11
;
to
->
fp
.
powerpc_regs
.
fpr
[
12
]
=
from
->
Fpr12
;
to
->
fp
.
powerpc_regs
.
fpr
[
13
]
=
from
->
Fpr13
;
to
->
fp
.
powerpc_regs
.
fpr
[
14
]
=
from
->
Fpr14
;
to
->
fp
.
powerpc_regs
.
fpr
[
15
]
=
from
->
Fpr15
;
to
->
fp
.
powerpc_regs
.
fpr
[
16
]
=
from
->
Fpr16
;
to
->
fp
.
powerpc_regs
.
fpr
[
17
]
=
from
->
Fpr17
;
to
->
fp
.
powerpc_regs
.
fpr
[
18
]
=
from
->
Fpr18
;
to
->
fp
.
powerpc_regs
.
fpr
[
19
]
=
from
->
Fpr19
;
to
->
fp
.
powerpc_regs
.
fpr
[
20
]
=
from
->
Fpr20
;
to
->
fp
.
powerpc_regs
.
fpr
[
21
]
=
from
->
Fpr21
;
to
->
fp
.
powerpc_regs
.
fpr
[
22
]
=
from
->
Fpr22
;
to
->
fp
.
powerpc_regs
.
fpr
[
23
]
=
from
->
Fpr23
;
to
->
fp
.
powerpc_regs
.
fpr
[
24
]
=
from
->
Fpr24
;
to
->
fp
.
powerpc_regs
.
fpr
[
25
]
=
from
->
Fpr25
;
to
->
fp
.
powerpc_regs
.
fpr
[
26
]
=
from
->
Fpr26
;
to
->
fp
.
powerpc_regs
.
fpr
[
27
]
=
from
->
Fpr27
;
to
->
fp
.
powerpc_regs
.
fpr
[
28
]
=
from
->
Fpr28
;
to
->
fp
.
powerpc_regs
.
fpr
[
29
]
=
from
->
Fpr29
;
to
->
fp
.
powerpc_regs
.
fpr
[
30
]
=
from
->
Fpr30
;
to
->
fp
.
powerpc_regs
.
fpr
[
31
]
=
from
->
Fpr31
;
to
->
fp
.
powerpc_regs
.
fpscr
=
from
->
Fpscr
;
}
return
STATUS_SUCCESS
;
}
/***********************************************************************
* context_from_server
*
* Convert a register context from the server format.
...
...
@@ -584,23 +471,6 @@ NTSTATUS context_from_server( CONTEXT *to, const context_t *from )
/***********************************************************************
* NtSetContextThread (NTDLL.@)
* ZwSetContextThread (NTDLL.@)
*/
NTSTATUS
WINAPI
NtSetContextThread
(
HANDLE
handle
,
const
CONTEXT
*
context
)
{
NTSTATUS
ret
;
BOOL
self
;
context_t
server_context
;
context_to_server
(
&
server_context
,
context
);
ret
=
set_thread_context
(
handle
,
&
server_context
,
&
self
);
if
(
self
&&
ret
==
STATUS_SUCCESS
)
set_cpu_context
(
context
);
return
ret
;
}
/***********************************************************************
* NtGetContextThread (NTDLL.@)
* ZwGetContextThread (NTDLL.@)
*/
...
...
dlls/ntdll/signal_x86_64.c
View file @
ac90898f
...
...
@@ -1967,73 +1967,6 @@ static void copy_context( CONTEXT *to, const CONTEXT *from, DWORD flags )
/***********************************************************************
* context_to_server
*
* Convert a register context to the server format.
*/
NTSTATUS
context_to_server
(
context_t
*
to
,
const
CONTEXT
*
from
)
{
DWORD
flags
=
from
->
ContextFlags
&
~
CONTEXT_AMD64
;
/* get rid of CPU id */
memset
(
to
,
0
,
sizeof
(
*
to
)
);
to
->
cpu
=
CPU_x86_64
;
if
(
flags
&
CONTEXT_CONTROL
)
{
to
->
flags
|=
SERVER_CTX_CONTROL
;
to
->
ctl
.
x86_64_regs
.
rbp
=
from
->
Rbp
;
to
->
ctl
.
x86_64_regs
.
rip
=
from
->
Rip
;
to
->
ctl
.
x86_64_regs
.
rsp
=
from
->
Rsp
;
to
->
ctl
.
x86_64_regs
.
cs
=
from
->
SegCs
;
to
->
ctl
.
x86_64_regs
.
ss
=
from
->
SegSs
;
to
->
ctl
.
x86_64_regs
.
flags
=
from
->
EFlags
;
}
if
(
flags
&
CONTEXT_INTEGER
)
{
to
->
flags
|=
SERVER_CTX_INTEGER
;
to
->
integer
.
x86_64_regs
.
rax
=
from
->
Rax
;
to
->
integer
.
x86_64_regs
.
rcx
=
from
->
Rcx
;
to
->
integer
.
x86_64_regs
.
rdx
=
from
->
Rdx
;
to
->
integer
.
x86_64_regs
.
rbx
=
from
->
Rbx
;
to
->
integer
.
x86_64_regs
.
rsi
=
from
->
Rsi
;
to
->
integer
.
x86_64_regs
.
rdi
=
from
->
Rdi
;
to
->
integer
.
x86_64_regs
.
r8
=
from
->
R8
;
to
->
integer
.
x86_64_regs
.
r9
=
from
->
R9
;
to
->
integer
.
x86_64_regs
.
r10
=
from
->
R10
;
to
->
integer
.
x86_64_regs
.
r11
=
from
->
R11
;
to
->
integer
.
x86_64_regs
.
r12
=
from
->
R12
;
to
->
integer
.
x86_64_regs
.
r13
=
from
->
R13
;
to
->
integer
.
x86_64_regs
.
r14
=
from
->
R14
;
to
->
integer
.
x86_64_regs
.
r15
=
from
->
R15
;
}
if
(
flags
&
CONTEXT_SEGMENTS
)
{
to
->
flags
|=
SERVER_CTX_SEGMENTS
;
to
->
seg
.
x86_64_regs
.
ds
=
from
->
SegDs
;
to
->
seg
.
x86_64_regs
.
es
=
from
->
SegEs
;
to
->
seg
.
x86_64_regs
.
fs
=
from
->
SegFs
;
to
->
seg
.
x86_64_regs
.
gs
=
from
->
SegGs
;
}
if
(
flags
&
CONTEXT_FLOATING_POINT
)
{
to
->
flags
|=
SERVER_CTX_FLOATING_POINT
;
memcpy
(
to
->
fp
.
x86_64_regs
.
fpregs
,
&
from
->
u
.
FltSave
,
sizeof
(
to
->
fp
.
x86_64_regs
.
fpregs
)
);
}
if
(
flags
&
CONTEXT_DEBUG_REGISTERS
)
{
to
->
flags
|=
SERVER_CTX_DEBUG_REGISTERS
;
to
->
debug
.
x86_64_regs
.
dr0
=
from
->
Dr0
;
to
->
debug
.
x86_64_regs
.
dr1
=
from
->
Dr1
;
to
->
debug
.
x86_64_regs
.
dr2
=
from
->
Dr2
;
to
->
debug
.
x86_64_regs
.
dr3
=
from
->
Dr3
;
to
->
debug
.
x86_64_regs
.
dr6
=
from
->
Dr6
;
to
->
debug
.
x86_64_regs
.
dr7
=
from
->
Dr7
;
}
return
STATUS_SUCCESS
;
}
/***********************************************************************
* context_from_server
*
* Convert a register context from the server format.
...
...
@@ -2101,35 +2034,6 @@ NTSTATUS context_from_server( CONTEXT *to, const context_t *from )
/***********************************************************************
* NtSetContextThread (NTDLL.@)
* ZwSetContextThread (NTDLL.@)
*/
NTSTATUS
WINAPI
NtSetContextThread
(
HANDLE
handle
,
const
CONTEXT
*
context
)
{
NTSTATUS
ret
=
STATUS_SUCCESS
;
BOOL
self
=
(
handle
==
GetCurrentThread
());
/* debug registers require a server call */
if
(
self
&&
(
context
->
ContextFlags
&
(
CONTEXT_DEBUG_REGISTERS
&
~
CONTEXT_AMD64
)))
self
=
(
amd64_thread_data
()
->
dr0
==
context
->
Dr0
&&
amd64_thread_data
()
->
dr1
==
context
->
Dr1
&&
amd64_thread_data
()
->
dr2
==
context
->
Dr2
&&
amd64_thread_data
()
->
dr3
==
context
->
Dr3
&&
amd64_thread_data
()
->
dr6
==
context
->
Dr6
&&
amd64_thread_data
()
->
dr7
==
context
->
Dr7
);
if
(
!
self
)
{
context_t
server_context
;
context_to_server
(
&
server_context
,
context
);
ret
=
set_thread_context
(
handle
,
&
server_context
,
&
self
);
}
if
(
self
&&
ret
==
STATUS_SUCCESS
)
set_cpu_context
(
context
);
return
ret
;
}
/***********************************************************************
* NtGetContextThread (NTDLL.@)
* ZwGetContextThread (NTDLL.@)
*/
...
...
dlls/ntdll/thread.c
View file @
ac90898f
...
...
@@ -767,6 +767,16 @@ NTSTATUS get_thread_context( HANDLE handle, context_t *context, unsigned int fla
}
/***********************************************************************
* NtSetContextThread (NTDLL.@)
* ZwSetContextThread (NTDLL.@)
*/
NTSTATUS
WINAPI
NtSetContextThread
(
HANDLE
handle
,
const
CONTEXT
*
context
)
{
return
unix_funcs
->
NtSetContextThread
(
handle
,
context
);
}
/******************************************************************************
* NtSetLdtEntries (NTDLL.@)
* ZwSetLdtEntries (NTDLL.@)
...
...
dlls/ntdll/unix/loader.c
View file @
ac90898f
...
...
@@ -986,6 +986,7 @@ static struct unix_funcs unix_funcs =
NtClose
,
NtCurrentTeb
,
NtDuplicateObject
,
NtSetContextThread
,
NtSetLdtEntries
,
get_main_args
,
get_paths
,
...
...
dlls/ntdll/unix/signal_arm.c
View file @
ac90898f
...
...
@@ -70,6 +70,27 @@ static pthread_key_t teb_key;
/***********************************************************************
* set_cpu_context
*
* Set the new CPU context.
*/
void
DECLSPEC_HIDDEN
set_cpu_context
(
const
CONTEXT
*
context
);
__ASM_GLOBAL_FUNC
(
set_cpu_context
,
".arm
\n\t
"
"ldr r2, [r0, #0x44]
\n\t
"
/* context->Cpsr */
"tst r2, #0x20
\n\t
"
/* thumb? */
"ldr r1, [r0, #0x40]
\n\t
"
/* context->Pc */
"orrne r1, r1, #1
\n\t
"
/* Adjust PC according to thumb */
"biceq r1, r1, #1
\n\t
"
/* Adjust PC according to arm */
"msr CPSR_f, r2
\n\t
"
"ldr lr, [r0, #0x3c]
\n\t
"
/* context->Lr */
"ldr sp, [r0, #0x38]
\n\t
"
/* context->Sp */
"push {r1}
\n\t
"
"ldmib r0, {r0-r12}
\n\t
"
/* context->R0..R12 */
"pop {pc}"
)
/***********************************************************************
* context_to_server
*
* Convert a register context to the server format.
...
...
@@ -179,6 +200,23 @@ NTSTATUS context_from_server( CONTEXT *to, const context_t *from )
}
/***********************************************************************
* NtSetContextThread (NTDLL.@)
* ZwSetContextThread (NTDLL.@)
*/
NTSTATUS
WINAPI
NtSetContextThread
(
HANDLE
handle
,
const
CONTEXT
*
context
)
{
NTSTATUS
ret
;
BOOL
self
;
context_t
server_context
;
context_to_server
(
&
server_context
,
context
);
ret
=
set_thread_context
(
handle
,
&
server_context
,
&
self
);
if
(
self
&&
ret
==
STATUS_SUCCESS
)
set_cpu_context
(
context
);
return
ret
;
}
/**********************************************************************
* get_thread_ldt_entry
*/
...
...
dlls/ntdll/unix/signal_arm64.c
View file @
ac90898f
...
...
@@ -73,6 +73,31 @@ static pthread_key_t teb_key;
static
const
size_t
teb_size
=
0x2000
;
/* we reserve two pages for the TEB */
struct
arm64_thread_data
{
void
*
exit_frame
;
/* exit frame pointer */
CONTEXT
*
context
;
/* context to set with SIGUSR2 */
};
C_ASSERT
(
sizeof
(
struct
arm64_thread_data
)
<=
sizeof
(((
TEB
*
)
0
)
->
SystemReserved2
)
);
C_ASSERT
(
offsetof
(
TEB
,
SystemReserved2
)
+
offsetof
(
struct
arm64_thread_data
,
exit_frame
)
==
0x300
);
static
inline
struct
arm64_thread_data
*
arm64_thread_data
(
void
)
{
return
(
struct
arm64_thread_data
*
)
NtCurrentTeb
()
->
SystemReserved2
;
}
/***********************************************************************
* set_cpu_context
*
* Set the new CPU context.
*/
static
void
set_cpu_context
(
const
CONTEXT
*
context
)
{
InterlockedExchangePointer
(
(
void
**
)
&
arm64_thread_data
()
->
context
,
(
void
*
)
context
);
raise
(
SIGUSR2
);
}
/***********************************************************************
* context_to_server
...
...
@@ -172,6 +197,29 @@ NTSTATUS context_from_server( CONTEXT *to, const context_t *from )
}
/***********************************************************************
* NtSetContextThread (NTDLL.@)
* ZwSetContextThread (NTDLL.@)
*/
NTSTATUS
WINAPI
NtSetContextThread
(
HANDLE
handle
,
const
CONTEXT
*
context
)
{
NTSTATUS
ret
=
STATUS_SUCCESS
;
BOOL
self
=
(
handle
==
GetCurrentThread
());
if
(
self
&&
(
context
->
ContextFlags
&
(
CONTEXT_DEBUG_REGISTERS
&
~
CONTEXT_ARM64
)))
self
=
FALSE
;
if
(
!
self
)
{
context_t
server_context
;
context_to_server
(
&
server_context
,
context
);
ret
=
set_thread_context
(
handle
,
&
server_context
,
&
self
);
}
if
(
self
&&
ret
==
STATUS_SUCCESS
)
set_cpu_context
(
context
);
return
ret
;
}
/**********************************************************************
* get_thread_ldt_entry
*/
...
...
dlls/ntdll/unix/signal_i386.c
View file @
ac90898f
...
...
@@ -61,6 +61,34 @@
#include "unix_private.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL
(
seh
);
/* not defined for x86, so copy the x86_64 definition */
typedef
struct
DECLSPEC_ALIGN
(
16
)
_M128A
{
ULONGLONG
Low
;
LONGLONG
High
;
}
M128A
;
typedef
struct
{
WORD
ControlWord
;
WORD
StatusWord
;
BYTE
TagWord
;
BYTE
Reserved1
;
WORD
ErrorOpcode
;
DWORD
ErrorOffset
;
WORD
ErrorSelector
;
WORD
Reserved2
;
DWORD
DataOffset
;
WORD
DataSelector
;
WORD
Reserved3
;
DWORD
MxCsr
;
DWORD
MxCsr_Mask
;
M128A
FloatRegisters
[
8
];
M128A
XmmRegisters
[
16
];
BYTE
Reserved4
[
96
];
}
XMM_SAVE_AREA32
;
/***********************************************************************
* signal context platform-specific definitions
...
...
@@ -152,6 +180,11 @@ struct x86_thread_data
C_ASSERT
(
offsetof
(
TEB
,
SystemReserved2
)
+
offsetof
(
struct
x86_thread_data
,
gs
)
==
0x1d8
);
C_ASSERT
(
offsetof
(
TEB
,
SystemReserved2
)
+
offsetof
(
struct
x86_thread_data
,
exit_frame
)
==
0x1f4
);
static
inline
struct
x86_thread_data
*
x86_thread_data
(
void
)
{
return
(
struct
x86_thread_data
*
)
NtCurrentTeb
()
->
SystemReserved2
;
}
static
inline
WORD
get_cs
(
void
)
{
WORD
res
;
__asm__
(
"movw %%cs,%0"
:
"=r"
(
res
)
);
return
res
;
}
static
inline
WORD
get_ds
(
void
)
{
WORD
res
;
__asm__
(
"movw %%ds,%0"
:
"=r"
(
res
)
);
return
res
;
}
static
inline
WORD
get_fs
(
void
)
{
WORD
res
;
__asm__
(
"movw %%fs,%0"
:
"=r"
(
res
)
);
return
res
;
}
...
...
@@ -169,6 +202,134 @@ static inline int is_gdt_sel( WORD sel )
/***********************************************************************
* restore_fpu
*
* Restore the FPU context to a sigcontext.
*/
static
inline
void
restore_fpu
(
const
CONTEXT
*
context
)
{
FLOATING_SAVE_AREA
float_status
=
context
->
FloatSave
;
/* reset the current interrupt status */
float_status
.
StatusWord
&=
float_status
.
ControlWord
|
0xffffff80
;
__asm__
__volatile__
(
"frstor %0; fwait"
:
:
"m"
(
float_status
)
);
}
/***********************************************************************
* restore_fpux
*
* Restore the FPU extended context to a sigcontext.
*/
static
inline
void
restore_fpux
(
const
CONTEXT
*
context
)
{
/* we have to enforce alignment by hand */
char
buffer
[
sizeof
(
XMM_SAVE_AREA32
)
+
16
];
XMM_SAVE_AREA32
*
state
=
(
XMM_SAVE_AREA32
*
)(((
ULONG_PTR
)
buffer
+
15
)
&
~
15
);
memcpy
(
state
,
context
->
ExtendedRegisters
,
sizeof
(
*
state
)
);
/* reset the current interrupt status */
state
->
StatusWord
&=
state
->
ControlWord
|
0xff80
;
__asm__
__volatile__
(
"fxrstor %0"
:
:
"m"
(
*
state
)
);
}
/***********************************************************************
* set_full_cpu_context
*
* Set the new CPU context.
*/
extern
void
set_full_cpu_context
(
const
CONTEXT
*
context
);
__ASM_GLOBAL_FUNC
(
set_full_cpu_context
,
"movl 4(%esp),%ecx
\n\t
"
"movw 0x8c(%ecx),%gs
\n\t
"
/* SegGs */
"movw 0x90(%ecx),%fs
\n\t
"
/* SegFs */
"movw 0x94(%ecx),%es
\n\t
"
/* SegEs */
"movl 0x9c(%ecx),%edi
\n\t
"
/* Edi */
"movl 0xa0(%ecx),%esi
\n\t
"
/* Esi */
"movl 0xa4(%ecx),%ebx
\n\t
"
/* Ebx */
"movl 0xb4(%ecx),%ebp
\n\t
"
/* Ebp */
"movw %ss,%ax
\n\t
"
"cmpw 0xc8(%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 0xc4(%ecx),%eax
\n\t
"
/* Esp */
"leal -4*4(%eax),%eax
\n\t
"
"movl 0xc0(%ecx),%edx
\n\t
"
/* EFlags */
"movl %edx,3*4(%eax)
\n\t
"
"movl 0xbc(%ecx),%edx
\n\t
"
/* SegCs */
"movl %edx,2*4(%eax)
\n\t
"
"movl 0xb8(%ecx),%edx
\n\t
"
/* Eip */
"movl %edx,1*4(%eax)
\n\t
"
"movl 0xb0(%ecx),%edx
\n\t
"
/* Eax */
"movl %edx,0*4(%eax)
\n\t
"
"pushl 0x98(%ecx)
\n\t
"
/* SegDs */
"movl 0xa8(%ecx),%edx
\n\t
"
/* Edx */
"movl 0xac(%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 0xa8(%ecx),%edx
\n\t
"
/* Edx */
"movl 0xb0(%ecx),%eax
\n\t
"
/* Eax */
"movw 0xc8(%ecx),%ss
\n\t
"
/* SegSs */
"movl 0xc4(%ecx),%esp
\n\t
"
/* Esp */
"pushl 0xc0(%ecx)
\n\t
"
/* EFlags */
"pushl 0xbc(%ecx)
\n\t
"
/* SegCs */
"pushl 0xb8(%ecx)
\n\t
"
/* Eip */
"pushl 0x98(%ecx)
\n\t
"
/* SegDs */
"movl 0xac(%ecx),%ecx
\n\t
"
/* Ecx */
"popl %ds
\n\t
"
"iret"
)
/***********************************************************************
* set_cpu_context
*
* Set the new CPU context. Used by NtSetContextThread.
*/
void
DECLSPEC_HIDDEN
set_cpu_context
(
const
CONTEXT
*
context
)
{
DWORD
flags
=
context
->
ContextFlags
&
~
CONTEXT_i386
;
if
(
flags
&
CONTEXT_EXTENDED_REGISTERS
)
restore_fpux
(
context
);
else
if
(
flags
&
CONTEXT_FLOATING_POINT
)
restore_fpu
(
context
);
if
(
flags
&
CONTEXT_DEBUG_REGISTERS
)
{
x86_thread_data
()
->
dr0
=
context
->
Dr0
;
x86_thread_data
()
->
dr1
=
context
->
Dr1
;
x86_thread_data
()
->
dr2
=
context
->
Dr2
;
x86_thread_data
()
->
dr3
=
context
->
Dr3
;
x86_thread_data
()
->
dr6
=
context
->
Dr6
;
x86_thread_data
()
->
dr7
=
context
->
Dr7
;
}
if
(
flags
&
CONTEXT_FULL
)
{
if
(
!
(
flags
&
CONTEXT_CONTROL
))
FIXME
(
"setting partial context (%x) not supported
\n
"
,
flags
);
else
if
(
flags
&
CONTEXT_SEGMENTS
)
set_full_cpu_context
(
context
);
else
{
CONTEXT
newcontext
=
*
context
;
newcontext
.
SegDs
=
get_ds
();
newcontext
.
SegEs
=
get_ds
();
newcontext
.
SegFs
=
get_fs
();
newcontext
.
SegGs
=
get_gs
();
set_full_cpu_context
(
&
newcontext
);
}
}
}
/***********************************************************************
* context_to_server
*
* Convert a register context to the server format.
...
...
@@ -311,6 +472,36 @@ NTSTATUS context_from_server( CONTEXT *to, const context_t *from )
/***********************************************************************
* NtSetContextThread (NTDLL.@)
* ZwSetContextThread (NTDLL.@)
*/
NTSTATUS
WINAPI
NtSetContextThread
(
HANDLE
handle
,
const
CONTEXT
*
context
)
{
NTSTATUS
ret
=
STATUS_SUCCESS
;
BOOL
self
=
(
handle
==
GetCurrentThread
());
/* debug registers require a server call */
if
(
self
&&
(
context
->
ContextFlags
&
(
CONTEXT_DEBUG_REGISTERS
&
~
CONTEXT_i386
)))
self
=
(
x86_thread_data
()
->
dr0
==
context
->
Dr0
&&
x86_thread_data
()
->
dr1
==
context
->
Dr1
&&
x86_thread_data
()
->
dr2
==
context
->
Dr2
&&
x86_thread_data
()
->
dr3
==
context
->
Dr3
&&
x86_thread_data
()
->
dr6
==
context
->
Dr6
&&
x86_thread_data
()
->
dr7
==
context
->
Dr7
);
if
(
!
self
)
{
context_t
server_context
;
context_to_server
(
&
server_context
,
context
);
ret
=
set_thread_context
(
handle
,
&
server_context
,
&
self
);
}
if
(
self
&&
ret
==
STATUS_SUCCESS
)
set_cpu_context
(
context
);
return
ret
;
}
/***********************************************************************
* LDT support
*/
...
...
dlls/ntdll/unix/signal_powerpc.c
View file @
ac90898f
...
...
@@ -67,6 +67,17 @@ static pthread_key_t teb_key;
/***********************************************************************
* set_cpu_context
*
* Set the new CPU context.
*/
static
void
set_cpu_context
(
const
CONTEXT
*
context
)
{
FIXME
(
"not implemented
\n
"
);
}
/***********************************************************************
* context_to_server
*
* Convert a register context to the server format.
...
...
@@ -268,6 +279,23 @@ NTSTATUS context_from_server( CONTEXT *to, const context_t *from )
}
/***********************************************************************
* NtSetContextThread (NTDLL.@)
* ZwSetContextThread (NTDLL.@)
*/
NTSTATUS
WINAPI
NtSetContextThread
(
HANDLE
handle
,
const
CONTEXT
*
context
)
{
NTSTATUS
ret
;
BOOL
self
;
context_t
server_context
;
context_to_server
(
&
server_context
,
context
);
ret
=
set_thread_context
(
handle
,
&
server_context
,
&
self
);
if
(
self
&&
ret
==
STATUS_SUCCESS
)
set_cpu_context
(
context
);
return
ret
;
}
/**********************************************************************
* get_thread_ldt_entry
*/
...
...
dlls/ntdll/unix/signal_x86_64.c
View file @
ac90898f
...
...
@@ -76,6 +76,8 @@
#include "unix_private.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL
(
seh
);
/***********************************************************************
* signal context platform-specific definitions
*/
...
...
@@ -112,6 +114,110 @@ enum i386_trap_code
static
const
size_t
teb_size
=
0x2000
;
/* we reserve two pages for the TEB */
struct
amd64_thread_data
{
DWORD_PTR
dr0
;
/* debug registers */
DWORD_PTR
dr1
;
DWORD_PTR
dr2
;
DWORD_PTR
dr3
;
DWORD_PTR
dr6
;
DWORD_PTR
dr7
;
void
*
exit_frame
;
/* exit frame pointer */
};
C_ASSERT
(
sizeof
(
struct
amd64_thread_data
)
<=
sizeof
(((
TEB
*
)
0
)
->
SystemReserved2
)
);
C_ASSERT
(
offsetof
(
TEB
,
SystemReserved2
)
+
offsetof
(
struct
amd64_thread_data
,
exit_frame
)
==
0x330
);
static
inline
struct
amd64_thread_data
*
amd64_thread_data
(
void
)
{
return
(
struct
amd64_thread_data
*
)
NtCurrentTeb
()
->
SystemReserved2
;
}
/***********************************************************************
* set_full_cpu_context
*
* Set the new CPU context.
*/
extern
void
set_full_cpu_context
(
const
CONTEXT
*
context
);
__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
"
)
"ldmxcsr 0x34(%rdi)
\n\t
"
/* context->MxCsr */
"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 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->FtlSave */
"movdqa 0x1a0(%rdi),%xmm0
\n\t
"
/* context->Xmm0 */
"movdqa 0x1b0(%rdi),%xmm1
\n\t
"
/* context->Xmm1 */
"movdqa 0x1c0(%rdi),%xmm2
\n\t
"
/* context->Xmm2 */
"movdqa 0x1d0(%rdi),%xmm3
\n\t
"
/* context->Xmm3 */
"movdqa 0x1e0(%rdi),%xmm4
\n\t
"
/* context->Xmm4 */
"movdqa 0x1f0(%rdi),%xmm5
\n\t
"
/* context->Xmm5 */
"movdqa 0x200(%rdi),%xmm6
\n\t
"
/* context->Xmm6 */
"movdqa 0x210(%rdi),%xmm7
\n\t
"
/* context->Xmm7 */
"movdqa 0x220(%rdi),%xmm8
\n\t
"
/* context->Xmm8 */
"movdqa 0x230(%rdi),%xmm9
\n\t
"
/* context->Xmm9 */
"movdqa 0x240(%rdi),%xmm10
\n\t
"
/* context->Xmm10 */
"movdqa 0x250(%rdi),%xmm11
\n\t
"
/* context->Xmm11 */
"movdqa 0x260(%rdi),%xmm12
\n\t
"
/* context->Xmm12 */
"movdqa 0x270(%rdi),%xmm13
\n\t
"
/* context->Xmm13 */
"movdqa 0x280(%rdi),%xmm14
\n\t
"
/* context->Xmm14 */
"movdqa 0x290(%rdi),%xmm15
\n\t
"
/* context->Xmm15 */
"movq 0x78(%rdi),%rax
\n\t
"
/* context->Rax */
"movq 0xb0(%rdi),%rdi
\n\t
"
/* context->Rdi */
"iretq"
);
/***********************************************************************
* set_cpu_context
*
* Set the new CPU context. Used by NtSetContextThread.
*/
void
DECLSPEC_HIDDEN
set_cpu_context
(
const
CONTEXT
*
context
)
{
DWORD
flags
=
context
->
ContextFlags
&
~
CONTEXT_AMD64
;
if
(
flags
&
CONTEXT_DEBUG_REGISTERS
)
{
amd64_thread_data
()
->
dr0
=
context
->
Dr0
;
amd64_thread_data
()
->
dr1
=
context
->
Dr1
;
amd64_thread_data
()
->
dr2
=
context
->
Dr2
;
amd64_thread_data
()
->
dr3
=
context
->
Dr3
;
amd64_thread_data
()
->
dr6
=
context
->
Dr6
;
amd64_thread_data
()
->
dr7
=
context
->
Dr7
;
}
if
(
flags
&
CONTEXT_FULL
)
{
if
(
!
(
flags
&
CONTEXT_CONTROL
))
FIXME
(
"setting partial context (%x) not supported
\n
"
,
flags
);
else
set_full_cpu_context
(
context
);
}
}
/***********************************************************************
* context_to_server
...
...
@@ -247,6 +353,35 @@ NTSTATUS context_from_server( CONTEXT *to, const context_t *from )
}
/***********************************************************************
* NtSetContextThread (NTDLL.@)
* ZwSetContextThread (NTDLL.@)
*/
NTSTATUS
WINAPI
NtSetContextThread
(
HANDLE
handle
,
const
CONTEXT
*
context
)
{
NTSTATUS
ret
=
STATUS_SUCCESS
;
BOOL
self
=
(
handle
==
GetCurrentThread
());
/* debug registers require a server call */
if
(
self
&&
(
context
->
ContextFlags
&
(
CONTEXT_DEBUG_REGISTERS
&
~
CONTEXT_AMD64
)))
self
=
(
amd64_thread_data
()
->
dr0
==
context
->
Dr0
&&
amd64_thread_data
()
->
dr1
==
context
->
Dr1
&&
amd64_thread_data
()
->
dr2
==
context
->
Dr2
&&
amd64_thread_data
()
->
dr3
==
context
->
Dr3
&&
amd64_thread_data
()
->
dr6
==
context
->
Dr6
&&
amd64_thread_data
()
->
dr7
==
context
->
Dr7
);
if
(
!
self
)
{
context_t
server_context
;
context_to_server
(
&
server_context
,
context
);
ret
=
set_thread_context
(
handle
,
&
server_context
,
&
self
);
}
if
(
self
&&
ret
==
STATUS_SUCCESS
)
set_cpu_context
(
context
);
return
ret
;
}
/**********************************************************************
* get_thread_ldt_entry
*/
...
...
dlls/ntdll/unix/thread.c
View file @
ac90898f
...
...
@@ -148,3 +148,23 @@ void CDECL exit_process( int status )
pthread_sigmask
(
SIG_BLOCK
,
&
server_block_set
,
NULL
);
signal_exit_thread
(
get_unix_exit_code
(
status
),
exit
);
}
/***********************************************************************
* set_thread_context
*/
NTSTATUS
set_thread_context
(
HANDLE
handle
,
const
context_t
*
context
,
BOOL
*
self
)
{
NTSTATUS
ret
;
SERVER_START_REQ
(
set_thread_context
)
{
req
->
handle
=
wine_server_obj_handle
(
handle
);
wine_server_add_data
(
req
,
context
,
sizeof
(
*
context
)
);
ret
=
wine_server_call
(
req
);
*
self
=
reply
->
self
;
}
SERVER_END_REQ
;
return
ret
;
}
dlls/ntdll/unix/unix_private.h
View file @
ac90898f
...
...
@@ -103,6 +103,7 @@ extern void start_server( BOOL debug ) DECLSPEC_HIDDEN;
extern
NTSTATUS
context_to_server
(
context_t
*
to
,
const
CONTEXT
*
from
)
DECLSPEC_HIDDEN
;
extern
NTSTATUS
context_from_server
(
CONTEXT
*
to
,
const
context_t
*
from
)
DECLSPEC_HIDDEN
;
extern
NTSTATUS
set_thread_context
(
HANDLE
handle
,
const
context_t
*
context
,
BOOL
*
self
)
DECLSPEC_HIDDEN
;
extern
void
signal_init_threading
(
void
)
DECLSPEC_HIDDEN
;
extern
NTSTATUS
signal_alloc_thread
(
TEB
*
teb
)
DECLSPEC_HIDDEN
;
...
...
dlls/ntdll/unixlib.h
View file @
ac90898f
...
...
@@ -27,7 +27,7 @@
struct
ldt_copy
;
/* increment this when you change the function table */
#define NTDLL_UNIXLIB_VERSION 1
3
#define NTDLL_UNIXLIB_VERSION 1
4
struct
unix_funcs
{
...
...
@@ -37,6 +37,7 @@ struct unix_funcs
NTSTATUS
(
WINAPI
*
NtDuplicateObject
)(
HANDLE
source_process
,
HANDLE
source
,
HANDLE
dest_process
,
HANDLE
*
dest
,
ACCESS_MASK
access
,
ULONG
attributes
,
ULONG
options
);
NTSTATUS
(
WINAPI
*
NtSetContextThread
)(
HANDLE
handle
,
const
CONTEXT
*
context
);
NTSTATUS
(
WINAPI
*
NtSetLdtEntries
)(
ULONG
sel1
,
LDT_ENTRY
entry1
,
ULONG
sel2
,
LDT_ENTRY
entry2
);
/* environment functions */
...
...
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