Branch data Line data Source code
1 : : /* 2 : : * Created by: Jason Wessel <jason.wessel@windriver.com> 3 : : * 4 : : * Copyright (c) 2009 Wind River Systems, Inc. All Rights Reserved. 5 : : * 6 : : * This file is licensed under the terms of the GNU General Public 7 : : * License version 2. This program is licensed "as is" without any 8 : : * warranty of any kind, whether express or implied. 9 : : */ 10 : : 11 : : #include <linux/kgdb.h> 12 : : #include <linux/kdb.h> 13 : : #include <linux/kdebug.h> 14 : : #include <linux/export.h> 15 : : #include <linux/hardirq.h> 16 : : #include "kdb_private.h" 17 : : #include "../debug_core.h" 18 : : 19 : : /* 20 : : * KDB interface to KGDB internals 21 : : */ 22 : : get_char_func kdb_poll_funcs[] = { 23 : : dbg_io_get_char, 24 : : NULL, 25 : : NULL, 26 : : NULL, 27 : : NULL, 28 : : NULL, 29 : : }; 30 : : EXPORT_SYMBOL_GPL(kdb_poll_funcs); 31 : : 32 : : int kdb_poll_idx = 1; 33 : : EXPORT_SYMBOL_GPL(kdb_poll_idx); 34 : : 35 : : static struct kgdb_state *kdb_ks; 36 : : 37 : 0 : int kdb_common_init_state(struct kgdb_state *ks) 38 : : { 39 : 0 : kdb_initial_cpu = atomic_read(&kgdb_active); 40 : 0 : kdb_current_task = kgdb_info[ks->cpu].task; 41 : 0 : kdb_current_regs = kgdb_info[ks->cpu].debuggerinfo; 42 : 0 : return 0; 43 : : } 44 : : 45 : 0 : int kdb_common_deinit_state(void) 46 : : { 47 : 0 : kdb_initial_cpu = -1; 48 : 0 : kdb_current_task = NULL; 49 : 0 : kdb_current_regs = NULL; 50 : 0 : return 0; 51 : : } 52 : : 53 : 0 : int kdb_stub(struct kgdb_state *ks) 54 : : { 55 : : int error = 0; 56 : : kdb_bp_t *bp; 57 : 0 : unsigned long addr = kgdb_arch_pc(ks->ex_vector, ks->linux_regs); 58 : : kdb_reason_t reason = KDB_REASON_OOPS; 59 : : kdb_dbtrap_t db_result = KDB_DB_NOBPT; 60 : : int i; 61 : : 62 : 0 : kdb_ks = ks; 63 : 0 : if (KDB_STATE(REENTRY)) { 64 : : reason = KDB_REASON_SWITCH; 65 : 0 : KDB_STATE_CLEAR(REENTRY); 66 : 0 : addr = instruction_pointer(ks->linux_regs); 67 : : } 68 : 0 : ks->pass_exception = 0; 69 : 0 : if (atomic_read(&kgdb_setting_breakpoint)) 70 : : reason = KDB_REASON_KEYBOARD; 71 : : 72 : 0 : if (ks->err_code == KDB_REASON_SYSTEM_NMI && ks->signo == SIGTRAP) 73 : : reason = KDB_REASON_SYSTEM_NMI; 74 : : 75 : 0 : else if (in_nmi()) 76 : : reason = KDB_REASON_NMI; 77 : : 78 : 0 : for (i = 0, bp = kdb_breakpoints; i < KDB_MAXBPT; i++, bp++) { 79 : 0 : if ((bp->bp_enabled) && (bp->bp_addr == addr)) { 80 : : reason = KDB_REASON_BREAK; 81 : : db_result = KDB_DB_BPT; 82 : 0 : if (addr != instruction_pointer(ks->linux_regs)) 83 : 0 : kgdb_arch_set_pc(ks->linux_regs, addr); 84 : : break; 85 : : } 86 : : } 87 : 0 : if (reason == KDB_REASON_BREAK || reason == KDB_REASON_SWITCH) { 88 : 0 : for (i = 0, bp = kdb_breakpoints; i < KDB_MAXBPT; i++, bp++) { 89 : 0 : if (bp->bp_free) 90 : 0 : continue; 91 : 0 : if (bp->bp_addr == addr) { 92 : 0 : bp->bp_delay = 1; 93 : 0 : bp->bp_delayed = 1; 94 : : /* 95 : : * SSBPT is set when the kernel debugger must single step a 96 : : * task in order to re-establish an instruction breakpoint 97 : : * which uses the instruction replacement mechanism. It is 98 : : * cleared by any action that removes the need to single-step 99 : : * the breakpoint. 100 : : */ 101 : : reason = KDB_REASON_BREAK; 102 : : db_result = KDB_DB_BPT; 103 : 0 : KDB_STATE_SET(SSBPT); 104 : 0 : break; 105 : : } 106 : : } 107 : : } 108 : : 109 : 0 : if (reason != KDB_REASON_BREAK && ks->ex_vector == 0 && 110 : 0 : ks->signo == SIGTRAP) { 111 : : reason = KDB_REASON_SSTEP; 112 : : db_result = KDB_DB_BPT; 113 : : } 114 : : /* Set initial kdb state variables */ 115 : 0 : KDB_STATE_CLEAR(KGDB_TRANS); 116 : : kdb_common_init_state(ks); 117 : : /* Remove any breakpoints as needed by kdb and clear single step */ 118 : 0 : kdb_bp_remove(); 119 : 0 : KDB_STATE_CLEAR(DOING_SS); 120 : 0 : KDB_STATE_SET(PAGER); 121 : 0 : if (ks->err_code == DIE_OOPS || reason == KDB_REASON_OOPS) { 122 : 0 : ks->pass_exception = 1; 123 : 0 : KDB_FLAG_SET(CATASTROPHIC); 124 : : } 125 : : /* set CATASTROPHIC if the system contains unresponsive processors */ 126 : 0 : for_each_online_cpu(i) 127 : 0 : if (!kgdb_info[i].enter_kgdb) 128 : 0 : KDB_FLAG_SET(CATASTROPHIC); 129 : 0 : if (KDB_STATE(SSBPT) && reason == KDB_REASON_SSTEP) { 130 : 0 : KDB_STATE_CLEAR(SSBPT); 131 : 0 : KDB_STATE_CLEAR(DOING_SS); 132 : : } else { 133 : : /* Start kdb main loop */ 134 : 0 : error = kdb_main_loop(KDB_REASON_ENTER, reason, 135 : : ks->err_code, db_result, ks->linux_regs); 136 : : } 137 : : /* 138 : : * Upon exit from the kdb main loop setup break points and restart 139 : : * the system based on the requested continue state 140 : : */ 141 : : kdb_common_deinit_state(); 142 : 0 : KDB_STATE_CLEAR(PAGER); 143 : 0 : kdbnearsym_cleanup(); 144 : 0 : if (error == KDB_CMD_KGDB) { 145 : 0 : if (KDB_STATE(DOING_KGDB)) 146 : 0 : KDB_STATE_CLEAR(DOING_KGDB); 147 : : return DBG_PASS_EVENT; 148 : : } 149 : 0 : kdb_bp_install(ks->linux_regs); 150 : 0 : dbg_activate_sw_breakpoints(); 151 : : /* Set the exit state to a single step or a continue */ 152 : 0 : if (KDB_STATE(DOING_SS)) 153 : 0 : gdbstub_state(ks, "s"); 154 : : else 155 : 0 : gdbstub_state(ks, "c"); 156 : : 157 : 0 : KDB_FLAG_CLEAR(CATASTROPHIC); 158 : : 159 : : /* Invoke arch specific exception handling prior to system resume */ 160 : 0 : kgdb_info[ks->cpu].ret_state = gdbstub_state(ks, "e"); 161 : 0 : if (ks->pass_exception) 162 : 0 : kgdb_info[ks->cpu].ret_state = 1; 163 : 0 : if (error == KDB_CMD_CPU) { 164 : 0 : KDB_STATE_SET(REENTRY); 165 : : /* 166 : : * Force clear the single step bit because kdb emulates this 167 : : * differently vs the gdbstub 168 : : */ 169 : 0 : kgdb_single_step = 0; 170 : 0 : dbg_deactivate_sw_breakpoints(); 171 : 0 : return DBG_SWITCH_CPU_EVENT; 172 : : } 173 : 0 : return kgdb_info[ks->cpu].ret_state; 174 : : } 175 : : 176 : 0 : void kdb_gdb_state_pass(char *buf) 177 : : { 178 : 0 : gdbstub_state(kdb_ks, buf); 179 : 0 : }