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
7c32b2dd
Commit
7c32b2dd
authored
Jun 02, 2020
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ntdll: Move NtGetContextThread() implementation to the Unix library.
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
ac90898f
Hide whitespace changes
Inline
Side-by-side
Showing
16 changed files
with
660 additions
and
870 deletions
+660
-870
ntdll_misc.h
dlls/ntdll/ntdll_misc.h
+0
-1
signal_arm.c
dlls/ntdll/signal_arm.c
+0
-142
signal_arm64.c
dlls/ntdll/signal_arm64.c
+0
-130
signal_i386.c
dlls/ntdll/signal_i386.c
+11
-160
signal_powerpc.c
dlls/ntdll/signal_powerpc.c
+0
-241
signal_x86_64.c
dlls/ntdll/signal_x86_64.c
+0
-195
thread.c
dlls/ntdll/thread.c
+12
-0
loader.c
dlls/ntdll/unix/loader.c
+1
-0
signal_arm.c
dlls/ntdll/unix/signal_arm.c
+88
-0
signal_arm64.c
dlls/ntdll/unix/signal_arm64.c
+86
-0
signal_i386.c
dlls/ntdll/unix/signal_i386.c
+150
-0
signal_powerpc.c
dlls/ntdll/unix/signal_powerpc.c
+141
-0
signal_x86_64.c
dlls/ntdll/unix/signal_x86_64.c
+128
-0
thread.c
dlls/ntdll/unix/thread.c
+40
-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 @
7c32b2dd
...
...
@@ -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_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
;
extern
LONG
WINAPI
call_unhandled_exception_filter
(
PEXCEPTION_POINTERS
eptr
)
DECLSPEC_HIDDEN
;
...
...
dlls/ntdll/signal_arm.c
View file @
7c32b2dd
...
...
@@ -296,148 +296,6 @@ __ASM_GLOBAL_FUNC( set_cpu_context,
"pop {pc}"
)
/***********************************************************************
* get_server_context_flags
*
* Convert CPU-specific flags to generic server flags
*/
static
unsigned
int
get_server_context_flags
(
DWORD
flags
)
{
unsigned
int
ret
=
0
;
flags
&=
~
CONTEXT_ARM
;
/* get rid of CPU id */
if
(
flags
&
CONTEXT_CONTROL
)
ret
|=
SERVER_CTX_CONTROL
;
if
(
flags
&
CONTEXT_INTEGER
)
ret
|=
SERVER_CTX_INTEGER
;
if
(
flags
&
CONTEXT_FLOATING_POINT
)
ret
|=
SERVER_CTX_FLOATING_POINT
;
if
(
flags
&
CONTEXT_DEBUG_REGISTERS
)
ret
|=
SERVER_CTX_DEBUG_REGISTERS
;
return
ret
;
}
/***********************************************************************
* copy_context
*
* Copy a register context according to the flags.
*/
static
void
copy_context
(
CONTEXT
*
to
,
const
CONTEXT
*
from
,
DWORD
flags
)
{
flags
&=
~
CONTEXT_ARM
;
/* get rid of CPU id */
if
(
flags
&
CONTEXT_CONTROL
)
{
to
->
Sp
=
from
->
Sp
;
to
->
Lr
=
from
->
Lr
;
to
->
Pc
=
from
->
Pc
;
to
->
Cpsr
=
from
->
Cpsr
;
}
if
(
flags
&
CONTEXT_INTEGER
)
{
to
->
R0
=
from
->
R0
;
to
->
R1
=
from
->
R1
;
to
->
R2
=
from
->
R2
;
to
->
R3
=
from
->
R3
;
to
->
R4
=
from
->
R4
;
to
->
R5
=
from
->
R5
;
to
->
R6
=
from
->
R6
;
to
->
R7
=
from
->
R7
;
to
->
R8
=
from
->
R8
;
to
->
R9
=
from
->
R9
;
to
->
R10
=
from
->
R10
;
to
->
R11
=
from
->
R11
;
to
->
R12
=
from
->
R12
;
}
if
(
flags
&
CONTEXT_FLOATING_POINT
)
{
to
->
Fpscr
=
from
->
Fpscr
;
memcpy
(
to
->
u
.
D
,
from
->
u
.
D
,
sizeof
(
to
->
u
.
D
)
);
}
}
/***********************************************************************
* context_from_server
*
* Convert a register context from the server format.
*/
NTSTATUS
context_from_server
(
CONTEXT
*
to
,
const
context_t
*
from
)
{
DWORD
i
;
if
(
from
->
cpu
!=
CPU_ARM
)
return
STATUS_INVALID_PARAMETER
;
to
->
ContextFlags
=
CONTEXT_ARM
;
if
(
from
->
flags
&
SERVER_CTX_CONTROL
)
{
to
->
ContextFlags
|=
CONTEXT_CONTROL
;
to
->
Sp
=
from
->
ctl
.
arm_regs
.
sp
;
to
->
Lr
=
from
->
ctl
.
arm_regs
.
lr
;
to
->
Pc
=
from
->
ctl
.
arm_regs
.
pc
;
to
->
Cpsr
=
from
->
ctl
.
arm_regs
.
cpsr
;
}
if
(
from
->
flags
&
SERVER_CTX_INTEGER
)
{
to
->
ContextFlags
|=
CONTEXT_INTEGER
;
to
->
R0
=
from
->
integer
.
arm_regs
.
r
[
0
];
to
->
R1
=
from
->
integer
.
arm_regs
.
r
[
1
];
to
->
R2
=
from
->
integer
.
arm_regs
.
r
[
2
];
to
->
R3
=
from
->
integer
.
arm_regs
.
r
[
3
];
to
->
R4
=
from
->
integer
.
arm_regs
.
r
[
4
];
to
->
R5
=
from
->
integer
.
arm_regs
.
r
[
5
];
to
->
R6
=
from
->
integer
.
arm_regs
.
r
[
6
];
to
->
R7
=
from
->
integer
.
arm_regs
.
r
[
7
];
to
->
R8
=
from
->
integer
.
arm_regs
.
r
[
8
];
to
->
R9
=
from
->
integer
.
arm_regs
.
r
[
9
];
to
->
R10
=
from
->
integer
.
arm_regs
.
r
[
10
];
to
->
R11
=
from
->
integer
.
arm_regs
.
r
[
11
];
to
->
R12
=
from
->
integer
.
arm_regs
.
r
[
12
];
}
if
(
from
->
flags
&
SERVER_CTX_FLOATING_POINT
)
{
to
->
ContextFlags
|=
CONTEXT_FLOATING_POINT
;
for
(
i
=
0
;
i
<
32
;
i
++
)
to
->
u
.
D
[
i
]
=
from
->
fp
.
arm_regs
.
d
[
i
];
to
->
Fpscr
=
from
->
fp
.
arm_regs
.
fpscr
;
}
if
(
from
->
flags
&
SERVER_CTX_DEBUG_REGISTERS
)
{
to
->
ContextFlags
|=
CONTEXT_DEBUG_REGISTERS
;
for
(
i
=
0
;
i
<
ARM_MAX_BREAKPOINTS
;
i
++
)
to
->
Bvr
[
i
]
=
from
->
debug
.
arm_regs
.
bvr
[
i
];
for
(
i
=
0
;
i
<
ARM_MAX_BREAKPOINTS
;
i
++
)
to
->
Bcr
[
i
]
=
from
->
debug
.
arm_regs
.
bcr
[
i
];
for
(
i
=
0
;
i
<
ARM_MAX_WATCHPOINTS
;
i
++
)
to
->
Wvr
[
i
]
=
from
->
debug
.
arm_regs
.
wvr
[
i
];
for
(
i
=
0
;
i
<
ARM_MAX_WATCHPOINTS
;
i
++
)
to
->
Wcr
[
i
]
=
from
->
debug
.
arm_regs
.
wcr
[
i
];
}
return
STATUS_SUCCESS
;
}
/***********************************************************************
* NtGetContextThread (NTDLL.@)
* ZwGetContextThread (NTDLL.@)
*/
NTSTATUS
WINAPI
NtGetContextThread
(
HANDLE
handle
,
CONTEXT
*
context
)
{
NTSTATUS
ret
;
DWORD
needed_flags
=
context
->
ContextFlags
;
BOOL
self
=
(
handle
==
GetCurrentThread
());
if
(
!
self
)
{
context_t
server_context
;
unsigned
int
server_flags
=
get_server_context_flags
(
context
->
ContextFlags
);
if
((
ret
=
get_thread_context
(
handle
,
&
server_context
,
server_flags
,
&
self
)))
return
ret
;
if
((
ret
=
context_from_server
(
context
,
&
server_context
)))
return
ret
;
needed_flags
&=
~
context
->
ContextFlags
;
}
if
(
self
&&
needed_flags
)
{
CONTEXT
ctx
;
RtlCaptureContext
(
&
ctx
);
copy_context
(
context
,
&
ctx
,
ctx
.
ContextFlags
&
needed_flags
);
context
->
ContextFlags
|=
ctx
.
ContextFlags
&
needed_flags
;
}
return
STATUS_SUCCESS
;
}
extern
void
raise_func_trampoline_thumb
(
EXCEPTION_RECORD
*
rec
,
CONTEXT
*
context
,
raise_func
func
);
__ASM_GLOBAL_FUNC
(
raise_func_trampoline_thumb
,
".thumb
\n\t
"
...
...
dlls/ntdll/signal_arm64.c
View file @
7c32b2dd
...
...
@@ -308,136 +308,6 @@ static void set_cpu_context( const CONTEXT *context )
raise
(
SIGUSR2
);
}
/***********************************************************************
* get_server_context_flags
*
* Convert CPU-specific flags to generic server flags
*/
static
unsigned
int
get_server_context_flags
(
DWORD
flags
)
{
unsigned
int
ret
=
0
;
flags
&=
~
CONTEXT_ARM64
;
/* get rid of CPU id */
if
(
flags
&
CONTEXT_CONTROL
)
ret
|=
SERVER_CTX_CONTROL
;
if
(
flags
&
CONTEXT_INTEGER
)
ret
|=
SERVER_CTX_INTEGER
;
if
(
flags
&
CONTEXT_FLOATING_POINT
)
ret
|=
SERVER_CTX_FLOATING_POINT
;
if
(
flags
&
CONTEXT_DEBUG_REGISTERS
)
ret
|=
SERVER_CTX_DEBUG_REGISTERS
;
return
ret
;
}
/***********************************************************************
* copy_context
*
* Copy a register context according to the flags.
*/
static
void
copy_context
(
CONTEXT
*
to
,
const
CONTEXT
*
from
,
DWORD
flags
)
{
flags
&=
~
CONTEXT_ARM64
;
/* get rid of CPU id */
if
(
flags
&
CONTEXT_CONTROL
)
{
to
->
u
.
s
.
Fp
=
from
->
u
.
s
.
Fp
;
to
->
u
.
s
.
Lr
=
from
->
u
.
s
.
Lr
;
to
->
Sp
=
from
->
Sp
;
to
->
Pc
=
from
->
Pc
;
to
->
Cpsr
=
from
->
Cpsr
;
}
if
(
flags
&
CONTEXT_INTEGER
)
{
memcpy
(
to
->
u
.
X
,
from
->
u
.
X
,
sizeof
(
to
->
u
.
X
)
);
}
if
(
flags
&
CONTEXT_FLOATING_POINT
)
{
memcpy
(
to
->
V
,
from
->
V
,
sizeof
(
to
->
V
)
);
to
->
Fpcr
=
from
->
Fpcr
;
to
->
Fpsr
=
from
->
Fpsr
;
}
if
(
flags
&
CONTEXT_DEBUG_REGISTERS
)
{
memcpy
(
to
->
Bcr
,
from
->
Bcr
,
sizeof
(
to
->
Bcr
)
);
memcpy
(
to
->
Bvr
,
from
->
Bvr
,
sizeof
(
to
->
Bvr
)
);
memcpy
(
to
->
Wcr
,
from
->
Wcr
,
sizeof
(
to
->
Wcr
)
);
memcpy
(
to
->
Wvr
,
from
->
Wvr
,
sizeof
(
to
->
Wvr
)
);
}
}
/***********************************************************************
* context_from_server
*
* Convert a register context from the server format.
*/
NTSTATUS
context_from_server
(
CONTEXT
*
to
,
const
context_t
*
from
)
{
DWORD
i
;
if
(
from
->
cpu
!=
CPU_ARM64
)
return
STATUS_INVALID_PARAMETER
;
to
->
ContextFlags
=
CONTEXT_ARM64
;
if
(
from
->
flags
&
SERVER_CTX_CONTROL
)
{
to
->
ContextFlags
|=
CONTEXT_CONTROL
;
to
->
u
.
s
.
Fp
=
from
->
integer
.
arm64_regs
.
x
[
29
];
to
->
u
.
s
.
Lr
=
from
->
integer
.
arm64_regs
.
x
[
30
];
to
->
Sp
=
from
->
ctl
.
arm64_regs
.
sp
;
to
->
Pc
=
from
->
ctl
.
arm64_regs
.
pc
;
to
->
Cpsr
=
from
->
ctl
.
arm64_regs
.
pstate
;
}
if
(
from
->
flags
&
SERVER_CTX_INTEGER
)
{
to
->
ContextFlags
|=
CONTEXT_INTEGER
;
for
(
i
=
0
;
i
<=
28
;
i
++
)
to
->
u
.
X
[
i
]
=
from
->
integer
.
arm64_regs
.
x
[
i
];
}
if
(
from
->
flags
&
SERVER_CTX_FLOATING_POINT
)
{
to
->
ContextFlags
|=
CONTEXT_FLOATING_POINT
;
for
(
i
=
0
;
i
<
32
;
i
++
)
{
to
->
V
[
i
].
s
.
Low
=
from
->
fp
.
arm64_regs
.
q
[
i
].
low
;
to
->
V
[
i
].
s
.
High
=
from
->
fp
.
arm64_regs
.
q
[
i
].
high
;
}
to
->
Fpcr
=
from
->
fp
.
arm64_regs
.
fpcr
;
to
->
Fpsr
=
from
->
fp
.
arm64_regs
.
fpsr
;
}
if
(
from
->
flags
&
SERVER_CTX_DEBUG_REGISTERS
)
{
to
->
ContextFlags
|=
CONTEXT_DEBUG_REGISTERS
;
for
(
i
=
0
;
i
<
ARM64_MAX_BREAKPOINTS
;
i
++
)
to
->
Bcr
[
i
]
=
from
->
debug
.
arm64_regs
.
bcr
[
i
];
for
(
i
=
0
;
i
<
ARM64_MAX_BREAKPOINTS
;
i
++
)
to
->
Bvr
[
i
]
=
from
->
debug
.
arm64_regs
.
bvr
[
i
];
for
(
i
=
0
;
i
<
ARM64_MAX_WATCHPOINTS
;
i
++
)
to
->
Wcr
[
i
]
=
from
->
debug
.
arm64_regs
.
wcr
[
i
];
for
(
i
=
0
;
i
<
ARM64_MAX_WATCHPOINTS
;
i
++
)
to
->
Wvr
[
i
]
=
from
->
debug
.
arm64_regs
.
wvr
[
i
];
}
return
STATUS_SUCCESS
;
}
/***********************************************************************
* NtGetContextThread (NTDLL.@)
* ZwGetContextThread (NTDLL.@)
*/
NTSTATUS
WINAPI
NtGetContextThread
(
HANDLE
handle
,
CONTEXT
*
context
)
{
NTSTATUS
ret
;
DWORD
needed_flags
=
context
->
ContextFlags
;
BOOL
self
=
(
handle
==
GetCurrentThread
());
if
(
!
self
)
{
context_t
server_context
;
unsigned
int
server_flags
=
get_server_context_flags
(
context
->
ContextFlags
);
if
((
ret
=
get_thread_context
(
handle
,
&
server_context
,
server_flags
,
&
self
)))
return
ret
;
if
((
ret
=
context_from_server
(
context
,
&
server_context
)))
return
ret
;
needed_flags
&=
~
context
->
ContextFlags
;
}
if
(
self
&&
needed_flags
)
{
CONTEXT
ctx
;
RtlCaptureContext
(
&
ctx
);
copy_context
(
context
,
&
ctx
,
ctx
.
ContextFlags
&
needed_flags
);
context
->
ContextFlags
|=
ctx
.
ContextFlags
&
needed_flags
;
}
return
STATUS_SUCCESS
;
}
/***********************************************************************
* libunwind_virtual_unwind
...
...
dlls/ntdll/signal_i386.c
View file @
7c32b2dd
...
...
@@ -1252,96 +1252,6 @@ void DECLSPEC_HIDDEN set_cpu_context( const CONTEXT *context )
/***********************************************************************
* get_server_context_flags
*
* Convert CPU-specific flags to generic server flags
*/
static
unsigned
int
get_server_context_flags
(
DWORD
flags
)
{
unsigned
int
ret
=
0
;
flags
&=
~
CONTEXT_i386
;
/* get rid of CPU id */
if
(
flags
&
CONTEXT_CONTROL
)
ret
|=
SERVER_CTX_CONTROL
;
if
(
flags
&
CONTEXT_INTEGER
)
ret
|=
SERVER_CTX_INTEGER
;
if
(
flags
&
CONTEXT_SEGMENTS
)
ret
|=
SERVER_CTX_SEGMENTS
;
if
(
flags
&
CONTEXT_FLOATING_POINT
)
ret
|=
SERVER_CTX_FLOATING_POINT
;
if
(
flags
&
CONTEXT_DEBUG_REGISTERS
)
ret
|=
SERVER_CTX_DEBUG_REGISTERS
;
if
(
flags
&
CONTEXT_EXTENDED_REGISTERS
)
ret
|=
SERVER_CTX_EXTENDED_REGISTERS
;
return
ret
;
}
/***********************************************************************
* context_from_server
*
* Convert a register context from the server format.
*/
NTSTATUS
context_from_server
(
CONTEXT
*
to
,
const
context_t
*
from
)
{
if
(
from
->
cpu
!=
CPU_x86
)
return
STATUS_INVALID_PARAMETER
;
to
->
ContextFlags
=
CONTEXT_i386
;
if
(
from
->
flags
&
SERVER_CTX_CONTROL
)
{
to
->
ContextFlags
|=
CONTEXT_CONTROL
;
to
->
Ebp
=
from
->
ctl
.
i386_regs
.
ebp
;
to
->
Esp
=
from
->
ctl
.
i386_regs
.
esp
;
to
->
Eip
=
from
->
ctl
.
i386_regs
.
eip
;
to
->
SegCs
=
from
->
ctl
.
i386_regs
.
cs
;
to
->
SegSs
=
from
->
ctl
.
i386_regs
.
ss
;
to
->
EFlags
=
from
->
ctl
.
i386_regs
.
eflags
;
}
if
(
from
->
flags
&
SERVER_CTX_INTEGER
)
{
to
->
ContextFlags
|=
CONTEXT_INTEGER
;
to
->
Eax
=
from
->
integer
.
i386_regs
.
eax
;
to
->
Ebx
=
from
->
integer
.
i386_regs
.
ebx
;
to
->
Ecx
=
from
->
integer
.
i386_regs
.
ecx
;
to
->
Edx
=
from
->
integer
.
i386_regs
.
edx
;
to
->
Esi
=
from
->
integer
.
i386_regs
.
esi
;
to
->
Edi
=
from
->
integer
.
i386_regs
.
edi
;
}
if
(
from
->
flags
&
SERVER_CTX_SEGMENTS
)
{
to
->
ContextFlags
|=
CONTEXT_SEGMENTS
;
to
->
SegDs
=
from
->
seg
.
i386_regs
.
ds
;
to
->
SegEs
=
from
->
seg
.
i386_regs
.
es
;
to
->
SegFs
=
from
->
seg
.
i386_regs
.
fs
;
to
->
SegGs
=
from
->
seg
.
i386_regs
.
gs
;
}
if
(
from
->
flags
&
SERVER_CTX_FLOATING_POINT
)
{
to
->
ContextFlags
|=
CONTEXT_FLOATING_POINT
;
to
->
FloatSave
.
ControlWord
=
from
->
fp
.
i386_regs
.
ctrl
;
to
->
FloatSave
.
StatusWord
=
from
->
fp
.
i386_regs
.
status
;
to
->
FloatSave
.
TagWord
=
from
->
fp
.
i386_regs
.
tag
;
to
->
FloatSave
.
ErrorOffset
=
from
->
fp
.
i386_regs
.
err_off
;
to
->
FloatSave
.
ErrorSelector
=
from
->
fp
.
i386_regs
.
err_sel
;
to
->
FloatSave
.
DataOffset
=
from
->
fp
.
i386_regs
.
data_off
;
to
->
FloatSave
.
DataSelector
=
from
->
fp
.
i386_regs
.
data_sel
;
to
->
FloatSave
.
Cr0NpxState
=
from
->
fp
.
i386_regs
.
cr0npx
;
memcpy
(
to
->
FloatSave
.
RegisterArea
,
from
->
fp
.
i386_regs
.
regs
,
sizeof
(
to
->
FloatSave
.
RegisterArea
)
);
}
if
(
from
->
flags
&
SERVER_CTX_DEBUG_REGISTERS
)
{
to
->
ContextFlags
|=
CONTEXT_DEBUG_REGISTERS
;
to
->
Dr0
=
from
->
debug
.
i386_regs
.
dr0
;
to
->
Dr1
=
from
->
debug
.
i386_regs
.
dr1
;
to
->
Dr2
=
from
->
debug
.
i386_regs
.
dr2
;
to
->
Dr3
=
from
->
debug
.
i386_regs
.
dr3
;
to
->
Dr6
=
from
->
debug
.
i386_regs
.
dr6
;
to
->
Dr7
=
from
->
debug
.
i386_regs
.
dr7
;
}
if
(
from
->
flags
&
SERVER_CTX_EXTENDED_REGISTERS
)
{
to
->
ContextFlags
|=
CONTEXT_EXTENDED_REGISTERS
;
memcpy
(
to
->
ExtendedRegisters
,
from
->
ext
.
i386_regs
,
sizeof
(
to
->
ExtendedRegisters
)
);
}
return
STATUS_SUCCESS
;
}
/***********************************************************************
* NtGetContextThread (NTDLL.@)
* ZwGetContextThread (NTDLL.@)
*
...
...
@@ -1352,82 +1262,23 @@ NTSTATUS CDECL DECLSPEC_HIDDEN __regs_NtGetContextThread( DWORD edi, DWORD esi,
DWORD
ebp
,
DWORD
retaddr
,
HANDLE
handle
,
CONTEXT
*
context
)
{
NTSTATUS
ret
;
DWORD
needed_flags
=
context
->
ContextFlags
&
~
CONTEXT_i386
;
BOOL
self
=
(
handle
==
GetCurrentThread
());
/* debug registers require a server call */
if
(
needed_flags
&
CONTEXT_DEBUG_REGISTERS
)
self
=
FALSE
;
if
(
!
self
)
/* preset the registers that we got from the asm wrapper */
if
(
needed_flags
&
CONTEXT_INTEGER
)
{
context_t
server_context
;
unsigned
int
server_flags
=
get_server_context_flags
(
context
->
ContextFlags
);
if
((
ret
=
get_thread_context
(
handle
,
&
server_context
,
server_flags
,
&
self
)))
return
ret
;
if
((
ret
=
context_from_server
(
context
,
&
server_context
)))
return
ret
;
needed_flags
&=
~
context
->
ContextFlags
;
context
->
Ebx
=
ebx
;
context
->
Esi
=
esi
;
context
->
Edi
=
edi
;
}
if
(
self
)
if
(
needed_flags
&
CONTEXT_CONTROL
)
{
if
(
needed_flags
&
CONTEXT_INTEGER
)
{
context
->
Eax
=
0
;
context
->
Ebx
=
ebx
;
context
->
Ecx
=
0
;
context
->
Edx
=
0
;
context
->
Esi
=
esi
;
context
->
Edi
=
edi
;
context
->
ContextFlags
|=
CONTEXT_INTEGER
;
}
if
(
needed_flags
&
CONTEXT_CONTROL
)
{
context
->
Ebp
=
ebp
;
context
->
Esp
=
(
DWORD
)
&
retaddr
;
context
->
Eip
=
*
(
&
edi
-
1
);
context
->
SegCs
=
get_cs
();
context
->
SegSs
=
get_ds
();
context
->
EFlags
=
eflags
;
context
->
ContextFlags
|=
CONTEXT_CONTROL
;
}
if
(
needed_flags
&
CONTEXT_SEGMENTS
)
{
context
->
SegDs
=
get_ds
();
context
->
SegEs
=
get_ds
();
context
->
SegFs
=
get_fs
();
context
->
SegGs
=
get_gs
();
context
->
ContextFlags
|=
CONTEXT_SEGMENTS
;
}
if
(
needed_flags
&
CONTEXT_FLOATING_POINT
)
save_fpu
(
context
);
if
(
needed_flags
&
CONTEXT_EXTENDED_REGISTERS
)
save_fpux
(
context
);
/* FIXME: xstate */
/* update the cached version of the debug registers */
if
(
context
->
ContextFlags
&
(
CONTEXT_DEBUG_REGISTERS
&
~
CONTEXT_i386
))
{
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
;
}
context
->
Ebp
=
ebp
;
context
->
Esp
=
(
DWORD
)
&
retaddr
;
context
->
Eip
=
*
(
&
edi
-
1
);
context
->
EFlags
=
eflags
;
}
if
(
context
->
ContextFlags
&
(
CONTEXT_INTEGER
&
~
CONTEXT_i386
))
TRACE
(
"%p: eax=%08x ebx=%08x ecx=%08x edx=%08x esi=%08x edi=%08x
\n
"
,
handle
,
context
->
Eax
,
context
->
Ebx
,
context
->
Ecx
,
context
->
Edx
,
context
->
Esi
,
context
->
Edi
);
if
(
context
->
ContextFlags
&
(
CONTEXT_CONTROL
&
~
CONTEXT_i386
))
TRACE
(
"%p: ebp=%08x esp=%08x eip=%08x cs=%04x ss=%04x flags=%08x
\n
"
,
handle
,
context
->
Ebp
,
context
->
Esp
,
context
->
Eip
,
context
->
SegCs
,
context
->
SegSs
,
context
->
EFlags
);
if
(
context
->
ContextFlags
&
(
CONTEXT_SEGMENTS
&
~
CONTEXT_i386
))
TRACE
(
"%p: ds=%04x es=%04x fs=%04x gs=%04x
\n
"
,
handle
,
context
->
SegDs
,
context
->
SegEs
,
context
->
SegFs
,
context
->
SegGs
);
if
(
context
->
ContextFlags
&
(
CONTEXT_DEBUG_REGISTERS
&
~
CONTEXT_i386
))
TRACE
(
"%p: dr0=%08x dr1=%08x dr2=%08x dr3=%08x dr6=%08x dr7=%08x
\n
"
,
handle
,
context
->
Dr0
,
context
->
Dr1
,
context
->
Dr2
,
context
->
Dr3
,
context
->
Dr6
,
context
->
Dr7
);
return
STATUS_SUCCESS
;
return
unix_funcs
->
NtGetContextThread
(
handle
,
context
);
}
__ASM_STDCALL_FUNC
(
NtGetContextThread
,
8
,
"pushl %ebp
\n\t
"
...
...
dlls/ntdll/signal_powerpc.c
View file @
7c32b2dd
...
...
@@ -260,247 +260,6 @@ void WINAPI RtlCaptureContext( CONTEXT *context )
}
/***********************************************************************
* get_server_context_flags
*
* Convert CPU-specific flags to generic server flags
*/
static
unsigned
int
get_server_context_flags
(
DWORD
flags
)
{
unsigned
int
ret
=
0
;
if
(
flags
&
CONTEXT_CONTROL
)
ret
|=
SERVER_CTX_CONTROL
;
if
(
flags
&
CONTEXT_INTEGER
)
ret
|=
SERVER_CTX_INTEGER
;
if
(
flags
&
CONTEXT_FLOATING_POINT
)
ret
|=
SERVER_CTX_FLOATING_POINT
;
if
(
flags
&
CONTEXT_DEBUG_REGISTERS
)
ret
|=
SERVER_CTX_DEBUG_REGISTERS
;
return
ret
;
}
/***********************************************************************
* copy_context
*
* Copy a register context according to the flags.
*/
static
void
copy_context
(
CONTEXT
*
to
,
const
CONTEXT
*
from
,
DWORD
flags
)
{
if
(
flags
&
CONTEXT_CONTROL
)
{
to
->
Msr
=
from
->
Msr
;
to
->
Ctr
=
from
->
Ctr
;
to
->
Iar
=
from
->
Iar
;
to
->
Lr
=
from
->
Lr
;
to
->
Dar
=
from
->
Dar
;
to
->
Dsisr
=
from
->
Dsisr
;
to
->
Trap
=
from
->
Trap
;
}
if
(
flags
&
CONTEXT_INTEGER
)
{
to
->
Gpr0
=
from
->
Gpr0
;
to
->
Gpr1
=
from
->
Gpr1
;
to
->
Gpr2
=
from
->
Gpr2
;
to
->
Gpr3
=
from
->
Gpr3
;
to
->
Gpr4
=
from
->
Gpr4
;
to
->
Gpr5
=
from
->
Gpr5
;
to
->
Gpr6
=
from
->
Gpr6
;
to
->
Gpr7
=
from
->
Gpr7
;
to
->
Gpr8
=
from
->
Gpr8
;
to
->
Gpr9
=
from
->
Gpr9
;
to
->
Gpr10
=
from
->
Gpr10
;
to
->
Gpr11
=
from
->
Gpr11
;
to
->
Gpr12
=
from
->
Gpr12
;
to
->
Gpr13
=
from
->
Gpr13
;
to
->
Gpr14
=
from
->
Gpr14
;
to
->
Gpr15
=
from
->
Gpr15
;
to
->
Gpr16
=
from
->
Gpr16
;
to
->
Gpr17
=
from
->
Gpr17
;
to
->
Gpr18
=
from
->
Gpr18
;
to
->
Gpr19
=
from
->
Gpr19
;
to
->
Gpr20
=
from
->
Gpr20
;
to
->
Gpr21
=
from
->
Gpr21
;
to
->
Gpr22
=
from
->
Gpr22
;
to
->
Gpr23
=
from
->
Gpr23
;
to
->
Gpr24
=
from
->
Gpr24
;
to
->
Gpr25
=
from
->
Gpr25
;
to
->
Gpr26
=
from
->
Gpr26
;
to
->
Gpr27
=
from
->
Gpr27
;
to
->
Gpr28
=
from
->
Gpr28
;
to
->
Gpr29
=
from
->
Gpr29
;
to
->
Gpr30
=
from
->
Gpr30
;
to
->
Gpr31
=
from
->
Gpr31
;
to
->
Xer
=
from
->
Xer
;
to
->
Cr
=
from
->
Cr
;
}
if
(
flags
&
CONTEXT_FLOATING_POINT
)
{
to
->
Fpr0
=
from
->
Fpr0
;
to
->
Fpr1
=
from
->
Fpr1
;
to
->
Fpr2
=
from
->
Fpr2
;
to
->
Fpr3
=
from
->
Fpr3
;
to
->
Fpr4
=
from
->
Fpr4
;
to
->
Fpr5
=
from
->
Fpr5
;
to
->
Fpr6
=
from
->
Fpr6
;
to
->
Fpr7
=
from
->
Fpr7
;
to
->
Fpr8
=
from
->
Fpr8
;
to
->
Fpr9
=
from
->
Fpr9
;
to
->
Fpr10
=
from
->
Fpr10
;
to
->
Fpr11
=
from
->
Fpr11
;
to
->
Fpr12
=
from
->
Fpr12
;
to
->
Fpr13
=
from
->
Fpr13
;
to
->
Fpr14
=
from
->
Fpr14
;
to
->
Fpr15
=
from
->
Fpr15
;
to
->
Fpr16
=
from
->
Fpr16
;
to
->
Fpr17
=
from
->
Fpr17
;
to
->
Fpr18
=
from
->
Fpr18
;
to
->
Fpr19
=
from
->
Fpr19
;
to
->
Fpr20
=
from
->
Fpr20
;
to
->
Fpr21
=
from
->
Fpr21
;
to
->
Fpr22
=
from
->
Fpr22
;
to
->
Fpr23
=
from
->
Fpr23
;
to
->
Fpr24
=
from
->
Fpr24
;
to
->
Fpr25
=
from
->
Fpr25
;
to
->
Fpr26
=
from
->
Fpr26
;
to
->
Fpr27
=
from
->
Fpr27
;
to
->
Fpr28
=
from
->
Fpr28
;
to
->
Fpr29
=
from
->
Fpr29
;
to
->
Fpr30
=
from
->
Fpr30
;
to
->
Fpr31
=
from
->
Fpr31
;
to
->
Fpscr
=
from
->
Fpscr
;
}
}
/***********************************************************************
* context_from_server
*
* Convert a register context from the server format.
*/
NTSTATUS
context_from_server
(
CONTEXT
*
to
,
const
context_t
*
from
)
{
if
(
from
->
cpu
!=
CPU_POWERPC
)
return
STATUS_INVALID_PARAMETER
;
to
->
ContextFlags
=
0
;
/* no CPU id? */
if
(
from
->
flags
&
SERVER_CTX_CONTROL
)
{
to
->
ContextFlags
|=
CONTEXT_CONTROL
;
to
->
Msr
=
from
->
ctl
.
powerpc_regs
.
msr
;
to
->
Ctr
=
from
->
ctl
.
powerpc_regs
.
ctr
;
to
->
Iar
=
from
->
ctl
.
powerpc_regs
.
iar
;
to
->
Lr
=
from
->
ctl
.
powerpc_regs
.
lr
;
to
->
Dar
=
from
->
ctl
.
powerpc_regs
.
dar
;
to
->
Dsisr
=
from
->
ctl
.
powerpc_regs
.
dsisr
;
to
->
Trap
=
from
->
ctl
.
powerpc_regs
.
trap
;
}
if
(
from
->
flags
&
SERVER_CTX_INTEGER
)
{
to
->
ContextFlags
|=
CONTEXT_INTEGER
;
to
->
Gpr0
=
from
->
integer
.
powerpc_regs
.
gpr
[
0
];
to
->
Gpr1
=
from
->
integer
.
powerpc_regs
.
gpr
[
1
];
to
->
Gpr2
=
from
->
integer
.
powerpc_regs
.
gpr
[
2
];
to
->
Gpr3
=
from
->
integer
.
powerpc_regs
.
gpr
[
3
];
to
->
Gpr4
=
from
->
integer
.
powerpc_regs
.
gpr
[
4
];
to
->
Gpr5
=
from
->
integer
.
powerpc_regs
.
gpr
[
5
];
to
->
Gpr6
=
from
->
integer
.
powerpc_regs
.
gpr
[
6
];
to
->
Gpr7
=
from
->
integer
.
powerpc_regs
.
gpr
[
7
];
to
->
Gpr8
=
from
->
integer
.
powerpc_regs
.
gpr
[
8
];
to
->
Gpr9
=
from
->
integer
.
powerpc_regs
.
gpr
[
9
];
to
->
Gpr10
=
from
->
integer
.
powerpc_regs
.
gpr
[
10
];
to
->
Gpr11
=
from
->
integer
.
powerpc_regs
.
gpr
[
11
];
to
->
Gpr12
=
from
->
integer
.
powerpc_regs
.
gpr
[
12
];
to
->
Gpr13
=
from
->
integer
.
powerpc_regs
.
gpr
[
13
];
to
->
Gpr14
=
from
->
integer
.
powerpc_regs
.
gpr
[
14
];
to
->
Gpr15
=
from
->
integer
.
powerpc_regs
.
gpr
[
15
];
to
->
Gpr16
=
from
->
integer
.
powerpc_regs
.
gpr
[
16
];
to
->
Gpr17
=
from
->
integer
.
powerpc_regs
.
gpr
[
17
];
to
->
Gpr18
=
from
->
integer
.
powerpc_regs
.
gpr
[
18
];
to
->
Gpr19
=
from
->
integer
.
powerpc_regs
.
gpr
[
19
];
to
->
Gpr20
=
from
->
integer
.
powerpc_regs
.
gpr
[
20
];
to
->
Gpr21
=
from
->
integer
.
powerpc_regs
.
gpr
[
21
];
to
->
Gpr22
=
from
->
integer
.
powerpc_regs
.
gpr
[
22
];
to
->
Gpr23
=
from
->
integer
.
powerpc_regs
.
gpr
[
23
];
to
->
Gpr24
=
from
->
integer
.
powerpc_regs
.
gpr
[
24
];
to
->
Gpr25
=
from
->
integer
.
powerpc_regs
.
gpr
[
25
];
to
->
Gpr26
=
from
->
integer
.
powerpc_regs
.
gpr
[
26
];
to
->
Gpr27
=
from
->
integer
.
powerpc_regs
.
gpr
[
27
];
to
->
Gpr28
=
from
->
integer
.
powerpc_regs
.
gpr
[
28
];
to
->
Gpr29
=
from
->
integer
.
powerpc_regs
.
gpr
[
29
];
to
->
Gpr30
=
from
->
integer
.
powerpc_regs
.
gpr
[
30
];
to
->
Gpr31
=
from
->
integer
.
powerpc_regs
.
gpr
[
31
];
to
->
Xer
=
from
->
integer
.
powerpc_regs
.
xer
;
to
->
Cr
=
from
->
integer
.
powerpc_regs
.
cr
;
}
if
(
from
->
flags
&
SERVER_CTX_FLOATING_POINT
)
{
to
->
ContextFlags
|=
CONTEXT_FLOATING_POINT
;
to
->
Fpr0
=
from
->
fp
.
powerpc_regs
.
fpr
[
0
];
to
->
Fpr1
=
from
->
fp
.
powerpc_regs
.
fpr
[
1
];
to
->
Fpr2
=
from
->
fp
.
powerpc_regs
.
fpr
[
2
];
to
->
Fpr3
=
from
->
fp
.
powerpc_regs
.
fpr
[
3
];
to
->
Fpr4
=
from
->
fp
.
powerpc_regs
.
fpr
[
4
];
to
->
Fpr5
=
from
->
fp
.
powerpc_regs
.
fpr
[
5
];
to
->
Fpr6
=
from
->
fp
.
powerpc_regs
.
fpr
[
6
];
to
->
Fpr7
=
from
->
fp
.
powerpc_regs
.
fpr
[
7
];
to
->
Fpr8
=
from
->
fp
.
powerpc_regs
.
fpr
[
8
];
to
->
Fpr9
=
from
->
fp
.
powerpc_regs
.
fpr
[
9
];
to
->
Fpr10
=
from
->
fp
.
powerpc_regs
.
fpr
[
10
];
to
->
Fpr11
=
from
->
fp
.
powerpc_regs
.
fpr
[
11
];
to
->
Fpr12
=
from
->
fp
.
powerpc_regs
.
fpr
[
12
];
to
->
Fpr13
=
from
->
fp
.
powerpc_regs
.
fpr
[
13
];
to
->
Fpr14
=
from
->
fp
.
powerpc_regs
.
fpr
[
14
];
to
->
Fpr15
=
from
->
fp
.
powerpc_regs
.
fpr
[
15
];
to
->
Fpr16
=
from
->
fp
.
powerpc_regs
.
fpr
[
16
];
to
->
Fpr17
=
from
->
fp
.
powerpc_regs
.
fpr
[
17
];
to
->
Fpr18
=
from
->
fp
.
powerpc_regs
.
fpr
[
18
];
to
->
Fpr19
=
from
->
fp
.
powerpc_regs
.
fpr
[
19
];
to
->
Fpr20
=
from
->
fp
.
powerpc_regs
.
fpr
[
20
];
to
->
Fpr21
=
from
->
fp
.
powerpc_regs
.
fpr
[
21
];
to
->
Fpr22
=
from
->
fp
.
powerpc_regs
.
fpr
[
22
];
to
->
Fpr23
=
from
->
fp
.
powerpc_regs
.
fpr
[
23
];
to
->
Fpr24
=
from
->
fp
.
powerpc_regs
.
fpr
[
24
];
to
->
Fpr25
=
from
->
fp
.
powerpc_regs
.
fpr
[
25
];
to
->
Fpr26
=
from
->
fp
.
powerpc_regs
.
fpr
[
26
];
to
->
Fpr27
=
from
->
fp
.
powerpc_regs
.
fpr
[
27
];
to
->
Fpr28
=
from
->
fp
.
powerpc_regs
.
fpr
[
28
];
to
->
Fpr29
=
from
->
fp
.
powerpc_regs
.
fpr
[
29
];
to
->
Fpr30
=
from
->
fp
.
powerpc_regs
.
fpr
[
30
];
to
->
Fpr31
=
from
->
fp
.
powerpc_regs
.
fpr
[
31
];
to
->
Fpscr
=
from
->
fp
.
powerpc_regs
.
fpscr
;
}
return
STATUS_SUCCESS
;
}
/***********************************************************************
* NtGetContextThread (NTDLL.@)
* ZwGetContextThread (NTDLL.@)
*/
NTSTATUS
WINAPI
NtGetContextThread
(
HANDLE
handle
,
CONTEXT
*
context
)
{
NTSTATUS
ret
;
DWORD
needed_flags
=
context
->
ContextFlags
;
BOOL
self
=
(
handle
==
GetCurrentThread
());
if
(
!
self
)
{
context_t
server_context
;
unsigned
int
server_flags
=
get_server_context_flags
(
context
->
ContextFlags
);
if
((
ret
=
get_thread_context
(
handle
,
&
server_context
,
server_flags
,
&
self
)))
return
ret
;
if
((
ret
=
context_from_server
(
context
,
&
server_context
)))
return
ret
;
needed_flags
&=
~
context
->
ContextFlags
;
}
if
(
self
&&
needed_flags
)
{
CONTEXT
ctx
;
RtlCaptureContext
(
&
ctx
);
copy_context
(
context
,
&
ctx
,
ctx
.
ContextFlags
&
needed_flags
);
context
->
ContextFlags
|=
ctx
.
ContextFlags
&
needed_flags
;
}
return
STATUS_SUCCESS
;
}
/**********************************************************************
* call_stack_handlers
*
...
...
dlls/ntdll/signal_x86_64.c
View file @
7c32b2dd
...
...
@@ -1890,201 +1890,6 @@ void DECLSPEC_HIDDEN set_cpu_context( const CONTEXT *context )
/***********************************************************************
* get_server_context_flags
*
* Convert CPU-specific flags to generic server flags
*/
static
unsigned
int
get_server_context_flags
(
DWORD
flags
)
{
unsigned
int
ret
=
0
;
flags
&=
~
CONTEXT_AMD64
;
/* get rid of CPU id */
if
(
flags
&
CONTEXT_CONTROL
)
ret
|=
SERVER_CTX_CONTROL
;
if
(
flags
&
CONTEXT_INTEGER
)
ret
|=
SERVER_CTX_INTEGER
;
if
(
flags
&
CONTEXT_SEGMENTS
)
ret
|=
SERVER_CTX_SEGMENTS
;
if
(
flags
&
CONTEXT_FLOATING_POINT
)
ret
|=
SERVER_CTX_FLOATING_POINT
;
if
(
flags
&
CONTEXT_DEBUG_REGISTERS
)
ret
|=
SERVER_CTX_DEBUG_REGISTERS
;
return
ret
;
}
/***********************************************************************
* copy_context
*
* Copy a register context according to the flags.
*/
static
void
copy_context
(
CONTEXT
*
to
,
const
CONTEXT
*
from
,
DWORD
flags
)
{
flags
&=
~
CONTEXT_AMD64
;
/* get rid of CPU id */
if
(
flags
&
CONTEXT_CONTROL
)
{
to
->
Rbp
=
from
->
Rbp
;
to
->
Rip
=
from
->
Rip
;
to
->
Rsp
=
from
->
Rsp
;
to
->
SegCs
=
from
->
SegCs
;
to
->
SegSs
=
from
->
SegSs
;
to
->
EFlags
=
from
->
EFlags
;
}
if
(
flags
&
CONTEXT_INTEGER
)
{
to
->
Rax
=
from
->
Rax
;
to
->
Rcx
=
from
->
Rcx
;
to
->
Rdx
=
from
->
Rdx
;
to
->
Rbx
=
from
->
Rbx
;
to
->
Rsi
=
from
->
Rsi
;
to
->
Rdi
=
from
->
Rdi
;
to
->
R8
=
from
->
R8
;
to
->
R9
=
from
->
R9
;
to
->
R10
=
from
->
R10
;
to
->
R11
=
from
->
R11
;
to
->
R12
=
from
->
R12
;
to
->
R13
=
from
->
R13
;
to
->
R14
=
from
->
R14
;
to
->
R15
=
from
->
R15
;
}
if
(
flags
&
CONTEXT_SEGMENTS
)
{
to
->
SegDs
=
from
->
SegDs
;
to
->
SegEs
=
from
->
SegEs
;
to
->
SegFs
=
from
->
SegFs
;
to
->
SegGs
=
from
->
SegGs
;
}
if
(
flags
&
CONTEXT_FLOATING_POINT
)
{
to
->
MxCsr
=
from
->
MxCsr
;
to
->
u
.
FltSave
=
from
->
u
.
FltSave
;
}
if
(
flags
&
CONTEXT_DEBUG_REGISTERS
)
{
to
->
Dr0
=
from
->
Dr0
;
to
->
Dr1
=
from
->
Dr1
;
to
->
Dr2
=
from
->
Dr2
;
to
->
Dr3
=
from
->
Dr3
;
to
->
Dr6
=
from
->
Dr6
;
to
->
Dr7
=
from
->
Dr7
;
}
}
/***********************************************************************
* context_from_server
*
* Convert a register context from the server format.
*/
NTSTATUS
context_from_server
(
CONTEXT
*
to
,
const
context_t
*
from
)
{
if
(
from
->
cpu
!=
CPU_x86_64
)
return
STATUS_INVALID_PARAMETER
;
to
->
ContextFlags
=
CONTEXT_AMD64
;
if
(
from
->
flags
&
SERVER_CTX_CONTROL
)
{
to
->
ContextFlags
|=
CONTEXT_CONTROL
;
to
->
Rbp
=
from
->
ctl
.
x86_64_regs
.
rbp
;
to
->
Rip
=
from
->
ctl
.
x86_64_regs
.
rip
;
to
->
Rsp
=
from
->
ctl
.
x86_64_regs
.
rsp
;
to
->
SegCs
=
from
->
ctl
.
x86_64_regs
.
cs
;
to
->
SegSs
=
from
->
ctl
.
x86_64_regs
.
ss
;
to
->
EFlags
=
from
->
ctl
.
x86_64_regs
.
flags
;
}
if
(
from
->
flags
&
SERVER_CTX_INTEGER
)
{
to
->
ContextFlags
|=
CONTEXT_INTEGER
;
to
->
Rax
=
from
->
integer
.
x86_64_regs
.
rax
;
to
->
Rcx
=
from
->
integer
.
x86_64_regs
.
rcx
;
to
->
Rdx
=
from
->
integer
.
x86_64_regs
.
rdx
;
to
->
Rbx
=
from
->
integer
.
x86_64_regs
.
rbx
;
to
->
Rsi
=
from
->
integer
.
x86_64_regs
.
rsi
;
to
->
Rdi
=
from
->
integer
.
x86_64_regs
.
rdi
;
to
->
R8
=
from
->
integer
.
x86_64_regs
.
r8
;
to
->
R9
=
from
->
integer
.
x86_64_regs
.
r9
;
to
->
R10
=
from
->
integer
.
x86_64_regs
.
r10
;
to
->
R11
=
from
->
integer
.
x86_64_regs
.
r11
;
to
->
R12
=
from
->
integer
.
x86_64_regs
.
r12
;
to
->
R13
=
from
->
integer
.
x86_64_regs
.
r13
;
to
->
R14
=
from
->
integer
.
x86_64_regs
.
r14
;
to
->
R15
=
from
->
integer
.
x86_64_regs
.
r15
;
}
if
(
from
->
flags
&
SERVER_CTX_SEGMENTS
)
{
to
->
ContextFlags
|=
CONTEXT_SEGMENTS
;
to
->
SegDs
=
from
->
seg
.
x86_64_regs
.
ds
;
to
->
SegEs
=
from
->
seg
.
x86_64_regs
.
es
;
to
->
SegFs
=
from
->
seg
.
x86_64_regs
.
fs
;
to
->
SegGs
=
from
->
seg
.
x86_64_regs
.
gs
;
}
if
(
from
->
flags
&
SERVER_CTX_FLOATING_POINT
)
{
to
->
ContextFlags
|=
CONTEXT_FLOATING_POINT
;
memcpy
(
&
to
->
u
.
FltSave
,
from
->
fp
.
x86_64_regs
.
fpregs
,
sizeof
(
from
->
fp
.
x86_64_regs
.
fpregs
)
);
to
->
MxCsr
=
to
->
u
.
FltSave
.
MxCsr
;
}
if
(
from
->
flags
&
SERVER_CTX_DEBUG_REGISTERS
)
{
to
->
ContextFlags
|=
CONTEXT_DEBUG_REGISTERS
;
to
->
Dr0
=
from
->
debug
.
x86_64_regs
.
dr0
;
to
->
Dr1
=
from
->
debug
.
x86_64_regs
.
dr1
;
to
->
Dr2
=
from
->
debug
.
x86_64_regs
.
dr2
;
to
->
Dr3
=
from
->
debug
.
x86_64_regs
.
dr3
;
to
->
Dr6
=
from
->
debug
.
x86_64_regs
.
dr6
;
to
->
Dr7
=
from
->
debug
.
x86_64_regs
.
dr7
;
}
return
STATUS_SUCCESS
;
}
/***********************************************************************
* NtGetContextThread (NTDLL.@)
* ZwGetContextThread (NTDLL.@)
*/
NTSTATUS
WINAPI
NtGetContextThread
(
HANDLE
handle
,
CONTEXT
*
context
)
{
NTSTATUS
ret
;
DWORD
needed_flags
;
BOOL
self
=
(
handle
==
GetCurrentThread
());
if
(
!
context
)
return
STATUS_INVALID_PARAMETER
;
needed_flags
=
context
->
ContextFlags
;
/* debug registers require a server call */
if
(
context
->
ContextFlags
&
(
CONTEXT_DEBUG_REGISTERS
&
~
CONTEXT_AMD64
))
self
=
FALSE
;
if
(
!
self
)
{
context_t
server_context
;
unsigned
int
server_flags
=
get_server_context_flags
(
context
->
ContextFlags
);
if
((
ret
=
get_thread_context
(
handle
,
&
server_context
,
server_flags
,
&
self
)))
return
ret
;
if
((
ret
=
context_from_server
(
context
,
&
server_context
)))
return
ret
;
needed_flags
&=
~
context
->
ContextFlags
;
}
if
(
self
)
{
if
(
needed_flags
)
{
CONTEXT
ctx
;
RtlCaptureContext
(
&
ctx
);
copy_context
(
context
,
&
ctx
,
ctx
.
ContextFlags
&
needed_flags
);
context
->
ContextFlags
|=
ctx
.
ContextFlags
&
needed_flags
;
}
/* update the cached version of the debug registers */
if
(
context
->
ContextFlags
&
(
CONTEXT_DEBUG_REGISTERS
&
~
CONTEXT_AMD64
))
{
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
;
}
}
return
STATUS_SUCCESS
;
}
/***********************************************************************
* wow64_get_server_context_flags
*/
static
unsigned
int
wow64_get_server_context_flags
(
DWORD
flags
)
...
...
dlls/ntdll/thread.c
View file @
7c32b2dd
...
...
@@ -777,6 +777,18 @@ NTSTATUS WINAPI NtSetContextThread( HANDLE handle, const CONTEXT *context )
}
/***********************************************************************
* NtGetContextThread (NTDLL.@)
* ZwGetContextThread (NTDLL.@)
*/
#ifndef __i386__
NTSTATUS
WINAPI
NtGetContextThread
(
HANDLE
handle
,
CONTEXT
*
context
)
{
return
unix_funcs
->
NtGetContextThread
(
handle
,
context
);
}
#endif
/******************************************************************************
* NtSetLdtEntries (NTDLL.@)
* ZwSetLdtEntries (NTDLL.@)
...
...
dlls/ntdll/unix/loader.c
View file @
7c32b2dd
...
...
@@ -986,6 +986,7 @@ static struct unix_funcs unix_funcs =
NtClose
,
NtCurrentTeb
,
NtDuplicateObject
,
NtGetContextThread
,
NtSetContextThread
,
NtSetLdtEntries
,
get_main_args
,
...
...
dlls/ntdll/unix/signal_arm.c
View file @
7c32b2dd
...
...
@@ -91,6 +91,63 @@ __ASM_GLOBAL_FUNC( set_cpu_context,
/***********************************************************************
* get_server_context_flags
*
* Convert CPU-specific flags to generic server flags
*/
static
unsigned
int
get_server_context_flags
(
DWORD
flags
)
{
unsigned
int
ret
=
0
;
flags
&=
~
CONTEXT_ARM
;
/* get rid of CPU id */
if
(
flags
&
CONTEXT_CONTROL
)
ret
|=
SERVER_CTX_CONTROL
;
if
(
flags
&
CONTEXT_INTEGER
)
ret
|=
SERVER_CTX_INTEGER
;
if
(
flags
&
CONTEXT_FLOATING_POINT
)
ret
|=
SERVER_CTX_FLOATING_POINT
;
if
(
flags
&
CONTEXT_DEBUG_REGISTERS
)
ret
|=
SERVER_CTX_DEBUG_REGISTERS
;
return
ret
;
}
/***********************************************************************
* copy_context
*
* Copy a register context according to the flags.
*/
static
void
copy_context
(
CONTEXT
*
to
,
const
CONTEXT
*
from
,
DWORD
flags
)
{
flags
&=
~
CONTEXT_ARM
;
/* get rid of CPU id */
if
(
flags
&
CONTEXT_CONTROL
)
{
to
->
Sp
=
from
->
Sp
;
to
->
Lr
=
from
->
Lr
;
to
->
Pc
=
from
->
Pc
;
to
->
Cpsr
=
from
->
Cpsr
;
}
if
(
flags
&
CONTEXT_INTEGER
)
{
to
->
R0
=
from
->
R0
;
to
->
R1
=
from
->
R1
;
to
->
R2
=
from
->
R2
;
to
->
R3
=
from
->
R3
;
to
->
R4
=
from
->
R4
;
to
->
R5
=
from
->
R5
;
to
->
R6
=
from
->
R6
;
to
->
R7
=
from
->
R7
;
to
->
R8
=
from
->
R8
;
to
->
R9
=
from
->
R9
;
to
->
R10
=
from
->
R10
;
to
->
R11
=
from
->
R11
;
to
->
R12
=
from
->
R12
;
}
if
(
flags
&
CONTEXT_FLOATING_POINT
)
{
to
->
Fpscr
=
from
->
Fpscr
;
memcpy
(
to
->
u
.
D
,
from
->
u
.
D
,
sizeof
(
to
->
u
.
D
)
);
}
}
/***********************************************************************
* context_to_server
*
* Convert a register context to the server format.
...
...
@@ -217,6 +274,37 @@ NTSTATUS WINAPI NtSetContextThread( HANDLE handle, const CONTEXT *context )
}
/***********************************************************************
* NtGetContextThread (NTDLL.@)
* ZwGetContextThread (NTDLL.@)
*/
NTSTATUS
WINAPI
NtGetContextThread
(
HANDLE
handle
,
CONTEXT
*
context
)
{
NTSTATUS
ret
;
DWORD
needed_flags
=
context
->
ContextFlags
;
BOOL
self
=
(
handle
==
GetCurrentThread
());
if
(
!
self
)
{
context_t
server_context
;
unsigned
int
server_flags
=
get_server_context_flags
(
context
->
ContextFlags
);
if
((
ret
=
get_thread_context
(
handle
,
&
server_context
,
server_flags
,
&
self
)))
return
ret
;
if
((
ret
=
context_from_server
(
context
,
&
server_context
)))
return
ret
;
needed_flags
&=
~
context
->
ContextFlags
;
}
if
(
self
&&
needed_flags
)
{
CONTEXT
ctx
;
RtlCaptureContext
(
&
ctx
);
copy_context
(
context
,
&
ctx
,
ctx
.
ContextFlags
&
needed_flags
);
context
->
ContextFlags
|=
ctx
.
ContextFlags
&
needed_flags
;
}
return
STATUS_SUCCESS
;
}
/**********************************************************************
* get_thread_ldt_entry
*/
...
...
dlls/ntdll/unix/signal_arm64.c
View file @
7c32b2dd
...
...
@@ -99,6 +99,61 @@ static void set_cpu_context( const CONTEXT *context )
raise
(
SIGUSR2
);
}
/***********************************************************************
* get_server_context_flags
*
* Convert CPU-specific flags to generic server flags
*/
static
unsigned
int
get_server_context_flags
(
DWORD
flags
)
{
unsigned
int
ret
=
0
;
flags
&=
~
CONTEXT_ARM64
;
/* get rid of CPU id */
if
(
flags
&
CONTEXT_CONTROL
)
ret
|=
SERVER_CTX_CONTROL
;
if
(
flags
&
CONTEXT_INTEGER
)
ret
|=
SERVER_CTX_INTEGER
;
if
(
flags
&
CONTEXT_FLOATING_POINT
)
ret
|=
SERVER_CTX_FLOATING_POINT
;
if
(
flags
&
CONTEXT_DEBUG_REGISTERS
)
ret
|=
SERVER_CTX_DEBUG_REGISTERS
;
return
ret
;
}
/***********************************************************************
* copy_context
*
* Copy a register context according to the flags.
*/
static
void
copy_context
(
CONTEXT
*
to
,
const
CONTEXT
*
from
,
DWORD
flags
)
{
flags
&=
~
CONTEXT_ARM64
;
/* get rid of CPU id */
if
(
flags
&
CONTEXT_CONTROL
)
{
to
->
u
.
s
.
Fp
=
from
->
u
.
s
.
Fp
;
to
->
u
.
s
.
Lr
=
from
->
u
.
s
.
Lr
;
to
->
Sp
=
from
->
Sp
;
to
->
Pc
=
from
->
Pc
;
to
->
Cpsr
=
from
->
Cpsr
;
}
if
(
flags
&
CONTEXT_INTEGER
)
{
memcpy
(
to
->
u
.
X
,
from
->
u
.
X
,
sizeof
(
to
->
u
.
X
)
);
}
if
(
flags
&
CONTEXT_FLOATING_POINT
)
{
memcpy
(
to
->
V
,
from
->
V
,
sizeof
(
to
->
V
)
);
to
->
Fpcr
=
from
->
Fpcr
;
to
->
Fpsr
=
from
->
Fpsr
;
}
if
(
flags
&
CONTEXT_DEBUG_REGISTERS
)
{
memcpy
(
to
->
Bcr
,
from
->
Bcr
,
sizeof
(
to
->
Bcr
)
);
memcpy
(
to
->
Bvr
,
from
->
Bvr
,
sizeof
(
to
->
Bvr
)
);
memcpy
(
to
->
Wcr
,
from
->
Wcr
,
sizeof
(
to
->
Wcr
)
);
memcpy
(
to
->
Wvr
,
from
->
Wvr
,
sizeof
(
to
->
Wvr
)
);
}
}
/***********************************************************************
* context_to_server
*
...
...
@@ -220,6 +275,37 @@ NTSTATUS WINAPI NtSetContextThread( HANDLE handle, const CONTEXT *context )
}
/***********************************************************************
* NtGetContextThread (NTDLL.@)
* ZwGetContextThread (NTDLL.@)
*/
NTSTATUS
WINAPI
NtGetContextThread
(
HANDLE
handle
,
CONTEXT
*
context
)
{
NTSTATUS
ret
;
DWORD
needed_flags
=
context
->
ContextFlags
;
BOOL
self
=
(
handle
==
GetCurrentThread
());
if
(
!
self
)
{
context_t
server_context
;
unsigned
int
server_flags
=
get_server_context_flags
(
context
->
ContextFlags
);
if
((
ret
=
get_thread_context
(
handle
,
&
server_context
,
server_flags
,
&
self
)))
return
ret
;
if
((
ret
=
context_from_server
(
context
,
&
server_context
)))
return
ret
;
needed_flags
&=
~
context
->
ContextFlags
;
}
if
(
self
&&
needed_flags
)
{
CONTEXT
ctx
;
RtlCaptureContext
(
&
ctx
);
copy_context
(
context
,
&
ctx
,
ctx
.
ContextFlags
&
needed_flags
);
context
->
ContextFlags
|=
ctx
.
ContextFlags
&
needed_flags
;
}
return
STATUS_SUCCESS
;
}
/**********************************************************************
* get_thread_ldt_entry
*/
...
...
dlls/ntdll/unix/signal_i386.c
View file @
7c32b2dd
...
...
@@ -202,6 +202,53 @@ static inline int is_gdt_sel( WORD sel )
/***********************************************************************
* save_fpu
*
* Save the thread FPU context.
*/
static
inline
void
save_fpu
(
CONTEXT
*
context
)
{
struct
{
DWORD
ControlWord
;
DWORD
StatusWord
;
DWORD
TagWord
;
DWORD
ErrorOffset
;
DWORD
ErrorSelector
;
DWORD
DataOffset
;
DWORD
DataSelector
;
}
float_status
;
context
->
ContextFlags
|=
CONTEXT_FLOATING_POINT
;
__asm__
__volatile__
(
"fnsave %0; fwait"
:
"=m"
(
context
->
FloatSave
)
);
/* Reset unmasked exceptions status to avoid firing an exception. */
memcpy
(
&
float_status
,
&
context
->
FloatSave
,
sizeof
(
float_status
));
float_status
.
StatusWord
&=
float_status
.
ControlWord
|
0xffffff80
;
__asm__
__volatile__
(
"fldenv %0"
:
:
"m"
(
float_status
)
);
}
/***********************************************************************
* save_fpux
*
* Save the thread FPU extended context.
*/
static
inline
void
save_fpux
(
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
);
context
->
ContextFlags
|=
CONTEXT_EXTENDED_REGISTERS
;
__asm__
__volatile__
(
"fxsave %0"
:
"=m"
(
*
state
)
);
memcpy
(
context
->
ExtendedRegisters
,
state
,
sizeof
(
*
state
)
);
}
/***********************************************************************
* restore_fpu
*
* Restore the FPU context to a sigcontext.
...
...
@@ -330,6 +377,26 @@ void DECLSPEC_HIDDEN set_cpu_context( const CONTEXT *context )
/***********************************************************************
* get_server_context_flags
*
* Convert CPU-specific flags to generic server flags
*/
static
unsigned
int
get_server_context_flags
(
DWORD
flags
)
{
unsigned
int
ret
=
0
;
flags
&=
~
CONTEXT_i386
;
/* get rid of CPU id */
if
(
flags
&
CONTEXT_CONTROL
)
ret
|=
SERVER_CTX_CONTROL
;
if
(
flags
&
CONTEXT_INTEGER
)
ret
|=
SERVER_CTX_INTEGER
;
if
(
flags
&
CONTEXT_SEGMENTS
)
ret
|=
SERVER_CTX_SEGMENTS
;
if
(
flags
&
CONTEXT_FLOATING_POINT
)
ret
|=
SERVER_CTX_FLOATING_POINT
;
if
(
flags
&
CONTEXT_DEBUG_REGISTERS
)
ret
|=
SERVER_CTX_DEBUG_REGISTERS
;
if
(
flags
&
CONTEXT_EXTENDED_REGISTERS
)
ret
|=
SERVER_CTX_EXTENDED_REGISTERS
;
return
ret
;
}
/***********************************************************************
* context_to_server
*
* Convert a register context to the server format.
...
...
@@ -502,6 +569,89 @@ NTSTATUS WINAPI NtSetContextThread( HANDLE handle, const CONTEXT *context )
/***********************************************************************
* NtGetContextThread (NTDLL.@)
* ZwGetContextThread (NTDLL.@)
*
* Note: we use a small assembly wrapper to save the necessary registers
* in case we are fetching the context of the current thread.
*/
NTSTATUS
WINAPI
NtGetContextThread
(
HANDLE
handle
,
CONTEXT
*
context
)
{
NTSTATUS
ret
;
DWORD
needed_flags
=
context
->
ContextFlags
&
~
CONTEXT_i386
;
BOOL
self
=
(
handle
==
GetCurrentThread
());
/* debug registers require a server call */
if
(
needed_flags
&
CONTEXT_DEBUG_REGISTERS
)
self
=
FALSE
;
if
(
!
self
)
{
context_t
server_context
;
unsigned
int
server_flags
=
get_server_context_flags
(
context
->
ContextFlags
);
if
((
ret
=
get_thread_context
(
handle
,
&
server_context
,
server_flags
,
&
self
)))
return
ret
;
if
((
ret
=
context_from_server
(
context
,
&
server_context
)))
return
ret
;
needed_flags
&=
~
context
->
ContextFlags
;
}
if
(
self
)
{
if
(
needed_flags
&
CONTEXT_INTEGER
)
{
context
->
Eax
=
0
;
context
->
Ecx
=
0
;
context
->
Edx
=
0
;
/* other registers already set from asm wrapper */
context
->
ContextFlags
|=
CONTEXT_INTEGER
;
}
if
(
needed_flags
&
CONTEXT_CONTROL
)
{
context
->
SegCs
=
get_cs
();
context
->
SegSs
=
get_ds
();
/* other registers already set from asm wrapper */
context
->
ContextFlags
|=
CONTEXT_CONTROL
;
}
if
(
needed_flags
&
CONTEXT_SEGMENTS
)
{
context
->
SegDs
=
get_ds
();
context
->
SegEs
=
get_ds
();
context
->
SegFs
=
get_fs
();
context
->
SegGs
=
get_gs
();
context
->
ContextFlags
|=
CONTEXT_SEGMENTS
;
}
if
(
needed_flags
&
CONTEXT_FLOATING_POINT
)
save_fpu
(
context
);
if
(
needed_flags
&
CONTEXT_EXTENDED_REGISTERS
)
save_fpux
(
context
);
/* FIXME: xstate */
/* update the cached version of the debug registers */
if
(
context
->
ContextFlags
&
(
CONTEXT_DEBUG_REGISTERS
&
~
CONTEXT_i386
))
{
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
(
context
->
ContextFlags
&
(
CONTEXT_INTEGER
&
~
CONTEXT_i386
))
TRACE
(
"%p: eax=%08x ebx=%08x ecx=%08x edx=%08x esi=%08x edi=%08x
\n
"
,
handle
,
context
->
Eax
,
context
->
Ebx
,
context
->
Ecx
,
context
->
Edx
,
context
->
Esi
,
context
->
Edi
);
if
(
context
->
ContextFlags
&
(
CONTEXT_CONTROL
&
~
CONTEXT_i386
))
TRACE
(
"%p: ebp=%08x esp=%08x eip=%08x cs=%04x ss=%04x flags=%08x
\n
"
,
handle
,
context
->
Ebp
,
context
->
Esp
,
context
->
Eip
,
context
->
SegCs
,
context
->
SegSs
,
context
->
EFlags
);
if
(
context
->
ContextFlags
&
(
CONTEXT_SEGMENTS
&
~
CONTEXT_i386
))
TRACE
(
"%p: ds=%04x es=%04x fs=%04x gs=%04x
\n
"
,
handle
,
context
->
SegDs
,
context
->
SegEs
,
context
->
SegFs
,
context
->
SegGs
);
if
(
context
->
ContextFlags
&
(
CONTEXT_DEBUG_REGISTERS
&
~
CONTEXT_i386
))
TRACE
(
"%p: dr0=%08x dr1=%08x dr2=%08x dr3=%08x dr6=%08x dr7=%08x
\n
"
,
handle
,
context
->
Dr0
,
context
->
Dr1
,
context
->
Dr2
,
context
->
Dr3
,
context
->
Dr6
,
context
->
Dr7
);
return
STATUS_SUCCESS
;
}
/***********************************************************************
* LDT support
*/
...
...
dlls/ntdll/unix/signal_powerpc.c
View file @
7c32b2dd
...
...
@@ -78,6 +78,116 @@ static void set_cpu_context( const CONTEXT *context )
/***********************************************************************
* get_server_context_flags
*
* Convert CPU-specific flags to generic server flags
*/
static
unsigned
int
get_server_context_flags
(
DWORD
flags
)
{
unsigned
int
ret
=
0
;
if
(
flags
&
CONTEXT_CONTROL
)
ret
|=
SERVER_CTX_CONTROL
;
if
(
flags
&
CONTEXT_INTEGER
)
ret
|=
SERVER_CTX_INTEGER
;
if
(
flags
&
CONTEXT_FLOATING_POINT
)
ret
|=
SERVER_CTX_FLOATING_POINT
;
if
(
flags
&
CONTEXT_DEBUG_REGISTERS
)
ret
|=
SERVER_CTX_DEBUG_REGISTERS
;
return
ret
;
}
/***********************************************************************
* copy_context
*
* Copy a register context according to the flags.
*/
static
void
copy_context
(
CONTEXT
*
to
,
const
CONTEXT
*
from
,
DWORD
flags
)
{
if
(
flags
&
CONTEXT_CONTROL
)
{
to
->
Msr
=
from
->
Msr
;
to
->
Ctr
=
from
->
Ctr
;
to
->
Iar
=
from
->
Iar
;
to
->
Lr
=
from
->
Lr
;
to
->
Dar
=
from
->
Dar
;
to
->
Dsisr
=
from
->
Dsisr
;
to
->
Trap
=
from
->
Trap
;
}
if
(
flags
&
CONTEXT_INTEGER
)
{
to
->
Gpr0
=
from
->
Gpr0
;
to
->
Gpr1
=
from
->
Gpr1
;
to
->
Gpr2
=
from
->
Gpr2
;
to
->
Gpr3
=
from
->
Gpr3
;
to
->
Gpr4
=
from
->
Gpr4
;
to
->
Gpr5
=
from
->
Gpr5
;
to
->
Gpr6
=
from
->
Gpr6
;
to
->
Gpr7
=
from
->
Gpr7
;
to
->
Gpr8
=
from
->
Gpr8
;
to
->
Gpr9
=
from
->
Gpr9
;
to
->
Gpr10
=
from
->
Gpr10
;
to
->
Gpr11
=
from
->
Gpr11
;
to
->
Gpr12
=
from
->
Gpr12
;
to
->
Gpr13
=
from
->
Gpr13
;
to
->
Gpr14
=
from
->
Gpr14
;
to
->
Gpr15
=
from
->
Gpr15
;
to
->
Gpr16
=
from
->
Gpr16
;
to
->
Gpr17
=
from
->
Gpr17
;
to
->
Gpr18
=
from
->
Gpr18
;
to
->
Gpr19
=
from
->
Gpr19
;
to
->
Gpr20
=
from
->
Gpr20
;
to
->
Gpr21
=
from
->
Gpr21
;
to
->
Gpr22
=
from
->
Gpr22
;
to
->
Gpr23
=
from
->
Gpr23
;
to
->
Gpr24
=
from
->
Gpr24
;
to
->
Gpr25
=
from
->
Gpr25
;
to
->
Gpr26
=
from
->
Gpr26
;
to
->
Gpr27
=
from
->
Gpr27
;
to
->
Gpr28
=
from
->
Gpr28
;
to
->
Gpr29
=
from
->
Gpr29
;
to
->
Gpr30
=
from
->
Gpr30
;
to
->
Gpr31
=
from
->
Gpr31
;
to
->
Xer
=
from
->
Xer
;
to
->
Cr
=
from
->
Cr
;
}
if
(
flags
&
CONTEXT_FLOATING_POINT
)
{
to
->
Fpr0
=
from
->
Fpr0
;
to
->
Fpr1
=
from
->
Fpr1
;
to
->
Fpr2
=
from
->
Fpr2
;
to
->
Fpr3
=
from
->
Fpr3
;
to
->
Fpr4
=
from
->
Fpr4
;
to
->
Fpr5
=
from
->
Fpr5
;
to
->
Fpr6
=
from
->
Fpr6
;
to
->
Fpr7
=
from
->
Fpr7
;
to
->
Fpr8
=
from
->
Fpr8
;
to
->
Fpr9
=
from
->
Fpr9
;
to
->
Fpr10
=
from
->
Fpr10
;
to
->
Fpr11
=
from
->
Fpr11
;
to
->
Fpr12
=
from
->
Fpr12
;
to
->
Fpr13
=
from
->
Fpr13
;
to
->
Fpr14
=
from
->
Fpr14
;
to
->
Fpr15
=
from
->
Fpr15
;
to
->
Fpr16
=
from
->
Fpr16
;
to
->
Fpr17
=
from
->
Fpr17
;
to
->
Fpr18
=
from
->
Fpr18
;
to
->
Fpr19
=
from
->
Fpr19
;
to
->
Fpr20
=
from
->
Fpr20
;
to
->
Fpr21
=
from
->
Fpr21
;
to
->
Fpr22
=
from
->
Fpr22
;
to
->
Fpr23
=
from
->
Fpr23
;
to
->
Fpr24
=
from
->
Fpr24
;
to
->
Fpr25
=
from
->
Fpr25
;
to
->
Fpr26
=
from
->
Fpr26
;
to
->
Fpr27
=
from
->
Fpr27
;
to
->
Fpr28
=
from
->
Fpr28
;
to
->
Fpr29
=
from
->
Fpr29
;
to
->
Fpr30
=
from
->
Fpr30
;
to
->
Fpr31
=
from
->
Fpr31
;
to
->
Fpscr
=
from
->
Fpscr
;
}
}
/***********************************************************************
* context_to_server
*
* Convert a register context to the server format.
...
...
@@ -296,6 +406,37 @@ NTSTATUS WINAPI NtSetContextThread( HANDLE handle, const CONTEXT *context )
}
/***********************************************************************
* NtGetContextThread (NTDLL.@)
* ZwGetContextThread (NTDLL.@)
*/
NTSTATUS
WINAPI
NtGetContextThread
(
HANDLE
handle
,
CONTEXT
*
context
)
{
NTSTATUS
ret
;
DWORD
needed_flags
=
context
->
ContextFlags
;
BOOL
self
=
(
handle
==
GetCurrentThread
());
if
(
!
self
)
{
context_t
server_context
;
unsigned
int
server_flags
=
get_server_context_flags
(
context
->
ContextFlags
);
if
((
ret
=
get_thread_context
(
handle
,
&
server_context
,
server_flags
,
&
self
)))
return
ret
;
if
((
ret
=
context_from_server
(
context
,
&
server_context
)))
return
ret
;
needed_flags
&=
~
context
->
ContextFlags
;
}
if
(
self
&&
needed_flags
)
{
CONTEXT
ctx
;
RtlCaptureContext
(
&
ctx
);
copy_context
(
context
,
&
ctx
,
ctx
.
ContextFlags
&
needed_flags
);
context
->
ContextFlags
|=
ctx
.
ContextFlags
&
needed_flags
;
}
return
STATUS_SUCCESS
;
}
/**********************************************************************
* get_thread_ldt_entry
*/
...
...
dlls/ntdll/unix/signal_x86_64.c
View file @
7c32b2dd
...
...
@@ -220,6 +220,83 @@ void DECLSPEC_HIDDEN set_cpu_context( const CONTEXT *context )
/***********************************************************************
* get_server_context_flags
*
* Convert CPU-specific flags to generic server flags
*/
static
unsigned
int
get_server_context_flags
(
DWORD
flags
)
{
unsigned
int
ret
=
0
;
flags
&=
~
CONTEXT_AMD64
;
/* get rid of CPU id */
if
(
flags
&
CONTEXT_CONTROL
)
ret
|=
SERVER_CTX_CONTROL
;
if
(
flags
&
CONTEXT_INTEGER
)
ret
|=
SERVER_CTX_INTEGER
;
if
(
flags
&
CONTEXT_SEGMENTS
)
ret
|=
SERVER_CTX_SEGMENTS
;
if
(
flags
&
CONTEXT_FLOATING_POINT
)
ret
|=
SERVER_CTX_FLOATING_POINT
;
if
(
flags
&
CONTEXT_DEBUG_REGISTERS
)
ret
|=
SERVER_CTX_DEBUG_REGISTERS
;
return
ret
;
}
/***********************************************************************
* copy_context
*
* Copy a register context according to the flags.
*/
static
void
copy_context
(
CONTEXT
*
to
,
const
CONTEXT
*
from
,
DWORD
flags
)
{
flags
&=
~
CONTEXT_AMD64
;
/* get rid of CPU id */
if
(
flags
&
CONTEXT_CONTROL
)
{
to
->
Rbp
=
from
->
Rbp
;
to
->
Rip
=
from
->
Rip
;
to
->
Rsp
=
from
->
Rsp
;
to
->
SegCs
=
from
->
SegCs
;
to
->
SegSs
=
from
->
SegSs
;
to
->
EFlags
=
from
->
EFlags
;
}
if
(
flags
&
CONTEXT_INTEGER
)
{
to
->
Rax
=
from
->
Rax
;
to
->
Rcx
=
from
->
Rcx
;
to
->
Rdx
=
from
->
Rdx
;
to
->
Rbx
=
from
->
Rbx
;
to
->
Rsi
=
from
->
Rsi
;
to
->
Rdi
=
from
->
Rdi
;
to
->
R8
=
from
->
R8
;
to
->
R9
=
from
->
R9
;
to
->
R10
=
from
->
R10
;
to
->
R11
=
from
->
R11
;
to
->
R12
=
from
->
R12
;
to
->
R13
=
from
->
R13
;
to
->
R14
=
from
->
R14
;
to
->
R15
=
from
->
R15
;
}
if
(
flags
&
CONTEXT_SEGMENTS
)
{
to
->
SegDs
=
from
->
SegDs
;
to
->
SegEs
=
from
->
SegEs
;
to
->
SegFs
=
from
->
SegFs
;
to
->
SegGs
=
from
->
SegGs
;
}
if
(
flags
&
CONTEXT_FLOATING_POINT
)
{
to
->
MxCsr
=
from
->
MxCsr
;
to
->
u
.
FltSave
=
from
->
u
.
FltSave
;
}
if
(
flags
&
CONTEXT_DEBUG_REGISTERS
)
{
to
->
Dr0
=
from
->
Dr0
;
to
->
Dr1
=
from
->
Dr1
;
to
->
Dr2
=
from
->
Dr2
;
to
->
Dr3
=
from
->
Dr3
;
to
->
Dr6
=
from
->
Dr6
;
to
->
Dr7
=
from
->
Dr7
;
}
}
/***********************************************************************
* context_to_server
*
* Convert a register context to the server format.
...
...
@@ -382,6 +459,57 @@ NTSTATUS WINAPI NtSetContextThread( HANDLE handle, const CONTEXT *context )
}
/***********************************************************************
* NtGetContextThread (NTDLL.@)
* ZwGetContextThread (NTDLL.@)
*/
NTSTATUS
WINAPI
NtGetContextThread
(
HANDLE
handle
,
CONTEXT
*
context
)
{
NTSTATUS
ret
;
DWORD
needed_flags
;
BOOL
self
=
(
handle
==
GetCurrentThread
());
if
(
!
context
)
return
STATUS_INVALID_PARAMETER
;
needed_flags
=
context
->
ContextFlags
;
/* debug registers require a server call */
if
(
context
->
ContextFlags
&
(
CONTEXT_DEBUG_REGISTERS
&
~
CONTEXT_AMD64
))
self
=
FALSE
;
if
(
!
self
)
{
context_t
server_context
;
unsigned
int
server_flags
=
get_server_context_flags
(
context
->
ContextFlags
);
if
((
ret
=
get_thread_context
(
handle
,
&
server_context
,
server_flags
,
&
self
)))
return
ret
;
if
((
ret
=
context_from_server
(
context
,
&
server_context
)))
return
ret
;
needed_flags
&=
~
context
->
ContextFlags
;
}
if
(
self
)
{
if
(
needed_flags
)
{
CONTEXT
ctx
;
RtlCaptureContext
(
&
ctx
);
copy_context
(
context
,
&
ctx
,
ctx
.
ContextFlags
&
needed_flags
);
context
->
ContextFlags
|=
ctx
.
ContextFlags
&
needed_flags
;
}
/* update the cached version of the debug registers */
if
(
context
->
ContextFlags
&
(
CONTEXT_DEBUG_REGISTERS
&
~
CONTEXT_AMD64
))
{
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
;
}
}
return
STATUS_SUCCESS
;
}
/**********************************************************************
* get_thread_ldt_entry
*/
...
...
dlls/ntdll/unix/thread.c
View file @
7c32b2dd
...
...
@@ -168,3 +168,43 @@ NTSTATUS set_thread_context( HANDLE handle, const context_t *context, BOOL *self
return
ret
;
}
/***********************************************************************
* get_thread_context
*/
NTSTATUS
get_thread_context
(
HANDLE
handle
,
context_t
*
context
,
unsigned
int
flags
,
BOOL
*
self
)
{
NTSTATUS
ret
;
SERVER_START_REQ
(
get_thread_context
)
{
req
->
handle
=
wine_server_obj_handle
(
handle
);
req
->
flags
=
flags
;
wine_server_set_reply
(
req
,
context
,
sizeof
(
*
context
)
);
ret
=
wine_server_call
(
req
);
*
self
=
reply
->
self
;
handle
=
wine_server_ptr_handle
(
reply
->
handle
);
}
SERVER_END_REQ
;
if
(
ret
==
STATUS_PENDING
)
{
LARGE_INTEGER
timeout
;
timeout
.
QuadPart
=
-
1000000
;
if
(
NtWaitForSingleObject
(
handle
,
FALSE
,
&
timeout
))
{
NtClose
(
handle
);
return
STATUS_ACCESS_DENIED
;
}
SERVER_START_REQ
(
get_thread_context
)
{
req
->
handle
=
wine_server_obj_handle
(
handle
);
req
->
flags
=
flags
;
wine_server_set_reply
(
req
,
context
,
sizeof
(
*
context
)
);
ret
=
wine_server_call
(
req
);
}
SERVER_END_REQ
;
}
return
ret
;
}
dlls/ntdll/unix/unix_private.h
View file @
7c32b2dd
...
...
@@ -104,6 +104,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
NTSTATUS
get_thread_context
(
HANDLE
handle
,
context_t
*
context
,
unsigned
int
flags
,
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 @
7c32b2dd
...
...
@@ -27,7 +27,7 @@
struct
ldt_copy
;
/* increment this when you change the function table */
#define NTDLL_UNIXLIB_VERSION 1
4
#define NTDLL_UNIXLIB_VERSION 1
5
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
*
NtGetContextThread
)(
HANDLE
handle
,
CONTEXT
*
context
);
NTSTATUS
(
WINAPI
*
NtSetContextThread
)(
HANDLE
handle
,
const
CONTEXT
*
context
);
NTSTATUS
(
WINAPI
*
NtSetLdtEntries
)(
ULONG
sel1
,
LDT_ENTRY
entry1
,
ULONG
sel2
,
LDT_ENTRY
entry2
);
...
...
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