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 "kdb_private.h"
  15#include "../debug_core.h"
  16
  17/*
  18 * KDB interface to KGDB internals
  19 */
  20get_char_func kdb_poll_funcs[] = {
  21        dbg_io_get_char,
  22        NULL,
  23        NULL,
  24        NULL,
  25        NULL,
  26        NULL,
  27};
  28EXPORT_SYMBOL_GPL(kdb_poll_funcs);
  29
  30int kdb_poll_idx = 1;
  31EXPORT_SYMBOL_GPL(kdb_poll_idx);
  32
  33int kdb_stub(struct kgdb_state *ks)
  34{
  35        int error = 0;
  36        kdb_bp_t *bp;
  37        unsigned long addr = kgdb_arch_pc(ks->ex_vector, ks->linux_regs);
  38        kdb_reason_t reason = KDB_REASON_OOPS;
  39        kdb_dbtrap_t db_result = KDB_DB_NOBPT;
  40        int i;
  41
  42        if (KDB_STATE(REENTRY)) {
  43                reason = KDB_REASON_SWITCH;
  44                KDB_STATE_CLEAR(REENTRY);
  45                addr = instruction_pointer(ks->linux_regs);
  46        }
  47        ks->pass_exception = 0;
  48        if (atomic_read(&kgdb_setting_breakpoint))
  49                reason = KDB_REASON_KEYBOARD;
  50
  51        for (i = 0, bp = kdb_breakpoints; i < KDB_MAXBPT; i++, bp++) {
  52                if ((bp->bp_enabled) && (bp->bp_addr == addr)) {
  53                        reason = KDB_REASON_BREAK;
  54                        db_result = KDB_DB_BPT;
  55                        if (addr != instruction_pointer(ks->linux_regs))
  56                                kgdb_arch_set_pc(ks->linux_regs, addr);
  57                        break;
  58                }
  59        }
  60        if (reason == KDB_REASON_BREAK || reason == KDB_REASON_SWITCH) {
  61                for (i = 0, bp = kdb_breakpoints; i < KDB_MAXBPT; i++, bp++) {
  62                        if (bp->bp_free)
  63                                continue;
  64                        if (bp->bp_addr == addr) {
  65                                bp->bp_delay = 1;
  66                                bp->bp_delayed = 1;
  67        /*
  68         * SSBPT is set when the kernel debugger must single step a
  69         * task in order to re-establish an instruction breakpoint
  70         * which uses the instruction replacement mechanism.  It is
  71         * cleared by any action that removes the need to single-step
  72         * the breakpoint.
  73         */
  74                                reason = KDB_REASON_BREAK;
  75                                db_result = KDB_DB_BPT;
  76                                KDB_STATE_SET(SSBPT);
  77                                break;
  78                        }
  79                }
  80        }
  81
  82        if (reason != KDB_REASON_BREAK && ks->ex_vector == 0 &&
  83                ks->signo == SIGTRAP) {
  84                reason = KDB_REASON_SSTEP;
  85                db_result = KDB_DB_BPT;
  86        }
  87        /* Set initial kdb state variables */
  88        KDB_STATE_CLEAR(KGDB_TRANS);
  89        kdb_initial_cpu = atomic_read(&kgdb_active);
  90        kdb_current_task = kgdb_info[ks->cpu].task;
  91        kdb_current_regs = kgdb_info[ks->cpu].debuggerinfo;
  92        /* Remove any breakpoints as needed by kdb and clear single step */
  93        kdb_bp_remove();
  94        KDB_STATE_CLEAR(DOING_SS);
  95        KDB_STATE_CLEAR(DOING_SSB);
  96        KDB_STATE_SET(PAGER);
  97        /* zero out any offline cpu data */
  98        for_each_present_cpu(i) {
  99                if (!cpu_online(i)) {
 100                        kgdb_info[i].debuggerinfo = NULL;
 101                        kgdb_info[i].task = NULL;
 102                }
 103        }
 104        if (ks->err_code == DIE_OOPS || reason == KDB_REASON_OOPS) {
 105                ks->pass_exception = 1;
 106                KDB_FLAG_SET(CATASTROPHIC);
 107        }
 108        if (KDB_STATE(SSBPT) && reason == KDB_REASON_SSTEP) {
 109                KDB_STATE_CLEAR(SSBPT);
 110                KDB_STATE_CLEAR(DOING_SS);
 111        } else {
 112                /* Start kdb main loop */
 113                error = kdb_main_loop(KDB_REASON_ENTER, reason,
 114                                      ks->err_code, db_result, ks->linux_regs);
 115        }
 116        /*
 117         * Upon exit from the kdb main loop setup break points and restart
 118         * the system based on the requested continue state
 119         */
 120        kdb_initial_cpu = -1;
 121        kdb_current_task = NULL;
 122        kdb_current_regs = NULL;
 123        KDB_STATE_CLEAR(PAGER);
 124        kdbnearsym_cleanup();
 125        if (error == KDB_CMD_KGDB) {
 126                if (KDB_STATE(DOING_KGDB) || KDB_STATE(DOING_KGDB2)) {
 127        /*
 128         * This inteface glue which allows kdb to transition in into
 129         * the gdb stub.  In order to do this the '?' or '' gdb serial
 130         * packet response is processed here.  And then control is
 131         * passed to the gdbstub.
 132         */
 133                        if (KDB_STATE(DOING_KGDB))
 134                                gdbstub_state(ks, "?");
 135                        else
 136                                gdbstub_state(ks, "");
 137                        KDB_STATE_CLEAR(DOING_KGDB);
 138                        KDB_STATE_CLEAR(DOING_KGDB2);
 139                }
 140                return DBG_PASS_EVENT;
 141        }
 142        kdb_bp_install(ks->linux_regs);
 143        dbg_activate_sw_breakpoints();
 144        /* Set the exit state to a single step or a continue */
 145        if (KDB_STATE(DOING_SS))
 146                gdbstub_state(ks, "s");
 147        else
 148                gdbstub_state(ks, "c");
 149
 150        KDB_FLAG_CLEAR(CATASTROPHIC);
 151
 152        /* Invoke arch specific exception handling prior to system resume */
 153        kgdb_info[ks->cpu].ret_state = gdbstub_state(ks, "e");
 154        if (ks->pass_exception)
 155                kgdb_info[ks->cpu].ret_state = 1;
 156        if (error == KDB_CMD_CPU) {
 157                KDB_STATE_SET(REENTRY);
 158                /*
 159                 * Force clear the single step bit because kdb emulates this
 160                 * differently vs the gdbstub
 161                 */
 162                kgdb_single_step = 0;
 163                dbg_deactivate_sw_breakpoints();
 164                return DBG_SWITCH_CPU_EVENT;
 165        }
 166        return kgdb_info[ks->cpu].ret_state;
 167}
 168
 169