1/* 2 * Copyright (c) 2000-2005 Apple Computer, Inc. All rights reserved. 3 * 4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. The rights granted to you under the License 10 * may not be used to create, or enable the creation or redistribution of, 11 * unlawful or unlicensed copies of an Apple operating system, or to 12 * circumvent, violate, or enable the circumvention or violation of, any 13 * terms of an Apple operating system software license agreement. 14 * 15 * Please obtain a copy of the License at 16 * http://www.opensource.apple.com/apsl/ and read it before using this file. 17 * 18 * The Original Code and all software distributed under the License are 19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 23 * Please see the License for the specific language governing rights and 24 * limitations under the License. 25 * 26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ 27 */ 28/* 29 * @OSF_COPYRIGHT@ 30 */ 31/* 32 * Mach Operating System 33 * Copyright (c) 1991,1990 Carnegie Mellon University 34 * All Rights Reserved. 35 * 36 * Permission to use, copy, modify and distribute this software and its 37 * documentation is hereby granted, provided that both the copyright 38 * notice and this permission notice appear in all copies of the 39 * software, derivative works or modified versions, and any portions 40 * thereof, and that both notices appear in supporting documentation. 41 * 42 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" 43 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR 44 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 45 * 46 * Carnegie Mellon requests users of this software to return to 47 * 48 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU 49 * School of Computer Science 50 * Carnegie Mellon University 51 * Pittsburgh PA 15213-3890 52 * 53 * any improvements or extensions that they make and grant Carnegie Mellon 54 * the rights to redistribute these changes. 55 */ 56/* 57 */ 58 59/* 60 * Interface to new debugger. 61 */ 62#include <platforms.h> 63#include <time_stamp.h> 64#include <mach_mp_debug.h> 65#include <mach_ldebug.h> 66#include <kern/spl.h> 67#include <kern/cpu_number.h> 68#include <kern/kern_types.h> 69#include <kern/misc_protos.h> 70#include <vm/pmap.h> 71 72#include <i386/thread.h> 73#include <i386/db_machdep.h> 74#include <i386/seg.h> 75#include <i386/trap.h> 76#include <i386/setjmp.h> 77#include <i386/pmap.h> 78#include <i386/misc_protos.h> 79#include <i386/mp.h> 80#include <i386/machine_cpu.h> 81 82#include <mach/vm_param.h> 83#include <vm/vm_map.h> 84#include <kern/thread.h> 85#include <kern/task.h> 86 87#include <ddb/db_command.h> 88#include <ddb/db_task_thread.h> 89#include <ddb/db_run.h> 90#include <ddb/db_trap.h> 91#include <ddb/db_output.h> 92#include <ddb/db_access.h> 93#include <ddb/db_sym.h> 94#include <ddb/db_break.h> 95#include <ddb/db_watch.h> 96 97#include <i386/cpu_data.h> 98 99int db_active = 0; 100x86_saved_state32_t *i386_last_saved_statep; 101x86_saved_state32_t i386_nested_saved_state; 102unsigned i386_last_kdb_sp; 103 104extern thread_t db_default_act; 105extern pt_entry_t *DMAP1; 106extern caddr_t DADDR1; 107 108#if MACH_MP_DEBUG 109extern int masked_state_cnt[]; 110#endif /* MACH_MP_DEBUG */ 111 112/* 113 * Enter KDB through a keyboard trap. 114 * We show the registers as of the keyboard interrupt 115 * instead of those at its call to KDB. 116 */ 117struct int_regs { 118 int gs; 119 int fs; 120 int edi; 121 int esi; 122 int ebp; 123 int ebx; 124 x86_saved_state32_t *is; 125}; 126 127extern char * trap_type[]; 128extern int TRAP_TYPES; 129 130/* Forward */ 131 132extern void kdbprinttrap( 133 int type, 134 int code, 135 int *pc, 136 int sp); 137extern void kdb_kentry( 138 struct int_regs *int_regs); 139extern int db_user_to_kernel_address( 140 task_t task, 141 vm_offset_t addr, 142 unsigned *kaddr, 143 int flag); 144extern void db_write_bytes_user_space( 145 vm_offset_t addr, 146 int size, 147 char *data, 148 task_t task); 149extern int db_search_null( 150 task_t task, 151 unsigned *svaddr, 152 unsigned evaddr, 153 unsigned *skaddr, 154 int flag); 155extern int kdb_enter(int); 156extern void kdb_leave(void); 157extern void lock_kdb(void); 158extern void unlock_kdb(void); 159 160/* 161 * kdb_trap - field a TRACE or BPT trap 162 */ 163 164 165extern jmp_buf_t *db_recover; 166 167/* 168 * Translate the state saved in a task state segment into an 169 * exception frame. Since we "know" we always want the state 170 * in a ktss, we hard-wire that in, rather than indexing the gdt 171 * with tss_sel to derive a pointer to the desired tss. 172 */ 173 174/* 175 * Code used to synchronize kdb among all cpus, one active at a time, switch 176 * from one to another using cpu #cpu 177 */ 178 179decl_simple_lock_data(, kdb_lock) /* kdb lock */ 180 181#define db_simple_lock_init(l, e) hw_lock_init(&((l)->interlock)) 182#define db_simple_lock_try(l) hw_lock_try(&((l)->interlock)) 183#define db_simple_unlock(l) hw_lock_unlock(&((l)->interlock)) 184 185int kdb_cpu = -1; /* current cpu running kdb */ 186int kdb_debug = 1; 187volatile unsigned int cpus_holding_bkpts; /* counter for number of cpus 188 * holding breakpoints 189 */ 190extern boolean_t db_breakpoints_inserted; 191 192void 193db_tss_to_frame( 194 int tss_sel, 195 x86_saved_state32_t *regs) 196{ 197 extern struct i386_tss ktss; 198 int mycpu = cpu_number(); 199 struct i386_tss *tss; 200 201 tss = cpu_datap(mycpu)->cpu_desc_index.cdi_ktss; /* XXX */ 202 203 /* 204 * ddb will overwrite whatever's in esp, so put esp0 elsewhere, too. 205 */ 206 regs->cr2 = tss->esp0; 207 regs->efl = tss->eflags; 208 regs->eip = tss->eip; 209 regs->trapno = tss->ss0; /* XXX */ 210 regs->err = tss->esp0; /* XXX */ 211 regs->eax = tss->eax; 212 regs->ecx = tss->ecx; 213 regs->edx = tss->edx; 214 regs->ebx = tss->ebx; 215 regs->uesp = tss->esp; 216 regs->ebp = tss->ebp; 217 regs->esi = tss->esi; 218 regs->edi = tss->edi; 219 regs->es = tss->es; 220 regs->ss = tss->ss; 221 regs->cs = tss->cs; 222 regs->ds = tss->ds; 223 regs->fs = tss->fs; 224 regs->gs = tss->gs; 225} 226 227/* 228 * Compose a call to the debugger from the saved state in regs. (No 229 * reason not to do this in C.) 230 */ 231boolean_t 232db_trap_from_asm( 233 x86_saved_state32_t *regs) 234{ 235 int code; 236 int type; 237 238 type = regs->trapno; 239 code = regs->err; 240 return (kdb_trap(type, code, regs)); 241} 242 243int 244kdb_trap( 245 int type, 246 int code, 247 x86_saved_state32_t *regs) 248{ 249 extern char etext; 250 boolean_t trap_from_user; 251 spl_t s; 252 int previous_console_device; 253 254 s = splhigh(); 255 256 previous_console_device = switch_to_serial_console(); 257 258 db_printf("kdb_trap(): type %d, code %d, regs->eip 0x%x\n", type, code, regs->eip); 259 switch (type) { 260 case T_DEBUG: /* single_step */ 261 { 262 extern int dr_addr[]; 263 int addr; 264 uint32_t status; 265 266 __asm__ volatile ("movl %%dr6, %0" : "=r" (status)); 267 268 if (status & 0xf) { /* hmm hdw break */ 269 addr = status & 0x8 ? dr_addr[3] : 270 status & 0x4 ? dr_addr[2] : 271 status & 0x2 ? dr_addr[1] : 272 dr_addr[0]; 273 regs->efl |= EFL_RF; 274 db_single_step_cmd(addr, 0, 1, "p"); 275 } 276 } 277 case T_INT3: /* breakpoint */ 278 case T_WATCHPOINT: /* watchpoint */ 279 case -1: /* keyboard interrupt */ 280 break; 281 282 default: 283 if (db_recover) { 284 i386_nested_saved_state = *regs; 285 db_printf("Caught "); 286 if (type < 0 || type > TRAP_TYPES) 287 db_printf("type %d", type); 288 else 289 db_printf("%s", trap_type[type]); 290 db_printf(" trap, code = %x, pc = %x\n", 291 code, regs->eip); 292 splx(s); 293 db_error(""); 294 /*NOTREACHED*/ 295 } 296 kdbprinttrap(type, code, (int *)®s->eip, regs->uesp); 297 } 298 299 disable_preemption(); 300 301 current_cpu_datap()->cpu_kdb_saved_ipl = s; 302 current_cpu_datap()->cpu_kdb_saved_state = regs; 303 304 i386_last_saved_statep = regs; 305 i386_last_kdb_sp = (unsigned) &type; 306 307 if (!kdb_enter(regs->eip)) 308 goto kdb_exit; 309 310 /* Should switch to kdb's own stack here. */ 311 312 if (!IS_USER_TRAP(regs, &etext)) { 313 bzero((char *)&ddb_regs, sizeof (ddb_regs)); 314 *(struct x86_saved_state32_from_kernel *)&ddb_regs = 315 *(struct x86_saved_state32_from_kernel *)regs; 316 trap_from_user = FALSE; 317 } 318 else { 319 ddb_regs = *regs; 320 trap_from_user = TRUE; 321 } 322 if (!trap_from_user) { 323 /* 324 * Kernel mode - esp and ss not saved 325 */ 326 ddb_regs.uesp = (int)®s->uesp; /* kernel stack pointer */ 327 ddb_regs.ss = KERNEL_DS; 328 } 329 330 db_active++; 331 db_task_trap(type, code, trap_from_user); 332 db_active--; 333 334 regs->eip = ddb_regs.eip; 335 regs->efl = ddb_regs.efl; 336 regs->eax = ddb_regs.eax; 337 regs->ecx = ddb_regs.ecx; 338 regs->edx = ddb_regs.edx; 339 regs->ebx = ddb_regs.ebx; 340 341 if (trap_from_user) { 342 /* 343 * user mode - saved esp and ss valid 344 */ 345 regs->uesp = ddb_regs.uesp; /* user stack pointer */ 346 regs->ss = ddb_regs.ss & 0xffff; /* user stack segment */ 347 } 348 349 regs->ebp = ddb_regs.ebp; 350 regs->esi = ddb_regs.esi; 351 regs->edi = ddb_regs.edi; 352 regs->es = ddb_regs.es & 0xffff; 353 regs->cs = ddb_regs.cs & 0xffff; 354 regs->ds = ddb_regs.ds & 0xffff; 355 regs->fs = ddb_regs.fs & 0xffff; 356 regs->gs = ddb_regs.gs & 0xffff; 357 358 if ((type == T_INT3) && 359 (db_get_task_value(regs->eip, 360 BKPT_SIZE, 361 FALSE, 362 db_target_space(current_thread(), 363 trap_from_user)) 364 == BKPT_INST)) 365 regs->eip += BKPT_SIZE; 366 367 switch_to_old_console(previous_console_device); 368kdb_exit: 369 kdb_leave(); 370 371 current_cpu_datap()->cpu_kdb_saved_state = 0; 372 373 enable_preemption(); 374 375 splx(s); 376 377 /* Allow continue to upper layers of exception handling if 378 * trap was not a debugging trap. 379 */ 380 381 if (trap_from_user && type != T_DEBUG && type != T_INT3 382 && type != T_WATCHPOINT) 383 return 0; 384 else 385 return (1); 386} 387 388/* 389 * Enter KDB through a keyboard trap. 390 * We show the registers as of the keyboard interrupt 391 * instead of those at its call to KDB. 392 */ 393 394spl_t kdb_oldspl; 395 396void 397kdb_kentry( 398 struct int_regs *int_regs) 399{ 400 extern char etext; 401 boolean_t trap_from_user; 402 x86_saved_state32_t *is = int_regs->is; 403 x86_saved_state32_t regs; 404 spl_t s; 405 406 s = splhigh(); 407 kdb_oldspl = s; 408 409 if (IS_USER_TRAP(is, &etext)) 410 { 411 regs.uesp = ((int *)(is+1))[0]; 412 regs.ss = ((int *)(is+1))[1]; 413 } 414 else { 415 regs.ss = KERNEL_DS; 416 regs.uesp= (int)(is+1); 417 } 418 regs.efl = is->efl; 419 regs.cs = is->cs; 420 regs.eip = is->eip; 421 regs.eax = is->eax; 422 regs.ecx = is->ecx; 423 regs.edx = is->edx; 424 regs.ebx = int_regs->ebx; 425 regs.ebp = int_regs->ebp; 426 regs.esi = int_regs->esi; 427 regs.edi = int_regs->edi; 428 regs.ds = is->ds; 429 regs.es = is->es; 430 regs.fs = int_regs->fs; 431 regs.gs = int_regs->gs; 432 433 disable_preemption(); 434 435 current_cpu_datap()->cpu_kdb_saved_state = ®s; 436 437 if (!kdb_enter(regs.eip)) 438 goto kdb_exit; 439 440 bcopy((char *)®s, (char *)&ddb_regs, sizeof (ddb_regs)); 441 trap_from_user = IS_USER_TRAP(&ddb_regs, &etext); 442 443 db_active++; 444 db_task_trap(-1, 0, trap_from_user); 445 db_active--; 446 447 if (trap_from_user) { 448 ((int *)(is+1))[0] = ddb_regs.uesp; 449 ((int *)(is+1))[1] = ddb_regs.ss & 0xffff; 450 } 451 is->efl = ddb_regs.efl; 452 is->cs = ddb_regs.cs & 0xffff; 453 is->eip = ddb_regs.eip; 454 is->eax = ddb_regs.eax; 455 is->ecx = ddb_regs.ecx; 456 is->edx = ddb_regs.edx; 457 int_regs->ebx = ddb_regs.ebx; 458 int_regs->ebp = ddb_regs.ebp; 459 int_regs->esi = ddb_regs.esi; 460 int_regs->edi = ddb_regs.edi; 461 is->ds = ddb_regs.ds & 0xffff; 462 is->es = ddb_regs.es & 0xffff; 463 int_regs->fs = ddb_regs.fs & 0xffff; 464 int_regs->gs = ddb_regs.gs & 0xffff; 465 466kdb_exit: 467 kdb_leave(); 468 current_cpu_datap()->cpu_kdb_saved_state = 0; 469 470 enable_preemption(); 471 472 splx(s); 473} 474 475/* 476 * Print trap reason. 477 */ 478 479void 480kdbprinttrap( 481 int type, 482 int code, 483 int *pc, 484 int sp) 485{ 486 printf("kernel: "); 487 if (type < 0 || type > TRAP_TYPES) 488 db_printf("type %d", type); 489 else 490 db_printf("%s", trap_type[type]); 491 db_printf(" trap, code=%x eip@%x = %x esp=%x\n", 492 code, pc, *(int *)pc, sp); 493 db_run_mode = STEP_CONTINUE; 494} 495 496int 497db_user_to_kernel_address( 498 task_t task, 499 vm_offset_t addr, 500 unsigned *kaddr, 501 int flag) 502{ 503 register pt_entry_t *ptp; 504 vm_offset_t src; 505 506 /* 507 * must not pre-empted while using the pte pointer passed 508 * back since it's been mapped through a per-cpu window 509 */ 510 mp_disable_preemption(); 511 512 ptp = pmap_pte(task->map->pmap, (vm_map_offset_t)addr); 513 if (ptp == PT_ENTRY_NULL || (*ptp & INTEL_PTE_VALID) == 0) { 514 if (flag) { 515 db_printf("\nno memory is assigned to address %08x\n", addr); 516 db_error(0); 517 /* NOTREACHED */ 518 } 519 mp_enable_preemption(); 520 return(-1); 521 } 522 src = (vm_offset_t)pte_to_pa(*ptp); 523 524 mp_enable_preemption(); 525 526 *(int *) DMAP1 = INTEL_PTE_VALID | INTEL_PTE_RW | (src & PG_FRAME) | 527 INTEL_PTE_REF | INTEL_PTE_MOD; 528#if defined(I386_CPU) 529 if (cpu_class == CPUCLASS_386) { 530 invltlb(); 531 } else 532#endif 533 { 534 invlpg((u_int)DADDR1); 535 } 536 537 *kaddr = (unsigned)DADDR1 + (addr & PAGE_MASK); 538 539 return(0); 540} 541 542/* 543 * Read bytes from kernel address space for debugger. 544 */ 545 546void 547db_read_bytes( 548 vm_offset_t addr, 549 int size, 550 char *data, 551 task_t task) 552{ 553 register char *src; 554 register int n; 555 unsigned kern_addr; 556 557 src = (char *)addr; 558 if (task == kernel_task || task == TASK_NULL) { 559 while (--size >= 0) { 560 if (addr++ > VM_MAX_KERNEL_ADDRESS) { 561 db_printf("\nbad address %x\n", addr); 562 db_error(0); 563 /* NOTREACHED */ 564 } 565 *data++ = *src++; 566 } 567 return; 568 } 569 while (size > 0) { 570 if (db_user_to_kernel_address(task, addr, &kern_addr, 1) < 0) 571 return; 572 src = (char *)kern_addr; 573 n = intel_trunc_page(addr+INTEL_PGBYTES) - addr; 574 if (n > size) 575 n = size; 576 size -= n; 577 addr += n; 578 while (--n >= 0) 579 *data++ = *src++; 580 } 581} 582 583/* 584 * Write bytes to kernel address space for debugger. 585 */ 586 587void 588db_write_bytes( 589 vm_offset_t addr, 590 int size, 591 char *data, 592 task_t task) 593{ 594 register char *dst; 595 596 register pt_entry_t *ptep0 = 0; 597 pt_entry_t oldmap0 = 0; 598 vm_offset_t addr1; 599 register pt_entry_t *ptep1 = 0; 600 pt_entry_t oldmap1 = 0; 601 extern char etext; 602 603 if (task && task != kernel_task) { 604 db_write_bytes_user_space(addr, size, data, task); 605 return; 606 } 607 608 609 if (addr >= VM_MIN_KERNEL_LOADED_ADDRESS) { 610 db_write_bytes_user_space(addr, size, data, kernel_task); 611 return; 612 } 613 614 if (addr >= VM_MIN_KERNEL_ADDRESS && 615 addr <= (vm_offset_t)&etext) 616 { 617 ptep0 = pmap_pte(kernel_pmap, (vm_map_offset_t)addr); 618 oldmap0 = *ptep0; 619 *ptep0 |= INTEL_PTE_WRITE; 620 621 addr1 = i386_trunc_page(addr + size - 1); 622 if (i386_trunc_page(addr) != addr1) { 623 /* data crosses a page boundary */ 624 625 ptep1 = pmap_pte(kernel_pmap, (vm_map_offset_t)addr1); 626 oldmap1 = *ptep1; 627 *ptep1 |= INTEL_PTE_WRITE; 628 } 629 flush_tlb(); 630 } 631 632 dst = (char *)addr; 633 634 while (--size >= 0) { 635 if (addr++ > VM_MAX_KERNEL_ADDRESS) { 636 db_printf("\nbad address %x\n", addr); 637 db_error(0); 638 /* NOTREACHED */ 639 } 640 *dst++ = *data++; 641 } 642 643 if (ptep0) { 644 *ptep0 = oldmap0; 645 if (ptep1) { 646 *ptep1 = oldmap1; 647 } 648 flush_tlb(); 649 } 650} 651 652void 653db_write_bytes_user_space( 654 vm_offset_t addr, 655 int size, 656 char *data, 657 task_t task) 658{ 659 register char *dst; 660 register int n; 661 unsigned kern_addr; 662 663 while (size > 0) { 664 if (db_user_to_kernel_address(task, addr, &kern_addr, 1) < 0) 665 return; 666 dst = (char *)kern_addr; 667 n = intel_trunc_page(addr+INTEL_PGBYTES) - addr; 668 if (n > size) 669 n = size; 670 size -= n; 671 addr += n; 672 while (--n >= 0) 673 *dst++ = *data++; 674 } 675} 676 677boolean_t 678db_check_access( 679 vm_offset_t addr, 680 int size, 681 task_t task) 682{ 683 register n; 684 unsigned kern_addr; 685 686 if (task == kernel_task || task == TASK_NULL) { 687 if (kernel_task == TASK_NULL) 688 return(TRUE); 689 task = kernel_task; 690 } else if (task == TASK_NULL) { 691 if (current_thread() == THREAD_NULL) 692 return(FALSE); 693 task = current_thread()->task; 694 } 695 while (size > 0) { 696 if (db_user_to_kernel_address(task, addr, &kern_addr, 0) < 0) 697 return(FALSE); 698 n = intel_trunc_page(addr+INTEL_PGBYTES) - addr; 699 if (n > size) 700 n = size; 701 size -= n; 702 addr += n; 703 } 704 return(TRUE); 705} 706 707boolean_t 708db_phys_eq( 709 task_t task1, 710 vm_offset_t addr1, 711 task_t task2, 712 vm_offset_t addr2) 713{ 714 unsigned kern_addr1, kern_addr2; 715 716 if ((addr1 & (INTEL_PGBYTES-1)) != (addr2 & (INTEL_PGBYTES-1))) 717 return(FALSE); 718 if (task1 == TASK_NULL) { 719 if (current_thread() == THREAD_NULL) 720 return(FALSE); 721 task1 = current_thread()->task; 722 } 723 if (db_user_to_kernel_address(task1, addr1, &kern_addr1, 0) < 0 || 724 db_user_to_kernel_address(task2, addr2, &kern_addr2, 0) < 0) 725 return(FALSE); 726 return(kern_addr1 == kern_addr2); 727} 728 729#define DB_USER_STACK_ADDR (VM_MIN_KERNEL_ADDRESS) 730#define DB_NAME_SEARCH_LIMIT (DB_USER_STACK_ADDR-(INTEL_PGBYTES*3)) 731 732int 733db_search_null( 734 task_t task, 735 unsigned *svaddr, 736 unsigned evaddr, 737 unsigned *skaddr, 738 int flag) 739{ 740 register unsigned vaddr; 741 register unsigned *kaddr; 742 743 kaddr = (unsigned *)*skaddr; 744 for (vaddr = *svaddr; vaddr > evaddr; vaddr -= sizeof(unsigned)) { 745 if (vaddr % INTEL_PGBYTES == 0) { 746 vaddr -= sizeof(unsigned); 747 if (db_user_to_kernel_address(task, vaddr, skaddr, 0) < 0) 748 return(-1); 749 kaddr = (unsigned *)*skaddr; 750 } else { 751 vaddr -= sizeof(unsigned); 752 kaddr--; 753 } 754 if ((*kaddr == 0) ^ (flag == 0)) { 755 *svaddr = vaddr; 756 *skaddr = (unsigned)kaddr; 757 return(0); 758 } 759 } 760 return(-1); 761} 762 763void 764db_task_name( 765 task_t task) 766{ 767 register char *p; 768 register n; 769 unsigned vaddr, kaddr; 770 771 vaddr = DB_USER_STACK_ADDR; 772 kaddr = 0; 773 774 /* 775 * skip nulls at the end 776 */ 777 if (db_search_null(task, &vaddr, DB_NAME_SEARCH_LIMIT, &kaddr, 0) < 0) { 778 db_printf(DB_NULL_TASK_NAME); 779 return; 780 } 781 /* 782 * search start of args 783 */ 784 if (db_search_null(task, &vaddr, DB_NAME_SEARCH_LIMIT, &kaddr, 1) < 0) { 785 db_printf(DB_NULL_TASK_NAME); 786 return; 787 } 788 789 n = DB_TASK_NAME_LEN-1; 790 p = (char *)kaddr + sizeof(unsigned); 791 for (vaddr += sizeof(int); vaddr < DB_USER_STACK_ADDR && n > 0; 792 vaddr++, p++, n--) { 793 if (vaddr % INTEL_PGBYTES == 0) { 794 (void)db_user_to_kernel_address(task, vaddr, &kaddr, 0); 795 p = (char*)kaddr; 796 } 797 db_printf("%c", (*p < ' ' || *p > '~')? ' ': *p); 798 } 799 while (n-- >= 0) /* compare with >= 0 for one more space */ 800 db_printf(" "); 801} 802 803void 804db_machdep_init(void) 805{ 806 int c; 807 808 db_simple_lock_init(&kdb_lock, 0); 809 for (c = 0; c < real_ncpus; ++c) { 810 if (c == master_cpu) { 811 master_dbtss.esp0 = (int)(db_task_stack_store + 812 (INTSTACK_SIZE * (c + 1)) - sizeof (natural_t)); 813 master_dbtss.esp = master_dbtss.esp0; 814 master_dbtss.eip = (int)&db_task_start; 815 /* 816 * The TSS for the debugging task on each slave CPU 817 * is set up in cpu_desc_init(). 818 */ 819 } 820 } 821} 822 823/* 824 * Called when entering kdb: 825 * Takes kdb lock. If if we were called remotely (slave state) we just 826 * wait for kdb_cpu to be equal to cpu_number(). Otherwise enter kdb if 827 * not active on another cpu. 828 * If db_pass_thru[cpu_number()] > 0, then kdb can't stop now. 829 */ 830 831int 832kdb_enter(int pc) 833{ 834 int my_cpu; 835 int retval; 836 837 disable_preemption(); 838 839 my_cpu = cpu_number(); 840 841 if (current_cpu_datap()->cpu_db_pass_thru) { 842 retval = 0; 843 goto kdb_exit; 844 } 845 846 current_cpu_datap()->cpu_kdb_active++; 847 848 lock_kdb(); 849 850 db_printf("kdb_enter(): cpu_number %d, kdb_cpu %d\n", my_cpu, kdb_cpu); 851 852 if (db_breakpoints_inserted) 853 cpus_holding_bkpts++; 854 855 if (kdb_cpu == -1 && !current_cpu_datap()->cpu_kdb_is_slave) { 856 kdb_cpu = my_cpu; 857 db_printf("Signaling other processors..\n"); 858 remote_kdb(); /* stop other cpus */ 859 retval = 1; 860 } else if (kdb_cpu == my_cpu) 861 retval = 1; 862 else 863 retval = 0; 864 865kdb_exit: 866 enable_preemption(); 867 868 return (retval); 869} 870 871void 872kdb_leave(void) 873{ 874 int my_cpu; 875 boolean_t wait = FALSE; 876 877 disable_preemption(); 878 879 my_cpu = cpu_number(); 880 881 if (db_run_mode == STEP_CONTINUE) { 882 wait = TRUE; 883 kdb_cpu = -1; 884 } 885 if (db_breakpoints_inserted) 886 cpus_holding_bkpts--; 887 if (current_cpu_datap()->cpu_kdb_is_slave) 888 current_cpu_datap()->cpu_kdb_is_slave--; 889 if (kdb_debug) 890 db_printf("kdb_leave: cpu %d, kdb_cpu %d, run_mode %d pc %x (%x) holds %d\n", 891 my_cpu, kdb_cpu, db_run_mode, 892 ddb_regs.eip, *(int *)ddb_regs.eip, 893 cpus_holding_bkpts); 894 clear_kdb_intr(); 895 unlock_kdb(); 896 current_cpu_datap()->cpu_kdb_active--; 897 898 mp_kdb_exit(); 899 900 enable_preemption(); 901 902 if (wait) { 903 while(cpus_holding_bkpts); 904 } 905} 906 907void 908lock_kdb(void) 909{ 910 int my_cpu; 911 register i; 912 913 disable_preemption(); 914 915 my_cpu = cpu_number(); 916 917 for(;;) { 918 if (kdb_cpu != -1 && kdb_cpu != my_cpu) { 919 continue; 920 } 921 if (db_simple_lock_try(&kdb_lock)) { 922 if (kdb_cpu == -1 || kdb_cpu == my_cpu) 923 break; 924 db_simple_unlock(&kdb_lock); 925 } 926 } 927 928 enable_preemption(); 929} 930 931#if TIME_STAMP 932extern unsigned old_time_stamp; 933#endif /* TIME_STAMP */ 934 935void 936unlock_kdb(void) 937{ 938 db_simple_unlock(&kdb_lock); 939#if TIME_STAMP 940 old_time_stamp = 0; 941#endif /* TIME_STAMP */ 942} 943 944 945#ifdef __STDC__ 946#define KDB_SAVE(type, name) extern type name; type name##_save = name 947#define KDB_RESTORE(name) name = name##_save 948#else /* __STDC__ */ 949#define KDB_SAVE(type, name) extern type name; type name/**/_save = name 950#define KDB_RESTORE(name) name = name/**/_save 951#endif /* __STDC__ */ 952 953#define KDB_SAVE_CTXT() \ 954 KDB_SAVE(int, db_run_mode); \ 955 KDB_SAVE(boolean_t, db_sstep_print); \ 956 KDB_SAVE(int, db_loop_count); \ 957 KDB_SAVE(int, db_call_depth); \ 958 KDB_SAVE(int, db_inst_count); \ 959 KDB_SAVE(int, db_last_inst_count); \ 960 KDB_SAVE(int, db_load_count); \ 961 KDB_SAVE(int, db_store_count); \ 962 KDB_SAVE(boolean_t, db_cmd_loop_done); \ 963 KDB_SAVE(jmp_buf_t *, db_recover); \ 964 KDB_SAVE(db_addr_t, db_dot); \ 965 KDB_SAVE(db_addr_t, db_last_addr); \ 966 KDB_SAVE(db_addr_t, db_prev); \ 967 KDB_SAVE(db_addr_t, db_next); \ 968 KDB_SAVE(db_regs_t, ddb_regs); 969 970#define KDB_RESTORE_CTXT() \ 971 KDB_RESTORE(db_run_mode); \ 972 KDB_RESTORE(db_sstep_print); \ 973 KDB_RESTORE(db_loop_count); \ 974 KDB_RESTORE(db_call_depth); \ 975 KDB_RESTORE(db_inst_count); \ 976 KDB_RESTORE(db_last_inst_count); \ 977 KDB_RESTORE(db_load_count); \ 978 KDB_RESTORE(db_store_count); \ 979 KDB_RESTORE(db_cmd_loop_done); \ 980 KDB_RESTORE(db_recover); \ 981 KDB_RESTORE(db_dot); \ 982 KDB_RESTORE(db_last_addr); \ 983 KDB_RESTORE(db_prev); \ 984 KDB_RESTORE(db_next); \ 985 KDB_RESTORE(ddb_regs); 986 987/* 988 * switch to another cpu 989 */ 990 991void 992kdb_on( 993 int cpu) 994{ 995 KDB_SAVE_CTXT(); 996 if (cpu < 0 || cpu >= real_ncpus || !cpu_datap(cpu)->cpu_kdb_active) 997 return; 998 db_set_breakpoints(); 999 db_set_watchpoints(); 1000 kdb_cpu = cpu; 1001 unlock_kdb(); 1002 lock_kdb(); 1003 db_clear_breakpoints(); 1004 db_clear_watchpoints(); 1005 KDB_RESTORE_CTXT(); 1006 if (kdb_cpu == -1) {/* someone continued */ 1007 kdb_cpu = cpu_number(); 1008 db_continue_cmd(0, 0, 0, ""); 1009 } 1010} 1011 1012/* 1013 * system reboot 1014 */ 1015 1016extern void kdp_reboot(void); 1017 1018void db_reboot( 1019 db_expr_t addr, 1020 boolean_t have_addr, 1021 db_expr_t count, 1022 char *modif) 1023{ 1024 kdp_reboot(); 1025} 1026