[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] pdb: read/write registers for process target
# HG changeset patch # User ach61@xxxxxxxxxxxxxxxxxxxxxx # Node ID 9697bc63d4039196b15378f3b3fe406c6a445ea2 # Parent 722c372fe2017414acd568874a313a8f5e8685f5 pdb: read/write registers for process target diff -r 722c372fe201 -r 9697bc63d403 tools/debugger/pdb/Process.ml --- a/tools/debugger/pdb/Process.ml Sat Jul 16 16:45:24 2005 +++ b/tools/debugger/pdb/Process.ml Sun Jul 17 14:16:21 2005 @@ -54,7 +54,7 @@ proc_ctx.ring <- Xen_domain.get_ring dom_ctx; _attach_debugger proc_ctx -external read_registers : context_t -> registers = "proc_read_registers" +external read_registers : context_t -> unit = "proc_read_registers" external write_register : context_t -> register -> int32 -> unit = "proc_write_register" external read_memory : context_t -> int32 -> int -> int list = diff -r 722c372fe201 -r 9697bc63d403 tools/debugger/pdb/linux-2.6-module/Makefile --- a/tools/debugger/pdb/linux-2.6-module/Makefile Sat Jul 16 16:45:24 2005 +++ b/tools/debugger/pdb/linux-2.6-module/Makefile Sun Jul 17 14:16:21 2005 @@ -1,4 +1,4 @@ -XEN_ROOT=../../../.. +XEN_ROOT = ../../../.. LINUX_DIR = linux-2.6.12-xenU KDIR = $(XEN_ROOT)/$(LINUX_DIR) diff -r 722c372fe201 -r 9697bc63d403 tools/debugger/pdb/server.ml --- a/tools/debugger/pdb/server.ml Sat Jul 16 16:45:24 2005 +++ b/tools/debugger/pdb/server.ml Sun Jul 17 14:16:21 2005 @@ -9,7 +9,7 @@ open Unix open Buffer - +open Util (** * connection_t: The state for each connection. @@ -98,7 +98,7 @@ (String.escaped reply)); Util.send_reply sock reply with - Debugger.No_reply -> + Util.No_reply -> print_endline (Printf.sprintf "[%s] %s -> null" (Util.get_connection_info sock) (String.escaped command)) diff -r 722c372fe201 -r 9697bc63d403 tools/debugger/pdb/Xen_domain.ml --- a/tools/debugger/pdb/Xen_domain.ml Sat Jul 16 16:45:24 2005 +++ b/tools/debugger/pdb/Xen_domain.ml Sun Jul 17 14:16:21 2005 @@ -40,4 +40,4 @@ let string_of_context ctx = Printf.sprintf "{xen domain assist} domain: %d" ctx.domain -external process_response : int32 -> unit = "process_handle_response" +external process_response : int32 -> int * int * string = "process_handle_response" diff -r 722c372fe201 -r 9697bc63d403 tools/debugger/pdb/linux-2.6-module/debug.c --- a/tools/debugger/pdb/linux-2.6-module/debug.c Sat Jul 16 16:45:24 2005 +++ b/tools/debugger/pdb/linux-2.6-module/debug.c Sun Jul 17 14:16:21 2005 @@ -55,15 +55,47 @@ /* * from linux-2.6.11/arch/i386/kernel/ptrace.c::getreg() */ + +static unsigned long +_pdb_get_register (struct task_struct *target, int reg) +{ + unsigned long result = ~0UL; + unsigned long offset; + unsigned char *stack = 0L; + + switch (reg) + { + case FS: + result = target->thread.fs; + break; + case GS: + result = target->thread.gs; + break; + case DS: + case ES: + case SS: + case CS: + result = 0xffff; + /* fall through */ + default: + if (reg > GS) + reg -= 2; + + offset = reg * sizeof(long); + offset -= sizeof(struct pt_regs); + stack = (unsigned char *)target->thread.esp0; + stack += offset; + result &= *((int *)stack); + } + + return result; +} + int -pdb_read_register (int pid, pdb_op_rd_reg_p op, unsigned long *dest) +pdb_read_register (int pid, pdb_op_rd_regs_p op) { int rc = 0; struct task_struct *target; - unsigned long offset; - unsigned char *stack = 0L; - - *dest = ~0UL; read_lock(&tasklist_lock); target = find_task_by_pid(pid); @@ -71,35 +103,23 @@ get_task_struct(target); read_unlock(&tasklist_lock); - switch (op->reg) - { - case FS: - *dest = target->thread.fs; - break; - case GS: - *dest = target->thread.gs; - break; - case DS: - case ES: - case SS: - case CS: - *dest = 0xffff; - /* fall through */ - default: - if (op->reg > GS) - op->reg -= 2; + op->reg[ 0] = _pdb_get_register(target, LINUX_EAX); + op->reg[ 1] = _pdb_get_register(target, LINUX_ECX); + op->reg[ 2] = _pdb_get_register(target, LINUX_EDX); + op->reg[ 3] = _pdb_get_register(target, LINUX_EBX); + op->reg[ 4] = _pdb_get_register(target, LINUX_ESP); + op->reg[ 5] = _pdb_get_register(target, LINUX_EBP); + op->reg[ 6] = _pdb_get_register(target, LINUX_ESI); + op->reg[ 7] = _pdb_get_register(target, LINUX_EDI); + op->reg[ 8] = _pdb_get_register(target, LINUX_EIP); + op->reg[ 9] = _pdb_get_register(target, LINUX_EFL); - offset = op->reg * sizeof(long); - offset -= sizeof(struct pt_regs); - stack = (unsigned char *)target->thread.esp0; - stack += offset; - *dest &= *((int *)stack); - } - - /* - printk ("pdb read register: 0x%x %2d 0x%p 0x%lx\n", - pid, op->reg, stack, *dest); - */ + op->reg[10] = _pdb_get_register(target, LINUX_CS); + op->reg[11] = _pdb_get_register(target, LINUX_SS); + op->reg[12] = _pdb_get_register(target, LINUX_DS); + op->reg[13] = _pdb_get_register(target, LINUX_ES); + op->reg[14] = _pdb_get_register(target, LINUX_FS); + op->reg[15] = _pdb_get_register(target, LINUX_GS); return rc; } diff -r 722c372fe201 -r 9697bc63d403 tools/debugger/pdb/pdb_caml_xen.h --- a/tools/debugger/pdb/pdb_caml_xen.h Sat Jul 16 16:45:24 2005 +++ b/tools/debugger/pdb/pdb_caml_xen.h Sun Jul 17 14:16:21 2005 @@ -10,11 +10,12 @@ #ifndef _PDB_CAML_XEN_DEFINED_ #define _PDB_CAML_XEN_DEFINED_ -enum gdb_registers { GDB_EAX, GDB_ECX, GDB_EDX, GDB_EBX, - GDB_ESP, GDB_EBP, GDB_ESI, GDB_EDI, - GDB_EIP, GDB_EFL, - GDB_CS, GDB_SS, GDB_DS, GDB_ES, - GDB_FS, GDB_GS }; +enum gdb_registers { /* 32 */ GDB_EAX, GDB_ECX, GDB_EDX, GDB_EBX, + GDB_ESP, GDB_EBP, GDB_ESI, GDB_EDI, + GDB_EIP, GDB_EFL, + /* 16 */ GDB_CS, GDB_SS, GDB_DS, GDB_ES, + GDB_FS, GDB_GS }; +#define GDB_REGISTER_FRAME_SIZE 16 /* this order comes from linux-2.6.11/include/asm-i386/ptrace.h */ enum x86_registers { LINUX_EBX, LINUX_ECX, LINUX_EDX, LINUX_ESI, LINUX_EDI, @@ -24,7 +25,11 @@ #define REGISTER_FRAME_SIZE 17 +/* hack: this is also included from the pdb linux module which + has PAGE_SIZE defined */ +#ifndef PAGE_SIZE #define PAGE_SIZE 4096 +#endif extern int xc_handle; diff -r 722c372fe201 -r 9697bc63d403 tools/debugger/pdb/pdb_caml_process.c --- a/tools/debugger/pdb/pdb_caml_process.c Sat Jul 16 16:45:24 2005 +++ b/tools/debugger/pdb/pdb_caml_process.c Sun Jul 17 14:16:21 2005 @@ -66,49 +66,89 @@ } /* - * read a response from a pdb domain backend. + * process_handle_response : int32 -> int * int * string * - * grabs the response off a ring. - */ -static void -read_response (pdb_front_ring_t *pdb_ring, pdb_response_p response) -{ - RING_IDX loop, rp; - - rp = pdb_ring->sring->rsp_prod; + * A backend domain has notified pdb (via an event channel) + * that a command has finished. + * We read the result from the channel and formulate a response + * as a single string. Also return the domain and process. + */ + +static inline unsigned int +_flip (unsigned int orig) +{ + return (((orig << 24) & 0xff000000) | ((orig << 8) & 0x00ff0000) | + ((orig >> 8) & 0x0000ff00) | ((orig >> 24) & 0x000000ff)); +} + +value +process_handle_response (value ring) +{ + CAMLparam1(ring); + CAMLlocal2(result, str); + + RING_IDX rp; + pdb_response_p resp; + pdb_front_ring_t *my_ring = (pdb_front_ring_t *)Int32_val(ring); + char msg[2048]; + int msglen; + + memset(msg, 0, sizeof(msg)); + + rp = my_ring->sring->rsp_prod; rmb(); /* Ensure we see queued responses up to 'rp'. */ - for ( loop = pdb_ring->rsp_cons; loop != rp; loop++ ) - { - pdb_response_p resp; - - resp = RING_GET_RESPONSE(pdb_ring, loop); - memcpy(response, resp, sizeof(pdb_response_t)); - - /* - printf ("got response %x %x %x\n", response->operation, - response->status, response->value); - */ - } - pdb_ring->rsp_cons = loop; -} - -/* - * process_handle_response : int32 -> unit - */ - -value -process_handle_response (value ring) -{ - CAMLparam1(ring); - - pdb_front_ring_t *my_ring = (pdb_front_ring_t *)Int32_val(ring); - pdb_response_t resp; - - if ( my_ring ) - read_response(my_ring, &resp); - - CAMLreturn(Val_unit); + sprintf(msg, "OK"); + + /* for ( loop = my_ring->rsp_cons; loop != rp; loop++ ) */ + if (my_ring->rsp_cons != rp) + { + resp = RING_GET_RESPONSE(my_ring, my_ring->rsp_cons); + + switch (resp->operation) + { + case PDB_OPCODE_ATTACH : + case PDB_OPCODE_DETACH : + break; + + case PDB_OPCODE_RD_REGS : + { + int loop; + pdb_op_rd_regs_p regs = &resp->u.rd_regs; + + for (loop = 0; loop < GDB_REGISTER_FRAME_SIZE * 8; loop += 8) + { + sprintf(&msg[loop], "%08x", _flip(regs->reg[loop >> 3])); + } + + break; + } + + case PDB_OPCODE_WR_REG : + { + printf("(linux) wr regs\n"); + /* should check the return status */ + break; + } + default : + printf("(process) UNKNOWN MESSAGE TYPE IN RESPONSE\n"); + break; + } + + my_ring->rsp_cons++; + } + /* my_ring->rsp_cons = loop; */ + + msglen = strlen(msg); + result = caml_alloc(3,0); + str = alloc_string(msglen); + memmove(&Byte(str,0), msg, msglen); + + Store_field(result, 0, Val_int(resp->domain)); + Store_field(result, 1, Val_int(resp->process)); + Store_field(result, 2, str); + + CAMLreturn(result); } /* @@ -120,13 +160,8 @@ CAMLparam1(context); context_t ctx; pdb_request_t req; - pdb_response_t resp; - - decode_context(&ctx, context); - - printf("(pdb) attach process [%d.%d] %d %p\n", ctx.domain, ctx.process, - ctx.evtchn, ctx.ring); - fflush(stdout); + + decode_context(&ctx, context); req.operation = PDB_OPCODE_ATTACH; req.domain = ctx.domain; @@ -134,14 +169,6 @@ send_request (ctx.ring, ctx.evtchn, &req); - printf("awaiting response\n"); - fflush(stdout); - - read_response (ctx.ring, &resp); - - printf("response %d %d\n", resp.operation, resp.status); - fflush(stdout); - CAMLreturn(Val_unit); } @@ -191,56 +218,25 @@ /* - * proc_read_registers : context_t -> int32 + * proc_read_registers : context_t -> unit */ value proc_read_registers (value context) { CAMLparam1(context); - CAMLlocal1(result); - - u32 regs[REGISTER_FRAME_SIZE]; pdb_request_t req; context_t ctx; - int loop; - - decode_context(&ctx, context); - - req.operation = PDB_OPCODE_RD_REG; + + decode_context(&ctx, context); + + req.operation = PDB_OPCODE_RD_REGS; req.domain = ctx.domain; req.process = ctx.process; - for (loop = 0; loop < REGISTER_FRAME_SIZE; loop++) - { - pdb_response_t resp; - - req.u.rd_reg.reg = loop; - send_request(ctx.ring, ctx.evtchn, &req); - read_response(ctx.ring, &resp); - regs[loop] = resp.value; - } - - result = caml_alloc_tuple(16); - - Store_field(result, 0, caml_copy_int32(regs[LINUX_EAX])); - Store_field(result, 1, caml_copy_int32(regs[LINUX_ECX])); - Store_field(result, 2, caml_copy_int32(regs[LINUX_EDX])); - Store_field(result, 3, caml_copy_int32(regs[LINUX_EBX])); - Store_field(result, 4, caml_copy_int32(regs[LINUX_ESP])); - Store_field(result, 5, caml_copy_int32(regs[LINUX_EBP])); - Store_field(result, 6, caml_copy_int32(regs[LINUX_ESI])); - Store_field(result, 7, caml_copy_int32(regs[LINUX_EDI])); - Store_field(result, 8, caml_copy_int32(regs[LINUX_EIP])); - Store_field(result, 9, caml_copy_int32(regs[LINUX_EFL])); - Store_field(result, 10, caml_copy_int32(regs[LINUX_CS])); /* 16 */ - Store_field(result, 11, caml_copy_int32(regs[LINUX_SS])); /* 16 */ - Store_field(result, 12, caml_copy_int32(regs[LINUX_DS])); /* 16 */ - Store_field(result, 13, caml_copy_int32(regs[LINUX_ES])); /* 16 */ - Store_field(result, 14, caml_copy_int32(regs[LINUX_FS])); /* 16 */ - Store_field(result, 15, caml_copy_int32(regs[LINUX_GS])); /* 16 */ - - CAMLreturn(result); + send_request (ctx.ring, ctx.evtchn, &req); + + CAMLreturn(Val_unit); } @@ -257,7 +253,6 @@ context_t ctx; pdb_request_t req; - pdb_response_t resp; decode_context(&ctx, context); @@ -290,7 +285,6 @@ } send_request(ctx.ring, ctx.evtchn, &req); - read_response(ctx.ring, &resp); CAMLreturn(Val_unit); } diff -r 722c372fe201 -r 9697bc63d403 .hgignore --- a/.hgignore Sat Jul 16 16:45:24 2005 +++ b/.hgignore Sun Jul 17 14:16:21 2005 @@ -87,6 +87,11 @@ ^tools/cmdline/.*$ ^tools/cmdline/xen/.*$ ^tools/debugger/pdb/pdb$ +^tools/debugger/pdb/linux-[0-9.]*-module/.*\.ko$ +^tools/debugger/pdb/linux-[0-9.]*-module/.*\.mod.c$ +^tools/debugger/pdb/linux-[0-9.]*-module/\..*\.cmd$ +^tools/debugger/pdb/linux-[0-9.]*-module/.tmp_versions/.*$ +^tools/debugger/pdb/._bcdi/.*$ ^tools/firmware/acpi/acpigen$ ^tools/firmware/.*\.bin$ ^tools/firmware/.*\.sym$ diff -r 722c372fe201 -r 9697bc63d403 tools/debugger/pdb/linux-2.6-module/module.c --- a/tools/debugger/pdb/linux-2.6-module/module.c Sat Jul 16 16:45:24 2005 +++ b/tools/debugger/pdb/linux-2.6-module/module.c Sun Jul 17 14:16:21 2005 @@ -54,6 +54,10 @@ { pdb_response_t resp; + resp.operation = request->operation; + resp.domain = request->domain; + resp.process = request->process; + switch (request->operation) { case PDB_OPCODE_ATTACH : @@ -64,9 +68,8 @@ pdb_detach(request->process); resp.status = PDB_RESPONSE_OKAY; break; - case PDB_OPCODE_RD_REG : - pdb_read_register(request->process, &request->u.rd_reg, - (unsigned long *)&resp.value); + case PDB_OPCODE_RD_REGS : + pdb_read_register(request->process, &resp.u.rd_regs); resp.status = PDB_RESPONSE_OKAY; break; case PDB_OPCODE_WR_REG : @@ -78,8 +81,6 @@ resp.status = PDB_RESPONSE_ERROR; } - resp.operation = request->operation; - pdb_send_response (&resp); return; } diff -r 722c372fe201 -r 9697bc63d403 tools/debugger/pdb/linux-2.6-module/pdb_module.h --- a/tools/debugger/pdb/linux-2.6-module/pdb_module.h Sat Jul 16 16:45:24 2005 +++ b/tools/debugger/pdb/linux-2.6-module/pdb_module.h Sun Jul 17 14:16:21 2005 @@ -2,14 +2,16 @@ #ifndef __XEN_PDB_H_ #define __XEN_PDB_H_ +#include "../pdb_caml_xen.h" + #define PDB_OPCODE_ATTACH 1 #define PDB_OPCODE_DETACH 2 -#define PDB_OPCODE_RD_REG 3 -typedef struct pdb_op_rd_reg +#define PDB_OPCODE_RD_REGS 3 +typedef struct pdb_op_rd_regs { - u32 reg; -} pdb_op_rd_reg_t, *pdb_op_rd_reg_p; + u32 reg[GDB_REGISTER_FRAME_SIZE]; +} pdb_op_rd_regs_t, *pdb_op_rd_regs_p; #define PDB_OPCODE_WR_REG 4 typedef struct pdb_op_wr_reg @@ -25,8 +27,7 @@ u32 process; union { - pdb_op_rd_reg_t rd_reg; - pdb_op_wr_reg_t wr_reg; + pdb_op_wr_reg_t wr_reg; } u; } pdb_request_t, *pdb_request_p; @@ -36,8 +37,13 @@ typedef struct { u8 operation; /* copied from request */ + u32 domain; + u32 process; s16 status; /* PDB_RESPONSE_??? */ - u32 value; + union + { + pdb_op_rd_regs_t rd_regs; + } u; } pdb_response_t, *pdb_response_p; @@ -46,7 +52,7 @@ int pdb_attach (int pid); int pdb_detach (int pid); -int pdb_read_register (int pid, pdb_op_rd_reg_p op, unsigned long *dest); +int pdb_read_register (int pid, pdb_op_rd_regs_p op); int pdb_write_register (int pid, pdb_op_wr_reg_p op); diff -r 722c372fe201 -r 9697bc63d403 tools/debugger/pdb/debugger.ml --- a/tools/debugger/pdb/debugger.ml Sat Jul 16 16:45:24 2005 +++ b/tools/debugger/pdb/debugger.ml Sun Jul 17 14:16:21 2005 @@ -11,12 +11,6 @@ open PDB open Util open Str - -(** a few debugger commands such as step 's' and continue 'c' do - * not immediately return a response to the debugger. in these - * cases we raise No_reply instead. - *) -exception No_reply let initialize_debugger () = () @@ -295,12 +289,17 @@ let channel = Evtchn.read fd in let ctx = find_context fd in + let (dom, pid, str) = begin match ctx with | Xen_domain d -> Xen_domain.process_response (Xen_domain.get_ring d) | _ -> failwith ("process_xen_domain called without Xen_domain context") - end; - + end + in + let sock = PDB.find_process dom pid in + print_endline (Printf.sprintf "(linux) dom:%d pid:%d %s %s" + dom pid str (Util.get_connection_info sock)); + Util.send_reply sock str; Evtchn.unmask fd channel (* allow next virq *) diff -r 722c372fe201 -r 9697bc63d403 tools/debugger/pdb/Process.mli --- a/tools/debugger/pdb/Process.mli Sat Jul 16 16:45:24 2005 +++ b/tools/debugger/pdb/Process.mli Sun Jul 17 14:16:21 2005 @@ -27,7 +27,7 @@ val pause : context_t -> unit -val read_registers : context_t -> registers +val read_registers : context_t -> unit val write_register : context_t -> register -> int32 -> unit val read_memory : context_t -> int32 -> int -> int list val write_memory : context_t -> int32 -> int list -> unit diff -r 722c372fe201 -r 9697bc63d403 tools/debugger/pdb/Util.ml --- a/tools/debugger/pdb/Util.ml Sat Jul 16 16:45:24 2005 +++ b/tools/debugger/pdb/Util.ml Sun Jul 17 14:16:21 2005 @@ -154,3 +154,12 @@ * BUG NEED TO LISTEN FOR REPLY +/- AND POSSIBLY RE-TRANSMIT *) + +(** A few debugger commands such as step 's' and continue 'c' do + * not immediately return a response to the debugger. In these + * cases we raise No_reply instead. + * This is also used by some contexts (such as Linux processes) + * which utilize an asynchronous request / response protocol when + * communicating with their respective backends. + *) +exception No_reply diff -r 722c372fe201 -r 9697bc63d403 tools/debugger/pdb/Xen_domain.mli --- a/tools/debugger/pdb/Xen_domain.mli Sat Jul 16 16:45:24 2005 +++ b/tools/debugger/pdb/Xen_domain.mli Sun Jul 17 14:16:21 2005 @@ -21,5 +21,5 @@ val string_of_context : context_t -> string -val process_response : int32 -> unit +val process_response : int32 -> int * int * string diff -r 722c372fe201 -r 9697bc63d403 tools/debugger/pdb/PDB.ml --- a/tools/debugger/pdb/PDB.ml Sat Jul 16 16:45:24 2005 +++ b/tools/debugger/pdb/PDB.ml Sun Jul 17 14:16:21 2005 @@ -7,9 +7,12 @@ * @version 1 *) +open Util + exception Unimplemented of string exception Unknown_context of string exception Unknown_domain +exception Unknown_process type context_t = | Void @@ -44,6 +47,31 @@ let delete_context key = Hashtbl.remove hash key + + +(** + find_process : Locate the socket associated with the context(s) + matching a particular (domain, process id) pair. if there are multiple + contexts (there shouldn't be), then return the first one. + *) + +let find_process dom pid = + let find key ctx list = + match ctx with + | Process p -> + if (((Process.get_domain p) = dom) && + ((Process.get_process p) = pid)) + then + key :: list + else + list + | _ -> list + in + let sock_list = Hashtbl.fold find hash [] in + match sock_list with + | hd::tl -> hd + | [] -> raise Unknown_process + (** find_domain : Locate the socket associated with the context(s) @@ -98,10 +126,13 @@ begin let xdom_sock = find_xen_domain_context (Process.get_domain p) in let xdom_ctx = find_context xdom_sock in - match xdom_ctx with - | Xen_domain d -> - Process.attach_debugger p d - | _ -> failwith ("context has wrong xen domain type") + begin + match xdom_ctx with + | Xen_domain d -> + Process.attach_debugger p d + | _ -> failwith ("context has wrong xen domain type") + end; + raise No_reply end | _ -> raise (Unimplemented "attach debugger") @@ -158,8 +189,8 @@ match params with | dom::pid::_ -> let p = Process(Process.new_context dom pid) in - attach_debugger p; - Hashtbl.replace hash key p + Hashtbl.replace hash key p; + attach_debugger p | _ -> failwith "bogus parameters to process context" end | "xen domain" @@ -188,13 +219,21 @@ match ctx with | Void -> Intel.null_registers (* default for startup *) | Domain d -> Domain.read_registers d - | Process p -> Process.read_registers p + | Process p -> + begin + Process.read_registers p; + raise No_reply + end | _ -> raise (Unimplemented "read registers") let write_register ctx register value = match ctx with | Domain d -> Domain.write_register d register value - | Process p -> Process.write_register p register value + | Process p -> + begin + Process.write_register p register value; + raise No_reply + end | _ -> raise (Unimplemented "write register") _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |