ia64/xen-unstable

changeset 5312:861dee4a4782

bitkeeper revision 1.1665.1.3 (42a0c916S8M4GCtph6DmI_QigXvneA)

Merge arcadians.cl.cam.ac.uk:/auto/groups/xeno-xenod/BK/xeno.bk
into arcadians.cl.cam.ac.uk:/auto/anfs/nos1/ach61/debugger
author ach61@arcadians.cl.cam.ac.uk
date Fri Jun 03 21:18:14 2005 +0000 (2005-06-03)
parents 226484ec5fb0 d8ac19a4170e
children c59632e7ff3e
files .rootkeys BitKeeper/etc/logging_ok tools/libxc/Makefile tools/libxc/list.h tools/libxc/xc_debug.c tools/libxc/xc_debug.h tools/pdb/Domain.ml tools/pdb/Domain.mli tools/pdb/Intel.ml tools/pdb/Makefile tools/pdb/OCamlMakefile tools/pdb/PDB.ml tools/pdb/Process.ml tools/pdb/Process.mli tools/pdb/Util.ml tools/pdb/debugger.ml tools/pdb/evtchn.ml tools/pdb/evtchn.mli tools/pdb/pdb_caml_xc.c tools/pdb/pdb_xen.c tools/pdb/server.ml xen/Rules.mk xen/include/asm-x86/debugger.h xen/include/public/xen.h
line diff
     1.1 --- a/.rootkeys	Fri Jun 03 18:06:52 2005 +0000
     1.2 +++ b/.rootkeys	Fri Jun 03 21:18:14 2005 +0000
     1.3 @@ -681,11 +681,14 @@ 428d0d85d831iQvvCD3LcaOD9rYGkg tools/ioe
     1.4  428f0763_67jCiHbdgfGlgAOJqfg9A tools/ioemu/x86_64.ld
     1.5  3fbba6dbDfYvJSsw9500b4SZyUhxjQ tools/libxc/Makefile
     1.6  41dde8afKYRKxS4XtLv1KUegGQy_bg tools/libxc/linux_boot_params.h
     1.7 +42a0c8d8qbLfvuvDUA0tFB9nHMh-zg tools/libxc/list.h
     1.8  41cc934abX-QLXJXW_clV_wRjM0zYg tools/libxc/plan9a.out.h
     1.9  3fbba6dc1uU7U3IFeF6A-XEOYF2MkQ tools/libxc/rpm.spec
    1.10  3fbba6dcrNxtygEcgJYAJJ1gCQqfsA tools/libxc/xc.h
    1.11  3fbba6dbEVkVMX0JuDFzap9jeaucGA tools/libxc/xc_bvtsched.c
    1.12  4273458dyF2_sKA6CFkNJQYb8eY2dA tools/libxc/xc_core.c
    1.13 +42a0c8d98XtmbhyddBgIyyHllz5WTw tools/libxc/xc_debug.c
    1.14 +42a0c8d9ucRxWO41IHTfYI7xYGoKrw tools/libxc/xc_debug.h
    1.15  3fbba6dbasJQV-MVElDC0DGSHMiL5w tools/libxc/xc_domain.c
    1.16  40278d99BLsfUv3qxv0I8C1sClZ0ow tools/libxc/xc_elf.h
    1.17  403e0977Bjsm_e82pwvl9VvaJxh8Gg tools/libxc/xc_evtchn.c
    1.18 @@ -737,6 +740,21 @@ 40c9c4697z76HDfkCLdMhmaEwzFoNQ tools/mis
    1.19  41adc641dV-0cDLSyzMs5BT8nL7v3Q tools/misc/xenperf.c
    1.20  4056f5155QYZdsk-1fLdjsZPFTnlhg tools/misc/xensymoops
    1.21  40cf2937dqM1jWW87O5OoOYND8leuA tools/misc/xm
    1.22 +42a0c8d9zuGuWoaTux5NW4N3wOw8pg tools/pdb/Domain.ml
    1.23 +42a0c8d9pigEXFFtdut3R99jbf73NA tools/pdb/Domain.mli
    1.24 +42a0c8d93wnR_hcSAa7VHgn8CSrWEA tools/pdb/Intel.ml
    1.25 +42a0c8d95glt-jkgXe8GDOPT6TYN6Q tools/pdb/Makefile
    1.26 +42a0c8d9UueJDF0IRX3OozEvUhSTmw tools/pdb/OCamlMakefile
    1.27 +42a0c8d9PgBvaWPzTHSFb9ngii7c7w tools/pdb/PDB.ml
    1.28 +42a0c8danHHGiNywdeer6j4jzxAc2A tools/pdb/Process.ml
    1.29 +42a0c8dav_08OtySI4kYP1lahlVrpQ tools/pdb/Process.mli
    1.30 +42a0c8da51EqubQT5PJ4sxCKLF3xSw tools/pdb/Util.ml
    1.31 +42a0c8daxftpiXuvLmc9fOOEhdFWiQ tools/pdb/debugger.ml
    1.32 +42a0c8da81tzhpvIAfkx9nZqUNrQvg tools/pdb/evtchn.ml
    1.33 +42a0c8dasiso9c-2sCvHBzP6YVjATA tools/pdb/evtchn.mli
    1.34 +42a0c8daXD_6Y62A_u5-PO_Klrhi0w tools/pdb/pdb_caml_xc.c
    1.35 +42a0c8danJXun9ay5SPBhhkKvuUPfg tools/pdb/pdb_xen.c
    1.36 +42a0c8dbjK6Du89D2SUcxsuAdlUu3w tools/pdb/server.ml
    1.37  4270cc81g3nSNYCZ1ryCMDEbLtMtbQ tools/pygrub/Makefile
    1.38  4270deeccyRsJn6jLnRh9odRtMW9SA tools/pygrub/README
    1.39  4270cc81EIl7NyaS3Av6IPRk2c2a6Q tools/pygrub/setup.py
     2.1 --- a/BitKeeper/etc/logging_ok	Fri Jun 03 18:06:52 2005 +0000
     2.2 +++ b/BitKeeper/etc/logging_ok	Fri Jun 03 21:18:14 2005 +0000
     2.3 @@ -1,3 +1,4 @@
     2.4 +ach61@arcadians.cl.cam.ac.uk
     2.5  ach61@boulderdash.cl.cam.ac.uk
     2.6  ach61@labyrinth.cl.cam.ac.uk
     2.7  ach61@soar.cl.cam.ac.uk
     3.1 --- a/tools/libxc/Makefile	Fri Jun 03 18:06:52 2005 +0000
     3.2 +++ b/tools/libxc/Makefile	Fri Jun 03 21:18:14 2005 +0000
     3.3 @@ -17,6 +17,7 @@ SRCS     += xc_sedf.c
     3.4  SRCS     += xc_bvtsched.c
     3.5  SRCS     += xc_core.c
     3.6  SRCS     += xc_domain.c
     3.7 +SRCS     += xc_debug.c
     3.8  SRCS     += xc_evtchn.c
     3.9  SRCS     += xc_gnttab.c
    3.10  SRCS     += xc_linux_build.c
    3.11 @@ -93,7 +94,7 @@ rpm: build
    3.12  	mv staging/i386/*.rpm .
    3.13  	rm -rf staging
    3.14  
    3.15 -libxc.a: $(LIB_OBJS)
    3.16 +libxc.a: $(OBJS)
    3.17  	$(AR) rc $@ $^
    3.18  
    3.19  libxc.so: libxc.so.$(MAJOR)
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/tools/libxc/list.h	Fri Jun 03 21:18:14 2005 +0000
     4.3 @@ -0,0 +1,186 @@
     4.4 +#ifndef _LINUX_LIST_H
     4.5 +#define _LINUX_LIST_H
     4.6 +
     4.7 +/*
     4.8 + * Simple doubly linked list implementation.
     4.9 + *
    4.10 + * Some of the internal functions ("__xxx") are useful when
    4.11 + * manipulating whole lists rather than single entries, as
    4.12 + * sometimes we already know the next/prev entries and we can
    4.13 + * generate better code by using them directly rather than
    4.14 + * using the generic single-entry routines.
    4.15 + */
    4.16 +
    4.17 +struct list_head {
    4.18 +	struct list_head *next, *prev;
    4.19 +};
    4.20 +
    4.21 +#define LIST_HEAD_INIT(name) { &(name), &(name) }
    4.22 +
    4.23 +#define LIST_HEAD(name) \
    4.24 +	struct list_head name = LIST_HEAD_INIT(name)
    4.25 +
    4.26 +#define INIT_LIST_HEAD(ptr) do { \
    4.27 +	(ptr)->next = (ptr); (ptr)->prev = (ptr); \
    4.28 +} while (0)
    4.29 +
    4.30 +/*
    4.31 + * Insert a new entry between two known consecutive entries. 
    4.32 + *
    4.33 + * This is only for internal list manipulation where we know
    4.34 + * the prev/next entries already!
    4.35 + */
    4.36 +static __inline__ void __list_add(struct list_head * new,
    4.37 +	struct list_head * prev,
    4.38 +	struct list_head * next)
    4.39 +{
    4.40 +	next->prev = new;
    4.41 +	new->next = next;
    4.42 +	new->prev = prev;
    4.43 +	prev->next = new;
    4.44 +}
    4.45 +
    4.46 +/**
    4.47 + * list_add - add a new entry
    4.48 + * @new: new entry to be added
    4.49 + * @head: list head to add it after
    4.50 + *
    4.51 + * Insert a new entry after the specified head.
    4.52 + * This is good for implementing stacks.
    4.53 + */
    4.54 +static __inline__ void list_add(struct list_head *new, struct list_head *head)
    4.55 +{
    4.56 +	__list_add(new, head, head->next);
    4.57 +}
    4.58 +
    4.59 +/**
    4.60 + * list_add_tail - add a new entry
    4.61 + * @new: new entry to be added
    4.62 + * @head: list head to add it before
    4.63 + *
    4.64 + * Insert a new entry before the specified head.
    4.65 + * This is useful for implementing queues.
    4.66 + */
    4.67 +static __inline__ void list_add_tail(struct list_head *new, struct list_head *head)
    4.68 +{
    4.69 +	__list_add(new, head->prev, head);
    4.70 +}
    4.71 +
    4.72 +/*
    4.73 + * Delete a list entry by making the prev/next entries
    4.74 + * point to each other.
    4.75 + *
    4.76 + * This is only for internal list manipulation where we know
    4.77 + * the prev/next entries already!
    4.78 + */
    4.79 +static __inline__ void __list_del(struct list_head * prev,
    4.80 +				  struct list_head * next)
    4.81 +{
    4.82 +	next->prev = prev;
    4.83 +	prev->next = next;
    4.84 +}
    4.85 +
    4.86 +/**
    4.87 + * list_del - deletes entry from list.
    4.88 + * @entry: the element to delete from the list.
    4.89 + * Note: list_empty on entry does not return true after this, the entry is in an undefined state.
    4.90 + */
    4.91 +static __inline__ void list_del(struct list_head *entry)
    4.92 +{
    4.93 +	__list_del(entry->prev, entry->next);
    4.94 +}
    4.95 +
    4.96 +/**
    4.97 + * list_del_init - deletes entry from list and reinitialize it.
    4.98 + * @entry: the element to delete from the list.
    4.99 + */
   4.100 +static __inline__ void list_del_init(struct list_head *entry)
   4.101 +{
   4.102 +	__list_del(entry->prev, entry->next);
   4.103 +	INIT_LIST_HEAD(entry); 
   4.104 +}
   4.105 +
   4.106 +/**
   4.107 + * list_empty - tests whether a list is empty
   4.108 + * @head: the list to test.
   4.109 + */
   4.110 +static __inline__ int list_empty(struct list_head *head)
   4.111 +{
   4.112 +	return head->next == head;
   4.113 +}
   4.114 +
   4.115 +/**
   4.116 + * list_splice - join two lists
   4.117 + * @list: the new list to add.
   4.118 + * @head: the place to add it in the first list.
   4.119 + */
   4.120 +static __inline__ void list_splice(struct list_head *list, struct list_head *head)
   4.121 +{
   4.122 +	struct list_head *first = list->next;
   4.123 +
   4.124 +	if (first != list) {
   4.125 +		struct list_head *last = list->prev;
   4.126 +		struct list_head *at = head->next;
   4.127 +
   4.128 +		first->prev = head;
   4.129 +		head->next = first;
   4.130 +
   4.131 +		last->next = at;
   4.132 +		at->prev = last;
   4.133 +	}
   4.134 +}
   4.135 +
   4.136 +/**
   4.137 + * list_entry - get the struct for this entry
   4.138 + * @ptr:	the &struct list_head pointer.
   4.139 + * @type:	the type of the struct this is embedded in.
   4.140 + * @member:	the name of the list_struct within the struct.
   4.141 + */
   4.142 +#define list_entry(ptr, type, member) \
   4.143 +	((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member)))
   4.144 +
   4.145 +/**
   4.146 + * list_for_each	-	iterate over a list
   4.147 + * @pos:	the &struct list_head to use as a loop counter.
   4.148 + * @head:	the head for your list.
   4.149 + */
   4.150 +#define list_for_each(pos, head) \
   4.151 +	for (pos = (head)->next; pos != (head); pos = pos->next)
   4.152 +        	
   4.153 +/**
   4.154 + * list_for_each_safe	-	iterate over a list safe against removal of list entry
   4.155 + * @pos:	the &struct list_head to use as a loop counter.
   4.156 + * @n:		another &struct list_head to use as temporary storage
   4.157 + * @head:	the head for your list.
   4.158 + */
   4.159 +#define list_for_each_safe(pos, n, head) \
   4.160 +	for (pos = (head)->next, n = pos->next; pos != (head); \
   4.161 +		pos = n, n = pos->next)
   4.162 +
   4.163 +/**
   4.164 + * list_for_each_entry	-	iterate over list of given type
   4.165 + * @pos:	the type * to use as a loop counter.
   4.166 + * @head:	the head for your list.
   4.167 + * @member:	the name of the list_struct within the struct.
   4.168 + */
   4.169 +#define list_for_each_entry(pos, head, member)				\
   4.170 +	for (pos = list_entry((head)->next, typeof(*pos), member),	\
   4.171 +		     prefetch(pos->member.next);			\
   4.172 +	     &pos->member != (head); 					\
   4.173 +	     pos = list_entry(pos->member.next, typeof(*pos), member),	\
   4.174 +		     prefetch(pos->member.next))
   4.175 +
   4.176 +/**
   4.177 + * list_for_each_entry_safe - iterate over list of given type safe against removal of list entry
   4.178 + * @pos:	the type * to use as a loop counter.
   4.179 + * @n:		another type * to use as temporary storage
   4.180 + * @head:	the head for your list.
   4.181 + * @member:	the name of the list_struct within the struct.
   4.182 + */
   4.183 +#define list_for_each_entry_safe(pos, n, head, member)			\
   4.184 +	for (pos = list_entry((head)->next, typeof(*pos), member),	\
   4.185 +		n = list_entry(pos->member.next, typeof(*pos), member);	\
   4.186 +	     &pos->member != (head); 					\
   4.187 +	     pos = n, n = list_entry(n->member.next, typeof(*n), member))
   4.188 +#endif /* _LINUX_LIST_H */
   4.189 +
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/tools/libxc/xc_debug.c	Fri Jun 03 21:18:14 2005 +0000
     5.3 @@ -0,0 +1,580 @@
     5.4 +/*
     5.5 + * xc_debug.c
     5.6 + *
     5.7 + * alex ho
     5.8 + * http://www.cl.cam.ac.uk/netos/pdb
     5.9 + *
    5.10 + * xc_debug_memory_page adapted from xc_ptrace.c
    5.11 + */
    5.12 +
    5.13 +#include "xc_private.h"
    5.14 +#include "list.h"
    5.15 +
    5.16 +/* from xen/include/asm-x86/processor.h */
    5.17 +#define X86_EFLAGS_TF	0x00000100 /* Trap Flag */
    5.18 +
    5.19 +typedef int boolean;
    5.20 +#define true 1
    5.21 +#define false 0
    5.22 +
    5.23 +
    5.24 +typedef struct bwcpoint                           /* break/watch/catch point */
    5.25 +{
    5.26 +    struct list_head list;
    5.27 +    memory_t address;
    5.28 +    u32 domain;
    5.29 +    u16 vcpu;
    5.30 +    u8 old_value;                             /* old value for software bkpt */
    5.31 +} bwcpoint_t, *bwcpoint_p;
    5.32 +
    5.33 +static bwcpoint_t bwcpoint_list;
    5.34 +
    5.35 +
    5.36 +
    5.37 +typedef struct domain_context                 /* local cache of domain state */
    5.38 +{
    5.39 +    struct list_head     list;
    5.40 +    u32                  domid;
    5.41 +    boolean              valid[MAX_VIRT_CPUS];
    5.42 +    vcpu_guest_context_t context[MAX_VIRT_CPUS];
    5.43 +
    5.44 +    long            total_pages;
    5.45 +    unsigned long  *page_array;
    5.46 +
    5.47 +    unsigned long   cr3_phys[MAX_VIRT_CPUS];
    5.48 +    unsigned long  *cr3_virt[MAX_VIRT_CPUS];
    5.49 +    unsigned long   pde_phys[MAX_VIRT_CPUS];     
    5.50 +    unsigned long  *pde_virt[MAX_VIRT_CPUS];
    5.51 +    unsigned long   page_phys[MAX_VIRT_CPUS];     
    5.52 +    unsigned long  *page_virt[MAX_VIRT_CPUS];
    5.53 +    int             page_perm[MAX_VIRT_CPUS];
    5.54 +} domain_context_t, *domain_context_p;
    5.55 +
    5.56 +static domain_context_t domain_context_list;
    5.57 +
    5.58 +/* initialization */
    5.59 +
    5.60 +static boolean xc_debug_initialized = false;
    5.61 +
    5.62 +static __inline__ void
    5.63 +xc_debug_initialize()
    5.64 +{
    5.65 +    if ( !xc_debug_initialized )
    5.66 +    {
    5.67 +        memset((void *) &domain_context_list, 0, sizeof(domain_context_t));
    5.68 +        INIT_LIST_HEAD(&domain_context_list.list);
    5.69 +
    5.70 +        memset((void *) &bwcpoint_list, 0, sizeof(bwcpoint_t));
    5.71 +        INIT_LIST_HEAD(&bwcpoint_list.list);
    5.72 +
    5.73 +        xc_debug_initialized = true;
    5.74 +    }
    5.75 +}
    5.76 +
    5.77 +/**************/
    5.78 +
    5.79 +static domain_context_p
    5.80 +xc_debug_domain_context_search (u32 domid)
    5.81 +{
    5.82 +    struct list_head *entry;
    5.83 +    domain_context_p  ctxt;
    5.84 +
    5.85 +    list_for_each(entry, &domain_context_list.list)
    5.86 +    {
    5.87 +        ctxt = list_entry(entry, domain_context_t, list);
    5.88 +        if ( domid == ctxt->domid )
    5.89 +            return ctxt;
    5.90 +    }
    5.91 +    return (domain_context_p)NULL;
    5.92 +}
    5.93 +
    5.94 +static __inline__ domain_context_p
    5.95 +xc_debug_get_context (int xc_handle, u32 domid, u32 vcpu)
    5.96 +{
    5.97 +    int rc;
    5.98 +    domain_context_p ctxt;
    5.99 +
   5.100 +    xc_debug_initialize();
   5.101 +
   5.102 +    if ( (ctxt = xc_debug_domain_context_search(domid)) == NULL)
   5.103 +        return NULL;
   5.104 +
   5.105 +    if ( !ctxt->valid[vcpu] )
   5.106 +    {
   5.107 +        if ( (rc = xc_domain_get_vcpu_context(xc_handle, domid, vcpu, 
   5.108 +                                              &ctxt->context[vcpu])) )
   5.109 +            return NULL;
   5.110 +
   5.111 +        ctxt->valid[vcpu] = true;
   5.112 +    }
   5.113 +
   5.114 +    return ctxt;
   5.115 +}
   5.116 +
   5.117 +static __inline__ int
   5.118 +xc_debug_set_context (int xc_handle, domain_context_p ctxt, u32 vcpu)
   5.119 +{
   5.120 +    dom0_op_t op;
   5.121 +    int rc;
   5.122 +
   5.123 +    if ( !ctxt->valid[vcpu] )
   5.124 +        return -EINVAL;
   5.125 +
   5.126 +    op.interface_version = DOM0_INTERFACE_VERSION;
   5.127 +    op.cmd = DOM0_SETDOMAININFO;
   5.128 +    op.u.setdomaininfo.domain = ctxt->domid;
   5.129 +    op.u.setdomaininfo.vcpu = vcpu;
   5.130 +    op.u.setdomaininfo.ctxt = &ctxt->context[vcpu];
   5.131 +
   5.132 +    if ( (rc = mlock(&ctxt->context[vcpu], sizeof(vcpu_guest_context_t))) )
   5.133 +        return rc;
   5.134 +
   5.135 +    rc = do_dom0_op(xc_handle, &op);
   5.136 +    (void) munlock(&ctxt->context[vcpu], sizeof(vcpu_guest_context_t));
   5.137 +
   5.138 +    return rc;
   5.139 +}
   5.140 +
   5.141 +/**************/
   5.142 +
   5.143 +int
   5.144 +xc_debug_attach(int xc_handle,
   5.145 +                u32 domid,
   5.146 +                u32 vcpu)
   5.147 +{
   5.148 +    domain_context_p ctxt;
   5.149 +
   5.150 +    xc_debug_initialize();
   5.151 +
   5.152 +    if ( (ctxt = malloc(sizeof(domain_context_t))) == NULL )
   5.153 +        return -1;
   5.154 +    memset(ctxt, 0, sizeof(domain_context_t));
   5.155 +    
   5.156 +    ctxt->domid = domid;
   5.157 +    list_add(&ctxt->list, &domain_context_list.list);
   5.158 +
   5.159 +    return xc_domain_pause(xc_handle, domid);
   5.160 +}
   5.161 +
   5.162 +int
   5.163 +xc_debug_detach(int xc_handle,
   5.164 +                u32 domid,
   5.165 +                u32 vcpu)
   5.166 +{
   5.167 +    domain_context_p ctxt;
   5.168 +    
   5.169 +    xc_debug_initialize();
   5.170 +
   5.171 +    if ( (ctxt = xc_debug_domain_context_search (domid)) == NULL)
   5.172 +        return -EINVAL;
   5.173 +
   5.174 +    list_del(&ctxt->list);
   5.175 +
   5.176 +    if ( ctxt->page_array ) free(ctxt->page_array);
   5.177 +
   5.178 +    free(ctxt);
   5.179 +
   5.180 +    return xc_domain_unpause(xc_handle, domid);
   5.181 +}
   5.182 +
   5.183 +int
   5.184 +xc_debug_read_registers(int xc_handle,
   5.185 +                        u32 domid,
   5.186 +                        u32 vcpu,
   5.187 +                        cpu_user_regs_t **regs)
   5.188 +{
   5.189 +    domain_context_p ctxt;
   5.190 +    int rc = -1;
   5.191 +
   5.192 +    xc_debug_initialize();
   5.193 +
   5.194 +    ctxt = xc_debug_get_context(xc_handle, domid, vcpu);
   5.195 +    if (ctxt)
   5.196 +    {
   5.197 +        *regs = &ctxt->context[vcpu].user_regs;
   5.198 +        rc = 0;
   5.199 +    }
   5.200 +
   5.201 +    return rc;
   5.202 +}
   5.203 +
   5.204 +int
   5.205 +xc_debug_read_fpregisters (int xc_handle,
   5.206 +                           u32 domid,
   5.207 +                           u32 vcpu,
   5.208 +                           char **regs)
   5.209 +{
   5.210 +    domain_context_p ctxt;
   5.211 +    int rc = -1;
   5.212 +
   5.213 +    xc_debug_initialize();
   5.214 +
   5.215 +    ctxt = xc_debug_get_context(xc_handle, domid, vcpu);
   5.216 +    if (ctxt)
   5.217 +    {
   5.218 +        *regs = ctxt->context[vcpu].fpu_ctxt.x;
   5.219 +        rc = 0;
   5.220 +    }
   5.221 +
   5.222 +    return rc;
   5.223 +}
   5.224 +
   5.225 +int
   5.226 +xc_debug_write_registers(int xc_handle,
   5.227 +                         u32 domid,
   5.228 +                         u32 vcpu,
   5.229 +                         cpu_user_regs_t *regs)
   5.230 +{
   5.231 +    domain_context_p ctxt;
   5.232 +    int rc = -1;
   5.233 +
   5.234 +    xc_debug_initialize();
   5.235 +
   5.236 +    ctxt = xc_debug_get_context(xc_handle, domid, vcpu);
   5.237 +    if (ctxt)
   5.238 +    {
   5.239 +        memcpy(&ctxt->context[vcpu].user_regs, regs, sizeof(cpu_user_regs_t));
   5.240 +        rc = xc_debug_set_context(xc_handle, ctxt, vcpu);
   5.241 +    }
   5.242 +    
   5.243 +    return rc;
   5.244 +}
   5.245 +
   5.246 +int
   5.247 +xc_debug_step(int xc_handle,
   5.248 +              u32 domid,
   5.249 +              u32 vcpu)
   5.250 +{
   5.251 +    domain_context_p ctxt;
   5.252 +    int rc;
   5.253 +
   5.254 +    xc_debug_initialize();
   5.255 +
   5.256 +    ctxt = xc_debug_get_context(xc_handle, domid, vcpu);
   5.257 +    if (!ctxt) return -EINVAL;
   5.258 +
   5.259 +    ctxt->context[vcpu].user_regs.eflags |= X86_EFLAGS_TF;
   5.260 +
   5.261 +    if ( (rc = xc_debug_set_context(xc_handle, ctxt, vcpu)) )
   5.262 +        return rc;
   5.263 +
   5.264 +    ctxt->valid[vcpu] = false;
   5.265 +    return xc_domain_unpause(xc_handle, domid);
   5.266 +}
   5.267 +
   5.268 +int
   5.269 +xc_debug_continue(int xc_handle,
   5.270 +                  u32 domid,
   5.271 +                  u32 vcpu)
   5.272 +{
   5.273 +    domain_context_p ctxt;
   5.274 +    int rc;
   5.275 +
   5.276 +    xc_debug_initialize();
   5.277 +
   5.278 +    ctxt = xc_debug_get_context(xc_handle, domid, vcpu);
   5.279 +    if (!ctxt) return -EINVAL;
   5.280 +
   5.281 +    if ( ctxt->context[vcpu].user_regs.eflags & X86_EFLAGS_TF )
   5.282 +    {
   5.283 +        ctxt->context[vcpu].user_regs.eflags &= ~X86_EFLAGS_TF;
   5.284 +        if ( (rc = xc_debug_set_context(xc_handle, ctxt, vcpu)) )
   5.285 +            return rc;
   5.286 +    }
   5.287 +    ctxt->valid[vcpu] = false;
   5.288 +    return xc_domain_unpause(xc_handle, domid);
   5.289 +}
   5.290 +
   5.291 +/*************************************************/
   5.292 +
   5.293 +#define vtopdi(va) ((va) >> L2_PAGETABLE_SHIFT)
   5.294 +#define vtopti(va) (((va) >> PAGE_SHIFT) & 0x3ff)
   5.295 +
   5.296 +/* access to one page */
   5.297 +static int
   5.298 +xc_debug_memory_page (domain_context_p ctxt, int xc_handle, u32 vcpu,
   5.299 +                      int protection, memory_t address, int length, u8 *buffer)
   5.300 +{
   5.301 +    vcpu_guest_context_t *vcpu_ctxt = &ctxt->context[vcpu];
   5.302 +    unsigned long pde, page;
   5.303 +    unsigned long va = (unsigned long)address;
   5.304 +    void *ptr;
   5.305 +    long pages;
   5.306 +
   5.307 +    pages = xc_get_tot_pages(xc_handle, ctxt->domid);
   5.308 +
   5.309 +    if ( ctxt->total_pages != pages )
   5.310 +    {
   5.311 +        if ( ctxt->total_pages > 0 ) free( ctxt->page_array );
   5.312 +        ctxt->total_pages = pages;
   5.313 +
   5.314 +        ctxt->page_array = malloc(pages * sizeof(unsigned long));
   5.315 +        if ( ctxt->page_array == NULL )
   5.316 +        {
   5.317 +            printf("Could not allocate memory\n");
   5.318 +            return 0;
   5.319 +        }
   5.320 +
   5.321 +        if ( xc_get_pfn_list(xc_handle, ctxt->domid, ctxt->page_array,pages) !=
   5.322 +                pages )
   5.323 +        {
   5.324 +            printf("Could not get the page frame list\n");
   5.325 +            return 0;
   5.326 +        }
   5.327 +    }
   5.328 +
   5.329 +    if ( vcpu_ctxt->pt_base != ctxt->cr3_phys[vcpu]) 
   5.330 +    {
   5.331 +        ctxt->cr3_phys[vcpu] = vcpu_ctxt->pt_base;
   5.332 +        if ( ctxt->cr3_virt[vcpu] )
   5.333 +            munmap(ctxt->cr3_virt[vcpu], PAGE_SIZE);
   5.334 +        ctxt->cr3_virt[vcpu] = xc_map_foreign_range(xc_handle, ctxt->domid,
   5.335 +                    PAGE_SIZE, PROT_READ, ctxt->cr3_phys[vcpu] >> PAGE_SHIFT);
   5.336 +        if ( ctxt->cr3_virt[vcpu] == NULL )
   5.337 +            return 0;
   5.338 +    } 
   5.339 +
   5.340 +
   5.341 +    if ( (pde = ctxt->cr3_virt[vcpu][vtopdi(va)]) == 0) /* logical address */
   5.342 +        return 0;
   5.343 +    if (ctxt->context[vcpu].flags & VGCF_VMX_GUEST)
   5.344 +        pde = ctxt->page_array[pde >> PAGE_SHIFT] << PAGE_SHIFT;
   5.345 +    if (pde != ctxt->pde_phys[vcpu]) 
   5.346 +    {
   5.347 +        ctxt->pde_phys[vcpu] = pde;
   5.348 +        if ( ctxt->pde_virt[vcpu])
   5.349 +            munmap(ctxt->pde_virt[vcpu], PAGE_SIZE);
   5.350 +        ctxt->pde_virt[vcpu] = xc_map_foreign_range(xc_handle, ctxt->domid,
   5.351 +                    PAGE_SIZE, PROT_READ, ctxt->pde_phys[vcpu] >> PAGE_SHIFT);
   5.352 +        if ( ctxt->pde_virt[vcpu] == NULL )
   5.353 +            return 0;
   5.354 +    }
   5.355 +
   5.356 +    if ((page = ctxt->pde_virt[vcpu][vtopti(va)]) == 0) /* logical address */
   5.357 +        return 0;
   5.358 +    if (ctxt->context[vcpu].flags & VGCF_VMX_GUEST)
   5.359 +        page = ctxt->page_array[page >> PAGE_SHIFT] << PAGE_SHIFT;
   5.360 +    if (page != ctxt->page_phys[vcpu] || protection != ctxt->page_perm[vcpu]) 
   5.361 +    {
   5.362 +        ctxt->page_phys[vcpu] = page;
   5.363 +        if (ctxt->page_virt[vcpu])
   5.364 +            munmap(ctxt->page_virt[vcpu], PAGE_SIZE);
   5.365 +        ctxt->page_virt[vcpu] = xc_map_foreign_range(xc_handle, ctxt->domid, 
   5.366 +                  PAGE_SIZE, protection, ctxt->page_phys[vcpu] >> PAGE_SHIFT);
   5.367 +        if ( ctxt->page_virt[vcpu] == NULL )
   5.368 +        {
   5.369 +            printf("cr3 %lx pde %lx page %lx pti %lx\n", 
   5.370 +                   vcpu_ctxt->pt_base, pde, page, vtopti(va));
   5.371 +            ctxt->page_phys[vcpu] = 0;
   5.372 +            return 0;
   5.373 +        }
   5.374 +        ctxt->page_perm[vcpu] = protection;
   5.375 +    }	
   5.376 +
   5.377 +    ptr = (void *)( (unsigned long)ctxt->page_virt[vcpu] |
   5.378 +                    (va & ~PAGE_MASK) );
   5.379 +
   5.380 +    if ( protection & PROT_WRITE )
   5.381 +    {
   5.382 +        memcpy(ptr, buffer, length);
   5.383 +    }
   5.384 +    else
   5.385 +    {
   5.386 +        memcpy(buffer, ptr, length);
   5.387 +    }
   5.388 +
   5.389 +    return length;
   5.390 +}
   5.391 +
   5.392 +/* divide a memory operation into accesses to individual pages */
   5.393 +static int
   5.394 +xc_debug_memory_op (domain_context_p ctxt, int xc_handle, u32 vcpu,
   5.395 +                    int protection, memory_t address, int length, u8 *buffer)
   5.396 +{
   5.397 +    int      remain;              /* number of bytes to touch past this page */
   5.398 +    int      bytes   = 0;
   5.399 +
   5.400 +    while ( (remain = (address + length - 1) - (address | (PAGE_SIZE-1))) > 0)
   5.401 +    {
   5.402 +        bytes += xc_debug_memory_page(ctxt, xc_handle, vcpu, protection,
   5.403 +                                      address, length - remain, buffer);
   5.404 +        buffer += (length - remain);
   5.405 +        length = remain;
   5.406 +        address = (address | (PAGE_SIZE - 1)) + 1;
   5.407 +    }
   5.408 +
   5.409 +    bytes += xc_debug_memory_page(ctxt, xc_handle, vcpu, protection,
   5.410 +                                  address, length, buffer);
   5.411 +
   5.412 +    return bytes;
   5.413 +}
   5.414 +
   5.415 +int
   5.416 +xc_debug_read_memory(int xc_handle,
   5.417 +                     u32 domid,
   5.418 +                     u32 vcpu,
   5.419 +                     memory_t address,
   5.420 +                     u32 length,
   5.421 +                     u8 *data)
   5.422 +{
   5.423 +    domain_context_p ctxt;
   5.424 +
   5.425 +    xc_debug_initialize();
   5.426 +
   5.427 +    ctxt = xc_debug_get_context(xc_handle, domid, vcpu);
   5.428 +
   5.429 +    xc_debug_memory_op(ctxt, xc_handle, vcpu, PROT_READ, 
   5.430 +                       address, length, data);
   5.431 +
   5.432 +    return 0;
   5.433 +}
   5.434 +
   5.435 +int
   5.436 +xc_debug_write_memory(int xc_handle,
   5.437 +                      u32 domid,
   5.438 +                      u32 vcpu,
   5.439 +                      memory_t address,
   5.440 +                      u32 length,
   5.441 +                      u8 *data)
   5.442 +{
   5.443 +    domain_context_p ctxt;
   5.444 +
   5.445 +    xc_debug_initialize();
   5.446 +
   5.447 +    ctxt = xc_debug_get_context(xc_handle, domid, vcpu);
   5.448 +    xc_debug_memory_op(ctxt, xc_handle, vcpu, PROT_READ | PROT_WRITE,
   5.449 +
   5.450 +                       address, length, data);
   5.451 +
   5.452 +    return 0;
   5.453 +}
   5.454 +
   5.455 +int
   5.456 +xc_debug_insert_memory_breakpoint(int xc_handle,
   5.457 +                                  u32 domid,
   5.458 +                                  u32 vcpu,
   5.459 +                                  memory_t address,
   5.460 +                                  u32 length)
   5.461 +{
   5.462 +    bwcpoint_p bkpt;
   5.463 +    u8 breakpoint_opcode = 0xcc;
   5.464 +
   5.465 +    printf("insert breakpoint %d:%lx %d\n",
   5.466 +            domid, address, length);
   5.467 +
   5.468 +    xc_debug_initialize();
   5.469 +
   5.470 +    bkpt = malloc(sizeof(bwcpoint_t));
   5.471 +    if ( bkpt == NULL )
   5.472 +    {
   5.473 +        printf("error: breakpoint length should be 1\n");
   5.474 +        return -1;
   5.475 +    }
   5.476 +
   5.477 +    if ( length != 1 )
   5.478 +    {
   5.479 +        printf("error: breakpoint length should be 1\n");
   5.480 +        free(bkpt);
   5.481 +        return -1;
   5.482 +    }
   5.483 +
   5.484 +    bkpt->address = address;
   5.485 +    bkpt->domain  = domid;
   5.486 +
   5.487 +    xc_debug_read_memory(xc_handle, domid, vcpu, address, 1,
   5.488 +                         &bkpt->old_value);
   5.489 +
   5.490 +    xc_debug_write_memory(xc_handle, domid, vcpu, address, 1, 
   5.491 +                          &breakpoint_opcode);
   5.492 +    
   5.493 +    list_add(&bkpt->list, &bwcpoint_list.list);
   5.494 +
   5.495 +    printf("breakpoint_set %d:%lx 0x%x\n",
   5.496 +           domid, address, bkpt->old_value);
   5.497 +
   5.498 +    return 0;
   5.499 +}
   5.500 +
   5.501 +int
   5.502 +xc_debug_remove_memory_breakpoint(int xc_handle,
   5.503 +                                  u32 domid,
   5.504 +                                  u32 vcpu,
   5.505 +                                  memory_t address,
   5.506 +                                  u32 length)
   5.507 +{
   5.508 +    bwcpoint_p bkpt = NULL;
   5.509 +
   5.510 +    printf ("remove breakpoint %d:%lx\n",
   5.511 +            domid, address);
   5.512 +
   5.513 +    struct list_head *entry;
   5.514 +    list_for_each(entry, &bwcpoint_list.list)
   5.515 +    {
   5.516 +        bkpt = list_entry(entry, bwcpoint_t, list);
   5.517 +        if ( domid == bkpt->domain && address == bkpt->address )
   5.518 +            break;
   5.519 +    }
   5.520 +    
   5.521 +    if (bkpt == &bwcpoint_list || bkpt == NULL)
   5.522 +    {
   5.523 +        printf ("error: no breakpoint found\n");
   5.524 +        return -1;
   5.525 +    }
   5.526 +
   5.527 +    list_del(&bkpt->list);
   5.528 +
   5.529 +    xc_debug_write_memory(xc_handle, domid, vcpu, address, 1, 
   5.530 +                          &bkpt->old_value);
   5.531 +
   5.532 +    free(bkpt);
   5.533 +    return 0;
   5.534 +}
   5.535 +
   5.536 +int
   5.537 +xc_debug_query_domain_stop(int xc_handle, int *dom_list, int dom_list_size)
   5.538 +{
   5.539 +    xc_dominfo_t *info;
   5.540 +    u32 first_dom = 0;
   5.541 +    int max_doms = 1024;
   5.542 +    int nr_doms, loop;
   5.543 +    int count = 0;
   5.544 +
   5.545 +    if ( (info = malloc(max_doms * sizeof(xc_dominfo_t))) == NULL )
   5.546 +        return -ENOMEM;
   5.547 +
   5.548 +    nr_doms = xc_domain_getinfo(xc_handle, first_dom, max_doms, info);
   5.549 +
   5.550 +    for (loop = 0; loop < nr_doms; loop++)
   5.551 +    {
   5.552 +        printf ("domid: %d", info[loop].domid);
   5.553 +        printf (" %c%c%c%c%c%c",
   5.554 +                info[loop].dying ? 'D' : '-',
   5.555 +                info[loop].crashed ? 'C' : '-',
   5.556 +                info[loop].shutdown ? 'S' : '-',
   5.557 +                info[loop].paused ? 'P' : '-',
   5.558 +                info[loop].blocked ? 'B' : '-',
   5.559 +                info[loop].running ? 'R' : '-');
   5.560 +        printf (" pages: %ld, vcpus %d", 
   5.561 +                info[loop].nr_pages, info[loop].vcpus);
   5.562 +        printf ("\n");
   5.563 +
   5.564 +        if ( info[loop].paused && count < dom_list_size)
   5.565 +        {
   5.566 +            dom_list[count++] = info[loop].domid;
   5.567 +        }
   5.568 +    }
   5.569 +
   5.570 +    free(info);
   5.571 +
   5.572 +    return count;
   5.573 +}
   5.574 +
   5.575 +/*
   5.576 + * Local variables:
   5.577 + * mode: C
   5.578 + * c-set-style: "BSD"
   5.579 + * c-basic-offset: 4
   5.580 + * tab-width: 4
   5.581 + * indent-tabs-mode: nil
   5.582 + * End:
   5.583 + */
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/tools/libxc/xc_debug.h	Fri Jun 03 21:18:14 2005 +0000
     6.3 @@ -0,0 +1,76 @@
     6.4 +/*
     6.5 + * xc_debug.h
     6.6 + *
     6.7 + * alex ho
     6.8 + * http://www.cl.cam.ac.uk/netos/pdb
     6.9 + *
    6.10 + */
    6.11 +
    6.12 +#ifndef _XC_DEBUG_H_DEFINED
    6.13 +#define _XC_DEBUG_H_DEFINED
    6.14 +
    6.15 +int xc_debug_attach(int xc_handle,
    6.16 +		    u32 domid,
    6.17 +		    u32 vcpu);
    6.18 +
    6.19 +int xc_debug_detach(int xc_handle,
    6.20 +		    u32 domid,
    6.21 +		    u32 vcpu);
    6.22 +
    6.23 +int xc_debug_read_registers(int xc_handle,
    6.24 +			    u32 domid,
    6.25 +			    u32 vcpu,
    6.26 +			    cpu_user_regs_t **regs);
    6.27 +
    6.28 +int xc_debug_read_fpregisters (int xc_handle,
    6.29 +			       u32 domid,
    6.30 +			       u32 vcpu,
    6.31 +			       char **regs);
    6.32 +
    6.33 +int xc_debug_write_registers(int xc_handle,
    6.34 +			     u32 domid,
    6.35 +			     u32 vcpu,
    6.36 +			     cpu_user_regs_t *regs);
    6.37 +
    6.38 +int xc_debug_step(int xc_handle,
    6.39 +		  u32 domid,
    6.40 +		  u32 vcpu);
    6.41 +
    6.42 +int xc_debug_continue(int xc_handle,
    6.43 +		      u32 domid,
    6.44 +		      u32 vcpu);
    6.45 +
    6.46 +int xc_debug_read_memory(int xc_handle,
    6.47 +			 u32 domid,
    6.48 +			 u32 vcpu,
    6.49 +			 memory_t address,
    6.50 +			 u32 length,
    6.51 +			 u8 *data);
    6.52 +
    6.53 +
    6.54 +int xc_debug_write_memory(int xc_handle,
    6.55 +			  u32 domid,
    6.56 +			  u32 vcpu,
    6.57 +			  memory_t address,
    6.58 +			  u32 length,
    6.59 +			  u8 *data);
    6.60 +
    6.61 +
    6.62 +int xc_debug_insert_memory_breakpoint(int xc_handle,
    6.63 +				      u32 domid,
    6.64 +				      u32 vcpu,
    6.65 +				      memory_t address,
    6.66 +				      u32 length);
    6.67 +
    6.68 +int xc_debug_remove_memory_breakpoint(int xc_handle,
    6.69 +				      u32 domid,
    6.70 +				      u32 vcpu,
    6.71 +				      memory_t address,
    6.72 +				      u32 length);
    6.73 +
    6.74 +int xc_debug_query_domain_stop(int xc_handle,
    6.75 +			       int *dom_list, 
    6.76 +			       int dom_list_size);
    6.77 +
    6.78 +
    6.79 +#endif /* _XC_DEBUG_H_DEFINED */
     7.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.2 +++ b/tools/pdb/Domain.ml	Fri Jun 03 21:18:14 2005 +0000
     7.3 @@ -0,0 +1,63 @@
     7.4 +(** Domain.ml
     7.5 + *
     7.6 + *  domain context implementation
     7.7 + *
     7.8 + *  @author copyright (c) 2005 alex ho
     7.9 + *  @see <www.cl.cam.ac.uk/netos/pdb> pervasive debugger
    7.10 + *  @version 1
    7.11 + *)
    7.12 +
    7.13 +open Int32
    7.14 +open Intel
    7.15 +
    7.16 +type context_t =
    7.17 +{
    7.18 +  mutable domain : int;
    7.19 +  mutable execution_domain : int
    7.20 +}
    7.21 +
    7.22 +let default_context = { domain = 0; execution_domain = 0 }
    7.23 +
    7.24 +let new_context dom exec_dom = {domain = dom; execution_domain = exec_dom}
    7.25 +
    7.26 +let set_domain ctx value =
    7.27 +  ctx.domain <- value;
    7.28 +  print_endline (Printf.sprintf "ctx.domain <- %d" ctx.domain)
    7.29 +
    7.30 +let set_execution_domain ctx value =
    7.31 +  ctx.execution_domain <- value;
    7.32 +  print_endline (Printf.sprintf "ctx.execution_domain <- %d"
    7.33 +		 ctx.execution_domain)
    7.34 +
    7.35 +let get_domain ctx =
    7.36 +  ctx.domain
    7.37 +
    7.38 +let get_execution_domain ctx =
    7.39 +  ctx.execution_domain
    7.40 +
    7.41 +let string_of_context ctx =
    7.42 +      Printf.sprintf "{domain} domain: %d, execution_domain: %d"
    7.43 +                      ctx.domain  ctx.execution_domain
    7.44 +
    7.45 +external read_registers : context_t -> registers = "read_registers"
    7.46 +external write_register : context_t -> register -> int32 -> unit =
    7.47 +  "write_register"
    7.48 +external read_memory : context_t -> int32 -> int -> int list = 
    7.49 +  "read_memory"
    7.50 +external write_memory : context_t -> int32 -> int list -> unit = 
    7.51 +  "write_memory"
    7.52 +	
    7.53 +external continue : context_t -> unit = "continue_target"
    7.54 +external step : context_t -> unit = "step_target"
    7.55 +
    7.56 +external insert_memory_breakpoint : context_t -> int32 -> int -> unit = 
    7.57 +  "insert_memory_breakpoint"
    7.58 +external remove_memory_breakpoint : context_t -> int32 -> int -> unit = 
    7.59 +  "remove_memory_breakpoint"
    7.60 +
    7.61 +external attach_debugger : int -> int -> unit = "attach_debugger"
    7.62 +external detach_debugger : int -> int -> unit = "detach_debugger"
    7.63 +external pause_target : int -> unit = "pause_target"
    7.64 +
    7.65 +let pause ctx =
    7.66 +  pause_target ctx.domain
     8.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.2 +++ b/tools/pdb/Domain.mli	Fri Jun 03 21:18:14 2005 +0000
     8.3 @@ -0,0 +1,38 @@
     8.4 +(** Domain.mli
     8.5 + *
     8.6 + *  domain context interface
     8.7 + *
     8.8 + *  @author copyright (c) 2005 alex ho
     8.9 + *  @see <www.cl.cam.ac.uk/netos/pdb> pervasive debugger
    8.10 + *  @version 1
    8.11 + *)
    8.12 +
    8.13 +open Int32
    8.14 +open Intel
    8.15 +
    8.16 +type context_t
    8.17 +
    8.18 +val default_context : context_t
    8.19 +val new_context : int -> int -> context_t 
    8.20 +
    8.21 +val set_domain : context_t -> int -> unit
    8.22 +val get_domain : context_t -> int
    8.23 +val set_execution_domain : context_t -> int -> unit
    8.24 +val get_execution_domain : context_t -> int
    8.25 +
    8.26 +val string_of_context : context_t -> string
    8.27 +
    8.28 +val read_registers : context_t -> registers
    8.29 +val write_register : context_t -> register -> int32 -> unit
    8.30 +val read_memory : context_t -> int32 -> int -> int list
    8.31 +val write_memory : context_t -> int32 -> int list -> unit
    8.32 +	
    8.33 +val continue : context_t -> unit
    8.34 +val step : context_t -> unit
    8.35 +
    8.36 +val insert_memory_breakpoint : context_t -> int32 -> int -> unit
    8.37 +val remove_memory_breakpoint : context_t -> int32 -> int -> unit
    8.38 +
    8.39 +val attach_debugger : int -> int -> unit
    8.40 +val detach_debugger : int -> int -> unit
    8.41 +val pause : context_t -> unit
     9.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.2 +++ b/tools/pdb/Intel.ml	Fri Jun 03 21:18:14 2005 +0000
     9.3 @@ -0,0 +1,71 @@
     9.4 +(** Intel.ml
     9.5 + *
     9.6 + *  various sundry Intel x86 definitions
     9.7 + *
     9.8 + *  @author copyright (c) 2005 alex ho
     9.9 + *  @see <www.cl.cam.ac.uk/netos/pdb> pervasive debugger
    9.10 + *  @version 1
    9.11 + *)
    9.12 +
    9.13 +
    9.14 +type register =
    9.15 +  | EBX
    9.16 +  | ECX
    9.17 +  | EDX
    9.18 +  | ESI
    9.19 +  | EDI
    9.20 +  | EBP
    9.21 +  | EAX
    9.22 +  | Error_code
    9.23 +  | Entry_vector
    9.24 +  | EIP
    9.25 +  | CS
    9.26 +  | EFLAGS
    9.27 +  | ESP
    9.28 +  | SS
    9.29 +  | ES
    9.30 +  | DS
    9.31 +  | FS
    9.32 +  | GS
    9.33 +
    9.34 +type registers =
    9.35 +    { ebx : int32;
    9.36 +      ecx : int32;
    9.37 +      edx : int32;
    9.38 +      esi : int32;
    9.39 +      edi : int32;
    9.40 +      ebp : int32;
    9.41 +      eax : int32;
    9.42 +      error_code : int32;
    9.43 +      entry_vector : int32;
    9.44 +      eip : int32;
    9.45 +      cs : int32;
    9.46 +      eflags : int32;
    9.47 +      esp : int32;
    9.48 +      ss : int32;
    9.49 +      es : int32;
    9.50 +      ds : int32;
    9.51 +      fs : int32;
    9.52 +      gs : int32
    9.53 +    }
    9.54 +
    9.55 +let null_registers =
    9.56 +  { ebx = 0l;
    9.57 +    ecx = 0l;
    9.58 +    edx = 0l;
    9.59 +    esi = 0l;
    9.60 +    edi = 0l;
    9.61 +    ebp = 0l;
    9.62 +    eax = 0l;
    9.63 +    error_code = 0l;
    9.64 +    entry_vector = 0l;
    9.65 +    eip = 0l;
    9.66 +    cs = 0l;
    9.67 +    eflags = 0l;
    9.68 +    esp = 0l;
    9.69 +    ss = 0l;
    9.70 +    es = 0l;
    9.71 +    ds = 0l;
    9.72 +    fs = 0l;
    9.73 +    gs = 0l
    9.74 +  }
    10.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    10.2 +++ b/tools/pdb/Makefile	Fri Jun 03 21:18:14 2005 +0000
    10.3 @@ -0,0 +1,54 @@
    10.4 +OCAMLMAKEFILE = OCamlMakefile
    10.5 +
    10.6 +XEN_ROOT    = ../..
    10.7 +include $(XEN_ROOT)/tools/Rules.mk
    10.8 +
    10.9 +# overwrite LDFLAGS from xen/tool/Rules.mk
   10.10 +# otherwise, ocamlmktop gets confused.
   10.11 +LDFLAGS     =
   10.12 +
   10.13 +OCAML_ROOT=/usr/local
   10.14 +# force ocaml 3.08
   10.15 +# OCAML_ROOT  = /anfs/nos1/ach61/ocaml
   10.16 +
   10.17 +OCAMLC      = $(OCAML_ROOT)/bin/ocamlc
   10.18 +OCAMLMKTOP  = $(OCAML_ROOT)/bin/ocamlmktop
   10.19 +OCAMLLIBPATH= $(OCAML_ROOT)/lib/ocaml
   10.20 +
   10.21 +INCLUDES   += -I $(XEN_XC)
   10.22 +INCLUDES   += -I $(XEN_LIBXC)
   10.23 +INCLUDES   += -I $(OCAML_ROOT)/lib/ocaml
   10.24 +
   10.25 +CFLAGS     += $(INCLUDES)
   10.26 +CFLAGS     += -Wall
   10.27 +CFLAGS     += -Werror
   10.28 +CFLAGS     += -g
   10.29 +
   10.30 +CLIBS      += xc
   10.31 +CLIBS      += xutil
   10.32 +CLIBS      += pdb
   10.33 +
   10.34 +LIBDIRS    += $(XEN_LIBXC)
   10.35 +LIBDIRS    += $(XEN_LIBXUTIL)
   10.36 +LIBDIRS    += .
   10.37 +
   10.38 +LIBS       += unix str
   10.39 +
   10.40 +PRE_TARGETS = libpdb.a
   10.41 +
   10.42 +all : bc
   10.43 +
   10.44 +libpdb.a : pdb_xen.o
   10.45 +	ar rc $@ $^
   10.46 +	ranlib $@
   10.47 +
   10.48 +SOURCES    += pdb_caml_xc.c pdb_xen.c
   10.49 +SOURCES    += Util.ml Intel.ml 
   10.50 +SOURCES    += evtchn.ml evtchn.mli
   10.51 +SOURCES    += Domain.ml  Process.ml
   10.52 +SOURCES    += Domain.mli Process.mli
   10.53 +SOURCES    += PDB.ml debugger.ml server.ml
   10.54 +RESULT      = pdb
   10.55 +
   10.56 +include $(OCAMLMAKEFILE)
   10.57 +
    11.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    11.2 +++ b/tools/pdb/OCamlMakefile	Fri Jun 03 21:18:14 2005 +0000
    11.3 @@ -0,0 +1,1149 @@
    11.4 +###########################################################################
    11.5 +#                              OCamlMakefile
    11.6 +#                  Copyright (C) 1999-2004  Markus Mottl
    11.7 +#
    11.8 +#                             For updates see:
    11.9 +#                http://www.oefai.at/~markus/ocaml_sources
   11.10 +#
   11.11 +#        $Id: OCamlMakefile,v 1.1 2005/05/19 09:30:48 root Exp $
   11.12 +#
   11.13 +###########################################################################
   11.14 +
   11.15 +# Modified by damien for .glade.ml compilation
   11.16 +
   11.17 +# Set these variables to the names of the sources to be processed and
   11.18 +# the result variable. Order matters during linkage!
   11.19 +
   11.20 +ifndef SOURCES
   11.21 +  SOURCES := foo.ml
   11.22 +endif
   11.23 +export SOURCES
   11.24 +
   11.25 +ifndef RES_CLIB_SUF
   11.26 +  RES_CLIB_SUF := _stubs
   11.27 +endif
   11.28 +export RES_CLIB_SUF
   11.29 +
   11.30 +ifndef RESULT
   11.31 +  RESULT := foo
   11.32 +endif
   11.33 +export RESULT
   11.34 +
   11.35 +export LIB_PACK_NAME
   11.36 +
   11.37 +ifndef DOC_FILES
   11.38 +  DOC_FILES := $(filter %.mli, $(SOURCES))
   11.39 +endif
   11.40 +export DOC_FILES
   11.41 +
   11.42 +export BCSUFFIX
   11.43 +export NCSUFFIX
   11.44 +
   11.45 +ifndef TOPSUFFIX
   11.46 +  TOPSUFFIX := .top
   11.47 +endif
   11.48 +export TOPSUFFIX
   11.49 +
   11.50 +# Eventually set include- and library-paths, libraries to link,
   11.51 +# additional compilation-, link- and ocamlyacc-flags
   11.52 +# Path- and library information needs not be written with "-I" and such...
   11.53 +# Define THREADS if you need it, otherwise leave it unset (same for
   11.54 +# USE_CAMLP4)!
   11.55 +
   11.56 +export THREADS
   11.57 +export VMTHREADS
   11.58 +export ANNOTATE
   11.59 +export USE_CAMLP4
   11.60 +
   11.61 +export INCDIRS
   11.62 +export LIBDIRS
   11.63 +export EXTLIBDIRS
   11.64 +export RESULTDEPS
   11.65 +export OCAML_DEFAULT_DIRS
   11.66 +
   11.67 +export LIBS
   11.68 +export CLIBS
   11.69 +
   11.70 +export OCAMLFLAGS
   11.71 +export OCAMLNCFLAGS
   11.72 +export OCAMLBCFLAGS
   11.73 +
   11.74 +export OCAMLLDFLAGS
   11.75 +export OCAMLNLDFLAGS
   11.76 +export OCAMLBLDFLAGS
   11.77 +
   11.78 +ifndef OCAMLCPFLAGS
   11.79 +  OCAMLCPFLAGS := a
   11.80 +endif
   11.81 +
   11.82 +export OCAMLCPFLAGS
   11.83 +
   11.84 +export PPFLAGS
   11.85 +
   11.86 +export YFLAGS
   11.87 +export IDLFLAGS
   11.88 +
   11.89 +export OCAMLDOCFLAGS
   11.90 +
   11.91 +export OCAMLFIND_INSTFLAGS
   11.92 +
   11.93 +export DVIPSFLAGS
   11.94 +
   11.95 +export STATIC
   11.96 +
   11.97 +# Add a list of optional trash files that should be deleted by "make clean"
   11.98 +export TRASH
   11.99 +
  11.100 +####################  variables depending on your OCaml-installation
  11.101 +
  11.102 +ifdef MINGW
  11.103 +  export MINGW
  11.104 +  WIN32   := 1
  11.105 +  CFLAGS_WIN32 := -mno-cygwin
  11.106 +endif
  11.107 +ifdef MSVC
  11.108 +  export MSVC
  11.109 +  WIN32   := 1
  11.110 +  ifndef STATIC
  11.111 +    CPPFLAGS_WIN32 := -DCAML_DLL
  11.112 +  endif
  11.113 +  CFLAGS_WIN32 += -nologo
  11.114 +  EXT_OBJ := obj
  11.115 +  EXT_LIB := lib
  11.116 +  ifeq ($(CC),gcc)
  11.117 +    # work around GNU Make default value
  11.118 +    ifdef THREADS
  11.119 +      CC := cl -MT
  11.120 +    else
  11.121 +      CC := cl
  11.122 +    endif
  11.123 +  endif
  11.124 +  ifeq ($(CXX),g++)
  11.125 +    # work around GNU Make default value
  11.126 +    CXX := $(CC)
  11.127 +  endif
  11.128 +  CFLAG_O := -Fo
  11.129 +endif
  11.130 +ifdef WIN32
  11.131 +  EXT_CXX := cpp
  11.132 +  EXE     := .exe
  11.133 +endif
  11.134 +
  11.135 +ifndef EXT_OBJ
  11.136 +  EXT_OBJ := o
  11.137 +endif
  11.138 +ifndef EXT_LIB
  11.139 +  EXT_LIB := a
  11.140 +endif
  11.141 +ifndef EXT_CXX
  11.142 +  EXT_CXX := cc
  11.143 +endif
  11.144 +ifndef EXE
  11.145 +  EXE := # empty
  11.146 +endif
  11.147 +ifndef CFLAG_O
  11.148 +  CFLAG_O := -o # do not delete this comment (preserves trailing whitespace)!
  11.149 +endif
  11.150 +
  11.151 +export CC
  11.152 +export CXX
  11.153 +export CFLAGS
  11.154 +export CXXFLAGS
  11.155 +export LDFLAGS
  11.156 +export CPPFLAGS
  11.157 +
  11.158 +ifndef RPATH_FLAG
  11.159 +  RPATH_FLAG := -R
  11.160 +endif
  11.161 +export RPATH_FLAG
  11.162 +
  11.163 +ifndef MSVC
  11.164 +ifndef PIC_CFLAGS
  11.165 +  PIC_CFLAGS := -fPIC
  11.166 +endif
  11.167 +ifndef PIC_CPPFLAGS
  11.168 +  PIC_CPPFLAGS := -DPIC
  11.169 +endif
  11.170 +endif
  11.171 +
  11.172 +export PIC_CFLAGS
  11.173 +export PIC_CPPFLAGS
  11.174 +
  11.175 +BCRESULT  := $(addsuffix $(BCSUFFIX), $(RESULT))
  11.176 +NCRESULT  := $(addsuffix $(NCSUFFIX), $(RESULT))
  11.177 +TOPRESULT := $(addsuffix $(TOPSUFFIX), $(RESULT))
  11.178 +
  11.179 +ifndef OCAMLFIND
  11.180 +  OCAMLFIND := ocamlfind
  11.181 +endif
  11.182 +export OCAMLFIND
  11.183 +
  11.184 +ifndef OCAMLC
  11.185 +  OCAMLC := ocamlc
  11.186 +endif
  11.187 +export OCAMLC
  11.188 +
  11.189 +ifndef OCAMLOPT
  11.190 +  OCAMLOPT := ocamlopt
  11.191 +endif
  11.192 +export OCAMLOPT
  11.193 +
  11.194 +ifndef OCAMLMKTOP
  11.195 +  OCAMLMKTOP := ocamlmktop
  11.196 +endif
  11.197 +export OCAMLMKTOP
  11.198 +
  11.199 +ifndef OCAMLCP
  11.200 +  OCAMLCP := ocamlcp
  11.201 +endif
  11.202 +export OCAMLCP
  11.203 +
  11.204 +ifndef OCAMLDEP
  11.205 +  OCAMLDEP := ocamldep
  11.206 +endif
  11.207 +export OCAMLDEP
  11.208 +
  11.209 +ifndef OCAMLLEX
  11.210 +  OCAMLLEX := ocamllex
  11.211 +endif
  11.212 +export OCAMLLEX
  11.213 +
  11.214 +ifndef OCAMLYACC
  11.215 +  OCAMLYACC := ocamlyacc
  11.216 +endif
  11.217 +export OCAMLYACC
  11.218 +
  11.219 +ifndef OCAMLMKLIB
  11.220 +  OCAMLMKLIB := ocamlmklib
  11.221 +endif
  11.222 +export OCAMLMKLIB
  11.223 +
  11.224 +ifndef OCAML_GLADECC
  11.225 +  OCAML_GLADECC := lablgladecc2
  11.226 +endif
  11.227 +export OCAML_GLADECC
  11.228 +
  11.229 +ifndef OCAML_GLADECC_FLAGS
  11.230 +  OCAML_GLADECC_FLAGS :=
  11.231 +endif
  11.232 +export OCAML_GLADECC_FLAGS
  11.233 +
  11.234 +ifndef CAMELEON_REPORT
  11.235 +  CAMELEON_REPORT := report
  11.236 +endif
  11.237 +export CAMELEON_REPORT
  11.238 +
  11.239 +ifndef CAMELEON_REPORT_FLAGS
  11.240 +  CAMELEON_REPORT_FLAGS :=
  11.241 +endif
  11.242 +export CAMELEON_REPORT_FLAGS
  11.243 +
  11.244 +ifndef CAMELEON_ZOGGY
  11.245 +  CAMELEON_ZOGGY := camlp4o pa_zog.cma pr_o.cmo
  11.246 +endif
  11.247 +export CAMELEON_ZOGGY
  11.248 +
  11.249 +ifndef CAMELEON_ZOGGY_FLAGS
  11.250 +  CAMELEON_ZOGGY_FLAGS :=
  11.251 +endif
  11.252 +export CAMELEON_ZOGGY_FLAGS
  11.253 +
  11.254 +ifndef OXRIDL
  11.255 +  OXRIDL := oxridl
  11.256 +endif
  11.257 +export OXRIDL
  11.258 +
  11.259 +ifndef CAMLIDL
  11.260 +  CAMLIDL := camlidl
  11.261 +endif
  11.262 +export CAMLIDL
  11.263 +
  11.264 +ifndef CAMLIDLDLL
  11.265 +  CAMLIDLDLL := camlidldll
  11.266 +endif
  11.267 +export CAMLIDLDLL
  11.268 +
  11.269 +ifndef NOIDLHEADER
  11.270 +  MAYBE_IDL_HEADER := -header
  11.271 +endif
  11.272 +export NOIDLHEADER
  11.273 +
  11.274 +export NO_CUSTOM
  11.275 +
  11.276 +ifndef CAMLP4
  11.277 +  CAMLP4 := camlp4
  11.278 +endif
  11.279 +export CAMLP4
  11.280 +
  11.281 +ifndef REAL_OCAMLFIND
  11.282 +  ifdef PACKS
  11.283 +    ifndef CREATE_LIB
  11.284 +      ifdef THREADS
  11.285 +	PACKS += threads
  11.286 +      endif
  11.287 +    endif
  11.288 +    empty :=
  11.289 +    space := $(empty) $(empty)
  11.290 +    comma := ,
  11.291 +    ifdef PREDS
  11.292 +      PRE_OCAML_FIND_PREDICATES := $(subst $(space),$(comma),$(PREDS))
  11.293 +      PRE_OCAML_FIND_PACKAGES := $(subst $(space),$(comma),$(PACKS))
  11.294 +      OCAML_FIND_PREDICATES := -predicates $(PRE_OCAML_FIND_PREDICATES)
  11.295 +  #    OCAML_DEP_PREDICATES := -syntax $(PRE_OCAML_FIND_PREDICATES)
  11.296 +      OCAML_FIND_PACKAGES := $(OCAML_FIND_PREDICATES) -package $(PRE_OCAML_FIND_PACKAGES)
  11.297 +      OCAML_DEP_PACKAGES := $(OCAML_DEP_PREDICATES) -package $(PRE_OCAML_FIND_PACKAGES)
  11.298 +    else
  11.299 +      OCAML_FIND_PACKAGES := -package $(subst $(space),$(comma),$(PACKS))
  11.300 +      OCAML_DEP_PACKAGES :=
  11.301 +    endif
  11.302 +    OCAML_FIND_LINKPKG := -linkpkg
  11.303 +    REAL_OCAMLFIND := $(OCAMLFIND)
  11.304 +  endif
  11.305 +endif
  11.306 +
  11.307 +export OCAML_FIND_PACKAGES
  11.308 +export OCAML_DEP_PACKAGES
  11.309 +export OCAML_FIND_LINKPKG
  11.310 +export REAL_OCAMLFIND
  11.311 +
  11.312 +ifndef OCAMLDOC
  11.313 +  OCAMLDOC := ocamldoc
  11.314 +endif
  11.315 +export OCAMLDOC
  11.316 +
  11.317 +ifndef LATEX
  11.318 +  LATEX := latex
  11.319 +endif
  11.320 +export LATEX
  11.321 +
  11.322 +ifndef DVIPS
  11.323 +  DVIPS := dvips
  11.324 +endif
  11.325 +export DVIPS
  11.326 +
  11.327 +ifndef PS2PDF
  11.328 +  PS2PDF := ps2pdf
  11.329 +endif
  11.330 +export PS2PDF
  11.331 +
  11.332 +ifndef OCAMLMAKEFILE
  11.333 +  OCAMLMAKEFILE := OCamlMakefile
  11.334 +endif
  11.335 +export OCAMLMAKEFILE
  11.336 +
  11.337 +ifndef OCAMLLIBPATH
  11.338 +  OCAMLLIBPATH := \
  11.339 +    $(shell $(OCAMLC) 2>/dev/null -where || echo /usr/local/lib/ocaml)
  11.340 +endif
  11.341 +export OCAMLLIBPATH
  11.342 +
  11.343 +ifndef OCAML_LIB_INSTALL
  11.344 +  OCAML_LIB_INSTALL := $(OCAMLLIBPATH)/contrib
  11.345 +endif
  11.346 +export OCAML_LIB_INSTALL
  11.347 +
  11.348 +###########################################################################
  11.349 +
  11.350 +####################  change following sections only if
  11.351 +####################    you know what you are doing!
  11.352 +
  11.353 +# delete target files when a build command fails
  11.354 +.PHONY: .DELETE_ON_ERROR
  11.355 +.DELETE_ON_ERROR:
  11.356 +
  11.357 +# for pedants using "--warn-undefined-variables"
  11.358 +export MAYBE_IDL
  11.359 +export REAL_RESULT
  11.360 +export CAMLIDLFLAGS
  11.361 +export THREAD_FLAG
  11.362 +export RES_CLIB
  11.363 +export MAKEDLL
  11.364 +export ANNOT_FLAG
  11.365 +export C_OXRIDL
  11.366 +export SUBPROJS
  11.367 +export CFLAGS_WIN32
  11.368 +export CPPFLAGS_WIN32
  11.369 +
  11.370 +INCFLAGS :=
  11.371 +
  11.372 +SHELL := /bin/sh
  11.373 +
  11.374 +MLDEPDIR := ._d
  11.375 +BCDIDIR  := ._bcdi
  11.376 +NCDIDIR  := ._ncdi
  11.377 +
  11.378 +FILTER_EXTNS := %.mli %.ml %.mll %.mly %.idl %.oxridl %.c %.$(EXT_CXX) %.rep %.zog %.glade
  11.379 +
  11.380 +FILTERED     := $(filter $(FILTER_EXTNS), $(SOURCES))
  11.381 +SOURCE_DIRS  := $(filter-out ./, $(sort $(dir $(FILTERED))))
  11.382 +
  11.383 +FILTERED_REP := $(filter %.rep, $(FILTERED))
  11.384 +DEP_REP      := $(FILTERED_REP:%.rep=$(MLDEPDIR)/%.d)
  11.385 +AUTO_REP     := $(FILTERED_REP:.rep=.ml)
  11.386 +
  11.387 +FILTERED_ZOG := $(filter %.zog, $(FILTERED))
  11.388 +DEP_ZOG      := $(FILTERED_ZOG:%.zog=$(MLDEPDIR)/%.d)
  11.389 +AUTO_ZOG     := $(FILTERED_ZOG:.zog=.ml)
  11.390 +
  11.391 +FILTERED_GLADE := $(filter %.glade, $(FILTERED))
  11.392 +DEP_GLADE      := $(FILTERED_GLADE:%.glade=$(MLDEPDIR)/%.d)
  11.393 +AUTO_GLADE     := $(FILTERED_GLADE:.glade=.ml)
  11.394 +
  11.395 +FILTERED_ML  := $(filter %.ml, $(FILTERED))
  11.396 +DEP_ML       := $(FILTERED_ML:%.ml=$(MLDEPDIR)/%.d)
  11.397 +
  11.398 +FILTERED_MLI := $(filter %.mli, $(FILTERED))
  11.399 +DEP_MLI      := $(FILTERED_MLI:.mli=.di)
  11.400 +
  11.401 +FILTERED_MLL := $(filter %.mll, $(FILTERED))
  11.402 +DEP_MLL      := $(FILTERED_MLL:%.mll=$(MLDEPDIR)/%.d)
  11.403 +AUTO_MLL     := $(FILTERED_MLL:.mll=.ml)
  11.404 +
  11.405 +FILTERED_MLY := $(filter %.mly, $(FILTERED))
  11.406 +DEP_MLY      := $(FILTERED_MLY:%.mly=$(MLDEPDIR)/%.d) $(FILTERED_MLY:.mly=.di)
  11.407 +AUTO_MLY     := $(FILTERED_MLY:.mly=.mli) $(FILTERED_MLY:.mly=.ml)
  11.408 +
  11.409 +FILTERED_IDL := $(filter %.idl, $(FILTERED))
  11.410 +DEP_IDL      := $(FILTERED_IDL:%.idl=$(MLDEPDIR)/%.d) $(FILTERED_IDL:.idl=.di)
  11.411 +C_IDL        := $(FILTERED_IDL:%.idl=%_stubs.c)
  11.412 +ifndef NOIDLHEADER
  11.413 + C_IDL += $(FILTERED_IDL:.idl=.h)
  11.414 +endif
  11.415 +OBJ_C_IDL    := $(FILTERED_IDL:%.idl=%_stubs.$(EXT_OBJ))
  11.416 +AUTO_IDL     := $(FILTERED_IDL:.idl=.mli) $(FILTERED_IDL:.idl=.ml) $(C_IDL)
  11.417 +
  11.418 +FILTERED_OXRIDL := $(filter %.oxridl, $(FILTERED))
  11.419 +DEP_OXRIDL      := $(FILTERED_OXRIDL:%.oxridl=$(MLDEPDIR)/%.d) $(FILTERED_OXRIDL:.oxridl=.di)
  11.420 +AUTO_OXRIDL     := $(FILTERED_OXRIDL:.oxridl=.mli) $(FILTERED_OXRIDL:.oxridl=.ml) $(C_OXRIDL)
  11.421 +
  11.422 +FILTERED_C_CXX := $(filter %.c %.$(EXT_CXX), $(FILTERED))
  11.423 +OBJ_C_CXX      := $(FILTERED_C_CXX:.c=.$(EXT_OBJ))
  11.424 +OBJ_C_CXX      := $(OBJ_C_CXX:.$(EXT_CXX)=.$(EXT_OBJ))
  11.425 +
  11.426 +PRE_TARGETS  += $(AUTO_MLL) $(AUTO_MLY) $(AUTO_IDL) $(AUTO_OXRIDL) $(AUTO_ZOG) $(AUTO_REP) $(AUTO_GLADE)
  11.427 +
  11.428 +ALL_DEPS     := $(DEP_ML) $(DEP_MLI) $(DEP_MLL) $(DEP_MLY) $(DEP_IDL) $(DEP_OXRIDL) $(DEP_ZOG) $(DEP_REP) $(DEP_GLADE)
  11.429 +
  11.430 +MLDEPS       := $(filter %.d, $(ALL_DEPS))
  11.431 +MLIDEPS      := $(filter %.di, $(ALL_DEPS))
  11.432 +BCDEPIS      := $(MLIDEPS:%.di=$(BCDIDIR)/%.di)
  11.433 +NCDEPIS      := $(MLIDEPS:%.di=$(NCDIDIR)/%.di)
  11.434 +
  11.435 +ALLML        := $(filter %.mli %.ml %.mll %.mly %.idl %.oxridl %.rep %.zog %.glade, $(FILTERED))
  11.436 +
  11.437 +IMPLO_INTF   := $(ALLML:%.mli=%.mli.__)
  11.438 +IMPLO_INTF   := $(foreach file, $(IMPLO_INTF), \
  11.439 +                  $(basename $(file)).cmi $(basename $(file)).cmo)
  11.440 +IMPLO_INTF   := $(filter-out %.mli.cmo, $(IMPLO_INTF))
  11.441 +IMPLO_INTF   := $(IMPLO_INTF:%.mli.cmi=%.cmi)
  11.442 +
  11.443 +IMPLX_INTF   := $(IMPLO_INTF:.cmo=.cmx)
  11.444 +
  11.445 +INTF         := $(filter %.cmi, $(IMPLO_INTF))
  11.446 +IMPL_CMO     := $(filter %.cmo, $(IMPLO_INTF))
  11.447 +IMPL_CMX     := $(IMPL_CMO:.cmo=.cmx)
  11.448 +IMPL_ASM     := $(IMPL_CMO:.cmo=.asm)
  11.449 +IMPL_S       := $(IMPL_CMO:.cmo=.s)
  11.450 +
  11.451 +OBJ_LINK     := $(OBJ_C_IDL) $(OBJ_C_CXX)
  11.452 +OBJ_FILES    := $(IMPL_CMO:.cmo=.$(EXT_OBJ)) $(OBJ_LINK)
  11.453 +
  11.454 +EXECS        := $(addsuffix $(EXE), \
  11.455 +                            $(sort $(TOPRESULT) $(BCRESULT) $(NCRESULT)))
  11.456 +ifdef WIN32
  11.457 +  EXECS      += $(BCRESULT).dll $(NCRESULT).dll
  11.458 +endif
  11.459 +
  11.460 +CLIB_BASE    := $(RESULT)$(RES_CLIB_SUF)
  11.461 +ifneq ($(strip $(OBJ_LINK)),)
  11.462 +  RES_CLIB     := lib$(CLIB_BASE).$(EXT_LIB)
  11.463 +endif
  11.464 +
  11.465 +ifdef WIN32
  11.466 +DLLSONAME := $(CLIB_BASE).dll
  11.467 +else
  11.468 +DLLSONAME := dll$(CLIB_BASE).so
  11.469 +endif
  11.470 +
  11.471 +NONEXECS     := $(INTF) $(IMPL_CMO) $(IMPL_CMX) $(IMPL_ASM) $(IMPL_S) \
  11.472 +		$(OBJ_FILES) $(PRE_TARGETS) $(BCRESULT).cma $(NCRESULT).cmxa \
  11.473 +		$(NCRESULT).$(EXT_LIB) $(BCRESULT).cmi $(BCRESULT).cmo \
  11.474 +		$(NCRESULT).cmi $(NCRESULT).cmx $(NCRESULT).o \
  11.475 +		$(RES_CLIB) $(IMPL_CMO:.cmo=.annot) \
  11.476 +		$(LIB_PACK_NAME).cmi $(LIB_PACK_NAME).cmo $(LIB_PACK_NAME).cmx $(LIB_PACK_NAME).o
  11.477 +
  11.478 +ifndef STATIC
  11.479 +  NONEXECS += $(DLLSONAME)
  11.480 +endif
  11.481 +
  11.482 +ifndef LIBINSTALL_FILES
  11.483 +  LIBINSTALL_FILES := $(RESULT).mli $(RESULT).cmi $(RESULT).cma \
  11.484 +		      $(RESULT).cmxa $(RESULT).$(EXT_LIB) $(RES_CLIB)
  11.485 +  ifndef STATIC
  11.486 +    ifneq ($(strip $(OBJ_LINK)),)
  11.487 +      LIBINSTALL_FILES += $(DLLSONAME)
  11.488 +    endif
  11.489 +  endif
  11.490 +endif
  11.491 +
  11.492 +export LIBINSTALL_FILES
  11.493 +
  11.494 +ifdef WIN32
  11.495 +  # some extra stuff is created while linking DLLs
  11.496 +  NONEXECS   += $(BCRESULT).$(EXT_LIB) $(BCRESULT).exp $(NCRESULT).exp $(CLIB_BASE).exp $(CLIB_BASE).lib
  11.497 +endif
  11.498 +
  11.499 +TARGETS      := $(EXECS) $(NONEXECS)
  11.500 +
  11.501 +# If there are IDL-files
  11.502 +ifneq ($(strip $(FILTERED_IDL)),)
  11.503 +  MAYBE_IDL := -cclib -lcamlidl
  11.504 +endif
  11.505 +
  11.506 +ifdef USE_CAMLP4
  11.507 +  CAMLP4PATH := \
  11.508 +    $(shell $(CAMLP4) -where 2>/dev/null || echo /usr/local/lib/camlp4)
  11.509 +  INCFLAGS := -I $(CAMLP4PATH)
  11.510 +  CINCFLAGS := -I$(CAMLP4PATH)
  11.511 +endif
  11.512 +
  11.513 +DINCFLAGS := $(INCFLAGS) $(SOURCE_DIRS:%=-I %) $(OCAML_DEFAULT_DIRS:%=-I %)
  11.514 +INCFLAGS := $(DINCFLAGS) $(INCDIRS:%=-I %)
  11.515 +CINCFLAGS += $(SOURCE_DIRS:%=-I%) $(INCDIRS:%=-I%) $(OCAML_DEFAULT_DIRS:%=-I%)
  11.516 +
  11.517 +ifndef MSVC
  11.518 +CLIBFLAGS += $(SOURCE_DIRS:%=-L%) $(LIBDIRS:%=-L%) \
  11.519 +             $(EXTLIBDIRS:%=-L%) $(EXTLIBDIRS:%=-Wl,$(RPATH_FLAG)%) \
  11.520 +             $(OCAML_DEFAULT_DIRS:%=-L%)
  11.521 +endif
  11.522 +
  11.523 +ifndef PROFILING
  11.524 +  INTF_OCAMLC := $(OCAMLC)
  11.525 +else
  11.526 +  ifndef THREADS
  11.527 +    INTF_OCAMLC := $(OCAMLCP) -p $(OCAMLCPFLAGS)
  11.528 +  else
  11.529 +    # OCaml does not support profiling byte code
  11.530 +    # with threads (yet), therefore we force an error.
  11.531 +    ifndef REAL_OCAMLC
  11.532 +      $(error Profiling of multithreaded byte code not yet supported by OCaml)
  11.533 +    endif
  11.534 +    INTF_OCAMLC := $(OCAMLC)
  11.535 +  endif
  11.536 +endif
  11.537 +
  11.538 +ifndef MSVC
  11.539 +COMMON_LDFLAGS := $(LDFLAGS:%=-ccopt %) $(SOURCE_DIRS:%=-ccopt -L%) \
  11.540 +		  $(LIBDIRS:%=-ccopt -L%) $(EXTLIBDIRS:%=-ccopt -L%) \
  11.541 +		  $(EXTLIBDIRS:%=-ccopt -Wl,$(RPATH_FLAG)%) \
  11.542 +		  $(OCAML_DEFAULT_DIRS:%=-ccopt -L%)
  11.543 +else
  11.544 +COMMON_LDFLAGS := -ccopt "/link -NODEFAULTLIB:LIBC $(LDFLAGS:%=%) $(SOURCE_DIRS:%=-LIBPATH:%) \
  11.545 +		  $(LIBDIRS:%=-LIBPATH:%) $(EXTLIBDIRS:%=-LIBPATH:%) \
  11.546 +		  $(OCAML_DEFAULT_DIRS:%=-LIBPATH:%) "
  11.547 +endif
  11.548 +
  11.549 +CLIBS_OPTS := $(CLIBS:%=-cclib -l%)
  11.550 +ifdef MSVC
  11.551 +  ifndef STATIC
  11.552 +  # MSVC libraries do not have 'lib' prefix
  11.553 +  CLIBS_OPTS := $(CLIBS:%=-cclib %.lib)
  11.554 +  endif
  11.555 +endif
  11.556 +
  11.557 +ifneq ($(strip $(OBJ_LINK)),)
  11.558 +  ifdef CREATE_LIB
  11.559 +    OBJS_LIBS := -cclib -l$(CLIB_BASE) $(CLIBS_OPTS) $(MAYBE_IDL)
  11.560 +  else
  11.561 +    OBJS_LIBS := $(OBJ_LINK) $(CLIBS_OPTS) $(MAYBE_IDL)
  11.562 +  endif
  11.563 +else
  11.564 +  OBJS_LIBS := $(CLIBS_OPTS) $(MAYBE_IDL)
  11.565 +endif
  11.566 +
  11.567 +# If we have to make byte-code
  11.568 +ifndef REAL_OCAMLC
  11.569 +  BYTE_OCAML := y
  11.570 +
  11.571 +  # EXTRADEPS is added dependencies we have to insert for all
  11.572 +  # executable files we generate.  Ideally it should be all of the
  11.573 +  # libraries we use, but it's hard to find the ones that get searched on
  11.574 +  # the path since I don't know the paths built into the compiler, so
  11.575 +  # just include the ones with slashes in their names.
  11.576 +  EXTRADEPS := $(addsuffix .cma,$(foreach i,$(LIBS),$(if $(findstring /,$(i)),$(i))))
  11.577 +  SPECIAL_OCAMLFLAGS := $(OCAMLBCFLAGS)
  11.578 +
  11.579 +  REAL_OCAMLC := $(INTF_OCAMLC)
  11.580 +
  11.581 +  REAL_IMPL := $(IMPL_CMO)
  11.582 +  REAL_IMPL_INTF := $(IMPLO_INTF)
  11.583 +  IMPL_SUF := .cmo
  11.584 +
  11.585 +  DEPFLAGS  :=
  11.586 +  MAKE_DEPS := $(MLDEPS) $(BCDEPIS)
  11.587 +
  11.588 +  ifdef CREATE_LIB
  11.589 +    CFLAGS := $(PIC_CFLAGS) $(CFLAGS)
  11.590 +    CPPFLAGS := $(PIC_CPPFLAGS) $(CPPFLAGS)
  11.591 +    ifndef STATIC
  11.592 +      ifneq ($(strip $(OBJ_LINK)),)
  11.593 +	MAKEDLL := $(DLLSONAME)
  11.594 +	ALL_LDFLAGS := -dllib $(DLLSONAME)
  11.595 +      endif
  11.596 +    endif
  11.597 +  endif
  11.598 +
  11.599 +  ifndef NO_CUSTOM
  11.600 +    ifneq "$(strip $(OBJ_LINK) $(THREADS) $(MAYBE_IDL) $(CLIBS))" ""
  11.601 +      ALL_LDFLAGS += -custom
  11.602 +    endif
  11.603 +  endif
  11.604 +
  11.605 +  ALL_LDFLAGS += $(INCFLAGS) $(OCAMLLDFLAGS) $(OCAMLBLDFLAGS) \
  11.606 +                 $(COMMON_LDFLAGS) $(LIBS:%=%.cma)
  11.607 +  CAMLIDLDLLFLAGS :=
  11.608 +
  11.609 +  ifdef THREADS
  11.610 +    ifdef VMTHREADS
  11.611 +      THREAD_FLAG := -vmthread
  11.612 +    else
  11.613 +      THREAD_FLAG := -thread
  11.614 +    endif
  11.615 +    ALL_LDFLAGS := $(THREAD_FLAG) $(ALL_LDFLAGS)
  11.616 +    ifndef CREATE_LIB
  11.617 +      ifndef REAL_OCAMLFIND
  11.618 +        ALL_LDFLAGS := unix.cma threads.cma $(ALL_LDFLAGS)
  11.619 +      endif
  11.620 +    endif
  11.621 +  endif
  11.622 +
  11.623 +# we have to make native-code
  11.624 +else
  11.625 +  EXTRADEPS := $(addsuffix .cmxa,$(foreach i,$(LIBS),$(if $(findstring /,$(i)),$(i))))
  11.626 +  ifndef PROFILING
  11.627 +    SPECIAL_OCAMLFLAGS := $(OCAMLNCFLAGS)
  11.628 +    PLDFLAGS :=
  11.629 +  else
  11.630 +    SPECIAL_OCAMLFLAGS := -p $(OCAMLNCFLAGS)
  11.631 +    PLDFLAGS := -p
  11.632 +  endif
  11.633 +
  11.634 +  REAL_IMPL := $(IMPL_CMX)
  11.635 +  REAL_IMPL_INTF := $(IMPLX_INTF)
  11.636 +  IMPL_SUF := .cmx
  11.637 +
  11.638 +  CPPFLAGS := -DNATIVE_CODE $(CPPFLAGS)
  11.639 +
  11.640 +  DEPFLAGS  := -native
  11.641 +  MAKE_DEPS := $(MLDEPS) $(NCDEPIS)
  11.642 +
  11.643 +  ALL_LDFLAGS := $(PLDFLAGS) $(INCFLAGS) $(OCAMLLDFLAGS) \
  11.644 +                 $(OCAMLNLDFLAGS) $(COMMON_LDFLAGS)
  11.645 +  CAMLIDLDLLFLAGS := -opt
  11.646 +
  11.647 +  ifndef CREATE_LIB
  11.648 +    ALL_LDFLAGS += $(LIBS:%=%.cmxa)
  11.649 +  else
  11.650 +    CFLAGS := $(PIC_CFLAGS) $(CFLAGS)
  11.651 +    CPPFLAGS := $(PIC_CPPFLAGS) $(CPPFLAGS)
  11.652 +  endif
  11.653 +
  11.654 +  ifdef THREADS
  11.655 +    THREAD_FLAG := -thread
  11.656 +    ALL_LDFLAGS := $(THREAD_FLAG) $(ALL_LDFLAGS)
  11.657 +    ifndef CREATE_LIB
  11.658 +      ifndef REAL_OCAMLFIND
  11.659 +        ALL_LDFLAGS := unix.cmxa threads.cmxa $(ALL_LDFLAGS)
  11.660 +      endif
  11.661 +    endif
  11.662 +  endif
  11.663 +endif
  11.664 +
  11.665 +export MAKE_DEPS
  11.666 +
  11.667 +ifdef ANNOTATE
  11.668 +  ANNOT_FLAG := -dtypes
  11.669 +else
  11.670 +endif
  11.671 +
  11.672 +ALL_OCAMLCFLAGS := $(THREAD_FLAG) $(ANNOT_FLAG) $(OCAMLFLAGS) \
  11.673 +                   $(INCFLAGS) $(SPECIAL_OCAMLFLAGS)
  11.674 +
  11.675 +ifdef make_deps
  11.676 +  -include $(MAKE_DEPS)
  11.677 +  PRE_TARGETS :=
  11.678 +endif
  11.679 +
  11.680 +###########################################################################
  11.681 +# USER RULES
  11.682 +
  11.683 +# Call "OCamlMakefile QUIET=" to get rid of all of the @'s.
  11.684 +QUIET=@
  11.685 +
  11.686 +# generates byte-code (default)
  11.687 +byte-code:		$(PRE_TARGETS)
  11.688 +			$(QUIET)$(MAKE) -r -f $(OCAMLMAKEFILE) $(BCRESULT) \
  11.689 +				REAL_RESULT="$(BCRESULT)" make_deps=yes
  11.690 +bc:	byte-code
  11.691 +
  11.692 +byte-code-nolink:	$(PRE_TARGETS)
  11.693 +			$(QUIET)$(MAKE) -r -f $(OCAMLMAKEFILE) nolink \
  11.694 +				REAL_RESULT="$(BCRESULT)" make_deps=yes
  11.695 +bcnl:	byte-code-nolink
  11.696 +
  11.697 +top:			$(PRE_TARGETS)
  11.698 +			$(QUIET)$(MAKE) -r -f $(OCAMLMAKEFILE) $(TOPRESULT) \
  11.699 +				REAL_RESULT="$(BCRESULT)" make_deps=yes
  11.700 +
  11.701 +# generates native-code
  11.702 +
  11.703 +native-code:		$(PRE_TARGETS)
  11.704 +			$(QUIET)$(MAKE) -r -f $(OCAMLMAKEFILE) $(NCRESULT) \
  11.705 +				REAL_RESULT="$(NCRESULT)" \
  11.706 +				REAL_OCAMLC="$(OCAMLOPT)" \
  11.707 +				make_deps=yes
  11.708 +nc:	native-code
  11.709 +
  11.710 +native-code-nolink:	$(PRE_TARGETS)
  11.711 +			$(QUIET)$(MAKE) -r -f $(OCAMLMAKEFILE) nolink \
  11.712 +				REAL_RESULT="$(NCRESULT)" \
  11.713 +				REAL_OCAMLC="$(OCAMLOPT)" \
  11.714 +				make_deps=yes
  11.715 +ncnl:	native-code-nolink
  11.716 +
  11.717 +# generates byte-code libraries
  11.718 +byte-code-library:	$(PRE_TARGETS)
  11.719 +			$(QUIET)$(MAKE) -r -f $(OCAMLMAKEFILE) \
  11.720 +				$(RES_CLIB) $(BCRESULT).cma \
  11.721 +				REAL_RESULT="$(BCRESULT)" \
  11.722 +				CREATE_LIB=yes \
  11.723 +				make_deps=yes
  11.724 +bcl:	byte-code-library
  11.725 +
  11.726 +# generates native-code libraries
  11.727 +native-code-library:	$(PRE_TARGETS)
  11.728 +			$(QUIET)$(MAKE) -r -f $(OCAMLMAKEFILE) \
  11.729 +				$(RES_CLIB) $(NCRESULT).cmxa \
  11.730 +				REAL_RESULT="$(NCRESULT)" \
  11.731 +				REAL_OCAMLC="$(OCAMLOPT)" \
  11.732 +				CREATE_LIB=yes \
  11.733 +				make_deps=yes
  11.734 +ncl:	native-code-library
  11.735 +
  11.736 +ifdef WIN32
  11.737 +# generates byte-code dll
  11.738 +byte-code-dll:		$(PRE_TARGETS)
  11.739 +			$(QUIET)$(MAKE) -r -f $(OCAMLMAKEFILE) \
  11.740 +				$(RES_CLIB) $(BCRESULT).dll \
  11.741 +				REAL_RESULT="$(BCRESULT)" \
  11.742 +				make_deps=yes
  11.743 +bcd:	byte-code-dll
  11.744 +
  11.745 +# generates native-code dll
  11.746 +native-code-dll:	$(PRE_TARGETS)
  11.747 +			$(QUIET)$(MAKE) -r -f $(OCAMLMAKEFILE) \
  11.748 +				$(RES_CLIB) $(NCRESULT).dll \
  11.749 +				REAL_RESULT="$(NCRESULT)" \
  11.750 +				REAL_OCAMLC="$(OCAMLOPT)" \
  11.751 +				make_deps=yes
  11.752 +ncd:	native-code-dll
  11.753 +endif
  11.754 +
  11.755 +# generates byte-code with debugging information
  11.756 +debug-code:		$(PRE_TARGETS)
  11.757 +			$(QUIET)$(MAKE) -r -f $(OCAMLMAKEFILE) $(BCRESULT) \
  11.758 +				REAL_RESULT="$(BCRESULT)" make_deps=yes \
  11.759 +				OCAMLFLAGS="-g $(OCAMLFLAGS)" \
  11.760 +				OCAMLLDFLAGS="-g $(OCAMLLDFLAGS)"
  11.761 +dc:	debug-code
  11.762 +
  11.763 +debug-code-nolink:	$(PRE_TARGETS)
  11.764 +			$(QUIET)$(MAKE) -r -f $(OCAMLMAKEFILE) nolink \
  11.765 +				REAL_RESULT="$(BCRESULT)" make_deps=yes \
  11.766 +				OCAMLFLAGS="-g $(OCAMLFLAGS)" \
  11.767 +				OCAMLLDFLAGS="-g $(OCAMLLDFLAGS)"
  11.768 +dcnl:	debug-code-nolink
  11.769 +
  11.770 +# generates byte-code libraries with debugging information
  11.771 +debug-code-library:	$(PRE_TARGETS)
  11.772 +			$(QUIET)$(MAKE) -r -f $(OCAMLMAKEFILE) \
  11.773 +				$(RES_CLIB) $(BCRESULT).cma \
  11.774 +				REAL_RESULT="$(BCRESULT)" make_deps=yes \
  11.775 +				CREATE_LIB=yes \
  11.776 +				OCAMLFLAGS="-g $(OCAMLFLAGS)" \
  11.777 +				OCAMLLDFLAGS="-g $(OCAMLLDFLAGS)"
  11.778 +dcl:	debug-code-library
  11.779 +
  11.780 +# generates byte-code for profiling
  11.781 +profiling-byte-code:		$(PRE_TARGETS)
  11.782 +			$(QUIET)$(MAKE) -r -f $(OCAMLMAKEFILE) $(BCRESULT) \
  11.783 +				REAL_RESULT="$(BCRESULT)" PROFILING="y" \
  11.784 +				make_deps=yes
  11.785 +pbc:	profiling-byte-code
  11.786 +
  11.787 +# generates native-code
  11.788 +
  11.789 +profiling-native-code:		$(PRE_TARGETS)
  11.790 +			$(QUIET)$(MAKE) -r -f $(OCAMLMAKEFILE) $(NCRESULT) \
  11.791 +				REAL_RESULT="$(NCRESULT)" \
  11.792 +				REAL_OCAMLC="$(OCAMLOPT)" \
  11.793 +				PROFILING="y" \
  11.794 +				make_deps=yes
  11.795 +pnc:	profiling-native-code
  11.796 +
  11.797 +# generates byte-code libraries
  11.798 +profiling-byte-code-library:	$(PRE_TARGETS)
  11.799 +			$(QUIET)$(MAKE) -r -f $(OCAMLMAKEFILE) \
  11.800 +				$(RES_CLIB) $(BCRESULT).cma \
  11.801 +				REAL_RESULT="$(BCRESULT)" PROFILING="y" \
  11.802 +				CREATE_LIB=yes \
  11.803 +				make_deps=yes
  11.804 +pbcl:	profiling-byte-code-library
  11.805 +
  11.806 +# generates native-code libraries
  11.807 +profiling-native-code-library:	$(PRE_TARGETS)
  11.808 +			$(QUIET)$(MAKE) -r -f $(OCAMLMAKEFILE) \
  11.809 +				$(RES_CLIB) $(NCRESULT).cmxa \
  11.810 +				REAL_RESULT="$(NCRESULT)" PROFILING="y" \
  11.811 +				REAL_OCAMLC="$(OCAMLOPT)" \
  11.812 +				CREATE_LIB=yes \
  11.813 +				make_deps=yes
  11.814 +pncl:	profiling-native-code-library
  11.815 +
  11.816 +# packs byte-code objects
  11.817 +pack-byte-code:			$(PRE_TARGETS)
  11.818 +			$(QUIET)$(MAKE) -r -f $(OCAMLMAKEFILE) $(BCRESULT).cmo \
  11.819 +				REAL_RESULT="$(BCRESULT)" \
  11.820 +				PACK_LIB=yes make_deps=yes
  11.821 +pabc:	pack-byte-code
  11.822 +
  11.823 +# packs native-code objects
  11.824 +pack-native-code:		$(PRE_TARGETS)
  11.825 +			$(QUIET)$(MAKE) -r -f $(OCAMLMAKEFILE) \
  11.826 +				$(NCRESULT).cmx $(NCRESULT).o \
  11.827 +				REAL_RESULT="$(NCRESULT)" \
  11.828 +				REAL_OCAMLC="$(OCAMLOPT)" \
  11.829 +				PACK_LIB=yes make_deps=yes
  11.830 +panc:	pack-native-code
  11.831 +
  11.832 +# generates HTML-documentation
  11.833 +htdoc:	doc/$(RESULT)/html
  11.834 +
  11.835 +# generates Latex-documentation
  11.836 +ladoc:	doc/$(RESULT)/latex
  11.837 +
  11.838 +# generates PostScript-documentation
  11.839 +psdoc:	doc/$(RESULT)/latex/doc.ps
  11.840 +
  11.841 +# generates PDF-documentation
  11.842 +pdfdoc:	doc/$(RESULT)/latex/doc.pdf
  11.843 +
  11.844 +# generates all supported forms of documentation
  11.845 +doc: htdoc ladoc psdoc pdfdoc
  11.846 +
  11.847 +###########################################################################
  11.848 +# LOW LEVEL RULES
  11.849 +
  11.850 +$(REAL_RESULT):		$(REAL_IMPL_INTF) $(OBJ_LINK) $(EXTRADEPS) $(RESULTDEPS)
  11.851 +			$(REAL_OCAMLFIND) $(REAL_OCAMLC) \
  11.852 +				$(OCAML_FIND_PACKAGES) $(OCAML_FIND_LINKPKG) \
  11.853 +				$(ALL_LDFLAGS) $(OBJS_LIBS) -o $@$(EXE) \
  11.854 +				$(REAL_IMPL)
  11.855 +
  11.856 +nolink:			$(REAL_IMPL_INTF) $(OBJ_LINK)
  11.857 +
  11.858 +ifdef WIN32
  11.859 +$(REAL_RESULT).dll:	$(REAL_IMPL_INTF) $(OBJ_LINK)
  11.860 +			$(CAMLIDLDLL) $(CAMLIDLDLLFLAGS) $(OBJ_LINK) $(CLIBS) \
  11.861 +				-o $@ $(REAL_IMPL)
  11.862 +endif
  11.863 +
  11.864 +%$(TOPSUFFIX):		$(REAL_IMPL_INTF) $(OBJ_LINK) $(EXTRADEPS)
  11.865 +			$(REAL_OCAMLFIND) $(OCAMLMKTOP) \
  11.866 +				$(OCAML_FIND_PACKAGES) $(OCAML_FIND_LINKPKG) \
  11.867 +				$(ALL_LDFLAGS) $(OBJS_LIBS) -o $@$(EXE) \
  11.868 +				$(REAL_IMPL)
  11.869 +
  11.870 +.SUFFIXES:		.mli .ml .cmi .cmo .cmx .cma .cmxa .$(EXT_OBJ) \
  11.871 +                        .mly .di .d .$(EXT_LIB) .idl %.oxridl .c .$(EXT_CXX) .h .so \
  11.872 +                        .rep .zog .glade
  11.873 +
  11.874 +ifndef STATIC
  11.875 +ifdef MINGW
  11.876 +$(DLLSONAME):		$(OBJ_LINK)
  11.877 +			$(CC) $(CFLAGS) $(CFLAGS_WIN32) $(OBJ_LINK) -shared -o $@ \
  11.878 +			-Wl,--whole-archive $(wildcard $(foreach dir,$(LIBDIRS),$(CLIBS:%=$(dir)/lib%.a))) \
  11.879 +			 $(OCAMLLIBPATH)/ocamlrun.a \
  11.880 +			-Wl,--export-all-symbols \
  11.881 +			-Wl,--no-whole-archive
  11.882 +else
  11.883 +ifdef MSVC
  11.884 +$(DLLSONAME):		$(OBJ_LINK)
  11.885 +			link /NOLOGO /DLL /OUT:$@ $(OBJ_LINK) \
  11.886 +			 $(wildcard $(foreach dir,$(LIBDIRS),$(CLIBS:%=$(dir)/%.lib))) \
  11.887 +			 $(OCAMLLIBPATH)/ocamlrun.lib
  11.888 +
  11.889 +else
  11.890 +$(DLLSONAME):		$(OBJ_LINK)
  11.891 +			$(OCAMLMKLIB) $(INCFLAGS) $(CLIBFLAGS) \
  11.892 +				-o $(CLIB_BASE) $(OBJ_LINK) $(CLIBS:%=-l%) \
  11.893 +				$(OCAMLMKLIB_FLAGS)
  11.894 +endif
  11.895 +endif
  11.896 +endif
  11.897 +
  11.898 +ifndef LIB_PACK_NAME
  11.899 +$(RESULT).cma:		$(REAL_IMPL_INTF) $(MAKEDLL) $(EXTRADEPS) $(RESULTDEPS)
  11.900 +			$(REAL_OCAMLFIND) $(REAL_OCAMLC) -a $(ALL_LDFLAGS) \
  11.901 +				$(OBJS_LIBS) -o $@ $(OCAMLBLDFLAGS) $(REAL_IMPL)
  11.902 +
  11.903 +$(RESULT).cmxa $(RESULT).$(EXT_LIB):	$(REAL_IMPL_INTF) $(EXTRADEPS) $(RESULTDEPS)
  11.904 +			$(REAL_OCAMLFIND) $(OCAMLOPT) -a $(ALL_LDFLAGS) $(OBJS_LIBS) \
  11.905 +				$(OCAMLNLDFLAGS) -o $@ $(REAL_IMPL)
  11.906 +else
  11.907 +ifdef BYTE_OCAML
  11.908 +$(LIB_PACK_NAME).cmi $(LIB_PACK_NAME).cmo: $(REAL_IMPL_INTF)
  11.909 +			$(REAL_OCAMLFIND) $(REAL_OCAMLC) -pack -o $(LIB_PACK_NAME).cmo $(REAL_IMPL)
  11.910 +else
  11.911 +$(LIB_PACK_NAME).cmi $(LIB_PACK_NAME).cmx: $(REAL_IMPL_INTF)
  11.912 +			$(REAL_OCAMLFIND) $(REAL_OCAMLC) -pack -o $(LIB_PACK_NAME).cmx $(REAL_IMPL)
  11.913 +endif
  11.914 +
  11.915 +$(RESULT).cma:		$(LIB_PACK_NAME).cmi $(LIB_PACK_NAME).cmo $(MAKEDLL) $(EXTRADEPS) $(RESULTDEPS)
  11.916 +			$(REAL_OCAMLFIND) $(REAL_OCAMLC) -a $(ALL_LDFLAGS) \
  11.917 +				$(OBJS_LIBS) -o $@ $(OCAMLBLDFLAGS) $(LIB_PACK_NAME).cmo
  11.918 +
  11.919 +$(RESULT).cmxa $(RESULT).$(EXT_LIB):	$(LIB_PACK_NAME).cmi $(LIB_PACK_NAME).cmx $(EXTRADEPS) $(RESULTDEPS)
  11.920 +			$(REAL_OCAMLFIND) $(OCAMLOPT) -a $(ALL_LDFLAGS) $(OBJS_LIBS) \
  11.921 +				$(OCAMLNLDFLAGS) -o $@ $(LIB_PACK_NAME).cmx
  11.922 +endif
  11.923 +
  11.924 +$(RES_CLIB): 		$(OBJ_LINK)
  11.925 +ifndef MSVC
  11.926 +  ifneq ($(strip $(OBJ_LINK)),)
  11.927 +		      $(AR) rcs $@ $(OBJ_LINK)
  11.928 +  endif
  11.929 +else
  11.930 +  ifneq ($(strip $(OBJ_LINK)),)
  11.931 +			lib -nologo -debugtype:cv -out:$(RES_CLIB) $(OBJ_LINK)
  11.932 +  endif
  11.933 +endif
  11.934 +
  11.935 +.mli.cmi: $(EXTRADEPS)
  11.936 +			$(QUIET)pp=`sed -n -e '/^#/d' -e 's/(\*pp \([^*]*\) \*)/\1/p;q' $<`; \
  11.937 +			if [ -z "$$pp" ]; then \
  11.938 +			  echo $(REAL_OCAMLFIND) $(INTF_OCAMLC) $(OCAML_FIND_PACKAGES) \
  11.939 +				-c $(THREAD_FLAG) $(ANNOT_FLAG) \
  11.940 +				$(OCAMLFLAGS) $(INCFLAGS) $<; \
  11.941 +			  $(REAL_OCAMLFIND) $(INTF_OCAMLC) $(OCAML_FIND_PACKAGES) \
  11.942 +				-c $(THREAD_FLAG) $(ANNOT_FLAG) \
  11.943 +				$(OCAMLFLAGS) $(INCFLAGS) $<; \
  11.944 +			else \
  11.945 +			    echo $(REAL_OCAMLFIND) $(INTF_OCAMLC) $(OCAML_FIND_PACKAGES) \
  11.946 +				-c -pp \"$$pp $(PPFLAGS)\" $(THREAD_FLAG) $(ANNOT_FLAG) \
  11.947 +				$(OCAMLFLAGS) $(INCFLAGS) $<; \
  11.948 +			    $(REAL_OCAMLFIND) $(INTF_OCAMLC) $(OCAML_FIND_PACKAGES) \
  11.949 +				-c -pp "$$pp $(PPFLAGS)" $(THREAD_FLAG) $(ANNOT_FLAG) \
  11.950 +				$(OCAMLFLAGS) $(INCFLAGS) $<; \
  11.951 +			fi
  11.952 +
  11.953 +.ml.cmi .ml.$(EXT_OBJ) .ml.cmx .ml.cmo: $(EXTRADEPS)
  11.954 +			$(QUIET)pp=`sed -n -e '/^#/d' -e 's/(\*pp \([^*]*\) \*)/\1/p;q' $<`; \
  11.955 +			if [ -z "$$pp" ]; then \
  11.956 +			  echo $(REAL_OCAMLFIND) $(REAL_OCAMLC) $(OCAML_FIND_PACKAGES) \
  11.957 +				-c $(ALL_OCAMLCFLAGS) $<; \
  11.958 +			  $(REAL_OCAMLFIND) $(REAL_OCAMLC) $(OCAML_FIND_PACKAGES) \
  11.959 +				-c $(ALL_OCAMLCFLAGS) $<; \
  11.960 +			else \
  11.961 +			  echo $(REAL_OCAMLFIND) $(REAL_OCAMLC) $(OCAML_FIND_PACKAGES) \
  11.962 +				-c -pp \"$$pp $(PPFLAGS)\" $(ALL_OCAMLCFLAGS) $<; \
  11.963 +			  $(REAL_OCAMLFIND) $(REAL_OCAMLC) $(OCAML_FIND_PACKAGES) \
  11.964 +				-c -pp "$$pp $(PPFLAGS)" $(ALL_OCAMLCFLAGS) $<; \
  11.965 +			fi
  11.966 +
  11.967 +ifdef PACK_LIB
  11.968 +$(REAL_RESULT).cmo $(REAL_RESULT).cmx $(REAL_RESULT).o: $(REAL_IMPL_INTF) $(OBJ_LINK) $(EXTRADEPS)
  11.969 +			$(REAL_OCAMLFIND) $(REAL_OCAMLC) -pack $(ALL_LDFLAGS) \
  11.970 +				$(OBJS_LIBS) -o $@ $(REAL_IMPL)
  11.971 +endif
  11.972 +
  11.973 +.PRECIOUS:		%.ml
  11.974 +%.ml:			%.mll
  11.975 +			$(OCAMLLEX) $<
  11.976 +
  11.977 +.PRECIOUS:              %.ml %.mli
  11.978 +%.ml %.mli:             %.mly
  11.979 +			$(OCAMLYACC) $(YFLAGS) $<
  11.980 +			$(QUIET)pp=`sed -n -e 's/.*(\*pp \([^*]*\) \*).*/\1/p;q' $<`; \
  11.981 +			if [ ! -z "$$pp" ]; then \
  11.982 +			  mv $*.ml $*.ml.temporary; \
  11.983 +			  echo "(*pp $$pp $(PPFLAGS)*)" > $*.ml; \
  11.984 +			  cat $*.ml.temporary >> $*.ml; \
  11.985 +			  rm $*.ml.temporary; \
  11.986 +			  mv $*.mli $*.mli.temporary; \
  11.987 +			  echo "(*pp $$pp $(PPFLAGS)*)" > $*.mli; \
  11.988 +			  cat $*.mli.temporary >> $*.mli; \
  11.989 +			  rm $*.mli.temporary; \
  11.990 +			fi
  11.991 +
  11.992 +
  11.993 +.PRECIOUS:		%.ml
  11.994 +%.ml:			%.rep
  11.995 +			$(CAMELEON_REPORT) $(CAMELEON_REPORT_FLAGS) -gen $<
  11.996 +
  11.997 +.PRECIOUS:		%.ml
  11.998 +%.ml:			%.zog
  11.999 +			$(CAMELEON_ZOGGY)  $(CAMELEON_ZOGGY_FLAGS) -impl $< > $@
 11.1000 +
 11.1001 +.PRECIOUS:		%.ml
 11.1002 +%.ml:			%.glade
 11.1003 +			$(OCAML_GLADECC)  $(OCAML_GLADECC_FLAGS) $< > $@
 11.1004 +
 11.1005 +.PRECIOUS:		%.ml %.mli
 11.1006 +%.ml %.mli:		%.oxridl
 11.1007 +			$(OXRIDL) $<
 11.1008 +
 11.1009 +.PRECIOUS:		%.ml %.mli %_stubs.c %.h
 11.1010 +%.ml %.mli %_stubs.c %.h:		%.idl
 11.1011 +			$(CAMLIDL) $(MAYBE_IDL_HEADER) $(IDLFLAGS) \
 11.1012 +				$(CAMLIDLFLAGS) $<
 11.1013 +			$(QUIET)if [ $(NOIDLHEADER) ]; then touch $*.h; fi
 11.1014 +
 11.1015 +.c.$(EXT_OBJ):
 11.1016 +			$(OCAMLC) -c -cc "$(CC)" -ccopt "$(CFLAGS) \
 11.1017 +				$(CPPFLAGS) $(CPPFLAGS_WIN32) \
 11.1018 +				$(CFLAGS_WIN32) $(CINCFLAGS) $(CFLAG_O)$@ " $< 
 11.1019 +
 11.1020 +.$(EXT_CXX).$(EXT_OBJ):
 11.1021 +			$(CXX) -c $(CXXFLAGS) $(CINCFLAGS) $(CPPFLAGS) \
 11.1022 +				-I'$(OCAMLLIBPATH)' \
 11.1023 +				$< $(CFLAG_O)$@
 11.1024 +
 11.1025 +$(MLDEPDIR)/%.d:	%.ml
 11.1026 +			$(QUIET)echo making $@ from $<
 11.1027 +			$(QUIET)if [ ! -d $(@D) ]; then mkdir -p $(@D); fi
 11.1028 +			$(QUIET)pp=`sed -n -e '/^#/d' -e 's/(\*pp \([^*]*\) \*)/\1/p;q' $<`; \
 11.1029 +			if [ -z "$$pp" ]; then \
 11.1030 +			  $(REAL_OCAMLFIND) $(OCAMLDEP) $(OCAML_DEP_PACKAGES) \
 11.1031 +				$(DINCFLAGS) $< > $@; \
 11.1032 +			else \
 11.1033 +			  $(REAL_OCAMLFIND) $(OCAMLDEP) $(OCAML_DEP_PACKAGES) \
 11.1034 +				-pp "$$pp $(PPFLAGS)" $(DINCFLAGS) $< > $@; \
 11.1035 +			fi
 11.1036 +
 11.1037 +$(BCDIDIR)/%.di $(NCDIDIR)/%.di:	%.mli
 11.1038 +			$(QUIET)echo making $@ from $<
 11.1039 +			$(QUIET)if [ ! -d $(@D) ]; then mkdir -p $(@D); fi
 11.1040 +			$(QUIET)pp=`sed -n -e '/^#/d' -e 's/(\*pp \([^*]*\) \*)/\1/p;q' $<`; \
 11.1041 +			if [ -z "$$pp" ]; then \
 11.1042 +			  $(REAL_OCAMLFIND) $(OCAMLDEP) $(DEPFLAGS) $(DINCFLAGS) $< > $@; \
 11.1043 +			else \
 11.1044 +			  $(REAL_OCAMLFIND) $(OCAMLDEP) $(DEPFLAGS) \
 11.1045 +			    -pp "$$pp $(PPFLAGS)" $(DINCFLAGS) $< > $@; \
 11.1046 +			fi
 11.1047 +
 11.1048 +doc/$(RESULT)/html: $(DOC_FILES)
 11.1049 +	rm -rf $@
 11.1050 +	mkdir -p $@
 11.1051 +	$(QUIET)pp=`sed -n -e '/^#/d' -e 's/(\*pp \([^*]*\) \*)/\1/p;q' $<`; \
 11.1052 +	if [ -z "$$pp" ]; then \
 11.1053 +	  echo $(OCAMLDOC) -html -d $@ $(OCAMLDOCFLAGS) $(INCFLAGS) $(DOC_FILES); \
 11.1054 +	  $(OCAMLDOC) -html -d $@ $(OCAMLDOCFLAGS) $(INCFLAGS) $(DOC_FILES); \
 11.1055 +	else \
 11.1056 +	  echo $(OCAMLDOC) -pp \"$$pp $(PPFLAGS)\" -html -d $@ $(OCAMLDOCFLAGS) \
 11.1057 +	  	$(INCFLAGS) $(DOC_FILES); \
 11.1058 +	  $(OCAMLDOC) -pp "$$pp $(PPFLAGS)" -html -d $@ $(OCAMLDOCFLAGS) \
 11.1059 +	  	$(INCFLAGS) $(DOC_FILES); \
 11.1060 +	fi
 11.1061 +
 11.1062 +doc/$(RESULT)/latex: $(DOC_FILES)
 11.1063 +	rm -rf $@
 11.1064 +	mkdir -p $@
 11.1065 +	$(QUIET)pp=`sed -n -e '/^#/d' -e 's/(\*pp \([^*]*\) \*)/\1/p;q' $<`; \
 11.1066 +	if [ -z "$$pp" ]; then \
 11.1067 +	  echo $(OCAMLDOC) -latex $(OCAMLDOCFLAGS) $(INCFLAGS) \
 11.1068 +	  	$(DOC_FILES) -o $@/doc.tex; \
 11.1069 +	  $(OCAMLDOC) -latex $(OCAMLDOCFLAGS) $(INCFLAGS) $(DOC_FILES) \
 11.1070 +	  	-o $@/doc.tex; \
 11.1071 +	else \
 11.1072 +	  echo $(OCAMLDOC) -pp \"$$pp $(PPFLAGS)\" -latex $(OCAMLDOCFLAGS) \
 11.1073 +	  	$(INCFLAGS) $(DOC_FILES) -o $@/doc.tex; \
 11.1074 +	  $(OCAMLDOC) -pp "$$pp $(PPFLAGS)" -latex $(OCAMLDOCFLAGS) \
 11.1075 +	  	$(INCFLAGS) $(DOC_FILES) -o $@/doc.tex; \
 11.1076 +	fi
 11.1077 +
 11.1078 +doc/$(RESULT)/latex/doc.ps: doc/$(RESULT)/latex
 11.1079 +	cd doc/$(RESULT)/latex && \
 11.1080 +	  $(LATEX) doc.tex && \
 11.1081 +	  $(LATEX) doc.tex && \
 11.1082 +	  $(DVIPS) $(DVIPSFLAGS) doc.dvi -o $(@F)
 11.1083 +
 11.1084 +doc/$(RESULT)/latex/doc.pdf: doc/$(RESULT)/latex/doc.ps
 11.1085 +	cd doc/$(RESULT)/latex && $(PS2PDF) $(<F)
 11.1086 +
 11.1087 +define make_subproj
 11.1088 +.PHONY:
 11.1089 +subproj_$(1):
 11.1090 +	$$(eval $$(call PROJ_$(1)))
 11.1091 +	$(QUIET)if [ "$(SUBTARGET)" != "all" ]; then \
 11.1092 +	  $(MAKE) -f $(OCAMLMAKEFILE) $(SUBTARGET); \
 11.1093 +	fi
 11.1094 +endef
 11.1095 +
 11.1096 +$(foreach subproj,$(SUBPROJS),$(eval $(call make_subproj,$(subproj))))
 11.1097 +
 11.1098 +.PHONY:
 11.1099 +subprojs: $(SUBPROJS:%=subproj_%)
 11.1100 +
 11.1101 +###########################################################################
 11.1102 +# (UN)INSTALL RULES FOR LIBRARIES
 11.1103 +
 11.1104 +.PHONY: libinstall
 11.1105 +libinstall:	all
 11.1106 +	$(QUIET)printf "\nInstalling library with ocamlfind\n"
 11.1107 +	$(OCAMLFIND) install $(OCAMLFIND_INSTFLAGS) $(RESULT) META $(LIBINSTALL_FILES)
 11.1108 +	$(QUIET)printf "\nInstallation successful.\n"
 11.1109 +
 11.1110 +.PHONY: libuninstall
 11.1111 +libuninstall:
 11.1112 +	$(QUIET)printf "\nUninstalling library with ocamlfind\n"
 11.1113 +	$(OCAMLFIND) remove $(OCAMLFIND_INSTFLAGS) $(RESULT)
 11.1114 +	$(QUIET)printf "\nUninstallation successful.\n"
 11.1115 +
 11.1116 +.PHONY: rawinstall
 11.1117 +rawinstall:	all
 11.1118 +	$(QUIET)printf "\nInstalling library to: $(OCAML_LIB_INSTALL)\n"
 11.1119 +	-install -d $(OCAML_LIB_INSTALL)
 11.1120 +	for i in $(LIBINSTALL_FILES); do \
 11.1121 +	  if [ -f $$i ]; then \
 11.1122 +	    install -c -m 0644 $$i $(OCAML_LIB_INSTALL); \
 11.1123 +	  fi; \
 11.1124 +	done
 11.1125 +	$(QUIET)printf "\nInstallation successful.\n"
 11.1126 +
 11.1127 +.PHONY: rawuninstall
 11.1128 +rawuninstall:
 11.1129 +	$(QUIET)printf "\nUninstalling library from: $(OCAML_LIB_INSTALL)\n"
 11.1130 +	cd $(OCAML_LIB_INSTALL) && rm $(notdir $(LIBINSTALL_FILES))
 11.1131 +	$(QUIET)printf "\nUninstallation successful.\n"
 11.1132 +
 11.1133 +###########################################################################
 11.1134 +# MAINTAINANCE RULES
 11.1135 +
 11.1136 +.PHONY:	clean
 11.1137 +clean::
 11.1138 +	rm -f $(TARGETS) $(TRASH)
 11.1139 +	rm -rf $(BCDIDIR) $(NCDIDIR) $(MLDEPDIR)
 11.1140 +
 11.1141 +.PHONY:	cleanup
 11.1142 +cleanup::
 11.1143 +	rm -f $(NONEXECS) $(TRASH)
 11.1144 +	rm -rf $(BCDIDIR) $(NCDIDIR) $(MLDEPDIR)
 11.1145 +
 11.1146 +.PHONY: clean-doc
 11.1147 +clean-doc::
 11.1148 +	rm -rf doc
 11.1149 +
 11.1150 +.PHONY: nobackup
 11.1151 +nobackup:
 11.1152 +	rm -f *.bak *~ *.dup
    12.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    12.2 +++ b/tools/pdb/PDB.ml	Fri Jun 03 21:18:14 2005 +0000
    12.3 @@ -0,0 +1,180 @@
    12.4 +(** PDB.ml
    12.5 + *
    12.6 + *  Dispatch debugger commands to the appropriate context
    12.7 + *
    12.8 + *  @author copyright (c) 2005 alex ho
    12.9 + *  @see <www.cl.cam.ac.uk/netos/pdb> pervasive debugger
   12.10 + *  @version 1
   12.11 + *)
   12.12 +
   12.13 +exception Unimplemented of string
   12.14 +exception Unknown_context of string
   12.15 +exception Unknown_domain
   12.16 +
   12.17 +type context_t =
   12.18 +  | Void
   12.19 +  | Event_channel
   12.20 +  | Domain of Domain.context_t
   12.21 +  | Process of Process.context_t
   12.22 +
   12.23 +let string_of_context ctx =
   12.24 +  match ctx with
   12.25 +  | Void -> "{void}"
   12.26 +  | Event_channel -> "{event channel}"
   12.27 +  | Domain d  -> Domain.string_of_context d
   12.28 +  | Process p -> Process.string_of_context p
   12.29 +
   12.30 +
   12.31 +
   12.32 +let read_registers ctx =
   12.33 +  match ctx with
   12.34 +  | Domain d  -> Domain.read_registers d 
   12.35 +  | _ -> Intel.null_registers
   12.36 +
   12.37 +let write_register ctx register value =
   12.38 +  match ctx with
   12.39 +  | Domain d  -> Domain.write_register d register value
   12.40 +  | _ -> raise (Unimplemented "write register")
   12.41 +
   12.42 +
   12.43 +let read_memory ctx addr len =
   12.44 +  match ctx with
   12.45 +  | Domain d  -> Domain.read_memory d addr len
   12.46 +  | _ -> raise (Unimplemented "read memory")
   12.47 +
   12.48 +let write_memory ctx addr values =
   12.49 +  match ctx with
   12.50 +  | Domain d  -> Domain.write_memory d addr values
   12.51 +  | _ -> raise (Unimplemented "write memory")
   12.52 +
   12.53 +
   12.54 +let continue ctx =
   12.55 +  match ctx with
   12.56 +  | Domain d  -> Domain.continue d
   12.57 +  | _ -> raise (Unimplemented "continue")
   12.58 +
   12.59 +let step ctx =
   12.60 +  match ctx with
   12.61 +  | Domain d  -> Domain.step d
   12.62 +  | _ -> raise (Unimplemented "step")
   12.63 +
   12.64 +
   12.65 +let insert_memory_breakpoint ctx addr len =
   12.66 +  match ctx with
   12.67 +  | Domain d  -> Domain.insert_memory_breakpoint d addr len
   12.68 +  | _ -> raise (Unimplemented "insert memory breakpoint")
   12.69 +
   12.70 +let remove_memory_breakpoint ctx addr len =
   12.71 +  match ctx with
   12.72 +  | Domain d  -> Domain.remove_memory_breakpoint d addr len
   12.73 +  | _ -> raise (Unimplemented "remove memory breakpoint")
   12.74 +
   12.75 +
   12.76 +let pause ctx =
   12.77 +  match ctx with
   12.78 +  | Domain d  -> Domain.pause d
   12.79 +  | _ -> raise (Unimplemented "pause target")
   12.80 +
   12.81 +
   12.82 +let attach_debugger ctx =
   12.83 +  match ctx with
   12.84 +  | Domain d  -> Domain.attach_debugger (Domain.get_domain d) 
   12.85 +	                                (Domain.get_execution_domain d)
   12.86 +  | _ -> raise (Unimplemented "attach debugger")
   12.87 +
   12.88 +let detach_debugger ctx =
   12.89 +  match ctx with
   12.90 +  | Domain d  -> Domain.detach_debugger (Domain.get_domain d) 
   12.91 +	                                (Domain.get_execution_domain d)
   12.92 +  | _ -> raise (Unimplemented "detach debugger")
   12.93 +
   12.94 +external open_debugger : unit -> unit = "open_context"
   12.95 +external close_debugger : unit -> unit = "close_context"
   12.96 +
   12.97 +(* this is just the domains right now... expand to other contexts later *)
   12.98 +external debugger_status : unit -> unit = "debugger_status"
   12.99 +
  12.100 +
  12.101 +(***********************************************************)
  12.102 +
  12.103 +
  12.104 +let hash = Hashtbl.create 10
  12.105 +
  12.106 +let debug_contexts () =
  12.107 +  print_endline "context list:";
  12.108 +  let print_context key ctx = 
  12.109 +    match ctx with
  12.110 +    | Void -> print_endline (Printf.sprintf "  [%s] {void}" 
  12.111 +			       (Util.get_connection_info key))
  12.112 +    | Event_channel -> print_endline (Printf.sprintf "  [%s] {event_channel}" 
  12.113 +			       (Util.get_connection_info key))
  12.114 +    | Process p -> print_endline (Printf.sprintf "  [%s] %s" 
  12.115 +				    (Util.get_connection_info key)
  12.116 +				    (Process.string_of_context p))
  12.117 +    | Domain d -> print_endline (Printf.sprintf "  [%s] %s" 
  12.118 +				   (Util.get_connection_info key)
  12.119 +				   (Domain.string_of_context d))
  12.120 +  in
  12.121 +  Hashtbl.iter print_context hash
  12.122 +
  12.123 +(** add_context : add a new context to the hash table.
  12.124 + *  if there is an existing context for the same key then it 
  12.125 + *  is first removed implictly by the hash table replace function.
  12.126 + *)
  12.127 +let add_context (key:Unix.file_descr) context params =
  12.128 +  match context with
  12.129 +  | "void" -> Hashtbl.replace hash key Void
  12.130 +  | "event channel" -> Hashtbl.replace hash key Event_channel
  12.131 +  | "domain" -> 
  12.132 +      begin
  12.133 +	match params with
  12.134 +	| dom::exec_dom::_ ->
  12.135 +            let d = Domain(Domain.new_context dom exec_dom) in
  12.136 +	    attach_debugger d;
  12.137 +            Hashtbl.replace hash key d
  12.138 +	| _ -> failwith "bogus parameters to domain context"
  12.139 +      end
  12.140 +  | "process" -> 
  12.141 +      begin
  12.142 +	match params with
  12.143 +	| dom::pid::_ ->
  12.144 +	    let p = Process.new_context dom pid in
  12.145 +	    Hashtbl.replace hash key (Process(p))
  12.146 +	| _ -> failwith "bogus parameters to process context"
  12.147 +      end
  12.148 +  | _ -> raise (Unknown_context context)
  12.149 +
  12.150 +let add_default_context sock =
  12.151 +  add_context sock "void" []
  12.152 +
  12.153 +let find_context key =
  12.154 +  try
  12.155 +    Hashtbl.find hash key
  12.156 +  with
  12.157 +    Not_found ->
  12.158 +      print_endline "error: (find_context) PDB context not found";
  12.159 +      raise Not_found
  12.160 +
  12.161 +let delete_context key =
  12.162 +  Hashtbl.remove hash key
  12.163 +
  12.164 +(** find_domain : Locate the context(s) matching a particular domain 
  12.165 + *  and execution_domain pair.
  12.166 + *)
  12.167 +
  12.168 +let find_domain dom exec_dom =
  12.169 +    let find key ctx list =
  12.170 +      match ctx with
  12.171 +      |	Domain d ->
  12.172 +	  if (((Domain.get_domain d) = dom) &&
  12.173 +	      ((Domain.get_execution_domain d) = exec_dom))
  12.174 +	  then
  12.175 +	    key :: list
  12.176 +	  else
  12.177 +	    list
  12.178 +      | _ -> list
  12.179 +    in
  12.180 +    let sock_list = Hashtbl.fold find hash [] in
  12.181 +    match sock_list with
  12.182 +    | hd::tl -> hd
  12.183 +    | [] -> raise Unknown_domain
    13.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    13.2 +++ b/tools/pdb/Process.ml	Fri Jun 03 21:18:14 2005 +0000
    13.3 @@ -0,0 +1,39 @@
    13.4 +(** Process.ml
    13.5 + *
    13.6 + *  process context implementation
    13.7 + *
    13.8 + *  @author copyright (c) 2005 alex ho
    13.9 + *  @see <www.cl.cam.ac.uk/netos/pdb> pervasive debugger
   13.10 + *  @version 1
   13.11 + *)
   13.12 +
   13.13 +open Int32
   13.14 +open Intel
   13.15 +
   13.16 +type context_t =
   13.17 +{
   13.18 +  mutable domain : int;
   13.19 +  mutable process : int;
   13.20 +}
   13.21 +
   13.22 +let default_context = { domain = 0; process = 0 }
   13.23 +
   13.24 +let new_context dom proc = { domain = dom; process = proc }
   13.25 +
   13.26 +let string_of_context ctx =
   13.27 +  Printf.sprintf "{process} domain: %d, process: %d"
   13.28 +                 ctx.domain  ctx.process
   13.29 +
   13.30 +let set_domain ctx value =
   13.31 +  ctx.domain <- value;
   13.32 +  print_endline (Printf.sprintf "ctx.domain <- %d" ctx.domain)
   13.33 +
   13.34 +let set_process ctx value =
   13.35 +  ctx.process <- value;
   13.36 +  print_endline (Printf.sprintf "ctx.process <- %d" ctx.process)
   13.37 +
   13.38 +let get_domain ctx =
   13.39 +  ctx.domain
   13.40 +
   13.41 +let get_process ctx =
   13.42 +  ctx.process
    14.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    14.2 +++ b/tools/pdb/Process.mli	Fri Jun 03 21:18:14 2005 +0000
    14.3 @@ -0,0 +1,20 @@
    14.4 +(** Process.mli
    14.5 + *
    14.6 + *  process context interface
    14.7 + *
    14.8 + *  @author copyright (c) 2005 alex ho
    14.9 + *  @see <www.cl.cam.ac.uk/netos/pdb> pervasive debugger
   14.10 + *  @version 1
   14.11 + *)
   14.12 +
   14.13 +type context_t
   14.14 +
   14.15 +val default_context : context_t
   14.16 +val new_context : int -> int -> context_t
   14.17 +
   14.18 +val set_domain : context_t -> int -> unit
   14.19 +val get_domain : context_t -> int
   14.20 +val set_process : context_t -> int -> unit
   14.21 +val get_process : context_t -> int
   14.22 +
   14.23 +val string_of_context : context_t -> string
    15.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    15.2 +++ b/tools/pdb/Util.ml	Fri Jun 03 21:18:14 2005 +0000
    15.3 @@ -0,0 +1,153 @@
    15.4 +(** Util.ml
    15.5 + *
    15.6 + *  various utility functions
    15.7 + *
    15.8 + *  @author copyright (c) 2005 alex ho
    15.9 + *  @see <www.cl.cam.ac.uk/netos/pdb> pervasive debugger
   15.10 + *  @version 1
   15.11 + *)
   15.12 +
   15.13 +let int_of_hexchar h = 
   15.14 +  let i = int_of_char h in
   15.15 +  match h with
   15.16 +  | '0' .. '9' -> i - (int_of_char '0')
   15.17 +  | 'a' .. 'f' -> i - (int_of_char 'a') + 10
   15.18 +  | 'A' .. 'F' -> i - (int_of_char 'A') + 10
   15.19 +  | _ -> raise (Invalid_argument "unknown hex character")
   15.20 +
   15.21 +let hexchar_of_int i = 
   15.22 +  let hexchars = [| '0'; '1'; '2'; '3'; '4'; '5'; '6'; '7';
   15.23 +		    '8'; '9'; 'a'; 'b'; 'c'; 'd'; 'e'; 'f' |]
   15.24 +  in
   15.25 +  hexchars.(i)
   15.26 +
   15.27 +
   15.28 +(** flip the bytes of a four byte int 
   15.29 + *)
   15.30 +
   15.31 +let flip_int num =
   15.32 +  let a = num mod 256
   15.33 +  and b = (num / 256) mod 256
   15.34 +  and c = (num / (256 * 256)) mod 256
   15.35 +  and d = (num / (256 * 256 * 256)) in
   15.36 +  (a * 256 * 256 * 256) + (b * 256 * 256) + (c * 256) + d
   15.37 +
   15.38 +    
   15.39 +let flip_int32 num =
   15.40 +  let a = Int32.logand num 0xffl
   15.41 +  and b = Int32.logand (Int32.shift_right_logical num 8)  0xffl
   15.42 +  and c = Int32.logand (Int32.shift_right_logical num 16) 0xffl
   15.43 +  and d =              (Int32.shift_right_logical num 24)       in
   15.44 +  (Int32.logor
   15.45 +     (Int32.logor (Int32.shift_left a 24) (Int32.shift_left b 16))
   15.46 +     (Int32.logor (Int32.shift_left c 8)  d))
   15.47 +
   15.48 +
   15.49 +let int_list_of_string_list list =
   15.50 +  List.map (fun x -> int_of_string x) list
   15.51 +    
   15.52 +let int_list_of_string str len =
   15.53 +  let array_of_string s =
   15.54 +    let int_array = Array.make len 0 in
   15.55 +    for loop = 0 to len - 1 do
   15.56 +      int_array.(loop) <- (Char.code s.[loop]);
   15.57 +    done;
   15.58 +    int_array
   15.59 +  in
   15.60 +  Array.to_list (array_of_string str)
   15.61 +
   15.62 +
   15.63 +(* remove leading and trailing whitespace from a string *)
   15.64 +
   15.65 +let chomp str =
   15.66 +  let head = Str.regexp "^[ \t\r\n]+" in
   15.67 +  let tail = Str.regexp "[ \t\r\n]+$" in
   15.68 +  let str = Str.global_replace head "" str in
   15.69 +  Str.global_replace tail "" str
   15.70 +
   15.71 +(* Stupid little parser for    "<key>=<value>[,<key>=<value>]*"
   15.72 +   It first chops the entire command at each ',', so no ',' in key or value!
   15.73 +   Mucked to return a list of words for "value"
   15.74 + *)
   15.75 +
   15.76 +let list_of_string str =
   15.77 +  let delim c = Str.regexp ("[ \t]*" ^ c ^ "[ \t]*") in
   15.78 +  let str_list = Str.split (delim " ") str in
   15.79 +  List.map (fun x -> chomp(x)) str_list
   15.80 +
   15.81 +let little_parser fn str =
   15.82 +  let delim c = Str.regexp ("[ \t]*" ^ c ^ "[ \t]*") in
   15.83 +  let str_list = Str.split (delim ",") str in
   15.84 +  let pair s =
   15.85 +    match Str.split (delim "=") s with
   15.86 +    | [key;value] -> fn (chomp key) (list_of_string value)
   15.87 +    | [key] -> fn (chomp key) []
   15.88 +    | _ -> failwith (Printf.sprintf "error: (little_parser) parse error [%s]" str)
   15.89 +  in
   15.90 +  List.iter pair str_list
   15.91 +
   15.92 +(* boolean list membership test *)
   15.93 +let not_list_member the_list element =
   15.94 +  try 
   15.95 +    List.find (fun x -> x = element) the_list;
   15.96 +    false
   15.97 +  with
   15.98 +    Not_found -> true
   15.99 +
  15.100 +(* a very inefficient way to remove the elements of one list from another *)
  15.101 +let list_remove the_list remove_list =
  15.102 +  List.filter (not_list_member remove_list) the_list
  15.103 +
  15.104 +(* get a description of a file descriptor *)
  15.105 +let get_connection_info fd =
  15.106 +  let get_local_info fd =
  15.107 +    let sockname = Unix.getsockname fd in
  15.108 +    match sockname with
  15.109 +    | Unix.ADDR_UNIX(s) -> s
  15.110 +    | Unix.ADDR_INET(a,p) -> ((Unix.string_of_inet_addr a) ^ ":" ^
  15.111 +			      (string_of_int p))
  15.112 +  and get_remote_info fd =
  15.113 +    let sockname = Unix.getpeername fd in 
  15.114 +    match sockname with
  15.115 +    | Unix.ADDR_UNIX(s) -> s
  15.116 +    | Unix.ADDR_INET(a,p) -> ((Unix.string_of_inet_addr a) ^ ":" ^
  15.117 +			      (string_of_int p))
  15.118 +  in
  15.119 +  try
  15.120 +    get_remote_info fd
  15.121 +  with
  15.122 +  | Unix.Unix_error (Unix.ENOTSOCK, s1, s2) -> 
  15.123 +      let s = Unix.fstat fd in
  15.124 +      Printf.sprintf "dev: %d, inode: %d" s.Unix.st_dev s.Unix.st_ino
  15.125 +  | _ -> get_local_info fd
  15.126 +
  15.127 +
  15.128 +(* really write a string *)
  15.129 +let really_write fd str =
  15.130 +  let strlen = String.length str in
  15.131 +  let sent = ref 0 in
  15.132 +  while (!sent < strlen) do
  15.133 +    sent := !sent + (Unix.write fd str !sent (strlen - !sent))
  15.134 +  done
  15.135 +
  15.136 +let write_character fd ch =
  15.137 +  let str = String.create 1 in
  15.138 +  str.[0] <- ch;
  15.139 +  really_write fd str
  15.140 +
  15.141 +
  15.142 +
  15.143 +let send_reply fd reply =
  15.144 +  let checksum = ref 0 in
  15.145 +  write_character fd '$';
  15.146 +  for loop = 0 to (String.length reply) - 1 do
  15.147 +    write_character fd reply.[loop];
  15.148 +    checksum := !checksum + int_of_char reply.[loop]
  15.149 +  done;
  15.150 +  write_character fd '#';
  15.151 +  write_character fd (hexchar_of_int ((!checksum mod 256) / 16));
  15.152 +  write_character fd (hexchar_of_int ((!checksum mod 256) mod 16))
  15.153 +  (*
  15.154 +   * BUG NEED TO LISTEN FOR REPLY +/- AND POSSIBLY RE-TRANSMIT
  15.155 +   *)
  15.156 +
    16.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    16.2 +++ b/tools/pdb/debugger.ml	Fri Jun 03 21:18:14 2005 +0000
    16.3 @@ -0,0 +1,315 @@
    16.4 +(** debugger.ml
    16.5 + *
    16.6 + *  main debug functionality
    16.7 + *
    16.8 + *  @author copyright (c) 2005 alex ho
    16.9 + *  @see <www.cl.cam.ac.uk/netos/pdb> pervasive debugger
   16.10 + *  @version 1
   16.11 + *)
   16.12 +
   16.13 +open Intel
   16.14 +open PDB
   16.15 +open Util
   16.16 +open Str
   16.17 +
   16.18 +(** a few debugger commands such as step 's' and continue 'c' do 
   16.19 + *  not immediately return a response to the debugger.  in these 
   16.20 + *  cases we raise No_reply instead. 
   16.21 + *)
   16.22 +exception No_reply
   16.23 +
   16.24 +let initialize_debugger () =
   16.25 +  ()
   16.26 +
   16.27 +let exit_debugger () =
   16.28 +  ()
   16.29 +
   16.30 +
   16.31 +(**
   16.32 +   Detach Command
   16.33 +   Note: response is ignored by gdb.  We leave the context in the
   16.34 +   hash.  It will be cleaned up with the socket is closed.
   16.35 + *)
   16.36 +let gdb_detach ctx =
   16.37 +  PDB.detach_debugger ctx;
   16.38 +  raise No_reply
   16.39 +
   16.40 +(**
   16.41 +   Kill Command
   16.42 +   Note: response is ignored by gdb.  We leave the context in the
   16.43 +   hash.  It will be cleaned up with the socket is closed.
   16.44 + *)
   16.45 +let gdb_kill () =
   16.46 +  ""
   16.47 +
   16.48 +
   16.49 +
   16.50 +(**
   16.51 +   Continue Command.
   16.52 +   resume the target
   16.53 + *)
   16.54 +let gdb_continue ctx =
   16.55 +  PDB.continue ctx;
   16.56 +  raise No_reply
   16.57 +
   16.58 +(**
   16.59 +   Step Command.
   16.60 +   single step the target
   16.61 + *)
   16.62 +let gdb_step ctx =
   16.63 +  PDB.step ctx;
   16.64 +  raise No_reply
   16.65 +
   16.66 +
   16.67 +(**
   16.68 +   Read Registers Command.
   16.69 +   returns 16 4-byte registers in a particular defined by gdb.
   16.70 + *)
   16.71 +let gdb_read_registers ctx =
   16.72 +  let regs = PDB.read_registers ctx in
   16.73 +  let str = 
   16.74 +    (Printf.sprintf "%08lx" (Util.flip_int32 regs.eax)) ^
   16.75 +    (Printf.sprintf "%08lx" (Util.flip_int32 regs.ecx)) ^
   16.76 +    (Printf.sprintf "%08lx" (Util.flip_int32 regs.edx)) ^
   16.77 +    (Printf.sprintf "%08lx" (Util.flip_int32 regs.ebx)) ^
   16.78 +    (Printf.sprintf "%08lx" (Util.flip_int32 regs.esp)) ^
   16.79 +    (Printf.sprintf "%08lx" (Util.flip_int32 regs.ebp)) ^
   16.80 +    (Printf.sprintf "%08lx" (Util.flip_int32 regs.esi)) ^
   16.81 +    (Printf.sprintf "%08lx" (Util.flip_int32 regs.edi)) ^
   16.82 +    (Printf.sprintf "%08lx" (Util.flip_int32 regs.eip)) ^
   16.83 +    (Printf.sprintf "%08lx" (Util.flip_int32 regs.eflags)) ^
   16.84 +    (Printf.sprintf "%08lx" (Util.flip_int32 regs.cs)) ^
   16.85 +    (Printf.sprintf "%08lx" (Util.flip_int32 regs.ss)) ^
   16.86 +    (Printf.sprintf "%08lx" (Util.flip_int32 regs.ds)) ^
   16.87 +    (Printf.sprintf "%08lx" (Util.flip_int32 regs.es)) ^
   16.88 +    (Printf.sprintf "%08lx" (Util.flip_int32 regs.fs)) ^
   16.89 +    (Printf.sprintf "%08lx" (Util.flip_int32 regs.gs)) in
   16.90 +  str
   16.91 +      
   16.92 +(**
   16.93 +   Set Thread Command
   16.94 + *)
   16.95 +let gdb_set_thread command =
   16.96 +  "OK"
   16.97 +
   16.98 +
   16.99 +(**
  16.100 +   Read Memory Packets
  16.101 + *)
  16.102 +let gdb_read_memory ctx command =
  16.103 +  let int_list_to_string i str =
  16.104 +    (Printf.sprintf "%02x" i) ^ str
  16.105 +  in
  16.106 +  let read_mem addr len =
  16.107 +    try
  16.108 +      let mem = PDB.read_memory ctx addr len  in
  16.109 +      List.fold_right int_list_to_string mem ""
  16.110 +    with
  16.111 +      Failure s -> "E02"
  16.112 +  in
  16.113 +  Scanf.sscanf command "m%lx,%d" read_mem
  16.114 +
  16.115 +
  16.116 +
  16.117 +(**
  16.118 +   Write Memory Packets
  16.119 + *)
  16.120 +let gdb_write_memory ctx command =
  16.121 +  let write_mem addr len =
  16.122 +    print_endline (Printf.sprintf "  gdb_write_memory %lx %x\n" addr len);
  16.123 +    print_endline (Printf.sprintf "  [[ unimplemented ]]\n")
  16.124 +  in
  16.125 +  Scanf.sscanf command "M%lx,%d" write_mem;
  16.126 +  "OK"
  16.127 +
  16.128 +
  16.129 +
  16.130 +(**
  16.131 +   Write Register Packets
  16.132 + *)
  16.133 +let gdb_write_register ctx command =
  16.134 +  let write_reg reg goofy_val =
  16.135 +    let new_val = Util.flip_int32 goofy_val in
  16.136 +    match reg with
  16.137 +    |  0 -> PDB.write_register ctx EAX new_val
  16.138 +    |  1 -> PDB.write_register ctx ECX new_val
  16.139 +    |  2 -> PDB.write_register ctx EDX new_val
  16.140 +    |  3 -> PDB.write_register ctx EBX new_val
  16.141 +    |  4 -> PDB.write_register ctx ESP new_val
  16.142 +    |  5 -> PDB.write_register ctx EBP new_val
  16.143 +    |  6 -> PDB.write_register ctx ESI new_val
  16.144 +    |  7 -> PDB.write_register ctx EDI new_val
  16.145 +    |  8 -> PDB.write_register ctx EIP new_val
  16.146 +    |  9 -> PDB.write_register ctx EFLAGS new_val
  16.147 +    | 10 -> PDB.write_register ctx CS new_val
  16.148 +    | 11 -> PDB.write_register ctx SS new_val
  16.149 +    | 12 -> PDB.write_register ctx DS new_val
  16.150 +    | 13 -> PDB.write_register ctx ES new_val
  16.151 +    | 14 -> PDB.write_register ctx FS new_val
  16.152 +    | 15 -> PDB.write_register ctx GS new_val
  16.153 +    | _  -> print_endline (Printf.sprintf "write unknown register [%d]" reg)
  16.154 +  in
  16.155 +  Scanf.sscanf command "P%x=%lx" write_reg;
  16.156 +  "OK"
  16.157 +
  16.158 +
  16.159 +(**
  16.160 +   General Query Packets
  16.161 + *)
  16.162 +let gdb_query command =
  16.163 +  match command with
  16.164 +  | "qC" -> ""
  16.165 +  | "qOffsets" -> ""
  16.166 +  | "qSymbol::" -> ""
  16.167 +  | _ -> 
  16.168 +      print_endline (Printf.sprintf "unknown gdb query packet [%s]" command);
  16.169 +      "E01"
  16.170 +
  16.171 +
  16.172 +(**
  16.173 +   Write Memory Binary Packets
  16.174 + *)
  16.175 +let gdb_write_memory_binary ctx command =
  16.176 +  let write_mem addr len =
  16.177 +    let pos = Str.search_forward (Str.regexp ":") command 0 in
  16.178 +    let txt = Str.string_after command (pos + 1) in
  16.179 +    PDB.write_memory ctx addr (int_list_of_string txt len)
  16.180 +  in
  16.181 +  Scanf.sscanf command "X%lx,%d" write_mem;
  16.182 +  "OK"
  16.183 +
  16.184 +
  16.185 +
  16.186 +(**
  16.187 +   Last Signal Command
  16.188 + *)
  16.189 +let gdb_last_signal =
  16.190 +  "S00"
  16.191 +
  16.192 +
  16.193 +
  16.194 +
  16.195 +(**
  16.196 +   Process PDB extensions to the GDB serial protocol.
  16.197 +   Changes the mutable context state.
  16.198 + *)
  16.199 +let pdb_extensions command sock =
  16.200 +  let process_extension key value =
  16.201 +    (* since this command can change the context, we need to grab it each time *)
  16.202 +    let ctx = PDB.find_context sock in
  16.203 +    match key with
  16.204 +    | "status" ->
  16.205 +	print_endline (string_of_context ctx);
  16.206 +	PDB.debug_contexts ();
  16.207 +	debugger_status ()
  16.208 +    | "context" ->
  16.209 +        PDB.add_context sock (List.hd value) 
  16.210 +                             (int_list_of_string_list (List.tl value))
  16.211 +    | _ -> failwith (Printf.sprintf "unknown pdb extension command [%s:%s]" 
  16.212 +		                    key (List.hd value))
  16.213 +  in
  16.214 +  try
  16.215 +    Util.little_parser process_extension 
  16.216 +                       (String.sub command 1 ((String.length command) - 1));
  16.217 +    "OK"
  16.218 +  with
  16.219 +  | Unknown_context s -> 
  16.220 +      print_endline (Printf.sprintf "unknown context [%s]" s);
  16.221 +      "E01"
  16.222 +  | Failure s -> "E01"
  16.223 +
  16.224 +
  16.225 +(**
  16.226 +   Insert Breakpoint or Watchpoint Packet
  16.227 + *)
  16.228 +let gdb_insert_bwcpoint ctx command =
  16.229 +  let insert cmd addr length =
  16.230 +    try
  16.231 +      match cmd with
  16.232 +      | 0 -> PDB.insert_memory_breakpoint ctx addr length; "OK"
  16.233 +      | _ -> ""
  16.234 +    with
  16.235 +      Failure s -> "E03"
  16.236 +  in
  16.237 +  Scanf.sscanf command "Z%d,%lx,%d" insert
  16.238 +
  16.239 +(**
  16.240 +   Remove Breakpoint or Watchpoint Packet
  16.241 + *)
  16.242 +let gdb_remove_bwcpoint ctx command =
  16.243 +  let insert cmd addr length =
  16.244 +    try
  16.245 +      match cmd with
  16.246 +      | 0 -> PDB.remove_memory_breakpoint ctx addr length; "OK"
  16.247 +      | _ -> ""
  16.248 +    with
  16.249 +      Failure s -> "E04"
  16.250 +  in
  16.251 +  Scanf.sscanf command "z%d,%lx,%d" insert
  16.252 +
  16.253 +(**
  16.254 +   Do Work!
  16.255 +
  16.256 +   @param command  char list
  16.257 + *)
  16.258 +
  16.259 +let process_command command sock =
  16.260 +  let ctx = PDB.find_context sock in
  16.261 +  try
  16.262 +    match command.[0] with
  16.263 +    | 'c' -> gdb_continue ctx
  16.264 +    | 'D' -> gdb_detach ctx
  16.265 +    | 'g' -> gdb_read_registers ctx
  16.266 +    | 'H' -> gdb_set_thread command
  16.267 +    | 'k' -> gdb_kill ()
  16.268 +    | 'm' -> gdb_read_memory ctx command
  16.269 +    | 'M' -> gdb_write_memory ctx command
  16.270 +    | 'P' -> gdb_write_register ctx command
  16.271 +    | 'q' -> gdb_query command
  16.272 +    | 's' -> gdb_step ctx
  16.273 +    | 'x' -> pdb_extensions command sock
  16.274 +    | 'X' -> gdb_write_memory_binary ctx command
  16.275 +    | '?' -> gdb_last_signal
  16.276 +    | 'z' -> gdb_remove_bwcpoint ctx command
  16.277 +    | 'Z' -> gdb_insert_bwcpoint ctx command
  16.278 +    | _ -> 
  16.279 +	print_endline (Printf.sprintf "unknown gdb command [%s]" command);
  16.280 +	""
  16.281 +  with
  16.282 +    Unimplemented s ->
  16.283 +      print_endline (Printf.sprintf "loser. unimplemented command [%s][%s]" 
  16.284 +		                    command s);
  16.285 +      ""
  16.286 +
  16.287 +
  16.288 +(**
  16.289 +   process_evtchn  
  16.290 +
  16.291 +   This is called each time a virq_pdb is sent from xen to dom 0.
  16.292 +   It is sent by Xen when a domain hits a breakpoint. 
  16.293 +
  16.294 +   Think of this as the continuation function for a "c" or "s" command.
  16.295 +*)
  16.296 +
  16.297 +external query_domain_stop : unit -> (int * int) list = "query_domain_stop"
  16.298 +(* returns a list of paused domains : () -> (domain, vcpu) list *)
  16.299 +
  16.300 +let process_evtchn fd =
  16.301 +  let channel = Evtchn.read fd in
  16.302 +  let find_pair (dom, vcpu) =
  16.303 +    print_endline (Printf.sprintf "checking %d.%d" dom vcpu);
  16.304 +    try
  16.305 +      let sock = PDB.find_domain dom vcpu in
  16.306 +      true
  16.307 +    with
  16.308 +      Unknown_domain -> false
  16.309 +  in
  16.310 +  let dom_list = query_domain_stop () in
  16.311 +  let (dom, vcpu) = List.find find_pair dom_list in
  16.312 +  let vec = 3 in
  16.313 +  let sock = PDB.find_domain dom vcpu in
  16.314 +  print_endline (Printf.sprintf "handle bkpt d:%d ed:%d v:%d  %s" 
  16.315 +		   dom vcpu vec (Util.get_connection_info sock));
  16.316 +  Util.send_reply sock "S05";
  16.317 +  Evtchn.unmask fd channel                                (* allow next virq *)
  16.318 +  
    17.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    17.2 +++ b/tools/pdb/evtchn.ml	Fri Jun 03 21:18:14 2005 +0000
    17.3 @@ -0,0 +1,32 @@
    17.4 +(** evtchn.ml
    17.5 + *
    17.6 + *  event channel interface
    17.7 + *
    17.8 + *  @author copyright (c) 2005 alex ho
    17.9 + *  @see <www.cl.cam.ac.uk/netos/pdb> pervasive debugger
   17.10 + *  @version 1
   17.11 + *)
   17.12 +
   17.13 +let dev_name = "/dev/xen/evtchn"                          (* EVTCHN_DEV_NAME *)
   17.14 +let dev_major = 10                                       (* EVTCHN_DEV_MAJOR *)
   17.15 +let dev_minor = 201                                      (* EVTCHN_DEV_MINOR *)
   17.16 +
   17.17 +let virq_pdb = 6                                      (* as defined VIRQ_PDB *)
   17.18 +
   17.19 +external bind_virq : int -> int = "evtchn_bind_virq"
   17.20 +external bind : Unix.file_descr -> int -> unit = "evtchn_bind"
   17.21 +external unbind : Unix.file_descr -> int -> unit = "evtchn_unbind"
   17.22 +external ec_open : string -> int -> int -> Unix.file_descr = "evtchn_open"
   17.23 +external read : Unix.file_descr -> int = "evtchn_read"
   17.24 +external ec_close : Unix.file_descr -> unit = "evtchn_close"
   17.25 +external unmask : Unix.file_descr -> int -> unit = "evtchn_unmask"
   17.26 +
   17.27 +let setup () =
   17.28 +  let port = bind_virq virq_pdb in
   17.29 +  let fd = ec_open dev_name dev_major dev_minor in
   17.30 +  bind fd port;
   17.31 +  fd
   17.32 +
   17.33 +let teardown fd =
   17.34 +  unbind fd virq_pdb;
   17.35 +  ec_close fd
    18.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    18.2 +++ b/tools/pdb/evtchn.mli	Fri Jun 03 21:18:14 2005 +0000
    18.3 @@ -0,0 +1,14 @@
    18.4 +(** evtchn.mli
    18.5 + *
    18.6 + *  event channel interface
    18.7 + *
    18.8 + *  @author copyright (c) 2005 alex ho
    18.9 + *  @see <www.cl.cam.ac.uk/netos/pdb> pervasive debugger
   18.10 + *  @version 1
   18.11 + *)
   18.12 +
   18.13 +
   18.14 +val setup : unit -> Unix.file_descr
   18.15 +val read : Unix.file_descr -> int
   18.16 +val teardown : Unix.file_descr -> unit
   18.17 +val unmask : Unix.file_descr -> int -> unit
    19.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    19.2 +++ b/tools/pdb/pdb_caml_xc.c	Fri Jun 03 21:18:14 2005 +0000
    19.3 @@ -0,0 +1,732 @@
    19.4 +/*
    19.5 + * pdb_caml_xc.c
    19.6 + *
    19.7 + * http://www.cl.cam.ac.uk/netos/pdb
    19.8 + *
    19.9 + * OCaml to libxc interface library for PDB
   19.10 + */
   19.11 +
   19.12 +#include <xc.h>
   19.13 +#include <xc_debug.h>
   19.14 +#include <errno.h>
   19.15 +#include <stdio.h>
   19.16 +#include <stdlib.h>
   19.17 +#include <string.h>
   19.18 +#include <sys/mman.h>
   19.19 +#include <caml/alloc.h>
   19.20 +#include <caml/fail.h>
   19.21 +#include <caml/memory.h>
   19.22 +#include <caml/mlvalues.h>
   19.23 +
   19.24 +int pdb_evtchn_bind_virq (int xc_handle, int virq, int *port);
   19.25 +int xen_evtchn_bind (int evtchn_fd, int idx);
   19.26 +int xen_evtchn_unbind (int evtchn_fd, int idx);
   19.27 +
   19.28 +/* this order comes from xen/include/public/arch-x86_32.h */
   19.29 +enum x86_registers { PDB_EBX, PDB_ECX, PDB_EDX, PDB_ESI, PDB_EDI,
   19.30 +                     PDB_EBP, PDB_EAX, PDB_Error_code, PDB_Entry_vector, 
   19.31 +                     PDB_EIP, PDB_CS, PDB_EFLAGS, PDB_ESP, PDB_SS,
   19.32 +                     PDB_ES, PDB_DS, PDB_FS, PDB_GS };
   19.33 +
   19.34 +static void dump_regs (cpu_user_regs_t *ctx);
   19.35 +
   19.36 +static int xc_handle = -1;
   19.37 +
   19.38 +typedef struct
   19.39 +{
   19.40 +    int domain;
   19.41 +    int vcpu;
   19.42 +} context_t;
   19.43 +
   19.44 +#define decode_context(_ctx, _ocaml)   \
   19.45 +{  \
   19.46 +    (_ctx)->domain = Int_val(Field((_ocaml),0));  \
   19.47 +    (_ctx)->vcpu = Int_val(Field((_ocaml),1));  \
   19.48 +}
   19.49 +
   19.50 +#define encode_context(_ctx, _ocaml)  \
   19.51 +{  \
   19.52 +    (_ocaml) = caml_alloc_tuple(2);  \
   19.53 +    Store_field((_ocaml), 0, Val_int((_ctx)->domain));  \
   19.54 +    Store_field((_ocaml), 1, Val_int((_ctx)->vcpu));  \
   19.55 +}
   19.56 +
   19.57 +
   19.58 +/****************************************************************************/
   19.59 +
   19.60 +/*
   19.61 + * open_context : unit -> unit
   19.62 + */
   19.63 +value
   19.64 +open_context (value unit)
   19.65 +{
   19.66 +    CAMLparam1(unit);
   19.67 +
   19.68 +    xc_handle = xc_interface_open();
   19.69 +
   19.70 +    if ( xc_handle < 0 )
   19.71 +    {
   19.72 +        fprintf(stderr, "(pdb) error opening xc interface: %d (%s)\n",
   19.73 +                errno, strerror(errno));
   19.74 +    }
   19.75 +
   19.76 +    CAMLreturn(Val_unit);
   19.77 +}
   19.78 +
   19.79 +/*
   19.80 + * close_context : unit -> unit
   19.81 + */
   19.82 +value
   19.83 +close_context (value unit)
   19.84 +{
   19.85 +    CAMLparam1(unit);
   19.86 +    int rc;
   19.87 +    
   19.88 +    if ( (rc = xc_interface_close(xc_handle)) < 0 )
   19.89 +    {
   19.90 +        fprintf(stderr, "(pdb) error closing xc interface: %d (%s)\n",
   19.91 +                errno, strerror(errno));
   19.92 +    }
   19.93 +
   19.94 +    CAMLreturn(Val_unit);
   19.95 +}
   19.96 +
   19.97 +/*
   19.98 + * read_registers : context_t -> int32
   19.99 + */
  19.100 +value
  19.101 +read_registers (value context)
  19.102 +{
  19.103 +    CAMLparam1(context);
  19.104 +    CAMLlocal1(result);
  19.105 +
  19.106 +    cpu_user_regs_t *regs;
  19.107 +    context_t ctx;
  19.108 +
  19.109 +    decode_context(&ctx, context);
  19.110 +
  19.111 +    if ( xc_debug_read_registers(xc_handle, ctx.domain, ctx.vcpu, &regs) )
  19.112 +    {
  19.113 +        printf("(pdb) read registers error!\n");  fflush(stdout);
  19.114 +        failwith("read registers error");
  19.115 +    }
  19.116 +
  19.117 +    dump_regs(regs);
  19.118 +
  19.119 +    result = caml_alloc_tuple(18);                                  /* FIXME */
  19.120 +
  19.121 +    Store_field(result,  0, caml_copy_int32(regs->ebx));
  19.122 +    Store_field(result,  1, caml_copy_int32(regs->ecx));
  19.123 +    Store_field(result,  2, caml_copy_int32(regs->edx));
  19.124 +    Store_field(result,  3, caml_copy_int32(regs->esi));
  19.125 +    Store_field(result,  4, caml_copy_int32(regs->edi));
  19.126 +    Store_field(result,  5, caml_copy_int32(regs->ebp));
  19.127 +    Store_field(result,  6, caml_copy_int32(regs->eax));
  19.128 +    Store_field(result,  7, caml_copy_int32(regs->error_code));        /* 16 */
  19.129 +    Store_field(result,  8, caml_copy_int32(regs->entry_vector));      /* 16 */
  19.130 +    Store_field(result,  9, caml_copy_int32(regs->eip));
  19.131 +    Store_field(result, 10, caml_copy_int32(regs->cs));                /* 16 */
  19.132 +    Store_field(result, 11, caml_copy_int32(regs->eflags));
  19.133 +    Store_field(result, 12, caml_copy_int32(regs->esp));
  19.134 +    Store_field(result, 13, caml_copy_int32(regs->ss));                /* 16 */
  19.135 +    Store_field(result, 14, caml_copy_int32(regs->es));                /* 16 */
  19.136 +    Store_field(result, 15, caml_copy_int32(regs->ds));                /* 16 */
  19.137 +    Store_field(result, 16, caml_copy_int32(regs->fs));                /* 16 */
  19.138 +    Store_field(result, 17, caml_copy_int32(regs->gs));                /* 16 */
  19.139 +
  19.140 +    CAMLreturn(result);
  19.141 +}
  19.142 +
  19.143 +
  19.144 +/*
  19.145 + * write_register : context_t -> register -> int32 -> unit
  19.146 + */
  19.147 +value
  19.148 +write_register (value context, value reg, value newval)
  19.149 +{
  19.150 +    CAMLparam3(context, reg, newval);
  19.151 +
  19.152 +    int my_reg = Int_val(reg);
  19.153 +    int val = Int32_val(newval);
  19.154 +
  19.155 +    context_t ctx;
  19.156 +    cpu_user_regs_t *regs;
  19.157 +
  19.158 +    printf("(pdb) write register\n");
  19.159 +
  19.160 +    decode_context(&ctx, context);
  19.161 +
  19.162 +    if ( xc_debug_read_registers(xc_handle, ctx.domain, ctx.vcpu, &regs) )
  19.163 +    {
  19.164 +        printf("(pdb) write register (get) error!\n");  fflush(stdout);
  19.165 +        failwith("write register error");
  19.166 +    }
  19.167 +
  19.168 +    switch (my_reg)
  19.169 +    {
  19.170 +    case PDB_EBX: regs->ebx = val; break;
  19.171 +    case PDB_ECX: regs->ecx = val; break;
  19.172 +    case PDB_EDX: regs->edx = val; break;
  19.173 +    case PDB_ESI: regs->esi = val; break;
  19.174 +    case PDB_EDI: regs->edi = val; break;
  19.175 +
  19.176 +    case PDB_EBP: regs->ebp = val; break;
  19.177 +    case PDB_EAX: regs->eax = val; break;
  19.178 +    case PDB_Error_code: regs->error_code = val; break;
  19.179 +    case PDB_Entry_vector: regs->entry_vector = val; break;
  19.180 + 
  19.181 +    case PDB_EIP: regs->eip = val; break;
  19.182 +    case PDB_CS:  regs->cs  = val; break;
  19.183 +    case PDB_EFLAGS: regs->eflags = val; break;
  19.184 +    case PDB_ESP: regs->esp = val; break;
  19.185 +    case PDB_SS:  regs->ss  = val; break;
  19.186 +    case PDB_ES:  regs->es  = val; break;
  19.187 +    case PDB_DS:  regs->ds  = val; break;
  19.188 +    case PDB_FS:  regs->fs  = val; break;
  19.189 +    case PDB_GS:  regs->gs  = val; break;
  19.190 +    }
  19.191 +
  19.192 +    if ( xc_debug_write_registers(xc_handle, ctx.domain, ctx.vcpu, regs) )
  19.193 +    {
  19.194 +        printf("(pdb) write register (set) error!\n");  fflush(stdout);
  19.195 +        failwith("write register error");
  19.196 +    }
  19.197 +
  19.198 +    CAMLreturn(Val_unit);
  19.199 +}
  19.200 +
  19.201 +/*
  19.202 + * read_memory : context_t -> int32 -> int -> int
  19.203 + */
  19.204 +value
  19.205 +read_memory (value context, value address, value length)
  19.206 +{
  19.207 +    CAMLparam3(context, address, length);
  19.208 +    CAMLlocal2(result, temp);
  19.209 +
  19.210 +    context_t ctx;
  19.211 +    int loop;
  19.212 +    char *buffer;
  19.213 +    memory_t my_address = Int32_val(address);
  19.214 +    u32 my_length = Int_val(length);
  19.215 +
  19.216 +    printf ("(pdb) read memory\n");
  19.217 +
  19.218 +    decode_context(&ctx, context);
  19.219 +
  19.220 +    buffer = malloc(my_length);
  19.221 +    if (buffer == NULL)
  19.222 +    {
  19.223 +        printf("(pdb) read memory: malloc failed.\n");  fflush(stdout);
  19.224 +        failwith("read memory error");
  19.225 +    }
  19.226 +
  19.227 +    if ( xc_debug_read_memory(xc_handle, ctx.domain, ctx.vcpu, 
  19.228 +                              my_address, my_length, buffer) )
  19.229 +    {
  19.230 +        printf("(pdb) read memory error!\n");  fflush(stdout);
  19.231 +        failwith("read memory error");
  19.232 +    }
  19.233 +
  19.234 +    result = caml_alloc(2,0);
  19.235 +    if ( my_length > 0 )                                              /* car */
  19.236 +    {
  19.237 +        Store_field(result, 0, Val_int(buffer[my_length - 1] & 0xff));
  19.238 +    }
  19.239 +    else
  19.240 +
  19.241 +    {
  19.242 +        Store_field(result, 0, Val_int(0));                    
  19.243 +    }
  19.244 +    Store_field(result, 1, Val_int(0));                               /* cdr */
  19.245 +
  19.246 +    for (loop = 1; loop < my_length; loop++)
  19.247 +    {
  19.248 +        temp = result;
  19.249 +        result = caml_alloc(2,0);
  19.250 +        Store_field(result, 0, Val_int(buffer[my_length - loop - 1] & 0xff));
  19.251 +        Store_field(result, 1, temp);
  19.252 +    }
  19.253 +
  19.254 +    CAMLreturn(result);
  19.255 +}
  19.256 +
  19.257 +/*
  19.258 + * write_memory : context_t -> int32 -> int list -> unit
  19.259 + */
  19.260 +value
  19.261 +write_memory (value context, value address, value val_list)
  19.262 +{
  19.263 +    CAMLparam3(context, address, val_list);
  19.264 +    CAMLlocal1(node);
  19.265 +
  19.266 +    context_t ctx;
  19.267 +
  19.268 +    char buffer[4096];  /* a big buffer */
  19.269 +    memory_t  my_address;
  19.270 +    u32 length = 0;
  19.271 +
  19.272 +    printf ("(pdb) write memory\n");
  19.273 +
  19.274 +    decode_context(&ctx, context);
  19.275 +
  19.276 +    node = val_list;
  19.277 +    if ( Int_val(node) == 0 )       /* gdb functionalty test uses empty list */
  19.278 +    {
  19.279 +        CAMLreturn(Val_unit);
  19.280 +    }
  19.281 +
  19.282 +    while ( Int_val(Field(node,1)) != 0 )
  19.283 +    {
  19.284 +        buffer[length++] = Int_val(Field(node, 0));
  19.285 +        node = Field(node,1);
  19.286 +    }
  19.287 +    buffer[length++] = Int_val(Field(node, 0));
  19.288 +
  19.289 +    my_address = (memory_t) Int32_val(address);
  19.290 +
  19.291 +    if ( xc_debug_write_memory(xc_handle, ctx.domain, ctx.vcpu,
  19.292 +                               my_address, length, buffer) )
  19.293 +    {
  19.294 +        printf("(pdb) write memory error!\n");  fflush(stdout);
  19.295 +        failwith("write memory error");
  19.296 +    }
  19.297 +
  19.298 +    CAMLreturn(Val_unit);
  19.299 +}
  19.300 +
  19.301 +
  19.302 +/*********************************************************************/
  19.303 +
  19.304 +void
  19.305 +dump_regs (cpu_user_regs_t *regs)
  19.306 +{
  19.307 +    printf ("   eax: %x\n", regs->eax);
  19.308 +    printf ("   ecx: %x\n", regs->ecx);
  19.309 +    printf ("   edx: %x\n", regs->edx);
  19.310 +    printf ("   ebx: %x\n", regs->ebx);
  19.311 +    printf ("   esp: %x\n", regs->esp);
  19.312 +    printf ("   ebp: %x\n", regs->ebp);
  19.313 +    printf ("   esi: %x\n", regs->esi);
  19.314 +    printf ("   edi: %x\n", regs->edi);
  19.315 +    printf ("   eip: %x\n", regs->eip);
  19.316 +    printf (" flags: %x\n", regs->eflags);
  19.317 +    printf ("    cs: %x\n", regs->cs);
  19.318 +    printf ("    ss: %x\n", regs->ss);
  19.319 +    printf ("    es: %x\n", regs->es);
  19.320 +    printf ("    ds: %x\n", regs->ds);
  19.321 +    printf ("    fs: %x\n", regs->fs);
  19.322 +    printf ("    gs: %x\n", regs->gs);
  19.323 +
  19.324 +    return;
  19.325 +}
  19.326 +
  19.327 +/*
  19.328 + * continue_target : context_t -> unit
  19.329 + */
  19.330 +value
  19.331 +continue_target (value context)
  19.332 +{
  19.333 +    CAMLparam1(context);
  19.334 +
  19.335 +    context_t ctx;
  19.336 +
  19.337 +    decode_context(&ctx, context);
  19.338 +
  19.339 +    if ( xc_debug_continue(xc_handle, ctx.domain, ctx.vcpu) )
  19.340 +    {
  19.341 +        printf("(pdb) continue\n");  fflush(stdout);
  19.342 +        failwith("continue");
  19.343 +    }
  19.344 +
  19.345 +    CAMLreturn(Val_unit);
  19.346 +}
  19.347 +
  19.348 +/*
  19.349 + * step_target : context_t -> unit
  19.350 + */
  19.351 +value
  19.352 +step_target (value context)
  19.353 +{
  19.354 +    CAMLparam1(context);
  19.355 +
  19.356 +    context_t ctx;
  19.357 +
  19.358 +    decode_context(&ctx, context);
  19.359 +
  19.360 +    if ( xc_debug_step(xc_handle, ctx.domain, ctx.vcpu) )
  19.361 +    {
  19.362 +        printf("(pdb) step\n");  fflush(stdout);
  19.363 +        failwith("step");
  19.364 +    }
  19.365 +
  19.366 +    CAMLreturn(Val_unit);
  19.367 +}
  19.368 +
  19.369 +
  19.370 +
  19.371 +/*
  19.372 + * insert_memory_breakpoint : context_t -> int32 -> int list -> unit
  19.373 + */
  19.374 +value
  19.375 +insert_memory_breakpoint (value context, value address, value length)
  19.376 +{
  19.377 +    CAMLparam3(context, address, length);
  19.378 +
  19.379 +    context_t ctx;
  19.380 +    memory_t my_address = (memory_t) Int32_val(address);
  19.381 +    int my_length = Int_val(length);
  19.382 +
  19.383 +    decode_context(&ctx, context);
  19.384 +
  19.385 +    printf ("(pdb) insert memory breakpoint 0x%lx %d\n",
  19.386 +            my_address, my_length);
  19.387 +
  19.388 +    if ( xc_debug_insert_memory_breakpoint(xc_handle, ctx.domain, ctx.vcpu,
  19.389 +                                           my_address, my_length) )
  19.390 +    {
  19.391 +        printf("(pdb) error: insert memory breakpoint\n");  fflush(stdout);
  19.392 +        failwith("insert memory breakpoint");
  19.393 +    }
  19.394 +
  19.395 +
  19.396 +    CAMLreturn(Val_unit);
  19.397 +}
  19.398 +
  19.399 +/*
  19.400 + * remove_memory_breakpoint : context_t -> int32 -> int list -> unit
  19.401 + */
  19.402 +value
  19.403 +remove_memory_breakpoint (value context, value address, value length)
  19.404 +{
  19.405 +    CAMLparam3(context, address, length);
  19.406 +
  19.407 +    context_t ctx;
  19.408 +
  19.409 +    memory_t my_address = (memory_t) Int32_val(address);
  19.410 +    int my_length = Int_val(length);
  19.411 +
  19.412 +    printf ("(pdb) remove memory breakpoint 0x%lx %d\n",
  19.413 +            my_address, my_length);
  19.414 +
  19.415 +    decode_context(&ctx, context);
  19.416 +
  19.417 +    if ( xc_debug_remove_memory_breakpoint(xc_handle, 
  19.418 +                                           ctx.domain, ctx.vcpu,
  19.419 +                                           my_address, my_length) )
  19.420 +    {
  19.421 +        printf("(pdb) error: remove memory breakpoint\n");  fflush(stdout);
  19.422 +        failwith("remove memory breakpoint");
  19.423 +    }
  19.424 +
  19.425 +    CAMLreturn(Val_unit);
  19.426 +}
  19.427 +
  19.428 +/*
  19.429 + * attach_debugger : int -> int -> unit
  19.430 + */
  19.431 +value
  19.432 +attach_debugger (value domain, value vcpu)
  19.433 +{
  19.434 +    CAMLparam2(domain, vcpu);
  19.435 +
  19.436 +    int my_domain = Int_val(domain);
  19.437 +    int my_vcpu = Int_val(vcpu);
  19.438 +
  19.439 +    printf ("(pdb) attach domain [%d.%d]\n", my_domain, my_vcpu);
  19.440 +
  19.441 +    if ( xc_debug_attach(xc_handle, my_domain, my_vcpu) )
  19.442 +    {
  19.443 +        printf("(pdb) attach error!\n");  fflush(stdout);
  19.444 +        failwith("attach error");
  19.445 +    }
  19.446 +
  19.447 +    CAMLreturn(Val_unit);
  19.448 +}
  19.449 +
  19.450 +
  19.451 +/*
  19.452 + * detach_debugger : int -> int -> unit
  19.453 + */
  19.454 +value
  19.455 +detach_debugger (value domain, value vcpu)
  19.456 +{
  19.457 +    CAMLparam2(domain, vcpu);
  19.458 +
  19.459 +    int my_domain = Int_val(domain);
  19.460 +    int my_vcpu = Int_val(vcpu);
  19.461 +
  19.462 +    printf ("(pdb) detach domain [%d.%d]\n", my_domain, my_vcpu);
  19.463 +
  19.464 +    if ( xc_debug_detach(xc_handle, my_domain, my_vcpu) )
  19.465 +    {
  19.466 +        printf("(pdb) detach error!\n");  fflush(stdout);
  19.467 +        failwith("detach error");
  19.468 +    }
  19.469 +
  19.470 +    CAMLreturn(Val_unit);
  19.471 +}
  19.472 +
  19.473 +
  19.474 +/*
  19.475 + * debugger_status : unit -> unit
  19.476 + */
  19.477 +value
  19.478 +debugger_status (value unit)
  19.479 +{
  19.480 +    CAMLparam1(unit);
  19.481 +
  19.482 +    printf ("(pdb) debugger status\n");
  19.483 +
  19.484 +    CAMLreturn(Val_unit);
  19.485 +}
  19.486 +
  19.487 +/*
  19.488 + * pause_target : int -> unit
  19.489 + */
  19.490 +value
  19.491 +pause_target (value domid)
  19.492 +{
  19.493 +    CAMLparam1(domid);
  19.494 +
  19.495 +    int my_domid = Int_val(domid);
  19.496 +
  19.497 +    printf ("(pdb) pause target %d\n", my_domid);
  19.498 +
  19.499 +    xc_domain_pause(xc_handle, my_domid);
  19.500 +
  19.501 +    CAMLreturn(Val_unit);
  19.502 +}
  19.503 +
  19.504 +/****************************************************************************/
  19.505 +/****************************************************************************/
  19.506 +
  19.507 +/*
  19.508 + * query_domain_stop : unit -> (int * int) list
  19.509 + */
  19.510 +value
  19.511 +query_domain_stop (value unit)
  19.512 +{
  19.513 +    CAMLparam1(unit);
  19.514 +    CAMLlocal3(result, temp, node);
  19.515 +
  19.516 +    int max_domains = 20;
  19.517 +    int dom_list[max_domains];
  19.518 +    int loop, count;
  19.519 +
  19.520 +    count = xc_debug_query_domain_stop(xc_handle, dom_list, max_domains);
  19.521 +    if ( count < 0 )
  19.522 +    {
  19.523 +        printf("(pdb) query domain stop!\n");  fflush(stdout);
  19.524 +        failwith("query domain stop");
  19.525 +    }
  19.526 +
  19.527 +    printf ("QDS: %d\n", count);
  19.528 +    for (loop = 0; loop < count; loop ++)
  19.529 +        printf ("  %d %d\n", loop, dom_list[loop]);
  19.530 +
  19.531 +    result = caml_alloc(2,0);
  19.532 +    if ( count > 0 )                                                  /* car */
  19.533 +    {
  19.534 +        node = caml_alloc(2,0);
  19.535 +        Store_field(node, 0, Val_int(dom_list[0]));             /* domain id */
  19.536 +        Store_field(node, 1, Val_int(0));                            /* vcpu */
  19.537 +        Store_field(result, 0, node);
  19.538 +    }
  19.539 +    else
  19.540 +    {
  19.541 +        Store_field(result, 0, Val_int(0));                    
  19.542 +    }
  19.543 +    Store_field(result, 1, Val_int(0));                               /* cdr */
  19.544 +
  19.545 +    for ( loop = 1; loop < count; loop++ )
  19.546 +    {
  19.547 +        temp = result;
  19.548 +        result = caml_alloc(2,0);
  19.549 +        node = caml_alloc(2,0);
  19.550 +        Store_field(node, 0, Val_int(dom_list[loop]));          /* domain id */
  19.551 +        Store_field(node, 1, Val_int(0));                            /* vcpu */
  19.552 +        Store_field(result, 0, node);
  19.553 +        Store_field(result, 1, temp);
  19.554 +    }
  19.555 +
  19.556 +    CAMLreturn(result);
  19.557 +}
  19.558 +
  19.559 +/****************************************************************************/
  19.560 +/****************************************************************************/
  19.561 +
  19.562 +#include <errno.h>
  19.563 +#include <sys/ioctl.h>
  19.564 +#include <sys/stat.h>
  19.565 +#include <fcntl.h>
  19.566 +#include <unistd.h>
  19.567 +
  19.568 +/*
  19.569 + * evtchn_open : string -> int -> int -> Unix.file_descr
  19.570 + *
  19.571 + * OCaml's Unix library doesn't have mknod, so it makes more sense just write
  19.572 + * this in C.  This code is from Keir/Andy.
  19.573 + */
  19.574 +value
  19.575 +evtchn_open (value filename, value major, value minor)
  19.576 +{
  19.577 +    CAMLparam3(filename, major, minor);
  19.578 +
  19.579 +    char *myfilename = String_val(filename);
  19.580 +    int   mymajor = Int_val(major);
  19.581 +    int   myminor = Int_val(minor);
  19.582 +    int   evtchn_fd;
  19.583 +    struct stat st;
  19.584 +    
  19.585 +    /* Make sure any existing device file links to correct device. */
  19.586 +    if ( (lstat(myfilename, &st) != 0) ||
  19.587 +         !S_ISCHR(st.st_mode) ||
  19.588 +         (st.st_rdev != makedev(mymajor, myminor)) )
  19.589 +    {
  19.590 +        (void)unlink(myfilename);
  19.591 +    }
  19.592 +
  19.593 + reopen:
  19.594 +    evtchn_fd = open(myfilename, O_RDWR); 
  19.595 +    if ( evtchn_fd == -1 )
  19.596 +    {
  19.597 +        if ( (errno == ENOENT) &&
  19.598 +             ((mkdir("/dev/xen", 0755) == 0) || (errno == EEXIST)) &&
  19.599 +             (mknod(myfilename, S_IFCHR|0600, makedev(mymajor,myminor)) == 0) )
  19.600 +        {
  19.601 +            goto reopen;
  19.602 +        }
  19.603 +        return -errno;
  19.604 +    }
  19.605 +
  19.606 +    CAMLreturn(Val_int(evtchn_fd));
  19.607 +}
  19.608 +
  19.609 +/*
  19.610 + * evtchn_bind_virq : int -> int
  19.611 + */
  19.612 +value
  19.613 +evtchn_bind_virq (value virq)
  19.614 +{
  19.615 +    CAMLparam1(virq);
  19.616 +
  19.617 +    int port;
  19.618 +
  19.619 +    if ( pdb_evtchn_bind_virq(xc_handle, Int_val(virq), &port) < 0 )
  19.620 +    {
  19.621 +        printf("(pdb) evtchn_bind_virq error!\n");  fflush(stdout);
  19.622 +        failwith("evtchn_bind_virq error");
  19.623 +    }
  19.624 +
  19.625 +    CAMLreturn(Val_int(port));
  19.626 +}
  19.627 +
  19.628 +/*
  19.629 + * evtchn_bind : Unix.file_descr -> int -> unit
  19.630 + */
  19.631 +value
  19.632 +evtchn_bind (value fd, value idx)
  19.633 +{
  19.634 +    CAMLparam2(fd, idx);
  19.635 +
  19.636 +    int myfd = Int_val(fd);
  19.637 +    int myidx = Int_val(idx);
  19.638 +
  19.639 +    if ( xen_evtchn_bind(myfd, myidx) < 0 )
  19.640 +    {
  19.641 +        printf("(pdb) evtchn_bind error!\n");  fflush(stdout);
  19.642 +        failwith("evtchn_bind error");
  19.643 +    }
  19.644 +
  19.645 +    CAMLreturn(Val_unit);
  19.646 +}
  19.647 +
  19.648 +/*
  19.649 + * evtchn_unbind : Unix.file_descr -> int -> unit
  19.650 + */
  19.651 +value
  19.652 +evtchn_unbind (value fd, value idx)
  19.653 +{
  19.654 +    CAMLparam2(fd, idx);
  19.655 +
  19.656 +    int myfd = Int_val(fd);
  19.657 +    int myidx = Int_val(idx);
  19.658 +
  19.659 +    if ( xen_evtchn_unbind(myfd, myidx) < 0 )
  19.660 +    {
  19.661 +        printf("(pdb) evtchn_unbind error!\n");  fflush(stdout);
  19.662 +        failwith("evtchn_unbind error");
  19.663 +    }
  19.664 +
  19.665 +    CAMLreturn(Val_unit);
  19.666 +}
  19.667 +
  19.668 +/*
  19.669 + * evtchn_read : Unix.file_descr -> int
  19.670 + */
  19.671 +value
  19.672 +evtchn_read (value fd)
  19.673 +{
  19.674 +    CAMLparam1(fd);
  19.675 +
  19.676 +    u16 v;
  19.677 +    int bytes;
  19.678 +    int rc = -1;
  19.679 +    int myfd = Int_val(fd);
  19.680 +
  19.681 +    while ( (bytes = read(myfd, &v, sizeof(v))) == -1 )
  19.682 +    {
  19.683 +        if ( errno == EINTR )  continue;
  19.684 +        rc = -errno;
  19.685 +        goto exit;
  19.686 +    }
  19.687 +    
  19.688 +    if ( bytes == sizeof(v) )
  19.689 +        rc = v;
  19.690 +    
  19.691 + exit:
  19.692 +    CAMLreturn(Val_int(rc));
  19.693 +}
  19.694 +
  19.695 +
  19.696 +/*
  19.697 + * evtchn_close : Unix.file_descr -> unit
  19.698 + */
  19.699 +value
  19.700 +evtchn_close (value fd)
  19.701 +{
  19.702 +    CAMLparam1(fd);
  19.703 +    int myfd = Int_val(fd);
  19.704 +
  19.705 +    (void)close(myfd);
  19.706 +
  19.707 +    CAMLreturn(Val_unit);
  19.708 +}
  19.709 +
  19.710 +/*
  19.711 + * evtchn_unmask : Unix.file_descr -> int -> unit
  19.712 + */
  19.713 +value
  19.714 +evtchn_unmask (value fd, value idx)
  19.715 +{
  19.716 +    CAMLparam1(fd);
  19.717 +
  19.718 +    int myfd = Int_val(fd);
  19.719 +    u16 myidx = Int_val(idx);
  19.720 +
  19.721 +    (void)write(myfd, &myidx, sizeof(myidx));
  19.722 +
  19.723 +    CAMLreturn(Val_unit);
  19.724 +}
  19.725 +
  19.726 +/*
  19.727 + * Local variables:
  19.728 + * mode: C
  19.729 + * c-set-style: "BSD"
  19.730 + * c-basic-offset: 4
  19.731 + * tab-width: 4
  19.732 + * indent-tabs-mode: nil
  19.733 + * End:
  19.734 + */
  19.735 +
    20.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    20.2 +++ b/tools/pdb/pdb_xen.c	Fri Jun 03 21:18:14 2005 +0000
    20.3 @@ -0,0 +1,93 @@
    20.4 +/*
    20.5 + * pdb_xen.c
    20.6 + *
    20.7 + * alex ho
    20.8 + * http://www.cl.cam.ac.uk/netos/pdb
    20.9 + *
   20.10 + * PDB interface library for accessing Xen
   20.11 + */
   20.12 +
   20.13 +#include <xc.h>
   20.14 +#include <stdio.h>
   20.15 +#include <stdlib.h>
   20.16 +#include <errno.h>
   20.17 +#include <string.h>
   20.18 +#include <sys/mman.h>
   20.19 +
   20.20 +int
   20.21 +pdb_open ()
   20.22 +{
   20.23 +    int xc_handle = xc_interface_open();
   20.24 +
   20.25 +    if ( xc_handle < 0 )
   20.26 +    {
   20.27 +        fprintf(stderr, "(pdb) error opening xc interface: %d (%s)\n",
   20.28 +                errno, strerror(errno));
   20.29 +    }
   20.30 +    return xc_handle;
   20.31 +}
   20.32 +
   20.33 +int 
   20.34 +pdb_close (int xc_handle)
   20.35 +{
   20.36 +    int rc;
   20.37 +
   20.38 +    
   20.39 +    if ( (rc = xc_interface_close(xc_handle)) < 0 )
   20.40 +    {
   20.41 +        fprintf(stderr, "(pdb) error closing xc interface: %d (%s)\n",
   20.42 +                errno, strerror(errno));
   20.43 +    }
   20.44 +    return rc;
   20.45 +}
   20.46 +
   20.47 +
   20.48 +int 
   20.49 +pdb_evtchn_bind_virq (int xc_handle, int virq, int *port)
   20.50 +{
   20.51 +    int rc;
   20.52 +    
   20.53 +    if ( (rc = xc_evtchn_bind_virq(xc_handle, virq, port) < 0 ) )
   20.54 +    {
   20.55 +        fprintf(stderr, "(pdb) error binding virq to event channel: %d (%s)\n",
   20.56 +                errno, strerror(errno));
   20.57 +    }
   20.58 +    return rc;
   20.59 +}
   20.60 +
   20.61 +
   20.62 +#include <sys/ioctl.h>
   20.63 +
   20.64 +/* /dev/xen/evtchn ioctls */
   20.65 +#define EVTCHN_RESET  _IO('E', 1)                   /* clear & reinit buffer */
   20.66 +#define EVTCHN_BIND   _IO('E', 2)                   /* bind to event channel */
   20.67 +#define EVTCHN_UNBIND _IO('E', 3)               /* unbind from event channel */
   20.68 +
   20.69 +int
   20.70 +xen_evtchn_bind (int evtchn_fd, int idx)
   20.71 +{
   20.72 +    if ( ioctl(evtchn_fd, EVTCHN_BIND, idx) != 0 )
   20.73 +        return -errno;
   20.74 +    
   20.75 +    return 0;
   20.76 +}
   20.77 +
   20.78 +int 
   20.79 +xen_evtchn_unbind (int evtchn_fd, int idx)
   20.80 +{
   20.81 +    if ( ioctl(evtchn_fd, EVTCHN_UNBIND, idx) != 0 )
   20.82 +        return -errno;
   20.83 +
   20.84 +    return 0;
   20.85 +}
   20.86 +
   20.87 +
   20.88 +/*
   20.89 + * Local variables:
   20.90 + * mode: C
   20.91 + * c-set-style: "BSD"
   20.92 + * c-basic-offset: 4
   20.93 + * tab-width: 4
   20.94 + * indent-tabs-mode: nil
   20.95 + * End:
   20.96 + */
    21.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    21.2 +++ b/tools/pdb/server.ml	Fri Jun 03 21:18:14 2005 +0000
    21.3 @@ -0,0 +1,219 @@
    21.4 +(** server.ml
    21.5 + *
    21.6 + *  PDB server main loop
    21.7 + *
    21.8 + *  @author copyright (c) 2005 alex ho
    21.9 + *  @see <www.cl.cam.ac.uk/netos/pdb> pervasive debugger
   21.10 + *  @version 1
   21.11 + *)
   21.12 +
   21.13 +open Unix
   21.14 +open Buffer
   21.15 +
   21.16 +
   21.17 +(**
   21.18 + * connection_t: The state for each connection.
   21.19 + * buffer & length contains bytes that have been read from the sock
   21.20 + * but not yet parsed / processed.
   21.21 + *)
   21.22 +type connection_t =
   21.23 +{ 
   21.24 +          fd : file_descr;
   21.25 +  mutable buffer : string;
   21.26 +  mutable length : int;
   21.27 +}
   21.28 +
   21.29 +
   21.30 +(**
   21.31 + * validate_checksum:  Compute and compare the checksum of a string
   21.32 + * against the provided checksum using the gdb serial protocol algorithm.
   21.33 + *
   21.34 + *)
   21.35 +let validate_checksum command checksum =
   21.36 +  let c0 = ref 0 in
   21.37 +  for loop = 0 to (String.length command - 1) do
   21.38 +    c0 := !c0 + int_of_char(command.[loop]);
   21.39 +  done;
   21.40 +  if (String.length checksum) = 2 
   21.41 +  then
   21.42 +    let c1 = Util.int_of_hexchar(checksum.[1]) +
   21.43 +	     Util.int_of_hexchar(checksum.[0]) * 16 in
   21.44 +    (!c0 mod 256) = (c1 mod 256)
   21.45 +  else
   21.46 +    false
   21.47 +  
   21.48 +
   21.49 +(**
   21.50 + * process_input: Oh, joy!  Someone sent us a message.  Let's open the
   21.51 + * envelope and see what they have to say.
   21.52 + *
   21.53 + * This function is a paradigm of inefficiency; it performs as many 
   21.54 + * string copies as possible.
   21.55 + *)
   21.56 +let process_input conn sock = 
   21.57 +  let max_buffer_size = 1024 in
   21.58 +  let in_string = String.create max_buffer_size in
   21.59 +
   21.60 +  let length = read sock in_string 0 max_buffer_size in
   21.61 +  conn.buffer <- conn.buffer ^ (String.sub in_string 0 length);
   21.62 +  conn.length <- conn.length + length;
   21.63 +  let re = Str.regexp "[^\\$]*\\$\\([^#]*\\)#\\(..\\)" in
   21.64 +
   21.65 +  begin
   21.66 +    try
   21.67 +      let break = String.index conn.buffer '\003' + 1 in
   21.68 +      print_endline (Printf.sprintf "{{%s}}" (String.escaped conn.buffer));
   21.69 +
   21.70 +      (* discard everything seen before the ctrl-c *)
   21.71 +      conn.buffer <- String.sub conn.buffer break (conn.length - break);
   21.72 +      conn.length <- conn.length - break;
   21.73 +
   21.74 +      (* pause the target *)
   21.75 +      PDB.pause (PDB.find_context sock);
   21.76 +
   21.77 +      (* send a code back to the debugger *)
   21.78 +      Util.send_reply sock "S05"
   21.79 +
   21.80 +    with
   21.81 +      Not_found -> ()
   21.82 +  end;
   21.83 +
   21.84 +  (* with gdb this is unlikely to loop since you ack each packet *)
   21.85 +  while ( Str.string_match re conn.buffer 0 ) do
   21.86 +    let command = Str.matched_group 1 conn.buffer in
   21.87 +    let checksum = Str.matched_group 2 conn.buffer in
   21.88 +    let match_end = Str.group_end 2 in
   21.89 +
   21.90 +    begin
   21.91 +      match validate_checksum command checksum with
   21.92 +      | true -> 
   21.93 +	  begin
   21.94 +	    Util.write_character sock '+';
   21.95 +	    try
   21.96 +	      let reply = Debugger.process_command command sock in
   21.97 +	      print_endline (Printf.sprintf "[%s] %s -> \"%s\"" 
   21.98 +			       (Util.get_connection_info sock)
   21.99 +			       (String.escaped command) 
  21.100 +			       (String.escaped reply));
  21.101 +	      Util.send_reply sock reply
  21.102 +	    with
  21.103 +	      Debugger.No_reply ->
  21.104 +		print_endline (Printf.sprintf "[%s] %s -> null" 
  21.105 +				 (Util.get_connection_info sock)
  21.106 +				 (String.escaped command))
  21.107 +	  end
  21.108 +      | false ->
  21.109 +	  Util.write_character sock '-';
  21.110 +    end;
  21.111 +
  21.112 +    conn.buffer <- String.sub conn.buffer match_end (conn.length - match_end);
  21.113 +    conn.length <- conn.length - match_end;
  21.114 +  done;
  21.115 +  if length = 0 then raise End_of_file
  21.116 +
  21.117 +
  21.118 +
  21.119 +(** main_server_loop.
  21.120 + *
  21.121 + *  connection_hash is a hash (duh!) with one connection_t for each
  21.122 + *  open connection.
  21.123 + * 
  21.124 + *  in_list is a list of active sockets.  it also contains two 
  21.125 + *  magic entries: server_sock for accepting new entries and 
  21.126 + *  event_sock for Xen event channel asynchronous notifications.
  21.127 + *)
  21.128 +let main_server_loop sockaddr =
  21.129 +  let connection_hash = Hashtbl.create 10
  21.130 +  in
  21.131 +  let process_socket svr_sock sockets sock =
  21.132 +    let (new_list, closed_list) = sockets in
  21.133 +    if sock == svr_sock
  21.134 +    then
  21.135 +      begin
  21.136 +	let (new_sock, caller) = accept sock in
  21.137 +	print_endline (Printf.sprintf "[%s] new connection from %s"
  21.138 +			              (Util.get_connection_info sock)
  21.139 +			              (Util.get_connection_info new_sock));
  21.140 +	Hashtbl.add connection_hash new_sock 
  21.141 +	            {fd=new_sock; buffer=""; length = 0};
  21.142 +	PDB.add_default_context new_sock;
  21.143 +	(new_sock :: new_list, closed_list)
  21.144 +      end
  21.145 +    else
  21.146 +      begin
  21.147 +	try
  21.148 +	  match PDB.find_context sock with
  21.149 +	  | PDB.Event_channel ->
  21.150 +	      print_endline (Printf.sprintf "[%s] event channel"
  21.151 +			                    (Util.get_connection_info sock));
  21.152 +	      Debugger.process_evtchn sock;
  21.153 +	      (new_list, closed_list)
  21.154 +	  | _ ->
  21.155 +	      let conn = Hashtbl.find connection_hash sock in
  21.156 +	      process_input conn sock;
  21.157 +	      (new_list, closed_list)
  21.158 +	with
  21.159 +	| Not_found -> 
  21.160 +	    print_endline "error: (main_svr_loop) context not found";
  21.161 +	    PDB.debug_contexts ();
  21.162 +	    raise Not_found
  21.163 +	| End_of_file -> 
  21.164 +	    print_endline (Printf.sprintf "[%s] close connection from %s"
  21.165 +  			                   (Util.get_connection_info sock)
  21.166 +			                   (Util.get_connection_info sock));
  21.167 +	    PDB.delete_context sock;
  21.168 +	    Hashtbl.remove connection_hash sock;
  21.169 +	    close sock;
  21.170 +	    (new_list, sock :: closed_list)
  21.171 +      end
  21.172 +  in
  21.173 +  let rec helper in_list server_sock =
  21.174 +  (*
  21.175 +   * List.iter (fun x->Printf.printf "{%s} " 
  21.176 +   *                                (Util.get_connection_info x)) in_list;   
  21.177 +   * Printf.printf "\n";
  21.178 +   *)
  21.179 +    let (rd_list, _, _) = select in_list [] [] (-1.0) in 
  21.180 +    let (new_list, closed_list) = List.fold_left (process_socket server_sock)
  21.181 +	                                         ([],[]) rd_list  in
  21.182 +    let merge_list = Util.list_remove (new_list @ in_list) closed_list  in
  21.183 +    helper merge_list server_sock
  21.184 +  in
  21.185 +  try
  21.186 +    let server_sock = socket (domain_of_sockaddr sockaddr) SOCK_STREAM 0 in
  21.187 +    setsockopt server_sock SO_REUSEADDR true;
  21.188 +    bind server_sock sockaddr;
  21.189 +    listen server_sock 2;
  21.190 +
  21.191 +    PDB.open_debugger ();
  21.192 +    let event_sock = Evtchn.setup () in
  21.193 +    PDB.add_context event_sock "event channel" [];
  21.194 +    helper [server_sock; event_sock] server_sock
  21.195 +  with
  21.196 +  | Sys.Break ->
  21.197 +      print_endline "break: cleaning up";
  21.198 +      PDB.close_debugger ();
  21.199 +      Hashtbl.iter (fun sock conn -> close sock) connection_hash
  21.200 +  | Unix_error(e,err,param) -> 
  21.201 +      Printf.printf "unix error: [%s][%s][%s]\n" (error_message e) err param
  21.202 +  | Sys_error s -> Printf.printf "sys error: [%s]\n" s
  21.203 +  | Failure s -> Printf.printf "failure: [%s]\n" s
  21.204 +  | End_of_file -> Printf.printf "end of file\n"
  21.205 +
  21.206 +
  21.207 +let get_port () =
  21.208 +  if (Array.length Sys.argv) = 2 
  21.209 +  then
  21.210 +    int_of_string Sys.argv.(1)
  21.211 +  else
  21.212 +    begin
  21.213 +      print_endline (Printf.sprintf "syntax error: %s <port>" Sys.argv.(0));
  21.214 +      exit 1
  21.215 +    end
  21.216 +
  21.217 +
  21.218 +let main =
  21.219 +  let address = inet_addr_any in
  21.220 +  let port = get_port () in
  21.221 +  main_server_loop (ADDR_INET(address, port))
  21.222 +
    22.1 --- a/xen/Rules.mk	Fri Jun 03 18:06:52 2005 +0000
    22.2 +++ b/xen/Rules.mk	Fri Jun 03 21:18:14 2005 +0000
    22.3 @@ -55,6 +55,11 @@ ifeq ($(domu_debug),y)
    22.4  CFLAGS += -DDOMU_DEBUG
    22.5  endif
    22.6  
    22.7 +ifeq ($(pdb),y)
    22.8 +CFLAGS += -g -DPDB_DEBUG
    22.9 +endif
   22.10 +
   22.11 +
   22.12  ifeq ($(crash_debug),y)
   22.13  CFLAGS += -g -DCRASH_DEBUG
   22.14  endif
    23.1 --- a/xen/include/asm-x86/debugger.h	Fri Jun 03 18:06:52 2005 +0000
    23.2 +++ b/xen/include/asm-x86/debugger.h	Fri Jun 03 21:18:14 2005 +0000
    23.3 @@ -80,6 +80,50 @@ static inline int debugger_trap_entry(
    23.4  #define debugger_trap_fatal(_v, _r) (0)
    23.5  #define debugger_trap_immediate()
    23.6  
    23.7 +#elif defined(PDB_DEBUG)
    23.8 +
    23.9 +#include <xen/event.h>
   23.10 +#include <xen/softirq.h>
   23.11 +#include <xen/sched.h>
   23.12 +#include <asm/regs.h>
   23.13 +
   23.14 +static inline int debugger_trap_entry(unsigned int vector,
   23.15 +				      struct cpu_user_regs *regs)
   23.16 +{
   23.17 +    struct vcpu *vcpu = current;
   23.18 +
   23.19 +    if ( !KERNEL_MODE(vcpu, regs) || (vcpu->domain->domain_id == 0) )
   23.20 +        return 0;
   23.21 +    
   23.22 +    switch ( vector )
   23.23 +    {
   23.24 +    case TRAP_debug:
   23.25 +    case TRAP_int3:
   23.26 +    {
   23.27 +        struct vcpu  *ptr;
   23.28 +
   23.29 +        /* suspend the guest domain */
   23.30 +        for_each_vcpu ( vcpu->domain, ptr )
   23.31 +        {
   23.32 +            test_and_set_bit(_VCPUF_ctrl_pause, &ptr->vcpu_flags);
   23.33 +        }
   23.34 +        sync_lazy_execstate_mask(vcpu->domain->cpumask);        /* TLB flush */
   23.35 +        raise_softirq(SCHEDULE_SOFTIRQ);
   23.36 +
   23.37 +        /* notify the debugger */
   23.38 +        send_guest_virq(dom0->vcpu[0], VIRQ_PDB);
   23.39 +
   23.40 +        return 1;
   23.41 +    }
   23.42 +    default:
   23.43 +        break;
   23.44 +    }
   23.45 +
   23.46 +    return 0;
   23.47 +}
   23.48 +
   23.49 +#define debugger_trap_fatal(_v, _r) (0)
   23.50 +#define debugger_trap_immediate()
   23.51  
   23.52  #elif 0
   23.53  
    24.1 --- a/xen/include/public/xen.h	Fri Jun 03 18:06:52 2005 +0000
    24.2 +++ b/xen/include/public/xen.h	Fri Jun 03 21:18:14 2005 +0000
    24.3 @@ -70,6 +70,7 @@
    24.4  #define VIRQ_DOM_EXC    3  /* (DOM0) Exceptional event for some domain.   */
    24.5  #define VIRQ_PARITY_ERR 4  /* (DOM0) NMI parity error.                    */
    24.6  #define VIRQ_IO_ERR     5  /* (DOM0) NMI I/O error.                       */
    24.7 +#define VIRQ_PDB        6  /* (DOM0) PDB                                  */
    24.8  #define NR_VIRQS        7
    24.9  
   24.10  /*