ia64/xen-unstable

view tools/debugger/pdb/pdb_caml_domain.c @ 6538:84ee014ebd41

Merge xen-vtx-unstable.hg
author adsharma@los-vmm.sc.intel.com
date Wed Aug 17 12:34:38 2005 -0800 (2005-08-17)
parents 23979fb12c49 60d20acf8928
children 99914b54f7bf
line source
1 /*
2 * pdb_caml_xc.c
3 *
4 * http://www.cl.cam.ac.uk/netos/pdb
5 *
6 * PDB's OCaml interface library for debugging domains
7 */
9 #include <xc.h>
10 #include <xendebug.h>
11 #include <errno.h>
12 #include <stdio.h>
13 #include <stdlib.h>
14 #include <string.h>
15 #include <sys/mman.h>
16 #include <caml/alloc.h>
17 #include <caml/fail.h>
18 #include <caml/memory.h>
19 #include <caml/mlvalues.h>
21 #include "pdb_caml_xen.h"
23 typedef struct
24 {
25 int domain;
26 int vcpu;
27 } context_t;
29 #define decode_context(_ctx, _ocaml) \
30 { \
31 (_ctx)->domain = Int_val(Field((_ocaml),0)); \
32 (_ctx)->vcpu = Int_val(Field((_ocaml),1)); \
33 }
35 #define encode_context(_ctx, _ocaml) \
36 { \
37 (_ocaml) = caml_alloc_tuple(2); \
38 Store_field((_ocaml), 0, Val_int((_ctx)->domain)); \
39 Store_field((_ocaml), 1, Val_int((_ctx)->vcpu)); \
40 }
43 /****************************************************************************/
45 /*
46 * dom_read_register : context_t -> int -> int32
47 */
48 value
49 dom_read_register (value context, value reg)
50 {
51 CAMLparam2(context, reg);
52 CAMLlocal1(result);
54 int my_reg = Int_val(reg);
55 cpu_user_regs_t *regs;
56 context_t ctx;
58 decode_context(&ctx, context);
60 if ( xendebug_read_registers(xc_handle, ctx.domain, ctx.vcpu, &regs) )
61 {
62 printf("(pdb) read registers error!\n"); fflush(stdout);
63 failwith("read registers error");
64 }
66 dump_regs(regs);
68 result = caml_alloc_tuple(16);
70 switch (my_reg)
71 {
72 case GDB_EAX: result = caml_copy_int32(regs->eax); break;
73 case GDB_ECX: result = caml_copy_int32(regs->ecx); break;
74 case GDB_EDX: result = caml_copy_int32(regs->edx); break;
75 case GDB_EBX: result = caml_copy_int32(regs->ebx); break;
76 case GDB_ESP: result = caml_copy_int32(regs->esp); break;
77 case GDB_EBP: result = caml_copy_int32(regs->ebp); break;
78 case GDB_ESI: result = caml_copy_int32(regs->esi); break;
79 case GDB_EDI: result = caml_copy_int32(regs->edi); break;
80 case GDB_EIP: result = caml_copy_int32(regs->eip); break;
81 case GDB_EFL: result = caml_copy_int32(regs->eflags); break;
82 case GDB_CS: result = caml_copy_int32(regs->cs); break;
83 case GDB_SS: result = caml_copy_int32(regs->ss); break;
84 case GDB_DS: result = caml_copy_int32(regs->ds); break;
85 case GDB_ES: result = caml_copy_int32(regs->es); break;
86 case GDB_FS: result = caml_copy_int32(regs->fs); break;
87 case GDB_GS: result = caml_copy_int32(regs->gs); break;
88 }
90 CAMLreturn(result);
91 }
93 /*
94 * dom_read_registers : context_t -> int32
95 */
96 value
97 dom_read_registers (value context)
98 {
99 CAMLparam1(context);
100 CAMLlocal1(result);
102 cpu_user_regs_t *regs;
103 context_t ctx;
105 decode_context(&ctx, context);
107 if ( xendebug_read_registers(xc_handle, ctx.domain, ctx.vcpu, &regs) )
108 {
109 printf("(pdb) read registers error!\n"); fflush(stdout);
110 failwith("read registers error");
111 }
113 dump_regs(regs);
115 result = caml_alloc_tuple(16);
117 Store_field(result, 0, caml_copy_int32(regs->eax));
118 Store_field(result, 1, caml_copy_int32(regs->ecx));
119 Store_field(result, 2, caml_copy_int32(regs->edx));
120 Store_field(result, 3, caml_copy_int32(regs->ebx));
121 Store_field(result, 4, caml_copy_int32(regs->esp));
122 Store_field(result, 5, caml_copy_int32(regs->ebp));
123 Store_field(result, 6, caml_copy_int32(regs->esi));
124 Store_field(result, 7, caml_copy_int32(regs->edi));
125 Store_field(result, 8, caml_copy_int32(regs->eip));
126 Store_field(result, 9, caml_copy_int32(regs->eflags));
127 Store_field(result, 10, caml_copy_int32(regs->cs)); /* 16 */
128 Store_field(result, 11, caml_copy_int32(regs->ss)); /* 16 */
129 Store_field(result, 12, caml_copy_int32(regs->ds)); /* 16 */
130 Store_field(result, 13, caml_copy_int32(regs->es)); /* 16 */
131 Store_field(result, 14, caml_copy_int32(regs->fs)); /* 16 */
132 Store_field(result, 15, caml_copy_int32(regs->gs)); /* 16 */
134 CAMLreturn(result);
135 }
138 /*
139 * dom_write_register : context_t -> register -> int32 -> unit
140 */
141 value
142 dom_write_register (value context, value reg, value newval)
143 {
144 CAMLparam3(context, reg, newval);
146 int my_reg = Int_val(reg);
147 int val = Int32_val(newval);
149 context_t ctx;
150 cpu_user_regs_t *regs;
152 printf("(pdb) write register\n");
154 decode_context(&ctx, context);
156 if ( xendebug_read_registers(xc_handle, ctx.domain, ctx.vcpu, &regs) )
157 {
158 printf("(pdb) write register (get) error!\n"); fflush(stdout);
159 failwith("write register error");
160 }
162 switch (my_reg)
163 {
164 case GDB_EAX: regs->eax = val; break;
165 case GDB_ECX: regs->ecx = val; break;
166 case GDB_EDX: regs->edx = val; break;
167 case GDB_EBX: regs->ebx = val; break;
169 case GDB_ESP: regs->esp = val; break;
170 case GDB_EBP: regs->ebp = val; break;
171 case GDB_ESI: regs->esi = val; break;
172 case GDB_EDI: regs->edi = val; break;
174 case GDB_EIP: regs->eip = val; break;
175 case GDB_EFL: regs->eflags = val; break;
177 case GDB_CS: regs->cs = val; break;
178 case GDB_SS: regs->ss = val; break;
179 case GDB_DS: regs->ds = val; break;
180 case GDB_ES: regs->es = val; break;
181 case GDB_FS: regs->fs = val; break;
182 case GDB_GS: regs->gs = val; break;
183 }
185 if ( xendebug_write_registers(xc_handle, ctx.domain, ctx.vcpu, regs) )
186 {
187 printf("(pdb) write register (set) error!\n"); fflush(stdout);
188 failwith("write register error");
189 }
191 CAMLreturn(Val_unit);
192 }
194 /*
195 * dom_read_memory : context_t -> int32 -> int -> int
196 */
197 value
198 dom_read_memory (value context, value address, value length)
199 {
200 CAMLparam3(context, address, length);
201 CAMLlocal2(result, temp);
203 context_t ctx;
204 int loop;
205 char *buffer;
206 memory_t my_address = Int32_val(address);
207 u32 my_length = Int_val(length);
209 printf ("(pdb) read memory\n");
211 decode_context(&ctx, context);
213 buffer = malloc(my_length);
214 if ( buffer == NULL )
215 {
216 printf("(pdb) read memory: malloc failed.\n"); fflush(stdout);
217 failwith("read memory error");
218 }
220 if ( xendebug_read_memory(xc_handle, ctx.domain, ctx.vcpu,
221 my_address, my_length, buffer) )
222 {
223 printf("(pdb) read memory error!\n"); fflush(stdout);
224 failwith("read memory error");
225 }
227 result = caml_alloc(2,0);
228 if ( my_length > 0 ) /* car */
229 {
230 Store_field(result, 0, Val_int(buffer[my_length - 1] & 0xff));
231 }
232 else
234 {
235 Store_field(result, 0, Val_int(0));
236 }
237 Store_field(result, 1, Val_int(0)); /* cdr */
239 for (loop = 1; loop < my_length; loop++)
240 {
241 temp = result;
242 result = caml_alloc(2,0);
243 Store_field(result, 0, Val_int(buffer[my_length - loop - 1] & 0xff));
244 Store_field(result, 1, temp);
245 }
247 CAMLreturn(result);
248 }
250 /*
251 * dom_write_memory : context_t -> int32 -> int list -> unit
252 */
253 value
254 dom_write_memory (value context, value address, value val_list)
255 {
256 CAMLparam3(context, address, val_list);
257 CAMLlocal1(node);
259 context_t ctx;
261 char buffer[4096]; /* a big buffer */
262 memory_t my_address;
263 u32 length = 0;
265 printf ("(pdb) write memory\n");
267 decode_context(&ctx, context);
269 node = val_list;
270 if ( Int_val(node) == 0 ) /* gdb functionalty test uses empty list */
271 {
272 CAMLreturn(Val_unit);
273 }
275 while ( Int_val(Field(node,1)) != 0 )
276 {
277 buffer[length++] = Int_val(Field(node, 0));
278 node = Field(node,1);
279 }
280 buffer[length++] = Int_val(Field(node, 0));
282 my_address = (memory_t) Int32_val(address);
284 if ( xendebug_write_memory(xc_handle, ctx.domain, ctx.vcpu,
285 my_address, length, buffer) )
286 {
287 printf("(pdb) write memory error!\n"); fflush(stdout);
288 failwith("write memory error");
289 }
291 CAMLreturn(Val_unit);
292 }
294 /*
295 * dom_continue_target : context_t -> unit
296 */
297 value
298 dom_continue_target (value context)
299 {
300 CAMLparam1(context);
302 context_t ctx;
304 decode_context(&ctx, context);
306 if ( xendebug_continue(xc_handle, ctx.domain, ctx.vcpu) )
307 {
308 printf("(pdb) continue\n"); fflush(stdout);
309 failwith("continue");
310 }
312 CAMLreturn(Val_unit);
313 }
315 /*
316 * dom_step_target : context_t -> unit
317 */
318 value
319 dom_step_target (value context)
320 {
321 CAMLparam1(context);
323 context_t ctx;
325 decode_context(&ctx, context);
327 if ( xendebug_step(xc_handle, ctx.domain, ctx.vcpu) )
328 {
329 printf("(pdb) step\n"); fflush(stdout);
330 failwith("step");
331 }
333 CAMLreturn(Val_unit);
334 }
338 /*
339 * dom_insert_memory_breakpoint : context_t -> int32 -> int list -> unit
340 */
341 value
342 dom_insert_memory_breakpoint (value context, value address, value length)
343 {
344 CAMLparam3(context, address, length);
346 context_t ctx;
347 memory_t my_address = (memory_t) Int32_val(address);
348 int my_length = Int_val(length);
350 decode_context(&ctx, context);
352 printf ("(pdb) insert memory breakpoint 0x%lx %d\n",
353 my_address, my_length);
355 if ( xendebug_insert_memory_breakpoint(xc_handle, ctx.domain, ctx.vcpu,
356 my_address, my_length) )
357 {
358 printf("(pdb) error: insert memory breakpoint\n"); fflush(stdout);
359 failwith("insert memory breakpoint");
360 }
363 CAMLreturn(Val_unit);
364 }
366 /*
367 * dom_remove_memory_breakpoint : context_t -> int32 -> int list -> unit
368 */
369 value
370 dom_remove_memory_breakpoint (value context, value address, value length)
371 {
372 CAMLparam3(context, address, length);
374 context_t ctx;
376 memory_t my_address = (memory_t) Int32_val(address);
377 int my_length = Int_val(length);
379 printf ("(pdb) remove memory breakpoint 0x%lx %d\n",
380 my_address, my_length);
382 decode_context(&ctx, context);
384 if ( xendebug_remove_memory_breakpoint(xc_handle,
385 ctx.domain, ctx.vcpu,
386 my_address, my_length) )
387 {
388 printf("(pdb) error: remove memory breakpoint\n"); fflush(stdout);
389 failwith("remove memory breakpoint");
390 }
392 CAMLreturn(Val_unit);
393 }
395 /*
396 * dom_attach_debugger : int -> int -> unit
397 */
398 value
399 dom_attach_debugger (value domain, value vcpu)
400 {
401 CAMLparam2(domain, vcpu);
403 int my_domain = Int_val(domain);
404 int my_vcpu = Int_val(vcpu);
406 printf ("(pdb) attach domain [%d.%d]\n", my_domain, my_vcpu);
408 if ( xendebug_attach(xc_handle, my_domain, my_vcpu) )
409 {
410 printf("(pdb) attach error!\n"); fflush(stdout);
411 failwith("attach error");
412 }
414 CAMLreturn(Val_unit);
415 }
418 /*
419 * dom_detach_debugger : int -> int -> unit
420 */
421 value
422 dom_detach_debugger (value domain, value vcpu)
423 {
424 CAMLparam2(domain, vcpu);
426 int my_domain = Int_val(domain);
427 int my_vcpu = Int_val(vcpu);
429 printf ("(pdb) detach domain [%d.%d]\n", my_domain, my_vcpu);
431 if ( xendebug_detach(xc_handle, my_domain, my_vcpu) )
432 {
433 printf("(pdb) detach error!\n"); fflush(stdout);
434 failwith("detach error");
435 }
437 CAMLreturn(Val_unit);
438 }
441 /*
442 * dom_pause_target : int -> unit
443 */
444 value
445 dom_pause_target (value domid)
446 {
447 CAMLparam1(domid);
449 int my_domid = Int_val(domid);
451 printf ("(pdb) pause target %d\n", my_domid);
453 xc_domain_pause(xc_handle, my_domid);
455 CAMLreturn(Val_unit);
456 }
458 /****************************************************************************/
459 /****************************************************************************/
461 /*
462 * query_domain_stop : unit -> (int * int) list
463 */
464 value
465 query_domain_stop (value unit)
466 {
467 CAMLparam1(unit);
468 CAMLlocal3(result, temp, node);
470 int max_domains = 20;
471 int dom_list[max_domains];
472 int loop, count;
474 count = xendebug_query_domain_stop(xc_handle, dom_list, max_domains);
475 if ( count < 0 )
476 {
477 printf("(pdb) query domain stop!\n"); fflush(stdout);
478 failwith("query domain stop");
479 }
481 printf ("QDS [%d]: \n", count);
482 for (loop = 0; loop < count; loop ++)
483 printf (" %d", dom_list[loop]);
484 printf ("\n");
486 result = caml_alloc(2,0);
487 if ( count > 0 ) /* car */
488 {
489 node = caml_alloc(2,0);
490 Store_field(node, 0, Val_int(dom_list[0])); /* domain id */
491 Store_field(node, 1, Val_int(0)); /* vcpu */
492 Store_field(result, 0, node);
493 }
494 else
495 {
496 Store_field(result, 0, Val_int(0));
497 }
498 Store_field(result, 1, Val_int(0)); /* cdr */
500 for ( loop = 1; loop < count; loop++ )
501 {
502 temp = result;
503 result = caml_alloc(2,0);
504 node = caml_alloc(2,0);
505 Store_field(node, 0, Val_int(dom_list[loop])); /* domain id */
506 Store_field(node, 1, Val_int(0)); /* vcpu */
507 Store_field(result, 0, node);
508 Store_field(result, 1, temp);
509 }
511 CAMLreturn(result);
512 }
514 /****************************************************************************/
518 /*
519 * Local variables:
520 * mode: C
521 * c-set-style: "BSD"
522 * c-basic-offset: 4
523 * tab-width: 4
524 * indent-tabs-mode: nil
525 * End:
526 */