1/* 2 * Copyright 2005-2011, Ingo Weinhold, ingo_weinhold@gmx.de. 3 * Distributed under the terms of the MIT License. 4 */ 5#ifndef _KERNEL_ARCH_X86_USER_DEBUGGER_H 6#define _KERNEL_ARCH_X86_USER_DEBUGGER_H 7 8 9#define ARCH_INIT_USER_DEBUG x86_init_user_debug 10 11// number of breakpoints the CPU supports 12// On 32-bit, DR3 is used to hold the Thread*. 13#ifdef __x86_64__ 14# define X86_BREAKPOINT_COUNT 4 15#else 16# define X86_BREAKPOINT_COUNT 3 17#endif 18 19// debug status register DR6 20enum { 21 X86_DR6_B0 = 0, // breakpoint condition detected 22 X86_DR6_B1 = 1, // 23 X86_DR6_B2 = 2, // 24 X86_DR6_B3 = 3, // 25 X86_DR6_BD = 13, // debug register access detected 26 X86_DR6_BS = 14, // single step 27 X86_DR6_BT = 15, // task switch 28 29 X86_DR6_BREAKPOINT_MASK = (1 << X86_DR6_B0) | (1 << X86_DR6_B1) 30 | (1 << X86_DR6_B2) | (1 << X86_DR6_B3), 31}; 32 33// debug control register DR7 layout: 34// 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 35// LEN3 R/W3 LEN2 R/W2 LEN1 R/W1 LEN0 R/W0 36// 37// 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 38// 0 0 GD 0 0 1 GE LE G3 L3 G2 L2 G1 L1 G0 L0 39// 40enum { 41 X86_DR7_L0 = 0, // local/global breakpoints enable 42 X86_DR7_G0 = 1, // 43 X86_DR7_L1 = 2, // 44 X86_DR7_G1 = 3, // 45 X86_DR7_L2 = 4, // 46 X86_DR7_G2 = 5, // 47 X86_DR7_L3 = 6, // 48 X86_DR7_G3 = 7, // 49 X86_DR7_LE = 8, // local/global exact breakpoint 50 X86_DR7_GE = 9, // 51 X86_DR7_GD = 13, // general detect enable: disallows debug 52 // register access 53 X86_DR7_RW0_LSB = 16, // breakpoints type and len 54 X86_DR7_LEN0_LSB = 18, // 55 X86_DR7_RW1_LSB = 20, // 56 X86_DR7_LEN1_LSB = 22, // 57 X86_DR7_RW2_LSB = 24, // 58 X86_DR7_LEN2_LSB = 26, // 59 X86_DR7_RW3_LSB = 28, // 60 X86_DR7_LEN3_LSB = 30, // 61 62 X86_BREAKPOINTS_DISABLED_DR7 63 = (1 << 10) | (1 << X86_DR7_GE) | (1 << X86_DR7_LE), 64 // all breakpoints disabled 65}; 66 67// the EFLAGS flags we need 68enum { 69 X86_EFLAGS_CF = 0, // carry flag 70 X86_EFLAGS_PF = 2, // parity flag 71 X86_EFLAGS_AF = 4, // auxiliary carry flag (adjust flag) 72 X86_EFLAGS_ZF = 6, // zero flag 73 X86_EFLAGS_SF = 7, // sign flag 74 X86_EFLAGS_TF = 8, // trap flag (single stepping) 75 X86_EFLAGS_DF = 10, // direction flag 76 X86_EFLAGS_OF = 11, // overflow flag 77 X86_EFLAGS_RF = 16, // resume flag (skips instruction breakpoint) 78 79 X86_EFLAGS_USER_SETTABLE_FLAGS 80 = (1 << X86_EFLAGS_CF) | (1 << X86_EFLAGS_PF) | (1 << X86_EFLAGS_AF) 81 | (1 << X86_EFLAGS_ZF) | (1 << X86_EFLAGS_SF) | (1 << X86_EFLAGS_DF) 82 | (1 << X86_EFLAGS_OF), 83}; 84 85// x86 breakpoint types 86enum { 87 X86_INSTRUCTION_BREAKPOINT = 0x0, 88 X86_DATA_WRITE_BREAKPOINT = 0x1, 89 X86_IO_READ_WRITE_BREAKPOINT = 0x2, // >= 586 90 X86_DATA_READ_WRITE_BREAKPOINT = 0x3, 91}; 92 93// x86 breakpoint lengths 94enum { 95 X86_BREAKPOINT_LENGTH_1 = 0x0, 96 X86_BREAKPOINT_LENGTH_2 = 0x1, 97 X86_BREAKPOINT_LENGTH_4 = 0x3, 98}; 99 100struct arch_breakpoint { 101 void *address; // NULL, if deactivated 102 size_t type; // one of the architecture types above 103 size_t length; // one of the length values above 104}; 105 106struct arch_team_debug_info { 107 struct arch_breakpoint breakpoints[X86_BREAKPOINT_COUNT]; 108 109 size_t dr7; // debug control register DR7 110}; 111 112struct arch_thread_debug_info { 113 uint32 flags; 114}; 115 116// The software breakpoint instruction (int3). 117extern const uint8 kX86SoftwareBreakpoint[1]; 118 119#ifdef __cplusplus 120extern "C" { 121#endif 122 123struct iframe; 124 125extern void x86_init_user_debug_at_kernel_exit(struct iframe *frame); 126extern void x86_exit_user_debug_at_kernel_entry(); 127 128extern void x86_handle_debug_exception(struct iframe *frame); 129extern void x86_handle_breakpoint_exception(struct iframe *frame); 130 131extern void x86_init_user_debug(); 132 133#ifdef __cplusplus 134} 135#endif 136 137// Feature macros we're supposed to define. 138#define DEBUG_MAX_BREAKPOINTS X86_BREAKPOINT_COUNT 139#define DEBUG_MAX_WATCHPOINTS X86_BREAKPOINT_COUNT 140#define DEBUG_SOFTWARE_BREAKPOINT kX86SoftwareBreakpoint 141#define DEBUG_SOFTWARE_BREAKPOINT_SIZE 1 142#define DEBUG_SHARED_BREAK_AND_WATCHPOINTS 1 143 144 145#endif // _KERNEL_ARCH_X86_USER_DEBUGGER_H 146