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