]> git.saurik.com Git - apple/xnu.git/blob - osfmk/i386/db_interface.c
xnu-1228.5.18.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_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
99 int db_active = 0;
100 x86_saved_state32_t *i386_last_saved_statep;
101 x86_saved_state32_t i386_nested_saved_state;
102 unsigned i386_last_kdb_sp;
103
104 extern thread_t db_default_act;
105 extern pt_entry_t *DMAP1;
106 extern caddr_t DADDR1;
107
108 #if MACH_MP_DEBUG
109 extern 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 */
117 struct 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
127 extern char * trap_type[];
128 extern int TRAP_TYPES;
129
130 /* Forward */
131
132 extern void kdbprinttrap(
133 int type,
134 int code,
135 int *pc,
136 int sp);
137 extern void kdb_kentry(
138 struct int_regs *int_regs);
139 extern int db_user_to_kernel_address(
140 task_t task,
141 vm_offset_t addr,
142 unsigned *kaddr,
143 int flag);
144 extern void db_write_bytes_user_space(
145 vm_offset_t addr,
146 int size,
147 char *data,
148 task_t task);
149 extern int db_search_null(
150 task_t task,
151 unsigned *svaddr,
152 unsigned evaddr,
153 unsigned *skaddr,
154 int flag);
155 extern int kdb_enter(int);
156 extern void kdb_leave(void);
157 extern void lock_kdb(void);
158 extern void unlock_kdb(void);
159
160 /*
161 * kdb_trap - field a TRACE or BPT trap
162 */
163
164
165 extern 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
179 decl_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
185 int kdb_cpu = -1; /* current cpu running kdb */
186 int kdb_debug = 1;
187 volatile unsigned int cpus_holding_bkpts; /* counter for number of cpus
188 * holding breakpoints
189 */
190 extern boolean_t db_breakpoints_inserted;
191
192 void
193 db_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 */
231 boolean_t
232 db_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
243 int
244 kdb_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 *)&regs->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)&regs->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);
368 kdb_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
394 spl_t kdb_oldspl;
395
396 void
397 kdb_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 = &regs;
436
437 if (!kdb_enter(regs.eip))
438 goto kdb_exit;
439
440 bcopy((char *)&regs, (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
466 kdb_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
479 void
480 kdbprinttrap(
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
496 int
497 db_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
546 void
547 db_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
587 void
588 db_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
652 void
653 db_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
677 boolean_t
678 db_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
707 boolean_t
708 db_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
732 int
733 db_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
763 void
764 db_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
803 void
804 db_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
831 int
832 kdb_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
865 kdb_exit:
866 enable_preemption();
867
868 return (retval);
869 }
870
871 void
872 kdb_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
907 void
908 lock_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
932 extern unsigned old_time_stamp;
933 #endif /* TIME_STAMP */
934
935 void
936 unlock_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
991 void
992 kdb_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
1016 extern void kdp_reboot(void);
1017
1018 void 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 }