linux/kernel/debug/kdb/kdb_debugger.c
<<
>>
Prefs
   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 */
  22get_char_func kdb_poll_funcs[] = {
  23        dbg_io_get_char,
  24        NULL,
  25        NULL,
  26        NULL,
  27        NULL,
  28        NULL,
  29};
  30EXPORT_SYMBOL_GPL(kdb_poll_funcs);
  31
  32int kdb_poll_idx = 1;
  33EXPORT_SYMBOL_GPL(kdb_poll_idx);
  34
  35static struct kgdb_state *kdb_ks;
  36
  37int kdb_common_init_state(struct kgdb_state *ks)
  38{
  39        kdb_initial_cpu = atomic_read(&kgdb_active);
  40        kdb_current_task = kgdb_info[ks->cpu].task;
  41        kdb_current_regs = kgdb_info[ks->cpu].debuggerinfo;
  42        return 0;
  43}
  44
  45int kdb_common_deinit_state(void)
  46{
  47        kdb_initial_cpu = -1;
  48        kdb_current_task = NULL;
  49        kdb_current_regs = NULL;
  50        return 0;
  51}
  52
  53int kdb_stub(struct kgdb_state *ks)
  54{
  55        int error = 0;
  56        kdb_bp_t *bp;
  57        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        kdb_ks = ks;
  63        if (KDB_STATE(REENTRY)) {
  64                reason = KDB_REASON_SWITCH;
  65                KDB_STATE_CLEAR(REENTRY);
  66                addr = instruction_pointer(ks->linux_regs);
  67        }
  68        ks->pass_exception = 0;
  69        if (atomic_read(&kgdb_setting_breakpoint))
  70                reason = KDB_REASON_KEYBOARD;
  71
  72        if (ks->err_code == KDB_REASON_SYSTEM_NMI && ks->signo == SIGTRAP)
  73                reason = KDB_REASON_SYSTEM_NMI;
  74
  75        else if (in_nmi())
  76                reason = KDB_REASON_NMI;
  77
  78        for (i = 0, bp = kdb_breakpoints; i < KDB_MAXBPT; i++, bp++) {
  79                if ((bp->bp_enabled) && (bp->bp_addr == addr)) {
  80                        reason = KDB_REASON_BREAK;
  81                        db_result = KDB_DB_BPT;
  82                        if (addr != instruction_pointer(ks->linux_regs))
  83                                kgdb_arch_set_pc(ks->linux_regs, addr);
  84                        break;
  85                }
  86        }
  87        if (reason == KDB_REASON_BREAK || reason == KDB_REASON_SWITCH) {
  88                for (i = 0, bp = kdb_breakpoints; i < KDB_MAXBPT; i++, bp++) {
  89                        if (bp->bp_free)
  90                                continue;
  91                        if (bp->bp_addr == addr) {
  92                                bp->bp_delay = 1;
  93                                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                                KDB_STATE_SET(SSBPT);
 104                                break;
 105                        }
 106                }
 107        }
 108
 109        if (reason != KDB_REASON_BREAK && ks->ex_vector == 0 &&
 110                ks->signo == SIGTRAP) {
 111                reason = KDB_REASON_SSTEP;
 112                db_result = KDB_DB_BPT;
 113        }
 114        /* Set initial kdb state variables */
 115        KDB_STATE_CLEAR(KGDB_TRANS);
 116        kdb_common_init_state(ks);
 117        /* Remove any breakpoints as needed by kdb and clear single step */
 118        kdb_bp_remove();
 119        KDB_STATE_CLEAR(DOING_SS);
 120        KDB_STATE_SET(PAGER);
 121        /* zero out any offline cpu data */
 122        for_each_present_cpu(i) {
 123                if (!cpu_online(i)) {
 124                        kgdb_info[i].debuggerinfo = NULL;
 125                        kgdb_info[i].task = NULL;
 126                }
 127        }
 128        if (ks->err_code == DIE_OOPS || reason == KDB_REASON_OOPS) {
 129                ks->pass_exception = 1;
 130                KDB_FLAG_SET(CATASTROPHIC);
 131        }
 132        if (KDB_STATE(SSBPT) && reason == KDB_REASON_SSTEP) {
 133                KDB_STATE_CLEAR(SSBPT);
 134                KDB_STATE_CLEAR(DOING_SS);
 135        } else {
 136                /* Start kdb main loop */
 137                error = kdb_main_loop(KDB_REASON_ENTER, reason,
 138                                      ks->err_code, db_result, ks->linux_regs);
 139        }
 140        /*
 141         * Upon exit from the kdb main loop setup break points and restart
 142         * the system based on the requested continue state
 143         */
 144        kdb_common_deinit_state();
 145        KDB_STATE_CLEAR(PAGER);
 146        kdbnearsym_cleanup();
 147        if (error == KDB_CMD_KGDB) {
 148                if (KDB_STATE(DOING_KGDB))
 149                        KDB_STATE_CLEAR(DOING_KGDB);
 150                return DBG_PASS_EVENT;
 151        }
 152        kdb_bp_install(ks->linux_regs);
 153        dbg_activate_sw_breakpoints();
 154        /* Set the exit state to a single step or a continue */
 155        if (KDB_STATE(DOING_SS))
 156                gdbstub_state(ks, "s");
 157        else
 158                gdbstub_state(ks, "c");
 159
 160        KDB_FLAG_CLEAR(CATASTROPHIC);
 161
 162        /* Invoke arch specific exception handling prior to system resume */
 163        kgdb_info[ks->cpu].ret_state = gdbstub_state(ks, "e");
 164        if (ks->pass_exception)
 165                kgdb_info[ks->cpu].ret_state = 1;
 166        if (error == KDB_CMD_CPU) {
 167                KDB_STATE_SET(REENTRY);
 168                /*
 169                 * Force clear the single step bit because kdb emulates this
 170                 * differently vs the gdbstub
 171                 */
 172                kgdb_single_step = 0;
 173                dbg_deactivate_sw_breakpoints();
 174                return DBG_SWITCH_CPU_EVENT;
 175        }
 176        return kgdb_info[ks->cpu].ret_state;
 177}
 178
 179void kdb_gdb_state_pass(char *buf)
 180{
 181        gdbstub_state(kdb_ks, buf);
 182}
 183