Moved the platform-independent part of the get/set_thread_context

requests to a common file.
This commit is contained in:
Alexandre Julliard 2005-11-02 14:12:13 +00:00
parent b2ff467e42
commit 3f85e26af2
6 changed files with 130 additions and 198 deletions

View File

@ -115,7 +115,7 @@ static inline int get_debug_reg( int pid, int num, DWORD *data )
}
/* retrieve a thread context */
static void get_thread_context( struct thread *thread, unsigned int flags, CONTEXT *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)
@ -171,7 +171,7 @@ static void get_thread_context( struct thread *thread, unsigned int flags, CONTE
/* set a thread context */
static void set_thread_context( struct thread *thread, unsigned int flags, const CONTEXT *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)
@ -231,7 +231,7 @@ static void set_thread_context( struct thread *thread, unsigned int flags, const
#elif defined(__sun) || defined(__sun__)
/* retrieve a thread context */
static void get_thread_context( struct thread *thread, unsigned int flags, CONTEXT *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)
@ -282,7 +282,7 @@ static void get_thread_context( struct thread *thread, unsigned int flags, CONTE
/* set a thread context */
static void set_thread_context( struct thread *thread, unsigned int flags, const CONTEXT *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)
@ -339,7 +339,7 @@ static void set_thread_context( struct thread *thread, unsigned int flags, const
#include <machine/reg.h>
/* retrieve a thread context */
static void get_thread_context( struct thread *thread, unsigned int flags, CONTEXT *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)
@ -411,7 +411,7 @@ static void get_thread_context( struct thread *thread, unsigned int flags, CONTE
/* set a thread context */
static void set_thread_context( struct thread *thread, unsigned int flags, const CONTEXT *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)
@ -489,7 +489,7 @@ static void set_thread_context( struct thread *thread, unsigned int flags, const
}
#else /* linux || __sun__ || __FreeBSD__ */
#error You must implement get/set_thread_context for your platform
#error You must implement get/set_thread_context_ptrace for your platform
#endif /* linux || __sun__ || __FreeBSD__ */
@ -536,7 +536,7 @@ void *get_thread_ip( struct thread *thread )
context.Eip = 0;
if (suspend_for_ptrace( thread ))
{
get_thread_context( thread, CONTEXT_CONTROL, &context );
get_thread_context_ptrace( thread, CONTEXT_CONTROL, &context );
resume_after_ptrace( thread );
}
return (void *)context.Eip;
@ -547,7 +547,7 @@ int get_thread_single_step( struct thread *thread )
{
CONTEXT context;
if (thread->context) return 0; /* don't single-step inside exception event */
get_thread_context( thread, CONTEXT_CONTROL, &context );
get_thread_context_ptrace( thread, CONTEXT_CONTROL, &context );
return (context.EFlags & 0x100) != 0;
}
@ -571,63 +571,39 @@ int tkill( int pid, int sig )
#endif
}
/* retrieve the current context of a thread */
DECL_HANDLER(get_thread_context)
/* retrieve the thread context */
void get_thread_context( struct thread *thread, CONTEXT *context, unsigned int flags )
{
struct thread *thread;
void *data;
int flags = req->flags & ~CONTEXT_i386; /* get rid of CPU id */
flags &= ~CONTEXT_i386; /* get rid of CPU id */
if (get_reply_max_size() < sizeof(CONTEXT))
if (thread->context) /* thread is inside an exception event or suspended */
{
set_error( STATUS_INVALID_PARAMETER );
return;
copy_context( context, thread->context, flags );
flags &= CONTEXT_DEBUG_REGISTERS;
}
if (!(thread = get_thread_from_handle( req->handle, THREAD_GET_CONTEXT ))) return;
if ((data = set_reply_data_size( sizeof(CONTEXT) )))
if (flags && suspend_for_ptrace( thread ))
{
memset( data, 0, sizeof(CONTEXT) );
if (thread->context) /* thread is inside an exception event */
{
copy_context( data, thread->context, flags );
flags &= CONTEXT_DEBUG_REGISTERS;
}
if (flags && suspend_for_ptrace( thread ))
{
get_thread_context( thread, flags, data );
resume_after_ptrace( thread );
}
get_thread_context_ptrace( thread, flags, context );
resume_after_ptrace( thread );
}
release_object( thread );
}
/* set the current context of a thread */
DECL_HANDLER(set_thread_context)
/* set the thread context */
void set_thread_context( struct thread *thread, const CONTEXT *context, unsigned int flags )
{
struct thread *thread;
int flags = req->flags & ~CONTEXT_i386; /* get rid of CPU id */
flags &= ~CONTEXT_i386; /* get rid of CPU id */
if (get_req_data_size() < sizeof(CONTEXT))
if (thread->context) /* thread is inside an exception event or suspended */
{
set_error( STATUS_INVALID_PARAMETER );
return;
copy_context( thread->context, context, flags );
flags &= CONTEXT_DEBUG_REGISTERS;
}
if ((thread = get_thread_from_handle( req->handle, THREAD_SET_CONTEXT )))
if (flags && suspend_for_ptrace( thread ))
{
if (thread->context) /* thread is inside an exception event */
{
copy_context( thread->context, get_req_data(), flags );
flags &= CONTEXT_DEBUG_REGISTERS;
}
if (flags && suspend_for_ptrace( thread ))
{
set_thread_context( thread, flags, get_req_data() );
resume_after_ptrace( thread );
}
release_object( thread );
set_thread_context_ptrace( thread, flags, context );
resume_after_ptrace( thread );
}
}

View File

@ -53,7 +53,7 @@
#include "request.h"
/* retrieve a thread context */
static void get_thread_context( struct thread *thread, unsigned int flags, CONTEXT *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)
@ -128,7 +128,7 @@ static void get_thread_context( struct thread *thread, unsigned int flags, CONTE
#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( struct thread *thread, unsigned int flags, const CONTEXT *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)
@ -264,7 +264,7 @@ void *get_thread_ip( struct thread *thread )
context.Iar = 0;
if (suspend_for_ptrace( thread ))
{
get_thread_context( thread, CONTEXT_CONTROL, &context );
get_thread_context_ptrace( thread, CONTEXT_CONTROL, &context );
resume_after_ptrace( thread );
}
return (void *)context.Iar;
@ -275,7 +275,7 @@ int get_thread_single_step( struct thread *thread )
{
CONTEXT context;
if (thread->context) return 0;
get_thread_context( thread, CONTEXT_CONTROL, &context );
get_thread_context_ptrace( thread, CONTEXT_CONTROL, &context );
#ifndef MSR_SE
# define MSR_SE (1<<10)
#endif
@ -290,63 +290,31 @@ int tkill( int pid, int sig )
return -1;
}
/* retrieve the current context of a thread */
DECL_HANDLER(get_thread_context)
/* retrieve the thread context */
void get_thread_context( struct thread *thread, CONTEXT *context, unsigned int flags )
{
struct thread *thread;
void *data;
int flags = req->flags;
if (get_reply_max_size() < sizeof(CONTEXT))
if (thread->context) /* thread is inside an exception event or suspended */
{
set_error( STATUS_INVALID_PARAMETER );
return;
copy_context( context, thread->context, flags );
}
if (!(thread = get_thread_from_handle( req->handle, THREAD_GET_CONTEXT ))) return;
if ((data = set_reply_data_size( sizeof(CONTEXT) )))
else if (flags && suspend_for_ptrace( thread ))
{
memset( data, 0, sizeof(CONTEXT) );
if (thread->context) /* thread is inside an exception event */
{
copy_context( data, thread->context, flags );
flags = 0;
}
if (flags && suspend_for_ptrace( thread ))
{
get_thread_context( thread, flags, data );
resume_after_ptrace( thread );
}
get_thread_context_ptrace( thread, flags, context );
resume_after_ptrace( thread );
}
release_object( thread );
}
/* set the current context of a thread */
DECL_HANDLER(set_thread_context)
/* set the thread context */
void set_thread_context( struct thread *thread, const CONTEXT *context, unsigned int flags )
{
struct thread *thread;
int flags = req->flags;
if (get_req_data_size() < sizeof(CONTEXT))
if (thread->context) /* thread is inside an exception event or suspended */
{
set_error( STATUS_INVALID_PARAMETER );
return;
copy_context( thread->context, context, flags );
}
if ((thread = get_thread_from_handle( req->handle, THREAD_SET_CONTEXT )))
else if (flags && suspend_for_ptrace( thread ))
{
if (thread->context) /* thread is inside an exception event */
{
copy_context( thread->context, get_req_data(), flags );
flags = 0;
}
if (flags && suspend_for_ptrace( thread ))
{
set_thread_context( thread, flags, get_req_data() );
resume_after_ptrace( thread );
}
release_object( thread );
set_thread_context_ptrace( thread, flags, context );
resume_after_ptrace( thread );
}
}

View File

@ -44,7 +44,7 @@
#if defined(__sun) || defined(__sun__)
/* retrieve a thread context */
static void get_thread_context( struct thread *thread, unsigned int flags, CONTEXT *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)
@ -94,13 +94,13 @@ static void get_thread_context( struct thread *thread, unsigned int flags, CONTE
/* set a thread context */
static void set_thread_context( struct thread *thread, unsigned int flags, const CONTEXT *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 for your platform
#error You must implement get/set_thread_context_ptrace for your platform
#endif /* __sun__ */
@ -164,7 +164,7 @@ void *get_thread_ip( struct thread *thread )
context.pc = 0;
if (suspend_for_ptrace( thread ))
{
get_thread_context( thread, CONTEXT_CONTROL, &context );
get_thread_context_ptrace( thread, CONTEXT_CONTROL, &context );
resume_after_ptrace( thread );
}
return (void *)context.pc;
@ -184,63 +184,35 @@ int tkill( int pid, int sig )
return -1;
}
/* retrieve the current context of a thread */
DECL_HANDLER(get_thread_context)
/* retrieve the thread context */
void get_thread_context( struct thread *thread, CONTEXT *context, unsigned int flags )
{
struct thread *thread;
void *data;
int flags = req->flags & ~CONTEXT_SPARC; /* get rid of CPU id */
flags &= ~CONTEXT_SPARC; /* get rid of CPU id */
if (get_reply_max_size() < sizeof(CONTEXT))
if (thread->context) /* thread is inside an exception event or suspended */
{
set_error( STATUS_INVALID_PARAMETER );
return;
copy_context( context, thread->context, flags );
}
if (!(thread = get_thread_from_handle( req->handle, THREAD_GET_CONTEXT ))) return;
if ((data = set_reply_data_size( sizeof(CONTEXT) )))
else if (flags && suspend_for_ptrace( thread ))
{
memset( data, 0, sizeof(CONTEXT) );
if (thread->context) /* thread is inside an exception event */
{
copy_context( data, thread->context, flags );
flags = 0;
}
if (flags && suspend_for_ptrace( thread ))
{
get_thread_context( thread, flags, data );
resume_after_ptrace( thread );
}
get_thread_context_ptrace( thread, flags, context );
resume_after_ptrace( thread );
}
release_object( thread );
}
/* set the current context of a thread */
DECL_HANDLER(set_thread_context)
/* set the thread context */
void set_thread_context( struct thread *thread, const CONTEXT *context, unsigned int flags )
{
struct thread *thread;
int flags = req->flags & ~CONTEXT_SPARC; /* get rid of CPU id */
flags &= ~CONTEXT_SPARC; /* get rid of CPU id */
if (get_req_data_size() < sizeof(CONTEXT))
if (thread->context) /* thread is inside an exception event or suspended */
{
set_error( STATUS_INVALID_PARAMETER );
return;
copy_context( thread->context, context, flags );
}
if ((thread = get_thread_from_handle( req->handle, THREAD_SET_CONTEXT )))
else if (flags && suspend_for_ptrace( thread ))
{
if (thread->context) /* thread is inside an exception event */
{
copy_context( thread->context, get_req_data(), flags );
flags = 0;
}
if (flags && suspend_for_ptrace( thread ))
{
set_thread_context( thread, flags, get_req_data() );
resume_after_ptrace( thread );
}
release_object( thread );
set_thread_context_ptrace( thread, flags, context );
resume_after_ptrace( thread );
}
}

View File

@ -66,7 +66,7 @@ static inline int get_debug_reg( int pid, int num, DWORD64 *data )
}
/* retrieve a thread context */
static void get_thread_context( struct thread *thread, unsigned int flags, CONTEXT *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)
@ -129,7 +129,7 @@ static void get_thread_context( struct thread *thread, unsigned int flags, CONTE
/* set a thread context */
static void set_thread_context( struct thread *thread, unsigned int flags, const CONTEXT *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)
@ -195,7 +195,7 @@ static void set_thread_context( struct thread *thread, unsigned int flags, const
}
#else /* linux */
#error You must implement get/set_thread_context for your platform
#error You must implement get/set_thread_context_ptrace for your platform
#endif /* linux */
@ -251,7 +251,7 @@ void *get_thread_ip( struct thread *thread )
context.Rip = 0;
if (suspend_for_ptrace( thread ))
{
get_thread_context( thread, CONTEXT_CONTROL, &context );
get_thread_context_ptrace( thread, CONTEXT_CONTROL, &context );
resume_after_ptrace( thread );
}
return (void *)context.Rip;
@ -262,7 +262,7 @@ int get_thread_single_step( struct thread *thread )
{
CONTEXT context;
if (thread->context) return 0; /* don't single-step inside exception event */
get_thread_context( thread, CONTEXT_CONTROL, &context );
get_thread_context_ptrace( thread, CONTEXT_CONTROL, &context );
return (context.EFlags & 0x100) != 0;
}
@ -282,63 +282,39 @@ int tkill( int pid, int sig )
#endif
}
/* retrieve the current context of a thread */
DECL_HANDLER(get_thread_context)
/* retrieve the thread context */
void get_thread_context( struct thread *thread, CONTEXT *context, unsigned int flags )
{
struct thread *thread;
void *data;
int flags = req->flags & ~CONTEXT_AMD64; /* get rid of CPU id */
flags &= ~CONTEXT_AMD64; /* get rid of CPU id */
if (get_reply_max_size() < sizeof(CONTEXT))
if (thread->context) /* thread is inside an exception event or suspended */
{
set_error( STATUS_INVALID_PARAMETER );
return;
copy_context( context, thread->context, flags );
flags &= CONTEXT_DEBUG_REGISTERS;
}
if (!(thread = get_thread_from_handle( req->handle, THREAD_GET_CONTEXT ))) return;
if ((data = set_reply_data_size( sizeof(CONTEXT) )))
if (flags && suspend_for_ptrace( thread ))
{
memset( data, 0, sizeof(CONTEXT) );
if (thread->context) /* thread is inside an exception event */
{
copy_context( data, thread->context, flags );
flags &= CONTEXT_DEBUG_REGISTERS;
}
if (flags && suspend_for_ptrace( thread ))
{
get_thread_context( thread, flags, data );
resume_after_ptrace( thread );
}
get_thread_context_ptrace( thread, flags, context );
resume_after_ptrace( thread );
}
release_object( thread );
}
/* set the current context of a thread */
DECL_HANDLER(set_thread_context)
/* set the thread context */
void set_thread_context( struct thread *thread, const CONTEXT *context, unsigned int flags )
{
struct thread *thread;
int flags = req->flags & ~CONTEXT_AMD64; /* get rid of CPU id */
flags &= ~CONTEXT_AMD64; /* get rid of CPU id */
if (get_req_data_size() < sizeof(CONTEXT))
if (thread->context) /* thread is inside an exception event or suspended */
{
set_error( STATUS_INVALID_PARAMETER );
return;
copy_context( thread->context, context, flags );
flags &= CONTEXT_DEBUG_REGISTERS;
}
if ((thread = get_thread_from_handle( req->handle, THREAD_SET_CONTEXT )))
if (flags && suspend_for_ptrace( thread ))
{
if (thread->context) /* thread is inside an exception event */
{
copy_context( thread->context, get_req_data(), flags );
flags &= CONTEXT_DEBUG_REGISTERS;
}
if (flags && suspend_for_ptrace( thread ))
{
set_thread_context( thread, flags, get_req_data() );
resume_after_ptrace( thread );
}
release_object( thread );
set_thread_context_ptrace( thread, flags, context );
resume_after_ptrace( thread );
}
}

View File

@ -1040,6 +1040,44 @@ DECL_HANDLER(get_apc)
free( apc );
}
/* retrieve the current context of a thread */
DECL_HANDLER(get_thread_context)
{
struct thread *thread;
void *data;
if (get_reply_max_size() < sizeof(CONTEXT))
{
set_error( STATUS_INVALID_PARAMETER );
return;
}
if (!(thread = get_thread_from_handle( req->handle, THREAD_GET_CONTEXT ))) return;
if ((data = set_reply_data_size( sizeof(CONTEXT) )))
{
memset( data, 0, sizeof(CONTEXT) );
get_thread_context( thread, data, req->flags );
}
release_object( thread );
}
/* set the current context of a thread */
DECL_HANDLER(set_thread_context)
{
struct thread *thread;
if (get_req_data_size() < sizeof(CONTEXT))
{
set_error( STATUS_INVALID_PARAMETER );
return;
}
if ((thread = get_thread_from_handle( req->handle, THREAD_SET_CONTEXT )))
{
set_thread_context( thread, get_req_data(), req->flags );
release_object( thread );
}
}
/* fetch a selector entry for a thread */
DECL_HANDLER(get_selector_entry)
{

View File

@ -130,6 +130,8 @@ extern int read_thread_int( struct thread *thread, const int *addr, int *data );
extern int write_thread_int( struct thread *thread, int *addr, int data, unsigned int mask );
extern void *get_thread_ip( struct thread *thread );
extern int get_thread_single_step( struct thread *thread );
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 int tkill( int pid, int sig );
extern int send_thread_signal( struct thread *thread, int sig );