Example #1
0
void
_mdb_fini(void)
{
	GElf_Sym sym;

	if (mdb_lookup_by_obj("ptm", "ptmwint", &sym) == 0)
		mdb_qops_remove(&ptm_qops, (uintptr_t)sym.st_value);
	if (mdb_lookup_by_obj("pts", "ptswint", &sym) == 0)
		mdb_qops_remove(&pts_qops, (uintptr_t)sym.st_value);
}
Example #2
0
const mdb_modinfo_t *
_mdb_init(void)
{
	GElf_Sym sym;

	if (mdb_lookup_by_obj("ptm", "ptmwint", &sym) == 0)
		mdb_qops_install(&ptm_qops, (uintptr_t)sym.st_value);
	if (mdb_lookup_by_obj("pts", "ptswint", &sym) == 0)
		mdb_qops_install(&pts_qops, (uintptr_t)sym.st_value);

	return (&modinfo);
}
Example #3
0
int
sonode_walk_init(mdb_walk_state_t *wsp)
{
	if (wsp->walk_addr == 0) {
		GElf_Sym sym;
		struct socklist *slp;

		if (mdb_lookup_by_obj("sockfs", "socklist", &sym) == -1) {
			mdb_warn("failed to lookup sockfs`socklist");
			return (WALK_ERR);
		}

		slp = (struct socklist *)(uintptr_t)sym.st_value;

		if (mdb_vread(&wsp->walk_addr, sizeof (wsp->walk_addr),
		    (uintptr_t)&slp->sl_list) == -1) {
			mdb_warn("failed to read address of initial sonode "
			    "at %p", &slp->sl_list);
			return (WALK_ERR);
		}
	}

	wsp->walk_data = mdb_alloc(sizeof (struct sotpi_sonode), UM_SLEEP);
	return (WALK_NEXT);
}
Example #4
0
int
uutil_listpool_walk_init(mdb_walk_state_t *wsp)
{
	uu_list_pool_t null_lpool;
	uutil_listpool_walk_t *ulpw;
	GElf_Sym sym;

	bzero(&null_lpool, sizeof (uu_list_pool_t));

	if (mdb_lookup_by_obj("libuutil.so.1", "uu_null_lpool", &sym) ==
	    -1) {
		mdb_warn("failed to find 'uu_null_lpool'\n");
		return (WALK_ERR);
	}

	if (mdb_vread(&null_lpool, sym.st_size, (uintptr_t)sym.st_value) ==
	    -1) {
		mdb_warn("failed to read data from 'uu_null_lpool' address\n");
		return (WALK_ERR);
	}

	ulpw = mdb_alloc(sizeof (uutil_listpool_walk_t), UM_SLEEP);

	ulpw->ulpw_final = (uintptr_t)null_lpool.ulp_prev;
	ulpw->ulpw_current = (uintptr_t)null_lpool.ulp_next;
	wsp->walk_data = ulpw;

	return (WALK_NEXT);
}
Example #5
0
static int
xhci_mdb_walk_xhci_init(mdb_walk_state_t *wsp)
{
	GElf_Sym sym;
	uintptr_t addr;

	if (wsp->walk_addr != 0) {
		mdb_warn("::walk xhci only supports global walks\n");
		return (WALK_ERR);
	}

	if (mdb_lookup_by_obj("xhci", "xhci_soft_state", &sym) != 0) {
		mdb_warn("failed to find xhci_soft_state symbol");
		return (WALK_ERR);
	}

	if (mdb_vread(&addr, sizeof (addr), sym.st_value) != sizeof (addr)) {
		mdb_warn("failed to read xhci_soft_state at %p", addr);
		return (WALK_ERR);
	}

	wsp->walk_addr = addr;
	if (mdb_layered_walk("softstate", wsp) != 0) {
		mdb_warn("failed to walk softstate");
		return (WALK_ERR);
	}

	return (WALK_NEXT);
}
Example #6
0
/*
 * To further confuse the issue, this dmod can run against either
 * libumem.so.1 *or* the libstandumem.so linked into kmdb(1M).  To figure
 * out which one we are working against, we look up "umem_alloc" in both
 * libumem.so and the executable.
 *
 * A further wrinkle is that libumem.so may not yet be loaded into the
 * process' address space.  That can lead to either the lookup failing, or
 * being unable to read from the data segment.  We treat either case as
 * an error.
 */
