debuggers.hg

view xen/arch/x86/pdb-linux.c @ 3674:fb875591fd72

bitkeeper revision 1.1159.223.63 (42028527-fv-d9BM0_LRp8UKGP19gQ)

Fix NMI deferral.
Signed-off-by: keir.fraser@cl.cam.ac.uk
author kaf24@scramble.cl.cam.ac.uk
date Thu Feb 03 20:10:15 2005 +0000 (2005-02-03)
parents 61a55dee09d8
children
line source
2 /*
3 * pervasive debugger
4 * www.cl.cam.ac.uk/netos/pdb
5 *
6 * alex ho
7 * 2004
8 * university of cambridge computer laboratory
9 *
10 * linux & i386 dependent code. bleech.
11 */
13 #include <asm/pdb.h>
15 /* offset to the first instruction in the linux system call code
16 where we can safely set a breakpoint */
17 unsigned int pdb_linux_syscall_enter_bkpt_offset = 20;
19 /* offset to eflags saved on the stack after an int 80 */
20 unsigned int pdb_linux_syscall_eflags_offset = 48;
22 /* offset to the instruction pointer saved on the stack after an int 80 */
23 unsigned int pdb_linux_syscall_eip_offset = 40;
25 unsigned char
26 pdb_linux_set_bkpt (unsigned long addr)
27 {
28 unsigned char old_instruction = *(unsigned char *)addr;
29 *(unsigned char *)addr = 0xcc;
30 return old_instruction;
31 }
33 void
34 pdb_linux_clr_bkpt (unsigned long addr, unsigned char value)
35 {
36 *(unsigned char *)addr = value;
37 }
39 void
40 pdb_linux_syscall_enter_bkpt (struct xen_regs *regs, long error_code,
41 trap_info_t *ti)
42 {
43 /* set at breakpoint at the beginning of the
44 system call in the target domain */
46 pdb_system_call_enter_instr = pdb_linux_set_bkpt(ti->address +
47 pdb_linux_syscall_enter_bkpt_offset);
48 pdb_system_call = 1;
49 }
51 void
52 pdb_linux_syscall_exit_bkpt (struct xen_regs *regs, struct pdb_context *pdb_ctx)
53 {
54 /*
55 we've hit an int 0x80 in a user's program, jumped into xen
56 (traps.c::do_general_protection()) which re-wrote the next
57 instruction in the os kernel to 0xcc, and then hit that
58 exception.
60 we need to re-write the return instruction in the user's
61 program so that we know when we have finished the system call
62 and are back in the user's program.
64 at this point our stack should look something like this:
66 esp = 0x80a59f0
67 esp + 4 = 0x0
68 esp + 8 = 0x80485a0
69 esp + 12 = 0x2d
70 esp + 16 = 0x80485f4
71 esp + 20 = 0xbffffa48
72 esp + 24 = 0xd
73 esp + 28 = 0xc00a0833
74 esp + 32 = 0x833
75 esp + 36 = 0xd
76 esp + 40 = 0x804dcdd saved eip
77 esp + 44 = 0x82b saved cs
78 esp + 48 = 0x213392 saved eflags
79 esp + 52 = 0xbffffa2c saved esp
80 esp + 56 = 0x833 saved ss
81 esp + 60 = 0x1000000
82 */
84 /* restore the entry instruction for the system call */
85 pdb_linux_clr_bkpt(regs->eip - 1, pdb_system_call_enter_instr);
87 /* save the address of eflags that was saved on the stack */
88 pdb_system_call_eflags_addr = (regs->esp +
89 pdb_linux_syscall_eflags_offset);
91 /* muck with the return instruction so that we trap back into the
92 debugger when re-entering user space */
93 pdb_system_call_next_addr = *(unsigned long *)(regs->esp +
94 pdb_linux_syscall_eip_offset);
95 pdb_linux_get_values (&pdb_system_call_leave_instr, 1,
96 pdb_system_call_next_addr,
97 pdb_ctx->process, pdb_ctx->ptbr);
98 pdb_linux_set_values ("cc", 1, pdb_system_call_next_addr,
99 pdb_ctx->process, pdb_ctx->ptbr);
100 }