const mdb_modinfo_t * _mdb_init(void) { GElf_Sym sym; if (mdb_lookup_by_name("ipp_action_byid", &sym) == -1) { mdb_warn("failed to lookup 'ipp_action_byid'"); return (NULL); } ipp_action_byid = (uintptr_t)sym.st_value; if (mdb_lookup_by_name("ipp_mod_byid", &sym) == -1) { mdb_warn("failed to lookup 'ipp_mod_byid'"); return (NULL); } ipp_mod_byid = (uintptr_t)sym.st_value; return (&ipp_modinfo); }
/* * Convert from ticks to milliseconds. */ static uint64_t tick2msec(uint64_t tick) { static int tick_per_msec; static int msec_per_tick; static int once; if (once == 0) { if (mdb_readvar(&tick_per_msec, "tick_per_msec") == -1) { mdb_warn("cannot read symbol tick_per_msec"); return (0); } if (mdb_readvar(&msec_per_tick, "msec_per_tick") == -1) { mdb_warn("cannot read symbol msec_per_tick"); return (0); } once++; } return (tick_per_msec ? tick / tick_per_msec : tick * msec_per_tick); }
int kmdb_dpi_brkpt_arm(uintptr_t addr, mdb_instr_t *instrp) { int rc; if ((rc = mdb.m_dpi->dpo_brkpt_arm(addr, instrp)) < 0) mdb_warn("failed to arm breakpoint at %a", addr); mdb_dprintf(MDB_DBG_DPI, "brkpt armed at %p %A\n", (void *)addr, addr); return (rc); }
/* * Walk the NCA node fanout table; `wsp->walk_data' is used to keep * track of the number of indicies that are left to walk so we know * when to stop. */ static int nca_nodef_walk_step(mdb_walk_state_t *wsp) { nodef_t nodef; node_t node; int status; intptr_t i = (intptr_t)wsp->walk_data; if (i-- <= 0) return (WALK_DONE); if (mdb_vread(&nodef, sizeof (nodef_t), wsp->walk_addr) == -1) { mdb_warn("cannot read nodef_t at %p", wsp->walk_addr); return (WALK_ERR); } status = wsp->walk_callback(wsp->walk_addr, &nodef, wsp->walk_cbdata); wsp->walk_data = (void *)i; wsp->walk_addr += sizeof (nodef_t); if (nodef.head != NULL) { /* * Point to the node_t instead of the nodef_t so that output * can be piped to ::nca_node dcmd. */ if (mdb_vread(&node, sizeof (node), (uintptr_t)nodef.head) == -1) { mdb_warn("cannot read node_t at %p", nodef.head); return (WALK_ERR); } status = wsp->walk_callback((uintptr_t)nodef.head, &node, wsp->walk_cbdata); } else { status = WALK_NEXT; } return (status); }
/*ARGSUSED*/ static int idt(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) { int i; if (!(flags & DCMD_ADDRSPEC)) { GElf_Sym idt0_va; gate_desc_t *idt0; if (mdb_lookup_by_name("idt0", &idt0_va) < 0) { mdb_warn("failed to find VA of idt0"); return (DCMD_ERR); } addr = idt0_va.st_value; if (mdb_vread(&idt0, sizeof (idt0), addr) != sizeof (idt0)) { mdb_warn("failed to read idt0 at %p\n", addr); return (DCMD_ERR); } addr = (uintptr_t)idt0; } for (i = 0; i < NIDT; i++, addr += sizeof (gate_desc_t)) { gate_desc_t gate; char label[6]; if (mdb_vread(&gate, sizeof (gate_desc_t), addr) != sizeof (gate_desc_t)) { mdb_warn("failed to read gate descriptor at %p\n", addr); return (DCMD_ERR); } (void) mdb_snprintf(label, sizeof (label), "%3d: ", i); gate_desc_dump(&gate, label, i == 0); } return (DCMD_OK); }
/*ARGSUSED*/ int stacks_thread_cb(uintptr_t addr, const void *ignored, void *cbarg) { stacks_info_t *sip = cbarg; findstack_info_t *fsip = &sip->si_fsi; stacks_entry_t **sepp, *nsep, *sep; int idx; size_t depth; if (stacks_findstack(addr, fsip, 0) != DCMD_OK && fsip->fsi_failed == FSI_FAIL_BADTHREAD) { mdb_warn("couldn't read thread at %p\n", addr); return (WALK_NEXT); } sip->si_count++; depth = fsip->fsi_depth; nsep = mdb_zalloc(STACKS_ENTRY_SIZE(depth), UM_SLEEP); nsep->se_thread = addr; nsep->se_sp = fsip->fsi_sp; nsep->se_sobj_ops = fsip->fsi_sobj_ops; nsep->se_tstate = fsip->fsi_tstate; nsep->se_count = 1; nsep->se_overflow = fsip->fsi_overflow; nsep->se_depth = depth; nsep->se_failed = fsip->fsi_failed; nsep->se_panic = fsip->fsi_panic; for (idx = 0; idx < depth; idx++) nsep->se_stack[idx] = fsip->fsi_stack[idx]; for (sepp = &sip->si_hash[stacks_hash_entry(nsep)]; (sep = *sepp) != NULL; sepp = &sep->se_next) { if (stacks_entry_comp_impl(sep, nsep, 0) != 0) continue; nsep->se_dup = sep->se_dup; sep->se_dup = nsep; sep->se_count++; return (WALK_NEXT); } nsep->se_next = NULL; *sepp = nsep; sip->si_entries++; return (WALK_NEXT); }
static int sv_gclient_winit(mdb_walk_state_t *wsp) { if (wsp->walk_addr == NULL && mdb_readvar(&wsp->walk_addr, "sv_gclients") == -1) { mdb_warn("unable to read 'sv_gclients'"); return (WALK_ERR); } wsp->walk_data = mdb_zalloc(sizeof (sv_gclient_t), UM_SLEEP); return (WALK_NEXT); }
static int stmf_sbd_it(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) { uint_t verbose = FALSE; sbd_lu_t slu; stmf_sbd_cb_t cb_st = {0}; if (!(flags & DCMD_ADDRSPEC)) return (DCMD_USAGE); if (mdb_getopts(argc, argv, 'v', MDB_OPT_SETBITS, TRUE, &verbose, NULL) != argc) return (DCMD_USAGE); if (verbose) { cb_st.flag |= STMF_SBD_VERBOSE; mdb_printf("\nLU:- %p\n", addr); } /* If address of pgr_key is given, just print that key and return */ if (mdb_vread(&slu, sizeof (sbd_lu_t), addr) == -1) { mdb_warn("failed to read sbd_lu at %p\n", addr); return (DCMD_ERR); } /* Just a sanity check, not necessarily needed */ if (slu.sl_it_list == NULL) { if (verbose) mdb_printf("sbd_it_list is empty\n", addr); return (DCMD_OK); } if (mdb_pwalk("stmf_sbd_it", (mdb_walk_cb_t)stmf_sbd_it_cb, &cb_st, (uintptr_t)slu.sl_it_list) == -1) { mdb_warn("failed to walk sbd_lu_it_list\n"); return (DCMD_ERR); } return (DCMD_OK); }
int rctl_val_walk_init(mdb_walk_state_t *wsp) { rctl_t rctl; if (mdb_vread(&rctl, sizeof (rctl_t), wsp->walk_addr) == -1) { mdb_warn("failed to read rctl at %p", wsp->walk_addr); return (WALK_ERR); } wsp->walk_addr = (uintptr_t)rctl.rc_values; wsp->walk_data = rctl.rc_values; return (WALK_NEXT); }
static int walk_thread_info_step(mdb_walk_state_t *wsp) { uintptr_t addr = wsp->walk_addr; thread_info_t ti; if (mdb_vread(&ti, sizeof (ti), addr) == -1) { mdb_warn("unable to read thread_info_t at %p", addr); return (WALK_ERR); } return (wsp->walk_callback(addr, &ti, wsp->walk_cbdata)); }
int sysevent_pend_walk_init(mdb_walk_state_t *wsp) { if (wsp->walk_addr == NULL) { if (mdb_readvar(&wsp->walk_addr, "log_eventq_head") == -1) { mdb_warn("failed to read 'log_eventq_head'"); return (WALK_ERR); } } wsp->walk_data = mdb_alloc(sizeof (log_eventq_t), UM_SLEEP); return (WALK_NEXT); }
int sysevent_channel_walk_init(mdb_walk_state_t *wsp) { channel_walk_data_t *ch_walker; if (wsp->walk_addr != NULL) { mdb_warn("sysevent_channel supports only global walks"); return (WALK_ERR); } ch_walker = mdb_zalloc(sizeof (channel_walk_data_t), UM_SLEEP); if (mdb_readvar(ch_walker->hash_tbl, "registered_channels") == -1) { mdb_warn("failed to read 'registered_channels'"); return (WALK_ERR); } wsp->walk_addr = (uintptr_t)ch_walker->hash_tbl[0]; wsp->walk_data = ch_walker; return (WALK_NEXT); }
static int kp_setcontext(mdb_tgt_t *t, void *context) { kp_data_t *kp = t->t_data; if (kp->kp_proc != context) { mdb_tgt_destroy(t); return (mdb_tgt_setcontext(mdb.m_target, context)); } mdb_warn("debugger context is already set to proc %p\n", context); return (0); }
/* ARGSUSED */ static int ii(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) { int maj, min, mic, baseline, i; if (argc != 0) return (DCMD_USAGE); if (mdb_readvar(&maj, "dsw_major_rev") == -1) { mdb_warn("unable to read 'dsw_major_rev'"); return (DCMD_ERR); } if (mdb_readvar(&min, "dsw_minor_rev") == -1) { mdb_warn("unable to read 'dsw_minor_rev'"); return (DCMD_ERR); } if (mdb_readvar(&mic, "dsw_micro_rev") == -1) { mdb_warn("unable to read 'dsw_micro_rev'"); return (DCMD_ERR); } if (mdb_readvar(&baseline, "dsw_baseline_rev") == -1) { mdb_warn("unable to read 'dsw_baseline_rev'"); return (DCMD_ERR); } mdb_printf("Point-in-Time Copy module version: kernel %d.%d.%d.%d; " "mdb %d.%d.%d.%d\n", maj, min, mic, baseline, ISS_VERSION_MAJ, ISS_VERSION_MIN, ISS_VERSION_MIC, ISS_VERSION_NUM); mdb_inc_indent(4); ii_get_print(ii_debug, "debug", "%d", i); ii_get_print(ii_bitmap, "bitmaps", "%d", i); mdb_dec_indent(4); return (DCMD_OK); }
int icmp_stacks_walk_step(mdb_walk_state_t *wsp) { uintptr_t kaddr; netstack_t nss; if (mdb_vread(&nss, sizeof (nss), wsp->walk_addr) == -1) { mdb_warn("can't read netstack at %p", wsp->walk_addr); return (WALK_ERR); } kaddr = (uintptr_t)nss.netstack_modules[NS_ICMP]; return (wsp->walk_callback(kaddr, wsp->walk_layer, wsp->walk_cbdata)); }
int cyccpu_walk_step(mdb_walk_state_t *wsp) { uintptr_t addr = (uintptr_t)((cpu_t *)wsp->walk_layer)->cpu_cyclic; cyc_cpu_t cpu; if (mdb_vread(&cpu, sizeof (cpu), addr) == -1) { mdb_warn("couldn't read cyc_cpu at %p", addr); return (WALK_ERR); } return (wsp->walk_callback(addr, &cpu, wsp->walk_cbdata)); }
static int buf_walk_init(mdb_walk_state_t *wsp) { fmd_buf_hash_t bh; if (mdb_vread(&bh, sizeof (bh), wsp->walk_addr) != sizeof (bh)) { mdb_warn("failed to read fmd_buf_hash_t at %p", wsp->walk_addr); return (WALK_ERR); } return (hash_walk_init(wsp, (uintptr_t)bh.bh_hash, bh.bh_hashlen, "fmd_buf", sizeof (fmd_buf_t), OFFSETOF(fmd_buf_t, buf_next))); }
static int fmd_ustat(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) { if (!(flags & DCMD_ADDRSPEC)) { struct fmd_cmd_data ud; ud.argc = argc; ud.argv = argv; if (mdb_walk("fmd_module", module_ustat, &ud) == -1) { mdb_warn("failed to walk 'fmd_module'"); return (DCMD_ERR); } return (DCMD_OK); } if (mdb_pwalk_dcmd("fmd_ustat", "fmd_stat", argc, argv, addr) != 0) { mdb_warn("failed to walk fmd_ustat at %p", addr); return (DCMD_ERR); } return (DCMD_OK); }
static int mod_walk_init(mdb_walk_state_t *wsp) { fmd_t F; if (mdb_readvar(&F, "fmd") != sizeof (F)) { mdb_warn("failed to read fmd meta-data"); return (WALK_ERR); } wsp->walk_addr = (uintptr_t)F.d_mod_list.l_next; return (WALK_NEXT); }
static int tmq_walk_init(mdb_walk_state_t *wsp) { fmd_timerq_t tmq; fmd_t F; if (wsp->walk_addr == NULL && mdb_readvar(&F, "fmd") != sizeof (F)) { mdb_warn("failed to read fmd meta-data"); return (WALK_ERR); } if (wsp->walk_addr == NULL) wsp->walk_addr = (uintptr_t)F.d_timers; if (mdb_vread(&tmq, sizeof (tmq), wsp->walk_addr) != sizeof (tmq)) { mdb_warn("failed to read timerq at %p", wsp->walk_addr); return (WALK_ERR); } wsp->walk_addr = (uintptr_t)tmq.tmq_list.l_next; return (WALK_NEXT); }
static int ustat_walk_init(mdb_walk_state_t *wsp) { fmd_ustat_t us; if (mdb_vread(&us, sizeof (us), wsp->walk_addr) != sizeof (us)) { mdb_warn("failed to read fmd_ustat_t at %p", wsp->walk_addr); return (WALK_ERR); } return (hash_walk_init(wsp, (uintptr_t)us.us_hash, us.us_hashlen, NULL, 0, 0)); }
/*ARGSUSED*/ int zid2zone(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) { if (!(flags & DCMD_ADDRSPEC) || argc != 0) return (DCMD_USAGE); if (mdb_walk("zone", (mdb_walk_cb_t)zid_lookup_cb, &addr) == -1) { mdb_warn("failed to walk zone"); return (DCMD_ERR); } return (DCMD_OK); }
static int asru_walk_init(mdb_walk_state_t *wsp) { fmd_asru_hash_t ah; fmd_t F; if (wsp->walk_addr == NULL && mdb_readvar(&F, "fmd") != sizeof (F)) { mdb_warn("failed to read fmd meta-data"); return (WALK_ERR); } if (wsp->walk_addr == NULL) wsp->walk_addr = (uintptr_t)F.d_asrus; if (mdb_vread(&ah, sizeof (ah), wsp->walk_addr) != sizeof (ah)) { mdb_warn("failed to read asru_hash at %p", wsp->walk_addr); return (WALK_ERR); } return (hash_walk_init(wsp, (uintptr_t)ah.ah_hash, ah.ah_hashlen, "fmd_asru", sizeof (fmd_asru_t), OFFSETOF(fmd_asru_t, asru_next))); }
int cmd_nmadd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) { uintptr_t opt_e = 0, opt_s = 0; uint_t opt_f = FALSE, opt_o = FALSE; GElf_Sym sym; int i; if (!(flags & DCMD_ADDRSPEC)) return (DCMD_USAGE); i = mdb_getopts(argc, argv, 'f', MDB_OPT_SETBITS, TRUE, &opt_f, 'o', MDB_OPT_SETBITS, TRUE, &opt_o, 'e', MDB_OPT_UINTPTR, &opt_e, 's', MDB_OPT_UINTPTR, &opt_s, NULL); if (i != (argc - 1) || argv[i].a_type != MDB_TYPE_STRING || argv[i].a_un.a_str[0] == '-' || argv[i].a_un.a_str[0] == '+') return (DCMD_USAGE); if (opt_e && opt_e < addr) { mdb_warn("end (%p) is less than start address (%p)\n", (void *)opt_e, (void *)addr); return (DCMD_USAGE); } if (mdb_gelf_symtab_lookup_by_name(mdb.m_prsym, argv[i].a_un.a_str, &sym, NULL) == -1) { bzero(&sym, sizeof (sym)); sym.st_info = GELF_ST_INFO(STB_GLOBAL, STT_NOTYPE); } if (opt_f) sym.st_info = GELF_ST_INFO(STB_GLOBAL, STT_FUNC); if (opt_o) sym.st_info = GELF_ST_INFO(STB_GLOBAL, STT_OBJECT); if (opt_e) sym.st_size = (GElf_Xword)(opt_e - addr); if (opt_s) sym.st_size = (GElf_Xword)(opt_s); sym.st_value = (GElf_Addr)addr; mdb_gelf_symtab_insert(mdb.m_prsym, argv[i].a_un.a_str, &sym); mdb_iob_printf(mdb.m_out, "added %s, value=%llr size=%llr\n", argv[i].a_un.a_str, sym.st_value, sym.st_size); return (DCMD_OK); }
/*ARGSUSED*/ static int py_stack(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) { uint_t verbose = FALSE; if (mdb_getopts(argc, argv, 'v', MDB_OPT_SETBITS, TRUE, &verbose, NULL) != argc) return (DCMD_USAGE); if (flags & DCMD_PIPE_OUT) { mdb_warn("py_stack cannot output into a pipe\n"); return (DCMD_ERR); } if (flags & DCMD_ADDRSPEC) { mdb_arg_t nargv; uint_t nargc = verbose ? 1 : 0; nargv.a_type = MDB_TYPE_STRING; nargv.a_un.a_str = "-v"; if (mdb_pwalk_dcmd("pyframe", "pyframe", nargc, &nargv, addr) == -1) { mdb_warn("can't walk 'pyframe'"); return (DCMD_ERR); } return (DCMD_OK); } if (mdb_walk("pyinterp", (mdb_walk_cb_t)python_thread, &verbose) == -1) { mdb_warn("can't walk 'pyinterp'"); return (DCMD_ERR); } return (DCMD_OK); }
int snode_walk_init(mdb_walk_state_t *wsp) { int stablesz; GElf_Sym sym; uintptr_t stable; uintptr_t sp; snode_walk_data_t *sw; if (mdb_readvar(&stablesz, "stablesz") == -1) { mdb_warn("failed to read 'stablesz'"); return (WALK_ERR); } if (stablesz == 0) return (WALK_DONE); if (mdb_lookup_by_name("stable", &sym) == -1) { mdb_warn("failed to read 'stable'"); return (WALK_ERR); } stable = (uintptr_t)sym.st_value; if (mdb_vread(&sp, sizeof (sp), stable) == -1) { mdb_warn("failed to read stable entry at %p", stable); return (WALK_DONE); } sw = mdb_alloc(sizeof (snode_walk_data_t), UM_SLEEP); sw->sw_stablesz = stablesz; sw->sw_stable = stable; wsp->walk_addr = sp; wsp->walk_data = sw; return (WALK_NEXT); }
static int serd_walk_init(mdb_walk_state_t *wsp) { fmd_serd_hash_t sh; if (mdb_vread(&sh, sizeof (sh), wsp->walk_addr) != sizeof (sh)) { mdb_warn("failed to read fmd_serd_hash at %p", wsp->walk_addr); return (WALK_ERR); } return (hash_walk_init(wsp, (uintptr_t)sh.sh_hash, sh.sh_hashlen, "fmd_serd_eng", sizeof (fmd_serd_eng_t), OFFSETOF(fmd_serd_eng_t, sg_next))); }
static int netstat_print_conn(const char *cache, int proto, mdb_walk_cb_t cbfunc, void *cbdata) { netstat_cb_data_t *ncb = cbdata; if ((ncb->opts & NETSTAT_VERBOSE) && proto == IPPROTO_TCP) netstat_tcp_verbose_header_pr(); if (mdb_walk(cache, cbfunc, cbdata) == -1) { mdb_warn("failed to walk %s", cache); return (DCMD_ERR); } return (DCMD_OK); }
/* * Get the address of the unique uberdata_t structure. */ static uintptr_t uberdata_addr(void) { uintptr_t uaddr; uintptr_t addr; GElf_Sym sym; if (mdb_lookup_by_obj("libc.so.1", "_tdb_bootstrap", &sym) != 0) { mdb_warn("cannot find libc.so.1`_tdb_bootstrap"); return (NULL); } if (mdb_vread(&addr, sizeof (addr), sym.st_value) == sizeof (addr) && addr != NULL && mdb_vread(&uaddr, sizeof (uaddr), addr) == sizeof (uaddr) && uaddr != NULL) { return (uaddr); } if (mdb_lookup_by_obj("libc.so.1", "_uberdata", &sym) != 0) { mdb_warn("cannot find libc.so.1`_uberdata"); return (NULL); } return ((uintptr_t)sym.st_value); }
/*ARGSUSED*/ static int d_sigjmp_buf(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) { #if defined(__sparc) struct { int sjs_flags; greg_t sjs_sp; greg_t sjs_pc; greg_t sjs_fp; greg_t sjs_i7; ucontext_t *sjs_uclink; ulong_t sjs_pad[_JBLEN - 6]; sigset_t sjs_sigmask; #if defined(_LP64) greg_t sjs_asi; greg_t sjs_fprs; #endif stack_t sjs_stack; } s; if (argc != 0) return (DCMD_USAGE); if (mdb_vread(&s, sizeof (s), addr) != sizeof (s)) { mdb_warn("failed to read sigjmp_buf at %p", addr); return (DCMD_ERR); } mdb_printf(" flags = 0x%x\n", s.sjs_flags); mdb_printf(" %%sp = 0x%lx %lA\n", s.sjs_sp, s.sjs_sp); mdb_printf(" %%pc = 0x%lx %lA\n", s.sjs_pc, s.sjs_pc); mdb_printf(" %%fp = 0x%lx %lA\n", s.sjs_fp, s.sjs_fp); mdb_printf(" %%i7 = 0x%lx %lA\n", s.sjs_i7, s.sjs_i7); mdb_printf(" uclink = %p\n", s.sjs_uclink); mdb_printf(" sigset = 0x%08x 0x%08x 0x%08x 0x%08x\n", s.sjs_sigmask.__sigbits[0], s.sjs_sigmask.__sigbits[1], s.sjs_sigmask.__sigbits[2], s.sjs_sigmask.__sigbits[3]); #if defined(_LP64) mdb_printf(" %%asi = 0x%lx\n", s.sjs_asi); mdb_printf(" %%fprs = 0x%lx\n", s.sjs_fprs); #endif mdb_printf(" stack = sp 0x%p size 0x%lx flags %s\n", s.sjs_stack.ss_sp, s.sjs_stack.ss_size, stack_flags(&s.sjs_stack)); return (DCMD_OK); #elif defined(__i386) || defined(__amd64) return (d_ucontext(addr, flags, argc, argv)); #endif }