int
umem_set_standalone(void)
{
	GElf_Sym sym;
	int ready;

	if (mdb_lookup_by_obj(UMEM_OBJNAME, "umem_alloc", &sym) == 0)
		umem_is_standalone = 0;
	else if (mdb_lookup_by_obj(MDB_OBJ_EXEC, "umem_alloc", &sym) == 0)
		umem_is_standalone = 1;
	else
		return (-1);

	/*
	 * now that we know where things should be, make sure we can actually
	 * read things out.
	 */
	if (umem_readvar(&ready, "umem_ready") == -1)
		return (-1);
	return (0);
}
Example #7
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);
}
Example #8
0
int
mdb_lookup_by_name(const char *name, GElf_Sym *sym)
{
	return (mdb_lookup_by_obj(MDB_TGT_OBJ_EXEC, name, sym));
}
Example #9
0
static int
dladm_show_bridge(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
{
	show_bridge_args_t *args;
	GElf_Sym sym;
	int i;

	args = mdb_zalloc(sizeof (*args), UM_SLEEP);

	i = mdb_getopts(argc, argv,
	    'l', MDB_OPT_SETBITS, 1, &args->opt_l,
	    'f', MDB_OPT_SETBITS, 1, &args->opt_f,
	    't', MDB_OPT_SETBITS, 1, &args->opt_t,
	    NULL);

	argc -= i;
	argv += i;

	if (argc > 1 || (argc == 1 && argv[0].a_type != MDB_TYPE_STRING)) {
		mdb_free(args, sizeof (*args));
		return (DCMD_USAGE);
	}
	if (argc == 1)
		args->name = argv[0].a_un.a_str;

	if ((args->lbolt = mdb_get_lbolt()) == -1) {
		mdb_warn("failed to read lbolt");
		goto err;
	}

	if (flags & DCMD_ADDRSPEC) {
		if (args->name != NULL) {
			mdb_printf("bridge name and address are mutually "
			    "exclusive\n");
			goto err;
		}
		if (!args->opt_l && !args->opt_f && !args->opt_t)
			mdb_printf("%-?s %-7s %-16s %-7s %-7s\n", "ADDR",
			    "PROTECT", "NAME", "NLINKS", "NFWD");
		if (do_show_bridge(addr, NULL, args) != WALK_NEXT)
			goto err;
		mdb_free(args, sizeof (*args));
		return (DCMD_OK);
	} else {
		if ((args->opt_l || args->opt_f || args->opt_t) &&
		    args->name == NULL) {
			mdb_printf("need bridge name or address with -[lft]\n");
			goto err;
		}
		if (mdb_lookup_by_obj("bridge", "inst_list", &sym) == -1) {
			mdb_warn("failed to find 'bridge`inst_list'");
			goto err;
		}
		if (!args->opt_l && !args->opt_f && !args->opt_t)
			mdb_printf("%-?s %-7s %-16s %-7s %-7s %-7s %s\n",
			    "ADDR", "PROTECT", "NAME", "NLINKS", "NFWD",
			    "NNICKS", "NICK");
		if (mdb_pwalk("list", do_show_bridge, args,
		    (uintptr_t)sym.st_value) != DCMD_OK)
			goto err;
		if (!args->found && args->name != NULL) {
			mdb_printf("bridge instance %s not found\n",
			    args->name);
			goto err;
		}
		mdb_free(args, sizeof (*args));
		return (DCMD_OK);
	}

err:
	mdb_free(args, sizeof (*args));
	return (DCMD_ERR);
}
Example #10
0
/* ARGSUSED */
int
memstat(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
{
	pgcnt_t total_pages, physmem;
	ulong_t freemem;
	memstat_t stats;
	GElf_Sym sym;
	vn_htable_t ht;
	struct vnode *kvps;
	uintptr_t vn_size = 0;
#if defined(__i386) || defined(__amd64)
	bln_stats_t bln_stats;
	ssize_t bln_size;
#endif

	bzero(&stats, sizeof (memstat_t));

	/*
	 * -s size, is an internal option. It specifies the size of vn_htable.
	 * Hash table size is set in the following order:
	 * If user has specified the size that is larger than VN_LARGE: try it,
	 * but if malloc failed default to VN_SMALL. Otherwise try VN_LARGE, if
	 * failed to allocate default to VN_SMALL.
	 * For a better efficiency of hash table it is highly recommended to
	 * set size to a prime number.
	 */
	if ((flags & DCMD_ADDRSPEC) || mdb_getopts(argc, argv,
	    's', MDB_OPT_UINTPTR, &vn_size, NULL) != argc)
		return (DCMD_USAGE);

	/* Initialize vnode hash list and queue */
	vn_htable_init(&ht, vn_size);
	stats.ms_vn_htable = &ht;

	/* Total physical memory */
	if (mdb_readvar(&total_pages, "total_pages") == -1) {
		mdb_warn("unable to read total_pages");
		return (DCMD_ERR);
	}

	/* Artificially limited memory */
	if (mdb_readvar(&physmem, "physmem") == -1) {
		mdb_warn("unable to read physmem");
		return (DCMD_ERR);
	}

	/* read kernel vnode array pointer */
	if (mdb_lookup_by_obj(MDB_OBJ_EXEC, "kvps",
	    (GElf_Sym *)&sym) == -1) {
		mdb_warn("unable to read kvps");
		return (DCMD_ERR);
	}
	kvps = (struct vnode *)(uintptr_t)sym.st_value;
	stats.ms_kvp =  &kvps[KV_KVP];

	/*
	 * Read the zio vnode pointer.
	 */
	stats.ms_zvp = &kvps[KV_ZVP];

	/*
	 * If physmem != total_pages, then the administrator has limited the
	 * number of pages available in the system.  Excluded pages are
	 * associated with the unused pages vnode.  Read this vnode so the
	 * pages can be excluded in the page accounting.
	 */
	if (mdb_lookup_by_obj(MDB_OBJ_EXEC, "unused_pages_vp",
	    (GElf_Sym *)&sym) == -1) {
		mdb_warn("unable to read unused_pages_vp");
		return (DCMD_ERR);
	}
	stats.ms_unused_vp = (struct vnode *)(uintptr_t)sym.st_value;

	/* walk all pages, collect statistics */
	if (mdb_walk("allpages", (mdb_walk_cb_t)memstat_callback,
	    &stats) == -1) {
		mdb_warn("can't walk memseg");
		return (DCMD_ERR);
	}

#define	MS_PCT_TOTAL(x)	((ulong_t)((((5 * total_pages) + ((x) * 1000ull))) / \
		((physmem) * 10)))

	mdb_printf("Page Summary                Pages                MB"
	    "  %%Tot\n");
	mdb_printf("------------     ----------------  ----------------"
	    "  ----\n");
	mdb_printf("Kernel           %16llu  %16llu  %3lu%%\n",
	    stats.ms_kmem,
	    (uint64_t)stats.ms_kmem * PAGESIZE / (1024 * 1024),
	    MS_PCT_TOTAL(stats.ms_kmem));

	if (stats.ms_zfs_data != 0)
		mdb_printf("ZFS File Data    %16llu  %16llu  %3lu%%\n",
		    stats.ms_zfs_data,
		    (uint64_t)stats.ms_zfs_data * PAGESIZE / (1024 * 1024),
		    MS_PCT_TOTAL(stats.ms_zfs_data));

	mdb_printf("Anon             %16llu  %16llu  %3lu%%\n",
	    stats.ms_anon,
	    (uint64_t)stats.ms_anon * PAGESIZE / (1024 * 1024),
	    MS_PCT_TOTAL(stats.ms_anon));
	mdb_printf("Exec and libs    %16llu  %16llu  %3lu%%\n",
	    stats.ms_exec,
	    (uint64_t)stats.ms_exec * PAGESIZE / (1024 * 1024),
	    MS_PCT_TOTAL(stats.ms_exec));
	mdb_printf("Page cache       %16llu  %16llu  %3lu%%\n",
	    stats.ms_vnode,
	    (uint64_t)stats.ms_vnode * PAGESIZE / (1024 * 1024),
	    MS_PCT_TOTAL(stats.ms_vnode));
	mdb_printf("Free (cachelist) %16llu  %16llu  %3lu%%\n",
	    stats.ms_cachelist,
	    (uint64_t)stats.ms_cachelist * PAGESIZE / (1024 * 1024),
	    MS_PCT_TOTAL(stats.ms_cachelist));

	/*
	 * occasionally, we double count pages above.  To avoid printing
	 * absurdly large values for freemem, we clamp it at zero.
	 */
	if (physmem > stats.ms_total)
		freemem = physmem - stats.ms_total;
	else
		freemem = 0;

#if defined(__i386) || defined(__amd64)
	/* Are we running under Xen?  If so, get balloon memory usage. */
	if ((bln_size = mdb_readvar(&bln_stats, "bln_stats")) != -1) {
		if (freemem > bln_stats.bln_hv_pages)
			freemem -= bln_stats.bln_hv_pages;
		else
			freemem = 0;
	}
#endif

	mdb_printf("Free (freelist)  %16lu  %16llu  %3lu%%\n", freemem,
	    (uint64_t)freemem * PAGESIZE / (1024 * 1024),
	    MS_PCT_TOTAL(freemem));

#if defined(__i386) || defined(__amd64)
	if (bln_size != -1) {
		mdb_printf("Balloon          %16lu  %16llu  %3lu%%\n",
		    bln_stats.bln_hv_pages,
		    (uint64_t)bln_stats.bln_hv_pages * PAGESIZE / (1024 * 1024),
		    MS_PCT_TOTAL(bln_stats.bln_hv_pages));
	}
#endif

	mdb_printf("\nTotal            %16lu  %16lu\n",
	    physmem,
	    (uint64_t)physmem * PAGESIZE / (1024 * 1024));

	if (physmem != total_pages) {
		mdb_printf("Physical         %16lu  %16lu\n",
		    total_pages,
		    (uint64_t)total_pages * PAGESIZE / (1024 * 1024));
	}

#undef MS_PCT_TOTAL

	return (DCMD_OK);
}
Example #11
0
ssize_t
umem_lookup_by_name(const char *name, GElf_Sym *sym)
{
	return (mdb_lookup_by_obj((umem_is_standalone ? MDB_OBJ_EXEC :
	    UMEM_OBJNAME), name, sym));
}