aboutsummaryrefslogtreecommitdiffstats
path: root/tools/debugger/pdb/pdb_caml_xc.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/debugger/pdb/pdb_caml_xc.c')
-rw-r--r--tools/debugger/pdb/pdb_caml_xc.c612
1 files changed, 25 insertions, 587 deletions
diff --git a/tools/debugger/pdb/pdb_caml_xc.c b/tools/debugger/pdb/pdb_caml_xc.c
index 6ba82a92c2..7507d98808 100644
--- a/tools/debugger/pdb/pdb_caml_xc.c
+++ b/tools/debugger/pdb/pdb_caml_xc.c
@@ -3,7 +3,7 @@
*
* http://www.cl.cam.ac.uk/netos/pdb
*
- * OCaml to libxc interface library for PDB
+ * PDB's OCaml interface library for debugging domains
*/
#include <xc.h>
@@ -18,38 +18,9 @@
#include <caml/memory.h>
#include <caml/mlvalues.h>
-int pdb_evtchn_bind_virq (int xc_handle, int virq, int *port);
-int xen_evtchn_bind (int evtchn_fd, int idx);
-int xen_evtchn_unbind (int evtchn_fd, int idx);
+#include "pdb_caml_xen.h"
-/* this order comes from xen/include/public/arch-x86_32.h */
-enum x86_registers { PDB_EBX, PDB_ECX, PDB_EDX, PDB_ESI, PDB_EDI,
- PDB_EBP, PDB_EAX, PDB_Error_code, PDB_Entry_vector,
- PDB_EIP, PDB_CS, PDB_EFLAGS, PDB_ESP, PDB_SS,
- PDB_ES, PDB_DS, PDB_FS, PDB_GS };
-
-static void dump_regs (cpu_user_regs_t *ctx);
-
-static int xc_handle = -1;
-
-typedef struct
-{
- int domain;
- int vcpu;
-} context_t;
-
-#define decode_context(_ctx, _ocaml) \
-{ \
- (_ctx)->domain = Int_val(Field((_ocaml),0)); \
- (_ctx)->vcpu = Int_val(Field((_ocaml),1)); \
-}
-
-#define encode_context(_ctx, _ocaml) \
-{ \
- (_ocaml) = caml_alloc_tuple(2); \
- Store_field((_ocaml), 0, Val_int((_ctx)->domain)); \
- Store_field((_ocaml), 1, Val_int((_ctx)->vcpu)); \
-}
+int xc_handle = -1;
/****************************************************************************/
@@ -91,210 +62,6 @@ close_context (value unit)
CAMLreturn(Val_unit);
}
-/*
- * read_registers : context_t -> int32
- */
-value
-read_registers (value context)
-{
- CAMLparam1(context);
- CAMLlocal1(result);
-
- cpu_user_regs_t *regs;
- context_t ctx;
-
- decode_context(&ctx, context);
-
- if ( xendebug_read_registers(xc_handle, ctx.domain, ctx.vcpu, &regs) )
- {
- printf("(pdb) read registers error!\n"); fflush(stdout);
- failwith("read registers error");
- }
-
- dump_regs(regs);
-
- result = caml_alloc_tuple(18); /* FIXME */
-
- Store_field(result, 0, caml_copy_int32(regs->ebx));
- Store_field(result, 1, caml_copy_int32(regs->ecx));
- Store_field(result, 2, caml_copy_int32(regs->edx));
- Store_field(result, 3, caml_copy_int32(regs->esi));
- Store_field(result, 4, caml_copy_int32(regs->edi));
- Store_field(result, 5, caml_copy_int32(regs->ebp));
- Store_field(result, 6, caml_copy_int32(regs->eax));
- Store_field(result, 7, caml_copy_int32(regs->error_code)); /* 16 */
- Store_field(result, 8, caml_copy_int32(regs->entry_vector)); /* 16 */
- Store_field(result, 9, caml_copy_int32(regs->eip));
- Store_field(result, 10, caml_copy_int32(regs->cs)); /* 16 */
- Store_field(result, 11, caml_copy_int32(regs->eflags));
- Store_field(result, 12, caml_copy_int32(regs->esp));
- Store_field(result, 13, caml_copy_int32(regs->ss)); /* 16 */
- Store_field(result, 14, caml_copy_int32(regs->es)); /* 16 */
- Store_field(result, 15, caml_copy_int32(regs->ds)); /* 16 */
- Store_field(result, 16, caml_copy_int32(regs->fs)); /* 16 */
- Store_field(result, 17, caml_copy_int32(regs->gs)); /* 16 */
-
- CAMLreturn(result);
-}
-
-
-/*
- * write_register : context_t -> register -> int32 -> unit
- */
-value
-write_register (value context, value reg, value newval)
-{
- CAMLparam3(context, reg, newval);
-
- int my_reg = Int_val(reg);
- int val = Int32_val(newval);
-
- context_t ctx;
- cpu_user_regs_t *regs;
-
- printf("(pdb) write register\n");
-
- decode_context(&ctx, context);
-
- if ( xendebug_read_registers(xc_handle, ctx.domain, ctx.vcpu, &regs) )
- {
- printf("(pdb) write register (get) error!\n"); fflush(stdout);
- failwith("write register error");
- }
-
- switch (my_reg)
- {
- case PDB_EBX: regs->ebx = val; break;
- case PDB_ECX: regs->ecx = val; break;
- case PDB_EDX: regs->edx = val; break;
- case PDB_ESI: regs->esi = val; break;
- case PDB_EDI: regs->edi = val; break;
-
- case PDB_EBP: regs->ebp = val; break;
- case PDB_EAX: regs->eax = val; break;
- case PDB_Error_code: regs->error_code = val; break;
- case PDB_Entry_vector: regs->entry_vector = val; break;
-
- case PDB_EIP: regs->eip = val; break;
- case PDB_CS: regs->cs = val; break;
- case PDB_EFLAGS: regs->eflags = val; break;
- case PDB_ESP: regs->esp = val; break;
- case PDB_SS: regs->ss = val; break;
- case PDB_ES: regs->es = val; break;
- case PDB_DS: regs->ds = val; break;
- case PDB_FS: regs->fs = val; break;
- case PDB_GS: regs->gs = val; break;
- }
-
- if ( xendebug_write_registers(xc_handle, ctx.domain, ctx.vcpu, regs) )
- {
- printf("(pdb) write register (set) error!\n"); fflush(stdout);
- failwith("write register error");
- }
-
- CAMLreturn(Val_unit);
-}
-
-/*
- * read_memory : context_t -> int32 -> int -> int
- */
-value
-read_memory (value context, value address, value length)
-{
- CAMLparam3(context, address, length);
- CAMLlocal2(result, temp);
-
- context_t ctx;
- int loop;
- char *buffer;
- memory_t my_address = Int32_val(address);
- u32 my_length = Int_val(length);
-
- printf ("(pdb) read memory\n");
-
- decode_context(&ctx, context);
-
- buffer = malloc(my_length);
- if (buffer == NULL)
- {
- printf("(pdb) read memory: malloc failed.\n"); fflush(stdout);
- failwith("read memory error");
- }
-
- if ( xendebug_read_memory(xc_handle, ctx.domain, ctx.vcpu,
- my_address, my_length, buffer) )
- {
- printf("(pdb) read memory error!\n"); fflush(stdout);
- failwith("read memory error");
- }
-
- result = caml_alloc(2,0);
- if ( my_length > 0 ) /* car */
- {
- Store_field(result, 0, Val_int(buffer[my_length - 1] & 0xff));
- }
- else
-
- {
- Store_field(result, 0, Val_int(0));
- }
- Store_field(result, 1, Val_int(0)); /* cdr */
-
- for (loop = 1; loop < my_length; loop++)
- {
- temp = result;
- result = caml_alloc(2,0);
- Store_field(result, 0, Val_int(buffer[my_length - loop - 1] & 0xff));
- Store_field(result, 1, temp);
- }
-
- CAMLreturn(result);
-}
-
-/*
- * write_memory : context_t -> int32 -> int list -> unit
- */
-value
-write_memory (value context, value address, value val_list)
-{
- CAMLparam3(context, address, val_list);
- CAMLlocal1(node);
-
- context_t ctx;
-
- char buffer[4096]; /* a big buffer */
- memory_t my_address;
- u32 length = 0;
-
- printf ("(pdb) write memory\n");
-
- decode_context(&ctx, context);
-
- node = val_list;
- if ( Int_val(node) == 0 ) /* gdb functionalty test uses empty list */
- {
- CAMLreturn(Val_unit);
- }
-
- while ( Int_val(Field(node,1)) != 0 )
- {
- buffer[length++] = Int_val(Field(node, 0));
- node = Field(node,1);
- }
- buffer[length++] = Int_val(Field(node, 0));
-
- my_address = (memory_t) Int32_val(address);
-
- if ( xendebug_write_memory(xc_handle, ctx.domain, ctx.vcpu,
- my_address, length, buffer) )
- {
- printf("(pdb) write memory error!\n"); fflush(stdout);
- failwith("write memory error");
- }
-
- CAMLreturn(Val_unit);
-}
-
/*********************************************************************/
@@ -322,153 +89,6 @@ dump_regs (cpu_user_regs_t *regs)
}
/*
- * continue_target : context_t -> unit
- */
-value
-continue_target (value context)
-{
- CAMLparam1(context);
-
- context_t ctx;
-
- decode_context(&ctx, context);
-
- if ( xendebug_continue(xc_handle, ctx.domain, ctx.vcpu) )
- {
- printf("(pdb) continue\n"); fflush(stdout);
- failwith("continue");
- }
-
- CAMLreturn(Val_unit);
-}
-
-/*
- * step_target : context_t -> unit
- */
-value
-step_target (value context)
-{
- CAMLparam1(context);
-
- context_t ctx;
-
- decode_context(&ctx, context);
-
- if ( xendebug_step(xc_handle, ctx.domain, ctx.vcpu) )
- {
- printf("(pdb) step\n"); fflush(stdout);
- failwith("step");
- }
-
- CAMLreturn(Val_unit);
-}
-
-
-
-/*
- * insert_memory_breakpoint : context_t -> int32 -> int list -> unit
- */
-value
-insert_memory_breakpoint (value context, value address, value length)
-{
- CAMLparam3(context, address, length);
-
- context_t ctx;
- memory_t my_address = (memory_t) Int32_val(address);
- int my_length = Int_val(length);
-
- decode_context(&ctx, context);
-
- printf ("(pdb) insert memory breakpoint 0x%lx %d\n",
- my_address, my_length);
-
- if ( xendebug_insert_memory_breakpoint(xc_handle, ctx.domain, ctx.vcpu,
- my_address, my_length) )
- {
- printf("(pdb) error: insert memory breakpoint\n"); fflush(stdout);
- failwith("insert memory breakpoint");
- }
-
-
- CAMLreturn(Val_unit);
-}
-
-/*
- * remove_memory_breakpoint : context_t -> int32 -> int list -> unit
- */
-value
-remove_memory_breakpoint (value context, value address, value length)
-{
- CAMLparam3(context, address, length);
-
- context_t ctx;
-
- memory_t my_address = (memory_t) Int32_val(address);
- int my_length = Int_val(length);
-
- printf ("(pdb) remove memory breakpoint 0x%lx %d\n",
- my_address, my_length);
-
- decode_context(&ctx, context);
-
- if ( xendebug_remove_memory_breakpoint(xc_handle,
- ctx.domain, ctx.vcpu,
- my_address, my_length) )
- {
- printf("(pdb) error: remove memory breakpoint\n"); fflush(stdout);
- failwith("remove memory breakpoint");
- }
-
- CAMLreturn(Val_unit);
-}
-
-/*
- * attach_debugger : int -> int -> unit
- */
-value
-attach_debugger (value domain, value vcpu)
-{
- CAMLparam2(domain, vcpu);
-
- int my_domain = Int_val(domain);
- int my_vcpu = Int_val(vcpu);
-
- printf ("(pdb) attach domain [%d.%d]\n", my_domain, my_vcpu);
-
- if ( xendebug_attach(xc_handle, my_domain, my_vcpu) )
- {
- printf("(pdb) attach error!\n"); fflush(stdout);
- failwith("attach error");
- }
-
- CAMLreturn(Val_unit);
-}
-
-
-/*
- * detach_debugger : int -> int -> unit
- */
-value
-detach_debugger (value domain, value vcpu)
-{
- CAMLparam2(domain, vcpu);
-
- int my_domain = Int_val(domain);
- int my_vcpu = Int_val(vcpu);
-
- printf ("(pdb) detach domain [%d.%d]\n", my_domain, my_vcpu);
-
- if ( xendebug_detach(xc_handle, my_domain, my_vcpu) )
- {
- printf("(pdb) detach error!\n"); fflush(stdout);
- failwith("detach error");
- }
-
- CAMLreturn(Val_unit);
-}
-
-
-/*
* debugger_status : unit -> unit
*/
value
@@ -476,25 +96,6 @@ debugger_status (value unit)
{
CAMLparam1(unit);
- printf ("(pdb) debugger status\n");
-
- CAMLreturn(Val_unit);
-}
-
-/*
- * pause_target : int -> unit
- */
-value
-pause_target (value domid)
-{
- CAMLparam1(domid);
-
- int my_domid = Int_val(domid);
-
- printf ("(pdb) pause target %d\n", my_domid);
-
- xc_domain_pause(xc_handle, my_domid);
-
CAMLreturn(Val_unit);
}
@@ -502,108 +103,6 @@ pause_target (value domid)
/****************************************************************************/
/*
- * query_domain_stop : unit -> (int * int) list
- */
-value
-query_domain_stop (value unit)
-{
- CAMLparam1(unit);
- CAMLlocal3(result, temp, node);
-
- int max_domains = 20;
- int dom_list[max_domains];
- int loop, count;
-
- count = xendebug_query_domain_stop(xc_handle, dom_list, max_domains);
- if ( count < 0 )
- {
- printf("(pdb) query domain stop!\n"); fflush(stdout);
- failwith("query domain stop");
- }
-
- printf ("QDS: %d\n", count);
- for (loop = 0; loop < count; loop ++)
- printf (" %d %d\n", loop, dom_list[loop]);
-
- result = caml_alloc(2,0);
- if ( count > 0 ) /* car */
- {
- node = caml_alloc(2,0);
- Store_field(node, 0, Val_int(dom_list[0])); /* domain id */
- Store_field(node, 1, Val_int(0)); /* vcpu */
- Store_field(result, 0, node);
- }
- else
- {
- Store_field(result, 0, Val_int(0));
- }
- Store_field(result, 1, Val_int(0)); /* cdr */
-
- for ( loop = 1; loop < count; loop++ )
- {
- temp = result;
- result = caml_alloc(2,0);
- node = caml_alloc(2,0);
- Store_field(node, 0, Val_int(dom_list[loop])); /* domain id */
- Store_field(node, 1, Val_int(0)); /* vcpu */
- Store_field(result, 0, node);
- Store_field(result, 1, temp);
- }
-
- CAMLreturn(result);
-}
-
-/****************************************************************************/
-/****************************************************************************/
-
-#include <errno.h>
-#include <sys/ioctl.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <unistd.h>
-
-/*
- * evtchn_open : string -> int -> int -> Unix.file_descr
- *
- * OCaml's Unix library doesn't have mknod, so it makes more sense just write
- * this in C. This code is from Keir/Andy.
- */
-value
-evtchn_open (value filename, value major, value minor)
-{
- CAMLparam3(filename, major, minor);
-
- char *myfilename = String_val(filename);
- int mymajor = Int_val(major);
- int myminor = Int_val(minor);
- int evtchn_fd;
- struct stat st;
-
- /* Make sure any existing device file links to correct device. */
- if ( (lstat(myfilename, &st) != 0) ||
- !S_ISCHR(st.st_mode) ||
- (st.st_rdev != makedev(mymajor, myminor)) )
- {
- (void)unlink(myfilename);
- }
-
- reopen:
- evtchn_fd = open(myfilename, O_RDWR);
- if ( evtchn_fd == -1 )
- {
- if ( (errno == ENOENT) &&
- ((mkdir("/dev/xen", 0755) == 0) || (errno == EEXIST)) &&
- (mknod(myfilename, S_IFCHR|0600, makedev(mymajor,myminor)) == 0) )
- {
- goto reopen;
- }
- return -errno;
- }
-
- CAMLreturn(Val_int(evtchn_fd));
-}
-
-/*
* evtchn_bind_virq : int -> int
*/
value
@@ -612,8 +111,9 @@ evtchn_bind_virq (value virq)
CAMLparam1(virq);
int port;
+ int my_virq = Int_val(virq);
- if ( pdb_evtchn_bind_virq(xc_handle, Int_val(virq), &port) < 0 )
+ if ( xc_evtchn_bind_virq(xc_handle, my_virq, &port) < 0 )
{
printf("(pdb) evtchn_bind_virq error!\n"); fflush(stdout);
failwith("evtchn_bind_virq error");
@@ -623,102 +123,40 @@ evtchn_bind_virq (value virq)
}
/*
- * evtchn_bind : Unix.file_descr -> int -> unit
+ * evtchn_bind_interdomain : int -> int * int
*/
value
-evtchn_bind (value fd, value idx)
+evtchn_bind_interdomain (value remote_domain)
{
- CAMLparam2(fd, idx);
-
- int myfd = Int_val(fd);
- int myidx = Int_val(idx);
-
- if ( xen_evtchn_bind(myfd, myidx) < 0 )
- {
- printf("(pdb) evtchn_bind error!\n"); fflush(stdout);
- failwith("evtchn_bind error");
- }
-
- CAMLreturn(Val_unit);
-}
-
-/*
- * evtchn_unbind : Unix.file_descr -> int -> unit
- */
-value
-evtchn_unbind (value fd, value idx)
-{
- CAMLparam2(fd, idx);
+ CAMLparam1(remote_domain);
+ CAMLlocal1(result);
- int myfd = Int_val(fd);
- int myidx = Int_val(idx);
+ int my_remote_domain = Int_val(remote_domain);
+ int local_domain = 0;
+ int local_port = 0;
+ int remote_port = 0;
- if ( xen_evtchn_unbind(myfd, myidx) < 0 )
+ if ( xc_evtchn_bind_interdomain(xc_handle, local_domain, my_remote_domain,
+ &local_port, &remote_port) < 0 )
{
- printf("(pdb) evtchn_unbind error!\n"); fflush(stdout);
- failwith("evtchn_unbind error");
+ printf("(pdb) evtchn_bind_interdomain error!\n"); fflush(stdout);
+ failwith("evtchn_bind_interdomain error");
}
- CAMLreturn(Val_unit);
-}
+ result = caml_alloc_tuple(2); /* FIXME */
+ Store_field(result, 0, Val_int(local_port));
+ Store_field(result, 1, Val_int(remote_port));
-/*
- * evtchn_read : Unix.file_descr -> int
- */
-value
-evtchn_read (value fd)
-{
- CAMLparam1(fd);
-
- u16 v;
- int bytes;
- int rc = -1;
- int myfd = Int_val(fd);
-
- while ( (bytes = read(myfd, &v, sizeof(v))) == -1 )
- {
- if ( errno == EINTR ) continue;
- rc = -errno;
- goto exit;
- }
-
- if ( bytes == sizeof(v) )
- rc = v;
-
- exit:
- CAMLreturn(Val_int(rc));
+ CAMLreturn(result);
}
-
-/*
- * evtchn_close : Unix.file_descr -> unit
- */
-value
-evtchn_close (value fd)
+void *
+map_ring(u32 dom, unsigned long mfn )
{
- CAMLparam1(fd);
- int myfd = Int_val(fd);
-
- (void)close(myfd);
-
- CAMLreturn(Val_unit);
+ return xc_map_foreign_range(xc_handle, dom, PAGE_SIZE,
+ PROT_READ | PROT_WRITE, mfn);
}
-/*
- * evtchn_unmask : Unix.file_descr -> int -> unit
- */
-value
-evtchn_unmask (value fd, value idx)
-{
- CAMLparam1(fd);
-
- int myfd = Int_val(fd);
- u16 myidx = Int_val(idx);
-
- (void)write(myfd, &myidx, sizeof(myidx));
-
- CAMLreturn(Val_unit);
-}
/*
* Local variables: