Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-cw
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-cw
Commits
2878d992
Commit
2878d992
authored
Jan 13, 2006
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ntdll: Add debug registers to the context of all exceptions.
Maintain a local cache of the debug registers to avoid server calls where possible.
parent
d6bfc17b
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
81 additions
and
24 deletions
+81
-24
ntdll_misc.h
dlls/ntdll/ntdll_misc.h
+17
-0
signal_i386.c
dlls/ntdll/signal_i386.c
+28
-19
thread.c
dlls/ntdll/thread.c
+30
-3
server_protocol.h
include/wine/server_protocol.h
+2
-1
winternl.h
include/winternl.h
+1
-1
protocol.def
server/protocol.def
+1
-0
thread.c
server/thread.c
+1
-0
trace.c
server/trace.c
+1
-0
No files found.
dlls/ntdll/ntdll_misc.h
View file @
2878d992
...
...
@@ -134,4 +134,21 @@ static inline struct ntdll_thread_data *ntdll_get_thread_data(void)
return
(
struct
ntdll_thread_data
*
)
NtCurrentTeb
()
->
SystemReserved2
;
}
/* thread registers, stored in NtCurrentTeb()->SpareBytes1 */
struct
ntdll_thread_regs
{
DWORD
dr0
;
/* debug registers */
DWORD
dr1
;
DWORD
dr2
;
DWORD
dr3
;
DWORD
dr6
;
DWORD
dr7
;
DWORD
spare
[
4
];
/* change this if you add fields! */
};
static
inline
struct
ntdll_thread_regs
*
ntdll_get_thread_regs
(
void
)
{
return
(
struct
ntdll_thread_regs
*
)
NtCurrentTeb
()
->
SpareBytes1
;
}
#endif
dlls/ntdll/signal_i386.c
View file @
2878d992
...
...
@@ -740,7 +740,9 @@ inline static void restore_fpu( const CONTEXT *context )
*/
inline
static
void
save_context
(
CONTEXT
*
context
,
const
SIGCONTEXT
*
sigcontext
,
WORD
fs
,
WORD
gs
)
{
context
->
ContextFlags
=
CONTEXT_FULL
;
struct
ntdll_thread_regs
*
const
regs
=
ntdll_get_thread_regs
();
context
->
ContextFlags
=
CONTEXT_FULL
|
CONTEXT_DEBUG_REGISTERS
;
context
->
Eax
=
EAX_sig
(
sigcontext
);
context
->
Ebx
=
EBX_sig
(
sigcontext
);
context
->
Ecx
=
ECX_sig
(
sigcontext
);
...
...
@@ -757,6 +759,12 @@ inline static void save_context( CONTEXT *context, const SIGCONTEXT *sigcontext,
context
->
SegFs
=
fs
;
context
->
SegGs
=
gs
;
context
->
SegSs
=
LOWORD
(
SS_sig
(
sigcontext
));
context
->
Dr0
=
regs
->
dr0
;
context
->
Dr1
=
regs
->
dr1
;
context
->
Dr2
=
regs
->
dr2
;
context
->
Dr3
=
regs
->
dr3
;
context
->
Dr6
=
regs
->
dr6
;
context
->
Dr7
=
regs
->
dr7
;
}
...
...
@@ -767,6 +775,14 @@ inline static void save_context( CONTEXT *context, const SIGCONTEXT *sigcontext,
*/
inline
static
void
restore_context
(
const
CONTEXT
*
context
,
SIGCONTEXT
*
sigcontext
)
{
struct
ntdll_thread_regs
*
const
regs
=
ntdll_get_thread_regs
();
regs
->
dr0
=
context
->
Dr0
;
regs
->
dr1
=
context
->
Dr1
;
regs
->
dr2
=
context
->
Dr2
;
regs
->
dr3
=
context
->
Dr3
;
regs
->
dr6
=
context
->
Dr6
;
regs
->
dr7
=
context
->
Dr7
;
EAX_sig
(
sigcontext
)
=
context
->
Eax
;
EBX_sig
(
sigcontext
)
=
context
->
Ebx
;
ECX_sig
(
sigcontext
)
=
context
->
Ecx
;
...
...
@@ -797,7 +813,7 @@ inline static void restore_context( const CONTEXT *context, SIGCONTEXT *sigconte
/***********************************************************************
* set_cpu_context
*
* Set the new CPU context.
* Set the new CPU context.
Used by NtSetContextThread.
*/
void
set_cpu_context
(
const
CONTEXT
*
context
)
{
...
...
@@ -805,6 +821,16 @@ void set_cpu_context( const CONTEXT *context )
if
(
flags
&
CONTEXT_FLOATING_POINT
)
restore_fpu
(
context
);
if
(
flags
&
CONTEXT_DEBUG_REGISTERS
)
{
struct
ntdll_thread_regs
*
const
regs
=
ntdll_get_thread_regs
();
regs
->
dr0
=
context
->
Dr0
;
regs
->
dr1
=
context
->
Dr1
;
regs
->
dr2
=
context
->
Dr2
;
regs
->
dr3
=
context
->
Dr3
;
regs
->
dr6
=
context
->
Dr6
;
regs
->
dr7
=
context
->
Dr7
;
}
if
(
flags
&
CONTEXT_FULL
)
{
if
((
flags
&
CONTEXT_FULL
)
!=
(
CONTEXT_FULL
&
~
CONTEXT_i386
))
...
...
@@ -1027,8 +1053,6 @@ done:
*/
static
void
WINAPI
raise_trap_exception
(
EXCEPTION_RECORD
*
rec
,
CONTEXT
*
context
)
{
DWORD
dr0
,
dr1
,
dr2
,
dr3
,
dr6
,
dr7
;
if
(
rec
->
ExceptionCode
==
EXCEPTION_SINGLE_STEP
)
{
if
(
context
->
EFlags
&
0x100
)
...
...
@@ -1048,22 +1072,7 @@ static void WINAPI raise_trap_exception( EXCEPTION_RECORD *rec, CONTEXT *context
}
}
dr0
=
context
->
Dr0
;
dr1
=
context
->
Dr1
;
dr2
=
context
->
Dr2
;
dr3
=
context
->
Dr3
;
dr6
=
context
->
Dr6
;
dr7
=
context
->
Dr7
;
__regs_RtlRaiseException
(
rec
,
context
);
context
->
ContextFlags
=
CONTEXT_FULL
;
if
(
dr0
!=
context
->
Dr0
||
dr1
!=
context
->
Dr1
||
dr2
!=
context
->
Dr2
||
dr3
!=
context
->
Dr3
||
dr6
!=
context
->
Dr6
||
dr7
!=
context
->
Dr7
)
{
/* the debug registers have changed, set the new values */
context
->
ContextFlags
|=
CONTEXT_DEBUG_REGISTERS
;
}
NtSetContextThread
(
GetCurrentThread
(),
context
);
}
...
...
dlls/ntdll/thread.c
View file @
2878d992
...
...
@@ -294,6 +294,9 @@ NTSTATUS WINAPI RtlCreateUserThread( HANDLE process, const SECURITY_DESCRIPTOR *
teb
->
ClientId
.
UniqueProcess
=
(
HANDLE
)
GetCurrentProcessId
();
teb
->
ClientId
.
UniqueThread
=
(
HANDLE
)
tid
;
/* inherit registers from parent thread */
memcpy
(
teb
->
SpareBytes1
,
ntdll_get_thread_regs
(),
sizeof
(
teb
->
SpareBytes1
)
);
thread_data
=
(
struct
ntdll_thread_data
*
)
teb
->
SystemReserved2
;
thread_data
->
request_fd
=
request_pipe
[
1
];
...
...
@@ -495,8 +498,14 @@ NTSTATUS WINAPI NtSetContextThread( HANDLE handle, const CONTEXT *context )
#ifdef __i386__
/* on i386 debug registers always require a server call */
self
=
((
handle
==
GetCurrentThread
())
&&
!
(
context
->
ContextFlags
&
(
CONTEXT_DEBUG_REGISTERS
&
~
CONTEXT_i386
)));
self
=
(
handle
==
GetCurrentThread
());
if
(
self
&&
(
context
->
ContextFlags
&
(
CONTEXT_DEBUG_REGISTERS
&
~
CONTEXT_i386
)))
{
struct
ntdll_thread_regs
*
const
regs
=
ntdll_get_thread_regs
();
self
=
(
regs
->
dr0
==
context
->
Dr0
&&
regs
->
dr1
==
context
->
Dr1
&&
regs
->
dr2
==
context
->
Dr2
&&
regs
->
dr3
==
context
->
Dr3
&&
regs
->
dr6
==
context
->
Dr6
&&
regs
->
dr7
==
context
->
Dr7
);
}
#endif
if
(
!
self
)
...
...
@@ -781,6 +790,7 @@ NTSTATUS WINAPI NtGetContextThread( HANDLE handle, CONTEXT *context )
NTSTATUS
ret
;
CONTEXT
ctx
;
DWORD
dummy
,
i
;
BOOL
self
=
FALSE
;
SERVER_START_REQ
(
get_thread_context
)
{
...
...
@@ -789,6 +799,7 @@ NTSTATUS WINAPI NtGetContextThread( HANDLE handle, CONTEXT *context )
req
->
suspend
=
0
;
wine_server_set_reply
(
req
,
&
ctx
,
sizeof
(
ctx
)
);
ret
=
wine_server_call
(
req
);
self
=
reply
->
self
;
}
SERVER_END_REQ
;
...
...
@@ -814,7 +825,23 @@ NTSTATUS WINAPI NtGetContextThread( HANDLE handle, CONTEXT *context )
}
}
if
(
ret
==
STATUS_SUCCESS
)
copy_context
(
context
,
&
ctx
,
context
->
ContextFlags
);
if
(
ret
==
STATUS_SUCCESS
)
{
copy_context
(
context
,
&
ctx
,
context
->
ContextFlags
);
#ifdef __i386__
/* update the cached version of the debug registers */
if
(
self
&&
(
context
->
ContextFlags
&
(
CONTEXT_DEBUG_REGISTERS
&
~
CONTEXT_i386
)))
{
struct
ntdll_thread_regs
*
const
regs
=
ntdll_get_thread_regs
();
regs
->
dr0
=
context
->
Dr0
;
regs
->
dr1
=
context
->
Dr1
;
regs
->
dr2
=
context
->
Dr2
;
regs
->
dr3
=
context
->
Dr3
;
regs
->
dr6
=
context
->
Dr6
;
regs
->
dr7
=
context
->
Dr7
;
}
#endif
}
else
if
(
ret
==
STATUS_PENDING
)
ret
=
STATUS_ACCESS_DENIED
;
return
ret
;
}
...
...
include/wine/server_protocol.h
View file @
2878d992
...
...
@@ -1990,6 +1990,7 @@ struct get_thread_context_request
struct
get_thread_context_reply
{
struct
reply_header
__header
;
int
self
;
/* VARARG(context,context); */
};
...
...
@@ -4348,6 +4349,6 @@ union generic_reply
struct
query_symlink_reply
query_symlink_reply
;
};
#define SERVER_PROTOCOL_VERSION 2
19
#define SERVER_PROTOCOL_VERSION 2
20
#endif
/* __WINE_WINE_SERVER_PROTOCOL_H */
include/winternl.h
View file @
2878d992
...
...
@@ -282,7 +282,7 @@ typedef struct _TEB
PVOID
SystemReserved1
[
54
];
/* 0cc used for kernel32 private data in Wine */
PVOID
Spare1
;
/* 1a4 */
LONG
ExceptionCode
;
/* 1a8 */
BYTE
SpareBytes1
[
40
];
/* 1ac */
BYTE
SpareBytes1
[
40
];
/* 1ac
used for ntdll private data in Wine
*/
PVOID
SystemReserved2
[
10
];
/* 1d4 used for ntdll private data in Wine */
GDI_TEB_BATCH
GdiTebBatch
;
/* 1fc */
ULONG
gdiRgn
;
/* 6dc */
...
...
server/protocol.def
View file @
2878d992
...
...
@@ -1432,6 +1432,7 @@ enum char_info_mode
unsigned int flags; /* context flags */
int suspend; /* if getting context during suspend */
@REPLY
int self; /* was it a handle to the current thread? */
VARARG(context,context); /* thread context */
@END
...
...
server/thread.c
View file @
2878d992
...
...
@@ -1094,6 +1094,7 @@ DECL_HANDLER(get_thread_context)
memset
(
data
,
0
,
sizeof
(
CONTEXT
)
);
get_thread_context
(
thread
,
data
,
req
->
flags
);
}
reply
->
self
=
(
thread
==
current
);
release_object
(
thread
);
}
...
...
server/trace.c
View file @
2878d992
...
...
@@ -1895,6 +1895,7 @@ static void dump_get_thread_context_request( const struct get_thread_context_req
static
void
dump_get_thread_context_reply
(
const
struct
get_thread_context_reply
*
req
)
{
fprintf
(
stderr
,
" self=%d,"
,
req
->
self
);
fprintf
(
stderr
,
" context="
);
dump_varargs_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