Exemplo n.º 1
0
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);
}
Exemplo n.º 2
0
/*
 * 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);
}
Exemplo n.º 3
0
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);
}
Exemplo n.º 4
0
/*
 * 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);
}
Exemplo n.º 5
0
/*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);
}
Exemplo n.º 6
0
/*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);
}
Exemplo n.º 7
0
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);
}
Exemplo n.º 8
0
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);
}
Exemplo n.º 9
0
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);
}
Exemplo n.º 10
0
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));
}
Exemplo n.º 11
0
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);
}
Exemplo n.º 12
0
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);
}
Exemplo n.º 13
0
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);
}
Exemplo n.º 14
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);
}
Exemplo n.º 15
0
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));
}
Exemplo n.º 16
0
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));
}
Exemplo n.º 17
0
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)));
}
Exemplo n.º 18
0
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);
}
Exemplo n.º 19
0
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);
}
Exemplo n.º 20
0
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);
}
Exemplo n.º 21
0
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));
}
Exemplo n.º 22
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);
}
Exemplo n.º 23
0
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)));
}
Exemplo n.º 24
0
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);
}
Exemplo n.º 25
0
/*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);
}
Exemplo n.º 26
0
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);
}
Exemplo n.º 27
0
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)));
}
Exemplo n.º 28
0
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);
}
Exemplo n.º 29
0
/*
 * 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);
}
Exemplo n.º 30
0
/*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
}