X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/8ad349bb6ed4a0be06e34c92be0d98b92e078db4..7e4a7d3939db04e70062ae6c7bf24b8c8b2f5a7c:/osfmk/i386/db_trace.c diff --git a/osfmk/i386/db_trace.c b/osfmk/i386/db_trace.c index 6847d5766..a14bb16b5 100644 --- a/osfmk/i386/db_trace.c +++ b/osfmk/i386/db_trace.c @@ -1,31 +1,29 @@ /* - * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2000-2006 Apple Computer, Inc. All rights reserved. * - * @APPLE_LICENSE_OSREFERENCE_HEADER_START@ + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. The rights granted to you under the - * License may not be used to create, or enable the creation or - * redistribution of, unlawful or unlicensed copies of an Apple operating - * system, or to circumvent, violate, or enable the circumvention or - * violation of, any terms of an Apple operating system software license - * agreement. - * - * Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and * limitations under the License. - * - * @APPLE_LICENSE_OSREFERENCE_HEADER_END@ + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ */ /* * @OSF_COPYRIGHT@ @@ -69,6 +67,13 @@ #include #include #include +#include + +#include +#include +#include +#include +#include #include #include @@ -78,29 +83,17 @@ #include extern jmp_buf_t *db_recover; -extern struct i386_saved_state *saved_state[]; +struct x86_kernel_state ddb_null_kregs; +extern kmod_info_t *kmod; -struct i386_kernel_state ddb_null_kregs; /* * Stack trace. */ -extern vm_offset_t vm_min_inks_addr; /* set by db_clone_symtabXXX */ -#define INKSERVER(va) (((vm_offset_t)(va)) >= vm_min_inks_addr) +#define INKERNELSTACK(va, th) 1 -extern vm_offset_t interrupt_stack[]; -#define ININTSTACK(va) \ - (((vm_offset_t)(va)) >= interrupt_stack[cpu_number()] &&\ - (((vm_offset_t)(va)) < interrupt_stack[cpu_number()] + \ - INTSTACK_SIZE)) - -#define INKERNELSTACK(va, th) \ - (th == THREAD_NULL || \ - (((vm_offset_t)(va)) >= th->thread->kernel_stack && \ - (((vm_offset_t)(va)) < th->thread->kernel_stack + \ - KERNEL_STACK_SIZE)) || \ - ININTSTACK(va)) +#define DB_NUMARGS_MAX 5 struct i386_frame { struct i386_frame *f_frame; @@ -121,20 +114,20 @@ boolean_t db_trace_symbols_found = FALSE; struct i386_kregs { char *name; - int offset; + unsigned int offset; } i386_kregs[] = { - { "ebx", (int)(&((struct i386_kernel_state *)0)->k_ebx) }, - { "esp", (int)(&((struct i386_kernel_state *)0)->k_esp) }, - { "ebp", (int)(&((struct i386_kernel_state *)0)->k_ebp) }, - { "edi", (int)(&((struct i386_kernel_state *)0)->k_edi) }, - { "esi", (int)(&((struct i386_kernel_state *)0)->k_esi) }, - { "eip", (int)(&((struct i386_kernel_state *)0)->k_eip) }, - { 0 }, + { "ebx", (unsigned int)(&((struct x86_kernel_state *)0)->k_ebx) }, + { "esp", (unsigned int)(&((struct x86_kernel_state *)0)->k_esp) }, + { "ebp", (unsigned int)(&((struct x86_kernel_state *)0)->k_ebp) }, + { "edi", (unsigned int)(&((struct x86_kernel_state *)0)->k_edi) }, + { "esi", (unsigned int)(&((struct x86_kernel_state *)0)->k_esi) }, + { "eip", (unsigned int)(&((struct x86_kernel_state *)0)->k_eip) }, + { 0 } }; /* Forward */ -extern int * db_lookup_i386_kreg( +extern unsigned int * db_lookup_i386_kreg( char *name, int *kregp); extern int db_i386_reg_value( @@ -159,26 +152,26 @@ extern int _setjmp( * Machine register set. */ struct db_variable db_regs[] = { - { "cs", (int *)&ddb_regs.cs, db_i386_reg_value, 0, 0, 0, 0, TRUE }, - { "ds", (int *)&ddb_regs.ds, db_i386_reg_value, 0, 0, 0, 0, TRUE }, - { "es", (int *)&ddb_regs.es, db_i386_reg_value, 0, 0, 0, 0, TRUE }, - { "fs", (int *)&ddb_regs.fs, db_i386_reg_value, 0, 0, 0, 0, TRUE }, - { "gs", (int *)&ddb_regs.gs, db_i386_reg_value, 0, 0, 0, 0, TRUE }, - { "ss", (int *)&ddb_regs.ss, db_i386_reg_value, 0, 0, 0, 0, TRUE }, - { "eax",(int *)&ddb_regs.eax, db_i386_reg_value, 0, 0, 0, 0, TRUE }, - { "ecx",(int *)&ddb_regs.ecx, db_i386_reg_value, 0, 0, 0, 0, TRUE }, - { "edx",(int *)&ddb_regs.edx, db_i386_reg_value, 0, 0, 0, 0, TRUE }, - { "ebx",(int *)&ddb_regs.ebx, db_i386_reg_value, 0, 0, 0, 0, TRUE }, - { "esp",(int *)&ddb_regs.uesp,db_i386_reg_value, 0, 0, 0, 0, TRUE }, - { "ebp",(int *)&ddb_regs.ebp, db_i386_reg_value, 0, 0, 0, 0, TRUE }, - { "esi",(int *)&ddb_regs.esi, db_i386_reg_value, 0, 0, 0, 0, TRUE }, - { "edi",(int *)&ddb_regs.edi, db_i386_reg_value, 0, 0, 0, 0, TRUE }, - { "eip",(int *)&ddb_regs.eip, db_i386_reg_value, 0, 0, 0, 0, TRUE }, - { "efl",(int *)&ddb_regs.efl, db_i386_reg_value, 0, 0, 0, 0, TRUE }, + { "cs", (unsigned int *)&ddb_regs.cs, db_i386_reg_value, 0, 0, 0, 0, TRUE, 0, 0, (int *)0, 0 }, + { "ds", (unsigned int *)&ddb_regs.ds, db_i386_reg_value, 0, 0, 0, 0, TRUE, 0, 0, (int *)0, 0 }, + { "es", (unsigned int *)&ddb_regs.es, db_i386_reg_value, 0, 0, 0, 0, TRUE, 0, 0, (int *)0, 0 }, + { "fs", (unsigned int *)&ddb_regs.fs, db_i386_reg_value, 0, 0, 0, 0, TRUE, 0, 0, (int *)0, 0 }, + { "gs", (unsigned int *)&ddb_regs.gs, db_i386_reg_value, 0, 0, 0, 0, TRUE, 0, 0, (int *)0, 0 }, + { "ss", (unsigned int *)&ddb_regs.ss, db_i386_reg_value, 0, 0, 0, 0, TRUE, 0, 0, (int *)0, 0 }, + { "eax",(unsigned int *)&ddb_regs.eax, db_i386_reg_value, 0, 0, 0, 0, TRUE, 0, 0, (int *)0, 0 }, + { "ecx",(unsigned int *)&ddb_regs.ecx, db_i386_reg_value, 0, 0, 0, 0, TRUE, 0, 0, (int *)0, 0 }, + { "edx",(unsigned int *)&ddb_regs.edx, db_i386_reg_value, 0, 0, 0, 0, TRUE, 0, 0, (int *)0, 0 }, + { "ebx",(unsigned int *)&ddb_regs.ebx, db_i386_reg_value, 0, 0, 0, 0, TRUE, 0, 0, (int *)0, 0 }, + { "esp",(unsigned int *)&ddb_regs.uesp,db_i386_reg_value, 0, 0, 0, 0, TRUE, 0, 0, (int *)0, 0 }, + { "ebp",(unsigned int *)&ddb_regs.ebp, db_i386_reg_value, 0, 0, 0, 0, TRUE, 0, 0, (int *)0, 0 }, + { "esi",(unsigned int *)&ddb_regs.esi, db_i386_reg_value, 0, 0, 0, 0, TRUE, 0, 0, (int *)0, 0 }, + { "edi",(unsigned int *)&ddb_regs.edi, db_i386_reg_value, 0, 0, 0, 0, TRUE, 0, 0, (int *)0, 0 }, + { "eip",(unsigned int *)&ddb_regs.eip, db_i386_reg_value, 0, 0, 0, 0, TRUE, 0, 0, (int *)0, 0 }, + { "efl",(unsigned int *)&ddb_regs.efl, db_i386_reg_value, 0, 0, 0, 0, TRUE, 0, 0, (int *)0, 0 } }; struct db_variable *db_eregs = db_regs + sizeof(db_regs)/sizeof(db_regs[0]); -int * +unsigned int * db_lookup_i386_kreg( char *name, int *kregp) @@ -187,7 +180,7 @@ db_lookup_i386_kreg( for (kp = i386_kregs; kp->name; kp++) { if (strcmp(name, kp->name) == 0) - return((int *)((int)kregp + kp->offset)); + return((unsigned int *)((int)kregp + kp->offset)); } return(0); } @@ -200,11 +193,9 @@ db_i386_reg_value( db_var_aux_param_t ap) { extern char etext; - int *dp = 0; + unsigned int *dp = 0; db_expr_t null_reg = 0; register thread_t thr_act = ap->thr_act; - extern unsigned int_stack_high; - int cpu; if (db_option(ap->modif, 'u')) { if (thr_act == THREAD_NULL) { @@ -214,38 +205,36 @@ db_i386_reg_value( if (thr_act == current_thread()) { if (IS_USER_TRAP(&ddb_regs, &etext)) dp = vp->valuep; - else if (ddb_regs.ebp < int_stack_high) - db_error("cannot get/set user registers in nested interrupt\n"); } } else { if (thr_act == THREAD_NULL || thr_act == current_thread()) { dp = vp->valuep; } else { - if (thr_act->thread && - !(thr_act->thread->state & TH_STACK_HANDOFF) && - thr_act->thread->kernel_stack) { + if (thr_act && + (thr_act->continuation != THREAD_CONTINUE_NULL) && + thr_act->kernel_stack) { int cpu; for (cpu = 0; cpu < real_ncpus; cpu++) { if (cpu_datap(cpu)->cpu_running == TRUE && - cpu_datap(cpu)->cpu_active_thread == thr_act->thread && saved_state[cpu]) { - dp = (int *) (((int)saved_state[cpu]) + - (((int) vp->valuep) - - (int) &ddb_regs)); + cpu_datap(cpu)->cpu_active_thread == thr_act && cpu_datap(cpu)->cpu_kdb_saved_state) { + dp = (unsigned int *) (((unsigned int)cpu_datap(cpu)->cpu_kdb_saved_state) + + (((unsigned int) vp->valuep) - + (unsigned int) &ddb_regs)); break; } } - if (dp == 0 && thr_act && thr_act->thread) + if (dp == 0 && thr_act) dp = db_lookup_i386_kreg(vp->name, - (int *)(STACK_IKS(thr_act->thread->kernel_stack))); + (unsigned int *)(STACK_IKS(thr_act->kernel_stack))); if (dp == 0) dp = &null_reg; - } else if (thr_act->thread && - (thr_act->thread->state&TH_STACK_HANDOFF)){ - /* only EIP is valid */ - if (vp->valuep == (int *) &ddb_regs.eip) { - dp = (int *)(&thr_act->thread->continuation); - } else { + } else if (thr_act && + (thr_act->continuation != THREAD_CONTINUE_NULL)) { + /* only EIP is valid */ + if (vp->valuep == (unsigned int *) &ddb_regs.eip) { + dp = (unsigned int *)(&thr_act->continuation); + } else { dp = &null_reg; } } @@ -257,10 +246,10 @@ db_i386_reg_value( if (!db_option(ap->modif, 'u')) { for (cpu = 0; cpu < real_ncpus; cpu++) { if (cpu_datap(cpu)->cpu_running == TRUE && - cpu_datap(cpu)->cpu_active_thread == thr_act->thread && saved_state[cpu]) { - dp = (int *) (((int)saved_state[cpu]) + - (((int) vp->valuep) - - (int) &ddb_regs)); + cpu_datap(cpu)->cpu_active_thread == thr_act && cpu_datap(cpu)->cpu_kdb_saved_state) { + dp = (unsigned int *) (((unsigned int)cpu_datap(cpu)->cpu_kdb_saved_state) + + (((unsigned int) vp->valuep) - + (unsigned int) &ddb_regs)); break; } } @@ -268,8 +257,8 @@ db_i386_reg_value( if (dp == 0) { if (!thr_act || thr_act->machine.pcb == 0) db_error("no pcb\n"); - dp = (int *)((int)(&thr_act->machine.pcb->iss) + - ((int)vp->valuep - (int)&ddb_regs)); + dp = (unsigned int *)((unsigned int)(thr_act->machine.pcb->iss) + + ((unsigned int)vp->valuep - (unsigned int)&ddb_regs)); } } if (flag == DB_VAR_SET) @@ -356,6 +345,9 @@ struct interrupt_frame { int if_efl; /* saved efl(iret_i) */ }; +extern const char *trap_type[]; +extern int TRAP_TYPES; + /* * Figure out the next frame up in the call stack. * For trap(), we print the address of the faulting instruction and @@ -374,64 +366,65 @@ db_nextframe( int frame_type, /* in */ thread_t thr_act) /* in */ { - extern char * trap_type[]; - extern int TRAP_TYPES; - - struct i386_saved_state *saved_regs; + x86_saved_state32_t *iss32; struct interrupt_frame *ifp; - struct i386_interrupt_state *isp; task_t task = (thr_act != THREAD_NULL)? thr_act->task: TASK_NULL; switch(frame_type) { case TRAP: - /* - * We know that trap() has 1 argument and we know that - * it is an (strcut i386_saved_state *). - */ - saved_regs = (struct i386_saved_state *) + /* + * We know that trap() has 1 argument and we know that + * it is an (strcut x86_saved_state32_t *). + */ + iss32 = (x86_saved_state32_t *) db_get_task_value((int)&((*fp)->f_arg0),4,FALSE,task); - if (saved_regs->trapno >= 0 && saved_regs->trapno < TRAP_TYPES) { - db_printf(">>>>> %s trap at ", - trap_type[saved_regs->trapno]); - } else { - db_printf(">>>>> trap (number %d) at ", - saved_regs->trapno & 0xffff); - } - db_task_printsym(saved_regs->eip, DB_STGY_PROC, task); - db_printf(" <<<<<\n"); - *fp = (struct i386_frame *)saved_regs->ebp; - *ip = (db_addr_t)saved_regs->eip; - break; + + if (iss32->trapno >= 0 && iss32->trapno < TRAP_TYPES) { + db_printf(">>>>> %s trap at ", + trap_type[iss32->trapno]); + } else { + db_printf(">>>>> trap (number %d) at ", + iss32->trapno & 0xffff); + } + db_task_printsym(iss32->eip, DB_STGY_PROC, task); + db_printf(" <<<<<\n"); + *fp = (struct i386_frame *)iss32->ebp; + *ip = (db_addr_t)iss32->eip; + break; + case INTERRUPT: - if (*lfp == 0) { - db_printf(">>>>> interrupt <<<<<\n"); - goto miss_frame; - } - db_printf(">>>>> interrupt at "); - ifp = (struct interrupt_frame *)(*lfp); - *fp = ifp->if_frame; - if (ifp->if_iretaddr == db_return_to_iret_symbol_value) - *ip = ((struct i386_interrupt_state *) ifp->if_edx)->eip; - else - *ip = (db_addr_t) ifp->if_eip; - db_task_printsym(*ip, DB_STGY_PROC, task); - db_printf(" <<<<<\n"); - break; + if (*lfp == 0) { + db_printf(">>>>> interrupt <<<<<\n"); + goto miss_frame; + } + db_printf(">>>>> interrupt at "); + ifp = (struct interrupt_frame *)(*lfp); + *fp = ifp->if_frame; + if (ifp->if_iretaddr == db_return_to_iret_symbol_value) { + *ip = ((x86_saved_state32_t *)ifp->if_edx)->eip; + } else + *ip = (db_addr_t)ifp->if_eip; + db_task_printsym(*ip, DB_STGY_PROC, task); + db_printf(" <<<<<\n"); + break; + case SYSCALL: - if (thr_act != THREAD_NULL && thr_act->machine.pcb) { - *ip = (db_addr_t) thr_act->machine.pcb->iss.eip; - *fp = (struct i386_frame *) thr_act->machine.pcb->iss.ebp; + if (thr_act != THREAD_NULL && thr_act->machine.pcb) { + iss32 = (x86_saved_state32_t *)thr_act->machine.pcb->iss; + + *ip = (db_addr_t)(iss32->eip); + *fp = (struct i386_frame *)(iss32->ebp); + } + break; + + default: /* falling down for unknown case */ +miss_frame: + *ip = (db_addr_t) + db_get_task_value((int)&(*fp)->f_retaddr, 4, FALSE, task); + *lfp = *fp; + *fp = (struct i386_frame *) + db_get_task_value((int)&(*fp)->f_frame, 4, FALSE, task); break; - } - /* falling down for unknown case */ - default: - miss_frame: - *ip = (db_addr_t) - db_get_task_value((int)&(*fp)->f_retaddr, 4, FALSE, task); - *lfp = *fp; - *fp = (struct i386_frame *) - db_get_task_value((int)&(*fp)->f_frame, 4, FALSE, task); - break; } } @@ -443,6 +436,7 @@ db_stack_trace_cmd( char *modif) { struct i386_frame *frame, *lastframe; + x86_saved_state32_t *iss32; int *argp; db_addr_t callpc, lastcallpc; int frame_type; @@ -483,17 +477,17 @@ db_stack_trace_cmd( if (!have_addr && !trace_thread) { have_addr = TRUE; trace_thread = TRUE; - act_list = &(current_task()->thr_acts); + act_list = &(current_task()->threads); addr = (db_expr_t) queue_first(act_list); } else if (trace_thread) { if (have_addr) { if (!db_check_act_address_valid((thread_t)addr)) { if (db_lookup_task((task_t)addr) == -1) return; - act_list = &(((task_t)addr)->thr_acts); + act_list = &(((task_t)addr)->threads); addr = (db_expr_t) queue_first(act_list); } else { - act_list = &(((thread_t)addr)->task->thr_acts); + act_list = &(((thread_t)addr)->task->threads); thcount = db_lookup_task_act(((thread_t)addr)->task, (thread_t)addr); } @@ -506,7 +500,7 @@ db_stack_trace_cmd( return; } have_addr = TRUE; - act_list = &th->task->thr_acts; + act_list = &th->task->threads; addr = (db_expr_t) queue_first(act_list); } } @@ -515,7 +509,7 @@ db_stack_trace_cmd( if (count == -1) count = 65535; - next_thread: +next_thread: top_act = THREAD_NULL; user_frame = 0; @@ -526,11 +520,13 @@ db_stack_trace_cmd( callpc = (db_addr_t)ddb_regs.eip; th = current_thread(); task = (th != THREAD_NULL)? th->task: TASK_NULL; + db_printf("thread 0x%x, current_thread() is 0x%x, ebp is 0x%x, eip is 0x%x\n", th, current_thread(), ddb_regs.ebp, ddb_regs.eip); } else if (trace_thread) { if (have_addr) { th = (thread_t) addr; - if (!db_check_act_address_valid(th)) - return; + if (!db_check_act_address_valid(th)) { + return; + } } else { th = db_default_act; if (th == THREAD_NULL) @@ -542,11 +538,11 @@ db_stack_trace_cmd( } if (trace_all_threads) db_printf("---------- Thread 0x%x (#%d of %d) ----------\n", - addr, thcount, th->task->thr_act_count); + addr, thcount, th->task->thread_count); next_activation: user_frame = 0; - +// kprintf("th is %x, current_thread() is %x, ddb_regs.ebp is %x ddb_regs.eip is %x\n", th, current_thread(), ddb_regs.ebp, ddb_regs.eip); task = th->task; if (th == current_thread()) { frame = (struct i386_frame *)ddb_regs.ebp; @@ -556,36 +552,31 @@ db_stack_trace_cmd( db_printf("thread has no pcb\n"); return; } - if (!th->thread) { - register struct i386_saved_state *iss = - &th->machine.pcb->iss; - + if (!th) { db_printf("thread has no shuttle\n"); -#if 0 - frame = (struct i386_frame *) (iss->ebp); - callpc = (db_addr_t) (iss->eip); -#else + goto thread_done; -#endif } - else if ((th->thread->state & TH_STACK_HANDOFF) || - th->thread->kernel_stack == 0) { - register struct i386_saved_state *iss = - &th->machine.pcb->iss; + else if ( (th->continuation != THREAD_CONTINUE_NULL) || + th->kernel_stack == 0) { db_printf("Continuation "); - db_task_printsym((db_expr_t)th->thread->continuation, + db_task_printsym((db_expr_t)th->continuation, DB_STGY_PROC, task); db_printf("\n"); - frame = (struct i386_frame *) (iss->ebp); - callpc = (db_addr_t) (iss->eip); + + iss32 = (x86_saved_state32_t *)th->machine.pcb->iss; + + frame = (struct i386_frame *) (iss32->ebp); + callpc = (db_addr_t) (iss32->eip); + } else { int cpu; for (cpu = 0; cpu < real_ncpus; cpu++) { if (cpu_datap(cpu)->cpu_running == TRUE && - cpu_datap(cpu)->cpu_active_thread == th->thread && - saved_state[cpu]) { + cpu_datap(cpu)->cpu_active_thread == th && + cpu_datap(cpu)->cpu_kdb_saved_state) { break; } } @@ -595,16 +586,16 @@ db_stack_trace_cmd( * which is not the top_most one in the RPC chain: * use the activation's pcb. */ - register struct i386_saved_state *iss = - &th->machine.pcb->iss; - frame = (struct i386_frame *) (iss->ebp); - callpc = (db_addr_t) (iss->eip); + iss32 = (x86_saved_state32_t *)th->machine.pcb->iss; + + frame = (struct i386_frame *) (iss32->ebp); + callpc = (db_addr_t) (iss32->eip); } else { - if (cpu == NCPUS) { - register struct i386_kernel_state *iks; + if (cpu == real_ncpus) { + register struct x86_kernel_state *iks; int r; - iks = STACK_IKS(th->thread->kernel_stack); + iks = STACK_IKS(th->kernel_stack); prev = db_recover; if ((r = _setjmp(db_recover = &db_jmp_buf)) == 0) { frame = (struct i386_frame *) (iks->k_ebp); @@ -626,13 +617,15 @@ db_stack_trace_cmd( } else { db_printf(">>>>> active on cpu %d <<<<<\n", cpu); - frame = (struct i386_frame *) - saved_state[cpu]->ebp; - callpc = (db_addr_t) saved_state[cpu]->eip; + + iss32 = (x86_saved_state32_t *)cpu_datap(cpu)->cpu_kdb_saved_state; + + frame = (struct i386_frame *) (iss32->ebp); + callpc = (db_addr_t) (iss32->eip); + } } } } - } } else { frame = (struct i386_frame *)addr; th = (db_default_act)? db_default_act: current_thread(); @@ -648,19 +641,18 @@ db_stack_trace_cmd( if (kernel_only) goto thread_done; user_frame++; - } else if (INKSERVER(callpc) && INKSERVER(frame)) { - db_printf(">>>>> INKserver space <<<<<\n"); } lastframe = 0; lastcallpc = (db_addr_t) 0; while (frame_count-- && frame != 0) { - int narg; + int narg = DB_NUMARGS_MAX; char * name; db_expr_t offset; db_addr_t call_func = 0; int r; - + db_addr_t off; + db_symbol_values(NULL, db_search_task_symbol_and_line( callpc, @@ -671,15 +663,22 @@ db_stack_trace_cmd( (user_frame) ? task : 0, &narg), &name, (db_expr_t *)&call_func); + if ( name == NULL) { + db_find_task_sym_and_offset(callpc, + &name, &off, (user_frame) ? task : 0); + offset = (db_expr_t) off; + } + if (user_frame == 0) { - if (call_func == db_user_trap_symbol_value || + if (call_func && call_func == db_user_trap_symbol_value || call_func == db_kernel_trap_symbol_value) { frame_type = TRAP; narg = 1; - } else if (call_func == db_interrupt_symbol_value) { + } else if (call_func && + call_func == db_interrupt_symbol_value) { frame_type = INTERRUPT; goto next_frame; - } else if (call_func == db_syscall_symbol_value) { + } else if (call_func && call_func == db_syscall_symbol_value) { frame_type = SYSCALL; goto next_frame; } else { @@ -761,16 +760,16 @@ db_stack_trace_cmd( } db_printf("\n"); - next_frame: +next_frame: lastcallpc = callpc; db_nextframe(&lastframe, &frame, &callpc, frame_type, (user_frame) ? th : THREAD_NULL); if (frame == 0) { - if (th->lower != THREAD_NULL) { + if (th->task_threads.prev != THREAD_NULL) { if (top_act == THREAD_NULL) top_act = th; - th = th->lower; + th = th->task_threads.prev; db_printf(">>>>> next activation 0x%x ($task%d.%d) <<<<<\n", th, db_lookup_task(th->task), @@ -787,25 +786,21 @@ db_stack_trace_cmd( db_printf(">>>>> user space <<<<<\n"); if (kernel_only) break; - } else if ((!INKSERVER(lastframe) || !INKSERVER(lastcallpc)) && - (INKSERVER(callpc) && INKSERVER(frame))) { - db_printf(">>>>> inkserver space <<<<<\n"); } if (frame <= lastframe) { if ((INKERNELSTACK(lastframe, th) && - !INKERNELSTACK(frame, th)) || - (INKSERVER(lastframe) ^ INKSERVER(frame))) + !INKERNELSTACK(frame, th))) continue; db_printf("Bad frame pointer: 0x%x\n", frame); break; } } - thread_done: +thread_done: if (trace_all_threads) { if (top_act != THREAD_NULL) th = top_act; - th = (thread_t) queue_next(&th->thr_acts); + th = (thread_t) queue_next(&th->task_threads); if (! queue_end(act_list, (queue_entry_t) th)) { db_printf("\n"); addr = (db_expr_t) th; @@ -815,3 +810,71 @@ db_stack_trace_cmd( } } } + +extern mach_vm_size_t kdp_machine_vm_read(mach_vm_address_t, caddr_t, mach_vm_size_t); +extern boolean_t kdp_trans_off; +/* + * Print out 256 bytes of real storage + * + * dr [entaddr] + */ +void +db_display_real(db_expr_t addr, boolean_t have_addr, db_expr_t count, + char *modif) +{ + int i; + unsigned int xbuf[8]; + unsigned read_result = 0; +/* Print 256 bytes */ + for(i=0; i<8; i++) { + +/* + * Do a physical read using kdp_machine_vm_read(), rather than replicating the same + * facility + */ + kdp_trans_off = 1; + read_result = kdp_machine_vm_read(addr, &xbuf[0], 32); + kdp_trans_off = 0; + + if (read_result != 32) + db_printf("Unable to read address\n"); + else + db_printf("%016llX %08X %08X %08X %08X %08X %08X %08X %08X\n", addr, /* Print a line */ + xbuf[0], xbuf[1], xbuf[2], xbuf[3], + xbuf[4], xbuf[5], xbuf[6], xbuf[7]); + addr = addr + 0x00000020; /* Point to next address */ + } + db_next = addr; +} + +/* + * Displays all of the kmods in the system. + * + * dk + */ +void +db_display_kmod(__unused db_expr_t addr, __unused boolean_t have_addr, + __unused db_expr_t count, __unused char *modif) +{ + + kmod_info_t *kmd; + unsigned int strt, end; + + kmd = kmod; /* Start at the start */ + + db_printf("info addr start - end name ver\n"); + + while (kmd) { /* Dump 'em all */ + strt = (unsigned int) kmd->address + kmd->hdr_size; + end = (unsigned int) kmd->address + kmd->size; + db_printf("%08X %08X %08X - %08X: %s, %s\n", + kmd, kmd->address, strt, end, kmd->name, kmd->version); + kmd = kmd->next; + } +} + +void +db_display_iokit(__unused db_expr_t addr, __unused boolean_t have_addr, + __unused db_expr_t count, __unused char *modif) +{ +}