1/*- 2 * Mach Operating System 3 * Copyright (c) 1991,1990 Carnegie Mellon University 4 * All Rights Reserved. 5 * 6 * Permission to use, copy, modify and distribute this software and its 7 * documentation is hereby granted, provided that both the copyright 8 * notice and this permission notice appear in all copies of the 9 * software, derivative works or modified versions, and any portions 10 * thereof, and that both notices appear in supporting documentation. 11 * 12 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS 13 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR 14 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 15 * 16 * Carnegie Mellon requests users of this software to return to 17 * 18 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU 19 * School of Computer Science 20 * Carnegie Mellon University 21 * Pittsburgh PA 15213-3890 22 * 23 * any improvements or extensions that they make and grant Carnegie the 24 * rights to redistribute these changes. 25 */ 26 27#include <sys/cdefs.h> 28__FBSDID("$FreeBSD$"); 29 30#include <sys/param.h> 31#include <sys/systm.h> 32#include <sys/kdb.h> 33#include <sys/proc.h> 34#include <sys/sysent.h> 35 36#include <machine/cpu.h> 37#include <machine/md_var.h> 38#include <machine/pcb.h> 39#include <machine/reg.h> 40#include <machine/stack.h> 41 42#include <vm/vm.h> 43#include <vm/vm_param.h> 44#include <vm/pmap.h> 45 46#include <ddb/ddb.h> 47#include <ddb/db_access.h> 48#include <ddb/db_sym.h> 49#include <ddb/db_variables.h> 50 51static db_varfcn_t db_dr0; 52static db_varfcn_t db_dr1; 53static db_varfcn_t db_dr2; 54static db_varfcn_t db_dr3; 55static db_varfcn_t db_dr4; 56static db_varfcn_t db_dr5; 57static db_varfcn_t db_dr6; 58static db_varfcn_t db_dr7; 59static db_varfcn_t db_esp; 60static db_varfcn_t db_frame; 61static db_varfcn_t db_ss; 62 63/* 64 * Machine register set. 65 */ 66#define DB_OFFSET(x) (db_expr_t *)offsetof(struct trapframe, x) 67struct db_variable db_regs[] = { 68 { "cs", DB_OFFSET(tf_cs), db_frame }, 69 { "ds", DB_OFFSET(tf_ds), db_frame }, 70 { "es", DB_OFFSET(tf_es), db_frame }, 71 { "fs", DB_OFFSET(tf_fs), db_frame }, 72 { "ss", NULL, db_ss }, 73 { "eax", DB_OFFSET(tf_eax), db_frame }, 74 { "ecx", DB_OFFSET(tf_ecx), db_frame }, 75 { "edx", DB_OFFSET(tf_edx), db_frame }, 76 { "ebx", DB_OFFSET(tf_ebx), db_frame }, 77 { "esp", NULL, db_esp }, 78 { "ebp", DB_OFFSET(tf_ebp), db_frame }, 79 { "esi", DB_OFFSET(tf_esi), db_frame }, 80 { "edi", DB_OFFSET(tf_edi), db_frame }, 81 { "eip", DB_OFFSET(tf_eip), db_frame }, 82 { "efl", DB_OFFSET(tf_eflags), db_frame }, 83#define DB_N_SHOW_REGS 15 /* Don't show registers after here. */ 84 { "dr0", NULL, db_dr0 }, 85 { "dr1", NULL, db_dr1 }, 86 { "dr2", NULL, db_dr2 }, 87 { "dr3", NULL, db_dr3 }, 88 { "dr4", NULL, db_dr4 }, 89 { "dr5", NULL, db_dr5 }, 90 { "dr6", NULL, db_dr6 }, 91 { "dr7", NULL, db_dr7 }, 92}; 93struct db_variable *db_eregs = db_regs + DB_N_SHOW_REGS; 94 95#define DB_DRX_FUNC(reg) \ 96static int \ 97db_ ## reg (vp, valuep, op) \ 98 struct db_variable *vp; \ 99 db_expr_t * valuep; \ 100 int op; \ 101{ \ 102 if (op == DB_VAR_GET) \ 103 *valuep = r ## reg (); \ 104 else \ 105 load_ ## reg (*valuep); \ 106 return (1); \ 107} 108 109DB_DRX_FUNC(dr0) 110DB_DRX_FUNC(dr1) 111DB_DRX_FUNC(dr2) 112DB_DRX_FUNC(dr3) 113DB_DRX_FUNC(dr4) 114DB_DRX_FUNC(dr5) 115DB_DRX_FUNC(dr6) 116DB_DRX_FUNC(dr7) 117 118static __inline int 119get_esp(struct trapframe *tf) 120{ 121 return ((ISPL(tf->tf_cs)) ? tf->tf_esp : 122 (db_expr_t)tf + (uintptr_t)DB_OFFSET(tf_esp)); 123} 124 125static int 126db_frame(struct db_variable *vp, db_expr_t *valuep, int op) 127{ 128 int *reg; 129 130 if (kdb_frame == NULL) 131 return (0); 132 133 reg = (int *)((uintptr_t)kdb_frame + (db_expr_t)vp->valuep); 134 if (op == DB_VAR_GET) 135 *valuep = *reg; 136 else 137 *reg = *valuep; 138 return (1); 139} 140 141static int 142db_esp(struct db_variable *vp, db_expr_t *valuep, int op) 143{ 144 145 if (kdb_frame == NULL) 146 return (0); 147 148 if (op == DB_VAR_GET) 149 *valuep = get_esp(kdb_frame); 150 else if (ISPL(kdb_frame->tf_cs)) 151 kdb_frame->tf_esp = *valuep; 152 return (1); 153} 154 155static int 156db_ss(struct db_variable *vp, db_expr_t *valuep, int op) 157{ 158 159 if (kdb_frame == NULL) 160 return (0); 161 162 if (op == DB_VAR_GET) 163 *valuep = (ISPL(kdb_frame->tf_cs)) ? kdb_frame->tf_ss : rss(); 164 else if (ISPL(kdb_frame->tf_cs)) 165 kdb_frame->tf_ss = *valuep; 166 return (1); 167} 168 169#define NORMAL 0 170#define TRAP 1 171#define INTERRUPT 2 172#define SYSCALL 3 173#define DOUBLE_FAULT 4 174#define TRAP_INTERRUPT 5 175#define TRAP_TIMERINT 6 176 177static void db_nextframe(struct i386_frame **, db_addr_t *, struct thread *); 178static int db_numargs(struct i386_frame *); 179static void db_print_stack_entry(const char *, int, char **, int *, db_addr_t, 180 void *); 181static void decode_syscall(int, struct thread *); 182 183static const char * watchtype_str(int type); 184int i386_set_watch(int watchnum, unsigned int watchaddr, int size, int access, 185 struct dbreg *d); 186int i386_clr_watch(int watchnum, struct dbreg *d); 187 188/* 189 * Figure out how many arguments were passed into the frame at "fp". 190 */ 191static int 192db_numargs(fp) 193 struct i386_frame *fp; 194{ 195 char *argp; 196 int inst; 197 int args; 198 199 argp = (char *)db_get_value((int)&fp->f_retaddr, 4, FALSE); 200 /* 201 * XXX etext is wrong for LKMs. We should attempt to interpret 202 * the instruction at the return address in all cases. This 203 * may require better fault handling. 204 */ 205 if (argp < btext || argp >= etext) { 206 args = -1; 207 } else { 208retry: 209 inst = db_get_value((int)argp, 4, FALSE); 210 if ((inst & 0xff) == 0x59) /* popl %ecx */ 211 args = 1; 212 else if ((inst & 0xffff) == 0xc483) /* addl $Ibs, %esp */ 213 args = ((inst >> 16) & 0xff) / 4; 214 else if ((inst & 0xf8ff) == 0xc089) { /* movl %eax, %Reg */ 215 argp += 2; 216 goto retry; 217 } else 218 args = -1; 219 } 220 return (args); 221} 222 223static void 224db_print_stack_entry(name, narg, argnp, argp, callpc, frame) 225 const char *name; 226 int narg; 227 char **argnp; 228 int *argp; 229 db_addr_t callpc; 230 void *frame; 231{ 232 int n = narg >= 0 ? narg : 5; 233 234 db_printf("%s(", name); 235 while (n) { 236 if (argnp) 237 db_printf("%s=", *argnp++); 238 db_printf("%r", db_get_value((int)argp, 4, FALSE)); 239 argp++; 240 if (--n != 0) 241 db_printf(","); 242 } 243 if (narg < 0) 244 db_printf(",..."); 245 db_printf(") at "); 246 db_printsym(callpc, DB_STGY_PROC); 247 if (frame != NULL) 248 db_printf("/frame 0x%r", (register_t)frame); 249 db_printf("\n"); 250} 251 252static void 253decode_syscall(int number, struct thread *td) 254{ 255 struct proc *p; 256 c_db_sym_t sym; 257 db_expr_t diff; 258 sy_call_t *f; 259 const char *symname; 260 261 db_printf(" (%d", number); 262 p = (td != NULL) ? td->td_proc : NULL; 263 if (p != NULL && 0 <= number && number < p->p_sysent->sv_size) { 264 f = p->p_sysent->sv_table[number].sy_call; 265 sym = db_search_symbol((db_addr_t)f, DB_STGY_ANY, &diff); 266 if (sym != DB_SYM_NULL && diff == 0) { 267 db_symbol_values(sym, &symname, NULL); 268 db_printf(", %s, %s", p->p_sysent->sv_name, symname); 269 } 270 } 271 db_printf(")"); 272} 273 274/* 275 * Figure out the next frame up in the call stack. 276 */ 277static void 278db_nextframe(struct i386_frame **fp, db_addr_t *ip, struct thread *td) 279{ 280 struct trapframe *tf; 281 int frame_type; 282 int eip, esp, ebp; 283 db_expr_t offset; 284 c_db_sym_t sym; 285 const char *name; 286 287 eip = db_get_value((int) &(*fp)->f_retaddr, 4, FALSE); 288 ebp = db_get_value((int) &(*fp)->f_frame, 4, FALSE); 289 290 /* 291 * Figure out frame type. We look at the address just before 292 * the saved instruction pointer as the saved EIP is after the 293 * call function, and if the function being called is marked as 294 * dead (such as panic() at the end of dblfault_handler()), then 295 * the instruction at the saved EIP will be part of a different 296 * function (syscall() in this example) rather than the one that 297 * actually made the call. 298 */ 299 frame_type = NORMAL; 300 sym = db_search_symbol(eip - 1, DB_STGY_ANY, &offset); 301 db_symbol_values(sym, &name, NULL); 302 if (name != NULL) { 303 if (strcmp(name, "calltrap") == 0 || 304 strcmp(name, "fork_trampoline") == 0) 305 frame_type = TRAP; 306 else if (strncmp(name, "Xatpic_intr", 11) == 0 || 307 strncmp(name, "Xapic_isr", 9) == 0) 308 frame_type = INTERRUPT; 309 else if (strcmp(name, "Xlcall_syscall") == 0 || 310 strcmp(name, "Xint0x80_syscall") == 0) 311 frame_type = SYSCALL; 312 else if (strcmp(name, "dblfault_handler") == 0) 313 frame_type = DOUBLE_FAULT; 314 /* XXX: These are interrupts with trap frames. */ 315 else if (strcmp(name, "Xtimerint") == 0) 316 frame_type = TRAP_TIMERINT; 317 else if (strcmp(name, "Xcpustop") == 0 || 318 strcmp(name, "Xrendezvous") == 0 || 319 strcmp(name, "Xipi_intr_bitmap_handler") == 0 || 320 strcmp(name, "Xlazypmap") == 0) 321 frame_type = TRAP_INTERRUPT; 322 } 323 324 /* 325 * Normal frames need no special processing. 326 */ 327 if (frame_type == NORMAL) { 328 *ip = (db_addr_t) eip; 329 *fp = (struct i386_frame *) ebp; 330 return; 331 } 332 333 db_print_stack_entry(name, 0, 0, 0, eip, &(*fp)->f_frame); 334 335 /* 336 * For a double fault, we have to snag the values from the 337 * previous TSS since a double fault uses a task gate to 338 * switch to a known good state. 339 */ 340 if (frame_type == DOUBLE_FAULT) { 341 esp = PCPU_GET(common_tss.tss_esp); 342 eip = PCPU_GET(common_tss.tss_eip); 343 ebp = PCPU_GET(common_tss.tss_ebp); 344 db_printf( 345 "--- trap 0x17, eip = %#r, esp = %#r, ebp = %#r ---\n", 346 eip, esp, ebp); 347 *ip = (db_addr_t) eip; 348 *fp = (struct i386_frame *) ebp; 349 return; 350 } 351 352 /* 353 * Point to base of trapframe which is just above the 354 * current frame. 355 */ 356 if (frame_type == INTERRUPT) 357 tf = (struct trapframe *)((int)*fp + 16); 358 else if (frame_type == TRAP_INTERRUPT) 359 tf = (struct trapframe *)((int)*fp + 8); 360 else 361 tf = (struct trapframe *)((int)*fp + 12); 362 363 if (INKERNEL((int) tf)) { 364 esp = get_esp(tf); 365 eip = tf->tf_eip; 366 ebp = tf->tf_ebp; 367 switch (frame_type) { 368 case TRAP: 369 db_printf("--- trap %#r", tf->tf_trapno); 370 break; 371 case SYSCALL: 372 db_printf("--- syscall"); 373 decode_syscall(tf->tf_eax, td); 374 break; 375 case TRAP_TIMERINT: 376 case TRAP_INTERRUPT: 377 case INTERRUPT: 378 db_printf("--- interrupt"); 379 break; 380 default: 381 panic("The moon has moved again."); 382 } 383 db_printf(", eip = %#r, esp = %#r, ebp = %#r ---\n", eip, 384 esp, ebp); 385 } 386 387 *ip = (db_addr_t) eip; 388 *fp = (struct i386_frame *) ebp; 389} 390 391static int 392db_backtrace(struct thread *td, struct trapframe *tf, struct i386_frame *frame, 393 db_addr_t pc, int count) 394{ 395 struct i386_frame *actframe; 396#define MAXNARG 16 397 char *argnames[MAXNARG], **argnp = NULL; 398 const char *name; 399 int *argp; 400 db_expr_t offset; 401 c_db_sym_t sym; 402 int instr, narg; 403 boolean_t first; 404 405 /* 406 * If an indirect call via an invalid pointer caused a trap, 407 * %pc contains the invalid address while the return address 408 * of the unlucky caller has been saved by CPU on the stack 409 * just before the trap frame. In this case, try to recover 410 * the caller's address so that the first frame is assigned 411 * to the right spot in the right function, for that is where 412 * the failure actually happened. 413 * 414 * This trick depends on the fault address stashed in tf_err 415 * by trap_fatal() before entering KDB. 416 */ 417 if (kdb_frame && pc == kdb_frame->tf_err) { 418 /* 419 * Find where the trap frame actually ends. 420 * It won't contain tf_esp or tf_ss unless crossing rings. 421 */ 422 if (ISPL(kdb_frame->tf_cs)) 423 instr = (int)(kdb_frame + 1); 424 else 425 instr = (int)&kdb_frame->tf_esp; 426 pc = db_get_value(instr, 4, FALSE); 427 } 428 429 if (count == -1) 430 count = 1024; 431 432 first = TRUE; 433 while (count-- && !db_pager_quit) { 434 sym = db_search_symbol(pc, DB_STGY_ANY, &offset); 435 db_symbol_values(sym, &name, NULL); 436 437 /* 438 * Attempt to determine a (possibly fake) frame that gives 439 * the caller's pc. It may differ from `frame' if the 440 * current function never sets up a standard frame or hasn't 441 * set one up yet or has just discarded one. The last two 442 * cases can be guessed fairly reliably for code generated 443 * by gcc. The first case is too much trouble to handle in 444 * general because the amount of junk on the stack depends 445 * on the pc (the special handling of "calltrap", etc. in 446 * db_nextframe() works because the `next' pc is special). 447 */ 448 actframe = frame; 449 if (first) { 450 if (tf != NULL) { 451 instr = db_get_value(pc, 4, FALSE); 452 if ((instr & 0xffffff) == 0x00e58955) { 453 /* pushl %ebp; movl %esp, %ebp */ 454 actframe = (void *)(get_esp(tf) - 4); 455 } else if ((instr & 0xffff) == 0x0000e589) { 456 /* movl %esp, %ebp */ 457 actframe = (void *)get_esp(tf); 458 if (tf->tf_ebp == 0) { 459 /* Fake frame better. */ 460 frame = actframe; 461 } 462 } else if ((instr & 0xff) == 0x000000c3) { 463 /* ret */ 464 actframe = (void *)(get_esp(tf) - 4); 465 } else if (offset == 0) { 466 /* Probably an assembler symbol. */ 467 actframe = (void *)(get_esp(tf) - 4); 468 } 469 } else if (strcmp(name, "fork_trampoline") == 0) { 470 /* 471 * Don't try to walk back on a stack for a 472 * process that hasn't actually been run yet. 473 */ 474 db_print_stack_entry(name, 0, 0, 0, pc, 475 actframe); 476 break; 477 } 478 first = FALSE; 479 } 480 481 argp = &actframe->f_arg0; 482 narg = MAXNARG; 483 if (sym != NULL && db_sym_numargs(sym, &narg, argnames)) { 484 argnp = argnames; 485 } else { 486 narg = db_numargs(frame); 487 } 488 489 db_print_stack_entry(name, narg, argnp, argp, pc, actframe); 490 491 if (actframe != frame) { 492 /* `frame' belongs to caller. */ 493 pc = (db_addr_t) 494 db_get_value((int)&actframe->f_retaddr, 4, FALSE); 495 continue; 496 } 497 498 db_nextframe(&frame, &pc, td); 499 500 if (INKERNEL((int)pc) && !INKERNEL((int) frame)) { 501 sym = db_search_symbol(pc, DB_STGY_ANY, &offset); 502 db_symbol_values(sym, &name, NULL); 503 db_print_stack_entry(name, 0, 0, 0, pc, frame); 504 break; 505 } 506 if (!INKERNEL((int) frame)) { 507 break; 508 } 509 } 510 511 return (0); 512} 513 514void 515db_trace_self(void) 516{ 517 struct i386_frame *frame; 518 db_addr_t callpc; 519 register_t ebp; 520 521 __asm __volatile("movl %%ebp,%0" : "=r" (ebp)); 522 frame = (struct i386_frame *)ebp; 523 callpc = (db_addr_t)db_get_value((int)&frame->f_retaddr, 4, FALSE); 524 frame = frame->f_frame; 525 db_backtrace(curthread, NULL, frame, callpc, -1); 526} 527 528int 529db_trace_thread(struct thread *thr, int count) 530{ 531 struct pcb *ctx; 532 533 ctx = kdb_thr_ctx(thr); 534 return (db_backtrace(thr, NULL, (struct i386_frame *)ctx->pcb_ebp, 535 ctx->pcb_eip, count)); 536} 537 538int 539i386_set_watch(watchnum, watchaddr, size, access, d) 540 int watchnum; 541 unsigned int watchaddr; 542 int size; 543 int access; 544 struct dbreg *d; 545{ 546 int i, len; 547 548 if (watchnum == -1) { 549 for (i = 0; i < 4; i++) 550 if (!DBREG_DR7_ENABLED(d->dr[7], i)) 551 break; 552 if (i < 4) 553 watchnum = i; 554 else 555 return (-1); 556 } 557 558 switch (access) { 559 case DBREG_DR7_EXEC: 560 size = 1; /* size must be 1 for an execution breakpoint */ 561 /* fall through */ 562 case DBREG_DR7_WRONLY: 563 case DBREG_DR7_RDWR: 564 break; 565 default: 566 return (-1); 567 } 568 569 /* 570 * we can watch a 1, 2, or 4 byte sized location 571 */ 572 switch (size) { 573 case 1: 574 len = DBREG_DR7_LEN_1; 575 break; 576 case 2: 577 len = DBREG_DR7_LEN_2; 578 break; 579 case 4: 580 len = DBREG_DR7_LEN_4; 581 break; 582 default: 583 return (-1); 584 } 585 586 /* clear the bits we are about to affect */ 587 d->dr[7] &= ~DBREG_DR7_MASK(watchnum); 588 589 /* set drN register to the address, N=watchnum */ 590 DBREG_DRX(d, watchnum) = watchaddr; 591 592 /* enable the watchpoint */ 593 d->dr[7] |= DBREG_DR7_SET(watchnum, len, access, 594 DBREG_DR7_GLOBAL_ENABLE); 595 596 return (watchnum); 597} 598 599 600int 601i386_clr_watch(watchnum, d) 602 int watchnum; 603 struct dbreg *d; 604{ 605 606 if (watchnum < 0 || watchnum >= 4) 607 return (-1); 608 609 d->dr[7] &= ~DBREG_DR7_MASK(watchnum); 610 DBREG_DRX(d, watchnum) = 0; 611 612 return (0); 613} 614 615 616int 617db_md_set_watchpoint(addr, size) 618 db_expr_t addr; 619 db_expr_t size; 620{ 621 struct dbreg d; 622 int avail, i, wsize; 623 624 fill_dbregs(NULL, &d); 625 626 avail = 0; 627 for(i = 0; i < 4; i++) { 628 if (!DBREG_DR7_ENABLED(d.dr[7], i)) 629 avail++; 630 } 631 632 if (avail * 4 < size) 633 return (-1); 634 635 for (i = 0; i < 4 && (size > 0); i++) { 636 if (!DBREG_DR7_ENABLED(d.dr[7], i)) { 637 if (size > 2) 638 wsize = 4; 639 else 640 wsize = size; 641 i386_set_watch(i, addr, wsize, 642 DBREG_DR7_WRONLY, &d); 643 addr += wsize; 644 size -= wsize; 645 } 646 } 647 648 set_dbregs(NULL, &d); 649 650 return(0); 651} 652 653 654int 655db_md_clr_watchpoint(addr, size) 656 db_expr_t addr; 657 db_expr_t size; 658{ 659 struct dbreg d; 660 int i; 661 662 fill_dbregs(NULL, &d); 663 664 for(i = 0; i < 4; i++) { 665 if (DBREG_DR7_ENABLED(d.dr[7], i)) { 666 if ((DBREG_DRX((&d), i) >= addr) && 667 (DBREG_DRX((&d), i) < addr+size)) 668 i386_clr_watch(i, &d); 669 670 } 671 } 672 673 set_dbregs(NULL, &d); 674 675 return(0); 676} 677 678 679static const char * 680watchtype_str(type) 681 int type; 682{ 683 switch (type) { 684 case DBREG_DR7_EXEC : return "execute"; break; 685 case DBREG_DR7_RDWR : return "read/write"; break; 686 case DBREG_DR7_WRONLY : return "write"; break; 687 default : return "invalid"; break; 688 } 689} 690 691 692void 693db_md_list_watchpoints() 694{ 695 struct dbreg d; 696 int i, len, type; 697 698 fill_dbregs(NULL, &d); 699 700 db_printf("\nhardware watchpoints:\n"); 701 db_printf(" watch status type len address\n"); 702 db_printf(" ----- -------- ---------- --- ----------\n"); 703 for (i = 0; i < 4; i++) { 704 if (DBREG_DR7_ENABLED(d.dr[7], i)) { 705 type = DBREG_DR7_ACCESS(d.dr[7], i); 706 len = DBREG_DR7_LEN(d.dr[7], i); 707 db_printf(" %-5d %-8s %10s %3d ", 708 i, "enabled", watchtype_str(type), len + 1); 709 db_printsym((db_addr_t)DBREG_DRX((&d), i), DB_STGY_ANY); 710 db_printf("\n"); 711 } else { 712 db_printf(" %-5d disabled\n", i); 713 } 714 } 715 716 db_printf("\ndebug register values:\n"); 717 for (i = 0; i < 8; i++) { 718 db_printf(" dr%d 0x%08x\n", i, DBREG_DRX((&d), i)); 719 } 720 db_printf("\n"); 721} 722 723 724