| 1 | |
| 2 | |
| 3 | * Kernel Debugger Architecture Independent Breakpoint Handler
|
| 4 | *
|
| 5 | * Copyright (c) 1999-2004 Silicon Graphics, Inc. All Rights Reserved.
|
| 6 | * Copyright (c) 2009 Wind River Systems, Inc. All Rights Reserved.
|
| 7 |
|
| 8 |
|
| 9 | #include <linux/string.h>
|
| 10 | #include <linux/kernel.h>
|
| 11 | #include <linux/init.h>
|
| 12 | #include <linux/kdb.h>
|
| 13 | #include <linux/kgdb.h>
|
| 14 | #include <linux/smp.h>
|
| 15 | #include <linux/sched.h>
|
| 16 | #include <linux/interrupt.h>
|
| 17 | #include "kdb_private.h"
|
| 18 |
|
| 19 | |
| 20 | * Table of kdb_breakpoints
|
| 21 |
|
| 22 | kdb_bp_t kdb_breakpoints[KDB_MAXBPT];
|
| 23 |
|
| 24 | static void kdb_setsinglestep(struct pt_regs *regs)
|
| 25 | {
|
| 26 | KDB_STATE_SET(DOING_SS);
|
| 27 | }
|
| 28 |
|
| 29 | static char *kdb_rwtypes[] = {
|
| 30 | "Instruction(i)",
|
| 31 | "Instruction(Register)",
|
| 32 | "Data Write",
|
| 33 | "I/O",
|
| 34 | "Data Access"
|
| 35 | };
|
| 36 |
|
| 37 | static char *kdb_bptype(kdb_bp_t *bp)
|
| 38 | {
|
| 39 | if (bp->bp_type < 0 || bp->bp_type > 4)
|
| 40 | return "";
|
| 41 |
|
| 42 | return kdb_rwtypes[bp->bp_type];
|
| 43 | }
|
| 44 |
|
| 45 | static int kdb_parsebp(int argc, const char **argv, int *nextargp, kdb_bp_t *bp)
|
| 46 | {
|
| 47 | int nextarg = *nextargp;
|
| 48 | int diag;
|
| 49 |
|
| 50 | bp->bph_length = 1;
|
| 51 | if ((argc + 1) != nextarg) {
|
| 52 | if (strncasecmp(argv[nextarg], "datar", sizeof("datar")) == 0)
|
| 53 | bp->bp_type = BP_ACCESS_WATCHPOINT;
|
| 54 | else if (strncasecmp(argv[nextarg], "dataw", sizeof("dataw")) == 0)
|
| 55 | bp->bp_type = BP_WRITE_WATCHPOINT;
|
| 56 | else if (strncasecmp(argv[nextarg], "inst", sizeof("inst")) == 0)
|
| 57 | bp->bp_type = BP_HARDWARE_BREAKPOINT;
|
| 58 | else
|
| 59 | return KDB_ARGCOUNT;
|
| 60 |
|
| 61 | bp->bph_length = 1;
|
| 62 |
|
| 63 | nextarg++;
|
| 64 |
|
| 65 | if ((argc + 1) != nextarg) {
|
| 66 | unsigned long len;
|
| 67 |
|
| 68 | diag = kdbgetularg((char *)argv[nextarg],
|
| 69 | &len);
|
| 70 | if (diag)
|
| 71 | return diag;
|
| 72 |
|
| 73 |
|
| 74 | if (len > 8)
|
| 75 | return KDB_BADLENGTH;
|
| 76 |
|
| 77 | bp->bph_length = len;
|
| 78 | nextarg++;
|
| 79 | }
|
| 80 |
|
| 81 | if ((argc + 1) != nextarg)
|
| 82 | return KDB_ARGCOUNT;
|
| 83 | }
|
| 84 |
|
| 85 | *nextargp = nextarg;
|
| 86 | return 0;
|
| 87 | }
|
| 88 |
|
| 89 | static int _kdb_bp_remove(kdb_bp_t *bp)
|
| 90 | {
|
| 91 | int ret = 1;
|
| 92 | if (!bp->bp_installed)
|
| 93 | return ret;
|
| 94 | if (!bp->bp_type)
|
| 95 | ret = dbg_remove_sw_break(bp->bp_addr);
|
| 96 | else
|
| 97 | ret = arch_kgdb_ops.remove_hw_breakpoint(bp->bp_addr,
|
| 98 | bp->bph_length,
|
| 99 | bp->bp_type);
|
| 100 | if (ret == 0)
|
| 101 | bp->bp_installed = 0;
|
| 102 | return ret;
|
| 103 | }
|
| 104 |
|
| 105 | static void kdb_handle_bp(struct pt_regs *regs, kdb_bp_t *bp)
|
| 106 | {
|
| 107 | if (KDB_DEBUG(BP))
|
| 108 | kdb_printf("regs->ip = 0x%lx\n", instruction_pointer(regs));
|
| 109 |
|
| 110 | |
| 111 | * Setup single step
|
| 112 |
|
| 113 | kdb_setsinglestep(regs);
|
| 114 |
|
| 115 | |
| 116 | * Reset delay attribute
|
| 117 |
|
| 118 | bp->bp_delay = 0;
|
| 119 | bp->bp_delayed = 1;
|
| 120 | }
|
| 121 |
|
| 122 | static int _kdb_bp_install(struct pt_regs *regs, kdb_bp_t *bp)
|
| 123 | {
|
| 124 | int ret;
|
| 125 | |
| 126 | * Install the breakpoint, if it is not already installed.
|
| 127 |
|
| 128 |
|
| 129 | if (KDB_DEBUG(BP))
|
| 130 | kdb_printf("%s: bp_installed %d\n",
|
| 131 | __func__, bp->bp_installed);
|
| 132 | if (!KDB_STATE(SSBPT))
|
| 133 | bp->bp_delay = 0;
|
| 134 | if (bp->bp_installed)
|
| 135 | return 1;
|
| 136 | if (bp->bp_delay || (bp->bp_delayed && KDB_STATE(DOING_SS))) {
|
| 137 | if (KDB_DEBUG(BP))
|
| 138 | kdb_printf("%s: delayed bp\n", __func__);
|
| 139 | kdb_handle_bp(regs, bp);
|
| 140 | return 0;
|
| 141 | }
|
| 142 | if (!bp->bp_type)
|
| 143 | ret = dbg_set_sw_break(bp->bp_addr);
|
| 144 | else
|
| 145 | ret = arch_kgdb_ops.set_hw_breakpoint(bp->bp_addr,
|
| 146 | bp->bph_length,
|
| 147 | bp->bp_type);
|
| 148 | if (ret == 0) {
|
| 149 | bp->bp_installed = 1;
|
| 150 | } else {
|
| 151 | kdb_printf("%s: failed to set breakpoint at 0x%lx\n",
|
| 152 | __func__, bp->bp_addr);
|
| 153 | if (!bp->bp_type) {
|
| 154 | kdb_printf("Software breakpoints are unavailable.\n"
|
| 155 | " Boot the kernel with rodata=off\n"
|
| 156 | " OR use hw breaks: help bph\n");
|
| 157 | }
|
| 158 | return 1;
|
| 159 | }
|
| 160 | return 0;
|
| 161 | }
|
| 162 |
|
| 163 | |
| 164 | * kdb_bp_install
|
| 165 | *
|
| 166 | * Install kdb_breakpoints prior to returning from the
|
| 167 | * kernel debugger. This allows the kdb_breakpoints to be set
|
| 168 | * upon functions that are used internally by kdb, such as
|
| 169 | * printk(). This function is only called once per kdb session.
|
| 170 |
|
| 171 | void kdb_bp_install(struct pt_regs *regs)
|
| 172 | {
|
| 173 | int i;
|
| 174 |
|
| 175 | for (i = 0; i < KDB_MAXBPT; i++) {
|
| 176 | kdb_bp_t *bp = &kdb_breakpoints[i];
|
| 177 |
|
| 178 | if (KDB_DEBUG(BP)) {
|
| 179 | kdb_printf("%s: bp %d bp_enabled %d\n",
|
| 180 | __func__, i, bp->bp_enabled);
|
| 181 | }
|
| 182 | if (bp->bp_enabled)
|
| 183 | _kdb_bp_install(regs, bp);
|
| 184 | }
|
| 185 | }
|
| 186 |
|
| 187 | |
| 188 | * kdb_bp_remove
|
| 189 | *
|
| 190 | * Remove kdb_breakpoints upon entry to the kernel debugger.
|
| 191 | *
|
| 192 | * Parameters:
|
| 193 | * None.
|
| 194 | * Outputs:
|
| 195 | * None.
|
| 196 | * Returns:
|
| 197 | * None.
|
| 198 | * Locking:
|
| 199 | * None.
|
| 200 | * Remarks:
|
| 201 |
|
| 202 | void kdb_bp_remove(void)
|
| 203 | {
|
| 204 | int i;
|
| 205 |
|
| 206 | for (i = KDB_MAXBPT - 1; i >= 0; i--) {
|
| 207 | kdb_bp_t *bp = &kdb_breakpoints[i];
|
| 208 |
|
| 209 | if (KDB_DEBUG(BP)) {
|
| 210 | kdb_printf("%s: bp %d bp_enabled %d\n",
|
| 211 | __func__, i, bp->bp_enabled);
|
| 212 | }
|
| 213 | if (bp->bp_enabled)
|
| 214 | _kdb_bp_remove(bp);
|
| 215 | }
|
| 216 | }
|
| 217 |
|
| 218 |
|
| 219 | |
| 220 | * kdb_printbp
|
| 221 | *
|
| 222 | * Internal function to format and print a breakpoint entry.
|
| 223 | *
|
| 224 | * Parameters:
|
| 225 | * None.
|
| 226 | * Outputs:
|
| 227 | * None.
|
| 228 | * Returns:
|
| 229 | * None.
|
| 230 | * Locking:
|
| 231 | * None.
|
| 232 | * Remarks:
|
| 233 |
|
| 234 |
|
| 235 | static void kdb_printbp(kdb_bp_t *bp, int i)
|
| 236 | {
|
| 237 | kdb_printf("%s ", kdb_bptype(bp));
|
| 238 | kdb_printf("BP #%d at ", i);
|
| 239 | kdb_symbol_print(bp->bp_addr, NULL, KDB_SP_DEFAULT);
|
| 240 |
|
| 241 | if (bp->bp_enabled)
|
| 242 | kdb_printf("\n is enabled ");
|
| 243 | else
|
| 244 | kdb_printf("\n is disabled");
|
| 245 |
|
| 246 | kdb_printf(" addr at %016lx, hardtype=%d installed=%d\n",
|
| 247 | bp->bp_addr, bp->bp_type, bp->bp_installed);
|
| 248 |
|
| 249 | kdb_printf("\n");
|
| 250 | }
|
| 251 |
|
| 252 | |
| 253 | * kdb_bp
|
| 254 | *
|
| 255 | * Handle the bp commands.
|
| 256 | *
|
| 257 | * [bp|bph] <addr-expression> [DATAR|DATAW]
|
| 258 | *
|
| 259 | * Parameters:
|
| 260 | * argc Count of arguments in argv
|
| 261 | * argv Space delimited command line arguments
|
| 262 | * Outputs:
|
| 263 | * None.
|
| 264 | * Returns:
|
| 265 | * Zero for success, a kdb diagnostic if failure.
|
| 266 | * Locking:
|
| 267 | * None.
|
| 268 | * Remarks:
|
| 269 | *
|
| 270 | * bp Set breakpoint on all cpus. Only use hardware assist if need.
|
| 271 | * bph Set breakpoint on all cpus. Force hardware register
|
| 272 |
|
| 273 |
|
| 274 | static int kdb_bp(int argc, const char **argv)
|
| 275 | {
|
| 276 | int i, bpno;
|
| 277 | kdb_bp_t *bp, *bp_check;
|
| 278 | int diag;
|
| 279 | char *symname = NULL;
|
| 280 | long offset = 0ul;
|
| 281 | int nextarg;
|
| 282 | kdb_bp_t template = {0};
|
| 283 |
|
| 284 | if (argc == 0) {
|
| 285 | |
| 286 | * Display breakpoint table
|
| 287 |
|
| 288 | for (bpno = 0, bp = kdb_breakpoints; bpno < KDB_MAXBPT;
|
| 289 | bpno++, bp++) {
|
| 290 | if (bp->bp_free)
|
| 291 | continue;
|
| 292 | kdb_printbp(bp, bpno);
|
| 293 | }
|
| 294 |
|
| 295 | return 0;
|
| 296 | }
|
| 297 |
|
| 298 | nextarg = 1;
|
| 299 | diag = kdbgetaddrarg(argc, argv, &nextarg, &template.bp_addr,
|
| 300 | &offset, &symname);
|
| 301 | if (diag)
|
| 302 | return diag;
|
| 303 | if (!template.bp_addr)
|
| 304 | return KDB_BADINT;
|
| 305 |
|
| 306 | |
| 307 | * This check is redundant (since the breakpoint machinery should
|
| 308 | * be doing the same check during kdb_bp_install) but gives the
|
| 309 | * user immediate feedback.
|
| 310 |
|
| 311 | diag = kgdb_validate_break_address(template.bp_addr);
|
| 312 | if (diag)
|
| 313 | return diag;
|
| 314 |
|
| 315 | |
| 316 | * Find an empty bp structure to allocate
|
| 317 |
|
| 318 | for (bpno = 0, bp = kdb_breakpoints; bpno < KDB_MAXBPT; bpno++, bp++) {
|
| 319 | if (bp->bp_free)
|
| 320 | break;
|
| 321 | }
|
| 322 |
|
| 323 | if (bpno == KDB_MAXBPT)
|
| 324 | return KDB_TOOMANYBPT;
|
| 325 |
|
| 326 | if (strcmp(argv[0], "bph") == 0) {
|
| 327 | template.bp_type = BP_HARDWARE_BREAKPOINT;
|
| 328 | diag = kdb_parsebp(argc, argv, &nextarg, &template);
|
| 329 | if (diag)
|
| 330 | return diag;
|
| 331 | } else {
|
| 332 | template.bp_type = BP_BREAKPOINT;
|
| 333 | }
|
| 334 |
|
| 335 | |
| 336 | * Check for clashing breakpoints.
|
| 337 | *
|
| 338 | * Note, in this design we can't have hardware breakpoints
|
| 339 | * enabled for both read and write on the same address.
|
| 340 |
|
| 341 | for (i = 0, bp_check = kdb_breakpoints; i < KDB_MAXBPT;
|
| 342 | i++, bp_check++) {
|
| 343 | if (!bp_check->bp_free &&
|
| 344 | bp_check->bp_addr == template.bp_addr) {
|
| 345 | kdb_printf("You already have a breakpoint at "
|
| 346 | kdb_bfd_vma_fmt0 "\n", template.bp_addr);
|
| 347 | return KDB_DUPBPT;
|
| 348 | }
|
| 349 | }
|
| 350 |
|
| 351 | template.bp_enabled = 1;
|
| 352 |
|
| 353 | |
| 354 | * Actually allocate the breakpoint found earlier
|
| 355 |
|
| 356 | *bp = template;
|
| 357 | bp->bp_free = 0;
|
| 358 |
|
| 359 | kdb_printbp(bp, bpno);
|
| 360 |
|
| 361 | return 0;
|
| 362 | }
|
| 363 |
|
| 364 | |
| 365 | * kdb_bc
|
| 366 | *
|
| 367 | * Handles the 'bc', 'be', and 'bd' commands
|
| 368 | *
|
| 369 | * [bd|bc|be] <breakpoint-number>
|
| 370 | * [bd|bc|be] *
|
| 371 | *
|
| 372 | * Parameters:
|
| 373 | * argc Count of arguments in argv
|
| 374 | * argv Space delimited command line arguments
|
| 375 | * Outputs:
|
| 376 | * None.
|
| 377 | * Returns:
|
| 378 | * Zero for success, a kdb diagnostic for failure
|
| 379 | * Locking:
|
| 380 | * None.
|
| 381 | * Remarks:
|
| 382 |
|
| 383 | static int kdb_bc(int argc, const char **argv)
|
| 384 | {
|
| 385 | unsigned long addr;
|
| 386 | kdb_bp_t *bp = NULL;
|
| 387 | int lowbp = KDB_MAXBPT;
|
| 388 | int highbp = 0;
|
| 389 | int done = 0;
|
| 390 | int i;
|
| 391 | int diag = 0;
|
| 392 |
|
| 393 | int cmd;
|
| 394 | #define KDBCMD_BC 0
|
| 395 | #define KDBCMD_BE 1
|
| 396 | #define KDBCMD_BD 2
|
| 397 |
|
| 398 | if (strcmp(argv[0], "be") == 0)
|
| 399 | cmd = KDBCMD_BE;
|
| 400 | else if (strcmp(argv[0], "bd") == 0)
|
| 401 | cmd = KDBCMD_BD;
|
| 402 | else
|
| 403 | cmd = KDBCMD_BC;
|
| 404 |
|
| 405 | if (argc != 1)
|
| 406 | return KDB_ARGCOUNT;
|
| 407 |
|
| 408 | if (strcmp(argv[1], "*") == 0) {
|
| 409 | lowbp = 0;
|
| 410 | highbp = KDB_MAXBPT;
|
| 411 | } else {
|
| 412 | diag = kdbgetularg(argv[1], &addr);
|
| 413 | if (diag)
|
| 414 | return diag;
|
| 415 |
|
| 416 | |
| 417 | * For addresses less than the maximum breakpoint number,
|
| 418 | * assume that the breakpoint number is desired.
|
| 419 |
|
| 420 | if (addr < KDB_MAXBPT) {
|
| 421 | lowbp = highbp = addr;
|
| 422 | highbp++;
|
| 423 | } else {
|
| 424 | for (i = 0, bp = kdb_breakpoints; i < KDB_MAXBPT;
|
| 425 | i++, bp++) {
|
| 426 | if (bp->bp_addr == addr) {
|
| 427 | lowbp = highbp = i;
|
| 428 | highbp++;
|
| 429 | break;
|
| 430 | }
|
| 431 | }
|
| 432 | }
|
| 433 | }
|
| 434 |
|
| 435 | |
| 436 | * Now operate on the set of breakpoints matching the input
|
| 437 | * criteria (either '*' for all, or an individual breakpoint).
|
| 438 |
|
| 439 | for (bp = &kdb_breakpoints[lowbp], i = lowbp;
|
| 440 | i < highbp;
|
| 441 | i++, bp++) {
|
| 442 | if (bp->bp_free)
|
| 443 | continue;
|
| 444 |
|
| 445 | done++;
|
| 446 |
|
| 447 | switch (cmd) {
|
| 448 | case KDBCMD_BC:
|
| 449 | bp->bp_enabled = 0;
|
| 450 |
|
| 451 | kdb_printf("Breakpoint %d at "
|
| 452 | kdb_bfd_vma_fmt " cleared\n",
|
| 453 | i, bp->bp_addr);
|
| 454 |
|
| 455 | bp->bp_addr = 0;
|
| 456 | bp->bp_free = 1;
|
| 457 |
|
| 458 | break;
|
| 459 | case KDBCMD_BE:
|
| 460 | if (bp->bp_enabled)
|
| 461 | break;
|
| 462 |
|
| 463 | bp->bp_enabled = 1;
|
| 464 |
|
| 465 | kdb_printf("Breakpoint %d at "
|
| 466 | kdb_bfd_vma_fmt " enabled\n",
|
| 467 | i, bp->bp_addr);
|
| 468 |
|
| 469 | break;
|
| 470 | case KDBCMD_BD:
|
| 471 | if (!bp->bp_enabled)
|
| 472 | break;
|
| 473 |
|
| 474 | bp->bp_enabled = 0;
|
| 475 |
|
| 476 | kdb_printf("Breakpoint %d at "
|
| 477 | kdb_bfd_vma_fmt " disabled\n",
|
| 478 | i, bp->bp_addr);
|
| 479 |
|
| 480 | break;
|
| 481 | }
|
| 482 | if (bp->bp_delay && (cmd == KDBCMD_BC || cmd == KDBCMD_BD)) {
|
| 483 | bp->bp_delay = 0;
|
| 484 | KDB_STATE_CLEAR(SSBPT);
|
| 485 | }
|
| 486 | }
|
| 487 |
|
| 488 | return (!done) ? KDB_BPTNOTFOUND : 0;
|
| 489 | }
|
| 490 |
|
| 491 | |
| 492 | * kdb_ss
|
| 493 | *
|
| 494 | * Process the 'ss' (Single Step) command.
|
| 495 | *
|
| 496 | * ss
|
| 497 | *
|
| 498 | * Parameters:
|
| 499 | * argc Argument count
|
| 500 | * argv Argument vector
|
| 501 | * Outputs:
|
| 502 | * None.
|
| 503 | * Returns:
|
| 504 | * KDB_CMD_SS for success, a kdb error if failure.
|
| 505 | * Locking:
|
| 506 | * None.
|
| 507 | * Remarks:
|
| 508 | *
|
| 509 | * Set the arch specific option to trigger a debug trap after the next
|
| 510 | * instruction.
|
| 511 |
|
| 512 |
|
| 513 | static int kdb_ss(int argc, const char **argv)
|
| 514 | {
|
| 515 | if (argc != 0)
|
| 516 | return KDB_ARGCOUNT;
|
| 517 | |
| 518 | * Set trace flag and go.
|
| 519 |
|
| 520 | KDB_STATE_SET(DOING_SS);
|
| 521 | return KDB_CMD_SS;
|
| 522 | }
|
| 523 |
|
| 524 | static kdbtab_t bptab[] = {
|
| 525 | { .name = "bp",
|
| 526 | .func = kdb_bp,
|
| 527 | .usage = "[<vaddr>]",
|
| 528 | .help = "Set/Display breakpoints",
|
| 529 | .flags = KDB_ENABLE_FLOW_CTRL | KDB_REPEAT_NO_ARGS,
|
| 530 | },
|
| 531 | { .name = "bl",
|
| 532 | .func = kdb_bp,
|
| 533 | .usage = "[<vaddr>]",
|
| 534 | .help = "Display breakpoints",
|
| 535 | .flags = KDB_ENABLE_FLOW_CTRL | KDB_REPEAT_NO_ARGS,
|
| 536 | },
|
| 537 | { .name = "bc",
|
| 538 | .func = kdb_bc,
|
| 539 | .usage = "<bpnum>",
|
| 540 | .help = "Clear Breakpoint",
|
| 541 | .flags = KDB_ENABLE_FLOW_CTRL,
|
| 542 | },
|
| 543 | { .name = "be",
|
| 544 | .func = kdb_bc,
|
| 545 | .usage = "<bpnum>",
|
| 546 | .help = "Enable Breakpoint",
|
| 547 | .flags = KDB_ENABLE_FLOW_CTRL,
|
| 548 | },
|
| 549 | { .name = "bd",
|
| 550 | .func = kdb_bc,
|
| 551 | .usage = "<bpnum>",
|
| 552 | .help = "Disable Breakpoint",
|
| 553 | .flags = KDB_ENABLE_FLOW_CTRL,
|
| 554 | },
|
| 555 | { .name = "ss",
|
| 556 | .func = kdb_ss,
|
| 557 | .usage = "",
|
| 558 | .help = "Single Step",
|
| 559 | .minlen = 1,
|
| 560 | .flags = KDB_ENABLE_FLOW_CTRL | KDB_REPEAT_NO_ARGS,
|
| 561 | },
|
| 562 | };
|
| 563 |
|
| 564 | static kdbtab_t bphcmd = {
|
| 565 | .name = "bph",
|
| 566 | .func = kdb_bp,
|
| 567 | .usage = "[<vaddr>]",
|
| 568 | .help = "[datar [length]|dataw [length]] Set hw brk",
|
| 569 | .flags = KDB_ENABLE_FLOW_CTRL | KDB_REPEAT_NO_ARGS,
|
| 570 | };
|
| 571 |
|
| 572 |
|
| 573 |
|
| 574 | void __init kdb_initbptab(void)
|
| 575 | {
|
| 576 | int i;
|
| 577 | kdb_bp_t *bp;
|
| 578 |
|
| 579 | |
| 580 | * First time initialization.
|
| 581 |
|
| 582 | memset(&kdb_breakpoints, '\0', sizeof(kdb_breakpoints));
|
| 583 |
|
| 584 | for (i = 0, bp = kdb_breakpoints; i < KDB_MAXBPT; i++, bp++)
|
| 585 | bp->bp_free = 1;
|
| 586 |
|
| 587 | kdb_register_table(bptab, ARRAY_SIZE(bptab));
|
| 588 | if (arch_kgdb_ops.flags & KGDB_HW_BREAKPOINT)
|
| 589 | kdb_register_table(&bphcmd, 1);
|
| 590 | }
|