From: Horms <horms@verge.net.au>
To: Keir Fraser <Keir.Fraser@cl.cam.ac.uk>
Cc: xen-devel@lists.xensource.com
Subject: Re: [PATCH] gdbserver-xen: fix corefile access
Date: Mon, 6 Mar 2006 19:08:20 +0900 [thread overview]
Message-ID: <20060306100818.GA12969@verge.net.au> (raw)
In-Reply-To: <583a8afe9e9ca10df1d4d5d4fdfaeaef@cl.cam.ac.uk>
[-- Attachment #1: Type: text/plain, Size: 1233 bytes --]
On Fri, Mar 03, 2006 at 01:02:59PM +0000, Keir Fraser wrote:
>
> On 3 Mar 2006, at 11:15, Horms wrote:
>
> >I have made a first pass at this, passing isfile as the data argument
> >to xc_ptrace() ATTACH. Its a little rough, but I wanted to get it out
> >for feedback before I head off for the day.
> >
> >There are 4 patches attached, which need to be applied in order.
> >Please let me know if posting patches in this way is a problem.
> >And of course, please let me know of any and all objections
> >so that I can refactor (or explain) accordingly.
>
> Yeah, diffstat tells me that you probably have the right approach (more
> lines deleted than added). I'd prefer fewer but bigger patches. e.g.,
> merge the first three 'cleanup' patches into one.
Here is the second round of patches. Please apply them in order.
The current split is a cleanup patch, followed by the consolidation
patch. Localy I actually have the cleanup patch broken out into the
error handling changes and other changes - as per the split in the
changelog entry. Let me know if you want me to send the broken out
patches.
I've done a little bit of testing, and I can trace both a core
and a running domain. Testing and feedback welcome.
--
Horms
[-- Attachment #2: 35-libxc_cleanup.patch --]
[-- Type: text/plain, Size: 20273 bytes --]
# HG changeset patch
# User Horms <horms@verge.net.au>
# Node ID 76218624fb4ad5f2ce5831ec0dcee1f0e24d7f41
# Parent 64f11b0e2e7d0c53320c4dc6e983fcb144258c43
libxc: xc_ptrace cleanups
General Cleanups
* Use { after if consistently in xc_ptrace.c and xc_ptrace_core.c
(But not in xc_ptrace_core() which should be removed shortly)
* Remove duplicate code and centralise around xc_ptrace.h
* Avoid ifing values covered by case in xc_ptrace()
- PTRACE_GETREGS, PTRACE_GETFPREGS and PTRACE_GETFPXREGS are grouped into
a single case, and then with the exception of a call to FETCH_REGS(),
different code is executed based on ifing the values covered by the
case. The PTRACE_GETFPREGS and PTRACE_GETFPXREGS code is actually a
duplicate. This patch breaks the code out to two different cases.
Error Handling
* Eliminate FETCH_REGS macro as it forces several functions
to have an otherwise uneeded error_out label, mittigating
any code savins.
* Rework error handling in xc_ptrace().
- Remove FETCH_REGS as above
- Make sure that all dom0 errors are caught
- Make sure errno is always set on error
* Eliminate gotos in xc_ptrace_core.c that do nothing but return
Signed-Off-By: Horms <horms@verge.net.au>
diff -r 64f11b0e2e7d tools/libxc/xc_ptrace.c
--- a/tools/libxc/xc_ptrace.c Sat Mar 4 19:16:36 2006 +0100
+++ b/tools/libxc/xc_ptrace.c Mon Mar 6 14:42:37 2006 +0900
@@ -7,9 +7,35 @@
#include "xc_private.h"
#include "xg_private.h"
-#include <thread_db.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;
@@ -32,7 +58,8 @@ fetch_regs(int xc_handle, int cpu, int *
if (online)
*online = 0;
- if ( !(regs_valid & (1 << cpu)) ) {
+ if ( !(regs_valid & (1 << cpu)) )
+ {
retval = xc_vcpu_getcontext(xc_handle, current_domid,
cpu, &ctxt[cpu]);
if ( retval )
@@ -50,9 +77,6 @@ fetch_regs(int xc_handle, int cpu, int *
return retval;
}
-#define FETCH_REGS(cpu) if (fetch_regs(xc_handle, cpu, NULL)) goto error_out;
-
-
static struct thr_ev_handlers {
thr_ev_handler_t td_create;
thr_ev_handler_t td_death;
@@ -95,14 +119,12 @@ get_online_cpumap(int xc_handle, dom0_ge
*cpumap = 0;
for (i = 0; i <= d->max_vcpu_id; i++) {
if ((retval = fetch_regs(xc_handle, i, &online)))
- goto error_out;
+ return retval;
if (online)
*cpumap |= (1 << i);
}
return 0;
- error_out:
- return retval;
}
/*
@@ -118,7 +140,8 @@ online_vcpus_changed(cpumap_t cpumap)
int index;
while ( (index = ffsll(changed_cpumap)) ) {
- if ( cpumap & (1 << (index - 1)) ) {
+ if ( cpumap & (1 << (index - 1)) )
+ {
if (handlers.td_create) handlers.td_create(index - 1);
} else {
printf("thread death: %d\n", index - 1);
@@ -143,34 +166,32 @@ map_domain_va_pae(
uint64_t *l3, *l2, *l1;
static void *v;
- FETCH_REGS(cpu);
+ if (fetch_regs(xc_handle, cpu, NULL))
+ return NULL;
l3 = xc_map_foreign_range(
xc_handle, current_domid, PAGE_SIZE, PROT_READ, ctxt[cpu].ctrlreg[3] >> PAGE_SHIFT);
if ( l3 == NULL )
- goto error_out;
+ return NULL;
l2p = l3[l3_table_offset_pae(va)] >> PAGE_SHIFT;
l2 = xc_map_foreign_range(xc_handle, current_domid, PAGE_SIZE, PROT_READ, l2p);
if ( l2 == NULL )
- goto error_out;
+ return NULL;
l1p = l2[l2_table_offset_pae(va)] >> PAGE_SHIFT;
l1 = xc_map_foreign_range(xc_handle, current_domid, PAGE_SIZE, perm, l1p);
if ( l1 == NULL )
- goto error_out;
+ return NULL;
p = l1[l1_table_offset_pae(va)] >> PAGE_SHIFT;
if ( v != NULL )
munmap(v, PAGE_SIZE);
v = xc_map_foreign_range(xc_handle, current_domid, PAGE_SIZE, perm, p);
if ( v == NULL )
- goto error_out;
+ return NULL;
return (void *)((unsigned long)v | (va & (PAGE_SIZE - 1)));
-
- error_out:
- return NULL;
}
static void *
@@ -215,17 +236,18 @@ map_domain_va(
if ( (page_array = malloc(nr_pages * sizeof(unsigned long))) == NULL )
{
printf("Could not allocate memory\n");
- goto error_out;
+ return NULL;
}
if ( xc_get_pfn_list(xc_handle, current_domid,
page_array, nr_pages) != nr_pages )
{
printf("Could not get the page frame list\n");
- goto error_out;
- }
- }
-
- FETCH_REGS(cpu);
+ return NULL;
+ }
+ }
+
+ if (fetch_regs(xc_handle, cpu, NULL))
+ return NULL;
if ( ctxt[cpu].ctrlreg[3] != cr3_phys[cpu] )
{
@@ -236,10 +258,10 @@ map_domain_va(
xc_handle, current_domid, PAGE_SIZE, PROT_READ,
cr3_phys[cpu] >> PAGE_SHIFT);
if ( cr3_virt[cpu] == NULL )
- goto error_out;
+ return NULL;
}
if ( (pde = cr3_virt[cpu][vtopdi(va)]) == 0 )
- goto error_out;
+ return NULL;
if ( (ctxt[cpu].flags & VGCF_HVM_GUEST) && paging_enabled(&ctxt[cpu]) )
pde = page_array[pde >> PAGE_SHIFT] << PAGE_SHIFT;
if ( pde != pde_phys[cpu] )
@@ -251,10 +273,10 @@ map_domain_va(
xc_handle, current_domid, PAGE_SIZE, PROT_READ,
pde_phys[cpu] >> PAGE_SHIFT);
if ( pde_virt[cpu] == NULL )
- goto error_out;
+ return NULL;
}
if ( (page = pde_virt[cpu][vtopti(va)]) == 0 )
- goto error_out;
+ return NULL;
if ( (ctxt[cpu].flags & VGCF_HVM_GUEST) && paging_enabled(&ctxt[cpu]) )
page = page_array[page >> PAGE_SHIFT] << PAGE_SHIFT;
if ( (page != page_phys[cpu]) || (perm != prev_perm[cpu]) )
@@ -268,15 +290,12 @@ map_domain_va(
if ( page_virt[cpu] == NULL )
{
page_phys[cpu] = 0;
- goto error_out;
+ return NULL;
}
prev_perm[cpu] = perm;
}
return (void *)(((unsigned long)page_virt[cpu]) | (va & BSD_PAGE_MASK));
-
- error_out:
- return NULL;
}
int
@@ -335,7 +354,6 @@ xc_ptrace(
long edata)
{
DECLARE_DOM0_OP;
- int status = 0;
struct gdb_regs pt;
long retval = 0;
unsigned long *guest_va;
@@ -353,10 +371,7 @@ xc_ptrace(
guest_va = (unsigned long *)map_domain_va(
xc_handle, cpu, addr, PROT_READ);
if ( guest_va == NULL )
- {
- status = EFAULT;
- goto error_out;
- }
+ goto out_error;
retval = *guest_va;
break;
@@ -365,38 +380,30 @@ xc_ptrace(
/* 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 ( guest_va == NULL ) {
- status = EFAULT;
- goto error_out;
- }
+ if ( guest_va == NULL )
+ goto out_error;
*guest_va = (unsigned long)data;
break;
case PTRACE_GETREGS:
+ if (fetch_regs(xc_handle, cpu, NULL))
+ goto out_error;
+ SET_PT_REGS(pt, ctxt[cpu].user_regs);
+ memcpy(data, &pt, sizeof(struct gdb_regs));
+ break;
+
case PTRACE_GETFPREGS:
case PTRACE_GETFPXREGS:
-
- FETCH_REGS(cpu);
- 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));
- }
+ if (fetch_regs(xc_handle, cpu, NULL))
+ goto out_error;
+ memcpy(data, &ctxt[cpu].fpu_ctxt, sizeof(ctxt[cpu].fpu_ctxt));
break;
case PTRACE_SETREGS:
SET_XC_REGS(((struct gdb_regs *)data), ctxt[cpu].user_regs);
- retval = xc_vcpu_setcontext(xc_handle, current_domid, cpu, &ctxt[cpu]);
- if (retval)
- goto error_out;
+ if ((retval = xc_vcpu_setcontext(xc_handle, current_domid, cpu,
+ &ctxt[cpu])))
+ goto out_error_dom0;
break;
case PTRACE_SINGLESTEP:
@@ -404,12 +411,9 @@ xc_ptrace(
* during single-stepping - but that just seems retarded
*/
ctxt[cpu].user_regs.eflags |= PSL_T;
- retval = xc_vcpu_setcontext(xc_handle, current_domid, cpu, &ctxt[cpu]);
- if ( retval )
- {
- perror("dom0 op failed");
- goto error_out;
- }
+ if ((retval = xc_vcpu_setcontext(xc_handle, current_domid, cpu,
+ &ctxt[cpu])))
+ goto out_error_dom0;
/* FALLTHROUGH */
case PTRACE_CONT:
@@ -418,16 +422,15 @@ xc_ptrace(
{
FOREACH_CPU(cpumap, index) {
cpu = index - 1;
- FETCH_REGS(cpu);
+ if (fetch_regs(xc_handle, cpu, NULL))
+ goto out_error;
/* Clear trace flag */
- if ( ctxt[cpu].user_regs.eflags & PSL_T ) {
+ if ( ctxt[cpu].user_regs.eflags & PSL_T )
+ {
ctxt[cpu].user_regs.eflags &= ~PSL_T;
- retval = xc_vcpu_setcontext(xc_handle, current_domid,
- cpu, &ctxt[cpu]);
- if ( retval ) {
- perror("dom0 op failed");
- goto error_out;
- }
+ if ((retval = xc_vcpu_setcontext(xc_handle, current_domid,
+ cpu, &ctxt[cpu])))
+ goto out_error_dom0;
}
}
}
@@ -436,10 +439,13 @@ xc_ptrace(
op.cmd = DOM0_SETDEBUGGING;
op.u.setdebugging.domain = current_domid;
op.u.setdebugging.enable = 0;
- retval = do_dom0_op(xc_handle, &op);
+ if ((retval = do_dom0_op(xc_handle, &op)))
+ goto out_error_dom0;
}
regs_valid = 0;
- xc_domain_unpause(xc_handle, current_domid > 0 ? current_domid : -current_domid);
+ if ((retval = xc_domain_unpause(xc_handle, current_domid > 0 ?
+ current_domid : -current_domid)))
+ goto out_error_dom0;
break;
case PTRACE_ATTACH:
@@ -448,19 +454,16 @@ xc_ptrace(
op.u.getdomaininfo.domain = current_domid;
retval = do_dom0_op(xc_handle, &op);
if ( retval || (op.u.getdomaininfo.domain != current_domid) )
- {
- perror("dom0 op failed");
- goto error_out;
- }
+ goto out_error_dom0;
if ( op.u.getdomaininfo.flags & DOMFLAGS_PAUSED )
- {
printf("domain currently paused\n");
- } else
- retval = xc_domain_pause(xc_handle, current_domid);
+ else if ((retval = xc_domain_pause(xc_handle, current_domid)))
+ goto out_error_dom0;
op.cmd = DOM0_SETDEBUGGING;
op.u.setdebugging.domain = current_domid;
op.u.setdebugging.enable = 1;
- retval = do_dom0_op(xc_handle, &op);
+ if ((retval = do_dom0_op(xc_handle, &op)))
+ goto out_error_dom0;
if (get_online_cpumap(xc_handle, &op.u.getdomaininfo, &cpumap))
printf("get_online_cpumap failed\n");
@@ -478,21 +481,20 @@ xc_ptrace(
printf("unsupported xc_ptrace request %s\n", ptrace_names[request]);
#endif
/* XXX not yet supported */
- status = ENOSYS;
- break;
+ errno = ENOSYS;
+ return -1;
case PTRACE_TRACEME:
printf("PTRACE_TRACEME is an invalid request under Xen\n");
- status = EINVAL;
- }
-
- if ( status )
- {
- errno = status;
- retval = -1;
- }
-
- error_out:
+ goto out_error;
+ }
+
+ return retval;
+
+ out_error_dom0:
+ perror("dom0 op failed");
+ out_error:
+ errno = EINVAL;
return retval;
}
diff -r 64f11b0e2e7d tools/libxc/xc_ptrace.h
--- a/tools/libxc/xc_ptrace.h Sat Mar 4 19:16:36 2006 +0100
+++ b/tools/libxc/xc_ptrace.h Mon Mar 6 14:42:37 2006 +0900
@@ -1,5 +1,7 @@
#ifndef XC_PTRACE_
#define XC_PTRACE_
+
+#include <thread_db.h>
#ifdef XC_PTRACE_PRIVATE
#define X86_CR0_PE 0x00000001 /* Enable Protected Mode (RW) */
@@ -8,33 +10,7 @@
#define PDRSHIFT 22
#define PSL_T 0x00000100 /* trace enable bit */
-char * 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",
-};
+extern const char const * ptrace_names[];
struct gdb_regs {
long ebx; /* 0 */
diff -r 64f11b0e2e7d tools/libxc/xc_ptrace_core.c
--- a/tools/libxc/xc_ptrace_core.c Sat Mar 4 19:16:36 2006 +0100
+++ b/tools/libxc/xc_ptrace_core.c Mon Mar 6 14:42:37 2006 +0900
@@ -1,81 +1,12 @@
+#define XC_PTRACE_PRIVATE
+
#include <sys/ptrace.h>
#include <sys/wait.h>
#include "xc_private.h"
+#include "xc_ptrace.h"
#include <time.h>
-#define BSD_PAGE_MASK (PAGE_SIZE-1)
-#define PDRSHIFT 22
#define VCPU 0 /* XXX */
-
-/*
- * long
- * ptrace(enum __ptrace_request request, pid_t pid, void *addr, void *data);
- */
-
-struct gdb_regs {
- long ebx; /* 0 */
- long ecx; /* 4 */
- long edx; /* 8 */
- long esi; /* 12 */
- long edi; /* 16 */
- long ebp; /* 20 */
- long eax; /* 24 */
- int xds; /* 28 */
- int xes; /* 32 */
- int xfs; /* 36 */
- int xgs; /* 40 */
- long orig_eax; /* 44 */
- long eip; /* 48 */
- int xcs; /* 52 */
- long eflags; /* 56 */
- long esp; /* 60 */
- int xss; /* 64 */
-};
-
-#define printval(x) printf("%s = %lx\n", #x, (long)x);
-#define SET_PT_REGS(pt, xc) \
-{ \
- pt.ebx = xc.ebx; \
- pt.ecx = xc.ecx; \
- pt.edx = xc.edx; \
- pt.esi = xc.esi; \
- pt.edi = xc.edi; \
- pt.ebp = xc.ebp; \
- pt.eax = xc.eax; \
- pt.eip = xc.eip; \
- pt.xcs = xc.cs; \
- pt.eflags = xc.eflags; \
- pt.esp = xc.esp; \
- pt.xss = xc.ss; \
- pt.xes = xc.es; \
- pt.xds = xc.ds; \
- pt.xfs = xc.fs; \
- pt.xgs = xc.gs; \
-}
-
-#define SET_XC_REGS(pt, xc) \
-{ \
- xc.ebx = pt->ebx; \
- xc.ecx = pt->ecx; \
- xc.edx = pt->edx; \
- xc.esi = pt->esi; \
- xc.edi = pt->edi; \
- xc.ebp = pt->ebp; \
- xc.eax = pt->eax; \
- xc.eip = pt->eip; \
- xc.cs = pt->xcs; \
- xc.eflags = pt->eflags; \
- xc.esp = pt->esp; \
- xc.ss = pt->xss; \
- xc.es = pt->xes; \
- xc.ds = pt->xds; \
- xc.fs = pt->xfs; \
- xc.gs = pt->xgs; \
-}
-
-
-#define vtopdi(va) ((va) >> PDRSHIFT)
-#define vtopti(va) (((va) >> PAGE_SHIFT) & 0x3ff)
/* XXX application state */
@@ -120,12 +51,12 @@ map_domain_va(unsigned long domfd, int c
if (v == MAP_FAILED)
{
perror("mmap failed");
- goto error_out;
+ return NULL;
}
cr3_virt[cpu] = v;
}
if ((pde = cr3_virt[cpu][vtopdi(va)]) == 0) /* logical address */
- goto error_out;
+ return NULL;
if (ctxt[cpu].flags & VGCF_HVM_GUEST)
pde = p2m_array[pde >> PAGE_SHIFT] << PAGE_SHIFT;
if (pde != pde_phys[cpu])
@@ -137,11 +68,11 @@ map_domain_va(unsigned long domfd, int c
NULL, PAGE_SIZE, PROT_READ, MAP_PRIVATE, domfd,
map_mtop_offset(pde_phys[cpu]));
if (v == MAP_FAILED)
- goto error_out;
+ return NULL;
pde_virt[cpu] = v;
}
if ((page = pde_virt[cpu][vtopti(va)]) == 0) /* logical address */
- goto error_out;
+ return NULL;
if (ctxt[cpu].flags & VGCF_HVM_GUEST)
page = p2m_array[page >> PAGE_SHIFT] << PAGE_SHIFT;
if (page != page_phys[cpu])
@@ -152,17 +83,15 @@ map_domain_va(unsigned long domfd, int c
v = mmap(
NULL, PAGE_SIZE, PROT_READ, MAP_PRIVATE, domfd,
map_mtop_offset(page_phys[cpu]));
- if (v == MAP_FAILED) {
+ if (v == MAP_FAILED)
+ {
printf("cr3 %lx pde %lx page %lx pti %lx\n", cr3[cpu], pde, page, vtopti(va));
page_phys[cpu] = 0;
- goto error_out;
+ return NULL;
}
page_virt[cpu] = v;
}
return (void *)(((unsigned long)page_virt[cpu]) | (va & BSD_PAGE_MASK));
-
- error_out:
- return 0;
}
int
@@ -172,12 +101,12 @@ xc_waitdomain_core(
int *status,
int options)
{
- int retval = -1;
int nr_vcpus;
int i;
xc_core_header_t header;
- if (nr_pages == 0) {
+ if (nr_pages == 0)
+ {
if (read(domfd, &header, sizeof(header)) != sizeof(header))
return -1;
@@ -193,17 +122,19 @@ xc_waitdomain_core(
for (i = 0; i < nr_vcpus; i++) {
cr3[i] = ctxt[i].ctrlreg[3];
}
- if ((p2m_array = malloc(nr_pages * sizeof(unsigned long))) == NULL) {
+ if ((p2m_array = malloc(nr_pages * sizeof(unsigned long))) == NULL)
+ {
printf("Could not allocate p2m_array\n");
- goto error_out;
+ return -1;
}
if (read(domfd, p2m_array, sizeof(unsigned long)*nr_pages) !=
sizeof(unsigned long)*nr_pages)
return -1;
- if ((m2p_array = malloc((1<<20) * sizeof(unsigned long))) == NULL) {
+ if ((m2p_array = malloc((1<<20) * sizeof(unsigned long))) == NULL)
+ {
printf("Could not allocate m2p array\n");
- goto error_out;
+ return -1;
}
bzero(m2p_array, sizeof(unsigned long)* 1 << 20);
@@ -212,10 +143,7 @@ xc_waitdomain_core(
}
}
- retval = 0;
- error_out:
- return retval;
-
+ return 0;
}
long
[-- Attachment #3: 36-libxc_ptrace-consolidation.patch --]
[-- Type: text/plain, Size: 15852 bytes --]
# HG changeset patch
# User Horms <horms@verge.net.au>
# Node ID ea13f335ceb3f370170799c121ba85ebfb559bcd
# Parent 5d6005d3424d96dbe969a17ac9fb2505436a8018
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>
diff -r 4fac2aa541aa tools/debugger/gdb/gdb-6.2.1-xen-sparse/gdb/gdbserver/linux-xen-low.c
--- a/tools/debugger/gdb/gdb-6.2.1-xen-sparse/gdb/gdbserver/linux-xen-low.c Mon Mar 6 14:48:19 2006 +0900
+++ b/tools/debugger/gdb/gdb-6.2.1-xen-sparse/gdb/gdbserver/linux-xen-low.c Mon Mar 6 14:58:39 2006 +0900
@@ -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_
{
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 @@ linux_detach_one_process (struct inferio
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 @@ linux_wait (char *status)
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 *resu
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, ch
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, c
/* 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, c
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 ();
}
diff -r 4fac2aa541aa tools/libxc/xc_ptrace.c
--- a/tools/libxc/xc_ptrace.c Mon Mar 6 14:48:19 2006 +0900
+++ b/tools/libxc/xc_ptrace.c Mon Mar 6 14:58:39 2006 +0900
@@ -8,39 +8,12 @@
#include "xc_private.h"
#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);
}
/*
diff -r 4fac2aa541aa tools/libxc/xc_ptrace_core.c
--- a/tools/libxc/xc_ptrace_core.c Mon Mar 6 14:48:19 2006 +0900
+++ b/tools/libxc/xc_ptrace_core.c Mon Mar 6 14:58:39 2006 +0900
@@ -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 *m2p_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 @@ map_mtop_offset(unsigned long ma)
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
diff -r 4fac2aa541aa tools/libxc/xenctrl.h
--- a/tools/libxc/xenctrl.h Mon Mar 6 14:48:19 2006 +0900
+++ b/tools/libxc/xenctrl.h Mon Mar 6 14:58:39 2006 +0900
@@ -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
[-- Attachment #4: Type: text/plain, Size: 138 bytes --]
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xensource.com
http://lists.xensource.com/xen-devel
prev parent reply other threads:[~2006-03-06 10:08 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2006-03-02 8:28 [PATCH] gdbserver-xen: fix corefile access Horms
2006-03-02 10:45 ` Keir Fraser
2006-03-02 12:19 ` Horms
2006-03-02 13:24 ` Keir Fraser
2006-03-03 1:20 ` Horms
2006-03-03 1:28 ` Horms
2006-03-03 8:11 ` Keir Fraser
2006-03-03 11:15 ` Horms
2006-03-03 13:02 ` Keir Fraser
2006-03-06 10:08 ` Horms [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20060306100818.GA12969@verge.net.au \
--to=horms@verge.net.au \
--cc=Keir.Fraser@cl.cam.ac.uk \
--cc=xen-devel@lists.xensource.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.