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
2654be08
Commit
2654be08
authored
Jan 11, 2006
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ntdll: Handle NtSetContextThread on the client side (as far as
possible) when setting the context of the current thread.
parent
7114f8c3
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
109 additions
and
46 deletions
+109
-46
ntdll_misc.h
dlls/ntdll/ntdll_misc.h
+1
-0
signal_i386.c
dlls/ntdll/signal_i386.c
+24
-17
signal_powerpc.c
dlls/ntdll/signal_powerpc.c
+11
-0
signal_sparc.c
dlls/ntdll/signal_sparc.c
+11
-0
signal_x86_64.c
dlls/ntdll/signal_x86_64.c
+11
-0
thread.c
dlls/ntdll/thread.c
+38
-24
server_protocol.h
include/wine/server_protocol.h
+2
-1
context_i386.c
server/context_i386.c
+2
-3
protocol.def
server/protocol.def
+2
-0
thread.c
server/thread.c
+1
-0
trace.c
server/trace.c
+6
-1
No files found.
dlls/ntdll/ntdll_misc.h
View file @
2654be08
...
...
@@ -32,6 +32,7 @@
/* exceptions */
extern
void
wait_suspend
(
CONTEXT
*
context
);
extern
void
WINAPI
__regs_RtlRaiseException
(
PEXCEPTION_RECORD
,
PCONTEXT
);
extern
void
set_cpu_context
(
const
CONTEXT
*
context
);
/* debug helper */
extern
LPCSTR
debugstr_us
(
const
UNICODE_STRING
*
str
);
...
...
dlls/ntdll/signal_i386.c
View file @
2654be08
...
...
@@ -722,13 +722,13 @@ inline static void save_fpu( CONTEXT *context, const SIGCONTEXT *sigcontext )
*
* Restore the FPU context to a sigcontext.
*/
inline
static
void
restore_fpu
(
CONTEXT
*
context
)
inline
static
void
restore_fpu
(
const
CONTEXT
*
context
)
{
FLOATING_SAVE_AREA
float_status
=
context
->
FloatSave
;
/* reset the current interrupt status */
context
->
FloatSave
.
StatusWord
&=
context
->
FloatSave
.
ControlWord
|
0xffffff80
;
float_status
.
StatusWord
&=
float_status
.
ControlWord
|
0xffffff80
;
#ifdef __GNUC__
/* avoid nested exceptions */
__asm__
__volatile__
(
"frstor %0; fwait"
:
:
"m"
(
context
->
FloatSave
)
);
__asm__
__volatile__
(
"frstor %0; fwait"
:
:
"m"
(
float_status
)
);
#endif
/* __GNUC__ */
}
...
...
@@ -799,12 +799,19 @@ inline static void restore_context( const CONTEXT *context, SIGCONTEXT *sigconte
*
* Set the new CPU context.
*/
inline
static
void
DECLSPEC_NORETURN
set_cpu_context
(
CONTEXT
*
context
)
void
set_cpu_context
(
const
CONTEXT
*
context
)
{
DWORD
flags
=
context
->
ContextFlags
&
~
CONTEXT_i386
;
if
(
flags
&
CONTEXT_FLOATING_POINT
)
restore_fpu
(
context
);
__wine_call_from_32_restore_regs
(
context
);
if
(
flags
&
CONTEXT_FULL
)
{
if
((
flags
&
CONTEXT_FULL
)
!=
(
CONTEXT_FULL
&
~
CONTEXT_i386
))
FIXME
(
"setting partial context (%lx) not supported
\n
"
,
flags
);
else
__wine_call_from_32_restore_regs
(
context
);
}
}
...
...
@@ -991,7 +998,7 @@ static inline DWORD get_fpu_code( const CONTEXT *context )
/**********************************************************************
* raise_segv_exception
*/
static
void
WINAPI
DECLSPEC_NORETURN
raise_segv_exception
(
EXCEPTION_RECORD
*
rec
,
CONTEXT
*
context
)
static
void
WINAPI
raise_segv_exception
(
EXCEPTION_RECORD
*
rec
,
CONTEXT
*
context
)
{
switch
(
rec
->
ExceptionCode
)
{
...
...
@@ -1011,14 +1018,14 @@ static void WINAPI DECLSPEC_NORETURN raise_segv_exception( EXCEPTION_RECORD *rec
}
__regs_RtlRaiseException
(
rec
,
context
);
done:
set_cpu_context
(
context
);
NtSetContextThread
(
GetCurrentThread
(),
context
);
}
/**********************************************************************
* raise_trap_exception
*/
static
void
WINAPI
DECLSPEC_NORETURN
raise_trap_exception
(
EXCEPTION_RECORD
*
rec
,
CONTEXT
*
context
)
static
void
WINAPI
raise_trap_exception
(
EXCEPTION_RECORD
*
rec
,
CONTEXT
*
context
)
{
DWORD
dr0
,
dr1
,
dr2
,
dr3
,
dr6
,
dr7
;
...
...
@@ -1037,6 +1044,7 @@ static void WINAPI DECLSPEC_NORETURN raise_trap_exception( EXCEPTION_RECORD *rec
* shall return a breakpoint, not a single step exception
*/
if
(
!
(
context
->
Dr6
&
0xf
))
rec
->
ExceptionCode
=
EXCEPTION_BREAKPOINT
;
context
->
ContextFlags
|=
CONTEXT_FULL
;
/* restore flags */
}
}
...
...
@@ -1049,15 +1057,14 @@ static void WINAPI DECLSPEC_NORETURN raise_trap_exception( EXCEPTION_RECORD *rec
__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
);
context
->
ContextFlags
|=
CONTEXT_DEBUG_REGISTERS
;
}
context
->
ContextFlags
=
CONTEXT_FULL
;
/* restore flags */
set_cpu_context
(
context
);
NtSetContextThread
(
GetCurrentThread
(),
context
);
}
...
...
@@ -1066,10 +1073,10 @@ static void WINAPI DECLSPEC_NORETURN raise_trap_exception( EXCEPTION_RECORD *rec
*
* Generic raise function for exceptions that don't need special treatment.
*/
static
void
WINAPI
DECLSPEC_NORETURN
raise_exception
(
EXCEPTION_RECORD
*
rec
,
CONTEXT
*
context
)
static
void
WINAPI
raise_exception
(
EXCEPTION_RECORD
*
rec
,
CONTEXT
*
context
)
{
__regs_RtlRaiseException
(
rec
,
context
);
set_cpu_context
(
context
);
NtSetContextThread
(
GetCurrentThread
(),
context
);
}
...
...
@@ -1077,7 +1084,7 @@ static void WINAPI DECLSPEC_NORETURN raise_exception( EXCEPTION_RECORD *rec, CON
/**********************************************************************
* raise_vm86_sti_exception
*/
static
void
WINAPI
DECLSPEC_NORETURN
raise_vm86_sti_exception
(
EXCEPTION_RECORD
*
rec
,
CONTEXT
*
context
)
static
void
WINAPI
raise_vm86_sti_exception
(
EXCEPTION_RECORD
*
rec
,
CONTEXT
*
context
)
{
/* merge_vm86_pending_flags merges the vm86_pending flag in safely */
NtCurrentTeb
()
->
vm86_pending
|=
VIP_MASK
;
...
...
@@ -1101,7 +1108,7 @@ static void WINAPI DECLSPEC_NORETURN raise_vm86_sti_exception( EXCEPTION_RECORD
__regs_RtlRaiseException
(
rec
,
context
);
}
done:
set_cpu_context
(
context
);
NtSetContextThread
(
GetCurrentThread
(),
context
);
}
...
...
dlls/ntdll/signal_powerpc.c
View file @
2654be08
...
...
@@ -268,6 +268,17 @@ inline static void restore_fpu( CONTEXT *context, const SIGCONTEXT *sigcontext )
}
/***********************************************************************
* set_cpu_context
*
* Set the new CPU context.
*/
void
set_cpu_context
(
const
CONTEXT
*
context
)
{
FIXME
(
"not implemented
\n
"
);
}
/**********************************************************************
* get_fpu_code
*
...
...
dlls/ntdll/signal_sparc.c
View file @
2654be08
...
...
@@ -148,6 +148,17 @@ static void restore_fpu( CONTEXT *context, ucontext_t *ucontext )
}
/***********************************************************************
* set_cpu_context
*
* Set the new CPU context.
*/
void
set_cpu_context
(
const
CONTEXT
*
context
)
{
FIXME
(
"not implemented
\n
"
);
}
/**********************************************************************
* segv_handler
*
...
...
dlls/ntdll/signal_x86_64.c
View file @
2654be08
...
...
@@ -196,6 +196,17 @@ static void restore_context( const CONTEXT *context, SIGCONTEXT *sigcontext )
}
/***********************************************************************
* set_cpu_context
*
* Set the new CPU context.
*/
void
set_cpu_context
(
const
CONTEXT
*
context
)
{
FIXME
(
"not implemented
\n
"
);
}
/**********************************************************************
* segv_handler
*
...
...
dlls/ntdll/thread.c
View file @
2654be08
...
...
@@ -491,41 +491,55 @@ NTSTATUS WINAPI NtSetContextThread( HANDLE handle, const CONTEXT *context )
{
NTSTATUS
ret
;
DWORD
dummy
,
i
;
BOOL
self
=
FALSE
;
SERVER_START_REQ
(
set_thread_context
)
{
req
->
handle
=
handle
;
req
->
flags
=
context
->
ContextFlags
;
req
->
suspend
=
0
;
wine_server_add_data
(
req
,
context
,
sizeof
(
*
context
)
);
ret
=
wine_server_call
(
req
);
}
SERVER_END_REQ
;
#ifdef __i386__
/* on i386 debug registers always require a server call */
self
=
((
handle
==
GetCurrentThread
())
&&
!
(
context
->
ContextFlags
&
(
CONTEXT_DEBUG_REGISTERS
&
~
CONTEXT_i386
)));
#endif
if
(
ret
==
STATUS_PENDING
)
if
(
!
self
)
{
if
(
NtSuspendThread
(
handle
,
&
dummy
)
==
STATUS_SUCCESS
)
SERVER_START_REQ
(
set_thread_context
)
{
for
(
i
=
0
;
i
<
100
;
i
++
)
req
->
handle
=
handle
;
req
->
flags
=
context
->
ContextFlags
;
req
->
suspend
=
0
;
wine_server_add_data
(
req
,
context
,
sizeof
(
*
context
)
);
ret
=
wine_server_call
(
req
);
self
=
reply
->
self
;
}
SERVER_END_REQ
;
if
(
ret
==
STATUS_PENDING
)
{
if
(
NtSuspendThread
(
handle
,
&
dummy
)
==
STATUS_SUCCESS
)
{
SERVER_START_REQ
(
set_thread_context
)
for
(
i
=
0
;
i
<
100
;
i
++
)
{
req
->
handle
=
handle
;
req
->
flags
=
context
->
ContextFlags
;
req
->
suspend
=
0
;
wine_server_add_data
(
req
,
context
,
sizeof
(
*
context
)
);
ret
=
wine_server_call
(
req
);
SERVER_START_REQ
(
set_thread_context
)
{
req
->
handle
=
handle
;
req
->
flags
=
context
->
ContextFlags
;
req
->
suspend
=
0
;
wine_server_add_data
(
req
,
context
,
sizeof
(
*
context
)
);
ret
=
wine_server_call
(
req
);
}
SERVER_END_REQ
;
if
(
ret
!=
STATUS_PENDING
)
break
;
NtYieldExecution
();
}
SERVER_END_REQ
;
if
(
ret
!=
STATUS_PENDING
)
break
;
NtYieldExecution
();
NtResumeThread
(
handle
,
&
dummy
);
}
NtResumeThread
(
handle
,
&
dummy
)
;
if
(
ret
==
STATUS_PENDING
)
ret
=
STATUS_ACCESS_DENIED
;
}
if
(
ret
)
return
ret
;
}
if
(
ret
==
STATUS_PENDING
)
ret
=
STATUS_ACCESS_DENIED
;
return
ret
;
if
(
self
)
set_cpu_context
(
context
)
;
return
STATUS_SUCCESS
;
}
...
...
include/wine/server_protocol.h
View file @
2654be08
...
...
@@ -2006,6 +2006,7 @@ struct set_thread_context_request
struct
set_thread_context_reply
{
struct
reply_header
__header
;
int
self
;
};
...
...
@@ -4347,6 +4348,6 @@ union generic_reply
struct
query_symlink_reply
query_symlink_reply
;
};
#define SERVER_PROTOCOL_VERSION 21
8
#define SERVER_PROTOCOL_VERSION 21
9
#endif
/* __WINE_WINE_SERVER_PROTOCOL_H */
server/context_i386.c
View file @
2654be08
...
...
@@ -604,10 +604,9 @@ void set_thread_context( struct thread *thread, const CONTEXT *context, unsigned
flags
&=
~
CONTEXT_i386
;
/* get rid of CPU id */
if
(
thread
->
context
)
/* thread is inside an exception event or suspended */
{
copy_context
(
thread
->
context
,
context
,
flags
);
flags
&=
CONTEXT_DEBUG_REGISTERS
;
}
flags
&=
CONTEXT_DEBUG_REGISTERS
;
/* the other registers are handled on the client side */
if
(
flags
&&
suspend_for_ptrace
(
thread
))
{
...
...
server/protocol.def
View file @
2654be08
...
...
@@ -1442,6 +1442,8 @@ enum char_info_mode
unsigned int flags; /* context flags */
int suspend; /* if setting context during suspend */
VARARG(context,context); /* thread context */
@REPLY
int self; /* was it a handle to the current thread? */
@END
...
...
server/thread.c
View file @
2654be08
...
...
@@ -1132,6 +1132,7 @@ DECL_HANDLER(set_thread_context)
{
set_thread_context
(
thread
,
get_req_data
(),
req
->
flags
);
}
reply
->
self
=
(
thread
==
current
);
release_object
(
thread
);
}
...
...
server/trace.c
View file @
2654be08
...
...
@@ -1908,6 +1908,11 @@ static void dump_set_thread_context_request( const struct set_thread_context_req
dump_varargs_context
(
cur_size
);
}
static
void
dump_set_thread_context_reply
(
const
struct
set_thread_context_reply
*
req
)
{
fprintf
(
stderr
,
" self=%d"
,
req
->
self
);
}
static
void
dump_get_selector_entry_request
(
const
struct
get_selector_entry_request
*
req
)
{
fprintf
(
stderr
,
" handle=%p,"
,
req
->
handle
);
...
...
@@ -3527,7 +3532,7 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
(
dump_func
)
dump_cancel_timer_reply
,
(
dump_func
)
dump_get_timer_info_reply
,
(
dump_func
)
dump_get_thread_context_reply
,
(
dump_func
)
0
,
(
dump_func
)
dump_set_thread_context_reply
,
(
dump_func
)
dump_get_selector_entry_reply
,
(
dump_func
)
dump_add_atom_reply
,
(
dump_func
)
0
,
...
...
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