1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * CDDL HEADER START 3*7c478bd9Sstevel@tonic-gate * 4*7c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*7c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*7c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*7c478bd9Sstevel@tonic-gate * with the License. 8*7c478bd9Sstevel@tonic-gate * 9*7c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*7c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*7c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 12*7c478bd9Sstevel@tonic-gate * and limitations under the License. 13*7c478bd9Sstevel@tonic-gate * 14*7c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*7c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*7c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*7c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*7c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*7c478bd9Sstevel@tonic-gate * 20*7c478bd9Sstevel@tonic-gate * CDDL HEADER END 21*7c478bd9Sstevel@tonic-gate */ 22*7c478bd9Sstevel@tonic-gate /* 23*7c478bd9Sstevel@tonic-gate * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 24*7c478bd9Sstevel@tonic-gate * Use is subject to license terms. 25*7c478bd9Sstevel@tonic-gate */ 26*7c478bd9Sstevel@tonic-gate 27*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 28*7c478bd9Sstevel@tonic-gate 29*7c478bd9Sstevel@tonic-gate /* 30*7c478bd9Sstevel@tonic-gate * Libkvm Kernel Target Intel 32-bit component 31*7c478bd9Sstevel@tonic-gate * 32*7c478bd9Sstevel@tonic-gate * This file provides the ISA-dependent portion of the libkvm kernel target. 33*7c478bd9Sstevel@tonic-gate * For more details on the implementation refer to mdb_kvm.c. 34*7c478bd9Sstevel@tonic-gate */ 35*7c478bd9Sstevel@tonic-gate 36*7c478bd9Sstevel@tonic-gate #include <sys/types.h> 37*7c478bd9Sstevel@tonic-gate #include <sys/regset.h> 38*7c478bd9Sstevel@tonic-gate #include <sys/frame.h> 39*7c478bd9Sstevel@tonic-gate #include <sys/stack.h> 40*7c478bd9Sstevel@tonic-gate #include <sys/sysmacros.h> 41*7c478bd9Sstevel@tonic-gate #include <sys/panic.h> 42*7c478bd9Sstevel@tonic-gate #include <strings.h> 43*7c478bd9Sstevel@tonic-gate 44*7c478bd9Sstevel@tonic-gate #include <mdb/mdb_target_impl.h> 45*7c478bd9Sstevel@tonic-gate #include <mdb/mdb_disasm.h> 46*7c478bd9Sstevel@tonic-gate #include <mdb/mdb_modapi.h> 47*7c478bd9Sstevel@tonic-gate #include <mdb/mdb_conf.h> 48*7c478bd9Sstevel@tonic-gate #include <mdb/mdb_kreg_impl.h> 49*7c478bd9Sstevel@tonic-gate #include <mdb/mdb_ia32util.h> 50*7c478bd9Sstevel@tonic-gate #include <mdb/mdb_kvm.h> 51*7c478bd9Sstevel@tonic-gate #include <mdb/mdb_err.h> 52*7c478bd9Sstevel@tonic-gate #include <mdb/mdb_debug.h> 53*7c478bd9Sstevel@tonic-gate #include <mdb/mdb.h> 54*7c478bd9Sstevel@tonic-gate 55*7c478bd9Sstevel@tonic-gate static int 56*7c478bd9Sstevel@tonic-gate kt_getareg(mdb_tgt_t *t, mdb_tgt_tid_t tid, 57*7c478bd9Sstevel@tonic-gate const char *rname, mdb_tgt_reg_t *rp) 58*7c478bd9Sstevel@tonic-gate { 59*7c478bd9Sstevel@tonic-gate const mdb_tgt_regdesc_t *rdp; 60*7c478bd9Sstevel@tonic-gate kt_data_t *kt = t->t_data; 61*7c478bd9Sstevel@tonic-gate 62*7c478bd9Sstevel@tonic-gate if (tid != kt->k_tid) 63*7c478bd9Sstevel@tonic-gate return (set_errno(EMDB_NOREGS)); 64*7c478bd9Sstevel@tonic-gate 65*7c478bd9Sstevel@tonic-gate for (rdp = kt->k_rds; rdp->rd_name != NULL; rdp++) { 66*7c478bd9Sstevel@tonic-gate if (strcmp(rname, rdp->rd_name) == 0) { 67*7c478bd9Sstevel@tonic-gate *rp = kt->k_regs->kregs[rdp->rd_num]; 68*7c478bd9Sstevel@tonic-gate return (0); 69*7c478bd9Sstevel@tonic-gate } 70*7c478bd9Sstevel@tonic-gate } 71*7c478bd9Sstevel@tonic-gate 72*7c478bd9Sstevel@tonic-gate return (set_errno(EMDB_BADREG)); 73*7c478bd9Sstevel@tonic-gate } 74*7c478bd9Sstevel@tonic-gate 75*7c478bd9Sstevel@tonic-gate static int 76*7c478bd9Sstevel@tonic-gate kt_putareg(mdb_tgt_t *t, mdb_tgt_tid_t tid, const char *rname, mdb_tgt_reg_t r) 77*7c478bd9Sstevel@tonic-gate { 78*7c478bd9Sstevel@tonic-gate const mdb_tgt_regdesc_t *rdp; 79*7c478bd9Sstevel@tonic-gate kt_data_t *kt = t->t_data; 80*7c478bd9Sstevel@tonic-gate 81*7c478bd9Sstevel@tonic-gate if (tid != kt->k_tid) 82*7c478bd9Sstevel@tonic-gate return (set_errno(EMDB_NOREGS)); 83*7c478bd9Sstevel@tonic-gate 84*7c478bd9Sstevel@tonic-gate for (rdp = kt->k_rds; rdp->rd_name != NULL; rdp++) { 85*7c478bd9Sstevel@tonic-gate if (strcmp(rname, rdp->rd_name) == 0) { 86*7c478bd9Sstevel@tonic-gate kt->k_regs->kregs[rdp->rd_num] = (kreg_t)r; 87*7c478bd9Sstevel@tonic-gate return (0); 88*7c478bd9Sstevel@tonic-gate } 89*7c478bd9Sstevel@tonic-gate } 90*7c478bd9Sstevel@tonic-gate 91*7c478bd9Sstevel@tonic-gate return (set_errno(EMDB_BADREG)); 92*7c478bd9Sstevel@tonic-gate } 93*7c478bd9Sstevel@tonic-gate 94*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 95*7c478bd9Sstevel@tonic-gate int 96*7c478bd9Sstevel@tonic-gate kt_regs(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 97*7c478bd9Sstevel@tonic-gate { 98*7c478bd9Sstevel@tonic-gate kt_data_t *kt = mdb.m_target->t_data; 99*7c478bd9Sstevel@tonic-gate 100*7c478bd9Sstevel@tonic-gate if (argc != 0 || (flags & DCMD_ADDRSPEC)) 101*7c478bd9Sstevel@tonic-gate return (DCMD_USAGE); 102*7c478bd9Sstevel@tonic-gate 103*7c478bd9Sstevel@tonic-gate mdb_ia32_printregs(kt->k_regs); 104*7c478bd9Sstevel@tonic-gate 105*7c478bd9Sstevel@tonic-gate return (DCMD_OK); 106*7c478bd9Sstevel@tonic-gate } 107*7c478bd9Sstevel@tonic-gate 108*7c478bd9Sstevel@tonic-gate /* 109*7c478bd9Sstevel@tonic-gate * Return a flag indicating if the specified %eip is likely to have an 110*7c478bd9Sstevel@tonic-gate * interrupt frame on the stack. We do this by comparing the address to the 111*7c478bd9Sstevel@tonic-gate * range of addresses spanned by several well-known routines, and looking 112*7c478bd9Sstevel@tonic-gate * to see if the next and previous %ebp values are "far" apart. Sigh. 113*7c478bd9Sstevel@tonic-gate */ 114*7c478bd9Sstevel@tonic-gate int 115*7c478bd9Sstevel@tonic-gate mdb_kvm_intrframe(mdb_tgt_t *t, uintptr_t pc, uintptr_t fp, 116*7c478bd9Sstevel@tonic-gate uintptr_t prevfp) 117*7c478bd9Sstevel@tonic-gate { 118*7c478bd9Sstevel@tonic-gate kt_data_t *kt = t->t_data; 119*7c478bd9Sstevel@tonic-gate 120*7c478bd9Sstevel@tonic-gate return ((pc >= kt->k_intr_sym.st_value && 121*7c478bd9Sstevel@tonic-gate (pc < kt->k_intr_sym.st_value + kt->k_intr_sym.st_size)) || 122*7c478bd9Sstevel@tonic-gate (pc >= kt->k_trap_sym.st_value && 123*7c478bd9Sstevel@tonic-gate (pc < kt->k_trap_sym.st_value + kt->k_trap_sym.st_size)) || 124*7c478bd9Sstevel@tonic-gate (fp >= prevfp + 0x2000) || (fp <= prevfp - 0x2000)); 125*7c478bd9Sstevel@tonic-gate } 126*7c478bd9Sstevel@tonic-gate 127*7c478bd9Sstevel@tonic-gate static int 128*7c478bd9Sstevel@tonic-gate kt_stack_common(uintptr_t addr, uint_t flags, int argc, 129*7c478bd9Sstevel@tonic-gate const mdb_arg_t *argv, mdb_tgt_stack_f *func) 130*7c478bd9Sstevel@tonic-gate { 131*7c478bd9Sstevel@tonic-gate kt_data_t *kt = mdb.m_target->t_data; 132*7c478bd9Sstevel@tonic-gate void *arg = (void *)mdb.m_nargs; 133*7c478bd9Sstevel@tonic-gate mdb_tgt_gregset_t gregs, *grp; 134*7c478bd9Sstevel@tonic-gate 135*7c478bd9Sstevel@tonic-gate if (flags & DCMD_ADDRSPEC) { 136*7c478bd9Sstevel@tonic-gate bzero(&gregs, sizeof (gregs)); 137*7c478bd9Sstevel@tonic-gate gregs.kregs[KREG_EBP] = addr; 138*7c478bd9Sstevel@tonic-gate grp = &gregs; 139*7c478bd9Sstevel@tonic-gate } else 140*7c478bd9Sstevel@tonic-gate grp = kt->k_regs; 141*7c478bd9Sstevel@tonic-gate 142*7c478bd9Sstevel@tonic-gate if (argc != 0) { 143*7c478bd9Sstevel@tonic-gate if (argv->a_type == MDB_TYPE_CHAR || argc > 1) 144*7c478bd9Sstevel@tonic-gate return (DCMD_USAGE); 145*7c478bd9Sstevel@tonic-gate 146*7c478bd9Sstevel@tonic-gate if (argv->a_type == MDB_TYPE_STRING) 147*7c478bd9Sstevel@tonic-gate arg = (void *)(uint_t)mdb_strtoull(argv->a_un.a_str); 148*7c478bd9Sstevel@tonic-gate else 149*7c478bd9Sstevel@tonic-gate arg = (void *)(uint_t)argv->a_un.a_val; 150*7c478bd9Sstevel@tonic-gate } 151*7c478bd9Sstevel@tonic-gate 152*7c478bd9Sstevel@tonic-gate (void) mdb_ia32_kvm_stack_iter(mdb.m_target, grp, func, arg); 153*7c478bd9Sstevel@tonic-gate return (DCMD_OK); 154*7c478bd9Sstevel@tonic-gate } 155*7c478bd9Sstevel@tonic-gate 156*7c478bd9Sstevel@tonic-gate static int 157*7c478bd9Sstevel@tonic-gate kt_stack(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 158*7c478bd9Sstevel@tonic-gate { 159*7c478bd9Sstevel@tonic-gate return (kt_stack_common(addr, flags, argc, argv, mdb_ia32_kvm_frame)); 160*7c478bd9Sstevel@tonic-gate } 161*7c478bd9Sstevel@tonic-gate 162*7c478bd9Sstevel@tonic-gate static int 163*7c478bd9Sstevel@tonic-gate kt_stackv(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 164*7c478bd9Sstevel@tonic-gate { 165*7c478bd9Sstevel@tonic-gate return (kt_stack_common(addr, flags, argc, argv, mdb_ia32_kvm_framev)); 166*7c478bd9Sstevel@tonic-gate } 167*7c478bd9Sstevel@tonic-gate 168*7c478bd9Sstevel@tonic-gate const mdb_tgt_ops_t kt_ia32_ops = { 169*7c478bd9Sstevel@tonic-gate kt_setflags, /* t_setflags */ 170*7c478bd9Sstevel@tonic-gate kt_setcontext, /* t_setcontext */ 171*7c478bd9Sstevel@tonic-gate kt_activate, /* t_activate */ 172*7c478bd9Sstevel@tonic-gate kt_deactivate, /* t_deactivate */ 173*7c478bd9Sstevel@tonic-gate (void (*)()) mdb_tgt_nop, /* t_periodic */ 174*7c478bd9Sstevel@tonic-gate kt_destroy, /* t_destroy */ 175*7c478bd9Sstevel@tonic-gate kt_name, /* t_name */ 176*7c478bd9Sstevel@tonic-gate (const char *(*)()) mdb_conf_isa, /* t_isa */ 177*7c478bd9Sstevel@tonic-gate kt_platform, /* t_platform */ 178*7c478bd9Sstevel@tonic-gate kt_uname, /* t_uname */ 179*7c478bd9Sstevel@tonic-gate kt_dmodel, /* t_dmodel */ 180*7c478bd9Sstevel@tonic-gate kt_aread, /* t_aread */ 181*7c478bd9Sstevel@tonic-gate kt_awrite, /* t_awrite */ 182*7c478bd9Sstevel@tonic-gate kt_vread, /* t_vread */ 183*7c478bd9Sstevel@tonic-gate kt_vwrite, /* t_vwrite */ 184*7c478bd9Sstevel@tonic-gate kt_pread, /* t_pread */ 185*7c478bd9Sstevel@tonic-gate kt_pwrite, /* t_pwrite */ 186*7c478bd9Sstevel@tonic-gate kt_fread, /* t_fread */ 187*7c478bd9Sstevel@tonic-gate kt_fwrite, /* t_fwrite */ 188*7c478bd9Sstevel@tonic-gate (ssize_t (*)()) mdb_tgt_notsup, /* t_ioread */ 189*7c478bd9Sstevel@tonic-gate (ssize_t (*)()) mdb_tgt_notsup, /* t_iowrite */ 190*7c478bd9Sstevel@tonic-gate kt_vtop, /* t_vtop */ 191*7c478bd9Sstevel@tonic-gate kt_lookup_by_name, /* t_lookup_by_name */ 192*7c478bd9Sstevel@tonic-gate kt_lookup_by_addr, /* t_lookup_by_addr */ 193*7c478bd9Sstevel@tonic-gate kt_symbol_iter, /* t_symbol_iter */ 194*7c478bd9Sstevel@tonic-gate kt_mapping_iter, /* t_mapping_iter */ 195*7c478bd9Sstevel@tonic-gate kt_object_iter, /* t_object_iter */ 196*7c478bd9Sstevel@tonic-gate kt_addr_to_map, /* t_addr_to_map */ 197*7c478bd9Sstevel@tonic-gate kt_name_to_map, /* t_name_to_map */ 198*7c478bd9Sstevel@tonic-gate kt_addr_to_ctf, /* t_addr_to_ctf */ 199*7c478bd9Sstevel@tonic-gate kt_name_to_ctf, /* t_name_to_ctf */ 200*7c478bd9Sstevel@tonic-gate kt_status, /* t_status */ 201*7c478bd9Sstevel@tonic-gate (int (*)()) mdb_tgt_notsup, /* t_run */ 202*7c478bd9Sstevel@tonic-gate (int (*)()) mdb_tgt_notsup, /* t_step */ 203*7c478bd9Sstevel@tonic-gate (int (*)()) mdb_tgt_notsup, /* t_step_out */ 204*7c478bd9Sstevel@tonic-gate (int (*)()) mdb_tgt_notsup, /* t_step_branch */ 205*7c478bd9Sstevel@tonic-gate (int (*)()) mdb_tgt_notsup, /* t_next */ 206*7c478bd9Sstevel@tonic-gate (int (*)()) mdb_tgt_notsup, /* t_cont */ 207*7c478bd9Sstevel@tonic-gate (int (*)()) mdb_tgt_notsup, /* t_signal */ 208*7c478bd9Sstevel@tonic-gate (int (*)()) mdb_tgt_null, /* t_add_vbrkpt */ 209*7c478bd9Sstevel@tonic-gate (int (*)()) mdb_tgt_null, /* t_add_sbrkpt */ 210*7c478bd9Sstevel@tonic-gate (int (*)()) mdb_tgt_null, /* t_add_pwapt */ 211*7c478bd9Sstevel@tonic-gate (int (*)()) mdb_tgt_null, /* t_add_vwapt */ 212*7c478bd9Sstevel@tonic-gate (int (*)()) mdb_tgt_null, /* t_add_iowapt */ 213*7c478bd9Sstevel@tonic-gate (int (*)()) mdb_tgt_null, /* t_add_sysenter */ 214*7c478bd9Sstevel@tonic-gate (int (*)()) mdb_tgt_null, /* t_add_sysexit */ 215*7c478bd9Sstevel@tonic-gate (int (*)()) mdb_tgt_null, /* t_add_signal */ 216*7c478bd9Sstevel@tonic-gate (int (*)()) mdb_tgt_null, /* t_add_fault */ 217*7c478bd9Sstevel@tonic-gate kt_getareg, /* t_getareg */ 218*7c478bd9Sstevel@tonic-gate kt_putareg, /* t_putareg */ 219*7c478bd9Sstevel@tonic-gate mdb_ia32_kvm_stack_iter, /* t_stack_iter */ 220*7c478bd9Sstevel@tonic-gate }; 221*7c478bd9Sstevel@tonic-gate 222*7c478bd9Sstevel@tonic-gate void 223*7c478bd9Sstevel@tonic-gate kt_ia32_init(mdb_tgt_t *t) 224*7c478bd9Sstevel@tonic-gate { 225*7c478bd9Sstevel@tonic-gate kt_data_t *kt = t->t_data; 226*7c478bd9Sstevel@tonic-gate 227*7c478bd9Sstevel@tonic-gate panic_data_t pd; 228*7c478bd9Sstevel@tonic-gate kreg_t *kregs; 229*7c478bd9Sstevel@tonic-gate label_t label; 230*7c478bd9Sstevel@tonic-gate struct regs regs; 231*7c478bd9Sstevel@tonic-gate uintptr_t addr; 232*7c478bd9Sstevel@tonic-gate 233*7c478bd9Sstevel@tonic-gate /* 234*7c478bd9Sstevel@tonic-gate * Initialize the machine-dependent parts of the kernel target 235*7c478bd9Sstevel@tonic-gate * structure. Once this is complete and we fill in the ops 236*7c478bd9Sstevel@tonic-gate * vector, the target is now fully constructed and we can use 237*7c478bd9Sstevel@tonic-gate * the target API itself to perform the rest of our initialization. 238*7c478bd9Sstevel@tonic-gate */ 239*7c478bd9Sstevel@tonic-gate kt->k_rds = mdb_ia32_kregs; 240*7c478bd9Sstevel@tonic-gate kt->k_regs = mdb_zalloc(sizeof (mdb_tgt_gregset_t), UM_SLEEP); 241*7c478bd9Sstevel@tonic-gate kt->k_regsize = sizeof (mdb_tgt_gregset_t); 242*7c478bd9Sstevel@tonic-gate kt->k_dcmd_regs = kt_regs; 243*7c478bd9Sstevel@tonic-gate kt->k_dcmd_stack = kt_stack; 244*7c478bd9Sstevel@tonic-gate kt->k_dcmd_stackv = kt_stackv; 245*7c478bd9Sstevel@tonic-gate kt->k_dcmd_stackr = kt_stackv; 246*7c478bd9Sstevel@tonic-gate 247*7c478bd9Sstevel@tonic-gate t->t_ops = &kt_ia32_ops; 248*7c478bd9Sstevel@tonic-gate kregs = kt->k_regs->kregs; 249*7c478bd9Sstevel@tonic-gate 250*7c478bd9Sstevel@tonic-gate (void) mdb_dis_select("ia32"); 251*7c478bd9Sstevel@tonic-gate 252*7c478bd9Sstevel@tonic-gate /* 253*7c478bd9Sstevel@tonic-gate * Lookup the symbols corresponding to subroutines in locore.s where 254*7c478bd9Sstevel@tonic-gate * we expect a saved regs structure to be pushed on the stack. When 255*7c478bd9Sstevel@tonic-gate * performing stack tracebacks we will attempt to detect interrupt 256*7c478bd9Sstevel@tonic-gate * frames by comparing the %eip value to these symbols. 257*7c478bd9Sstevel@tonic-gate */ 258*7c478bd9Sstevel@tonic-gate (void) mdb_tgt_lookup_by_name(t, MDB_TGT_OBJ_EXEC, 259*7c478bd9Sstevel@tonic-gate "cmnint", &kt->k_intr_sym, NULL); 260*7c478bd9Sstevel@tonic-gate 261*7c478bd9Sstevel@tonic-gate (void) mdb_tgt_lookup_by_name(t, MDB_TGT_OBJ_EXEC, 262*7c478bd9Sstevel@tonic-gate "cmntrap", &kt->k_trap_sym, NULL); 263*7c478bd9Sstevel@tonic-gate 264*7c478bd9Sstevel@tonic-gate /* 265*7c478bd9Sstevel@tonic-gate * Don't attempt to load any thread or register information if 266*7c478bd9Sstevel@tonic-gate * we're examining the live operating system. 267*7c478bd9Sstevel@tonic-gate */ 268*7c478bd9Sstevel@tonic-gate if (strcmp(kt->k_symfile, "/dev/ksyms") == 0) 269*7c478bd9Sstevel@tonic-gate return; 270*7c478bd9Sstevel@tonic-gate 271*7c478bd9Sstevel@tonic-gate /* 272*7c478bd9Sstevel@tonic-gate * If the panicbuf symbol is present and we can consume a panicbuf 273*7c478bd9Sstevel@tonic-gate * header of the appropriate version from this address, then we can 274*7c478bd9Sstevel@tonic-gate * initialize our current register set based on its contents. 275*7c478bd9Sstevel@tonic-gate * Prior to the re-structuring of panicbuf, our only register data 276*7c478bd9Sstevel@tonic-gate * was the panic_regs label_t, into which a setjmp() was performed, 277*7c478bd9Sstevel@tonic-gate * or the panic_reg register pointer, which was only non-zero if 278*7c478bd9Sstevel@tonic-gate * the system panicked as a result of a trap calling die(). 279*7c478bd9Sstevel@tonic-gate */ 280*7c478bd9Sstevel@tonic-gate if (mdb_tgt_readsym(t, MDB_TGT_AS_VIRT, &pd, sizeof (pd), 281*7c478bd9Sstevel@tonic-gate MDB_TGT_OBJ_EXEC, "panicbuf") == sizeof (pd) && 282*7c478bd9Sstevel@tonic-gate pd.pd_version == PANICBUFVERS) { 283*7c478bd9Sstevel@tonic-gate 284*7c478bd9Sstevel@tonic-gate size_t pd_size = MIN(PANICBUFSIZE, pd.pd_msgoff); 285*7c478bd9Sstevel@tonic-gate panic_data_t *pdp = mdb_zalloc(pd_size, UM_SLEEP); 286*7c478bd9Sstevel@tonic-gate uint_t i, n; 287*7c478bd9Sstevel@tonic-gate 288*7c478bd9Sstevel@tonic-gate (void) mdb_tgt_readsym(t, MDB_TGT_AS_VIRT, pdp, pd_size, 289*7c478bd9Sstevel@tonic-gate MDB_TGT_OBJ_EXEC, "panicbuf"); 290*7c478bd9Sstevel@tonic-gate 291*7c478bd9Sstevel@tonic-gate n = (pd_size - (sizeof (panic_data_t) - 292*7c478bd9Sstevel@tonic-gate sizeof (panic_nv_t))) / sizeof (panic_nv_t); 293*7c478bd9Sstevel@tonic-gate 294*7c478bd9Sstevel@tonic-gate for (i = 0; i < n; i++) { 295*7c478bd9Sstevel@tonic-gate (void) kt_putareg(t, kt->k_tid, 296*7c478bd9Sstevel@tonic-gate pdp->pd_nvdata[i].pnv_name, 297*7c478bd9Sstevel@tonic-gate pdp->pd_nvdata[i].pnv_value); 298*7c478bd9Sstevel@tonic-gate } 299*7c478bd9Sstevel@tonic-gate 300*7c478bd9Sstevel@tonic-gate mdb_free(pdp, pd_size); 301*7c478bd9Sstevel@tonic-gate 302*7c478bd9Sstevel@tonic-gate } else if (mdb_tgt_readsym(t, MDB_TGT_AS_VIRT, &addr, sizeof (addr), 303*7c478bd9Sstevel@tonic-gate MDB_TGT_OBJ_EXEC, "panic_reg") == sizeof (addr) && addr != NULL && 304*7c478bd9Sstevel@tonic-gate mdb_tgt_vread(t, ®s, sizeof (regs), addr) == sizeof (regs)) { 305*7c478bd9Sstevel@tonic-gate 306*7c478bd9Sstevel@tonic-gate kregs[KREG_SAVFP] = regs.r_savfp; 307*7c478bd9Sstevel@tonic-gate kregs[KREG_SAVPC] = regs.r_savpc; 308*7c478bd9Sstevel@tonic-gate kregs[KREG_EAX] = regs.r_eax; 309*7c478bd9Sstevel@tonic-gate kregs[KREG_EBX] = regs.r_ebx; 310*7c478bd9Sstevel@tonic-gate kregs[KREG_ECX] = regs.r_ecx; 311*7c478bd9Sstevel@tonic-gate kregs[KREG_EDX] = regs.r_edx; 312*7c478bd9Sstevel@tonic-gate kregs[KREG_ESI] = regs.r_esi; 313*7c478bd9Sstevel@tonic-gate kregs[KREG_EDI] = regs.r_edi; 314*7c478bd9Sstevel@tonic-gate kregs[KREG_EBP] = regs.r_ebp; 315*7c478bd9Sstevel@tonic-gate kregs[KREG_ESP] = regs.r_esp; 316*7c478bd9Sstevel@tonic-gate kregs[KREG_CS] = regs.r_cs; 317*7c478bd9Sstevel@tonic-gate kregs[KREG_DS] = regs.r_ds; 318*7c478bd9Sstevel@tonic-gate kregs[KREG_SS] = regs.r_ss; 319*7c478bd9Sstevel@tonic-gate kregs[KREG_ES] = regs.r_es; 320*7c478bd9Sstevel@tonic-gate kregs[KREG_FS] = regs.r_fs; 321*7c478bd9Sstevel@tonic-gate kregs[KREG_GS] = regs.r_gs; 322*7c478bd9Sstevel@tonic-gate kregs[KREG_EFLAGS] = regs.r_efl; 323*7c478bd9Sstevel@tonic-gate kregs[KREG_EIP] = regs.r_eip; 324*7c478bd9Sstevel@tonic-gate kregs[KREG_UESP] = regs.r_uesp; 325*7c478bd9Sstevel@tonic-gate kregs[KREG_TRAPNO] = regs.r_trapno; 326*7c478bd9Sstevel@tonic-gate kregs[KREG_ERR] = regs.r_err; 327*7c478bd9Sstevel@tonic-gate 328*7c478bd9Sstevel@tonic-gate } else if (mdb_tgt_readsym(t, MDB_TGT_AS_VIRT, &label, sizeof (label), 329*7c478bd9Sstevel@tonic-gate MDB_TGT_OBJ_EXEC, "panic_regs") == sizeof (label)) { 330*7c478bd9Sstevel@tonic-gate 331*7c478bd9Sstevel@tonic-gate kregs[KREG_EDI] = label.val[0]; 332*7c478bd9Sstevel@tonic-gate kregs[KREG_ESI] = label.val[1]; 333*7c478bd9Sstevel@tonic-gate kregs[KREG_EBX] = label.val[2]; 334*7c478bd9Sstevel@tonic-gate kregs[KREG_EBP] = label.val[3]; 335*7c478bd9Sstevel@tonic-gate kregs[KREG_ESP] = label.val[4]; 336*7c478bd9Sstevel@tonic-gate kregs[KREG_EIP] = label.val[5]; 337*7c478bd9Sstevel@tonic-gate 338*7c478bd9Sstevel@tonic-gate } else { 339*7c478bd9Sstevel@tonic-gate warn("failed to read panicbuf, panic_reg and panic_regs -- " 340*7c478bd9Sstevel@tonic-gate "current register set will be unavailable\n"); 341*7c478bd9Sstevel@tonic-gate } 342*7c478bd9Sstevel@tonic-gate } 343