X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/43866e378188c25dd1e2208016ab3cbeb086ae6c..060df5ea7c632b1ac8cc8aac1fb59758165c2084:/osfmk/ppc/db_trace.c diff --git a/osfmk/ppc/db_trace.c b/osfmk/ppc/db_trace.c index 8029df721..601378162 100644 --- a/osfmk/ppc/db_trace.c +++ b/osfmk/ppc/db_trace.c @@ -1,16 +1,19 @@ /* - * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2000-2006 Apple Computer, Inc. All rights reserved. * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * @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. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. + * 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 @@ -20,7 +23,7 @@ * Please see the License for the specific language governing rights and * limitations under the License. * - * @APPLE_LICENSE_HEADER_END@ + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ */ /* * @OSF_COPYRIGHT@ @@ -29,15 +32,20 @@ #include #include +#include + #include + #include #include #include +#include +#include + #include #include #include -#include #include #include @@ -47,7 +55,6 @@ #include extern jmp_buf_t *db_recover; -extern struct savearea *saved_state[]; struct savearea ddb_null_kregs; @@ -55,36 +62,19 @@ extern vm_offset_t vm_min_inks_addr; /* set by db_clone_symtabXXX */ #define DB_NUMARGS_MAX 5 +#define INFIXEDSTACK(va) 0 \ -extern char FixedStackStart[], FixedStackEnd[]; -#define INFIXEDSTACK(va) \ - ((((vm_offset_t)(va)) >= (vm_offset_t)&FixedStackStart) && \ - (((vm_offset_t)(va)) < ((vm_offset_t)&FixedStackEnd))) - -#if 0 - -#define INKERNELSTACK(va, th) \ - (th == THR_ACT_NULL || \ - (((vm_offset_t)(va)) >= th->thread->kernel_stack && \ - (((vm_offset_t)(va)) < th->thread->kernel_stack + \ - KERNEL_STACK_SIZE)) || \ - INFIXEDSTACK(va)) -#else #define INKERNELSTACK(va, th) 1 -#endif - -#ifdef __MACHO__ struct db_ppc_frame { struct db_ppc_frame *f_frame; int pad1; - db_addr_t f_retaddr; + uint32_t f_retaddr; int pad3; int pad4; int pad5; - db_addr_t f_arg[DB_NUMARGS_MAX]; + uint32_t f_arg[DB_NUMARGS_MAX]; }; -#endif #define TRAP 1 #define INTERRUPT 2 @@ -97,75 +87,424 @@ db_addr_t db_return_to_iret_symbol_value = 0; db_addr_t db_syscall_symbol_value = 0; boolean_t db_trace_symbols_found = FALSE; -extern int db_ppc_reg_value( +static int db_ppc_reg_value( struct db_variable * vp, db_expr_t * val, int flag, db_var_aux_param_t ap); -extern void db_find_trace_symbols(void); -extern int db_numargs( +static void db_find_trace_symbols(void); +static int db_numargs( struct db_ppc_frame *fp, task_t task); -extern boolean_t db_find_arg( +static boolean_t db_find_arg( struct db_ppc_frame *frame, db_addr_t calleepc, task_t task, int narg, db_addr_t *arg); -extern void db_nextframe( +static void db_nextframe( struct db_ppc_frame **lfp, struct db_ppc_frame **fp, db_addr_t *ip, int frame_type, thread_act_t thr_act, db_addr_t linkpc); -extern int _setjmp( - jmp_buf_t * jb); /* * Machine register set. */ struct db_variable db_regs[] = { /* XXX "pc" is an alias to "srr0"... */ - { "pc", (int *)&ddb_regs.save_srr0, db_ppc_reg_value, 0, 0, 0, 0, TRUE }, - { "srr0", (int *)&ddb_regs.save_srr0, db_ppc_reg_value, 0, 0, 0, 0, TRUE }, - { "srr1", (int *)&ddb_regs.save_srr1, db_ppc_reg_value, 0, 0, 0, 0, TRUE }, - { "r0", (int *)&ddb_regs.save_r0, db_ppc_reg_value, 0, 0, 0, 0, TRUE }, - { "r1", (int *)&ddb_regs.save_r1, db_ppc_reg_value, 0, 0, 0, 0, TRUE }, - { "r2", (int *)&ddb_regs.save_r2, db_ppc_reg_value, 0, 0, 0, 0, TRUE }, - { "r3", (int *)&ddb_regs.save_r3, db_ppc_reg_value, 0, 0, 0, 0, TRUE }, - { "r4", (int *)&ddb_regs.save_r4, db_ppc_reg_value, 0, 0, 0, 0, TRUE }, - { "r5", (int *)&ddb_regs.save_r5, db_ppc_reg_value, 0, 0, 0, 0, TRUE }, - { "r6", (int *)&ddb_regs.save_r6, db_ppc_reg_value, 0, 0, 0, 0, TRUE }, - { "r7", (int *)&ddb_regs.save_r7, db_ppc_reg_value, 0, 0, 0, 0, TRUE }, - { "r8", (int *)&ddb_regs.save_r8, db_ppc_reg_value, 0, 0, 0, 0, TRUE }, - { "r9", (int *)&ddb_regs.save_r9, db_ppc_reg_value, 0, 0, 0, 0, TRUE }, - { "r10", (int *)&ddb_regs.save_r10, db_ppc_reg_value, 0, 0, 0, 0, TRUE }, - { "r11", (int *)&ddb_regs.save_r11, db_ppc_reg_value, 0, 0, 0, 0, TRUE }, - { "r12", (int *)&ddb_regs.save_r12, db_ppc_reg_value, 0, 0, 0, 0, TRUE }, - { "r13", (int *)&ddb_regs.save_r13, db_ppc_reg_value, 0, 0, 0, 0, TRUE }, - { "r14", (int *)&ddb_regs.save_r14, db_ppc_reg_value, 0, 0, 0, 0, TRUE }, - { "r15", (int *)&ddb_regs.save_r15, db_ppc_reg_value, 0, 0, 0, 0, TRUE }, - { "r16", (int *)&ddb_regs.save_r16, db_ppc_reg_value, 0, 0, 0, 0, TRUE }, - { "r17", (int *)&ddb_regs.save_r17, db_ppc_reg_value, 0, 0, 0, 0, TRUE }, - { "r18", (int *)&ddb_regs.save_r18, db_ppc_reg_value, 0, 0, 0, 0, TRUE }, - { "r19", (int *)&ddb_regs.save_r19, db_ppc_reg_value, 0, 0, 0, 0, TRUE }, - { "r20", (int *)&ddb_regs.save_r20, db_ppc_reg_value, 0, 0, 0, 0, TRUE }, - { "r21", (int *)&ddb_regs.save_r21, db_ppc_reg_value, 0, 0, 0, 0, TRUE }, - { "r22", (int *)&ddb_regs.save_r22, db_ppc_reg_value, 0, 0, 0, 0, TRUE }, - { "r23", (int *)&ddb_regs.save_r23, db_ppc_reg_value, 0, 0, 0, 0, TRUE }, - { "r24", (int *)&ddb_regs.save_r24, db_ppc_reg_value, 0, 0, 0, 0, TRUE }, - { "r25", (int *)&ddb_regs.save_r25, db_ppc_reg_value, 0, 0, 0, 0, TRUE }, - { "r26", (int *)&ddb_regs.save_r26, db_ppc_reg_value, 0, 0, 0, 0, TRUE }, - { "r27", (int *)&ddb_regs.save_r27, db_ppc_reg_value, 0, 0, 0, 0, TRUE }, - { "r28", (int *)&ddb_regs.save_r28, db_ppc_reg_value, 0, 0, 0, 0, TRUE }, - { "r29", (int *)&ddb_regs.save_r29, db_ppc_reg_value, 0, 0, 0, 0, TRUE }, - { "r30", (int *)&ddb_regs.save_r30, db_ppc_reg_value, 0, 0, 0, 0, TRUE }, - { "r31", (int *)&ddb_regs.save_r31, db_ppc_reg_value, 0, 0, 0, 0, TRUE }, - { "cr", (int *)&ddb_regs.save_cr, db_ppc_reg_value, 0, 0, 0, 0, TRUE }, - { "xer", (int *)&ddb_regs.save_xer, db_ppc_reg_value, 0, 0, 0, 0, TRUE }, - { "lr", (int *)&ddb_regs.save_lr, db_ppc_reg_value, 0, 0, 0, 0, TRUE }, - { "ctr", (int *)&ddb_regs.save_ctr, db_ppc_reg_value, 0, 0, 0, 0, TRUE }, + { + .name = "pc", + .valuep = &ddb_regs.save_srr0, + .fcn = db_ppc_reg_value, + .min_level = 0, + .max_level = 0, + .low = 0, + .high = 0, + .hidden_level = TRUE, + }, + { + .name = "srr0", + .valuep = &ddb_regs.save_srr0, + .fcn = db_ppc_reg_value, + .min_level = 0, + .max_level = 0, + .low = 0, + .high = 0, + .hidden_level = TRUE, + }, + { + .name = "srr1", + .valuep = &ddb_regs.save_srr1, + .fcn = db_ppc_reg_value, + .min_level = 0, + .max_level = 0, + .low = 0, + .high = 0, + .hidden_level = TRUE, + }, + { + .name = "r0", + .valuep = &ddb_regs.save_r0, + .fcn = db_ppc_reg_value, + .min_level = 0, + .max_level = 0, + .low = 0, + .high = 0, + .hidden_level = TRUE, + }, + { + .name = "r1", + .valuep = &ddb_regs.save_r1, + .fcn = db_ppc_reg_value, + .min_level = 0, + .max_level = 0, + .low = 0, + .high = 0, + .hidden_level = TRUE, + }, + { + .name = "r2", + .valuep = &ddb_regs.save_r2, + .fcn = db_ppc_reg_value, + .min_level = 0, + .max_level = 0, + .low = 0, + .high = 0, + .hidden_level = TRUE, + }, + { + .name = "r3", + .valuep = &ddb_regs.save_r3, + .fcn = db_ppc_reg_value, + .min_level = 0, + .max_level = 0, + .low = 0, + .high = 0, + .hidden_level = TRUE, + }, + { + .name = "r4", + .valuep = &ddb_regs.save_r4, + .fcn = db_ppc_reg_value, + .min_level = 0, + .max_level = 0, + .low = 0, + .high = 0, + .hidden_level = TRUE, + }, + { + .name = "r5", + .valuep = &ddb_regs.save_r5, + .fcn = db_ppc_reg_value, + .min_level = 0, + .max_level = 0, + .low = 0, + .high = 0, + .hidden_level = TRUE, + }, + { + .name = "r6", + .valuep = &ddb_regs.save_r6, + .fcn = db_ppc_reg_value, + .min_level = 0, + .max_level = 0, + .low = 0, + .high = 0, + .hidden_level = TRUE, + }, + { + .name = "r7", + .valuep = &ddb_regs.save_r7, + .fcn = db_ppc_reg_value, + .min_level = 0, + .max_level = 0, + .low = 0, + .high = 0, + .hidden_level = TRUE, + }, + { + .name = "r8", + .valuep = &ddb_regs.save_r8, + .fcn = db_ppc_reg_value, + .min_level = 0, + .max_level = 0, + .low = 0, + .high = 0, + .hidden_level = TRUE, + }, + { + .name = "r9", + .valuep = &ddb_regs.save_r9, + .fcn = db_ppc_reg_value, + .min_level = 0, + .max_level = 0, + .low = 0, + .high = 0, + .hidden_level = TRUE, + }, + { + .name = "r10", + .valuep = &ddb_regs.save_r10, + .fcn = db_ppc_reg_value, + .min_level = 0, + .max_level = 0, + .low = 0, + .high = 0, + .hidden_level = TRUE, + }, + { + .name = "r11", + .valuep = &ddb_regs.save_r11, + .fcn = db_ppc_reg_value, + .min_level = 0, + .max_level = 0, + .low = 0, + .high = 0, + .hidden_level = TRUE, + }, + { + .name = "r12", + .valuep = &ddb_regs.save_r12, + .fcn = db_ppc_reg_value, + .min_level = 0, + .max_level = 0, + .low = 0, + .high = 0, + .hidden_level = TRUE, + }, + { + .name = "r13", + .valuep = &ddb_regs.save_r13, + .fcn = db_ppc_reg_value, + .min_level = 0, + .max_level = 0, + .low = 0, + .high = 0, + .hidden_level = TRUE, + }, + { + .name = "r14", + .valuep = &ddb_regs.save_r14, + .fcn = db_ppc_reg_value, + .min_level = 0, + .max_level = 0, + .low = 0, + .high = 0, + .hidden_level = TRUE, + }, + { + .name = "r15", + .valuep = &ddb_regs.save_r15, + .fcn = db_ppc_reg_value, + .min_level = 0, + .max_level = 0, + .low = 0, + .high = 0, + .hidden_level = TRUE, + }, + { + .name = "r16", + .valuep = &ddb_regs.save_r16, + .fcn = db_ppc_reg_value, + .min_level = 0, + .max_level = 0, + .low = 0, + .high = 0, + .hidden_level = TRUE, + }, + { + .name = "r17", + .valuep = &ddb_regs.save_r17, + .fcn = db_ppc_reg_value, + .min_level = 0, + .max_level = 0, + .low = 0, + .high = 0, + .hidden_level = TRUE, + }, + { + .name = "r18", + .valuep = &ddb_regs.save_r18, + .fcn = db_ppc_reg_value, + .min_level = 0, + .max_level = 0, + .low = 0, + .high = 0, + .hidden_level = TRUE, + }, + { + .name = "r19", + .valuep = &ddb_regs.save_r19, + .fcn = db_ppc_reg_value, + .min_level = 0, + .max_level = 0, + .low = 0, + .high = 0, + .hidden_level = TRUE, + }, + { + .name = "r20", + .valuep = &ddb_regs.save_r20, + .fcn = db_ppc_reg_value, + .min_level = 0, + .max_level = 0, + .low = 0, + .high = 0, + .hidden_level = TRUE, + }, + { + .name = "r21", + .valuep = &ddb_regs.save_r21, + .fcn = db_ppc_reg_value, + .min_level = 0, + .max_level = 0, + .low = 0, + .high = 0, + .hidden_level = TRUE, + }, + { + .name = "r22", + .valuep = &ddb_regs.save_r22, + .fcn = db_ppc_reg_value, + .min_level = 0, + .max_level = 0, + .low = 0, + .high = 0, + .hidden_level = TRUE, + }, + { + .name = "r23", + .valuep = &ddb_regs.save_r23, + .fcn = db_ppc_reg_value, + .min_level = 0, + .max_level = 0, + .low = 0, + .high = 0, + .hidden_level = TRUE, + }, + { + .name = "r24", + .valuep = &ddb_regs.save_r24, + .fcn = db_ppc_reg_value, + .min_level = 0, + .max_level = 0, + .low = 0, + .high = 0, + .hidden_level = TRUE, + }, + { + .name = "r25", + .valuep = &ddb_regs.save_r25, + .fcn = db_ppc_reg_value, + .min_level = 0, + .max_level = 0, + .low = 0, + .high = 0, + .hidden_level = TRUE, + }, + { + .name = "r26", + .valuep = &ddb_regs.save_r26, + .fcn = db_ppc_reg_value, + .min_level = 0, + .max_level = 0, + .low = 0, + .high = 0, + .hidden_level = TRUE, + }, + { + .name = "r27", + .valuep = &ddb_regs.save_r27, + .fcn = db_ppc_reg_value, + .min_level = 0, + .max_level = 0, + .low = 0, + .high = 0, + .hidden_level = TRUE, + }, + { + .name = "r28", + .valuep = &ddb_regs.save_r28, + .fcn = db_ppc_reg_value, + .min_level = 0, + .max_level = 0, + .low = 0, + .high = 0, + .hidden_level = TRUE, + }, + { + .name = "r29", + .valuep = &ddb_regs.save_r29, + .fcn = db_ppc_reg_value, + .min_level = 0, + .max_level = 0, + .low = 0, + .high = 0, + .hidden_level = TRUE, + }, + { + .name = "r30", + .valuep = &ddb_regs.save_r30, + .fcn = db_ppc_reg_value, + .min_level = 0, + .max_level = 0, + .low = 0, + .high = 0, + .hidden_level = TRUE, + }, + { + .name = "r31", + .valuep = &ddb_regs.save_r31, + .fcn = db_ppc_reg_value, + .min_level = 0, + .max_level = 0, + .low = 0, + .high = 0, + .hidden_level = TRUE, + }, + { + .name = "cr", + .valuep = (db_expr_t *)&ddb_regs.save_cr, + .fcn = db_ppc_reg_value, + .min_level = 0, + .max_level = 0, + .low = 0, + .high = 0, + .hidden_level = TRUE, + }, + { + .name = "xer", + .valuep = &ddb_regs.save_xer, + .fcn = db_ppc_reg_value, + .min_level = 0, + .max_level = 0, + .low = 0, + .high = 0, + .hidden_level = TRUE, + }, + { + .name = "lr", + .valuep = &ddb_regs.save_lr, + .fcn = db_ppc_reg_value, + .min_level = 0, + .max_level = 0, + .low = 0, + .high = 0, + .hidden_level = TRUE, + }, + { + .name = "ctr", + .valuep = &ddb_regs.save_ctr, + .fcn = db_ppc_reg_value, + .min_level = 0, + .max_level = 0, + .low = 0, + .high = 0, + .hidden_level = TRUE, + }, }; struct db_variable *db_eregs = db_regs + sizeof(db_regs)/sizeof(db_regs[0]); @@ -176,82 +515,90 @@ db_ppc_reg_value( int flag, db_var_aux_param_t ap) { - int *dp = 0; - db_expr_t null_reg = 0; - register thread_act_t thr_act = ap->thr_act; - int cpu; + db_expr_t *dp = 0; + db_expr_t null_reg = 0; + uint32_t *dp32; + thread_act_t thr_act = ap->thr_act; + unsigned int cpu; if (db_option(ap->modif, 'u')) { - if (thr_act == THR_ACT_NULL) { - if ((thr_act = current_act()) == THR_ACT_NULL) - db_error("no user registers\n"); - } - if (thr_act == current_act()) { - if (IS_USER_TRAP((&ddb_regs))) - dp = vp->valuep; - else if (INFIXEDSTACK(ddb_regs.save_r1)) - db_error("cannot get/set user registers in nested interrupt\n"); - } - } else { - if (thr_act == THR_ACT_NULL || thr_act == current_act()) { - dp = vp->valuep; - } else { - if (thr_act->thread && - !(thr_act->thread->state & TH_STACK_HANDOFF) && - thr_act->thread->kernel_stack) { - int cpu; - - for (cpu = 0; cpu < NCPUS; cpu++) { - if (cpu_to_processor(cpu)->state == PROCESSOR_RUNNING && - cpu_to_processor(cpu)->cpu_data->active_thread == thr_act->thread && saved_state[cpu]) { - dp = (int *) (((int)saved_state[cpu]) + - (((int) vp->valuep) - - (int) &ddb_regs)); - break; - } + if (thr_act == THR_ACT_NULL) { + if ((thr_act = current_thread()) == THR_ACT_NULL) + db_error("no user registers\n"); } + if (thr_act == current_thread()) { + if (IS_USER_TRAP((&ddb_regs))) dp = vp->valuep; + else if (INFIXEDSTACK(ddb_regs.save_r1)) + db_error("cannot get/set user registers in nested interrupt\n"); + } + } + else { + if (thr_act == THR_ACT_NULL || thr_act == current_thread()) { + dp = vp->valuep; + } + else { + if (thr_act->kernel_stack) { + for (cpu = 0; cpu < real_ncpus; cpu++) { + if (cpu_to_processor(cpu)->state == PROCESSOR_RUNNING && + cpu_to_processor(cpu)->active_thread == thr_act && + PerProcTable[cpu].ppe_vaddr->db_saved_state) { - if (dp == 0) - dp = &null_reg; - } else if (thr_act->thread && - (thr_act->thread->state&TH_STACK_HANDOFF)){ - /* only PC is valid */ - if (vp->valuep == (int *) &ddb_regs.save_srr0) { - dp = (int *)(&thr_act->thread->continuation); - } else { - dp = &null_reg; + dp = (db_expr_t)(((uint32_t)(PerProcTable[cpu].ppe_vaddr->db_saved_state)) + + (((uint32_t) vp->valuep) - + (uint32_t) &ddb_regs)); + break; + } + } + + if (dp == 0) + dp = &null_reg; + } + else { + /* only PC is valid */ + if (vp->valuep == &ddb_regs.save_srr0) + dp = (db_expr_t *)&thr_act->continuation; + else + dp = &null_reg; + } } - } - } } if (dp == 0) { - int cpu; - - if (!db_option(ap->modif, 'u')) { - for (cpu = 0; cpu < NCPUS; cpu++) { - if (cpu_to_processor(cpu)->state == PROCESSOR_RUNNING && - cpu_to_processor(cpu)->cpu_data->active_thread == thr_act->thread && saved_state[cpu]) { - dp = (int *) (((int)saved_state[cpu]) + - (((int) vp->valuep) - - (int) &ddb_regs)); - break; - } + if (!db_option(ap->modif, 'u')) { + for (cpu = 0; cpu < real_ncpus; cpu++) { + if (cpu_to_processor(cpu)->state == PROCESSOR_RUNNING && + cpu_to_processor(cpu)->active_thread == thr_act && + PerProcTable[cpu].ppe_vaddr->db_saved_state) { + dp = (int *) (((int)(PerProcTable[cpu].ppe_vaddr->db_saved_state)) + + (((int) vp->valuep) - (int) &ddb_regs)); + break; + } + } + } + if (dp == 0) { + if (!thr_act || thr_act->machine.pcb == 0) + db_error("no pcb\n"); + dp = (int *)((int)thr_act->machine.pcb + ((int)vp->valuep - (int)&ddb_regs)); } - } - if (dp == 0) { - if (!thr_act || thr_act->mact.pcb == 0) - db_error("no pcb\n"); - dp = (int *)((int)thr_act->mact.pcb + - ((int)vp->valuep - (int)&ddb_regs)); - } } - if (flag == DB_VAR_SET) - *dp = *valuep; - else - *valuep = *dp; - return(0); + + if(vp->valuep == (db_expr_t *)&ddb_regs.save_cr) { /* Is this the CR we are doing? */ + dp32 = (uint32_t *)dp; /* Make this easier */ + if (flag == DB_VAR_SET) + *dp32 = *valuep; + else + *valuep = *dp32; + } + else { /* Normal 64-bit registers */ + if (flag == DB_VAR_SET) + *dp = *valuep; + else + *valuep = *(unsigned long long *)dp; + } + + return 0; } + void db_find_trace_symbols(void) { @@ -260,29 +607,29 @@ db_find_trace_symbols(void) found_some = FALSE; if (db_value_of_name(CC_SYM_PREFIX "thandler", &value)) { - db_user_trap_symbol_value = (db_addr_t) value; - found_some = TRUE; + db_user_trap_symbol_value = (db_addr_t) value; + found_some = TRUE; } if (db_value_of_name(CC_SYM_PREFIX "thandler", &value)) { - db_kernel_trap_symbol_value = (db_addr_t) value; - found_some = TRUE; + db_kernel_trap_symbol_value = (db_addr_t) value; + found_some = TRUE; } if (db_value_of_name(CC_SYM_PREFIX "ihandler", &value)) { - db_interrupt_symbol_value = (db_addr_t) value; - found_some = TRUE; + db_interrupt_symbol_value = (db_addr_t) value; + found_some = TRUE; } #if 0 if (db_value_of_name(CC_SYM_PREFIX "return_to_iret", &value)) { - db_return_to_iret_symbol_value = (db_addr_t) value; - found_some = TRUE; + db_return_to_iret_symbol_value = (db_addr_t) value; + found_some = TRUE; } #endif if (db_value_of_name(CC_SYM_PREFIX "thandler", &value)) { - db_syscall_symbol_value = (db_addr_t) value; - found_some = TRUE; + db_syscall_symbol_value = (db_addr_t) value; + found_some = TRUE; } if (found_some) - db_trace_symbols_found = TRUE; + db_trace_symbols_found = TRUE; } int @@ -290,7 +637,7 @@ db_numargs( struct db_ppc_frame *fp, task_t task) { - return (DB_NUMARGS_MAX); + return DB_NUMARGS_MAX; } boolean_t @@ -308,7 +655,7 @@ db_find_arg( int inst; char *name; -#if XXX_BS +#if 0 db_find_task_sym_and_offset(calleepc, &name, &offset, task); calleep = calleepc-offset; @@ -318,7 +665,7 @@ db_find_arg( } inst = db_get_task_value(calleep, 4, FALSE, task); if ((inst & 0xffff0000) == (0x907f0000 + (narg << 21)) || - (inst & 0xffff0000) == (0x90610000 + (narg << 21))) { + (inst & 0xffff0000) == (0x90610000 + (narg << 21))) { argp = (db_addr_t) &(fp->f_arg[narg]); *arg = argp; return TRUE; @@ -328,6 +675,7 @@ db_find_arg( return FALSE; } +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 @@ -347,49 +695,51 @@ db_nextframe( thread_act_t thr_act, db_addr_t linkpc) /* in */ { - extern char * trap_type[]; - extern int TRAP_TYPES; - struct savearea *saved_regs; task_t task = (thr_act != THR_ACT_NULL)? thr_act->task: TASK_NULL; switch(frame_type) { case TRAP: - - db_printf(">>>>> trap <<<<<\n"); - goto miss_frame; - break; + db_printf(">>>>> trap <<<<<\n"); + goto miss_frame; + break; case INTERRUPT: - if (*lfp == 0) { + if (*lfp == 0) { + db_printf(">>>>> interrupt <<<<<\n"); + goto miss_frame; + } db_printf(">>>>> interrupt <<<<<\n"); goto miss_frame; - } - db_printf(">>>>> interrupt <<<<<\n"); - goto miss_frame; - break; - case SYSCALL: - if (thr_act != THR_ACT_NULL && thr_act->mact.pcb) { - *ip = (db_addr_t) thr_act->mact.pcb->save_srr0; - *fp = (struct db_ppc_frame *) (thr_act->mact.pcb->save_r1); break; - } - /* falling down for unknown case */ + case SYSCALL: + if (thr_act != THR_ACT_NULL && thr_act->machine.pcb) { + *ip = (db_addr_t) thr_act->machine.pcb->save_srr0; + *fp = (struct db_ppc_frame *) (thr_act->machine.pcb->save_r1); + break; + } + /* falling down for unknown case */ default: - miss_frame: +miss_frame: + if(!pmap_find_phys(kernel_pmap, (addr64_t)*fp)) { /* Check if this is valid */ + db_printf("Frame not mapped %08X\n",*fp); /* Say not found */ + *fp = 0; /* Show not found */ + break; /* Out of here */ + } + if ((*fp)->f_frame) - *ip = (db_addr_t) - db_get_task_value((int)&(*fp)->f_frame->f_retaddr, - 4, FALSE, task); + *ip = (db_addr_t) + db_get_task_value((int)&(*fp)->f_frame->f_retaddr, + 4, FALSE, task); else *ip = (db_addr_t) - db_get_task_value((int)&(*fp)->f_retaddr, - 4, FALSE, task); + db_get_task_value((int)&(*fp)->f_retaddr, + 4, FALSE, task); - *lfp = *fp; - *fp = (struct db_ppc_frame *) - db_get_task_value((int)&(*fp)->f_frame, 4, FALSE, task); - break; + *lfp = *fp; + *fp = (struct db_ppc_frame *) + db_get_task_value((int)&(*fp)->f_frame, 4, FALSE, task); + break; } } @@ -418,10 +768,10 @@ db_stack_trace_cmd( queue_entry_t act_list; if (!db_trace_symbols_found) - db_find_trace_symbols(); + db_find_trace_symbols(); { - register char *cp = modif; - register char c; + char *cp = modif; + char c; while ((c = *cp++) != 0) { if (c == 't') @@ -436,43 +786,43 @@ db_stack_trace_cmd( } if (trace_all_threads) { - if (!have_addr && !trace_thread) { + 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_act_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_act_t)addr)->task->thr_acts); + act_list = &(((thread_act_t)addr)->task->threads); thcount = db_lookup_task_act(((thread_act_t)addr)->task, - (thread_act_t)addr); + (thread_act_t)addr); } } else { th = db_default_act; if (th == THR_ACT_NULL) - th = current_act(); + th = current_thread(); if (th == THR_ACT_NULL) { db_printf("no active thr_act\n"); return; } have_addr = TRUE; - act_list = &th->task->thr_acts; + act_list = &th->task->threads; addr = (db_expr_t) queue_first(act_list); } - } + } } if (count == -1) - count = 65535; + count = 65535; next_thread: top_act = THR_ACT_NULL; @@ -481,61 +831,51 @@ next_thread: frame_count = count; if (!have_addr && !trace_thread) { - frame = (struct db_ppc_frame *)(ddb_regs.save_r1); - callpc = (db_addr_t)ddb_regs.save_srr0; - linkpc = (db_addr_t)ddb_regs.save_lr; - th = current_act(); - task = (th != THR_ACT_NULL)? th->task: TASK_NULL; + frame = (struct db_ppc_frame *)(ddb_regs.save_r1); + callpc = (db_addr_t)ddb_regs.save_srr0; + linkpc = (db_addr_t)ddb_regs.save_lr; + th = current_thread(); + task = (th != THR_ACT_NULL)? th->task: TASK_NULL; } else if (trace_thread) { - if (have_addr) { + if (have_addr) { th = (thread_act_t) addr; if (!db_check_act_address_valid(th)) - return; - } + return; + } else { th = db_default_act; if (th == THR_ACT_NULL) - th = current_act(); + th = current_thread(); if (th == THR_ACT_NULL) { - db_printf("no active thread\n"); - return; + db_printf("no active thread\n"); + return; } - } - if (trace_all_threads) - db_printf("---------- Thread 0x%x (#%d of %d) ----------\n", - addr, thcount, th->task->thr_act_count); + } + if (trace_all_threads) + db_printf("---------- Thread 0x%x (#%d of %d) ----------\n", + addr, thcount, th->task->thread_count); next_activation: + user_frame = 0; - user_frame = 0; - - task = th->task; - if (th == current_act()) { - frame = (struct db_ppc_frame *)(ddb_regs.save_r1); - callpc = (db_addr_t)ddb_regs.save_srr0; + task = th->task; + if (th == current_thread()) { + frame = (struct db_ppc_frame *)(ddb_regs.save_r1); + callpc = (db_addr_t)ddb_regs.save_srr0; linkpc = (db_addr_t)ddb_regs.save_lr; - } + } else { - if (th->mact.pcb == 0) { - db_printf("thread has no pcb\n"); + if (th->machine.pcb == 0) { + db_printf("thread has no pcb\n"); goto thread_done; } - if (!th->thread) { - register struct savearea *pss = - th->mact.pcb; - - db_printf("thread has no shuttle\n"); - goto thread_done; - } - else if ((th->thread->state & TH_STACK_HANDOFF) || - th->thread->kernel_stack == 0) { - register struct savearea *pss = - th->mact.pcb; - + if (th->kernel_stack == 0) { + struct savearea *pss = th->machine.pcb; + db_printf("Continuation "); - db_task_printsym((db_expr_t)th->thread->continuation, - DB_STGY_PROC, task); + db_task_printsym((db_expr_t)th->continuation, + DB_STGY_PROC, task); db_printf("\n"); frame = (struct db_ppc_frame *) (pss->save_r1); callpc = (db_addr_t) (pss->save_srr0); @@ -543,11 +883,11 @@ next_activation: } else { int cpu; - - for (cpu = 0; cpu < NCPUS; cpu++) { + + for (cpu = 0; cpu < real_ncpus; cpu++) { if (cpu_to_processor(cpu)->state == PROCESSOR_RUNNING && - cpu_to_processor(cpu)->cpu_data->active_thread == th->thread && - saved_state[cpu]) { + cpu_to_processor(cpu)->active_thread == th && + PerProcTable[cpu].ppe_vaddr->db_saved_state) { break; } } @@ -558,68 +898,68 @@ next_activation: * use the activation's pcb. */ struct savearea *pss; - - pss = th->mact.pcb; + + pss = th->machine.pcb; frame = (struct db_ppc_frame *) (pss->save_r1); callpc = (db_addr_t) (pss->save_srr0); linkpc = (db_addr_t) (pss->save_lr); - } else { - if (cpu == NCPUS) { - register struct savearea *iks; - int r; - - iks = th->mact.pcb; - prev = db_recover; - if ((r = _setjmp(db_recover = &db_jmp_buf)) == 0) { - frame = (struct db_ppc_frame *) (iks->save_r1); - callpc = (db_addr_t) (iks->save_lr); - linkpc = 0; - } else { - /* - * The kernel stack has probably been - * paged out (swapped out activation). - */ - db_recover = prev; - if (r == 2) /* 'q' from db_more() */ - db_error(0); - db_printf("\n", - iks); - goto next_act; - } - db_recover = prev; + } else { + if (cpu == real_ncpus) { + struct savearea *iks; + int r; + + iks = th->machine.pcb; + prev = db_recover; + if ((r = _setjmp(db_recover = &db_jmp_buf)) == 0) { + frame = (struct db_ppc_frame *) (iks->save_r1); + callpc = (db_addr_t) (iks->save_lr); + linkpc = 0; } else { - db_printf(">>>>> active on cpu %d <<<<<\n", - cpu); - frame = (struct db_ppc_frame *) - (saved_state[cpu]->save_r1); - callpc = (db_addr_t) saved_state[cpu]->save_srr0; - linkpc = (db_addr_t) saved_state[cpu]->save_lr; + /* + * The kernel stack has probably been + * paged out (swapped out activation). + */ + db_recover = prev; + if (r == 2) /* 'q' from db_more() */ + db_error(0); + db_printf("\n", + iks); + goto next_act; } + db_recover = prev; + } else { + db_printf(">>>>> active on cpu %d <<<<<\n", + cpu); + frame = (struct db_ppc_frame *) + (PerProcTable[cpu].ppe_vaddr->db_saved_state->save_r1); + callpc = (db_addr_t) PerProcTable[cpu].ppe_vaddr->db_saved_state->save_srr0; + linkpc = (db_addr_t) PerProcTable[cpu].ppe_vaddr->db_saved_state->save_lr; } } - } + } + } } else { - frame = (struct db_ppc_frame *)addr; - th = (db_default_act)? db_default_act: current_act(); - task = (th != THR_ACT_NULL)? th->task: TASK_NULL; - if (frame->f_frame) { - callpc = (db_addr_t)db_get_task_value + frame = (struct db_ppc_frame *)addr; + th = (db_default_act)? db_default_act: current_thread(); + task = (th != THR_ACT_NULL)? th->task: TASK_NULL; + if (frame->f_frame) { + callpc = (db_addr_t)db_get_task_value ((int)&frame->f_frame->f_retaddr, - 4, FALSE, (user_frame) ? task : 0); - callpc = callpc-sizeof(callpc); - } else - callpc =0; - linkpc = 0; + 4, FALSE, (user_frame) ? task : 0); + callpc = callpc-sizeof(callpc); + } else + callpc =0; + linkpc = 0; } if (!INKERNELSTACK((unsigned)frame, th)) { - db_printf(">>>>> user space <<<<<\n"); - if (kernel_only) - goto thread_done; - user_frame++; + db_printf(">>>>> user space <<<<<\n"); + if (kernel_only) + goto thread_done; + user_frame++; } - + lastframe = 0; lastcallpc = (db_addr_t) 0; while (frame_count-- && frame != 0) { @@ -632,51 +972,51 @@ next_activation: db_addr_t off; db_symbol_values(NULL, - db_search_task_symbol_and_line( - callpc, DB_STGY_XTRN, &offset, &filename, - &linenum, (user_frame) ? task : 0, &narg), - &name, (db_expr_t *)&call_func); + db_search_task_symbol_and_line( + callpc, DB_STGY_XTRN, &offset, &filename, + &linenum, (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); + &name, &off, (user_frame) ? task : 0); offset = (db_expr_t) off; } if (user_frame == 0) { if (call_func && - (call_func == db_user_trap_symbol_value || - call_func == db_kernel_trap_symbol_value)) { - frame_type = TRAP; - narg = 1; + (call_func == db_user_trap_symbol_value || + call_func == db_kernel_trap_symbol_value)) { + frame_type = TRAP; + narg = 1; } else if (call_func && - call_func == db_interrupt_symbol_value) { + call_func == db_interrupt_symbol_value) { frame_type = INTERRUPT; goto next_frame; } else if (call_func && - call_func == db_syscall_symbol_value) { + call_func == db_syscall_symbol_value) { frame_type = SYSCALL; goto next_frame; } else { frame_type = 0; prev = db_recover; if ((r = _setjmp(db_recover = &db_jmp_buf)) - == 0) { - if (narg < 0) + == 0) { + if (narg < 0) narg = db_numargs(frame, - (user_frame) ? task : 0); + (user_frame) ? task : 0); db_recover = prev; } else { db_recover = prev; goto next_act; } } - } else { + } else { frame_type = 0; prev = db_recover; if ((r = _setjmp(db_recover = &db_jmp_buf)) == 0) { if (narg < 0) narg = db_numargs(frame, - (user_frame) ? task : 0); + (user_frame) ? task : 0); db_recover = prev; } else { db_recover = prev; @@ -684,109 +1024,99 @@ next_activation: } } - if (name == 0 || offset > db_maxoff) { - db_printf("[%08X]0x%08X(", frame, callpc); - } else { - db_printf("[%08X]%s", frame, name); - if (offset) - db_printf("+%x", offset); - db_printf("("); - }; + if (name == 0 || offset > db_maxoff) { + db_printf("[%08X]0x%08X(", frame, callpc); + } else { + db_printf("[%08X]%s", frame, name); + if (offset) + db_printf("+%llx", offset); + db_printf("("); + }; + + narg = db_numargs(frame, (user_frame) ? task : 0); - narg = db_numargs(frame, (user_frame) ? task : 0); + for (arg = 0; arg < narg; arg++) { + db_addr_t argp; + int value; + boolean_t found; - for (arg =0; arg < narg; arg++) { - db_addr_t argp; - int value; - boolean_t found; + prev = db_recover; + if ((r = _setjmp(db_recover = &db_jmp_buf)) == 0) { + found = FALSE; + if (lastframe) + found = db_find_arg(frame, lastframe->f_retaddr, + (user_frame) ? task : 0, arg, &argp); + if (found) + value = db_get_task_value(argp, 4, FALSE, + (user_frame) ? task : 0); + } else { + db_recover = prev; + if (r == 2) /* 'q' from db_more() */ + db_error(0); + db_printf("... )"); + db_printf("\n"); + goto next_act; + } + db_recover = prev; + if (found) + db_printf("%08X", value); + else + db_printf("??"); + argp = argp + sizeof(argp); + if (arg < narg-1) + db_printf(","); + } + if (arg != narg) + db_printf("..."); + db_printf(")"); + db_printf("\n"); +next_frame: + lastcallpc = callpc; prev = db_recover; if ((r = _setjmp(db_recover = &db_jmp_buf)) == 0) { - found = FALSE; - if (lastframe) - found = db_find_arg(frame, lastframe->f_retaddr, - (user_frame) ? task : 0, arg, &argp); - if (found) - value = db_get_task_value(argp, 4, FALSE, - (user_frame) ? task : 0); + db_nextframe(&lastframe, &frame, &callpc, frame_type, + (user_frame) ? th : THR_ACT_NULL, linkpc); + callpc = callpc-sizeof(callpc); + db_recover = prev; } else { db_recover = prev; - if (r == 2) /* 'q' from db_more() */ - db_error(0); - db_printf("... )"); - db_printf("\n"); - goto next_act; + frame = 0; } - db_recover = prev; - if (found) - db_printf("%08X", value); - else - db_printf("??"); - argp = argp + sizeof(argp); - if (arg < narg-1) - db_printf(","); - } - if (arg != narg) - db_printf("..."); - db_printf(")"); - db_printf("\n"); - - next_frame: - lastcallpc = callpc; - prev = db_recover; - if ((r = _setjmp(db_recover = &db_jmp_buf)) == 0) { - db_nextframe(&lastframe, &frame, &callpc, frame_type, - (user_frame) ? th : THR_ACT_NULL, linkpc); - callpc = callpc-sizeof(callpc); - db_recover = prev; - } else { - db_recover = prev; - frame = 0; - } - linkpc = 0; - - if (frame == 0) { - next_act: - if (th->lower != THR_ACT_NULL) { - if (top_act == THR_ACT_NULL) - top_act = th; - th = th->lower; - db_printf(">>>>> next activation 0x%x ($task%d.%d) <<<<<\n", - th, - db_lookup_task(th->task), - db_lookup_task_act(th->task, th)); - goto next_activation; + linkpc = 0; + + if (frame == 0) { +next_act: + /* end of chain */ + break; } - /* end of chain */ - break; - } - if (!INKERNELSTACK(lastframe, th) || - !INKERNELSTACK((unsigned)frame, th)) - user_frame++; - if (user_frame == 1) { - db_printf(">>>>> user space <<<<<\n"); - if (kernel_only) - break; - } - + if (!INKERNELSTACK(lastframe, th) || + !INKERNELSTACK((unsigned)frame, th)) + user_frame++; + if (user_frame == 1) { + db_printf(">>>>> user space <<<<<\n"); + if (kernel_only) + break; + } + if (frame <= lastframe) { - if ((INKERNELSTACK(lastframe, th) && !INKERNELSTACK(frame, th))) continue; - db_printf("Bad frame pointer: 0x%x\n", frame); - break; - } + if ((INKERNELSTACK(lastframe, th) && !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 != THR_ACT_NULL) - th = top_act; - th = (thread_act_t) queue_next(&th->thr_acts); - if (! queue_end(act_list, (queue_entry_t) th)) { - db_printf("\n"); - addr = (db_expr_t) th; - thcount++; - goto next_thread; - - } + if (top_act != THR_ACT_NULL) + th = top_act; + th = (thread_act_t) queue_next(&th->task_threads); + if (! queue_end(act_list, (queue_entry_t) th)) { + db_printf("\n"); + addr = (db_expr_t) th; + thcount++; + goto next_thread; + } } }