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