mirror of
https://github.com/xen-project/xen.git
synced 2026-10-29 18:50:05 +01:00
Consolidate xc_ptrace and xc_ptrace_core
* xc_ptrace
- Merge xc_ptrace_core into xc_ptrace
- ATTACH now reads the data argument. If non-zero then
a corefile is being debuged. Otherwise a thread has
been attached to. This allows xc_waitdomain_core() or
xc_waitdomain() to be called as appropriate in
subsequent xc_ptrace() calls.
* xc_waitdomain
- Rename xc_waitdomain (xc_ptrace.c version) __xc_waitdomain
- Rename xc_waitdomain (xc_ptrace_core.c version) xc_waitdomain_core
- Create xc_waitdomain (in xc_ptrace.c), a wrapper for __xc_waitdomain
and xc_waitdomain_core.
Consolidation seemed difficult but ctxt needs to be
passed into xc_waitdomain_core or made global.
Alternatively, xc_waitdomain_core could be moved into xc_ptrace.c,
but this seems messy.
* map_domain_va
- Rename map_domain_va (xc_ptrace_core.c version) map_domain_va_core
- Have it accept ctxt, like xc_waitdomain_core
* myptrace and myxcwait (linux-xen-low.c)
Removed, call the now generic xc_ptrace() and xc_waitdomain() instead
When calling xc_ptrace ATTACH, if a corefile is in use, a fd will
be passed, otherwise a pid. The fd part is important, as this
is saved internally in xc_ptrace_core.c, and passed to xc_waitdomain_core()
as neccessary. Pereviously xc_waitdomain_core() received a pid and
thus could not open the corefile.
Signed-Off-By: Horms <horms@verge.net.au>
This commit is contained in:
1 parent
d531f7eb39
commit
e265d47bd6
4 files changed
+74
-151
No files matched your search
@@ -41,8 +41,6 @@
|
||||
|
||||
#define TRACE_ENTER /* printf("enter %s\n", __FUNCTION__) */
|
||||
|
||||
long (*myptrace)(int xc_handle, enum __ptrace_request, uint32_t, long, long);
|
||||
int (*myxcwait)(int xc_handle, int domain, int *status, int options) ;
|
||||
static int xc_handle;
|
||||
|
||||
static inline int
|
||||
@@ -170,7 +168,7 @@ linux_attach (int domid)
|
||||
add_thread (0, new_process);
|
||||
new_process->stop_expected = 0;
|
||||
|
||||
if (myptrace (xc_handle, PTRACE_ATTACH, domid, 0, 0) != 0) {
|
||||
if (xc_ptrace (xc_handle, PTRACE_ATTACH, domid, 0, isfile) != 0) {
|
||||
fprintf (stderr, "Cannot attach to domain %d: %s (%d)\n", domid,
|
||||
strerror (errno), errno);
|
||||
fflush (stderr);
|
||||
@@ -188,7 +186,7 @@ linux_kill_one_process (struct inferior_list_entry *entry)
|
||||
{
|
||||
struct thread_info *thread = (struct thread_info *) entry;
|
||||
struct process_info *process = get_thread_process (thread);
|
||||
myptrace (xc_handle, PTRACE_KILL, pid_of (process), 0, 0);
|
||||
xc_ptrace (xc_handle, PTRACE_KILL, pid_of (process), 0, 0);
|
||||
}
|
||||
|
||||
|
||||
@@ -202,7 +200,7 @@ static void
|
||||
linux_detach_one_process (struct inferior_list_entry *entry)
|
||||
{
|
||||
|
||||
myptrace (xc_handle, PTRACE_DETACH, current_domid, 0, 0);
|
||||
xc_ptrace (xc_handle, PTRACE_DETACH, current_domid, 0, 0);
|
||||
}
|
||||
|
||||
|
||||
@@ -228,7 +226,7 @@ static unsigned char
|
||||
linux_wait (char *status)
|
||||
{
|
||||
int w;
|
||||
if (myxcwait(xc_handle, current_domid, &w, 0))
|
||||
if (xc_waitdomain(xc_handle, current_domid, &w, 0))
|
||||
return -1;
|
||||
|
||||
linux_set_inferior();
|
||||
@@ -250,7 +248,7 @@ linux_resume (struct thread_resume *resume_info)
|
||||
for_each_inferior(&all_threads, regcache_invalidate_one);
|
||||
if (debug_threads)
|
||||
fprintf(stderr, "step: %d\n", step);
|
||||
myptrace (xc_handle, step ? PTRACE_SINGLESTEP : PTRACE_CONT,
|
||||
xc_ptrace (xc_handle, step ? PTRACE_SINGLESTEP : PTRACE_CONT,
|
||||
resume_info->thread, 0, 0);
|
||||
|
||||
}
|
||||
@@ -275,7 +273,7 @@ regsets_fetch_inferior_registers ()
|
||||
}
|
||||
|
||||
buf = malloc (regset->size);
|
||||
res = myptrace (xc_handle, regset->get_request,
|
||||
res = xc_ptrace (xc_handle, regset->get_request,
|
||||
curvcpuid(),
|
||||
0, (PTRACE_XFER_TYPE)buf);
|
||||
if (res < 0)
|
||||
@@ -329,7 +327,7 @@ regsets_store_inferior_registers ()
|
||||
|
||||
buf = malloc (regset->size);
|
||||
regset->fill_function (buf);
|
||||
res = myptrace (xc_handle, regset->set_request, curvcpuid(), 0, (PTRACE_XFER_TYPE)buf);
|
||||
res = xc_ptrace (xc_handle, regset->set_request, curvcpuid(), 0, (PTRACE_XFER_TYPE)buf);
|
||||
if (res < 0)
|
||||
{
|
||||
if (errno == EIO)
|
||||
@@ -407,7 +405,7 @@ linux_read_memory (CORE_ADDR memaddr, char *myaddr, int len)
|
||||
for (i = 0; i < count; i++, addr += sizeof (PTRACE_XFER_TYPE))
|
||||
{
|
||||
errno = 0;
|
||||
buffer[i] = myptrace (xc_handle, PTRACE_PEEKTEXT, curvcpuid(), (PTRACE_ARG3_TYPE) addr, 0);
|
||||
buffer[i] = xc_ptrace (xc_handle, PTRACE_PEEKTEXT, curvcpuid(), (PTRACE_ARG3_TYPE) addr, 0);
|
||||
if (errno)
|
||||
return errno;
|
||||
}
|
||||
@@ -440,13 +438,13 @@ linux_write_memory (CORE_ADDR memaddr, const char *myaddr, int len)
|
||||
|
||||
/* Fill start and end extra bytes of buffer with existing memory data. */
|
||||
|
||||
buffer[0] = myptrace (xc_handle, PTRACE_PEEKTEXT, curvcpuid(),
|
||||
buffer[0] = xc_ptrace (xc_handle, PTRACE_PEEKTEXT, curvcpuid(),
|
||||
(PTRACE_ARG3_TYPE) addr, 0);
|
||||
|
||||
if (count > 1)
|
||||
{
|
||||
buffer[count - 1]
|
||||
= myptrace (xc_handle, PTRACE_PEEKTEXT, curvcpuid(),
|
||||
= xc_ptrace (xc_handle, PTRACE_PEEKTEXT, curvcpuid(),
|
||||
(PTRACE_ARG3_TYPE) (addr + (count - 1)
|
||||
* sizeof (PTRACE_XFER_TYPE)),
|
||||
0);
|
||||
@@ -460,7 +458,7 @@ linux_write_memory (CORE_ADDR memaddr, const char *myaddr, int len)
|
||||
for (i = 0; i < count; i++, addr += sizeof (PTRACE_XFER_TYPE))
|
||||
{
|
||||
errno = 0;
|
||||
myptrace (xc_handle, PTRACE_POKETEXT, curvcpuid(),
|
||||
xc_ptrace (xc_handle, PTRACE_POKETEXT, curvcpuid(),
|
||||
(PTRACE_ARG3_TYPE) addr, buffer[i]);
|
||||
if (errno)
|
||||
return errno;
|
||||
@@ -561,13 +559,6 @@ initialize_low (void)
|
||||
the_low_target.breakpoint_len);
|
||||
init_registers ();
|
||||
linux_init_signals ();
|
||||
if (isfile) {
|
||||
myptrace = xc_ptrace_core;
|
||||
myxcwait = xc_waitdomain_core;
|
||||
} else {
|
||||
myptrace = xc_ptrace;
|
||||
myxcwait = xc_waitdomain;
|
||||
}
|
||||
using_threads = thread_db_init ();
|
||||
|
||||
}
|
||||
|
||||
+48
-43
@@ -9,38 +9,11 @@
|
||||
#include "xg_private.h"
|
||||
#include "xc_ptrace.h"
|
||||
|
||||
const char const * ptrace_names[] = {
|
||||
"PTRACE_TRACEME",
|
||||
"PTRACE_PEEKTEXT",
|
||||
"PTRACE_PEEKDATA",
|
||||
"PTRACE_PEEKUSER",
|
||||
"PTRACE_POKETEXT",
|
||||
"PTRACE_POKEDATA",
|
||||
"PTRACE_POKEUSER",
|
||||
"PTRACE_CONT",
|
||||
"PTRACE_KILL",
|
||||
"PTRACE_SINGLESTEP",
|
||||
"PTRACE_INVALID",
|
||||
"PTRACE_INVALID",
|
||||
"PTRACE_GETREGS",
|
||||
"PTRACE_SETREGS",
|
||||
"PTRACE_GETFPREGS",
|
||||
"PTRACE_SETFPREGS",
|
||||
"PTRACE_ATTACH",
|
||||
"PTRACE_DETACH",
|
||||
"PTRACE_GETFPXREGS",
|
||||
"PTRACE_SETFPXREGS",
|
||||
"PTRACE_INVALID",
|
||||
"PTRACE_INVALID",
|
||||
"PTRACE_INVALID",
|
||||
"PTRACE_INVALID",
|
||||
"PTRACE_SYSCALL",
|
||||
};
|
||||
|
||||
/* XXX application state */
|
||||
static long nr_pages = 0;
|
||||
static unsigned long *page_array = NULL;
|
||||
static int current_domid = -1;
|
||||
static int current_isfile;
|
||||
|
||||
static cpumap_t online_cpumap;
|
||||
static cpumap_t regs_valid;
|
||||
@@ -298,8 +271,8 @@ map_domain_va(
|
||||
return (void *)(((unsigned long)page_virt[cpu]) | (va & BSD_PAGE_MASK));
|
||||
}
|
||||
|
||||
int
|
||||
xc_waitdomain(
|
||||
static int
|
||||
__xc_waitdomain(
|
||||
int xc_handle,
|
||||
int domain,
|
||||
int *status,
|
||||
@@ -368,8 +341,12 @@ xc_ptrace(
|
||||
{
|
||||
case PTRACE_PEEKTEXT:
|
||||
case PTRACE_PEEKDATA:
|
||||
guest_va = (unsigned long *)map_domain_va(
|
||||
xc_handle, cpu, addr, PROT_READ);
|
||||
if (current_isfile)
|
||||
guest_va = (unsigned long *)map_domain_va_core(current_domid,
|
||||
cpu, addr, ctxt);
|
||||
else
|
||||
guest_va = (unsigned long *)map_domain_va(xc_handle,
|
||||
cpu, addr, PROT_READ);
|
||||
if ( guest_va == NULL )
|
||||
goto out_error;
|
||||
retval = *guest_va;
|
||||
@@ -378,15 +355,19 @@ xc_ptrace(
|
||||
case PTRACE_POKETEXT:
|
||||
case PTRACE_POKEDATA:
|
||||
/* XXX assume that all CPUs have the same address space */
|
||||
guest_va = (unsigned long *)map_domain_va(
|
||||
xc_handle, cpu, addr, PROT_READ|PROT_WRITE);
|
||||
if (current_isfile)
|
||||
guest_va = (unsigned long *)map_domain_va_core(current_domid,
|
||||
cpu, addr, ctxt);
|
||||
else
|
||||
guest_va = (unsigned long *)map_domain_va(xc_handle,
|
||||
cpu, addr, PROT_READ|PROT_WRITE);
|
||||
if ( guest_va == NULL )
|
||||
goto out_error;
|
||||
*guest_va = (unsigned long)data;
|
||||
break;
|
||||
|
||||
case PTRACE_GETREGS:
|
||||
if (fetch_regs(xc_handle, cpu, NULL))
|
||||
if (!current_isfile && fetch_regs(xc_handle, cpu, NULL))
|
||||
goto out_error;
|
||||
SET_PT_REGS(pt, ctxt[cpu].user_regs);
|
||||
memcpy(data, &pt, sizeof(struct gdb_regs));
|
||||
@@ -394,12 +375,14 @@ xc_ptrace(
|
||||
|
||||
case PTRACE_GETFPREGS:
|
||||
case PTRACE_GETFPXREGS:
|
||||
if (fetch_regs(xc_handle, cpu, NULL))
|
||||
goto out_error;
|
||||
if (!current_isfile && fetch_regs(xc_handle, cpu, NULL))
|
||||
goto out_error;
|
||||
memcpy(data, &ctxt[cpu].fpu_ctxt, sizeof(ctxt[cpu].fpu_ctxt));
|
||||
break;
|
||||
|
||||
case PTRACE_SETREGS:
|
||||
if (!current_isfile)
|
||||
goto out_unspported; /* XXX not yet supported */
|
||||
SET_XC_REGS(((struct gdb_regs *)data), ctxt[cpu].user_regs);
|
||||
if ((retval = xc_vcpu_setcontext(xc_handle, current_domid, cpu,
|
||||
&ctxt[cpu])))
|
||||
@@ -407,6 +390,8 @@ xc_ptrace(
|
||||
break;
|
||||
|
||||
case PTRACE_SINGLESTEP:
|
||||
if (!current_isfile)
|
||||
goto out_unspported; /* XXX not yet supported */
|
||||
/* XXX we can still have problems if the user switches threads
|
||||
* during single-stepping - but that just seems retarded
|
||||
*/
|
||||
@@ -418,6 +403,8 @@ xc_ptrace(
|
||||
|
||||
case PTRACE_CONT:
|
||||
case PTRACE_DETACH:
|
||||
if (!current_isfile)
|
||||
goto out_unspported; /* XXX not yet supported */
|
||||
if ( request != PTRACE_SINGLESTEP )
|
||||
{
|
||||
FOREACH_CPU(cpumap, index) {
|
||||
@@ -450,6 +437,9 @@ xc_ptrace(
|
||||
|
||||
case PTRACE_ATTACH:
|
||||
current_domid = domid_tid;
|
||||
current_isfile = (int)edata;
|
||||
if (current_isfile)
|
||||
break;
|
||||
op.cmd = DOM0_GETDOMAININFO;
|
||||
op.u.getdomaininfo.domain = current_domid;
|
||||
retval = do_dom0_op(xc_handle, &op);
|
||||
@@ -477,12 +467,7 @@ xc_ptrace(
|
||||
case PTRACE_POKEUSER:
|
||||
case PTRACE_SYSCALL:
|
||||
case PTRACE_KILL:
|
||||
#ifdef DEBUG
|
||||
printf("unsupported xc_ptrace request %s\n", ptrace_names[request]);
|
||||
#endif
|
||||
/* XXX not yet supported */
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
goto out_unspported; /* XXX not yet supported */
|
||||
|
||||
case PTRACE_TRACEME:
|
||||
printf("PTRACE_TRACEME is an invalid request under Xen\n");
|
||||
@@ -496,6 +481,26 @@ xc_ptrace(
|
||||
out_error:
|
||||
errno = EINVAL;
|
||||
return retval;
|
||||
|
||||
out_unspported:
|
||||
#ifdef DEBUG
|
||||
printf("unsupported xc_ptrace request %s\n", ptrace_names[request]);
|
||||
#endif
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
|
||||
}
|
||||
|
||||
int
|
||||
xc_waitdomain(
|
||||
int xc_handle,
|
||||
int domain,
|
||||
int *status,
|
||||
int options)
|
||||
{
|
||||
if (current_isfile)
|
||||
return xc_waitdomain_core(xc_handle, domain, status, options, ctxt);
|
||||
return __xc_waitdomain(xc_handle, domain, status, options);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -6,8 +6,6 @@
|
||||
#include "xc_ptrace.h"
|
||||
#include <time.h>
|
||||
|
||||
#define VCPU 0 /* XXX */
|
||||
|
||||
/* XXX application state */
|
||||
|
||||
static long nr_pages = 0;
|
||||
@@ -15,7 +13,6 @@ static unsigned long *p2m_array = NULL;
|
||||
static unsigned long *m2p_array = NULL;
|
||||
static unsigned long pages_offset;
|
||||
static unsigned long cr3[MAX_VIRT_CPUS];
|
||||
static vcpu_guest_context_t ctxt[MAX_VIRT_CPUS];
|
||||
|
||||
/* --------------------- */
|
||||
|
||||
@@ -23,11 +20,13 @@ static unsigned long
|
||||
map_mtop_offset(unsigned long ma)
|
||||
{
|
||||
return pages_offset + (m2p_array[ma >> PAGE_SHIFT] << PAGE_SHIFT);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void *
|
||||
map_domain_va(unsigned long domfd, int cpu, void * guest_va)
|
||||
void *
|
||||
map_domain_va_core(unsigned long domfd, int cpu, void * guest_va,
|
||||
vcpu_guest_context_t *ctxt)
|
||||
{
|
||||
unsigned long pde, page;
|
||||
unsigned long va = (unsigned long)guest_va;
|
||||
@@ -99,7 +98,8 @@ xc_waitdomain_core(
|
||||
int xc_handle,
|
||||
int domfd,
|
||||
int *status,
|
||||
int options)
|
||||
int options,
|
||||
vcpu_guest_context_t *ctxt)
|
||||
{
|
||||
int nr_vcpus;
|
||||
int i;
|
||||
@@ -146,85 +146,6 @@ xc_waitdomain_core(
|
||||
return 0;
|
||||
}
|
||||
|
||||
long
|
||||
xc_ptrace_core(
|
||||
int xc_handle,
|
||||
enum __ptrace_request request,
|
||||
uint32_t domfd,
|
||||
long eaddr,
|
||||
long edata)
|
||||
{
|
||||
int status = 0;
|
||||
struct gdb_regs pt;
|
||||
long retval = 0;
|
||||
unsigned long *guest_va;
|
||||
int cpu = VCPU;
|
||||
void *addr = (char *)eaddr;
|
||||
void *data = (char *)edata;
|
||||
|
||||
#if 0
|
||||
printf("%20s %d, %p, %p \n", ptrace_names[request], domid, addr, data);
|
||||
#endif
|
||||
switch (request) {
|
||||
case PTRACE_PEEKTEXT:
|
||||
case PTRACE_PEEKDATA:
|
||||
if ((guest_va = (unsigned long *)map_domain_va(domfd, cpu, addr)) == NULL) {
|
||||
status = EFAULT;
|
||||
goto error_out;
|
||||
}
|
||||
|
||||
retval = *guest_va;
|
||||
break;
|
||||
case PTRACE_POKETEXT:
|
||||
case PTRACE_POKEDATA:
|
||||
if ((guest_va = (unsigned long *)map_domain_va(domfd, cpu, addr)) == NULL) {
|
||||
status = EFAULT;
|
||||
goto error_out;
|
||||
}
|
||||
*guest_va = (unsigned long)data;
|
||||
break;
|
||||
case PTRACE_GETREGS:
|
||||
case PTRACE_GETFPREGS:
|
||||
case PTRACE_GETFPXREGS:
|
||||
if (request == PTRACE_GETREGS) {
|
||||
SET_PT_REGS(pt, ctxt[cpu].user_regs);
|
||||
memcpy(data, &pt, sizeof(struct gdb_regs));
|
||||
} else if (request == PTRACE_GETFPREGS)
|
||||
memcpy(data, &ctxt[cpu].fpu_ctxt, sizeof(ctxt[cpu].fpu_ctxt));
|
||||
else /*if (request == PTRACE_GETFPXREGS)*/
|
||||
memcpy(data, &ctxt[cpu].fpu_ctxt, sizeof(ctxt[cpu].fpu_ctxt));
|
||||
break;
|
||||
case PTRACE_ATTACH:
|
||||
retval = 0;
|
||||
break;
|
||||
case PTRACE_SETREGS:
|
||||
case PTRACE_SINGLESTEP:
|
||||
case PTRACE_CONT:
|
||||
case PTRACE_DETACH:
|
||||
case PTRACE_SETFPREGS:
|
||||
case PTRACE_SETFPXREGS:
|
||||
case PTRACE_PEEKUSER:
|
||||
case PTRACE_POKEUSER:
|
||||
case PTRACE_SYSCALL:
|
||||
case PTRACE_KILL:
|
||||
#ifdef DEBUG
|
||||
printf("unsupported xc_ptrace request %s\n", ptrace_names[request]);
|
||||
#endif
|
||||
status = ENOSYS;
|
||||
break;
|
||||
case PTRACE_TRACEME:
|
||||
printf("PTRACE_TRACEME is an invalid request under Xen\n");
|
||||
status = EINVAL;
|
||||
}
|
||||
|
||||
if (status) {
|
||||
errno = status;
|
||||
retval = -1;
|
||||
}
|
||||
error_out:
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* mode: C
|
||||
|
||||
@@ -98,13 +98,19 @@ long xc_ptrace_core(
|
||||
enum __ptrace_request request,
|
||||
uint32_t domid,
|
||||
long addr,
|
||||
long data);
|
||||
|
||||
long data,
|
||||
vcpu_guest_context_t *ctxt);
|
||||
void * map_domain_va_core(
|
||||
unsigned long domfd,
|
||||
int cpu,
|
||||
void *guest_va,
|
||||
vcpu_guest_context_t *ctxt);
|
||||
int xc_waitdomain_core(
|
||||
int xc_handle,
|
||||
int domain,
|
||||
int *status,
|
||||
int options);
|
||||
int options,
|
||||
vcpu_guest_context_t *ctxt);
|
||||
|
||||
/*
|
||||
* DOMAIN MANAGEMENT FUNCTIONS
|
||||
|
||||