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/stack.h> 35 #include <sys/sysent.h> 36 37 #include <machine/cpu.h> 38 #include <machine/md_var.h> 39 #include <machine/pcb.h> 40 #include <machine/reg.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 51 static db_varfcn_t db_dr0; 52 static db_varfcn_t db_dr1; 53 static db_varfcn_t db_dr2; 54 static db_varfcn_t db_dr3; 55 static db_varfcn_t db_dr4; 56 static db_varfcn_t db_dr5; 57 static db_varfcn_t db_dr6; 58 static db_varfcn_t db_dr7; 59 static db_varfcn_t db_frame; 60 static db_varfcn_t db_rsp; 61 static db_varfcn_t db_ss; 62 63 /* 64 * Machine register set. 65 */ 66 #define DB_OFFSET(x) (db_expr_t *)offsetof(struct trapframe, x) 67 struct db_variable db_regs[] = { 68 { "cs", DB_OFFSET(tf_cs), db_frame }, 69 #if 0 70 { "ds", DB_OFFSET(tf_ds), db_frame }, 71 { "es", DB_OFFSET(tf_es), db_frame }, 72 { "fs", DB_OFFSET(tf_fs), db_frame }, 73 { "gs", DB_OFFSET(tf_gs), db_frame }, 74 #endif 75 { "ss", NULL, db_ss }, 76 { "rax", DB_OFFSET(tf_rax), db_frame }, 77 { "rcx", DB_OFFSET(tf_rcx), db_frame }, 78 { "rdx", DB_OFFSET(tf_rdx), db_frame }, 79 { "rbx", DB_OFFSET(tf_rbx), db_frame }, 80 { "rsp", NULL, db_rsp }, 81 { "rbp", DB_OFFSET(tf_rbp), db_frame }, 82 { "rsi", DB_OFFSET(tf_rsi), db_frame }, 83 { "rdi", DB_OFFSET(tf_rdi), db_frame }, 84 { "r8", DB_OFFSET(tf_r8), db_frame }, 85 { "r9", DB_OFFSET(tf_r9), db_frame }, 86 { "r10", DB_OFFSET(tf_r10), db_frame }, 87 { "r11", DB_OFFSET(tf_r11), db_frame }, 88 { "r12", DB_OFFSET(tf_r12), db_frame }, 89 { "r13", DB_OFFSET(tf_r13), db_frame }, 90 { "r14", DB_OFFSET(tf_r14), db_frame }, 91 { "r15", DB_OFFSET(tf_r15), db_frame }, 92 { "rip", DB_OFFSET(tf_rip), db_frame }, 93 { "rflags", DB_OFFSET(tf_rflags), db_frame }, 94 #define DB_N_SHOW_REGS 20 /* Don't show registers after here. */ 95 { "dr0", NULL, db_dr0 }, 96 { "dr1", NULL, db_dr1 }, 97 { "dr2", NULL, db_dr2 }, 98 { "dr3", NULL, db_dr3 }, 99 { "dr4", NULL, db_dr4 }, 100 { "dr5", NULL, db_dr5 }, 101 { "dr6", NULL, db_dr6 }, 102 { "dr7", NULL, db_dr7 }, 103 }; 104 struct db_variable *db_eregs = db_regs + DB_N_SHOW_REGS; 105 106 #define DB_DRX_FUNC(reg) \ 107 static int \ 108 db_ ## reg (vp, valuep, op) \ 109 struct db_variable *vp; \ 110 db_expr_t * valuep; \ 111 int op; \ 112 { \ 113 if (op == DB_VAR_GET) \ 114 *valuep = r ## reg (); \ 115 else \ 116 load_ ## reg (*valuep); \ 117 return (1); \ 118 } 119 120 DB_DRX_FUNC(dr0) 121 DB_DRX_FUNC(dr1) 122 DB_DRX_FUNC(dr2) 123 DB_DRX_FUNC(dr3) 124 DB_DRX_FUNC(dr4) 125 DB_DRX_FUNC(dr5) 126 DB_DRX_FUNC(dr6) 127 DB_DRX_FUNC(dr7) 128 129 static __inline long 130 get_rsp(struct trapframe *tf) 131 { 132 return ((ISPL(tf->tf_cs)) ? tf->tf_rsp : 133 (db_expr_t)tf + offsetof(struct trapframe, tf_rsp)); 134 } 135 136 static int 137 db_frame(struct db_variable *vp, db_expr_t *valuep, int op) 138 { 139 long *reg; 140 141 if (kdb_frame == NULL) 142 return (0); 143 144 reg = (long *)((uintptr_t)kdb_frame + (db_expr_t)vp->valuep); 145 if (op == DB_VAR_GET) 146 *valuep = *reg; 147 else 148 *reg = *valuep; 149 return (1); 150 } 151 152 static int 153 db_rsp(struct db_variable *vp, db_expr_t *valuep, int op) 154 { 155 156 if (kdb_frame == NULL) 157 return (0); 158 159 if (op == DB_VAR_GET) 160 *valuep = get_rsp(kdb_frame); 161 else if (ISPL(kdb_frame->tf_cs)) 162 kdb_frame->tf_rsp = *valuep; 163 return (1); 164 } 165 166 static int 167 db_ss(struct db_variable *vp, db_expr_t *valuep, int op) 168 { 169 170 if (kdb_frame == NULL) 171 return (0); 172 173 if (op == DB_VAR_GET) 174 *valuep = (ISPL(kdb_frame->tf_cs)) ? kdb_frame->tf_ss : rss(); 175 else if (ISPL(kdb_frame->tf_cs)) 176 kdb_frame->tf_ss = *valuep; 177 return (1); 178 } 179 180 /* 181 * Stack trace. 182 */ 183 #define INKERNEL(va) (((va) >= DMAP_MIN_ADDRESS && (va) < DMAP_MAX_ADDRESS) \ 184 || ((va) >= KERNBASE && (va) < VM_MAX_KERNEL_ADDRESS)) 185 186 struct amd64_frame { 187 struct amd64_frame *f_frame; 188 long f_retaddr; 189 long f_arg0; 190 }; 191 192 #define NORMAL 0 193 #define TRAP 1 194 #define INTERRUPT 2 195 #define SYSCALL 3 196 #define TRAP_INTERRUPT 5 197 198 static void db_nextframe(struct amd64_frame **, db_addr_t *, struct thread *); 199 static int db_numargs(struct amd64_frame *); 200 static void db_print_stack_entry(const char *, int, char **, long *, db_addr_t); 201 static void decode_syscall(int, struct thread *); 202 203 static const char * watchtype_str(int type); 204 int amd64_set_watch(int watchnum, unsigned long watchaddr, int size, 205 int access, struct dbreg *d); 206 int amd64_clr_watch(int watchnum, struct dbreg *d); 207 208 /* 209 * Figure out how many arguments were passed into the frame at "fp". 210 */ 211 static int 212 db_numargs(fp) 213 struct amd64_frame *fp; 214 { 215 #if 1 216 return (0); /* regparm, needs dwarf2 info */ 217 #else 218 long *argp; 219 int inst; 220 int args; 221 222 argp = (long *)db_get_value((long)&fp->f_retaddr, 8, FALSE); 223 /* 224 * XXX etext is wrong for LKMs. We should attempt to interpret 225 * the instruction at the return address in all cases. This 226 * may require better fault handling. 227 */ 228 if (argp < (long *)btext || argp >= (long *)etext) { 229 args = 5; 230 } else { 231 inst = db_get_value((long)argp, 4, FALSE); 232 if ((inst & 0xff) == 0x59) /* popl %ecx */ 233 args = 1; 234 else if ((inst & 0xffff) == 0xc483) /* addl $Ibs, %esp */ 235 args = ((inst >> 16) & 0xff) / 4; 236 else 237 args = 5; 238 } 239 return (args); 240 #endif 241 } 242 243 static void 244 db_print_stack_entry(name, narg, argnp, argp, callpc) 245 const char *name; 246 int narg; 247 char **argnp; 248 long *argp; 249 db_addr_t callpc; 250 { 251 db_printf("%s(", name); 252 #if 0 253 while (narg) { 254 if (argnp) 255 db_printf("%s=", *argnp++); 256 db_printf("%lr", (long)db_get_value((long)argp, 8, FALSE)); 257 argp++; 258 if (--narg != 0) 259 db_printf(","); 260 } 261 #endif 262 db_printf(") at "); 263 db_printsym(callpc, DB_STGY_PROC); 264 db_printf("\n"); 265 } 266 267 static void 268 decode_syscall(int number, struct thread *td) 269 { 270 struct proc *p; 271 c_db_sym_t sym; 272 db_expr_t diff; 273 sy_call_t *f; 274 const char *symname; 275 276 db_printf(" (%d", number); 277 p = (td != NULL) ? td->td_proc : NULL; 278 if (p != NULL && 0 <= number && number < p->p_sysent->sv_size) { 279 f = p->p_sysent->sv_table[number].sy_call; 280 sym = db_search_symbol((db_addr_t)f, DB_STGY_ANY, &diff); 281 if (sym != DB_SYM_NULL && diff == 0) { 282 db_symbol_values(sym, &symname, NULL); 283 db_printf(", %s, %s", p->p_sysent->sv_name, symname); 284 } 285 } 286 db_printf(")"); 287 } 288 289 /* 290 * Figure out the next frame up in the call stack. 291 */ 292 static void 293 db_nextframe(struct amd64_frame **fp, db_addr_t *ip, struct thread *td) 294 { 295 struct trapframe *tf; 296 int frame_type; 297 long rip, rsp, rbp; 298 db_expr_t offset; 299 c_db_sym_t sym; 300 const char *name; 301 302 rip = db_get_value((long) &(*fp)->f_retaddr, 8, FALSE); 303 rbp = db_get_value((long) &(*fp)->f_frame, 8, FALSE); 304 305 /* 306 * Figure out frame type. We look at the address just before 307 * the saved instruction pointer as the saved EIP is after the 308 * call function, and if the function being called is marked as 309 * dead (such as panic() at the end of dblfault_handler()), then 310 * the instruction at the saved EIP will be part of a different 311 * function (syscall() in this example) rather than the one that 312 * actually made the call. 313 */ 314 frame_type = NORMAL; 315 sym = db_search_symbol(rip - 1, DB_STGY_ANY, &offset); 316 db_symbol_values(sym, &name, NULL); 317 if (name != NULL) { 318 if (strcmp(name, "calltrap") == 0 || 319 strcmp(name, "fork_trampoline") == 0 || 320 strcmp(name, "nmi_calltrap") == 0) 321 frame_type = TRAP; 322 else if (strncmp(name, "Xatpic_intr", 11) == 0 || 323 strncmp(name, "Xapic_isr", 9) == 0 || 324 strcmp(name, "Xtimerint") == 0 || 325 strcmp(name, "Xipi_intr_bitmap_handler") == 0 || 326 strcmp(name, "Xcpustop") == 0 || 327 strcmp(name, "Xrendezvous") == 0) 328 frame_type = INTERRUPT; 329 else if (strcmp(name, "Xfast_syscall") == 0) 330 frame_type = SYSCALL; 331 /* XXX: These are interrupts with trap frames. */ 332 else if (strcmp(name, "Xtimerint") == 0 || 333 strcmp(name, "Xcpustop") == 0 || 334 strcmp(name, "Xrendezvous") == 0 || 335 strcmp(name, "Xipi_intr_bitmap_handler") == 0) 336 frame_type = TRAP_INTERRUPT; 337 } 338 339 /* 340 * Normal frames need no special processing. 341 */ 342 if (frame_type == NORMAL) { 343 *ip = (db_addr_t) rip; 344 *fp = (struct amd64_frame *) rbp; 345 return; 346 } 347 348 db_print_stack_entry(name, 0, 0, 0, rip); 349 350 /* 351 * Point to base of trapframe which is just above the 352 * current frame. 353 */ 354 tf = (struct trapframe *)((long)*fp + 16); 355 356 if (INKERNEL((long) tf)) { 357 rsp = get_rsp(tf); 358 rip = tf->tf_rip; 359 rbp = tf->tf_rbp; 360 switch (frame_type) { 361 case TRAP: 362 db_printf("--- trap %#lr", tf->tf_trapno); 363 break; 364 case SYSCALL: 365 db_printf("--- syscall"); 366 decode_syscall(tf->tf_rax, td); 367 break; 368 case TRAP_INTERRUPT: 369 case INTERRUPT: 370 db_printf("--- interrupt"); 371 break; 372 default: 373 panic("The moon has moved again."); 374 } 375 db_printf(", rip = %#lr, rsp = %#lr, rbp = %#lr ---\n", rip, 376 rsp, rbp); 377 } 378 379 *ip = (db_addr_t) rip; 380 *fp = (struct amd64_frame *) rbp; 381 } 382 383 static int 384 db_backtrace(struct thread *td, struct trapframe *tf, 385 struct amd64_frame *frame, db_addr_t pc, int count) 386 { 387 struct amd64_frame *actframe; 388 #define MAXNARG 16 389 char *argnames[MAXNARG], **argnp = NULL; 390 const char *name; 391 long *argp; 392 db_expr_t offset; 393 c_db_sym_t sym; 394 int narg; 395 boolean_t first; 396 397 if (count == -1) 398 count = 1024; 399 400 first = TRUE; 401 while (count-- && !db_pager_quit) { 402 sym = db_search_symbol(pc, DB_STGY_ANY, &offset); 403 db_symbol_values(sym, &name, NULL); 404 405 /* 406 * Attempt to determine a (possibly fake) frame that gives 407 * the caller's pc. It may differ from `frame' if the 408 * current function never sets up a standard frame or hasn't 409 * set one up yet or has just discarded one. The last two 410 * cases can be guessed fairly reliably for code generated 411 * by gcc. The first case is too much trouble to handle in 412 * general because the amount of junk on the stack depends 413 * on the pc (the special handling of "calltrap", etc. in 414 * db_nextframe() works because the `next' pc is special). 415 */ 416 actframe = frame; 417 if (first) { 418 if (tf != NULL) { 419 int instr; 420 421 instr = db_get_value(pc, 4, FALSE); 422 if ((instr & 0xffffffff) == 0xe5894855) { 423 /* pushq %rbp; movq %rsp, %rbp */ 424 actframe = (void *)(get_rsp(tf) - 8); 425 } else if ((instr & 0xffffff) == 0xe58948) { 426 /* movq %rsp, %rbp */ 427 actframe = (void *)get_rsp(tf); 428 if (tf->tf_rbp == 0) { 429 /* Fake frame better. */ 430 frame = actframe; 431 } 432 } else if ((instr & 0xff) == 0xc3) { 433 /* ret */ 434 actframe = (void *)(get_rsp(tf) - 8); 435 } else if (offset == 0) { 436 /* Probably an assembler symbol. */ 437 actframe = (void *)(get_rsp(tf) - 8); 438 } 439 } else if (strcmp(name, "fork_trampoline") == 0) { 440 /* 441 * Don't try to walk back on a stack for a 442 * process that hasn't actually been run yet. 443 */ 444 db_print_stack_entry(name, 0, 0, 0, pc); 445 break; 446 } 447 first = FALSE; 448 } 449 450 argp = &actframe->f_arg0; 451 narg = MAXNARG; 452 if (sym != NULL && db_sym_numargs(sym, &narg, argnames)) { 453 argnp = argnames; 454 } else { 455 narg = db_numargs(frame); 456 } 457 458 db_print_stack_entry(name, narg, argnp, argp, pc); 459 460 if (actframe != frame) { 461 /* `frame' belongs to caller. */ 462 pc = (db_addr_t) 463 db_get_value((long)&actframe->f_retaddr, 8, FALSE); 464 continue; 465 } 466 467 db_nextframe(&frame, &pc, td); 468 469 if (INKERNEL((long)pc) && !INKERNEL((long)frame)) { 470 sym = db_search_symbol(pc, DB_STGY_ANY, &offset); 471 db_symbol_values(sym, &name, NULL); 472 db_print_stack_entry(name, 0, 0, 0, pc); 473 break; 474 } 475 if (!INKERNEL((long) frame)) { 476 break; 477 } 478 } 479 480 return (0); 481 } 482 483 void 484 db_trace_self(void) 485 { 486 struct amd64_frame *frame; 487 db_addr_t callpc; 488 register_t rbp; 489 490 __asm __volatile("movq %%rbp,%0" : "=r" (rbp)); 491 frame = (struct amd64_frame *)rbp; 492 callpc = (db_addr_t)db_get_value((long)&frame->f_retaddr, 8, FALSE); 493 frame = frame->f_frame; 494 db_backtrace(curthread, NULL, frame, callpc, -1); 495 } 496 497 int 498 db_trace_thread(struct thread *thr, int count) 499 { 500 struct pcb *ctx; 501 502 ctx = kdb_thr_ctx(thr); 503 return (db_backtrace(thr, NULL, (struct amd64_frame *)ctx->pcb_rbp, 504 ctx->pcb_rip, count)); 505 } 506 507 void 508 stack_save(struct stack *st) 509 { 510 struct amd64_frame *frame; 511 vm_offset_t callpc; 512 register_t rbp; 513 514 stack_zero(st); 515 __asm __volatile("movq %%rbp,%0" : "=r" (rbp)); 516 frame = (struct amd64_frame *)rbp; 517 while (1) { 518 if (!INKERNEL((long)frame)) 519 break; 520 callpc = frame->f_retaddr; 521 if (!INKERNEL(callpc)) 522 break; 523 if (stack_put(st, callpc) == -1) 524 break; 525 if (frame->f_frame <= frame || 526 (vm_offset_t)frame->f_frame >= 527 (vm_offset_t)rbp + KSTACK_PAGES * PAGE_SIZE) 528 break; 529 frame = frame->f_frame; 530 } 531 } 532 533 int 534 amd64_set_watch(watchnum, watchaddr, size, access, d) 535 int watchnum; 536 unsigned long watchaddr; 537 int size; 538 int access; 539 struct dbreg *d; 540 { 541 int i, len; 542 543 if (watchnum == -1) { 544 for (i = 0; i < 4; i++) 545 if (!DBREG_DR7_ENABLED(d->dr[7], i)) 546 break; 547 if (i < 4) 548 watchnum = i; 549 else 550 return (-1); 551 } 552 553 switch (access) { 554 case DBREG_DR7_EXEC: 555 size = 1; /* size must be 1 for an execution breakpoint */ 556 /* fall through */ 557 case DBREG_DR7_WRONLY: 558 case DBREG_DR7_RDWR: 559 break; 560 default: 561 return (-1); 562 } 563 564 /* 565 * we can watch a 1, 2, 4, or 8 byte sized location 566 */ 567 switch (size) { 568 case 1: 569 len = DBREG_DR7_LEN_1; 570 break; 571 case 2: 572 len = DBREG_DR7_LEN_2; 573 break; 574 case 4: 575 len = DBREG_DR7_LEN_4; 576 break; 577 case 8: 578 len = DBREG_DR7_LEN_8; 579 break; 580 default: 581 return (-1); 582 } 583 584 /* clear the bits we are about to affect */ 585 d->dr[7] &= ~DBREG_DR7_MASK(watchnum); 586 587 /* set drN register to the address, N=watchnum */ 588 DBREG_DRX(d, watchnum) = watchaddr; 589 590 /* enable the watchpoint */ 591 d->dr[7] |= DBREG_DR7_SET(watchnum, len, access, 592 DBREG_DR7_GLOBAL_ENABLE); 593 594 return (watchnum); 595 } 596 597 598 int 599 amd64_clr_watch(watchnum, d) 600 int watchnum; 601 struct dbreg *d; 602 { 603 604 if (watchnum < 0 || watchnum >= 4) 605 return (-1); 606 607 d->dr[7] &= ~DBREG_DR7_MASK(watchnum); 608 DBREG_DRX(d, watchnum) = 0; 609 610 return (0); 611 } 612 613 614 int 615 db_md_set_watchpoint(addr, size) 616 db_expr_t addr; 617 db_expr_t size; 618 { 619 struct dbreg d; 620 int avail, i, wsize; 621 622 fill_dbregs(NULL, &d); 623 624 avail = 0; 625 for(i = 0; i < 4; i++) { 626 if (!DBREG_DR7_ENABLED(d.dr[7], i)) 627 avail++; 628 } 629 630 if (avail * 8 < size) 631 return (-1); 632 633 for (i = 0; i < 4 && (size > 0); i++) { 634 if (!DBREG_DR7_ENABLED(d.dr[7], i)) { 635 if (size >= 8 || (avail == 1 && size > 4)) 636 wsize = 8; 637 else if (size > 2) 638 wsize = 4; 639 else 640 wsize = size; 641 amd64_set_watch(i, addr, wsize, 642 DBREG_DR7_WRONLY, &d); 643 addr += wsize; 644 size -= wsize; 645 avail--; 646 } 647 } 648 649 set_dbregs(NULL, &d); 650 651 return(0); 652 } 653 654 655 int 656 db_md_clr_watchpoint(addr, size) 657 db_expr_t addr; 658 db_expr_t size; 659 { 660 struct dbreg d; 661 int i; 662 663 fill_dbregs(NULL, &d); 664 665 for(i = 0; i < 4; i++) { 666 if (DBREG_DR7_ENABLED(d.dr[7], i)) { 667 if ((DBREG_DRX((&d), i) >= addr) && 668 (DBREG_DRX((&d), i) < addr+size)) 669 amd64_clr_watch(i, &d); 670 671 } 672 } 673 674 set_dbregs(NULL, &d); 675 676 return(0); 677 } 678 679 680 static const char * 681 watchtype_str(type) 682 int type; 683 { 684 switch (type) { 685 case DBREG_DR7_EXEC : return "execute"; break; 686 case DBREG_DR7_RDWR : return "read/write"; break; 687 case DBREG_DR7_WRONLY : return "write"; break; 688 default : return "invalid"; break; 689 } 690 } 691 692 693 void 694 db_md_list_watchpoints() 695 { 696 struct dbreg d; 697 int i, len, type; 698 699 fill_dbregs(NULL, &d); 700 701 db_printf("\nhardware watchpoints:\n"); 702 db_printf(" watch status type len address\n"); 703 db_printf(" ----- -------- ---------- --- ------------------\n"); 704 for (i = 0; i < 4; i++) { 705 if (DBREG_DR7_ENABLED(d.dr[7], i)) { 706 type = DBREG_DR7_ACCESS(d.dr[7], i); 707 len = DBREG_DR7_LEN(d.dr[7], i); 708 if (len == DBREG_DR7_LEN_8) 709 len = 8; 710 else 711 len++; 712 db_printf(" %-5d %-8s %10s %3d ", 713 i, "enabled", watchtype_str(type), len); 714 db_printsym((db_addr_t)DBREG_DRX((&d), i), DB_STGY_ANY); 715 db_printf("\n"); 716 } else { 717 db_printf(" %-5d disabled\n", i); 718 } 719 } 720 721 db_printf("\ndebug register values:\n"); 722 for (i = 0; i < 8; i++) { 723 db_printf(" dr%d 0x%016lx\n", i, DBREG_DRX((&d), i)); 724 } 725 db_printf("\n"); 726 } 727