diff options
author | kaf24@freefall.cl.cam.ac.uk <kaf24@freefall.cl.cam.ac.uk> | 2004-11-13 17:17:59 +0000 |
---|---|---|
committer | kaf24@freefall.cl.cam.ac.uk <kaf24@freefall.cl.cam.ac.uk> | 2004-11-13 17:17:59 +0000 |
commit | 5435ea302127058a5f7f9b76f20d64ded949fd5a (patch) | |
tree | 7fadeb7693fffee58641f482eb973c1b8420ba18 /xen/include/asm-x86/debugger.h | |
parent | 92d81c3c284e90da3169e79b5e8ab91e17403961 (diff) | |
download | xen-5435ea302127058a5f7f9b76f20d64ded949fd5a.tar.gz xen-5435ea302127058a5f7f9b76f20d64ded949fd5a.tar.bz2 xen-5435ea302127058a5f7f9b76f20d64ded949fd5a.zip |
bitkeeper revision 1.1159.170.19 (419641c7PFSwb0OCvYznpBOaQJY6Fw)
Cleaned up debugger interface to traps.c.
Diffstat (limited to 'xen/include/asm-x86/debugger.h')
-rw-r--r-- | xen/include/asm-x86/debugger.h | 137 |
1 files changed, 137 insertions, 0 deletions
diff --git a/xen/include/asm-x86/debugger.h b/xen/include/asm-x86/debugger.h new file mode 100644 index 0000000000..b19e099a9f --- /dev/null +++ b/xen/include/asm-x86/debugger.h @@ -0,0 +1,137 @@ +/****************************************************************************** + * asm/debugger.h + * + * Generic hooks into arch-dependent Xen. + * + * Each debugger should define two functions here: + * + * 1. debugger_trap_entry(): + * Called at start of any synchronous fault or trap, before any other work + * is done. The idea is that if your debugger deliberately caused the trap + * (e.g. to implement breakpoints or data watchpoints) then you can take + * appropriate action and return a non-zero value to cause early exit from + * the trap function. + * + * 2. debugger_trap_fatal(): + * Called when Xen is about to give up and crash. Typically you will use this + * hook to drop into a debug session. It can also be used to hook off + * deliberately caused traps (which you then handle and return non-zero) + * but really these should be hooked off 'debugger_trap_entry'. + */ + +#ifndef __X86_DEBUGGER_H__ +#define __X86_DEBUGGER_H__ + +/* Avoid magic vector numbers by using these semi-sensical names. */ +#define TRAP_divide_error 0 +#define TRAP_debug 1 +#define TRAP_nmi 2 +#define TRAP_int3 3 +#define TRAP_overflow 4 +#define TRAP_bounds 5 +#define TRAP_invalid_op 6 +#define TRAP_no_device 7 +#define TRAP_double_fault 8 +#define TRAP_copro_seg 9 +#define TRAP_invalid_tss 10 +#define TRAP_no_segment 11 +#define TRAP_stack_error 12 +#define TRAP_gp_fault 13 +#define TRAP_page_fault 14 +#define TRAP_spurious_int 15 +#define TRAP_copro_error 16 +#define TRAP_alignment_check 17 +#define TRAP_machine_check 18 +#define TRAP_simd_error 19 + +/* The main trap handlers use these helper macros which include early bail. */ +#define DEBUGGER_trap_entry(_v, _r, _e) \ + if ( debugger_trap_entry(_v, _r, _e) ) return; +#define DEBUGGER_trap_fatal(_v, _r, _e) \ + if ( debugger_trap_fatal(_v, _r, _e) ) return; + +#ifdef XEN_DEBUGGER + +#include <asm/pdb.h> + +static inline int debugger_trap_entry( + unsigned int vector, struct xen_regs *regs, unsigned int error_code) +{ + int ret = 0; + + switch ( vector ) + { + case TRAP_debug: + if ( pdb_initialized ) + { + pdb_handle_debug_trap(regs, (long)error_code); + ret = 1; /* early exit */ + } + break; + + case TRAP_int3: + if ( pdb_initialized && (pdb_handle_exception(vector, regs) == 0) ) + ret = 1; /* early exit */ + break; + + case TRAP_gp_fault: + if ( ((regs->cs & 3) != 0) && ((error_code & 3) == 2) && + pdb_initialized && (pdb_ctx.system_call != 0) ) + { + unsigned long cr3 = read_cr3(); + if ( cr3 == pdb_ctx.ptbr ) + pdb_linux_syscall_enter_bkpt( + regs, error_code, current->thread.traps + (error_code>>3)); + } + break; + } + + return ret; +} + +static inline int debugger_trap_fatal( + unsigned int vector, struct xen_regs *regs, unsigned int error_code) +{ + int ret = 0; + + switch ( vector ) + { + case TRAP_page_fault: + if ( pdb_page_fault_possible ) + { + pdb_page_fault = 1; + /* make eax & edx valid to complete the instruction */ + regs->eax = (long)&pdb_page_fault_scratch; + regs->edx = (long)&pdb_page_fault_scratch; + ret = 1; /* exit - do not crash! */ + } + break; + } + + return ret; +} + +#elif 0 + +extern int kdb_trap(int, int, struct xen_regs *); + +static inline int debugger_trap_entry( + unsigned int vector, struct xen_regs *regs, unsigned int error_code) +{ + return 0; +} + +static inline int debugger_trap_fatal( + unsigned int vector, struct xen_regs *regs, unsigned int error_code) +{ + return kdb_trap(vector, 0, regs); +} + +#else + +#define debugger_trap_entry(_v, _r, _e) (0) +#define debugger_trap_fatal(_v, _r, _e) (0) + +#endif + +#endif /* __X86_DEBUGGER_H__ */ |