/root/src/xen/xen/include/asm/debugger.h
Line | Count | Source (jump to first uncovered line) |
1 | | /****************************************************************************** |
2 | | * asm/debugger.h |
3 | | * |
4 | | * Generic hooks into arch-dependent Xen. |
5 | | * |
6 | | * Each debugger should define two functions here: |
7 | | * |
8 | | * 1. debugger_trap_entry(): |
9 | | * Called at start of any synchronous fault or trap, before any other work |
10 | | * is done. The idea is that if your debugger deliberately caused the trap |
11 | | * (e.g. to implement breakpoints or data watchpoints) then you can take |
12 | | * appropriate action and return a non-zero value to cause early exit from |
13 | | * the trap function. |
14 | | * |
15 | | * 2. debugger_trap_fatal(): |
16 | | * Called when Xen is about to give up and crash. Typically you will use this |
17 | | * hook to drop into a debug session. It can also be used to hook off |
18 | | * deliberately caused traps (which you then handle and return non-zero). |
19 | | * |
20 | | * 3. debugger_trap_immediate(): |
21 | | * Called if we want to drop into a debugger now. This is essentially the |
22 | | * same as debugger_trap_fatal, except that we use the current register state |
23 | | * rather than the state which was in effect when we took the trap. |
24 | | * For example: if we're dying because of an unhandled exception, we call |
25 | | * debugger_trap_fatal; if we're dying because of a panic() we call |
26 | | * debugger_trap_immediate(). |
27 | | */ |
28 | | |
29 | | #ifndef __X86_DEBUGGER_H__ |
30 | | #define __X86_DEBUGGER_H__ |
31 | | |
32 | | #include <xen/sched.h> |
33 | | #include <asm/regs.h> |
34 | | #include <asm/processor.h> |
35 | | |
36 | | #ifdef CONFIG_CRASH_DEBUG |
37 | | |
38 | | #include <xen/gdbstub.h> |
39 | | |
40 | | static inline bool debugger_trap_fatal( |
41 | | unsigned int vector, struct cpu_user_regs *regs) |
42 | | { |
43 | | int rc = __trap_to_gdb(regs, vector); |
44 | | return ((rc == 0) || (vector == TRAP_int3)); |
45 | | } |
46 | | |
47 | | /* Int3 is a trivial way to gather cpu_user_regs context. */ |
48 | | #define debugger_trap_immediate() __asm__ __volatile__ ( "int3" ); |
49 | | |
50 | | #else |
51 | | |
52 | | static inline bool debugger_trap_fatal( |
53 | | unsigned int vector, struct cpu_user_regs *regs) |
54 | 0 | { |
55 | 0 | return false; |
56 | 0 | } Unexecuted instantiation: domain.c:debugger_trap_fatal Unexecuted instantiation: svm.c:debugger_trap_fatal Unexecuted instantiation: traps.c:debugger_trap_fatal Unexecuted instantiation: nmi.c:debugger_trap_fatal Unexecuted instantiation: domctl.c:debugger_trap_fatal Unexecuted instantiation: debug.c:debugger_trap_fatal Unexecuted instantiation: console.c:debugger_trap_fatal Unexecuted instantiation: shutdown.c:debugger_trap_fatal Unexecuted instantiation: keyhandler.c:debugger_trap_fatal Unexecuted instantiation: vmx.c:debugger_trap_fatal |
57 | | |
58 | 0 | #define debugger_trap_immediate() ((void)0) |
59 | | |
60 | | #endif |
61 | | |
62 | | static inline bool debugger_trap_entry( |
63 | | unsigned int vector, struct cpu_user_regs *regs) |
64 | 5 | { |
65 | 5 | /* |
66 | 5 | * This function is called before any checks are made. Amongst other |
67 | 5 | * things, be aware that during early boot, current is not a safe pointer |
68 | 5 | * to follow. |
69 | 5 | */ |
70 | 5 | struct vcpu *v = current; |
71 | 5 | |
72 | 5 | if ( vector != TRAP_int3 && vector != TRAP_debug ) |
73 | 4 | return false; |
74 | 5 | |
75 | 1 | if ( guest_mode(regs) && guest_kernel_mode(v, regs) && |
76 | 0 | v->domain->debugger_attached ) |
77 | 0 | { |
78 | 0 | if ( vector != TRAP_debug ) /* domain pause is good enough */ |
79 | 0 | current->arch.gdbsx_vcpu_event = vector; |
80 | 0 | domain_pause_for_debugger(); |
81 | 0 | return true; |
82 | 0 | } |
83 | 1 | |
84 | 1 | return false; |
85 | 1 | } Unexecuted instantiation: vmx.c:debugger_trap_entry Unexecuted instantiation: svm.c:debugger_trap_entry traps.c:debugger_trap_entry Line | Count | Source | 64 | 5 | { | 65 | 5 | /* | 66 | 5 | * This function is called before any checks are made. Amongst other | 67 | 5 | * things, be aware that during early boot, current is not a safe pointer | 68 | 5 | * to follow. | 69 | 5 | */ | 70 | 5 | struct vcpu *v = current; | 71 | 5 | | 72 | 5 | if ( vector != TRAP_int3 && vector != TRAP_debug ) | 73 | 4 | return false; | 74 | 5 | | 75 | 1 | if ( guest_mode(regs) && guest_kernel_mode(v, regs) && | 76 | 0 | v->domain->debugger_attached ) | 77 | 0 | { | 78 | 0 | if ( vector != TRAP_debug ) /* domain pause is good enough */ | 79 | 0 | current->arch.gdbsx_vcpu_event = vector; | 80 | 0 | domain_pause_for_debugger(); | 81 | 0 | return true; | 82 | 0 | } | 83 | 1 | | 84 | 1 | return false; | 85 | 1 | } |
Unexecuted instantiation: nmi.c:debugger_trap_entry Unexecuted instantiation: domctl.c:debugger_trap_entry Unexecuted instantiation: debug.c:debugger_trap_entry Unexecuted instantiation: console.c:debugger_trap_entry Unexecuted instantiation: shutdown.c:debugger_trap_entry Unexecuted instantiation: keyhandler.c:debugger_trap_entry Unexecuted instantiation: domain.c:debugger_trap_entry |
86 | | |
87 | | unsigned int dbg_rw_mem(void * __user addr, void * __user buf, |
88 | | unsigned int len, domid_t domid, bool toaddr, |
89 | | uint64_t pgd3); |
90 | | |
91 | | #endif /* __X86_DEBUGGER_H__ */ |