direct-io.hg

changeset 6941:ec01850d0ee9

Fix xc_ptrace (live debug, not coredump debug) for 32-bit pae.
Clean up interfaces and add simple documentation for using
the domU debug interfaces.

Signed-off-by: Keir Fraser <keir@xensource.com>
author kaf24@firebug.cl.cam.ac.uk
date Mon Sep 19 15:21:09 2005 +0000 (2005-09-19)
parents fc4375af5854
children 52d953dcef0e
files Config.mk tools/debugger/gdb/README tools/debugger/gdb/gdb-6.2.1-xen-sparse/gdb/gdbserver/linux-xen-low.c tools/libxc/Makefile tools/libxc/xc_ptrace.c tools/libxc/xc_ptrace_core.c tools/libxc/xenctrl.h
line diff
     1.1 --- a/Config.mk	Mon Sep 19 14:06:49 2005 +0000
     1.2 +++ b/Config.mk	Mon Sep 19 15:21:09 2005 +0000
     1.3 @@ -3,7 +3,7 @@
     1.4  # Currently supported architectures: x86_32, x86_64
     1.5  XEN_COMPILE_ARCH    ?= $(shell uname -m | sed -e s/i.86/x86_32/)
     1.6  XEN_TARGET_ARCH     ?= $(XEN_COMPILE_ARCH)
     1.7 -XEN_TARGET_X86_PAE  ?= n
     1.8 +XEN_TARGET_X86_PAE  ?= y
     1.9  
    1.10  # Tools to run on system hosting the build
    1.11  HOSTCC     = gcc
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/tools/debugger/gdb/README	Mon Sep 19 15:21:09 2005 +0000
     2.3 @@ -0,0 +1,18 @@
     2.4 +
     2.5 +DomU GDB server for 32-bit (PAE and non-PAE) systems
     2.6 +----------------------------------------------------
     2.7 +
     2.8 +To build:
     2.9 + 1. Run ./gdbbuild from within this directory.
    2.10 + 2. Copy ./gdb-6.2.1-linux-i386-xen/gdb/gdbserver/gdbserver-xen
    2.11 +    to your test machine.
    2.12 +
    2.13 +To debug a running domain:
    2.14 + 1. Use 'xm list' to discover its domain id ($domid). 
    2.15 + 2. Run 'gdbserver-xen 127.0.0.1:9999 --attach $domid'
    2.16 + 3. Run 'gdb /path/to/vmlinux-syms-2.6.xx-xenU'
    2.17 + 4. From within the gdb client session:
    2.18 +    # target remote 127.0.0.1:9999
    2.19 +    # bt
    2.20 +    # disass
    2.21 + 5. And so on...
     3.1 --- a/tools/debugger/gdb/gdb-6.2.1-xen-sparse/gdb/gdbserver/linux-xen-low.c	Mon Sep 19 14:06:49 2005 +0000
     3.2 +++ b/tools/debugger/gdb/gdb-6.2.1-xen-sparse/gdb/gdbserver/linux-xen-low.c	Mon Sep 19 15:21:09 2005 +0000
     3.3 @@ -37,9 +37,10 @@
     3.4  #include <errno.h>
     3.5  #include <xenctrl.h>
     3.6  #define TRACE_ENTER /* printf("enter %s\n", __FUNCTION__) */
     3.7 -long (*myptrace)(enum __ptrace_request, pid_t, long, long);
     3.8 -int (*myxcwait)(int domain, int *status, int options) ;
     3.9  
    3.10 +long (*myptrace)(int xc_handle, enum __ptrace_request, u32, long, long);
    3.11 +int (*myxcwait)(int xc_handle, int domain, int *status, int options) ;
    3.12 +static int xc_handle;
    3.13  
    3.14  #define DOMFLAGS_DYING     (1<<0) /* Domain is scheduled to die.             */
    3.15  #define DOMFLAGS_SHUTDOWN  (1<<2) /* The guest OS has shut down.             */
    3.16 @@ -47,11 +48,7 @@ int (*myxcwait)(int domain, int *status,
    3.17  #define DOMFLAGS_BLOCKED   (1<<4) /* Currently blocked pending an event.     */
    3.18  #define DOMFLAGS_RUNNING   (1<<5) /* Domain is currently running.            */
    3.19  
    3.20 -
    3.21 -
    3.22  struct inferior_list all_processes;
    3.23 -
    3.24 -
    3.25  static int current_domain;
    3.26  static int expect_signal = 0;
    3.27  static int signal_to_send = 0; 
    3.28 @@ -150,7 +147,7 @@ linux_attach (int domain)
    3.29  {
    3.30      struct process_info *new_process;
    3.31      current_domain = domain;
    3.32 -    if (myptrace (PTRACE_ATTACH, domain, 0, 0) != 0) {
    3.33 +    if (myptrace (xc_handle, PTRACE_ATTACH, domain, 0, 0) != 0) {
    3.34  	fprintf (stderr, "Cannot attach to domain %d: %s (%d)\n", domain,
    3.35  		 strerror (errno), errno);
    3.36  	fflush (stderr);
    3.37 @@ -173,8 +170,7 @@ linux_kill_one_process (struct inferior_
    3.38  {
    3.39    struct thread_info *thread = (struct thread_info *) entry;
    3.40    struct process_info *process = get_thread_process (thread);
    3.41 -  myptrace (PTRACE_KILL, pid_of (process), 0, 0);
    3.42 -
    3.43 +  myptrace (xc_handle, PTRACE_KILL, pid_of (process), 0, 0);
    3.44  }
    3.45  
    3.46  static void
    3.47 @@ -190,7 +186,7 @@ linux_detach_one_process (struct inferio
    3.48    struct thread_info *thread = (struct thread_info *) entry;
    3.49    struct process_info *process = get_thread_process (thread);
    3.50  
    3.51 -  myptrace (PTRACE_DETACH, pid_of (process), 0, 0);
    3.52 +  myptrace (xc_handle, PTRACE_DETACH, pid_of (process), 0, 0);
    3.53  }
    3.54  
    3.55  
    3.56 @@ -216,7 +212,7 @@ static unsigned char
    3.57  linux_wait (char *status)
    3.58  {
    3.59    int w;
    3.60 -  if (myxcwait(current_domain, &w, 0))
    3.61 +  if (myxcwait(xc_handle, current_domain, &w, 0))
    3.62        return -1;
    3.63    
    3.64    if (w & (DOMFLAGS_SHUTDOWN|DOMFLAGS_DYING)) {
    3.65 @@ -241,7 +237,7 @@ linux_resume (struct thread_resume *resu
    3.66    expect_signal = resume_info->sig;
    3.67    for_each_inferior(&all_threads, regcache_invalidate_one);
    3.68  
    3.69 -  myptrace (step ? PTRACE_SINGLESTEP : PTRACE_CONT, current_domain, 0, 0);
    3.70 +  myptrace (xc_handle, step ? PTRACE_SINGLESTEP : PTRACE_CONT, current_domain, 0, 0);
    3.71  
    3.72  }
    3.73  
    3.74 @@ -265,7 +261,7 @@ regsets_fetch_inferior_registers ()
    3.75  	}
    3.76  
    3.77        buf = malloc (regset->size);
    3.78 -      res = myptrace (regset->get_request, inferior_pid, 0, (PTRACE_XFER_TYPE)buf);
    3.79 +      res = myptrace (xc_handle, regset->get_request, inferior_pid, 0, (PTRACE_XFER_TYPE)buf);
    3.80        if (res < 0)
    3.81  	{
    3.82  	  if (errno == EIO)
    3.83 @@ -317,7 +313,7 @@ regsets_store_inferior_registers ()
    3.84  
    3.85        buf = malloc (regset->size);
    3.86        regset->fill_function (buf);
    3.87 -      res = myptrace (regset->set_request, inferior_pid, 0, (PTRACE_XFER_TYPE)buf);
    3.88 +      res = myptrace (xc_handle, regset->set_request, inferior_pid, 0, (PTRACE_XFER_TYPE)buf);
    3.89        if (res < 0)
    3.90  	{
    3.91  	  if (errno == EIO)
    3.92 @@ -395,7 +391,7 @@ linux_read_memory (CORE_ADDR memaddr, ch
    3.93    for (i = 0; i < count; i++, addr += sizeof (PTRACE_XFER_TYPE))
    3.94      {
    3.95        errno = 0;
    3.96 -      buffer[i] = myptrace (PTRACE_PEEKTEXT, inferior_pid, (PTRACE_ARG3_TYPE) addr, 0);
    3.97 +      buffer[i] = myptrace (xc_handle, PTRACE_PEEKTEXT, inferior_pid, (PTRACE_ARG3_TYPE) addr, 0);
    3.98        if (errno)
    3.99  	return errno;
   3.100      }
   3.101 @@ -428,13 +424,13 @@ linux_write_memory (CORE_ADDR memaddr, c
   3.102  
   3.103    /* Fill start and end extra bytes of buffer with existing memory data.  */
   3.104  
   3.105 -  buffer[0] = myptrace (PTRACE_PEEKTEXT, inferior_pid,
   3.106 +  buffer[0] = myptrace (xc_handle, PTRACE_PEEKTEXT, inferior_pid,
   3.107  		      (PTRACE_ARG3_TYPE) addr, 0);
   3.108  
   3.109    if (count > 1)
   3.110      {
   3.111        buffer[count - 1]
   3.112 -	= myptrace (PTRACE_PEEKTEXT, inferior_pid,
   3.113 +	= myptrace (xc_handle, PTRACE_PEEKTEXT, inferior_pid,
   3.114  		  (PTRACE_ARG3_TYPE) (addr + (count - 1)
   3.115  				      * sizeof (PTRACE_XFER_TYPE)),
   3.116  		  0);
   3.117 @@ -448,7 +444,7 @@ linux_write_memory (CORE_ADDR memaddr, c
   3.118    for (i = 0; i < count; i++, addr += sizeof (PTRACE_XFER_TYPE))
   3.119      {
   3.120        errno = 0;
   3.121 -      myptrace (PTRACE_POKETEXT, inferior_pid, (PTRACE_ARG3_TYPE) addr, buffer[i]);
   3.122 +      myptrace (xc_handle, PTRACE_POKETEXT, inferior_pid, (PTRACE_ARG3_TYPE) addr, buffer[i]);
   3.123        if (errno)
   3.124  	return errno;
   3.125      }
   3.126 @@ -539,7 +535,7 @@ linux_init_signals ()
   3.127  void
   3.128  initialize_low (void)
   3.129  {
   3.130 -
   3.131 +  xc_handle = xc_interface_open();
   3.132    set_target_ops (&linux_xen_target_ops);
   3.133    set_breakpoint_data (the_low_target.breakpoint,
   3.134  		       the_low_target.breakpoint_len);
     4.1 --- a/tools/libxc/Makefile	Mon Sep 19 14:06:49 2005 +0000
     4.2 +++ b/tools/libxc/Makefile	Mon Sep 19 15:21:09 2005 +0000
     4.3 @@ -30,8 +30,10 @@ BUILD_SRCS += xc_load_elf.c
     4.4  ifeq ($(XEN_TARGET_ARCH),ia64)
     4.5  BUILD_SRCS += xc_ia64_stubs.c
     4.6  else
     4.7 +ifeq ($(XEN_TARGET_ARCH),x86_32)
     4.8  SRCS       += xc_ptrace.c
     4.9  SRCS       += xc_ptrace_core.c
    4.10 +endif
    4.11  BUILD_SRCS += xc_load_aout9.c
    4.12  BUILD_SRCS += xc_linux_restore.c
    4.13  BUILD_SRCS += xc_linux_save.c
     5.1 --- a/tools/libxc/xc_ptrace.c	Mon Sep 19 14:06:49 2005 +0000
     5.2 +++ b/tools/libxc/xc_ptrace.c	Mon Sep 19 15:21:09 2005 +0000
     5.3 @@ -1,6 +1,7 @@
     5.4  #include <sys/ptrace.h>
     5.5  #include <sys/wait.h>
     5.6  #include "xc_private.h"
     5.7 +#include "xg_private.h"
     5.8  #include <time.h>
     5.9  
    5.10  #define X86_CR0_PE              0x00000001 /* Enable Protected Mode    (RW) */
    5.11 @@ -10,14 +11,6 @@
    5.12  #define PSL_T  0x00000100 /* trace enable bit */
    5.13  #define VCPU            0               /* XXX */
    5.14  
    5.15 -/*
    5.16 - * long  
    5.17 - * ptrace(enum __ptrace_request request, pid_t pid, void *addr, void *data);
    5.18 - */
    5.19 -
    5.20 -
    5.21 -int waitdomain(int domain, int *status, int options);
    5.22 -
    5.23  char * ptrace_names[] = {
    5.24      "PTRACE_TRACEME",
    5.25      "PTRACE_PEEKTEXT",
    5.26 @@ -122,8 +115,6 @@ struct gdb_regs {
    5.27  #define vtopti(va) (((va) >> PAGE_SHIFT) & 0x3ff)
    5.28  
    5.29  /* XXX application state */
    5.30 -
    5.31 -static int                      xc_handle;
    5.32  static long   nr_pages = 0;
    5.33  unsigned long   *page_array = NULL;
    5.34  static int                      regs_valid[MAX_VIRT_CPUS];
    5.35 @@ -133,14 +124,60 @@ static vcpu_guest_context_t ctxt[MAX_VIR
    5.36  static inline int paging_enabled(vcpu_guest_context_t *v)
    5.37  {
    5.38      unsigned long cr0 = v->ctrlreg[0];
    5.39 -
    5.40      return (cr0 & X86_CR0_PE) && (cr0 & X86_CR0_PG);
    5.41  }
    5.42  
    5.43  /* --------------------- */
    5.44  
    5.45  static void *
    5.46 -map_domain_va(unsigned long domid, int cpu, void * guest_va, int perm)
    5.47 +map_domain_va_pae(
    5.48 +    int xc_handle,
    5.49 +    unsigned long domid,
    5.50 +    int cpu,
    5.51 +    void *guest_va,
    5.52 +    int perm)
    5.53 +{
    5.54 +    unsigned long l2p, l1p, p, va = (unsigned long)guest_va;
    5.55 +    u64 *l3, *l2, *l1;
    5.56 +    static void *v;
    5.57 +
    5.58 +    FETCH_REGS(cpu);
    5.59 +
    5.60 +    l3 = xc_map_foreign_range(
    5.61 +        xc_handle, domid, PAGE_SIZE, PROT_READ, cr3[cpu] >> PAGE_SHIFT);
    5.62 +    if ( l3 == NULL )
    5.63 +        goto error_out;
    5.64 +
    5.65 +    l2p = l3[l3_table_offset_pae(va)] >> PAGE_SHIFT;
    5.66 +    l2 = xc_map_foreign_range(xc_handle, domid, PAGE_SIZE, PROT_READ, l2p);
    5.67 +    if ( l2 == NULL )
    5.68 +        goto error_out;
    5.69 +
    5.70 +    l1p = l2[l2_table_offset_pae(va)] >> PAGE_SHIFT;
    5.71 +    l1 = xc_map_foreign_range(xc_handle, domid, PAGE_SIZE, perm, l1p);
    5.72 +    if ( l1 == NULL )
    5.73 +        goto error_out;
    5.74 +
    5.75 +    p = l1[l1_table_offset_pae(va)] >> PAGE_SHIFT;
    5.76 +    if ( v != NULL )
    5.77 +        munmap(v, PAGE_SIZE);
    5.78 +    v = xc_map_foreign_range(xc_handle, domid, PAGE_SIZE, perm, p);
    5.79 +    if ( v == NULL )
    5.80 +        goto error_out;
    5.81 +
    5.82 +    return (void *)((unsigned long)v | (va & (PAGE_SIZE - 1)));
    5.83 +
    5.84 + error_out:
    5.85 +    return NULL;
    5.86 +}
    5.87 +
    5.88 +static void *
    5.89 +map_domain_va(
    5.90 +    int xc_handle,
    5.91 +    unsigned long domid,
    5.92 +    int cpu,
    5.93 +    void *guest_va,
    5.94 +    int perm)
    5.95  {
    5.96      unsigned long pde, page;
    5.97      unsigned long va = (unsigned long)guest_va;
    5.98 @@ -151,20 +188,35 @@ map_domain_va(unsigned long domid, int c
    5.99      static unsigned long  pde_phys[MAX_VIRT_CPUS];
   5.100      static unsigned long *pde_virt[MAX_VIRT_CPUS];
   5.101      static unsigned long  page_phys[MAX_VIRT_CPUS];
   5.102 -    static unsigned long *page_virt[MAX_VIRT_CPUS];
   5.103 -    
   5.104 +    static unsigned long *page_virt[MAX_VIRT_CPUS];    
   5.105      static int            prev_perm[MAX_VIRT_CPUS];
   5.106 +    static enum { MODE_UNKNOWN, MODE_32, MODE_PAE } mode;
   5.107  
   5.108 -    if (nr_pages != npgs) {
   5.109 -        if (nr_pages > 0)
   5.110 +    if ( mode == MODE_UNKNOWN )
   5.111 +    {
   5.112 +        xen_capabilities_info_t caps;
   5.113 +        (void)xc_version(xc_handle, XENVER_capabilities, caps);
   5.114 +        mode = MODE_32;
   5.115 +        if ( strstr(caps, "_x86_32p") )
   5.116 +            mode = MODE_PAE;
   5.117 +    }
   5.118 +
   5.119 +    if ( mode == MODE_PAE )
   5.120 +        return map_domain_va_pae(xc_handle, domid, cpu, guest_va, perm);
   5.121 +
   5.122 +    if ( nr_pages != npgs )
   5.123 +    {
   5.124 +        if ( nr_pages > 0 )
   5.125              free(page_array);
   5.126          nr_pages = npgs;
   5.127 -        if ((page_array = malloc(nr_pages * sizeof(unsigned long))) == NULL) {
   5.128 +        if ( (page_array = malloc(nr_pages * sizeof(unsigned long))) == NULL )
   5.129 +        {
   5.130              printf("Could not allocate memory\n");
   5.131              goto error_out;
   5.132          }
   5.133 -
   5.134 -        if (xc_get_pfn_list(xc_handle, domid, page_array, nr_pages) != nr_pages) {
   5.135 +        if ( xc_get_pfn_list(xc_handle, domid,
   5.136 +                             page_array, nr_pages) != nr_pages )
   5.137 +        {
   5.138              printf("Could not get the page frame list\n");
   5.139              goto error_out;
   5.140          }
   5.141 @@ -172,48 +224,52 @@ map_domain_va(unsigned long domid, int c
   5.142  
   5.143      FETCH_REGS(cpu);
   5.144  
   5.145 -    if (cr3[cpu] != cr3_phys[cpu]) 
   5.146 +    if ( cr3[cpu] != cr3_phys[cpu] )
   5.147      {
   5.148          cr3_phys[cpu] = cr3[cpu];
   5.149 -        if (cr3_virt[cpu])
   5.150 +        if ( cr3_virt[cpu] )
   5.151              munmap(cr3_virt[cpu], PAGE_SIZE);
   5.152 -        if ((cr3_virt[cpu] = xc_map_foreign_range(xc_handle, domid, PAGE_SIZE,
   5.153 -                                                  PROT_READ,
   5.154 -                                                  cr3_phys[cpu] >> PAGE_SHIFT)) == NULL)
   5.155 +        cr3_virt[cpu] = xc_map_foreign_range(
   5.156 +            xc_handle, domid, PAGE_SIZE, PROT_READ,
   5.157 +            cr3_phys[cpu] >> PAGE_SHIFT);
   5.158 +        if ( cr3_virt[cpu] == NULL )
   5.159              goto error_out;
   5.160 -    } 
   5.161 -    if ((pde = cr3_virt[cpu][vtopdi(va)]) == 0) /* logical address */
   5.162 +    }
   5.163 +    if ( (pde = cr3_virt[cpu][vtopdi(va)]) == 0 )
   5.164          goto error_out;
   5.165 -    if ((ctxt[cpu].flags & VGCF_VMX_GUEST) && paging_enabled(&ctxt[cpu]))
   5.166 +    if ( (ctxt[cpu].flags & VGCF_VMX_GUEST) && paging_enabled(&ctxt[cpu]) )
   5.167          pde = page_array[pde >> PAGE_SHIFT] << PAGE_SHIFT;
   5.168 -    if (pde != pde_phys[cpu]) 
   5.169 +    if ( pde != pde_phys[cpu] )
   5.170      {
   5.171          pde_phys[cpu] = pde;
   5.172 -        if (pde_virt[cpu])
   5.173 +        if ( pde_virt[cpu] )
   5.174              munmap(pde_virt[cpu], PAGE_SIZE);
   5.175 -        if ((pde_virt[cpu] = xc_map_foreign_range(xc_handle, domid, PAGE_SIZE,
   5.176 -                                                  PROT_READ,
   5.177 -                                                  pde_phys[cpu] >> PAGE_SHIFT)) == NULL)
   5.178 +        pde_virt[cpu] = xc_map_foreign_range(
   5.179 +            xc_handle, domid, PAGE_SIZE, PROT_READ,
   5.180 +            pde_phys[cpu] >> PAGE_SHIFT);
   5.181 +        if ( pde_virt[cpu] == NULL )
   5.182              goto error_out;
   5.183      }
   5.184 -    if ((page = pde_virt[cpu][vtopti(va)]) == 0) /* logical address */
   5.185 +    if ( (page = pde_virt[cpu][vtopti(va)]) == 0 )
   5.186          goto error_out;
   5.187 -    if (ctxt[cpu].flags & VGCF_VMX_GUEST && paging_enabled(&ctxt[cpu]))
   5.188 +    if ( (ctxt[cpu].flags & VGCF_VMX_GUEST) && paging_enabled(&ctxt[cpu]) )
   5.189          page = page_array[page >> PAGE_SHIFT] << PAGE_SHIFT;
   5.190 -    if (page != page_phys[cpu] || perm != prev_perm[cpu]) 
   5.191 +    if ( (page != page_phys[cpu]) || (perm != prev_perm[cpu]) )
   5.192      {
   5.193          page_phys[cpu] = page;
   5.194 -        if (page_virt[cpu])
   5.195 +        if ( page_virt[cpu] )
   5.196              munmap(page_virt[cpu], PAGE_SIZE);
   5.197 -        if ((page_virt[cpu] = xc_map_foreign_range(xc_handle, domid, PAGE_SIZE,
   5.198 -                                                   perm,
   5.199 -                                                   page_phys[cpu] >> PAGE_SHIFT)) == NULL) {
   5.200 -            printf("cr3 %lx pde %lx page %lx pti %lx\n", cr3[cpu], pde, page, vtopti(va));
   5.201 +        page_virt[cpu] = xc_map_foreign_range(
   5.202 +            xc_handle, domid, PAGE_SIZE, perm,
   5.203 +            page_phys[cpu] >> PAGE_SHIFT);
   5.204 +        if ( page_virt[cpu] == NULL )
   5.205 +        {
   5.206              page_phys[cpu] = 0;
   5.207              goto error_out;
   5.208          }
   5.209          prev_perm[cpu] = perm;
   5.210      } 
   5.211 +
   5.212      return (void *)(((unsigned long)page_virt[cpu]) | (va & BSD_PAGE_MASK));
   5.213  
   5.214   error_out:
   5.215 @@ -221,7 +277,11 @@ map_domain_va(unsigned long domid, int c
   5.216  }
   5.217  
   5.218  int 
   5.219 -xc_waitdomain(int domain, int *status, int options)
   5.220 +xc_waitdomain(
   5.221 +    int xc_handle,
   5.222 +    int domain,
   5.223 +    int *status,
   5.224 +    int options)
   5.225  {
   5.226      dom0_op_t op;
   5.227      int retval;
   5.228 @@ -229,38 +289,39 @@ xc_waitdomain(int domain, int *status, i
   5.229      ts.tv_sec = 0;
   5.230      ts.tv_nsec = 10*1000*1000;
   5.231  
   5.232 -    if (!xc_handle)
   5.233 -        if ((xc_handle = xc_interface_open()) < 0) 
   5.234 -        {
   5.235 -            printf("xc_interface_open failed\n");
   5.236 -            return -1;
   5.237 -        }
   5.238      op.cmd = DOM0_GETDOMAININFO;
   5.239      op.u.getdomaininfo.domain = domain;
   5.240 +
   5.241   retry:
   5.242 -
   5.243      retval = do_dom0_op(xc_handle, &op);
   5.244 -    if (retval || op.u.getdomaininfo.domain != domain) {
   5.245 +    if ( retval || (op.u.getdomaininfo.domain != domain) )
   5.246 +    {
   5.247          printf("getdomaininfo failed\n");
   5.248          goto done;
   5.249      }
   5.250      *status = op.u.getdomaininfo.flags;
   5.251      
   5.252 -    if (options & WNOHANG)
   5.253 +    if ( options & WNOHANG )
   5.254          goto done;
   5.255 - 
   5.256  
   5.257 -    if (!(op.u.getdomaininfo.flags & DOMFLAGS_PAUSED)) { 
   5.258 +    if ( !(op.u.getdomaininfo.flags & DOMFLAGS_PAUSED) )
   5.259 +    {
   5.260          nanosleep(&ts,NULL);
   5.261          goto retry;
   5.262      }
   5.263 +
   5.264   done:
   5.265      return retval;
   5.266  
   5.267  }
   5.268  
   5.269  long
   5.270 -xc_ptrace(enum __ptrace_request request, u32 domid, long eaddr, long edata)
   5.271 +xc_ptrace(
   5.272 +    int xc_handle,
   5.273 +    enum __ptrace_request request,
   5.274 +    u32 domid,
   5.275 +    long eaddr,
   5.276 +    long edata)
   5.277  {
   5.278      dom0_op_t       op;
   5.279      int             status = 0;
   5.280 @@ -273,44 +334,51 @@ xc_ptrace(enum __ptrace_request request,
   5.281  
   5.282      op.interface_version = DOM0_INTERFACE_VERSION;
   5.283      
   5.284 -    if (!xc_handle)
   5.285 -        if ((xc_handle = xc_interface_open()) < 0)
   5.286 -            return -1;
   5.287 -#if 0
   5.288 -    printf("%20s %d, %p, %p \n", ptrace_names[request], domid, addr, data);
   5.289 -#endif
   5.290 -    switch (request) { 
   5.291 +    switch ( request )
   5.292 +    { 
   5.293      case PTRACE_PEEKTEXT:
   5.294      case PTRACE_PEEKDATA:
   5.295 -        if ((guest_va = (unsigned long *)map_domain_va(domid, cpu, addr, PROT_READ)) == NULL) {
   5.296 +        guest_va = (unsigned long *)map_domain_va(
   5.297 +            xc_handle, domid, cpu, addr, PROT_READ);
   5.298 +        if ( guest_va == NULL )
   5.299 +        {
   5.300              status = EFAULT;
   5.301              goto error_out;
   5.302          }
   5.303 -
   5.304          retval = *guest_va;
   5.305          break;
   5.306 +
   5.307      case PTRACE_POKETEXT:
   5.308      case PTRACE_POKEDATA:
   5.309 -        if ((guest_va = (unsigned long *)map_domain_va(domid, cpu, addr, PROT_READ|PROT_WRITE)) == NULL) {
   5.310 +        guest_va = (unsigned long *)map_domain_va(
   5.311 +            xc_handle, domid, cpu, addr, PROT_READ|PROT_WRITE);
   5.312 +        if ( guest_va == NULL )
   5.313 +        {
   5.314              status = EFAULT;
   5.315              goto error_out;
   5.316          }
   5.317 -
   5.318          *guest_va = (unsigned long)data;
   5.319          break;
   5.320 +
   5.321      case PTRACE_GETREGS:
   5.322      case PTRACE_GETFPREGS:
   5.323      case PTRACE_GETFPXREGS:
   5.324          FETCH_REGS(cpu);
   5.325 -
   5.326 -        if (request == PTRACE_GETREGS) {
   5.327 +        if ( request == PTRACE_GETREGS )
   5.328 +        {
   5.329              SET_PT_REGS(pt, ctxt[cpu].user_regs); 
   5.330              memcpy(data, &pt, sizeof(struct gdb_regs));
   5.331 -        } else if (request == PTRACE_GETFPREGS)
   5.332 +        }
   5.333 +        else if (request == PTRACE_GETFPREGS)
   5.334 +        {
   5.335              memcpy(data, &ctxt[cpu].fpu_ctxt, sizeof(ctxt[cpu].fpu_ctxt));
   5.336 +        }
   5.337          else /*if (request == PTRACE_GETFPXREGS)*/
   5.338 +        {
   5.339              memcpy(data, &ctxt[cpu].fpu_ctxt, sizeof(ctxt[cpu].fpu_ctxt));
   5.340 +        }
   5.341          break;
   5.342 +
   5.343      case PTRACE_SETREGS:
   5.344          op.cmd = DOM0_SETDOMAININFO;
   5.345          SET_XC_REGS(((struct gdb_regs *)data), ctxt[VCPU].user_regs);
   5.346 @@ -321,17 +389,19 @@ xc_ptrace(enum __ptrace_request request,
   5.347          retval = do_dom0_op(xc_handle, &op);
   5.348          if (retval)
   5.349              goto error_out;
   5.350 +        break;
   5.351  
   5.352 -        break;
   5.353      case PTRACE_ATTACH:
   5.354          op.cmd = DOM0_GETDOMAININFO;
   5.355          op.u.getdomaininfo.domain = domid;
   5.356          retval = do_dom0_op(xc_handle, &op);
   5.357 -        if (retval || op.u.getdomaininfo.domain != domid) {
   5.358 +        if ( retval || (op.u.getdomaininfo.domain != domid) )
   5.359 +        {
   5.360              perror("dom0 op failed");
   5.361              goto error_out;
   5.362          }
   5.363 -        if (op.u.getdomaininfo.flags & DOMFLAGS_PAUSED) {
   5.364 +        if ( op.u.getdomaininfo.flags & DOMFLAGS_PAUSED )
   5.365 +        {
   5.366              printf("domain currently paused\n");
   5.367              goto error_out;
   5.368          }
   5.369 @@ -340,6 +410,7 @@ xc_ptrace(enum __ptrace_request request,
   5.370          op.u.pausedomain.domain = domid;
   5.371          retval = do_dom0_op(xc_handle, &op);
   5.372          break;
   5.373 +
   5.374      case PTRACE_SINGLESTEP:
   5.375          ctxt[VCPU].user_regs.eflags |= PSL_T;
   5.376          op.cmd = DOM0_SETDOMAININFO;
   5.377 @@ -347,24 +418,29 @@ xc_ptrace(enum __ptrace_request request,
   5.378          op.u.setdomaininfo.vcpu = 0;
   5.379          op.u.setdomaininfo.ctxt = &ctxt[cpu];
   5.380          retval = do_dom0_op(xc_handle, &op); 
   5.381 -        if (retval) {
   5.382 +        if ( retval )
   5.383 +        {
   5.384              perror("dom0 op failed");
   5.385              goto error_out;
   5.386          }
   5.387          /* FALLTHROUGH */
   5.388 +
   5.389      case PTRACE_CONT:
   5.390      case PTRACE_DETACH:
   5.391 -        if (request != PTRACE_SINGLESTEP) {
   5.392 +        if ( request != PTRACE_SINGLESTEP )
   5.393 +        {
   5.394              FETCH_REGS(cpu);
   5.395              /* Clear trace flag */
   5.396 -            if (ctxt[cpu].user_regs.eflags & PSL_T) {
   5.397 +            if ( ctxt[cpu].user_regs.eflags & PSL_T )
   5.398 +            {
   5.399                  ctxt[cpu].user_regs.eflags &= ~PSL_T;
   5.400                  op.cmd = DOM0_SETDOMAININFO;
   5.401                  op.u.setdomaininfo.domain = domid;
   5.402                  op.u.setdomaininfo.vcpu = cpu;
   5.403                  op.u.setdomaininfo.ctxt = &ctxt[cpu];
   5.404                  retval = do_dom0_op(xc_handle, &op); 
   5.405 -                if (retval) {
   5.406 +                if ( retval )
   5.407 +                {
   5.408                      perror("dom0 op failed");
   5.409                      goto error_out;
   5.410                  }
   5.411 @@ -375,6 +451,7 @@ xc_ptrace(enum __ptrace_request request,
   5.412          op.u.unpausedomain.domain = domid > 0 ? domid : -domid;
   5.413          retval = do_dom0_op(xc_handle, &op);
   5.414          break;
   5.415 +
   5.416      case PTRACE_SETFPREGS:
   5.417      case PTRACE_SETFPXREGS:
   5.418      case PTRACE_PEEKUSER:
   5.419 @@ -387,15 +464,18 @@ xc_ptrace(enum __ptrace_request request,
   5.420          /* XXX not yet supported */
   5.421          status = ENOSYS;
   5.422          break;
   5.423 +
   5.424      case PTRACE_TRACEME:
   5.425          printf("PTRACE_TRACEME is an invalid request under Xen\n");
   5.426          status = EINVAL;
   5.427      }
   5.428      
   5.429 -    if (status) {
   5.430 +    if ( status )
   5.431 +    {
   5.432          errno = status;
   5.433          retval = -1;
   5.434      }
   5.435 +
   5.436   error_out:
   5.437      return retval;
   5.438  }
     6.1 --- a/tools/libxc/xc_ptrace_core.c	Mon Sep 19 14:06:49 2005 +0000
     6.2 +++ b/tools/libxc/xc_ptrace_core.c	Mon Sep 19 15:21:09 2005 +0000
     6.3 @@ -166,7 +166,11 @@ map_domain_va(unsigned long domfd, int c
     6.4  }
     6.5  
     6.6  int 
     6.7 -xc_waitdomain_core(int domfd, int *status, int options)
     6.8 +xc_waitdomain_core(
     6.9 +    int xc_handle,
    6.10 +    int domfd,
    6.11 +    int *status,
    6.12 +    int options)
    6.13  {
    6.14      int retval = -1;
    6.15      int nr_vcpus;
    6.16 @@ -215,7 +219,12 @@ xc_waitdomain_core(int domfd, int *statu
    6.17  }
    6.18  
    6.19  long
    6.20 -xc_ptrace_core(enum __ptrace_request request, u32 domfd, long eaddr, long edata)
    6.21 +xc_ptrace_core(
    6.22 +    int xc_handle,
    6.23 +    enum __ptrace_request request,
    6.24 +    u32 domfd,
    6.25 +    long eaddr,
    6.26 +    long edata)
    6.27  {
    6.28      int             status = 0;
    6.29      struct gdb_regs pt;
     7.1 --- a/tools/libxc/xenctrl.h	Mon Sep 19 14:06:49 2005 +0000
     7.2 +++ b/tools/libxc/xenctrl.h	Mon Sep 19 15:21:09 2005 +0000
     7.3 @@ -101,23 +101,31 @@ typedef struct xc_core_header {
     7.4  } xc_core_header_t;
     7.5  
     7.6  
     7.7 -long xc_ptrace(enum __ptrace_request request, 
     7.8 -               u32  domid,
     7.9 -               long addr, 
    7.10 -               long data);
    7.11 +long xc_ptrace(
    7.12 +    int xc_handle,
    7.13 +    enum __ptrace_request request, 
    7.14 +    u32  domid,
    7.15 +    long addr, 
    7.16 +    long data);
    7.17  
    7.18 -long xc_ptrace_core(enum __ptrace_request request, 
    7.19 -                    u32 domid, 
    7.20 -                    long addr, 
    7.21 -                    long data);
    7.22 +long xc_ptrace_core(
    7.23 +    int xc_handle,
    7.24 +    enum __ptrace_request request, 
    7.25 +    u32 domid, 
    7.26 +    long addr, 
    7.27 +    long data);
    7.28  
    7.29 -int xc_waitdomain(int domain, 
    7.30 -                  int *status, 
    7.31 -                  int options);
    7.32 +int xc_waitdomain(
    7.33 +    int xc_handle,
    7.34 +    int domain, 
    7.35 +    int *status, 
    7.36 +    int options);
    7.37  
    7.38 -int xc_waitdomain_core(int domain, 
    7.39 -                       int *status, 
    7.40 -                       int options);
    7.41 +int xc_waitdomain_core(
    7.42 +    int xc_handle,
    7.43 +    int domain, 
    7.44 +    int *status, 
    7.45 +    int options);
    7.46  
    7.47  /*
    7.48   * DOMAIN MANAGEMENT FUNCTIONS