ia64/xen-unstable

changeset 1386:32674cd6340a

bitkeeper revision 1.891.1.22 (40a4dfcfIxTtNtL9Vh3WBZEZINWxqg)

vertical debugging: pdb can break when entering / exiting a system call from user space
author ach61@labyrinth.cl.cam.ac.uk
date Fri May 14 15:03:43 2004 +0000 (2004-05-14)
parents a693ae3c0f60
children bf3fc7825f74
files .rootkeys xen/arch/i386/pdb-linux.c xen/arch/i386/pdb-stub.c xen/arch/i386/traps.c xen/include/asm-i386/pdb.h xen/include/asm-i386/processor.h
line diff
     1.1 --- a/.rootkeys	Fri May 14 14:21:38 2004 +0000
     1.2 +++ b/.rootkeys	Fri May 14 15:03:43 2004 +0000
     1.3 @@ -144,6 +144,7 @@ 3ddb79bdeJ7_86z03yTAPIeeywOg3Q xen/arch/
     1.4  3ddb79bdIKgipvGoqExEQ7jawfVowA xen/arch/i386/pci-i386.h
     1.5  3ddb79bdHe6_Uij4-glW91vInNtBYQ xen/arch/i386/pci-irq.c
     1.6  3ddb79bcZ_2FxINljqNSkqa17ISyJw xen/arch/i386/pci-pc.c
     1.7 +40a4dfced2dnSzbKgJFlD3chKHexjQ xen/arch/i386/pdb-linux.c
     1.8  4022a73czgX7d-2zfF_cb33oVemApQ xen/arch/i386/pdb-stub.c
     1.9  3ddb79bc1_2bAt67x9MFCP4AZrQnvQ xen/arch/i386/process.c
    1.10  3ddb79bc7KxGCEJsgBnkDX7XjD_ZEQ xen/arch/i386/rwlock.c
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/xen/arch/i386/pdb-linux.c	Fri May 14 15:03:43 2004 +0000
     2.3 @@ -0,0 +1,100 @@
     2.4 +
     2.5 +/*
     2.6 + * pervasive debugger
     2.7 + * www.cl.cam.ac.uk/netos/pdb
     2.8 + *
     2.9 + * alex ho
    2.10 + * 2004
    2.11 + * university of cambridge computer laboratory
    2.12 + *
    2.13 + * linux & i386 dependent code. bleech.
    2.14 + */
    2.15 +
    2.16 +#include <asm/pdb.h>
    2.17 +
    2.18 +/* offset to the first instruction in the linux system call code
    2.19 +   where we can safely set a breakpoint */
    2.20 +unsigned int pdb_linux_syscall_enter_bkpt_offset = 20;
    2.21 +
    2.22 +/* offset to eflags saved on the stack after an int 80 */
    2.23 +unsigned int pdb_linux_syscall_eflags_offset     = 48;
    2.24 +
    2.25 +/* offset to the instruction pointer saved on the stack after an int 80 */
    2.26 +unsigned int pdb_linux_syscall_eip_offset        = 40;
    2.27 +
    2.28 +unsigned char
    2.29 +pdb_linux_set_bkpt (unsigned long addr)
    2.30 +{
    2.31 +    unsigned char old_instruction = *(unsigned char *)addr;
    2.32 +    *(unsigned char *)addr = 0xcc;
    2.33 +    return old_instruction;
    2.34 +}
    2.35 +
    2.36 +void
    2.37 +pdb_linux_clr_bkpt (unsigned long addr, unsigned char value)
    2.38 +{
    2.39 +    *(unsigned char *)addr = value;
    2.40 +}
    2.41 +
    2.42 +void
    2.43 +pdb_linux_syscall_enter_bkpt (struct pt_regs *regs, long error_code,
    2.44 +			      trap_info_t *ti)
    2.45 +{
    2.46 +    /* set at breakpoint at the beginning of the 
    2.47 +       system call in the target domain */
    2.48 + 
    2.49 +    pdb_system_call_enter_instr = pdb_linux_set_bkpt(ti->address +
    2.50 +				    pdb_linux_syscall_enter_bkpt_offset);
    2.51 +    pdb_system_call = 1;
    2.52 +}
    2.53 +
    2.54 +void
    2.55 +pdb_linux_syscall_exit_bkpt (struct pt_regs *regs, struct pdb_context *pdb_ctx)
    2.56 +{
    2.57 +    /*
    2.58 +      we've hit an int 0x80 in a user's program, jumped into xen
    2.59 +      (traps.c::do_general_protection()) which re-wrote the next
    2.60 +      instruction in the os kernel to 0xcc, and then hit that 
    2.61 +      exception.
    2.62 +
    2.63 +      we need to re-write the return instruction in the user's
    2.64 +      program so that we know when we have finished the system call
    2.65 +      and are back in the user's program.
    2.66 +
    2.67 +      at this point our stack should look something like this:
    2.68 +
    2.69 +      esp      = 0x80a59f0
    2.70 +      esp + 4  = 0x0
    2.71 +      esp + 8  = 0x80485a0
    2.72 +      esp + 12 = 0x2d
    2.73 +      esp + 16 = 0x80485f4
    2.74 +      esp + 20 = 0xbffffa48
    2.75 +      esp + 24 = 0xd
    2.76 +      esp + 28 = 0xc00a0833
    2.77 +      esp + 32 = 0x833
    2.78 +      esp + 36 = 0xd
    2.79 +      esp + 40 = 0x804dcdd     saved eip
    2.80 +      esp + 44 = 0x82b         saved cs
    2.81 +      esp + 48 = 0x213392      saved eflags
    2.82 +      esp + 52 = 0xbffffa2c    saved esp
    2.83 +      esp + 56 = 0x833         saved ss
    2.84 +      esp + 60 = 0x1000000
    2.85 +    */
    2.86 +
    2.87 +    /* restore the entry instruction for the system call */
    2.88 +    pdb_linux_clr_bkpt(regs->eip - 1, pdb_system_call_enter_instr);
    2.89 +
    2.90 +    /* save the address of eflags that was saved on the stack */
    2.91 +    pdb_system_call_eflags_addr = (regs->esp +
    2.92 +				   pdb_linux_syscall_eflags_offset);
    2.93 + 
    2.94 +    /* muck with the return instruction so that we trap back into the
    2.95 +       debugger when re-entering user space */
    2.96 +    pdb_system_call_next_addr = *(unsigned long *)(regs->esp + 
    2.97 +						 pdb_linux_syscall_eip_offset);
    2.98 +    pdb_linux_get_values (&pdb_system_call_leave_instr, 1, 
    2.99 +			  pdb_system_call_next_addr,
   2.100 +			  pdb_ctx->process, pdb_ctx->ptbr);
   2.101 +    pdb_linux_set_values ("cc", 1, pdb_system_call_next_addr,
   2.102 +			  pdb_ctx->process, pdb_ctx->ptbr);
   2.103 +}
     3.1 --- a/xen/arch/i386/pdb-stub.c	Fri May 14 14:21:38 2004 +0000
     3.2 +++ b/xen/arch/i386/pdb-stub.c	Fri May 14 15:03:43 2004 +0000
     3.3 @@ -47,26 +47,13 @@ static int  pdb_in_buffer_ptr;
     3.4  static unsigned char  pdb_in_checksum;
     3.5  static unsigned char  pdb_xmit_checksum;
     3.6  
     3.7 -/* function pointers in the near future... */
     3.8 -unsigned long pdb_linux_pid_ptbr (unsigned long cr3, int pid);
     3.9 -void pdb_linux_get_values(char *buffer, int length, unsigned long address,
    3.10 -			  int pid, unsigned long cr3);
    3.11 -void pdb_linux_set_values(char *buffer, int length, unsigned long address,
    3.12 -			  int pid, unsigned long cr3);
    3.13 -
    3.14 -struct pdb_context
    3.15 -{
    3.16 -    int valid;
    3.17 -    int domain;
    3.18 -    int process;
    3.19 -    unsigned long ptbr;                   /* cached page table base register */
    3.20 -};
    3.21  struct pdb_context pdb_ctx;
    3.22 -
    3.23  int pdb_continue_thread = 0;
    3.24  int pdb_general_thread = 0;
    3.25  
    3.26  void pdb_put_packet (unsigned char *buffer, int ack);
    3.27 +void pdb_bkpt_check (u_char *buffer, int length,
    3.28 +		     unsigned long cr3, unsigned long addr);
    3.29  
    3.30  int pdb_initialized = 0;
    3.31  int pdb_page_fault_possible = 0;
    3.32 @@ -75,6 +62,12 @@ int pdb_page_fault = 0;
    3.33  static int pdb_serhnd = -1;
    3.34  static int pdb_stepping = 0;
    3.35  
    3.36 +int pdb_system_call = 0;
    3.37 +unsigned char pdb_system_call_enter_instr = 0;       /* original enter instr */
    3.38 +unsigned char pdb_system_call_leave_instr = 0;        /* original next instr */
    3.39 +unsigned long pdb_system_call_next_addr = 0;         /* instr after int 0x80 */
    3.40 +unsigned long pdb_system_call_eflags_addr = 0;      /* saved eflags on stack */
    3.41 +
    3.42  static inline void pdb_put_char(unsigned char c)
    3.43  {
    3.44      serial_putc(pdb_serhnd, c);
    3.45 @@ -406,15 +399,49 @@ pdb_process_command (char *ptr, struct p
    3.46          break;
    3.47      case 'S':                                            /* step with signal */
    3.48      case 's':                                                        /* step */
    3.49 +    {
    3.50 +        if ( pdb_system_call_eflags_addr != 0 )
    3.51 +	{
    3.52 +	    unsigned long eflags;
    3.53 +	    char eflags_buf[sizeof(eflags)*2];       /* STUPID STUPID STUPID */
    3.54 +
    3.55 +	    pdb_linux_get_values((u_char*)&eflags, sizeof(eflags), 
    3.56 +				 pdb_system_call_eflags_addr, 
    3.57 +				 pdb_ctx.process, pdb_ctx.ptbr);
    3.58 +	    eflags |= X86_EFLAGS_TF;
    3.59 +	    mem2hex ((u_char *)&eflags, eflags_buf, sizeof(eflags)); 
    3.60 +	    pdb_linux_set_values(eflags_buf, sizeof(eflags),
    3.61 +				 pdb_system_call_eflags_addr,
    3.62 +				 pdb_ctx.process, pdb_ctx.ptbr);
    3.63 +	}
    3.64 +
    3.65          regs->eflags |= X86_EFLAGS_TF;
    3.66          pdb_stepping = 1;
    3.67          return 1;                                        
    3.68          /* not reached */
    3.69 +    }
    3.70      case 'C':                                        /* continue with signal */
    3.71      case 'c':                                                    /* continue */
    3.72 +    {
    3.73 +        if ( pdb_system_call_eflags_addr != 0 )
    3.74 +	{
    3.75 +	    unsigned long eflags;
    3.76 +	    char eflags_buf[sizeof(eflags)*2];       /* STUPID STUPID STUPID */
    3.77 +
    3.78 +	    pdb_linux_get_values((u_char*)&eflags, sizeof(eflags), 
    3.79 +				 pdb_system_call_eflags_addr, 
    3.80 +				 pdb_ctx.process, pdb_ctx.ptbr);
    3.81 +	    eflags &= ~X86_EFLAGS_TF;
    3.82 +	    mem2hex ((u_char *)&eflags, eflags_buf, sizeof(eflags)); 
    3.83 +	    pdb_linux_set_values(eflags_buf, sizeof(eflags),
    3.84 +				 pdb_system_call_eflags_addr,
    3.85 +				 pdb_ctx.process, pdb_ctx.ptbr);
    3.86 +	}
    3.87 +
    3.88          regs->eflags &= ~X86_EFLAGS_TF;
    3.89          return 1;                         /* jump out before replying to gdb */
    3.90          /* not reached */
    3.91 +    }
    3.92      case 'd':
    3.93          remote_debug = !(remote_debug);                 /* toggle debug flag */
    3.94          break;
    3.95 @@ -424,54 +451,11 @@ pdb_process_command (char *ptr, struct p
    3.96      case 'g':                       /* return the value of the CPU registers */
    3.97      {
    3.98          pdb_x86_to_gdb_regs (pdb_out_buffer, regs);
    3.99 -
   3.100 -	/*
   3.101 -	printk ("  reg: %s",   pdb_out_buffer);
   3.102 -	printk ("\n");
   3.103 -	printk ("  eax: 0x%08lx\n", regs->eax);
   3.104 -	printk ("  ecx: 0x%08lx\n", regs->ecx);
   3.105 -	printk ("  edx: 0x%08lx\n", regs->edx);
   3.106 -	printk ("  ebx: 0x%08lx\n", regs->ebx);
   3.107 -	printk ("  esp: 0x%08lx\n", regs->esp);
   3.108 -	printk ("  ebp: 0x%08lx\n", regs->ebp);
   3.109 -	printk ("  esi: 0x%08lx\n", regs->esi);
   3.110 -	printk ("  edi: 0x%08lx\n", regs->edi);
   3.111 -	printk ("  eip: 0x%08lx\n", regs->eip);
   3.112 -	printk ("  efl: 0x%08lx\n", regs->eflags);
   3.113 -	printk ("  xcs: 0x%08x\n",  regs->xcs);
   3.114 -	printk ("  xss: 0x%08x\n",  regs->xss);
   3.115 -	printk ("  xds: 0x%08x\n",  regs->xds);
   3.116 -	printk ("  xes: 0x%08x\n",  regs->xes);
   3.117 -	printk ("  xfs: 0x%08x\n",  regs->xfs);
   3.118 -	printk ("  xgs: 0x%08x\n",  regs->xgs);
   3.119 -	*/
   3.120 -
   3.121          break;
   3.122      }
   3.123      case 'G':              /* set the value of the CPU registers - return OK */
   3.124      {
   3.125          pdb_gdb_to_x86_regs (regs, ptr);
   3.126 -
   3.127 -	/*
   3.128 -	printk ("  ptr: %s \n\n",   ptr);
   3.129 -	printk ("  eax: 0x%08lx\n", regs->eax);
   3.130 -	printk ("  ecx: 0x%08lx\n", regs->ecx);
   3.131 -	printk ("  edx: 0x%08lx\n", regs->edx);
   3.132 -	printk ("  ebx: 0x%08lx\n", regs->ebx);
   3.133 -	printk ("  esp: 0x%08lx\n", regs->esp);
   3.134 -	printk ("  ebp: 0x%08lx\n", regs->ebp);
   3.135 -	printk ("  esi: 0x%08lx\n", regs->esi);
   3.136 -	printk ("  edi: 0x%08lx\n", regs->edi);
   3.137 -	printk ("  eip: 0x%08lx\n", regs->eip);
   3.138 -	printk ("  efl: 0x%08lx\n", regs->eflags);
   3.139 -	printk ("  xcs: 0x%08x\n",  regs->xcs);
   3.140 -	printk ("  xss: 0x%08x\n",  regs->xss);
   3.141 -	printk ("  xds: 0x%08x\n",  regs->xds);
   3.142 -	printk ("  xes: 0x%08x\n",  regs->xes);
   3.143 -	printk ("  xfs: 0x%08x\n",  regs->xfs);
   3.144 -	printk ("  xgs: 0x%08x\n",  regs->xgs);
   3.145 -	*/
   3.146 -
   3.147          break;
   3.148      }
   3.149      case 'H':
   3.150 @@ -572,17 +556,20 @@ pdb_process_command (char *ptr, struct p
   3.151  			if (addr >= PAGE_OFFSET)
   3.152  			{
   3.153  			    hex2mem (ptr, (char *)addr, length);
   3.154 +			    pdb_bkpt_check(ptr, length, pdb_ctx.ptbr, addr);
   3.155  			}
   3.156  			else if (pdb_ctx.process != -1)
   3.157  			{
   3.158  			    pdb_linux_set_values(ptr, length, addr,
   3.159  						 pdb_ctx.process, 
   3.160  						 pdb_ctx.ptbr);
   3.161 +			    pdb_bkpt_check(ptr, length, pdb_ctx.ptbr, addr);
   3.162  			}
   3.163  			else
   3.164  			{
   3.165  			    pdb_set_values (ptr, length,
   3.166  					    pdb_ctx.ptbr, addr);
   3.167 +			    pdb_bkpt_check(ptr, length, pdb_ctx.ptbr, addr);
   3.168  			}
   3.169  			pdb_page_fault_possible = 0;
   3.170                          if (pdb_page_fault)
   3.171 @@ -936,7 +923,6 @@ int pdb_set_values(u_char *buffer, int l
   3.172  		   unsigned long cr3, unsigned long addr)
   3.173  {
   3.174      int count = pdb_change_values(buffer, length, cr3, addr, __PDB_SET_VAL);
   3.175 -    pdb_bkpt_check(buffer, length, cr3, addr);
   3.176      return count;
   3.177  }
   3.178  
   3.179 @@ -1176,16 +1162,35 @@ int pdb_handle_exception(int exceptionVe
   3.180  
   3.181      __asm__ __volatile__ ("movl %%cr3,%0" : "=r" (cr3) : );
   3.182  
   3.183 +    /* If the exception is an int3 from user space then pdb is only
   3.184 +       interested if it re-wrote an instruction set the breakpoint.
   3.185 +       This occurs when leaving a system call from a domain.
   3.186 +    */
   3.187 +    if ( exceptionVector == 3 &&
   3.188 +	 (xen_regs->xcs & 3) == 3 && 
   3.189 +	 xen_regs->eip != pdb_system_call_next_addr + 1)
   3.190 +    {
   3.191 +        TRC(printf("pdb: user bkpt (0x%x) at 0x%x:0x%lx:0x%lx\n", 
   3.192 +		   exceptionVector, xen_regs->xcs & 3, cr3, xen_regs->eip));
   3.193 +	return 1;
   3.194 +    }
   3.195 +
   3.196      /*
   3.197 -     * If PDB didn't set the breakpoint, is not single stepping, and the user
   3.198 -     * didn't press the magic debug key, then we don't handle the exception.
   3.199 +     * If PDB didn't set the breakpoint, is not single stepping, 
   3.200 +     * is not entering a system call in a domain,
   3.201 +     * the user didn't press the magic debug key, 
   3.202 +     * then we don't handle the exception.
   3.203       */
   3.204      bkpt = pdb_bkpt_search(cr3, xen_regs->eip - 1);
   3.205      if ( (bkpt == NULL) &&
   3.206 -         !pdb_stepping && (exceptionVector != KEYPRESS_EXCEPTION) &&
   3.207 +         !pdb_stepping && 
   3.208 +	 !pdb_system_call &&
   3.209 +	 xen_regs->eip != pdb_system_call_next_addr + 1 &&
   3.210 +	 (exceptionVector != KEYPRESS_EXCEPTION) &&
   3.211  	 xen_regs->eip < 0xc0000000)                   /* xenolinux for now! */
   3.212      {
   3.213 -        TRC(printf("pdb: user bkpt at 0x%lx:0x%lx\n", cr3, xen_regs->eip));
   3.214 +        TRC(printf("pdb: user bkpt (0x%x) at 0x%lx:0x%lx\n", 
   3.215 +		   exceptionVector, cr3, xen_regs->eip));
   3.216  	return 1;
   3.217      }
   3.218  
   3.219 @@ -1199,12 +1204,54 @@ int pdb_handle_exception(int exceptionVe
   3.220          pdb_stepping = 0;
   3.221      }
   3.222  
   3.223 +    if ( pdb_system_call )
   3.224 +    {
   3.225 +	pdb_system_call = 0;
   3.226 +
   3.227 +	pdb_linux_syscall_exit_bkpt (xen_regs, &pdb_ctx);
   3.228 +
   3.229 +	/* we don't have a saved breakpoint so we need to rewind eip */
   3.230 +	xen_regs->eip--;
   3.231 +	
   3.232 +	/* if ther user doesn't care about breaking when entering a
   3.233 +	   system call then we'll just ignore the exception */
   3.234 +	if ( (pdb_ctx.system_call & 0x01) == 0 )
   3.235 +	{
   3.236 +	    return 0;
   3.237 +	}
   3.238 +    }
   3.239 +
   3.240      if ( exceptionVector == BREAKPT_EXCEPTION && bkpt != NULL)
   3.241      {
   3.242          /* Executed Int3: replace breakpoint byte with real program byte. */
   3.243          xen_regs->eip--;
   3.244      }
   3.245  
   3.246 +    /* returning to user space after a system call */
   3.247 +    if ( xen_regs->eip == pdb_system_call_next_addr + 1)
   3.248 +    {
   3.249 +        u_char instr[2];                      /* REALLY REALLY REALLY STUPID */
   3.250 +
   3.251 +	mem2hex (&pdb_system_call_leave_instr, instr, sizeof(instr)); 
   3.252 +
   3.253 +	pdb_linux_set_values (instr, 1, pdb_system_call_next_addr,
   3.254 +			      pdb_ctx.process, pdb_ctx.ptbr);
   3.255 +
   3.256 +	pdb_system_call_next_addr = 0;
   3.257 +	pdb_system_call_leave_instr = 0;
   3.258 +
   3.259 +	/* manually rewind eip */
   3.260 +	xen_regs->eip--;
   3.261 +
   3.262 +	/* if the user doesn't care about breaking when returning 
   3.263 +	   to user space after a system call then we'll just ignore 
   3.264 +	   the exception */
   3.265 +	if ( (pdb_ctx.system_call & 0x02) == 0 )
   3.266 +	{
   3.267 +	    return 0;
   3.268 +	}
   3.269 +    }
   3.270 +
   3.271      /* Generate a signal for GDB. */
   3.272      switch ( exceptionVector )
   3.273      {
   3.274 @@ -1267,6 +1314,7 @@ void initialize_pdb()
   3.275      pdb_ctx.valid = 1;
   3.276      pdb_ctx.domain = -1;
   3.277      pdb_ctx.process = -1;
   3.278 +    pdb_ctx.system_call = 0;
   3.279      pdb_ctx.ptbr = 0;
   3.280  
   3.281      printk("pdb: pervasive debugger (%s)   www.cl.cam.ac.uk/netos/pdb\n", 
     4.1 --- a/xen/arch/i386/traps.c	Fri May 14 14:21:38 2004 +0000
     4.2 +++ b/xen/arch/i386/traps.c	Fri May 14 15:03:43 2004 +0000
     4.3 @@ -258,10 +258,10 @@ asmlinkage void do_int3(struct pt_regs *
     4.4      struct guest_trap_bounce *gtb = guest_trap_bounce+smp_processor_id();
     4.5      trap_info_t *ti;
     4.6  
     4.7 +    if ( pdb_handle_exception(3, regs) == 0 )
     4.8 +        return;
     4.9      if ( (regs->xcs & 3) != 3 )
    4.10      {
    4.11 -        if ( pdb_handle_exception(3, regs) == 0 )
    4.12 -             return;
    4.13          if ( unlikely((regs->xcs & 3) == 0) )
    4.14          {
    4.15              show_registers(regs);
    4.16 @@ -436,6 +436,15 @@ asmlinkage void do_general_protection(st
    4.17          ti = current->thread.traps + (error_code>>3);
    4.18          if ( TI_GET_DPL(ti) >= (regs->xcs & 3) )
    4.19          {
    4.20 +	    unsigned long cr3;
    4.21 +	
    4.22 +	    __asm__ __volatile__ ("movl %%cr3,%0" : "=r" (cr3) : );
    4.23 +	    if (pdb_initialized && pdb_ctx.system_call != 0 &&
    4.24 +		cr3 == pdb_ctx.ptbr)
    4.25 +	    {
    4.26 +	        pdb_linux_syscall_enter_bkpt(regs, error_code, ti);
    4.27 +	    }
    4.28 +
    4.29              gtb->flags = GTBF_TRAP_NOCODE;
    4.30              regs->eip += 2;
    4.31              goto finish_propagation;
     5.1 --- a/xen/include/asm-i386/pdb.h	Fri May 14 14:21:38 2004 +0000
     5.2 +++ b/xen/include/asm-i386/pdb.h	Fri May 14 15:03:43 2004 +0000
     5.3 @@ -14,6 +14,7 @@
     5.4  
     5.5  #include <asm/ptrace.h>
     5.6  #include <xen/list.h>
     5.7 +#include <hypervisor-ifs/dom0_ops.h>
     5.8  #include <hypervisor-ifs/hypervisor-if.h>                   /* for domain id */
     5.9  
    5.10  extern int pdb_initialized;
    5.11 @@ -37,6 +38,17 @@ extern int pdb_handle_exception(int exce
    5.12  extern int pdb_serial_input(u_char c, struct pt_regs *regs);
    5.13  extern void pdb_do_debug(dom0_op_t *op);
    5.14  
    5.15 +/* PDB Context. */
    5.16 +struct pdb_context
    5.17 +{
    5.18 +    int valid;
    5.19 +    int domain;
    5.20 +    int process;
    5.21 +    int system_call;              /* 0x01 break on enter, 0x02 break on exit */
    5.22 +    unsigned long ptbr;
    5.23 +};
    5.24 +extern struct pdb_context pdb_ctx;
    5.25 +
    5.26  /* Breakpoints. */
    5.27  struct pdb_breakpoint
    5.28  {
    5.29 @@ -56,4 +68,21 @@ extern char *mem2hex (char *, char *, in
    5.30  extern char *hex2mem (char *, char *, int);
    5.31  extern int   hexToInt (char **ptr, int *intValue);
    5.32  
    5.33 +/* Temporary Linux specific definitions */
    5.34 +extern int pdb_system_call;
    5.35 +extern unsigned char pdb_system_call_enter_instr;    /* original enter instr */
    5.36 +extern unsigned char pdb_system_call_leave_instr;     /* original next instr */
    5.37 +extern unsigned long pdb_system_call_next_addr;      /* instr after int 0x80 */
    5.38 +extern unsigned long pdb_system_call_eflags_addr;   /* saved eflags on stack */
    5.39 +
    5.40 +unsigned long pdb_linux_pid_ptbr (unsigned long cr3, int pid);
    5.41 +void pdb_linux_get_values(char *buffer, int length, unsigned long address,
    5.42 +			  int pid, unsigned long cr3);
    5.43 +void pdb_linux_set_values(char *buffer, int length, unsigned long address,
    5.44 +			  int pid, unsigned long cr3);
    5.45 +void pdb_linux_syscall_enter_bkpt (struct pt_regs *regs, long error_code,
    5.46 +				   trap_info_t *ti);
    5.47 +void pdb_linux_syscall_exit_bkpt (struct pt_regs *regs, 
    5.48 +				  struct pdb_context *pdb_ctx);
    5.49 +
    5.50  #endif  /* __PDB_H__ */
     6.1 --- a/xen/include/asm-i386/processor.h	Fri May 14 14:21:38 2004 +0000
     6.2 +++ b/xen/include/asm-i386/processor.h	Fri May 14 15:03:43 2004 +0000
     6.3 @@ -12,6 +12,7 @@
     6.4  #include <asm/cpufeature.h>
     6.5  #include <asm/desc.h>
     6.6  #include <asm/flushtlb.h>
     6.7 +#include <asm/pdb.h>
     6.8  #include <xen/config.h>
     6.9  #include <xen/spinlock.h>
    6.10  #include <hypervisor-ifs/hypervisor-if.h>
    6.11 @@ -406,8 +407,9 @@ extern struct desc_struct *idt_tables[];
    6.12       0, 8))
    6.13  
    6.14  #define SET_FAST_TRAP(_p)   \
    6.15 -    (memcpy(idt_tables[smp_processor_id()] + (_p)->fast_trap_idx, \
    6.16 -     &((_p)->fast_trap_desc), 8))
    6.17 +    (pdb_initialized ? (void *) 0 : \
    6.18 +       (memcpy(idt_tables[smp_processor_id()] + (_p)->fast_trap_idx, \
    6.19 +	       &((_p)->fast_trap_desc), 8)))
    6.20  
    6.21  long set_fast_trap(struct task_struct *p, int idx);
    6.22