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
5316dd01
Commit
5316dd01
authored
Apr 08, 2009
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
server: Define a generic context structure instead of using the platform-specific version.
parent
53929f19
Show whitespace changes
Inline
Side-by-side
Showing
23 changed files
with
1132 additions
and
1225 deletions
+1132
-1225
exception.c
dlls/ntdll/exception.c
+13
-7
ntdll_misc.h
dlls/ntdll/ntdll_misc.h
+2
-0
signal_i386.c
dlls/ntdll/signal_i386.c
+144
-0
signal_powerpc.c
dlls/ntdll/signal_powerpc.c
+208
-0
signal_sparc.c
dlls/ntdll/signal_sparc.c
+132
-0
signal_x86_64.c
dlls/ntdll/signal_x86_64.c
+137
-0
thread.c
dlls/ntdll/thread.c
+40
-11
server_protocol.h
include/wine/server_protocol.h
+58
-2
Makefile.in
server/Makefile.in
+0
-5
context_alpha.c
server/context_alpha.c
+0
-348
context_i386.c
server/context_i386.c
+0
-104
context_powerpc.c
server/context_powerpc.c
+0
-286
context_sparc.c
server/context_sparc.c
+0
-184
context_x86_64.c
server/context_x86_64.c
+0
-104
debugger.c
server/debugger.c
+4
-4
mach.c
server/mach.c
+30
-37
procfs.c
server/procfs.c
+2
-8
protocol.def
server/protocol.def
+57
-1
ptrace.c
server/ptrace.c
+56
-63
request.h
server/request.h
+1
-2
thread.c
server/thread.c
+65
-18
thread.h
server/thread.h
+4
-10
trace.c
server/trace.c
+179
-31
No files found.
dlls/ntdll/exception.c
View file @
5316dd01
...
...
@@ -149,14 +149,16 @@ void wait_suspend( CONTEXT *context )
{
LARGE_INTEGER
timeout
;
int
saved_errno
=
errno
;
context_t
server_context
;
context_to_server
(
&
server_context
,
context
);
/* store the context we got at suspend time */
SERVER_START_REQ
(
set_thread_context
)
{
req
->
handle
=
wine_server_obj_handle
(
GetCurrentThread
()
);
req
->
flags
=
CONTEXT_FULL
;
req
->
suspend
=
1
;
wine_server_add_data
(
req
,
context
,
sizeof
(
*
context
)
);
wine_server_add_data
(
req
,
&
server_context
,
sizeof
(
server_
context
)
);
wine_server_call
(
req
);
}
SERVER_END_REQ
;
...
...
@@ -169,13 +171,13 @@ void wait_suspend( CONTEXT *context )
SERVER_START_REQ
(
get_thread_context
)
{
req
->
handle
=
wine_server_obj_handle
(
GetCurrentThread
()
);
req
->
flags
=
CONTEXT_FULL
;
req
->
suspend
=
1
;
wine_server_set_reply
(
req
,
context
,
sizeof
(
*
context
)
);
wine_server_set_reply
(
req
,
&
server_context
,
sizeof
(
server_
context
)
);
wine_server_call
(
req
);
}
SERVER_END_REQ
;
context_from_server
(
context
,
&
server_context
);
errno
=
saved_errno
;
}
...
...
@@ -187,16 +189,19 @@ void wait_suspend( CONTEXT *context )
*/
static
NTSTATUS
send_debug_event
(
EXCEPTION_RECORD
*
rec
,
int
first_chance
,
CONTEXT
*
context
)
{
int
ret
;
NTSTATUS
ret
;
DWORD
i
;
HANDLE
handle
=
0
;
client_ptr_t
params
[
EXCEPTION_MAXIMUM_PARAMETERS
];
context_t
server_context
;
if
(
!
NtCurrentTeb
()
->
Peb
->
BeingDebugged
)
return
0
;
/* no debugger present */
for
(
i
=
0
;
i
<
min
(
rec
->
NumberParameters
,
EXCEPTION_MAXIMUM_PARAMETERS
);
i
++
)
params
[
i
]
=
rec
->
ExceptionInformation
[
i
];
context_to_server
(
&
server_context
,
context
);
SERVER_START_REQ
(
queue_exception_event
)
{
req
->
first
=
first_chance
;
...
...
@@ -206,7 +211,7 @@ static NTSTATUS send_debug_event( EXCEPTION_RECORD *rec, int first_chance, CONTE
req
->
address
=
wine_server_client_ptr
(
rec
->
ExceptionAddress
);
req
->
len
=
i
*
sizeof
(
params
[
0
]);
wine_server_add_data
(
req
,
params
,
req
->
len
);
wine_server_add_data
(
req
,
context
,
sizeof
(
*
context
)
);
wine_server_add_data
(
req
,
&
server_context
,
sizeof
(
server_
context
)
);
if
(
!
wine_server_call
(
req
))
handle
=
wine_server_ptr_handle
(
reply
->
handle
);
}
SERVER_END_REQ
;
...
...
@@ -217,10 +222,11 @@ static NTSTATUS send_debug_event( EXCEPTION_RECORD *rec, int first_chance, CONTE
SERVER_START_REQ
(
get_exception_status
)
{
req
->
handle
=
wine_server_obj_handle
(
handle
);
wine_server_set_reply
(
req
,
context
,
sizeof
(
*
context
)
);
wine_server_set_reply
(
req
,
&
server_context
,
sizeof
(
server_
context
)
);
ret
=
wine_server_call
(
req
);
}
SERVER_END_REQ
;
if
(
!
ret
)
ret
=
context_from_server
(
context
,
&
server_context
);
return
ret
;
}
...
...
dlls/ntdll/ntdll_misc.h
View file @
5316dd01
...
...
@@ -44,6 +44,8 @@ extern void wait_suspend( CONTEXT *context );
extern
void
WINAPI
__regs_RtlRaiseException
(
PEXCEPTION_RECORD
,
PCONTEXT
);
extern
void
set_cpu_context
(
const
CONTEXT
*
context
);
extern
void
copy_context
(
CONTEXT
*
to
,
const
CONTEXT
*
from
,
DWORD
flags
);
extern
NTSTATUS
context_to_server
(
context_t
*
to
,
const
CONTEXT
*
from
);
extern
NTSTATUS
context_from_server
(
CONTEXT
*
to
,
const
context_t
*
from
);
/* debug helpers */
extern
LPCSTR
debugstr_us
(
const
UNICODE_STRING
*
str
);
...
...
dlls/ntdll/signal_i386.c
View file @
5316dd01
...
...
@@ -55,6 +55,8 @@
# include <sys/sysctl.h>
#endif
#include "ntstatus.h"
#define WIN32_NO_STATUS
#include "windef.h"
#include "wine/library.h"
#include "ntdll_misc.h"
...
...
@@ -1065,6 +1067,148 @@ 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_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.
*/
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
;
}
/***********************************************************************
* is_privileged_instr
*
* Check if the fault location is a privileged instruction.
...
...
dlls/ntdll/signal_powerpc.c
View file @
5316dd01
...
...
@@ -51,6 +51,8 @@
# include <sys/signal.h>
#endif
#include "ntstatus.h"
#define WIN32_NO_STATUS
#include "windef.h"
#include "winternl.h"
#include "wine/library.h"
...
...
@@ -301,6 +303,10 @@ void copy_context( CONTEXT *to, const CONTEXT *from, DWORD flags )
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
)
{
...
...
@@ -378,6 +384,208 @@ 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.
*/
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
;
}
/**********************************************************************
* get_fpu_code
*
...
...
dlls/ntdll/signal_sparc.c
View file @
5316dd01
...
...
@@ -33,6 +33,8 @@
#include <stdio.h>
#include <sys/ucontext.h>
#include "ntstatus.h"
#define WIN32_NO_STATUS
#include "windef.h"
#include "winternl.h"
#include "winnt.h"
...
...
@@ -230,6 +232,136 @@ 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_SPARC
;
/* get rid of CPU id */
memset
(
to
,
0
,
sizeof
(
*
to
)
);
to
->
cpu
=
CPU_SPARC
;
if
(
flags
&
CONTEXT_CONTROL
)
{
to
->
flags
|=
SERVER_CTX_CONTROL
;
to
->
ctl
.
sparc_regs
.
psr
=
from
->
psr
;
to
->
ctl
.
sparc_regs
.
pc
=
from
->
pc
;
to
->
ctl
.
sparc_regs
.
npc
=
from
->
npc
;
to
->
ctl
.
sparc_regs
.
y
=
from
->
y
;
to
->
ctl
.
sparc_regs
.
wim
=
from
->
wim
;
to
->
ctl
.
sparc_regs
.
tbr
=
from
->
tbr
;
}
if
(
flags
&
CONTEXT_INTEGER
)
{
to
->
flags
|=
SERVER_CTX_INTEGER
;
to
->
integer
.
sparc_regs
.
g
[
0
]
=
from
->
g0
;
to
->
integer
.
sparc_regs
.
g
[
1
]
=
from
->
g1
;
to
->
integer
.
sparc_regs
.
g
[
2
]
=
from
->
g2
;
to
->
integer
.
sparc_regs
.
g
[
3
]
=
from
->
g3
;
to
->
integer
.
sparc_regs
.
g
[
4
]
=
from
->
g4
;
to
->
integer
.
sparc_regs
.
g
[
5
]
=
from
->
g5
;
to
->
integer
.
sparc_regs
.
g
[
6
]
=
from
->
g6
;
to
->
integer
.
sparc_regs
.
g
[
7
]
=
from
->
g7
;
to
->
integer
.
sparc_regs
.
o
[
0
]
=
from
->
o0
;
to
->
integer
.
sparc_regs
.
o
[
1
]
=
from
->
o1
;
to
->
integer
.
sparc_regs
.
o
[
2
]
=
from
->
o2
;
to
->
integer
.
sparc_regs
.
o
[
3
]
=
from
->
o3
;
to
->
integer
.
sparc_regs
.
o
[
4
]
=
from
->
o4
;
to
->
integer
.
sparc_regs
.
o
[
5
]
=
from
->
o5
;
to
->
integer
.
sparc_regs
.
o
[
6
]
=
from
->
o6
;
to
->
integer
.
sparc_regs
.
o
[
7
]
=
from
->
o7
;
to
->
integer
.
sparc_regs
.
l
[
0
]
=
from
->
l0
;
to
->
integer
.
sparc_regs
.
l
[
1
]
=
from
->
l1
;
to
->
integer
.
sparc_regs
.
l
[
2
]
=
from
->
l2
;
to
->
integer
.
sparc_regs
.
l
[
3
]
=
from
->
l3
;
to
->
integer
.
sparc_regs
.
l
[
4
]
=
from
->
l4
;
to
->
integer
.
sparc_regs
.
l
[
5
]
=
from
->
l5
;
to
->
integer
.
sparc_regs
.
l
[
6
]
=
from
->
l6
;
to
->
integer
.
sparc_regs
.
l
[
7
]
=
from
->
l7
;
to
->
integer
.
sparc_regs
.
i
[
0
]
=
from
->
i0
;
to
->
integer
.
sparc_regs
.
i
[
1
]
=
from
->
i1
;
to
->
integer
.
sparc_regs
.
i
[
2
]
=
from
->
i2
;
to
->
integer
.
sparc_regs
.
i
[
3
]
=
from
->
i3
;
to
->
integer
.
sparc_regs
.
i
[
4
]
=
from
->
i4
;
to
->
integer
.
sparc_regs
.
i
[
5
]
=
from
->
i5
;
to
->
integer
.
sparc_regs
.
i
[
6
]
=
from
->
i6
;
to
->
integer
.
sparc_regs
.
i
[
7
]
=
from
->
i7
;
}
if
(
flags
&
CONTEXT_FLOATING_POINT
)
{
/* FIXME */
}
return
STATUS_SUCCESS
;
}
/***********************************************************************
* 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_SPARC
)
return
STATUS_INVALID_PARAMETER
;
to
->
ContextFlags
=
CONTEXT_SPARC
;
if
(
from
->
flags
&
SERVER_CTX_CONTROL
)
{
to
->
ContextFlags
|=
CONTEXT_CONTROL
;
to
->
psr
=
from
->
ctl
.
sparc_regs
.
psr
;
to
->
pc
=
from
->
ctl
.
sparc_regs
.
pc
;
to
->
npc
=
from
->
ctl
.
sparc_regs
.
npc
;
to
->
y
=
from
->
ctl
.
sparc_regs
.
y
;
to
->
wim
=
from
->
ctl
.
sparc_regs
.
wim
;
to
->
tbr
=
from
->
ctl
.
sparc_regs
.
tbr
;
}
if
(
from
->
flags
&
SERVER_CTX_INTEGER
)
{
to
->
ContextFlags
|=
CONTEXT_INTEGER
;
to
->
g0
=
from
->
integer
.
sparc_regs
.
g
[
0
];
to
->
g1
=
from
->
integer
.
sparc_regs
.
g
[
1
];
to
->
g2
=
from
->
integer
.
sparc_regs
.
g
[
2
];
to
->
g3
=
from
->
integer
.
sparc_regs
.
g
[
3
];
to
->
g4
=
from
->
integer
.
sparc_regs
.
g
[
4
];
to
->
g5
=
from
->
integer
.
sparc_regs
.
g
[
5
];
to
->
g6
=
from
->
integer
.
sparc_regs
.
g
[
6
];
to
->
g7
=
from
->
integer
.
sparc_regs
.
g
[
7
];
to
->
o0
=
from
->
integer
.
sparc_regs
.
o
[
0
];
to
->
o1
=
from
->
integer
.
sparc_regs
.
o
[
1
];
to
->
o2
=
from
->
integer
.
sparc_regs
.
o
[
2
];
to
->
o3
=
from
->
integer
.
sparc_regs
.
o
[
3
];
to
->
o4
=
from
->
integer
.
sparc_regs
.
o
[
4
];
to
->
o5
=
from
->
integer
.
sparc_regs
.
o
[
5
];
to
->
o6
=
from
->
integer
.
sparc_regs
.
o
[
6
];
to
->
o7
=
from
->
integer
.
sparc_regs
.
o
[
7
];
to
->
l0
=
from
->
integer
.
sparc_regs
.
l
[
0
];
to
->
l1
=
from
->
integer
.
sparc_regs
.
l
[
1
];
to
->
l2
=
from
->
integer
.
sparc_regs
.
l
[
2
];
to
->
l3
=
from
->
integer
.
sparc_regs
.
l
[
3
];
to
->
l4
=
from
->
integer
.
sparc_regs
.
l
[
4
];
to
->
l5
=
from
->
integer
.
sparc_regs
.
l
[
5
];
to
->
l6
=
from
->
integer
.
sparc_regs
.
l
[
6
];
to
->
l7
=
from
->
integer
.
sparc_regs
.
l
[
7
];
to
->
i0
=
from
->
integer
.
sparc_regs
.
i
[
0
];
to
->
i1
=
from
->
integer
.
sparc_regs
.
i
[
1
];
to
->
i2
=
from
->
integer
.
sparc_regs
.
i
[
2
];
to
->
i3
=
from
->
integer
.
sparc_regs
.
i
[
3
];
to
->
i4
=
from
->
integer
.
sparc_regs
.
i
[
4
];
to
->
i5
=
from
->
integer
.
sparc_regs
.
i
[
5
];
to
->
i6
=
from
->
integer
.
sparc_regs
.
i
[
6
];
to
->
i7
=
from
->
integer
.
sparc_regs
.
i
[
7
];
}
if
(
from
->
flags
&
SERVER_CTX_FLOATING_POINT
)
{
/* FIXME */
}
return
STATUS_SUCCESS
;
}
/**********************************************************************
* segv_handler
*
...
...
dlls/ntdll/signal_x86_64.c
View file @
5316dd01
...
...
@@ -40,6 +40,8 @@
#endif
#define NONAMELESSUNION
#include "ntstatus.h"
#define WIN32_NO_STATUS
#include "windef.h"
#include "winternl.h"
#include "wine/library.h"
...
...
@@ -327,6 +329,141 @@ 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
;
to
->
ctl
.
x86_64_regs
.
mxcsr
=
from
->
MxCsr
;
}
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.
*/
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
;
to
->
MxCsr
=
from
->
ctl
.
x86_64_regs
.
mxcsr
;
}
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
)
);
}
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
;
}
/**********************************************************************
* segv_handler
*
...
...
dlls/ntdll/thread.c
View file @
5316dd01
...
...
@@ -824,12 +824,15 @@ NTSTATUS WINAPI NtSetContextThread( HANDLE handle, const CONTEXT *context )
if
(
!
self
)
{
context_t
server_context
;
context_to_server
(
&
server_context
,
context
);
SERVER_START_REQ
(
set_thread_context
)
{
req
->
handle
=
wine_server_obj_handle
(
handle
);
req
->
flags
=
context
->
ContextFlags
;
req
->
suspend
=
0
;
wine_server_add_data
(
req
,
context
,
sizeof
(
*
context
)
);
wine_server_add_data
(
req
,
&
server_context
,
sizeof
(
server_
context
)
);
ret
=
wine_server_call
(
req
);
self
=
reply
->
self
;
}
...
...
@@ -844,9 +847,8 @@ NTSTATUS WINAPI NtSetContextThread( HANDLE handle, const CONTEXT *context )
SERVER_START_REQ
(
set_thread_context
)
{
req
->
handle
=
wine_server_obj_handle
(
handle
);
req
->
flags
=
context
->
ContextFlags
;
req
->
suspend
=
0
;
wine_server_add_data
(
req
,
context
,
sizeof
(
*
context
)
);
wine_server_add_data
(
req
,
&
server_context
,
sizeof
(
server_
context
)
);
ret
=
wine_server_call
(
req
);
}
SERVER_END_REQ
;
...
...
@@ -871,6 +873,29 @@ NTSTATUS WINAPI NtSetContextThread( HANDLE handle, const CONTEXT *context )
}
/* convert CPU-specific flags to generic server flags */
static
inline
unsigned
int
get_server_context_flags
(
DWORD
flags
)
{
unsigned
int
ret
=
0
;
flags
&=
~
0x3f
;
/* mask CPU id flags */
if
(
flags
&
CONTEXT_CONTROL
)
ret
|=
SERVER_CTX_CONTROL
;
if
(
flags
&
CONTEXT_INTEGER
)
ret
|=
SERVER_CTX_INTEGER
;
#ifdef CONTEXT_SEGMENTS
if
(
flags
&
CONTEXT_SEGMENTS
)
ret
|=
SERVER_CTX_SEGMENTS
;
#endif
#ifdef CONTEXT_FLOATING_POINT
if
(
flags
&
CONTEXT_FLOATING_POINT
)
ret
|=
SERVER_CTX_FLOATING_POINT
;
#endif
#ifdef CONTEXT_DEBUG_REGISTERS
if
(
flags
&
CONTEXT_DEBUG_REGISTERS
)
ret
|=
SERVER_CTX_DEBUG_REGISTERS
;
#endif
#ifdef CONTEXT_EXTENDED_REGISTERS
if
(
flags
&
CONTEXT_EXTENDED_REGISTERS
)
ret
|=
SERVER_CTX_EXTENDED_REGISTERS
;
#endif
return
ret
;
}
/***********************************************************************
* NtGetContextThread (NTDLL.@)
* ZwGetContextThread (NTDLL.@)
...
...
@@ -878,7 +903,6 @@ NTSTATUS WINAPI NtSetContextThread( HANDLE handle, const CONTEXT *context )
NTSTATUS
WINAPI
NtGetContextThread
(
HANDLE
handle
,
CONTEXT
*
context
)
{
NTSTATUS
ret
;
CONTEXT
ctx
;
DWORD
dummy
,
i
;
DWORD
needed_flags
=
context
->
ContextFlags
;
BOOL
self
=
(
handle
==
GetCurrentThread
());
...
...
@@ -890,12 +914,15 @@ NTSTATUS WINAPI NtGetContextThread( HANDLE handle, CONTEXT *context )
if
(
!
self
)
{
unsigned
int
server_flags
=
get_server_context_flags
(
context
->
ContextFlags
);
context_t
server_context
;
SERVER_START_REQ
(
get_thread_context
)
{
req
->
handle
=
wine_server_obj_handle
(
handle
);
req
->
flags
=
context
->
ContextF
lags
;
req
->
flags
=
server_f
lags
;
req
->
suspend
=
0
;
wine_server_set_reply
(
req
,
&
ctx
,
sizeof
(
ctx
)
);
wine_server_set_reply
(
req
,
&
server_context
,
sizeof
(
server_context
)
);
ret
=
wine_server_call
(
req
);
self
=
reply
->
self
;
}
...
...
@@ -910,9 +937,9 @@ NTSTATUS WINAPI NtGetContextThread( HANDLE handle, CONTEXT *context )
SERVER_START_REQ
(
get_thread_context
)
{
req
->
handle
=
wine_server_obj_handle
(
handle
);
req
->
flags
=
context
->
ContextF
lags
;
req
->
flags
=
server_f
lags
;
req
->
suspend
=
0
;
wine_server_set_reply
(
req
,
&
ctx
,
sizeof
(
ctx
)
);
wine_server_set_reply
(
req
,
&
server_context
,
sizeof
(
server_context
)
);
ret
=
wine_server_call
(
req
);
}
SERVER_END_REQ
;
...
...
@@ -928,17 +955,19 @@ NTSTATUS WINAPI NtGetContextThread( HANDLE handle, CONTEXT *context )
}
if
(
ret
==
STATUS_PENDING
)
ret
=
STATUS_ACCESS_DENIED
;
}
if
(
!
ret
)
ret
=
context_from_server
(
context
,
&
server_context
);
if
(
ret
)
return
ret
;
copy_context
(
context
,
&
ctx
,
context
->
ContextFlags
&
ctx
.
ContextFlags
);
needed_flags
&=
~
ctx
.
ContextFlags
;
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
;
}
#ifdef __i386__
/* update the cached version of the debug registers */
...
...
include/wine/server_protocol.h
View file @
5316dd01
...
...
@@ -135,6 +135,63 @@ enum cpu_type
typedef
int
cpu_type_t
;
typedef
struct
{
cpu_type_t
cpu
;
unsigned
int
flags
;
union
{
struct
{
unsigned
int
eip
,
ebp
,
esp
,
eflags
,
cs
,
ss
;
}
i386_regs
;
struct
{
unsigned
__int64
rip
,
rbp
,
rsp
;
unsigned
int
cs
,
ss
,
flags
,
mxcsr
;
}
x86_64_regs
;
struct
{
unsigned
__int64
fir
;
unsigned
int
psr
;
}
alpha_regs
;
struct
{
unsigned
int
iar
,
msr
,
ctr
,
lr
,
dar
,
dsisr
,
trap
;
}
powerpc_regs
;
struct
{
unsigned
int
psr
,
pc
,
npc
,
y
,
wim
,
tbr
;
}
sparc_regs
;
}
ctl
;
union
{
struct
{
unsigned
int
eax
,
ebx
,
ecx
,
edx
,
esi
,
edi
;
}
i386_regs
;
struct
{
unsigned
__int64
rax
,
rbx
,
rcx
,
rdx
,
rsi
,
rdi
,
r8
,
r9
,
r10
,
r11
,
r12
,
r13
,
r14
,
r15
;
}
x86_64_regs
;
struct
{
unsigned
__int64
v0
,
t0
,
t1
,
t2
,
t3
,
t4
,
t5
,
t6
,
t7
,
t8
,
t9
,
t10
,
t11
,
t12
,
s0
,
s1
,
s2
,
s3
,
s4
,
s5
,
s6
,
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
at
;
}
alpha_regs
;
struct
{
unsigned
int
gpr
[
32
],
cr
,
xer
;
}
powerpc_regs
;
struct
{
unsigned
int
g
[
8
],
o
[
8
],
l
[
8
],
i
[
8
];
}
sparc_regs
;
}
integer
;
union
{
struct
{
unsigned
int
ds
,
es
,
fs
,
gs
;
}
i386_regs
;
struct
{
unsigned
int
ds
,
es
,
fs
,
gs
;
}
x86_64_regs
;
}
seg
;
union
{
struct
{
unsigned
int
ctrl
,
status
,
tag
,
err_off
,
err_sel
,
data_off
,
data_sel
,
cr0npx
;
unsigned
char
regs
[
80
];
}
i386_regs
;
struct
{
struct
{
unsigned
__int64
low
,
high
;
}
fpregs
[
32
];
}
x86_64_regs
;
struct
{
unsigned
__int64
f
[
32
],
fpcr
,
softfpcr
;
}
alpha_regs
;
struct
{
double
fpr
[
32
],
fpscr
;
}
powerpc_regs
;
}
fp
;
union
{
struct
{
unsigned
int
dr0
,
dr1
,
dr2
,
dr3
,
dr6
,
dr7
;
}
i386_regs
;
struct
{
unsigned
__int64
dr0
,
dr1
,
dr2
,
dr3
,
dr6
,
dr7
;
}
x86_64_regs
;
struct
{
unsigned
int
dr
[
8
];
}
powerpc_regs
;
}
debug
;
union
{
unsigned
char
i386_regs
[
512
];
}
ext
;
}
context_t
;
#define SERVER_CTX_CONTROL 0x01
#define SERVER_CTX_INTEGER 0x02
#define SERVER_CTX_SEGMENTS 0x04
#define SERVER_CTX_FLOATING_POINT 0x08
#define SERVER_CTX_DEBUG_REGISTERS 0x10
#define SERVER_CTX_EXTENDED_REGISTERS 0x20
struct
send_fd
{
thread_id_t
tid
;
...
...
@@ -2356,7 +2413,6 @@ struct set_thread_context_request
{
struct
request_header
__header
;
obj_handle_t
handle
;
unsigned
int
flags
;
int
suspend
;
/* VARARG(context,context); */
};
...
...
@@ -5224,6 +5280,6 @@ union generic_reply
struct
set_window_layered_info_reply
set_window_layered_info_reply
;
};
#define SERVER_PROTOCOL_VERSION 38
4
#define SERVER_PROTOCOL_VERSION 38
5
#endif
/* __WINE_WINE_SERVER_PROTOCOL_H */
server/Makefile.in
View file @
5316dd01
...
...
@@ -14,11 +14,6 @@ C_SRCS = \
clipboard.c
\
completion.c
\
console.c
\
context_alpha.c
\
context_i386.c
\
context_powerpc.c
\
context_sparc.c
\
context_x86_64.c
\
debugger.c
\
device.c
\
directory.c
\
...
...
server/context_alpha.c
deleted
100644 → 0
View file @
53929f19
/*
* Alpha register context support
*
* Copyright (C) 2004 Vincent Béron
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "config.h"
#ifdef __ALPHA__
#include <assert.h>
#include <errno.h>
#ifdef HAVE_SYS_REG_H
# include <sys/reg.h>
#endif
#include <stdarg.h>
#include <unistd.h>
#ifdef HAVE_SYS_PTRACE_H
# include <sys/ptrace.h>
#endif
#include "file.h"
#include "thread.h"
#include "request.h"
#if 0 /* no longer used */
#ifdef HAVE_SYS_USER_H
# include <sys/user.h>
#endif
/* user definitions from asm/user.h */
struct kernel_user_struct
{
unsigned long regs[EF_SIZE/8+32];
size_t u_tsize;
size_t u_dsize;
size_t u_ssize;
unsigned long start_code;
unsigned long start_data;
unsigned long start_stack;
long int signal;
struct regs * u_ar0;
unsigned long magic;
char u_comm[32];
};
/* get thread context */
static void get_thread_context( struct thread *thread, unsigned int flags, CONTEXT *context )
{
int pid = get_ptrace_pid(thread);
if (flags & CONTEXT_FULL)
{
struct kernel_user_struct regs;
if (ptrace( PTRACE_GETREGS, pid, 0, ®s ) == -1) goto error;
if (flags & CONTEXT_INTEGER)
{
context->IntV0 = regs.regs[EF_V0];
context->IntT0 = regs.regs[EF_T0];
context->IntT1 = regs.regs[EF_T1];
context->IntT2 = regs.regs[EF_T2];
context->IntT3 = regs.regs[EF_T3];
context->IntT4 = regs.regs[EF_T4];
context->IntT5 = regs.regs[EF_T5];
context->IntT6 = regs.regs[EF_T6];
context->IntT7 = regs.regs[EF_T7];
context->IntS0 = regs.regs[EF_S0];
context->IntS1 = regs.regs[EF_S1];
context->IntS2 = regs.regs[EF_S2];
context->IntS3 = regs.regs[EF_S3];
context->IntS4 = regs.regs[EF_S4];
context->IntS5 = regs.regs[EF_S5];
context->IntFp = regs.regs[EF_S6];
context->IntA0 = regs.regs[EF_A0];
context->IntA1 = regs.regs[EF_A1];
context->IntA2 = regs.regs[EF_A2];
context->IntA3 = regs.regs[EF_A3];
context->IntA4 = regs.regs[EF_A4];
context->IntA5 = regs.regs[EF_A5];
context->IntT8 = regs.regs[EF_T8];
context->IntT9 = regs.regs[EF_T9];
context->IntT10 = regs.regs[EF_T10];
context->IntT11 = regs.regs[EF_T11];
context->IntT12 = regs.regs[EF_T12];
context->IntAt = regs.regs[EF_AT];
context->IntZero = 0;
}
if (flags & CONTEXT_CONTROL)
{
context->IntRa = regs.regs[EF_RA];
context->IntGp = regs.regs[EF_GP];
context->IntSp = regs.regs[EF_SP];
context->Fir = regs.regs[EF_PC];
context->Psr = regs.regs[EF_PS];
}
if (flags & CONTEXT_FLOATING_POINT)
{
context->FltF0 = regs.regs[EF_SIZE/8+0];
context->FltF1 = regs.regs[EF_SIZE/8+1];
context->FltF2 = regs.regs[EF_SIZE/8+2];
context->FltF3 = regs.regs[EF_SIZE/8+3];
context->FltF4 = regs.regs[EF_SIZE/8+4];
context->FltF5 = regs.regs[EF_SIZE/8+5];
context->FltF6 = regs.regs[EF_SIZE/8+6];
context->FltF7 = regs.regs[EF_SIZE/8+7];
context->FltF8 = regs.regs[EF_SIZE/8+8];
context->FltF9 = regs.regs[EF_SIZE/8+9];
context->FltF10 = regs.regs[EF_SIZE/8+10];
context->FltF11 = regs.regs[EF_SIZE/8+11];
context->FltF12 = regs.regs[EF_SIZE/8+12];
context->FltF13 = regs.regs[EF_SIZE/8+13];
context->FltF14 = regs.regs[EF_SIZE/8+14];
context->FltF15 = regs.regs[EF_SIZE/8+15];
context->FltF16 = regs.regs[EF_SIZE/8+16];
context->FltF17 = regs.regs[EF_SIZE/8+17];
context->FltF18 = regs.regs[EF_SIZE/8+18];
context->FltF19 = regs.regs[EF_SIZE/8+19];
context->FltF20 = regs.regs[EF_SIZE/8+20];
context->FltF21 = regs.regs[EF_SIZE/8+21];
context->FltF22 = regs.regs[EF_SIZE/8+22];
context->FltF23 = regs.regs[EF_SIZE/8+23];
context->FltF24 = regs.regs[EF_SIZE/8+24];
context->FltF25 = regs.regs[EF_SIZE/8+25];
context->FltF26 = regs.regs[EF_SIZE/8+26];
context->FltF27 = regs.regs[EF_SIZE/8+27];
context->FltF28 = regs.regs[EF_SIZE/8+28];
context->FltF29 = regs.regs[EF_SIZE/8+29];
context->FltF30 = regs.regs[EF_SIZE/8+30];
context->FltF31 = 0;
context->Fpcr = regs.regs[EF_SIZE/8+31];
context->SoftFpcr = 0; /* FIXME */
}
context->ContextFlags |= flags & CONTEXT_FULL;
}
return;
error:
file_set_error();
}
/* set a thread context */
static void set_thread_context( struct thread *thread, unsigned int flags, const CONTEXT *context )
{
int pid = get_ptrace_pid(thread);
if (flags & CONTEXT_FULL)
{
struct kernel_user_struct regs;
if (ptrace( PTRACE_GETREGS, pid, 0, ®s ) == -1) goto error;
if (flags & CONTEXT_INTEGER)
{
regs.regs[EF_V0] = context->IntV0;
regs.regs[EF_T0] = context->IntT0;
regs.regs[EF_T1] = context->IntT1;
regs.regs[EF_T2] = context->IntT2;
regs.regs[EF_T3] = context->IntT3;
regs.regs[EF_T4] = context->IntT4;
regs.regs[EF_T5] = context->IntT5;
regs.regs[EF_T6] = context->IntT6;
regs.regs[EF_T7] = context->IntT7;
regs.regs[EF_S0] = context->IntS0;
regs.regs[EF_S1] = context->IntS1;
regs.regs[EF_S2] = context->IntS2;
regs.regs[EF_S3] = context->IntS3;
regs.regs[EF_S4] = context->IntS4;
regs.regs[EF_S5] = context->IntS5;
regs.regs[EF_S6] = context->IntFp;
regs.regs[EF_A0] = context->IntA0;
regs.regs[EF_A1] = context->IntA1;
regs.regs[EF_A2] = context->IntA2;
regs.regs[EF_A3] = context->IntA3;
regs.regs[EF_A4] = context->IntA4;
regs.regs[EF_A5] = context->IntA5;
regs.regs[EF_T8] = context->IntT8;
regs.regs[EF_T9] = context->IntT9;
regs.regs[EF_T10] = context->IntT10;
regs.regs[EF_T11] = context->IntT11;
regs.regs[EF_T12] = context->IntT12;
regs.regs[EF_AT] = context->IntAt;
}
if (flags & CONTEXT_CONTROL)
{
regs.regs[EF_RA] = context->IntRa;
regs.regs[EF_GP] = context->IntGp;
regs.regs[EF_SP] = context->IntSp;
regs.regs[EF_PC] = context->Fir;
regs.regs[EF_PS] = context->Psr;
}
if (flags & CONTEXT_FLOATING_POINT)
{
regs.regs[EF_SIZE/8+0] = context->FltF0;
regs.regs[EF_SIZE/8+1] = context->FltF1;
regs.regs[EF_SIZE/8+2] = context->FltF2;
regs.regs[EF_SIZE/8+3] = context->FltF3;
regs.regs[EF_SIZE/8+4] = context->FltF4;
regs.regs[EF_SIZE/8+5] = context->FltF5;
regs.regs[EF_SIZE/8+6] = context->FltF6;
regs.regs[EF_SIZE/8+7] = context->FltF7;
regs.regs[EF_SIZE/8+8] = context->FltF8;
regs.regs[EF_SIZE/8+9] = context->FltF9;
regs.regs[EF_SIZE/8+10] = context->FltF10;
regs.regs[EF_SIZE/8+11] = context->FltF11;
regs.regs[EF_SIZE/8+12] = context->FltF12;
regs.regs[EF_SIZE/8+13] = context->FltF13;
regs.regs[EF_SIZE/8+14] = context->FltF14;
regs.regs[EF_SIZE/8+15] = context->FltF15;
regs.regs[EF_SIZE/8+16] = context->FltF16;
regs.regs[EF_SIZE/8+17] = context->FltF17;
regs.regs[EF_SIZE/8+18] = context->FltF18;
regs.regs[EF_SIZE/8+19] = context->FltF19;
regs.regs[EF_SIZE/8+20] = context->FltF20;
regs.regs[EF_SIZE/8+21] = context->FltF21;
regs.regs[EF_SIZE/8+22] = context->FltF22;
regs.regs[EF_SIZE/8+23] = context->FltF23;
regs.regs[EF_SIZE/8+24] = context->FltF24;
regs.regs[EF_SIZE/8+25] = context->FltF25;
regs.regs[EF_SIZE/8+26] = context->FltF26;
regs.regs[EF_SIZE/8+27] = context->FltF27;
regs.regs[EF_SIZE/8+28] = context->FltF28;
regs.regs[EF_SIZE/8+29] = context->FltF29;
regs.regs[EF_SIZE/8+30] = context->FltF30;
regs.regs[EF_SIZE/8+31] = context->Fpcr;
}
if (ptrace( PTRACE_SETREGS, pid, 0, ®s ) == -1) goto error;
}
return;
error:
file_set_error();
}
#endif /* 0 */
/* copy a context structure according to the flags */
void
copy_context
(
CONTEXT
*
to
,
const
CONTEXT
*
from
,
unsigned
int
flags
)
{
flags
&=
~
CONTEXT_ALPHA
;
/* get rid of CPU id */
if
(
flags
&
CONTEXT_CONTROL
)
{
to
->
IntRa
=
from
->
IntRa
;
to
->
IntGp
=
from
->
IntGp
;
to
->
IntSp
=
from
->
IntSp
;
to
->
Fir
=
from
->
Fir
;
to
->
Psr
=
from
->
Psr
;
}
if
(
flags
&
CONTEXT_INTEGER
)
{
to
->
IntV0
=
from
->
IntV0
;
to
->
IntT0
=
from
->
IntT0
;
to
->
IntT1
=
from
->
IntT1
;
to
->
IntT2
=
from
->
IntT2
;
to
->
IntT3
=
from
->
IntT3
;
to
->
IntT4
=
from
->
IntT4
;
to
->
IntT5
=
from
->
IntT5
;
to
->
IntT6
=
from
->
IntT6
;
to
->
IntT7
=
from
->
IntT7
;
to
->
IntS0
=
from
->
IntS0
;
to
->
IntS1
=
from
->
IntS1
;
to
->
IntS2
=
from
->
IntS2
;
to
->
IntS3
=
from
->
IntS3
;
to
->
IntS4
=
from
->
IntS4
;
to
->
IntS5
=
from
->
IntS5
;
to
->
IntFp
=
from
->
IntFp
;
to
->
IntA0
=
from
->
IntA0
;
to
->
IntA1
=
from
->
IntA1
;
to
->
IntA2
=
from
->
IntA2
;
to
->
IntA3
=
from
->
IntA3
;
to
->
IntA4
=
from
->
IntA4
;
to
->
IntA5
=
from
->
IntA5
;
to
->
IntT8
=
from
->
IntT8
;
to
->
IntT9
=
from
->
IntT9
;
to
->
IntT10
=
from
->
IntT10
;
to
->
IntT11
=
from
->
IntT11
;
to
->
IntT12
=
from
->
IntT12
;
to
->
IntAt
=
from
->
IntAt
;
to
->
IntZero
=
from
->
IntZero
;
}
if
(
flags
&
CONTEXT_FLOATING_POINT
)
{
to
->
FltF0
=
from
->
FltF0
;
to
->
FltF1
=
from
->
FltF1
;
to
->
FltF2
=
from
->
FltF2
;
to
->
FltF3
=
from
->
FltF3
;
to
->
FltF4
=
from
->
FltF4
;
to
->
FltF5
=
from
->
FltF5
;
to
->
FltF6
=
from
->
FltF6
;
to
->
FltF7
=
from
->
FltF7
;
to
->
FltF8
=
from
->
FltF8
;
to
->
FltF9
=
from
->
FltF9
;
to
->
FltF10
=
from
->
FltF10
;
to
->
FltF11
=
from
->
FltF11
;
to
->
FltF12
=
from
->
FltF12
;
to
->
FltF13
=
from
->
FltF13
;
to
->
FltF14
=
from
->
FltF14
;
to
->
FltF15
=
from
->
FltF15
;
to
->
FltF16
=
from
->
FltF16
;
to
->
FltF17
=
from
->
FltF17
;
to
->
FltF18
=
from
->
FltF18
;
to
->
FltF19
=
from
->
FltF19
;
to
->
FltF20
=
from
->
FltF20
;
to
->
FltF21
=
from
->
FltF21
;
to
->
FltF22
=
from
->
FltF22
;
to
->
FltF23
=
from
->
FltF23
;
to
->
FltF24
=
from
->
FltF24
;
to
->
FltF25
=
from
->
FltF25
;
to
->
FltF26
=
from
->
FltF26
;
to
->
FltF27
=
from
->
FltF27
;
to
->
FltF28
=
from
->
FltF28
;
to
->
FltF29
=
from
->
FltF29
;
to
->
FltF30
=
from
->
FltF30
;
to
->
FltF31
=
from
->
FltF31
;
to
->
Fpcr
=
from
->
Fpcr
;
to
->
SoftFpcr
=
from
->
SoftFpcr
;
}
to
->
ContextFlags
|=
flags
;
}
/* retrieve the current instruction pointer of a context */
client_ptr_t
get_context_ip
(
const
CONTEXT
*
context
)
{
return
context
->
Fir
;
}
/* return the context flag that contains the CPU id */
unsigned
int
get_context_cpu_flag
(
void
)
{
return
CONTEXT_ALPHA
;
}
/* return only the context flags that correspond to system regs */
/* (system regs are the ones we can't access on the client side) */
unsigned
int
get_context_system_regs
(
unsigned
int
flags
)
{
return
0
;
/* FIXME: implement client-side handling */
}
#endif
/* __ALPHA__ */
server/context_i386.c
deleted
100644 → 0
View file @
53929f19
/*
* i386 register context support
*
* Copyright (C) 1999 Alexandre Julliard
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "config.h"
#ifdef __i386__
#include <assert.h>
#include <errno.h>
#include <stdarg.h>
#include <unistd.h>
#include "windef.h"
#include "file.h"
#include "thread.h"
#include "request.h"
/* copy a context structure according to the flags */
void
copy_context
(
CONTEXT
*
to
,
const
CONTEXT
*
from
,
unsigned
int
flags
)
{
flags
&=
~
CONTEXT_i386
;
/* get rid of CPU id */
if
(
flags
&
CONTEXT_CONTROL
)
{
to
->
Ebp
=
from
->
Ebp
;
to
->
Eip
=
from
->
Eip
;
to
->
Esp
=
from
->
Esp
;
to
->
SegCs
=
from
->
SegCs
;
to
->
SegSs
=
from
->
SegSs
;
to
->
EFlags
=
from
->
EFlags
;
}
if
(
flags
&
CONTEXT_INTEGER
)
{
to
->
Eax
=
from
->
Eax
;
to
->
Ebx
=
from
->
Ebx
;
to
->
Ecx
=
from
->
Ecx
;
to
->
Edx
=
from
->
Edx
;
to
->
Esi
=
from
->
Esi
;
to
->
Edi
=
from
->
Edi
;
}
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
->
FloatSave
=
from
->
FloatSave
;
}
if
(
flags
&
CONTEXT_EXTENDED_REGISTERS
)
{
memcpy
(
to
->
ExtendedRegisters
,
from
->
ExtendedRegisters
,
sizeof
(
to
->
ExtendedRegisters
)
);
}
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
;
}
to
->
ContextFlags
|=
flags
;
}
/* retrieve the current instruction pointer of a context */
client_ptr_t
get_context_ip
(
const
CONTEXT
*
context
)
{
return
context
->
Eip
;
}
/* return the context flag that contains the CPU id */
unsigned
int
get_context_cpu_flag
(
void
)
{
return
CONTEXT_i386
;
}
/* return only the context flags that correspond to system regs */
/* (system regs are the ones we can't access on the client side) */
unsigned
int
get_context_system_regs
(
unsigned
int
flags
)
{
return
flags
&
(
CONTEXT_DEBUG_REGISTERS
&
~
CONTEXT_i386
);
}
#endif
/* __i386__ */
server/context_powerpc.c
deleted
100644 → 0
View file @
53929f19
/*
* PowerPC register context support
*
* Copyright (C) 2002 Marcus Meissner, SuSE Linux AG.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "config.h"
#ifdef __powerpc__
#include <assert.h>
#include <errno.h>
#include <sys/types.h>
#ifdef HAVE_SYS_REG_H
# include <sys/reg.h>
#endif
#include <stdarg.h>
#include <unistd.h>
#ifdef HAVE_SYS_PTRACE_H
# include <sys/ptrace.h>
#endif
#include "windef.h"
#if 0 /* no longer used */
#ifndef PTRACE_PEEKUSER
# ifdef PT_READ_D
# define PTRACE_PEEKUSER PT_READ_D
# endif
#endif /* PTRACE_PEEKUSER */
#ifndef PTRACE_POKEUSER
# ifdef PT_WRITE_D
# define PTRACE_POKEUSER PT_WRITE_D
# endif
#endif
/* PTRACE_POKEUSER */
#include "file.h"
#include "thread.h"
#include "request.h"
/* retrieve a thread context */
static
void
get_thread_context_ptrace
(
struct
thread
*
thread
,
unsigned
int
flags
,
CONTEXT
*
context
)
{
int
pid
=
get_ptrace_pid
(
thread
);
if
(
flags
&
CONTEXT_INTEGER
)
{
#define XREG(x,y) if (ptrace( PTRACE_PEEKUSER, pid, (void*)(x<<2), &context->y) == -1) goto error;
#define IREG(x) if (ptrace( PTRACE_PEEKUSER, pid, (void*)(x<<2), &context->Gpr##x) == -1) goto error;
IREG
(
0
);
IREG
(
1
);
IREG
(
2
);
IREG
(
3
);
IREG
(
4
);
IREG
(
5
);
IREG
(
6
);
IREG
(
7
);
IREG
(
8
);
IREG
(
9
);
IREG
(
10
);
IREG
(
11
);
IREG
(
12
);
IREG
(
13
);
IREG
(
14
);
IREG
(
15
);
IREG
(
16
);
IREG
(
17
);
IREG
(
18
);
IREG
(
19
);
IREG
(
20
);
IREG
(
21
);
IREG
(
22
);
IREG
(
23
);
IREG
(
24
);
IREG
(
25
);
IREG
(
26
);
IREG
(
27
);
IREG
(
28
);
IREG
(
29
);
IREG
(
30
);
IREG
(
31
);
#undef IREG
XREG
(
37
,
Xer
);
XREG
(
38
,
Cr
);
context
->
ContextFlags
|=
CONTEXT_INTEGER
;
}
if
(
flags
&
CONTEXT_CONTROL
)
{
XREG
(
32
,
Iar
);
XREG
(
33
,
Msr
);
XREG
(
35
,
Ctr
);
XREG
(
36
,
Lr
);
/* 36 is LNK ... probably Lr ? */
context
->
ContextFlags
|=
CONTEXT_CONTROL
;
}
if
(
flags
&
CONTEXT_FLOATING_POINT
)
{
#define FREG(x) if (ptrace( PTRACE_PEEKUSER, pid, (void*)((48+x*2)<<2), &context->Fpr##x) == -1) goto error;
FREG
(
0
);
FREG
(
1
);
FREG
(
2
);
FREG
(
3
);
FREG
(
4
);
FREG
(
5
);
FREG
(
6
);
FREG
(
7
);
FREG
(
8
);
FREG
(
9
);
FREG
(
10
);
FREG
(
11
);
FREG
(
12
);
FREG
(
13
);
FREG
(
14
);
FREG
(
15
);
FREG
(
16
);
FREG
(
17
);
FREG
(
18
);
FREG
(
19
);
FREG
(
20
);
FREG
(
21
);
FREG
(
22
);
FREG
(
23
);
FREG
(
24
);
FREG
(
25
);
FREG
(
26
);
FREG
(
27
);
FREG
(
28
);
FREG
(
29
);
FREG
(
30
);
FREG
(
31
);
XREG
((
48
+
32
*
2
),
Fpscr
);
context
->
ContextFlags
|=
CONTEXT_FLOATING_POINT
;
}
return
;
error:
file_set_error
();
}
#undef XREG
#undef IREG
#undef FREG
#define XREG(x,y) if (ptrace( PTRACE_POKEUSER, pid, (void*)(x<<2), &context->y) == -1) goto error;
#define IREG(x) if (ptrace( PTRACE_POKEUSER, pid, (void*)(x<<2), &context->Gpr##x) == -1) goto error;
#define FREG(x) if (ptrace( PTRACE_POKEUSER, pid, (void*)((48+x*2)<<2), &context->Fpr##x) == -1) goto error;
/* set a thread context */
static
void
set_thread_context_ptrace
(
struct
thread
*
thread
,
unsigned
int
flags
,
const
CONTEXT
*
context
)
{
int
pid
=
get_ptrace_pid
(
thread
);
if
(
flags
&
CONTEXT_FULL
)
{
if
(
flags
&
CONTEXT_INTEGER
)
{
IREG
(
0
);
IREG
(
1
);
IREG
(
2
);
IREG
(
3
);
IREG
(
4
);
IREG
(
5
);
IREG
(
6
);
IREG
(
7
);
IREG
(
8
);
IREG
(
9
);
IREG
(
10
);
IREG
(
11
);
IREG
(
12
);
IREG
(
13
);
IREG
(
14
);
IREG
(
15
);
IREG
(
16
);
IREG
(
17
);
IREG
(
18
);
IREG
(
19
);
IREG
(
20
);
IREG
(
21
);
IREG
(
22
);
IREG
(
23
);
IREG
(
24
);
IREG
(
25
);
IREG
(
26
);
IREG
(
27
);
IREG
(
28
);
IREG
(
29
);
IREG
(
30
);
IREG
(
31
);
XREG
(
37
,
Xer
);
XREG
(
38
,
Cr
);
}
if
(
flags
&
CONTEXT_CONTROL
)
{
XREG
(
32
,
Iar
);
XREG
(
33
,
Msr
);
XREG
(
35
,
Ctr
);
XREG
(
36
,
Lr
);
}
}
if
(
flags
&
CONTEXT_FLOATING_POINT
)
{
FREG
(
0
);
FREG
(
1
);
FREG
(
2
);
FREG
(
3
);
FREG
(
4
);
FREG
(
5
);
FREG
(
6
);
FREG
(
7
);
FREG
(
8
);
FREG
(
9
);
FREG
(
10
);
FREG
(
11
);
FREG
(
12
);
FREG
(
13
);
FREG
(
14
);
FREG
(
15
);
FREG
(
16
);
FREG
(
17
);
FREG
(
18
);
FREG
(
19
);
FREG
(
20
);
FREG
(
21
);
FREG
(
22
);
FREG
(
23
);
FREG
(
24
);
FREG
(
25
);
FREG
(
26
);
FREG
(
27
);
FREG
(
28
);
FREG
(
29
);
FREG
(
30
);
FREG
(
31
);
#undef FREG
XREG
((
48
+
32
*
2
),
Fpscr
);
}
return
;
error:
file_set_error
();
}
#undef XREG
#undef IREG
#undef FREG
#endif
/* 0 */
#define IREG(x) to->Gpr##x = from->Gpr##x;
#define FREG(x) to->Fpr##x = from->Fpr##x;
#define CREG(x) to->x = from->x;
/* copy a context structure according to the flags */
void
copy_context
(
CONTEXT
*
to
,
const
CONTEXT
*
from
,
unsigned
int
flags
)
{
if
(
flags
&
CONTEXT_CONTROL
)
{
CREG
(
Msr
);
CREG
(
Ctr
);
CREG
(
Iar
);
to
->
ContextFlags
|=
CONTEXT_CONTROL
;
}
if
(
flags
&
CONTEXT_INTEGER
)
{
IREG
(
0
);
IREG
(
1
);
IREG
(
2
);
IREG
(
3
);
IREG
(
4
);
IREG
(
5
);
IREG
(
6
);
IREG
(
7
);
IREG
(
8
);
IREG
(
9
);
IREG
(
10
);
IREG
(
11
);
IREG
(
12
);
IREG
(
13
);
IREG
(
14
);
IREG
(
15
);
IREG
(
16
);
IREG
(
17
);
IREG
(
18
);
IREG
(
19
);
IREG
(
20
);
IREG
(
21
);
IREG
(
22
);
IREG
(
23
);
IREG
(
24
);
IREG
(
25
);
IREG
(
26
);
IREG
(
27
);
IREG
(
28
);
IREG
(
29
);
IREG
(
30
);
IREG
(
31
);
CREG
(
Xer
);
CREG
(
Cr
);
to
->
ContextFlags
|=
CONTEXT_INTEGER
;
}
if
(
flags
&
CONTEXT_FLOATING_POINT
)
{
FREG
(
0
);
FREG
(
1
);
FREG
(
2
);
FREG
(
3
);
FREG
(
4
);
FREG
(
5
);
FREG
(
6
);
FREG
(
7
);
FREG
(
8
);
FREG
(
9
);
FREG
(
10
);
FREG
(
11
);
FREG
(
12
);
FREG
(
13
);
FREG
(
14
);
FREG
(
15
);
FREG
(
16
);
FREG
(
17
);
FREG
(
18
);
FREG
(
19
);
FREG
(
20
);
FREG
(
21
);
FREG
(
22
);
FREG
(
23
);
FREG
(
24
);
FREG
(
25
);
FREG
(
26
);
FREG
(
27
);
FREG
(
28
);
FREG
(
29
);
FREG
(
30
);
FREG
(
31
);
CREG
(
Fpscr
);
to
->
ContextFlags
|=
CONTEXT_FLOATING_POINT
;
}
}
/* retrieve the current instruction pointer of a context */
client_ptr_t
get_context_ip
(
const
CONTEXT
*
context
)
{
return
context
->
Iar
;
}
/* return the context flag that contains the CPU id */
unsigned
int
get_context_cpu_flag
(
void
)
{
return
0
;
}
/* return only the context flags that correspond to system regs */
/* (system regs are the ones we can't access on the client side) */
unsigned
int
get_context_system_regs
(
unsigned
int
flags
)
{
return
0
;
/* FIXME: implement client-side handling */
}
#endif
/* __powerpc__ */
server/context_sparc.c
deleted
100644 → 0
View file @
53929f19
/*
* Sparc register context support
*
* Copyright (C) 2000 Ulrich Weigand
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "config.h"
#ifdef __sparc__
#include <assert.h>
#include <errno.h>
#include <sys/types.h>
#ifdef HAVE_SYS_REG_H
# include <sys/reg.h>
#endif
#include <stdarg.h>
#include <unistd.h>
#ifdef HAVE_SYS_PTRACE_H
# include <sys/ptrace.h>
#endif
#include "windef.h"
#include "file.h"
#include "thread.h"
#include "request.h"
#if 0 /* no longer used */
#if defined(__sun) || defined(__sun__)
/* retrieve a thread context */
static void get_thread_context_ptrace( struct thread *thread, unsigned int flags, CONTEXT *context )
{
int pid = get_ptrace_pid(thread);
if (flags & CONTEXT_FULL)
{
struct regs regs;
if (ptrace( PTRACE_GETREGS, pid, 0, (int) ®s ) == -1) goto error;
if (flags & CONTEXT_INTEGER)
{
context->g0 = 0;
context->g1 = regs.r_g1;
context->g2 = regs.r_g2;
context->g3 = regs.r_g3;
context->g4 = regs.r_g4;
context->g5 = regs.r_g5;
context->g6 = regs.r_g6;
context->g7 = regs.r_g7;
context->o0 = regs.r_o0;
context->o1 = regs.r_o1;
context->o2 = regs.r_o2;
context->o3 = regs.r_o3;
context->o4 = regs.r_o4;
context->o5 = regs.r_o5;
context->o6 = regs.r_o6;
context->o7 = regs.r_o7;
/* FIXME: local and in registers */
}
if (flags & CONTEXT_CONTROL)
{
context->psr = regs.r_psr;
context->pc = regs.r_pc;
context->npc = regs.r_npc;
context->y = regs.r_y;
context->wim = 0; /* FIXME */
context->tbr = 0; /* FIXME */
}
context |= flags & (CONTEXT_CONTROL|CONTEXT_INTEGER);
}
if (flags & CONTEXT_FLOATING_POINT)
{
/* FIXME */
}
return;
error:
file_set_error();
}
/* set a thread context */
static void set_thread_context_ptrace( struct thread *thread, unsigned int flags, const CONTEXT *context )
{
/* FIXME */
}
#else /* __sun__ */
#error You must implement get/set_thread_context_ptrace for your platform
#endif /* __sun__ */
#endif
/* 0 */
/* copy a context structure according to the flags */
void
copy_context
(
CONTEXT
*
to
,
const
CONTEXT
*
from
,
unsigned
int
flags
)
{
flags
&=
~
CONTEXT_SPARC
;
/* get rid of CPU id */
if
(
flags
&
CONTEXT_CONTROL
)
{
to
->
psr
=
from
->
psr
;
to
->
pc
=
from
->
pc
;
to
->
npc
=
from
->
npc
;
to
->
y
=
from
->
y
;
to
->
wim
=
from
->
wim
;
to
->
tbr
=
from
->
tbr
;
}
if
(
flags
&
CONTEXT_INTEGER
)
{
to
->
g0
=
from
->
g0
;
to
->
g1
=
from
->
g1
;
to
->
g2
=
from
->
g2
;
to
->
g3
=
from
->
g3
;
to
->
g4
=
from
->
g4
;
to
->
g5
=
from
->
g5
;
to
->
g6
=
from
->
g6
;
to
->
g7
=
from
->
g7
;
to
->
o0
=
from
->
o0
;
to
->
o1
=
from
->
o1
;
to
->
o2
=
from
->
o2
;
to
->
o3
=
from
->
o3
;
to
->
o4
=
from
->
o4
;
to
->
o5
=
from
->
o5
;
to
->
o6
=
from
->
o6
;
to
->
o7
=
from
->
o7
;
to
->
l0
=
from
->
l0
;
to
->
l1
=
from
->
l1
;
to
->
l2
=
from
->
l2
;
to
->
l3
=
from
->
l3
;
to
->
l4
=
from
->
l4
;
to
->
l5
=
from
->
l5
;
to
->
l6
=
from
->
l6
;
to
->
l7
=
from
->
l7
;
to
->
i0
=
from
->
i0
;
to
->
i1
=
from
->
i1
;
to
->
i2
=
from
->
i2
;
to
->
i3
=
from
->
i3
;
to
->
i4
=
from
->
i4
;
to
->
i5
=
from
->
i5
;
to
->
i6
=
from
->
i6
;
to
->
i7
=
from
->
i7
;
}
if
(
flags
&
CONTEXT_FLOATING_POINT
)
{
/* FIXME */
}
context
|=
flags
&
(
CONTEXT_CONTROL
|
CONTEXT_INTEGER
);
}
/* retrieve the current instruction pointer of a context */
client_ptr_t
get_context_ip
(
const
CONTEXT
*
context
)
{
return
context
->
pc
;
}
/* return the context flag that contains the CPU id */
unsigned
int
get_context_cpu_flag
(
void
)
{
return
CONTEXT_SPARC
;
}
/* return only the context flags that correspond to system regs */
/* (system regs are the ones we can't access on the client side) */
unsigned
int
get_context_system_regs
(
unsigned
int
flags
)
{
return
0
;
/* FIXME: implement client-side handling */
}
#endif
/* __sparc__ */
server/context_x86_64.c
deleted
100644 → 0
View file @
53929f19
/*
* x86-64 register context support
*
* Copyright (C) 1999, 2005 Alexandre Julliard
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "config.h"
#ifdef __x86_64__
#include <assert.h>
#include <errno.h>
#include <stdarg.h>
#include <unistd.h>
#define NONAMELESSUNION
#include "windef.h"
#include "winbase.h"
#include "file.h"
#include "thread.h"
#include "request.h"
/* copy a context structure according to the flags */
void
copy_context
(
CONTEXT
*
to
,
const
CONTEXT
*
from
,
unsigned
int
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
;
to
->
MxCsr
=
from
->
MxCsr
;
}
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
->
u
.
FltSave
=
from
->
u
.
FltSave
;
}
/* we don't bother copying the debug registers, since they */
/* always need to be accessed by ptrace anyway */
to
->
ContextFlags
|=
flags
&
~
CONTEXT_DEBUG_REGISTERS
;
}
/* retrieve the current instruction pointer of a context */
client_ptr_t
get_context_ip
(
const
CONTEXT
*
context
)
{
return
context
->
Rip
;
}
/* return the context flag that contains the CPU id */
unsigned
int
get_context_cpu_flag
(
void
)
{
return
CONTEXT_AMD64
;
}
/* return only the context flags that correspond to system regs */
/* (system regs are the ones we can't access on the client side) */
unsigned
int
get_context_system_regs
(
unsigned
int
flags
)
{
return
flags
&
(
CONTEXT_DEBUG_REGISTERS
&
~
CONTEXT_AMD64
);
}
#endif
/* __x86_64__ */
server/debugger.c
View file @
5316dd01
...
...
@@ -49,7 +49,7 @@ struct debug_event
enum
debug_event_state
state
;
/* event state */
int
status
;
/* continuation status */
debug_event_t
data
;
/* event data */
CONTEXT
context
;
/* register context */
context_t
context
;
/* register context */
};
/* debug context */
...
...
@@ -652,11 +652,11 @@ DECL_HANDLER(queue_exception_event)
if
((
event
=
alloc_debug_event
(
current
,
EXCEPTION_DEBUG_EVENT
,
&
data
)))
{
const
CONTEXT
*
context
=
(
const
CONTEXT
*
)((
char
*
)
get_req_data
()
+
req
->
len
);
const
context_t
*
context
=
(
const
context_t
*
)((
char
*
)
get_req_data
()
+
req
->
len
);
data_size_t
size
=
get_req_data_size
()
-
req
->
len
;
memset
(
&
event
->
context
,
0
,
sizeof
(
event
->
context
)
);
memcpy
(
&
event
->
context
,
context
,
size
);
memcpy
(
&
event
->
context
,
context
,
min
(
sizeof
(
event
->
context
),
size
)
);
current
->
context
=
&
event
->
context
;
if
((
reply
->
handle
=
alloc_handle
(
current
->
process
,
event
,
SYNCHRONIZE
,
0
)))
...
...
@@ -682,7 +682,7 @@ DECL_HANDLER(get_exception_status)
{
if
(
current
->
context
==
&
event
->
context
)
{
data_size_t
size
=
min
(
sizeof
(
CONTEXT
),
get_reply_max_size
()
);
data_size_t
size
=
min
(
sizeof
(
context_t
),
get_reply_max_size
()
);
set_reply_data
(
&
event
->
context
,
size
);
current
->
context
=
NULL
;
}
...
...
server/mach.c
View file @
5316dd01
...
...
@@ -160,7 +160,7 @@ void finish_process_tracing( struct process *process )
}
/* retrieve the thread x86 registers */
void
get_thread_context
(
struct
thread
*
thread
,
CONTEXT
*
context
,
unsigned
int
flags
)
void
get_thread_context
(
struct
thread
*
thread
,
context_t
*
context
,
unsigned
int
flags
)
{
#ifdef __i386__
x86_debug_state32_t
state
;
...
...
@@ -169,7 +169,7 @@ void get_thread_context( struct thread *thread, CONTEXT *context, unsigned int f
mach_port_t
port
,
process_port
=
get_process_port
(
thread
->
process
);
/* all other regs are handled on the client side */
assert
(
(
flags
|
CONTEXT_i386
)
==
CONTEXT
_DEBUG_REGISTERS
);
assert
(
flags
==
SERVER_CTX
_DEBUG_REGISTERS
);
if
(
thread
->
unix_pid
==
-
1
||
!
process_port
||
mach_port_extract_right
(
process_port
,
thread
->
unix_tid
,
...
...
@@ -183,28 +183,28 @@ void get_thread_context( struct thread *thread, CONTEXT *context, unsigned int f
{
/* work around silly renaming of struct members in OS X 10.5 */
#if __DARWIN_UNIX03 && defined(_STRUCT_X86_DEBUG_STATE32)
context
->
D
r0
=
state
.
__dr0
;
context
->
D
r1
=
state
.
__dr1
;
context
->
D
r2
=
state
.
__dr2
;
context
->
D
r3
=
state
.
__dr3
;
context
->
D
r6
=
state
.
__dr6
;
context
->
D
r7
=
state
.
__dr7
;
context
->
debug
.
i386_regs
.
d
r0
=
state
.
__dr0
;
context
->
debug
.
i386_regs
.
d
r1
=
state
.
__dr1
;
context
->
debug
.
i386_regs
.
d
r2
=
state
.
__dr2
;
context
->
debug
.
i386_regs
.
d
r3
=
state
.
__dr3
;
context
->
debug
.
i386_regs
.
d
r6
=
state
.
__dr6
;
context
->
debug
.
i386_regs
.
d
r7
=
state
.
__dr7
;
#else
context
->
D
r0
=
state
.
dr0
;
context
->
D
r1
=
state
.
dr1
;
context
->
D
r2
=
state
.
dr2
;
context
->
D
r3
=
state
.
dr3
;
context
->
D
r6
=
state
.
dr6
;
context
->
D
r7
=
state
.
dr7
;
context
->
debug
.
i386_regs
.
d
r0
=
state
.
dr0
;
context
->
debug
.
i386_regs
.
d
r1
=
state
.
dr1
;
context
->
debug
.
i386_regs
.
d
r2
=
state
.
dr2
;
context
->
debug
.
i386_regs
.
d
r3
=
state
.
dr3
;
context
->
debug
.
i386_regs
.
d
r6
=
state
.
dr6
;
context
->
debug
.
i386_regs
.
d
r7
=
state
.
dr7
;
#endif
context
->
ContextFlags
|=
CONTEXT
_DEBUG_REGISTERS
;
context
->
flags
|=
SERVER_CTX
_DEBUG_REGISTERS
;
}
mach_port_deallocate
(
mach_task_self
(),
port
);
#endif
}
/* set the thread x86 registers */
void
set_thread_context
(
struct
thread
*
thread
,
const
CONTEXT
*
context
,
unsigned
int
flags
)
void
set_thread_context
(
struct
thread
*
thread
,
const
context_t
*
context
,
unsigned
int
flags
)
{
#ifdef __i386__
x86_debug_state32_t
state
;
...
...
@@ -213,7 +213,7 @@ void set_thread_context( struct thread *thread, const CONTEXT *context, unsigned
mach_port_t
port
,
process_port
=
get_process_port
(
thread
->
process
);
/* all other regs are handled on the client side */
assert
(
(
flags
|
CONTEXT_i386
)
==
CONTEXT
_DEBUG_REGISTERS
);
assert
(
flags
==
SERVER_CTX
_DEBUG_REGISTERS
);
if
(
thread
->
unix_pid
==
-
1
||
!
process_port
||
mach_port_extract_right
(
process_port
,
thread
->
unix_tid
,
...
...
@@ -224,35 +224,28 @@ void set_thread_context( struct thread *thread, const CONTEXT *context, unsigned
}
#if __DARWIN_UNIX03 && defined(_STRUCT_X86_DEBUG_STATE32)
state
.
__dr0
=
context
->
D
r0
;
state
.
__dr1
=
context
->
D
r1
;
state
.
__dr2
=
context
->
D
r2
;
state
.
__dr3
=
context
->
D
r3
;
state
.
__dr0
=
context
->
debug
.
i386_regs
.
d
r0
;
state
.
__dr1
=
context
->
debug
.
i386_regs
.
d
r1
;
state
.
__dr2
=
context
->
debug
.
i386_regs
.
d
r2
;
state
.
__dr3
=
context
->
debug
.
i386_regs
.
d
r3
;
state
.
__dr4
=
0
;
state
.
__dr5
=
0
;
state
.
__dr6
=
context
->
D
r6
;
state
.
__dr7
=
context
->
D
r7
;
state
.
__dr6
=
context
->
debug
.
i386_regs
.
d
r6
;
state
.
__dr7
=
context
->
debug
.
i386_regs
.
d
r7
;
#else
state
.
dr0
=
context
->
D
r0
;
state
.
dr1
=
context
->
D
r1
;
state
.
dr2
=
context
->
D
r2
;
state
.
dr3
=
context
->
D
r3
;
state
.
dr0
=
context
->
debug
.
i386_regs
.
d
r0
;
state
.
dr1
=
context
->
debug
.
i386_regs
.
d
r1
;
state
.
dr2
=
context
->
debug
.
i386_regs
.
d
r2
;
state
.
dr3
=
context
->
debug
.
i386_regs
.
d
r3
;
state
.
dr4
=
0
;
state
.
dr5
=
0
;
state
.
dr6
=
context
->
D
r6
;
state
.
dr7
=
context
->
D
r7
;
state
.
dr6
=
context
->
debug
.
i386_regs
.
d
r6
;
state
.
dr7
=
context
->
debug
.
i386_regs
.
d
r7
;
#endif
if
(
!
thread_set_state
(
port
,
x86_DEBUG_STATE32
,
(
thread_state_t
)
&
state
,
count
))
{
if
(
thread
->
context
)
/* update the cached values */
{
thread
->
context
->
Dr0
=
context
->
Dr0
;
thread
->
context
->
Dr1
=
context
->
Dr1
;
thread
->
context
->
Dr2
=
context
->
Dr2
;
thread
->
context
->
Dr3
=
context
->
Dr3
;
thread
->
context
->
Dr6
=
context
->
Dr6
;
thread
->
context
->
Dr7
=
context
->
Dr7
;
}
thread
->
context
->
debug
.
i386_regs
=
context
->
debug
.
i386_regs
;
}
mach_port_deallocate
(
mach_task_self
(),
port
);
#endif
...
...
server/procfs.c
View file @
5316dd01
...
...
@@ -200,20 +200,14 @@ error:
}
/* retrieve the thread registers */
void
get_thread_context
(
struct
thread
*
thread
,
CONTEXT
*
context
,
unsigned
int
flags
)
void
get_thread_context
(
struct
thread
*
thread
,
context_t
*
context
,
unsigned
int
flags
)
{
/* all other regs are handled on the client side */
assert
(
(
flags
|
CONTEXT_i386
)
==
CONTEXT_DEBUG_REGISTERS
);
/* FIXME: get debug registers */
}
/* set the thread registers */
void
set_thread_context
(
struct
thread
*
thread
,
const
CONTEXT
*
context
,
unsigned
int
flags
)
void
set_thread_context
(
struct
thread
*
thread
,
const
context_t
*
context
,
unsigned
int
flags
)
{
/* all other regs are handled on the client side */
assert
(
(
flags
|
CONTEXT_i386
)
==
CONTEXT_DEBUG_REGISTERS
);
/* FIXME: set debug registers */
}
...
...
server/protocol.def
View file @
5316dd01
...
...
@@ -150,6 +150,63 @@ enum cpu_type
};
typedef int cpu_type_t;
/* context data */
typedef struct
{
cpu_type_t cpu; /* cpu type */
unsigned int flags; /* SERVER_CTX_* flags */
union
{
struct { unsigned int eip, ebp, esp, eflags, cs, ss; } i386_regs;
struct { unsigned __int64 rip, rbp, rsp;
unsigned int cs, ss, flags, mxcsr; } x86_64_regs;
struct { unsigned __int64 fir;
unsigned int psr; } alpha_regs;
struct { unsigned int iar, msr, ctr, lr, dar, dsisr, trap; } powerpc_regs;
struct { unsigned int psr, pc, npc, y, wim, tbr; } sparc_regs;
} ctl; /* selected by SERVER_CTX_CONTROL */
union
{
struct { unsigned int eax, ebx, ecx, edx, esi, edi; } i386_regs;
struct { unsigned __int64 rax,rbx, rcx, rdx, rsi, rdi,
r8, r9, r10, r11, r12, r13, r14, r15; } x86_64_regs;
struct { unsigned __int64 v0, t0, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12,
s0, s1, s2, s3, s4, s5, s6, a0, a1, a2, a3, a4, a5, at; } alpha_regs;
struct { unsigned int gpr[32], cr, xer; } powerpc_regs;
struct { unsigned int g[8], o[8], l[8], i[8]; } sparc_regs;
} integer; /* selected by SERVER_CTX_INTEGER */
union
{
struct { unsigned int ds, es, fs, gs; } i386_regs;
struct { unsigned int ds, es, fs, gs; } x86_64_regs;
} seg; /* selected by SERVER_CTX_SEGMENTS */
union
{
struct { unsigned int ctrl, status, tag, err_off, err_sel, data_off, data_sel, cr0npx;
unsigned char regs[80]; } i386_regs;
struct { struct { unsigned __int64 low, high; } fpregs[32]; } x86_64_regs;
struct { unsigned __int64 f[32], fpcr, softfpcr; } alpha_regs;
struct { double fpr[32], fpscr; } powerpc_regs;
} fp; /* selected by SERVER_CTX_FLOATING_POINT */
union
{
struct { unsigned int dr0, dr1, dr2, dr3, dr6, dr7; } i386_regs;
struct { unsigned __int64 dr0, dr1, dr2, dr3, dr6, dr7; } x86_64_regs;
struct { unsigned int dr[8]; } powerpc_regs;
} debug; /* selected by SERVER_CTX_DEBUG_REGISTERS */
union
{
unsigned char i386_regs[512];
} ext; /* selected by SERVER_CTX_EXTENDED_REGISTERS */
} context_t;
#define SERVER_CTX_CONTROL 0x01
#define SERVER_CTX_INTEGER 0x02
#define SERVER_CTX_SEGMENTS 0x04
#define SERVER_CTX_FLOATING_POINT 0x08
#define SERVER_CTX_DEBUG_REGISTERS 0x10
#define SERVER_CTX_EXTENDED_REGISTERS 0x20
/* structure used in sending an fd from client to server */
struct send_fd
{
...
...
@@ -1732,7 +1789,6 @@ enum char_info_mode
/* Set the current context of a thread */
@REQ(set_thread_context)
obj_handle_t handle; /* thread handle */
unsigned int flags; /* context flags */
int suspend; /* if setting context during suspend */
VARARG(context,context); /* thread context */
@REPLY
...
...
server/ptrace.c
View file @
5316dd01
...
...
@@ -527,13 +527,13 @@ void get_selector_entry( struct thread *thread, int entry, unsigned int *base,
#define DR_OFFSET(dr) ((((struct user *)0)->u_debugreg) + (dr))
/* retrieve the thread x86 registers */
void
get_thread_context
(
struct
thread
*
thread
,
CONTEXT
*
context
,
unsigned
int
flags
)
void
get_thread_context
(
struct
thread
*
thread
,
context_t
*
context
,
unsigned
int
flags
)
{
int
i
,
pid
=
get_ptrace_tid
(
thread
);
long
data
[
8
];
/* all other regs are handled on the client side */
assert
(
(
flags
|
CONTEXT_i386
)
==
CONTEXT
_DEBUG_REGISTERS
);
assert
(
flags
==
SERVER_CTX
_DEBUG_REGISTERS
);
if
(
!
suspend_for_ptrace
(
thread
))
return
;
...
...
@@ -548,39 +548,39 @@ void get_thread_context( struct thread *thread, CONTEXT *context, unsigned int f
goto
done
;
}
}
context
->
D
r0
=
data
[
0
];
context
->
D
r1
=
data
[
1
];
context
->
D
r2
=
data
[
2
];
context
->
D
r3
=
data
[
3
];
context
->
D
r6
=
data
[
6
];
context
->
D
r7
=
data
[
7
];
context
->
ContextFlags
|=
CONTEXT
_DEBUG_REGISTERS
;
context
->
debug
.
i386_regs
.
d
r0
=
data
[
0
];
context
->
debug
.
i386_regs
.
d
r1
=
data
[
1
];
context
->
debug
.
i386_regs
.
d
r2
=
data
[
2
];
context
->
debug
.
i386_regs
.
d
r3
=
data
[
3
];
context
->
debug
.
i386_regs
.
d
r6
=
data
[
6
];
context
->
debug
.
i386_regs
.
d
r7
=
data
[
7
];
context
->
flags
|=
SERVER_CTX
_DEBUG_REGISTERS
;
done:
resume_after_ptrace
(
thread
);
}
/* set the thread x86 registers */
void
set_thread_context
(
struct
thread
*
thread
,
const
CONTEXT
*
context
,
unsigned
int
flags
)
void
set_thread_context
(
struct
thread
*
thread
,
const
context_t
*
context
,
unsigned
int
flags
)
{
int
pid
=
get_ptrace_tid
(
thread
);
/* all other regs are handled on the client side */
assert
(
(
flags
|
CONTEXT_i386
)
==
CONTEXT
_DEBUG_REGISTERS
);
assert
(
flags
==
SERVER_CTX
_DEBUG_REGISTERS
);
if
(
!
suspend_for_ptrace
(
thread
))
return
;
if
(
ptrace
(
PTRACE_POKEUSER
,
pid
,
DR_OFFSET
(
0
),
context
->
D
r0
)
==
-
1
)
goto
error
;
if
(
thread
->
context
)
thread
->
context
->
Dr0
=
context
->
D
r0
;
if
(
ptrace
(
PTRACE_POKEUSER
,
pid
,
DR_OFFSET
(
1
),
context
->
D
r1
)
==
-
1
)
goto
error
;
if
(
thread
->
context
)
thread
->
context
->
Dr1
=
context
->
D
r1
;
if
(
ptrace
(
PTRACE_POKEUSER
,
pid
,
DR_OFFSET
(
2
),
context
->
D
r2
)
==
-
1
)
goto
error
;
if
(
thread
->
context
)
thread
->
context
->
Dr2
=
context
->
D
r2
;
if
(
ptrace
(
PTRACE_POKEUSER
,
pid
,
DR_OFFSET
(
3
),
context
->
D
r3
)
==
-
1
)
goto
error
;
if
(
thread
->
context
)
thread
->
context
->
Dr3
=
context
->
D
r3
;
if
(
ptrace
(
PTRACE_POKEUSER
,
pid
,
DR_OFFSET
(
6
),
context
->
D
r6
)
==
-
1
)
goto
error
;
if
(
thread
->
context
)
thread
->
context
->
Dr6
=
context
->
D
r6
;
if
(
ptrace
(
PTRACE_POKEUSER
,
pid
,
DR_OFFSET
(
7
),
context
->
D
r7
)
==
-
1
)
goto
error
;
if
(
thread
->
context
)
thread
->
context
->
Dr7
=
context
->
D
r7
;
if
(
ptrace
(
PTRACE_POKEUSER
,
pid
,
DR_OFFSET
(
0
),
context
->
debug
.
i386_regs
.
d
r0
)
==
-
1
)
goto
error
;
if
(
thread
->
context
)
thread
->
context
->
debug
.
i386_regs
.
dr0
=
context
->
debug
.
i386_regs
.
d
r0
;
if
(
ptrace
(
PTRACE_POKEUSER
,
pid
,
DR_OFFSET
(
1
),
context
->
debug
.
i386_regs
.
d
r1
)
==
-
1
)
goto
error
;
if
(
thread
->
context
)
thread
->
context
->
debug
.
i386_regs
.
dr1
=
context
->
debug
.
i386_regs
.
d
r1
;
if
(
ptrace
(
PTRACE_POKEUSER
,
pid
,
DR_OFFSET
(
2
),
context
->
debug
.
i386_regs
.
d
r2
)
==
-
1
)
goto
error
;
if
(
thread
->
context
)
thread
->
context
->
debug
.
i386_regs
.
dr2
=
context
->
debug
.
i386_regs
.
d
r2
;
if
(
ptrace
(
PTRACE_POKEUSER
,
pid
,
DR_OFFSET
(
3
),
context
->
debug
.
i386_regs
.
d
r3
)
==
-
1
)
goto
error
;
if
(
thread
->
context
)
thread
->
context
->
debug
.
i386_regs
.
dr3
=
context
->
debug
.
i386_regs
.
d
r3
;
if
(
ptrace
(
PTRACE_POKEUSER
,
pid
,
DR_OFFSET
(
6
),
context
->
debug
.
i386_regs
.
d
r6
)
==
-
1
)
goto
error
;
if
(
thread
->
context
)
thread
->
context
->
debug
.
i386_regs
.
dr6
=
context
->
debug
.
i386_regs
.
d
r6
;
if
(
ptrace
(
PTRACE_POKEUSER
,
pid
,
DR_OFFSET
(
7
),
context
->
debug
.
i386_regs
.
d
r7
)
==
-
1
)
goto
error
;
if
(
thread
->
context
)
thread
->
context
->
debug
.
i386_regs
.
dr7
=
context
->
debug
.
i386_regs
.
d
r7
;
resume_after_ptrace
(
thread
);
return
;
error:
...
...
@@ -594,13 +594,13 @@ void set_thread_context( struct thread *thread, const CONTEXT *context, unsigned
#include <machine/reg.h>
/* retrieve the thread x86 registers */
void
get_thread_context
(
struct
thread
*
thread
,
CONTEXT
*
context
,
unsigned
int
flags
)
void
get_thread_context
(
struct
thread
*
thread
,
context_t
*
context
,
unsigned
int
flags
)
{
int
pid
=
get_ptrace_tid
(
thread
);
struct
dbreg
dbregs
;
/* all other regs are handled on the client side */
assert
(
(
flags
|
CONTEXT_i386
)
==
CONTEXT
_DEBUG_REGISTERS
);
assert
(
flags
==
SERVER_CTX
_DEBUG_REGISTERS
);
if
(
!
suspend_for_ptrace
(
thread
))
return
;
...
...
@@ -609,78 +609,71 @@ void get_thread_context( struct thread *thread, CONTEXT *context, unsigned int f
{
#ifdef DBREG_DRX
/* needed for FreeBSD, the structure fields have changed under 5.x */
context
->
D
r0
=
DBREG_DRX
((
&
dbregs
),
0
);
context
->
D
r1
=
DBREG_DRX
((
&
dbregs
),
1
);
context
->
D
r2
=
DBREG_DRX
((
&
dbregs
),
2
);
context
->
D
r3
=
DBREG_DRX
((
&
dbregs
),
3
);
context
->
D
r6
=
DBREG_DRX
((
&
dbregs
),
6
);
context
->
D
r7
=
DBREG_DRX
((
&
dbregs
),
7
);
context
->
debug
.
i386_regs
.
d
r0
=
DBREG_DRX
((
&
dbregs
),
0
);
context
->
debug
.
i386_regs
.
d
r1
=
DBREG_DRX
((
&
dbregs
),
1
);
context
->
debug
.
i386_regs
.
d
r2
=
DBREG_DRX
((
&
dbregs
),
2
);
context
->
debug
.
i386_regs
.
d
r3
=
DBREG_DRX
((
&
dbregs
),
3
);
context
->
debug
.
i386_regs
.
d
r6
=
DBREG_DRX
((
&
dbregs
),
6
);
context
->
debug
.
i386_regs
.
d
r7
=
DBREG_DRX
((
&
dbregs
),
7
);
#else
context
->
D
r0
=
dbregs
.
dr0
;
context
->
D
r1
=
dbregs
.
dr1
;
context
->
D
r2
=
dbregs
.
dr2
;
context
->
D
r3
=
dbregs
.
dr3
;
context
->
D
r6
=
dbregs
.
dr6
;
context
->
D
r7
=
dbregs
.
dr7
;
context
->
debug
.
i386_regs
.
d
r0
=
dbregs
.
dr0
;
context
->
debug
.
i386_regs
.
d
r1
=
dbregs
.
dr1
;
context
->
debug
.
i386_regs
.
d
r2
=
dbregs
.
dr2
;
context
->
debug
.
i386_regs
.
d
r3
=
dbregs
.
dr3
;
context
->
debug
.
i386_regs
.
d
r6
=
dbregs
.
dr6
;
context
->
debug
.
i386_regs
.
d
r7
=
dbregs
.
dr7
;
#endif
context
->
ContextFlags
|=
CONTEXT
_DEBUG_REGISTERS
;
context
->
flags
|=
SERVER_CTX
_DEBUG_REGISTERS
;
}
resume_after_ptrace
(
thread
);
}
/* set the thread x86 registers */
void
set_thread_context
(
struct
thread
*
thread
,
const
CONTEXT
*
context
,
unsigned
int
flags
)
void
set_thread_context
(
struct
thread
*
thread
,
const
context_t
*
context
,
unsigned
int
flags
)
{
int
pid
=
get_ptrace_tid
(
thread
);
struct
dbreg
dbregs
;
/* all other regs are handled on the client side */
assert
(
(
flags
|
CONTEXT_i386
)
==
CONTEXT
_DEBUG_REGISTERS
);
assert
(
flags
==
SERVER_CTX
_DEBUG_REGISTERS
);
if
(
!
suspend_for_ptrace
(
thread
))
return
;
#ifdef DBREG_DRX
/* needed for FreeBSD, the structure fields have changed under 5.x */
DBREG_DRX
((
&
dbregs
),
0
)
=
context
->
D
r0
;
DBREG_DRX
((
&
dbregs
),
1
)
=
context
->
D
r1
;
DBREG_DRX
((
&
dbregs
),
2
)
=
context
->
D
r2
;
DBREG_DRX
((
&
dbregs
),
3
)
=
context
->
D
r3
;
DBREG_DRX
((
&
dbregs
),
0
)
=
context
->
debug
.
i386_regs
.
d
r0
;
DBREG_DRX
((
&
dbregs
),
1
)
=
context
->
debug
.
i386_regs
.
d
r1
;
DBREG_DRX
((
&
dbregs
),
2
)
=
context
->
debug
.
i386_regs
.
d
r2
;
DBREG_DRX
((
&
dbregs
),
3
)
=
context
->
debug
.
i386_regs
.
d
r3
;
DBREG_DRX
((
&
dbregs
),
4
)
=
0
;
DBREG_DRX
((
&
dbregs
),
5
)
=
0
;
DBREG_DRX
((
&
dbregs
),
6
)
=
context
->
D
r6
;
DBREG_DRX
((
&
dbregs
),
7
)
=
context
->
D
r7
;
DBREG_DRX
((
&
dbregs
),
6
)
=
context
->
debug
.
i386_regs
.
d
r6
;
DBREG_DRX
((
&
dbregs
),
7
)
=
context
->
debug
.
i386_regs
.
d
r7
;
#else
dbregs
.
dr0
=
context
->
D
r0
;
dbregs
.
dr1
=
context
->
D
r1
;
dbregs
.
dr2
=
context
->
D
r2
;
dbregs
.
dr3
=
context
->
D
r3
;
dbregs
.
dr0
=
context
->
debug
.
i386_regs
.
d
r0
;
dbregs
.
dr1
=
context
->
debug
.
i386_regs
.
d
r1
;
dbregs
.
dr2
=
context
->
debug
.
i386_regs
.
d
r2
;
dbregs
.
dr3
=
context
->
debug
.
i386_regs
.
d
r3
;
dbregs
.
dr4
=
0
;
dbregs
.
dr5
=
0
;
dbregs
.
dr6
=
context
->
D
r6
;
dbregs
.
dr7
=
context
->
D
r7
;
dbregs
.
dr6
=
context
->
debug
.
i386_regs
.
d
r6
;
dbregs
.
dr7
=
context
->
debug
.
i386_regs
.
d
r7
;
#endif
if
(
ptrace
(
PTRACE_SETDBREGS
,
pid
,
(
caddr_t
)
&
dbregs
,
0
)
==
-
1
)
file_set_error
();
else
if
(
thread
->
context
)
/* update the cached values */
{
thread
->
context
->
Dr0
=
context
->
Dr0
;
thread
->
context
->
Dr1
=
context
->
Dr1
;
thread
->
context
->
Dr2
=
context
->
Dr2
;
thread
->
context
->
Dr3
=
context
->
Dr3
;
thread
->
context
->
Dr6
=
context
->
Dr6
;
thread
->
context
->
Dr7
=
context
->
Dr7
;
}
else
if
(
thread
->
context
)
thread
->
context
->
debug
.
i386_regs
=
context
->
debug
.
i386_regs
;
/* update the cached values */
resume_after_ptrace
(
thread
);
}
#else
/* linux || __FreeBSD__ */
/* retrieve the thread x86 registers */
void
get_thread_context
(
struct
thread
*
thread
,
CONTEXT
*
context
,
unsigned
int
flags
)
void
get_thread_context
(
struct
thread
*
thread
,
context_t
*
context
,
unsigned
int
flags
)
{
}
/* set the thread x86 debug registers */
void
set_thread_context
(
struct
thread
*
thread
,
const
CONTEXT
*
context
,
unsigned
int
flags
)
void
set_thread_context
(
struct
thread
*
thread
,
const
context_t
*
context
,
unsigned
int
flags
)
{
}
...
...
server/request.h
View file @
5316dd01
...
...
@@ -1212,8 +1212,7 @@ C_ASSERT( FIELD_OFFSET(struct get_thread_context_request, suspend) == 20 );
C_ASSERT
(
FIELD_OFFSET
(
struct
get_thread_context_reply
,
self
)
==
8
);
C_ASSERT
(
sizeof
(
struct
get_thread_context_reply
)
==
16
);
C_ASSERT
(
FIELD_OFFSET
(
struct
set_thread_context_request
,
handle
)
==
12
);
C_ASSERT
(
FIELD_OFFSET
(
struct
set_thread_context_request
,
flags
)
==
16
);
C_ASSERT
(
FIELD_OFFSET
(
struct
set_thread_context_request
,
suspend
)
==
20
);
C_ASSERT
(
FIELD_OFFSET
(
struct
set_thread_context_request
,
suspend
)
==
16
);
C_ASSERT
(
FIELD_OFFSET
(
struct
set_thread_context_reply
,
self
)
==
8
);
C_ASSERT
(
sizeof
(
struct
set_thread_context_reply
)
==
16
);
C_ASSERT
(
FIELD_OFFSET
(
struct
get_selector_entry_request
,
handle
)
==
12
);
...
...
server/thread.c
View file @
5316dd01
...
...
@@ -944,6 +944,34 @@ void kill_thread( struct thread *thread, int violent_death )
release_object
(
thread
);
}
/* copy parts of a context structure */
static
void
copy_context
(
context_t
*
to
,
const
context_t
*
from
,
unsigned
int
flags
)
{
assert
(
to
->
cpu
==
from
->
cpu
);
to
->
flags
|=
flags
;
if
(
flags
&
SERVER_CTX_CONTROL
)
to
->
ctl
=
from
->
ctl
;
if
(
flags
&
SERVER_CTX_INTEGER
)
to
->
integer
=
from
->
integer
;
if
(
flags
&
SERVER_CTX_SEGMENTS
)
to
->
seg
=
from
->
seg
;
if
(
flags
&
SERVER_CTX_FLOATING_POINT
)
to
->
fp
=
from
->
fp
;
if
(
flags
&
SERVER_CTX_DEBUG_REGISTERS
)
to
->
debug
=
from
->
debug
;
if
(
flags
&
SERVER_CTX_EXTENDED_REGISTERS
)
to
->
ext
=
from
->
ext
;
}
/* return the context flags that correspond to system regs */
/* (system regs are the ones we can't access on the client side) */
static
unsigned
int
get_context_system_regs
(
enum
cpu_type
cpu
)
{
switch
(
cpu
)
{
case
CPU_x86
:
return
SERVER_CTX_DEBUG_REGISTERS
;
case
CPU_x86_64
:
return
SERVER_CTX_DEBUG_REGISTERS
;
case
CPU_ALPHA
:
return
0
;
case
CPU_POWERPC
:
return
0
;
case
CPU_SPARC
:
return
0
;
}
return
0
;
}
/* trigger a breakpoint event in a given thread */
void
break_thread
(
struct
thread
*
thread
)
{
...
...
@@ -955,7 +983,24 @@ void break_thread( struct thread *thread )
data
.
exception
.
first
=
1
;
data
.
exception
.
exc_code
=
STATUS_BREAKPOINT
;
data
.
exception
.
flags
=
EXCEPTION_CONTINUABLE
;
data
.
exception
.
address
=
get_context_ip
(
thread
->
context
);
switch
(
thread
->
context
->
cpu
)
{
case
CPU_x86
:
data
.
exception
.
address
=
thread
->
context
->
ctl
.
i386_regs
.
eip
;
break
;
case
CPU_x86_64
:
data
.
exception
.
address
=
thread
->
context
->
ctl
.
x86_64_regs
.
rip
;
break
;
case
CPU_ALPHA
:
data
.
exception
.
address
=
thread
->
context
->
ctl
.
alpha_regs
.
fir
;
break
;
case
CPU_POWERPC
:
data
.
exception
.
address
=
thread
->
context
->
ctl
.
powerpc_regs
.
iar
;
break
;
case
CPU_SPARC
:
data
.
exception
.
address
=
thread
->
context
->
ctl
.
sparc_regs
.
pc
;
break
;
}
generate_debug_event
(
thread
,
EXCEPTION_DEBUG_EVENT
,
&
data
);
thread
->
debug_break
=
0
;
}
...
...
@@ -1357,9 +1402,9 @@ DECL_HANDLER(get_apc_result)
DECL_HANDLER
(
get_thread_context
)
{
struct
thread
*
thread
;
CONTEXT
*
context
;
context_t
*
context
;
if
(
get_reply_max_size
()
<
sizeof
(
CONTEXT
))
if
(
get_reply_max_size
()
<
sizeof
(
context_t
))
{
set_error
(
STATUS_INVALID_PARAMETER
);
return
;
...
...
@@ -1376,7 +1421,7 @@ DECL_HANDLER(get_thread_context)
else
{
if
(
thread
->
context
==
thread
->
suspend_context
)
thread
->
context
=
NULL
;
set_reply_data_ptr
(
thread
->
suspend_context
,
sizeof
(
CONTEXT
)
);
set_reply_data_ptr
(
thread
->
suspend_context
,
sizeof
(
context_t
)
);
thread
->
suspend_context
=
NULL
;
}
}
...
...
@@ -1386,12 +1431,12 @@ DECL_HANDLER(get_thread_context)
if
(
thread
->
state
!=
RUNNING
)
set_error
(
STATUS_ACCESS_DENIED
);
else
set_error
(
STATUS_PENDING
);
}
else
if
((
context
=
set_reply_data_size
(
sizeof
(
CONTEXT
)
)))
else
if
((
context
=
set_reply_data_size
(
sizeof
(
context_t
)
)))
{
unsigned
int
flags
=
get_context_system_regs
(
req
->
flags
);
unsigned
int
flags
=
get_context_system_regs
(
thread
->
process
->
cpu
);
memset
(
context
,
0
,
sizeof
(
CONTEXT
)
);
context
->
ContextFlags
=
get_context_cpu_flag
()
;
memset
(
context
,
0
,
sizeof
(
context_t
)
);
context
->
cpu
=
thread
->
process
->
cpu
;
if
(
thread
->
context
)
copy_context
(
context
,
thread
->
context
,
req
->
flags
&
~
flags
);
if
(
flags
)
get_thread_context
(
thread
,
context
,
flags
);
}
...
...
@@ -1403,8 +1448,9 @@ DECL_HANDLER(get_thread_context)
DECL_HANDLER
(
set_thread_context
)
{
struct
thread
*
thread
;
const
context_t
*
context
=
get_req_data
();
if
(
get_req_data_size
()
<
sizeof
(
CONTEXT
))
if
(
get_req_data_size
()
<
sizeof
(
context_t
))
{
set_error
(
STATUS_INVALID_PARAMETER
);
return
;
...
...
@@ -1413,14 +1459,14 @@ DECL_HANDLER(set_thread_context)
if
(
req
->
suspend
)
{
if
(
thread
!=
current
||
thread
->
context
)
if
(
thread
!=
current
||
thread
->
context
||
context
->
cpu
!=
thread
->
process
->
cpu
)
{
/* nested suspend or exception, shouldn't happen */
set_error
(
STATUS_INVALID_PARAMETER
);
}
else
if
((
thread
->
suspend_context
=
mem_alloc
(
sizeof
(
CONTEXT
)
)))
else
if
((
thread
->
suspend_context
=
mem_alloc
(
sizeof
(
context_t
)
)))
{
memcpy
(
thread
->
suspend_context
,
get_req_data
(),
sizeof
(
CONTEXT
)
);
memcpy
(
thread
->
suspend_context
,
get_req_data
(),
sizeof
(
context_t
)
);
thread
->
context
=
thread
->
suspend_context
;
if
(
thread
->
debug_break
)
break_thread
(
thread
);
}
...
...
@@ -1431,15 +1477,16 @@ DECL_HANDLER(set_thread_context)
if
(
thread
->
state
!=
RUNNING
)
set_error
(
STATUS_ACCESS_DENIED
);
else
set_error
(
STATUS_PENDING
);
}
else
else
if
(
context
->
cpu
==
thread
->
process
->
cpu
)
{
const
CONTEXT
*
context
=
get_req_data
()
;
unsigned
int
flags
=
get_context_system_regs
(
req
->
flags
)
;
unsigned
int
system_flags
=
get_context_system_regs
(
context
->
cpu
)
&
context
->
flags
;
unsigned
int
client_flags
=
context
->
flags
&
~
system_flags
;
if
(
flags
)
set_thread_context
(
thread
,
context
,
flags
);
if
(
thread
->
context
&&
!
get_error
())
copy_context
(
thread
->
context
,
context
,
req
->
flags
&
~
flags
);
if
(
system_flags
)
set_thread_context
(
thread
,
context
,
system_flags
);
if
(
thread
->
context
&&
!
get_error
())
copy_context
(
thread
->
context
,
context
,
client_flags
);
}
else
set_error
(
STATUS_INVALID_PARAMETER
);
reply
->
self
=
(
thread
==
current
);
release_object
(
thread
);
}
...
...
server/thread.h
View file @
5316dd01
...
...
@@ -76,8 +76,8 @@ struct thread
int
exit_code
;
/* thread exit code */
int
unix_pid
;
/* Unix pid of client */
int
unix_tid
;
/* Unix tid of client */
CONTEXT
*
context
;
/* current context if in an exception handler */
CONTEXT
*
suspend_context
;
/* current context if suspended */
context_t
*
context
;
/* current context if in an exception handler */
context_t
*
suspend_context
;
/* current context if suspended */
client_ptr_t
teb
;
/* TEB address (in client address space) */
affinity_t
affinity
;
/* affinity mask */
int
priority
;
/* priority level */
...
...
@@ -119,17 +119,11 @@ extern int thread_get_inflight_fd( struct thread *thread, int client );
extern
struct
thread_snapshot
*
thread_snap
(
int
*
count
);
extern
struct
token
*
thread_get_impersonation_token
(
struct
thread
*
thread
);
/* CPU context functions */
extern
void
copy_context
(
CONTEXT
*
to
,
const
CONTEXT
*
from
,
unsigned
int
flags
);
extern
client_ptr_t
get_context_ip
(
const
CONTEXT
*
context
);
extern
unsigned
int
get_context_cpu_flag
(
void
);
extern
unsigned
int
get_context_system_regs
(
unsigned
int
flags
);
/* ptrace functions */
extern
void
sigchld_callback
(
void
);
extern
void
get_thread_context
(
struct
thread
*
thread
,
CONTEXT
*
context
,
unsigned
int
flags
);
extern
void
set_thread_context
(
struct
thread
*
thread
,
const
CONTEXT
*
context
,
unsigned
int
flags
);
extern
void
get_thread_context
(
struct
thread
*
thread
,
context_t
*
context
,
unsigned
int
flags
);
extern
void
set_thread_context
(
struct
thread
*
thread
,
const
context_t
*
context
,
unsigned
int
flags
);
extern
int
send_thread_signal
(
struct
thread
*
thread
,
int
sig
);
extern
void
get_selector_entry
(
struct
thread
*
thread
,
int
entry
,
unsigned
int
*
base
,
unsigned
int
*
limit
,
unsigned
char
*
flags
);
...
...
server/trace.c
View file @
5316dd01
...
...
@@ -298,33 +298,6 @@ static void dump_luid( const char *prefix, const luid_t *luid )
fprintf
(
stderr
,
"%s%d.%u"
,
prefix
,
luid
->
high_part
,
luid
->
low_part
);
}
static
void
dump_context
(
const
CONTEXT
*
context
,
data_size_t
size
)
{
CONTEXT
ctx
;
memset
(
&
ctx
,
0
,
sizeof
(
ctx
)
);
memcpy
(
&
ctx
,
context
,
min
(
size
,
sizeof
(
CONTEXT
)
));
#ifdef __i386__
fprintf
(
stderr
,
"{flags=%08x,eax=%08x,ebx=%08x,ecx=%08x,edx=%08x,esi=%08x,edi=%08x,"
"ebp=%08x,eip=%08x,esp=%08x,eflags=%08x,cs=%04x,ds=%04x,es=%04x,"
"fs=%04x,gs=%04x,dr0=%08x,dr1=%08x,dr2=%08x,dr3=%08x,dr6=%08x,dr7=%08x,"
,
ctx
.
ContextFlags
,
ctx
.
Eax
,
ctx
.
Ebx
,
ctx
.
Ecx
,
ctx
.
Edx
,
ctx
.
Esi
,
ctx
.
Edi
,
ctx
.
Ebp
,
ctx
.
Eip
,
ctx
.
Esp
,
ctx
.
EFlags
,
ctx
.
SegCs
,
ctx
.
SegDs
,
ctx
.
SegEs
,
ctx
.
SegFs
,
ctx
.
SegGs
,
ctx
.
Dr0
,
ctx
.
Dr1
,
ctx
.
Dr2
,
ctx
.
Dr3
,
ctx
.
Dr6
,
ctx
.
Dr7
);
fprintf
(
stderr
,
"float="
);
dump_uints
(
(
const
int
*
)
&
ctx
.
FloatSave
,
sizeof
(
ctx
.
FloatSave
)
/
sizeof
(
int
)
);
if
(
size
>
FIELD_OFFSET
(
CONTEXT
,
ExtendedRegisters
))
{
fprintf
(
stderr
,
",extended="
);
dump_uints
(
(
const
int
*
)
&
ctx
.
ExtendedRegisters
,
sizeof
(
ctx
.
ExtendedRegisters
)
/
sizeof
(
int
)
);
}
fprintf
(
stderr
,
"}"
);
#else
dump_uints
(
(
const
int
*
)
&
ctx
,
sizeof
(
ctx
)
/
sizeof
(
int
)
);
#endif
}
static
void
dump_varargs_ints
(
const
char
*
prefix
,
data_size_t
size
)
{
const
int
*
data
=
cur_data
;
...
...
@@ -428,14 +401,190 @@ static void dump_varargs_unicode_str( const char *prefix, data_size_t size )
static
void
dump_varargs_context
(
const
char
*
prefix
,
data_size_t
size
)
{
const
context_t
*
context
=
cur_data
;
context_t
ctx
;
unsigned
int
i
;
if
(
!
size
)
{
fprintf
(
stderr
,
"%s{}"
,
prefix
);
return
;
}
fprintf
(
stderr
,
"%s"
,
prefix
);
dump_context
(
cur_data
,
size
);
remove_data
(
min
(
size
,
sizeof
(
CONTEXT
)
));
size
=
min
(
size
,
sizeof
(
ctx
)
);
memset
(
&
ctx
,
0
,
sizeof
(
ctx
)
);
memcpy
(
&
ctx
,
context
,
size
);
fprintf
(
stderr
,
"%s{"
,
prefix
);
dump_cpu_type
(
"cpu="
,
&
ctx
.
cpu
);
switch
(
ctx
.
cpu
)
{
case
CPU_x86
:
if
(
ctx
.
flags
&
SERVER_CTX_CONTROL
)
fprintf
(
stderr
,
",eip=%08x,esp=%08x,ebp=%08x,eflags=%08x,cs=%04x,ss=%04x"
,
ctx
.
ctl
.
i386_regs
.
eip
,
ctx
.
ctl
.
i386_regs
.
esp
,
ctx
.
ctl
.
i386_regs
.
ebp
,
ctx
.
ctl
.
i386_regs
.
eflags
,
ctx
.
ctl
.
i386_regs
.
cs
,
ctx
.
ctl
.
i386_regs
.
ss
);
if
(
ctx
.
flags
&
SERVER_CTX_SEGMENTS
)
fprintf
(
stderr
,
",ds=%04x,es=%04x,fs=%04x,gs=%04x"
,
ctx
.
seg
.
i386_regs
.
ds
,
ctx
.
seg
.
i386_regs
.
es
,
ctx
.
seg
.
i386_regs
.
fs
,
ctx
.
seg
.
i386_regs
.
gs
);
if
(
ctx
.
flags
&
SERVER_CTX_INTEGER
)
fprintf
(
stderr
,
",eax=%08x,ebx=%08x,ecx=%08x,edx=%08x,esi=%08x,edi=%08x"
,
ctx
.
integer
.
i386_regs
.
eax
,
ctx
.
integer
.
i386_regs
.
ebx
,
ctx
.
integer
.
i386_regs
.
ecx
,
ctx
.
integer
.
i386_regs
.
edx
,
ctx
.
integer
.
i386_regs
.
esi
,
ctx
.
integer
.
i386_regs
.
edi
);
if
(
ctx
.
flags
&
SERVER_CTX_DEBUG_REGISTERS
)
fprintf
(
stderr
,
",dr0=%08x,dr1=%08x,dr2=%08x,dr3=%08x,dr6=%08x,dr7=%08x"
,
ctx
.
debug
.
i386_regs
.
dr0
,
ctx
.
debug
.
i386_regs
.
dr1
,
ctx
.
debug
.
i386_regs
.
dr2
,
ctx
.
debug
.
i386_regs
.
dr3
,
ctx
.
debug
.
i386_regs
.
dr6
,
ctx
.
debug
.
i386_regs
.
dr7
);
if
(
ctx
.
flags
&
SERVER_CTX_FLOATING_POINT
)
{
fprintf
(
stderr
,
"fp.ctrl=%08x,fp.status=%08x,fp.tag=%08x,fp.err_off=%08x,fp.err_sel=%08x"
,
ctx
.
fp
.
i386_regs
.
ctrl
,
ctx
.
fp
.
i386_regs
.
status
,
ctx
.
fp
.
i386_regs
.
tag
,
ctx
.
fp
.
i386_regs
.
err_off
,
ctx
.
fp
.
i386_regs
.
err_sel
);
fprintf
(
stderr
,
",fp.data_off=%08x,fp.data_sel=%08x,fp.cr0npx=%08x"
,
ctx
.
fp
.
i386_regs
.
data_off
,
ctx
.
fp
.
i386_regs
.
data_sel
,
ctx
.
fp
.
i386_regs
.
cr0npx
);
for
(
i
=
0
;
i
<
8
;
i
++
)
fprintf
(
stderr
,
",fp.reg%u=%Lg"
,
i
,
*
(
long
double
*
)
&
ctx
.
fp
.
i386_regs
.
regs
[
10
*
i
]
);
}
if
(
ctx
.
flags
&
SERVER_CTX_EXTENDED_REGISTERS
)
{
fprintf
(
stderr
,
",extended="
);
dump_uints
(
(
const
int
*
)
ctx
.
ext
.
i386_regs
,
sizeof
(
ctx
.
ext
.
i386_regs
)
/
sizeof
(
int
)
);
}
break
;
case
CPU_x86_64
:
if
(
ctx
.
flags
&
SERVER_CTX_CONTROL
)
{
dump_uint64
(
",rip="
,
&
ctx
.
ctl
.
x86_64_regs
.
rip
);
dump_uint64
(
",rbp="
,
&
ctx
.
ctl
.
x86_64_regs
.
rbp
);
dump_uint64
(
",rsp="
,
&
ctx
.
ctl
.
x86_64_regs
.
rsp
);
fprintf
(
stderr
,
",cs=%04x,ss=%04x,flags=%08x,mxcsr=%08x"
,
ctx
.
ctl
.
x86_64_regs
.
cs
,
ctx
.
ctl
.
x86_64_regs
.
ss
,
ctx
.
ctl
.
x86_64_regs
.
flags
,
ctx
.
ctl
.
x86_64_regs
.
mxcsr
);
}
if
(
ctx
.
flags
&
SERVER_CTX_INTEGER
)
{
dump_uint64
(
",rax="
,
&
ctx
.
integer
.
x86_64_regs
.
rax
);
dump_uint64
(
",rbx="
,
&
ctx
.
integer
.
x86_64_regs
.
rbx
);
dump_uint64
(
",rcx="
,
&
ctx
.
integer
.
x86_64_regs
.
rcx
);
dump_uint64
(
",rdx="
,
&
ctx
.
integer
.
x86_64_regs
.
rdx
);
dump_uint64
(
",rsi="
,
&
ctx
.
integer
.
x86_64_regs
.
rsi
);
dump_uint64
(
",rdi="
,
&
ctx
.
integer
.
x86_64_regs
.
rdi
);
dump_uint64
(
",r8="
,
&
ctx
.
integer
.
x86_64_regs
.
r8
);
dump_uint64
(
",r9="
,
&
ctx
.
integer
.
x86_64_regs
.
r9
);
dump_uint64
(
",r10="
,
&
ctx
.
integer
.
x86_64_regs
.
r10
);
dump_uint64
(
",r11="
,
&
ctx
.
integer
.
x86_64_regs
.
r11
);
dump_uint64
(
",r12="
,
&
ctx
.
integer
.
x86_64_regs
.
r12
);
dump_uint64
(
",r13="
,
&
ctx
.
integer
.
x86_64_regs
.
r13
);
dump_uint64
(
",r14="
,
&
ctx
.
integer
.
x86_64_regs
.
r14
);
dump_uint64
(
",r15="
,
&
ctx
.
integer
.
x86_64_regs
.
r15
);
}
if
(
ctx
.
flags
&
SERVER_CTX_SEGMENTS
)
fprintf
(
stderr
,
",ds=%04x,es=%04x,fs=%04x,gs=%04x"
,
ctx
.
seg
.
x86_64_regs
.
ds
,
ctx
.
seg
.
x86_64_regs
.
es
,
ctx
.
seg
.
x86_64_regs
.
fs
,
ctx
.
seg
.
x86_64_regs
.
gs
);
if
(
ctx
.
flags
&
SERVER_CTX_DEBUG_REGISTERS
)
{
dump_uint64
(
",dr0="
,
&
ctx
.
debug
.
x86_64_regs
.
dr0
);
dump_uint64
(
",dr1="
,
&
ctx
.
debug
.
x86_64_regs
.
dr1
);
dump_uint64
(
",dr2="
,
&
ctx
.
debug
.
x86_64_regs
.
dr2
);
dump_uint64
(
",dr3="
,
&
ctx
.
debug
.
x86_64_regs
.
dr3
);
dump_uint64
(
",dr6="
,
&
ctx
.
debug
.
x86_64_regs
.
dr6
);
dump_uint64
(
",dr7="
,
&
ctx
.
debug
.
x86_64_regs
.
dr7
);
}
if
(
ctx
.
flags
&
SERVER_CTX_FLOATING_POINT
)
{
for
(
i
=
0
;
i
<
32
;
i
++
)
fprintf
(
stderr
,
",fp%u=%08x%08x%08x%08x"
,
i
,
(
unsigned
int
)(
ctx
.
fp
.
x86_64_regs
.
fpregs
[
i
].
high
>>
32
),
(
unsigned
int
)
ctx
.
fp
.
x86_64_regs
.
fpregs
[
i
].
high
,
(
unsigned
int
)(
ctx
.
fp
.
x86_64_regs
.
fpregs
[
i
].
low
>>
32
),
(
unsigned
int
)
ctx
.
fp
.
x86_64_regs
.
fpregs
[
i
].
low
);
}
break
;
case
CPU_ALPHA
:
if
(
ctx
.
flags
&
SERVER_CTX_CONTROL
)
{
dump_uint64
(
",fir="
,
&
ctx
.
ctl
.
alpha_regs
.
fir
);
fprintf
(
stderr
,
",psr=%08x"
,
ctx
.
ctl
.
alpha_regs
.
psr
);
}
if
(
ctx
.
flags
&
SERVER_CTX_INTEGER
)
{
dump_uint64
(
",v0="
,
&
ctx
.
integer
.
alpha_regs
.
v0
);
dump_uint64
(
",t0="
,
&
ctx
.
integer
.
alpha_regs
.
t0
);
dump_uint64
(
",t1="
,
&
ctx
.
integer
.
alpha_regs
.
t1
);
dump_uint64
(
",t2="
,
&
ctx
.
integer
.
alpha_regs
.
t2
);
dump_uint64
(
",t3="
,
&
ctx
.
integer
.
alpha_regs
.
t3
);
dump_uint64
(
",t4="
,
&
ctx
.
integer
.
alpha_regs
.
t4
);
dump_uint64
(
",t5="
,
&
ctx
.
integer
.
alpha_regs
.
t5
);
dump_uint64
(
",t6="
,
&
ctx
.
integer
.
alpha_regs
.
t6
);
dump_uint64
(
",t7="
,
&
ctx
.
integer
.
alpha_regs
.
t7
);
dump_uint64
(
",t8="
,
&
ctx
.
integer
.
alpha_regs
.
t8
);
dump_uint64
(
",t9="
,
&
ctx
.
integer
.
alpha_regs
.
t9
);
dump_uint64
(
",t10="
,
&
ctx
.
integer
.
alpha_regs
.
t10
);
dump_uint64
(
",t11="
,
&
ctx
.
integer
.
alpha_regs
.
t11
);
dump_uint64
(
",t12="
,
&
ctx
.
integer
.
alpha_regs
.
t12
);
dump_uint64
(
",s0="
,
&
ctx
.
integer
.
alpha_regs
.
s0
);
dump_uint64
(
",s1="
,
&
ctx
.
integer
.
alpha_regs
.
s1
);
dump_uint64
(
",s2="
,
&
ctx
.
integer
.
alpha_regs
.
s2
);
dump_uint64
(
",s3="
,
&
ctx
.
integer
.
alpha_regs
.
s3
);
dump_uint64
(
",s4="
,
&
ctx
.
integer
.
alpha_regs
.
s4
);
dump_uint64
(
",s5="
,
&
ctx
.
integer
.
alpha_regs
.
s5
);
dump_uint64
(
",s6="
,
&
ctx
.
integer
.
alpha_regs
.
s6
);
dump_uint64
(
",a0="
,
&
ctx
.
integer
.
alpha_regs
.
a0
);
dump_uint64
(
",a1="
,
&
ctx
.
integer
.
alpha_regs
.
a1
);
dump_uint64
(
",a2="
,
&
ctx
.
integer
.
alpha_regs
.
a2
);
dump_uint64
(
",a3="
,
&
ctx
.
integer
.
alpha_regs
.
a3
);
dump_uint64
(
",a4="
,
&
ctx
.
integer
.
alpha_regs
.
a4
);
dump_uint64
(
",a5="
,
&
ctx
.
integer
.
alpha_regs
.
a5
);
dump_uint64
(
",at="
,
&
ctx
.
integer
.
alpha_regs
.
at
);
}
if
(
ctx
.
flags
&
SERVER_CTX_FLOATING_POINT
)
{
for
(
i
=
0
;
i
<
32
;
i
++
)
{
fprintf
(
stderr
,
",f%u"
,
i
);
dump_uint64
(
"="
,
&
ctx
.
fp
.
alpha_regs
.
f
[
i
]
);
}
dump_uint64
(
",fpcr="
,
&
ctx
.
fp
.
alpha_regs
.
fpcr
);
dump_uint64
(
",softfpcr="
,
&
ctx
.
fp
.
alpha_regs
.
softfpcr
);
}
break
;
case
CPU_POWERPC
:
if
(
ctx
.
flags
&
SERVER_CTX_CONTROL
)
fprintf
(
stderr
,
",iar=%08x,msr=%08x,ctr=%08x,lr=%08x,dar=%08x,dsisr=%08x,trap=%08x"
,
ctx
.
ctl
.
powerpc_regs
.
iar
,
ctx
.
ctl
.
powerpc_regs
.
msr
,
ctx
.
ctl
.
powerpc_regs
.
ctr
,
ctx
.
ctl
.
powerpc_regs
.
lr
,
ctx
.
ctl
.
powerpc_regs
.
dar
,
ctx
.
ctl
.
powerpc_regs
.
dsisr
,
ctx
.
ctl
.
powerpc_regs
.
trap
);
if
(
ctx
.
flags
&
SERVER_CTX_INTEGER
)
{
for
(
i
=
0
;
i
<
32
;
i
++
)
fprintf
(
stderr
,
",gpr%u=%08x"
,
i
,
ctx
.
integer
.
powerpc_regs
.
gpr
[
i
]
);
fprintf
(
stderr
,
",cr=%08x,xer=%08x"
,
ctx
.
integer
.
powerpc_regs
.
cr
,
ctx
.
integer
.
powerpc_regs
.
xer
);
}
if
(
ctx
.
flags
&
SERVER_CTX_DEBUG_REGISTERS
)
for
(
i
=
0
;
i
<
8
;
i
++
)
fprintf
(
stderr
,
",dr%u=%08x"
,
i
,
ctx
.
debug
.
powerpc_regs
.
dr
[
i
]
);
if
(
ctx
.
flags
&
SERVER_CTX_FLOATING_POINT
)
{
for
(
i
=
0
;
i
<
32
;
i
++
)
fprintf
(
stderr
,
",fpr%u=%g"
,
i
,
ctx
.
fp
.
powerpc_regs
.
fpr
[
i
]
);
fprintf
(
stderr
,
",fpscr=%g"
,
ctx
.
fp
.
powerpc_regs
.
fpscr
);
}
break
;
case
CPU_SPARC
:
if
(
ctx
.
flags
&
SERVER_CTX_CONTROL
)
fprintf
(
stderr
,
",psr=%08x,pc=%08x,npc=%08x,y=%08x,wim=%08x,tbr=%08x"
,
ctx
.
ctl
.
sparc_regs
.
psr
,
ctx
.
ctl
.
sparc_regs
.
pc
,
ctx
.
ctl
.
sparc_regs
.
npc
,
ctx
.
ctl
.
sparc_regs
.
y
,
ctx
.
ctl
.
sparc_regs
.
wim
,
ctx
.
ctl
.
sparc_regs
.
tbr
);
if
(
ctx
.
flags
&
SERVER_CTX_INTEGER
)
{
for
(
i
=
0
;
i
<
8
;
i
++
)
fprintf
(
stderr
,
",g%u=%08x"
,
i
,
ctx
.
integer
.
sparc_regs
.
g
[
i
]
);
for
(
i
=
0
;
i
<
8
;
i
++
)
fprintf
(
stderr
,
",o%u=%08x"
,
i
,
ctx
.
integer
.
sparc_regs
.
o
[
i
]
);
for
(
i
=
0
;
i
<
8
;
i
++
)
fprintf
(
stderr
,
",l%u=%08x"
,
i
,
ctx
.
integer
.
sparc_regs
.
l
[
i
]
);
for
(
i
=
0
;
i
<
8
;
i
++
)
fprintf
(
stderr
,
",i%u=%08x"
,
i
,
ctx
.
integer
.
sparc_regs
.
i
[
i
]
);
}
break
;
}
fputc
(
'}'
,
stderr
);
remove_data
(
size
);
}
static
void
dump_varargs_debug_event
(
const
char
*
prefix
,
data_size_t
size
)
...
...
@@ -2128,7 +2277,6 @@ static void dump_get_thread_context_reply( const struct get_thread_context_reply
static
void
dump_set_thread_context_request
(
const
struct
set_thread_context_request
*
req
)
{
fprintf
(
stderr
,
" handle=%04x"
,
req
->
handle
);
fprintf
(
stderr
,
", flags=%08x"
,
req
->
flags
);
fprintf
(
stderr
,
", suspend=%d"
,
req
->
suspend
);
dump_varargs_context
(
", context="
,
cur_size
);
}
...
...
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