示例#1
0
static int
ctfsrc_member_cb(const char *member, ctf_id_t type, ulong_t off, void *arg)
{
	_NOTE(ARGUNUSED(arg));
	char name[MAX_NAMELEN];

	if (ctf_type_cname(g_fp, type, name, sizeof (name), member) == NULL) {
		if (ctf_errno(g_fp) != ECTF_NOPARENT) {
			ctfdump_fatal("type %ld missing name: %s\n", type,
			    ctf_errmsg(ctf_errno(g_fp)));
		}

		(void) snprintf(name, sizeof (name), "unknown_t %s", member);
	}

	/*
	 * A byte offset is friendlier, but we'll print bits too if it's not
	 * aligned (i.e. a bitfield).
	 */
	if (off % NBBY != 0) {
		(void) printf("\t%s; /* offset: %lu bytes (%lu bits) */\n",
		    name, off / NBBY, off);
	} else {
		(void) printf("\t%s; /* offset: %lu bytes */\n",
		    name, off / NBBY);
	}
	return (0);
}
示例#2
0
/*
 * When setting the strsize option, set the option in the dt_options array
 * using dt_opt_size() as usual, and then update the definition of the CTF
 * type for the D intrinsic "string" to be an array of the corresponding size.
 * If any errors occur, reset dt_options[option] to its previous value.
 */
static int
dt_opt_strsize(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
{
	dtrace_optval_t val = dtp->dt_options[option];
	ctf_file_t *fp = DT_STR_CTFP(dtp);
	ctf_id_t type = ctf_type_resolve(fp, DT_STR_TYPE(dtp));
	ctf_arinfo_t r;

	if (dt_opt_size(dtp, arg, option) != 0)
		return (-1); /* dt_errno is set for us */

	if (dtp->dt_options[option] > UINT_MAX) {
		dtp->dt_options[option] = val;
		return (dt_set_errno(dtp, EOVERFLOW));
	}

	if (ctf_array_info(fp, type, &r) == CTF_ERR) {
		dtp->dt_options[option] = val;
		dtp->dt_ctferr = ctf_errno(fp);
		return (dt_set_errno(dtp, EDT_CTF));
	}

	r.ctr_nelems = (uint_t)dtp->dt_options[option];

	if (ctf_set_array(fp, type, &r) == CTF_ERR ||
	    ctf_update(fp) == CTF_ERR) {
		dtp->dt_options[option] = val;
		dtp->dt_ctferr = ctf_errno(fp);
		return (dt_set_errno(dtp, EDT_CTF));
	}

	return (0);
}
示例#3
0
static void
ctfsrc_object(ctf_id_t id, const char *name)
{
	char tname[MAX_NAMELEN];

	if (ctf_type_cname(g_fp, id, tname, sizeof (tname), name) == NULL) {
		if (ctf_errno(g_fp) != ECTF_NOPARENT) {
			ctfdump_fatal("type %ld missing name: %s\n", id,
			    ctf_errmsg(ctf_errno(g_fp)));
		}
		(void) snprintf(tname, sizeof (tname), "unknown_t %s", name);
	}

	(void) printf("extern %s;\n", tname);
}
示例#4
0
int
mdb_ctf_type_iter(const char *object, mdb_ctf_type_f *cb, void *data)
{
	ctf_file_t *fp;
	mdb_tgt_t *t = mdb.m_target;
	int ret;
	type_iter_t ti;

	if (object == MDB_CTF_SYNTHETIC_ITER)
		fp = mdb.m_synth;
	else
		fp = mdb_tgt_name_to_ctf(t, object);

	if (fp == NULL)
		return (-1);

	ti.ti_cb = cb;
	ti.ti_arg = data;
	ti.ti_fp = fp;

	if ((ret = ctf_type_iter(fp, type_iter_cb, &ti)) == CTF_ERR)
		return (set_errno(ctf_to_errno(ctf_errno(fp))));

	return (ret);
}
示例#5
0
static int
ctfdump_functions_cb(const char *name, ulong_t symidx, ctf_funcinfo_t *ctc,
    void *arg)
{
	int i;

	if (ctc->ctc_argc != 0) {
		ctfdump_fargs_grow(ctc->ctc_argc);
		if (ctf_func_args(g_fp, symidx, g_nfargc, g_fargc) == CTF_ERR)
			ctfdump_fatal("failed to get arguments for function "
			    "%s: %s\n", name, ctf_errmsg(ctf_errno(g_fp)));
	}

	ctfdump_printf(CTFDUMP_FUNCTIONS,
	    "  [%lu] %s (%lu) returns: %u args: (", g_stats.cs_nfuncs, name,
	    symidx, ctc->ctc_return);
	for (i = 0; i < ctc->ctc_argc; i++)
		ctfdump_printf(CTFDUMP_FUNCTIONS, "%lu%s", g_fargc[i],
		    i + 1 == ctc->ctc_argc ? "" : ", ");
	if (ctc->ctc_flags & CTF_FUNC_VARARG)
		ctfdump_printf(CTFDUMP_FUNCTIONS, "%s...",
		    ctc->ctc_argc == 0 ? "" : ", ");
	ctfdump_printf(CTFDUMP_FUNCTIONS, ")\n");

	g_stats.cs_nfuncs++;
	g_stats.cs_nfuncargs += ctc->ctc_argc;
	g_stats.cs_nfuncmax = MAX(ctc->ctc_argc, g_stats.cs_nfuncmax);

	return (0);
}
示例#6
0
int
mdb_ctf_type_resolve(mdb_ctf_id_t mid, mdb_ctf_id_t *outp)
{
	ctf_id_t id;
	mdb_ctf_impl_t *idp = (mdb_ctf_impl_t *)&mid;

	if ((id = ctf_type_resolve(idp->mci_fp, idp->mci_id)) == CTF_ERR) {
		if (outp)
			mdb_ctf_type_invalidate(outp);
		return (set_errno(ctf_to_errno(ctf_errno(idp->mci_fp))));
	}

	if (ctf_type_kind(idp->mci_fp, id) == CTF_K_FORWARD) {
		char name[MDB_SYM_NAMLEN];
		mdb_ctf_id_t lookup_id;

		if (ctf_type_name(idp->mci_fp, id, name, sizeof (name)) !=
		    NULL &&
		    mdb_ctf_lookup_by_name(name, &lookup_id) == 0 &&
		    outp != NULL) {
			*outp = lookup_id;
			return (0);
		}
	}

	if (outp != NULL)
		set_ctf_id(outp, idp->mci_fp, id);

	return (0);
}
示例#7
0
int
mdb_ctf_func_args(const mdb_ctf_funcinfo_t *funcp, uint_t len,
    mdb_ctf_id_t *argv)
{
	ctf_file_t *fp;
	ctf_id_t cargv[32];
	int i;

	if (len > (sizeof (cargv) / sizeof (cargv[0])))
		return (set_errno(EINVAL));

	if (funcp == NULL || argv == NULL)
		return (set_errno(EINVAL));

	fp = mdb_ctf_type_file(funcp->mtf_return);

	if (ctf_func_args(fp, funcp->mtf_symidx, len, cargv) == CTF_ERR)
		return (set_errno(ctf_to_errno(ctf_errno(fp))));

	for (i = MIN(len, funcp->mtf_argc) - 1; i >= 0; i--) {
		set_ctf_id(&argv[i], fp, cargv[i]);
	}

	return (0);
}
示例#8
0
int
mdb_ctf_lookup_by_symbol(const GElf_Sym *symp, const mdb_syminfo_t *sip,
    mdb_ctf_id_t *p)
{
	ctf_file_t *fp = NULL;
	mdb_ctf_impl_t *mcip = (mdb_ctf_impl_t *)p;
	mdb_tgt_t *t = mdb.m_target;

	if (mcip == NULL)
		return (set_errno(EINVAL));

	if (symp == NULL || sip == NULL) {
		mdb_ctf_type_invalidate(p);
		return (set_errno(EINVAL));
	}

	if ((fp = mdb_tgt_addr_to_ctf(t, symp->st_value)) == NULL) {
		mdb_ctf_type_invalidate(p);
		return (-1); /* errno is set for us */
	}

	if ((mcip->mci_id = ctf_lookup_by_symbol(fp, sip->sym_id)) == CTF_ERR) {
		mdb_ctf_type_invalidate(p);
		return (set_errno(ctf_to_errno(ctf_errno(fp))));
	}

	mcip->mci_fp = fp;

	return (0);
}
示例#9
0
int
mdb_ctf_type_encoding(mdb_ctf_id_t id, ctf_encoding_t *ep)
{
	mdb_ctf_impl_t *idp = (mdb_ctf_impl_t *)&id;

	if (ctf_type_encoding(idp->mci_fp, idp->mci_id, ep) == CTF_ERR)
		return (set_errno(ctf_to_errno(ctf_errno(idp->mci_fp))));

	return (0);
}
示例#10
0
static void
ctfdump_objects(void)
{
	ctfdump_title(CTFDUMP_OBJECTS, "Data Objects");
	if (ctf_object_iter(g_fp, ctfdump_objects_cb, NULL) == CTF_ERR) {
		ctfdump_warn("failed to dump objects: %s\n",
		    ctf_errmsg(ctf_errno(g_fp)));
		g_exit = 1;
	}
}
示例#11
0
static void
ctfdump_labels(void)
{
	ctfdump_title(CTFDUMP_LABELS, "Label Table");
	if (ctf_label_iter(g_fp, ctfdump_labels_cb, NULL) == CTF_ERR) {
		ctfdump_warn("failed to dump labels: %s\n",
		    ctf_errmsg(ctf_errno(g_fp)));
		g_exit = 1;
	}
}
示例#12
0
int
mdb_ctf_type_kind(mdb_ctf_id_t id)
{
	mdb_ctf_impl_t *idp = (mdb_ctf_impl_t *)&id;
	int ret;

	if ((ret = ctf_type_kind(idp->mci_fp, idp->mci_id)) == CTF_ERR)
		return (set_errno(ctf_to_errno(ctf_errno(idp->mci_fp))));

	return (ret);
}
示例#13
0
static void
ctfdump_functions(void)
{
	ctfdump_title(CTFDUMP_FUNCTIONS, "Functions");

	if (ctf_function_iter(g_fp, ctfdump_functions_cb, NULL) == CTF_ERR) {
		ctfdump_warn("failed to dump functions: %s\n",
		    ctf_errmsg(ctf_errno(g_fp)));
		g_exit = 1;
	}
}
示例#14
0
static void
ctfdump_types(void)
{
	ctfdump_title(CTFDUMP_TYPES, "Types");

	if (ctf_type_iter(g_fp, B_TRUE, ctfdump_types_cb, NULL) == CTF_ERR) {
		ctfdump_warn("failed to dump labels: %s\n",
		    ctf_errmsg(ctf_errno(g_fp)));
		g_exit = 1;
	}
}
示例#15
0
static void
ctfsrc_refname(ctf_id_t id, char *buf, size_t bufsize)
{
	ctf_id_t ref;

	if ((ref = ctf_type_reference(g_fp, id)) == CTF_ERR) {
		ctfdump_fatal("failed to get reference type for %ld: "
		    "%s\n", id, ctf_errmsg(ctf_errno(g_fp)));
	}

	(void) ctf_type_name(g_fp, ref, buf, bufsize);
}
示例#16
0
static void
ctfdump_strings(void)
{
	ulong_t stroff = 0;

	ctfdump_title(CTFDUMP_STRINGS, "String Table");
	if (ctf_string_iter(g_fp, ctfdump_strings_cb, &stroff) == CTF_ERR) {
		ctfdump_warn("failed to dump strings: %s\n",
		    ctf_errmsg(ctf_errno(g_fp)));
		g_exit = 1;
	}
}
示例#17
0
const char *
mdb_ctf_enum_name(mdb_ctf_id_t id, int value)
{
	mdb_ctf_impl_t *idp = (mdb_ctf_impl_t *)&id;
	const char *ret;

	/* resolve the type in case there's a forward declaration */
	if (mdb_ctf_type_resolve(id, &id) != 0)
		return (NULL);

	if ((ret = ctf_enum_name(idp->mci_fp, idp->mci_id, value)) == NULL)
		(void) set_errno(ctf_to_errno(ctf_errno(idp->mci_fp)));

	return (ret);
}
示例#18
0
ssize_t
mdb_ctf_type_size(mdb_ctf_id_t id)
{
	mdb_ctf_impl_t *idp = (mdb_ctf_impl_t *)&id;
	ssize_t ret;

	/* resolve the type in case there's a forward declaration */
	if ((ret = mdb_ctf_type_resolve(id, &id)) != 0)
		return (ret);

	if ((ret = ctf_type_size(idp->mci_fp, idp->mci_id)) == CTF_ERR)
		return (set_errno(ctf_to_errno(ctf_errno(idp->mci_fp))));

	return (ret);
}
示例#19
0
int
mdb_ctf_array_info(mdb_ctf_id_t id, mdb_ctf_arinfo_t *arp)
{
	mdb_ctf_impl_t *idp = (mdb_ctf_impl_t *)&id;
	ctf_arinfo_t car;

	if (ctf_array_info(idp->mci_fp, idp->mci_id, &car) == CTF_ERR)
		return (set_errno(ctf_to_errno(ctf_errno(idp->mci_fp))));

	set_ctf_id(&arp->mta_contents, idp->mci_fp, car.ctr_contents);
	set_ctf_id(&arp->mta_index, idp->mci_fp, car.ctr_index);

	arp->mta_nelems = car.ctr_nelems;

	return (0);
}
示例#20
0
char *
mdb_ctf_type_name(mdb_ctf_id_t id, char *buf, size_t len)
{
	mdb_ctf_impl_t *idp = (mdb_ctf_impl_t *)&id;
	char *ret;

	if (!mdb_ctf_type_valid(id)) {
		(void) set_errno(EINVAL);
		return (NULL);
	}

	ret = ctf_type_name(idp->mci_fp, idp->mci_id, buf, len);
	if (ret == NULL)
		(void) set_errno(ctf_to_errno(ctf_errno(idp->mci_fp)));

	return (ret);
}
示例#21
0
int
mdb_ctf_type_reference(mdb_ctf_id_t mid, mdb_ctf_id_t *outp)
{
	mdb_ctf_impl_t *idp = (mdb_ctf_impl_t *)&mid;
	ctf_id_t id;

	if ((id = ctf_type_reference(idp->mci_fp, idp->mci_id)) == CTF_ERR) {
		if (outp)
			mdb_ctf_type_invalidate(outp);
		return (set_errno(ctf_to_errno(ctf_errno(idp->mci_fp))));
	}

	if (outp != NULL)
		set_ctf_id(outp, idp->mci_fp, id);

	return (0);
}
示例#22
0
/*ARGSUSED*/
int
mdb_ctf_func_info(const GElf_Sym *symp, const mdb_syminfo_t *sip,
    mdb_ctf_funcinfo_t *mfp)
{
	ctf_file_t *fp = NULL;
	ctf_funcinfo_t f;
	mdb_tgt_t *t = mdb.m_target;
	char name[MDB_SYM_NAMLEN];
	const mdb_map_t *mp;
	mdb_syminfo_t si;
	int err;

	if (symp == NULL || mfp == NULL)
		return (set_errno(EINVAL));

	/*
	 * In case the input symbol came from a merged or private symbol table,
	 * re-lookup the address as a symbol, and then perform a fully scoped
	 * lookup of that symbol name to get the mdb_syminfo_t for its CTF.
	 */
	if ((fp = mdb_tgt_addr_to_ctf(t, symp->st_value)) == NULL ||
	    (mp = mdb_tgt_addr_to_map(t, symp->st_value)) == NULL ||
	    mdb_tgt_lookup_by_addr(t, symp->st_value, MDB_TGT_SYM_FUZZY,
	    name, sizeof (name), NULL, NULL) != 0)
		return (-1); /* errno is set for us */

	if (strchr(name, '`') != NULL)
		err = mdb_tgt_lookup_by_scope(t, name, NULL, &si);
	else
		err = mdb_tgt_lookup_by_name(t, mp->map_name, name, NULL, &si);

	if (err != 0)
		return (-1); /* errno is set for us */

	if (ctf_func_info(fp, si.sym_id, &f) == CTF_ERR)
		return (set_errno(ctf_to_errno(ctf_errno(fp))));

	set_ctf_id(&mfp->mtf_return, fp, f.ctc_return);
	mfp->mtf_argc = f.ctc_argc;
	mfp->mtf_flags = f.ctc_flags;
	mfp->mtf_symidx = si.sym_id;

	return (0);
}
示例#23
0
文件: dt_module.c 项目: DataIX/src
int
dtrace_symbol_type(dtrace_hdl_t *dtp, const GElf_Sym *symp,
    const dtrace_syminfo_t *sip, dtrace_typeinfo_t *tip)
{
	dt_module_t *dmp;

	tip->dtt_object = NULL;
	tip->dtt_ctfp = NULL;
	tip->dtt_type = CTF_ERR;
	tip->dtt_flags = 0;

	if ((dmp = dt_module_lookup_by_name(dtp, sip->dts_object)) == NULL)
		return (dt_set_errno(dtp, EDT_NOMOD));

	if (symp->st_shndx == SHN_UNDEF && dmp->dm_extern != NULL) {
		dt_ident_t *idp =
		    dt_idhash_lookup(dmp->dm_extern, sip->dts_name);

		if (idp == NULL)
			return (dt_set_errno(dtp, EDT_NOSYM));

		tip->dtt_ctfp = idp->di_ctfp;
		tip->dtt_type = idp->di_type;

	} else if (GELF_ST_TYPE(symp->st_info) != STT_FUNC) {
		if (dt_module_getctf(dtp, dmp) == NULL)
			return (-1); /* errno is set for us */

		tip->dtt_ctfp = dmp->dm_ctfp;
		tip->dtt_type = ctf_lookup_by_symbol(dmp->dm_ctfp, sip->dts_id);

		if (tip->dtt_type == CTF_ERR) {
			dtp->dt_ctferr = ctf_errno(tip->dtt_ctfp);
			return (dt_set_errno(dtp, EDT_CTF));
		}

	} else {
		tip->dtt_ctfp = DT_FPTR_CTFP(dtp);
		tip->dtt_type = DT_FPTR_TYPE(dtp);
	}

	tip->dtt_object = dmp->dm_name;
	return (0);
}
示例#24
0
int
mdb_ctf_module_lookup(const char *name, mdb_ctf_id_t *p)
{
	ctf_file_t *fp;
	ctf_id_t id;
	mdb_module_t *mod;

	if ((mod = mdb_get_module()) == NULL)
		return (set_errno(EMDB_CTX));

	if ((fp = mod->mod_ctfp) == NULL)
		return (set_errno(EMDB_NOCTF));

	if ((id = ctf_lookup_by_name(fp, name)) == CTF_ERR)
		return (set_errno(ctf_to_errno(ctf_errno(fp))));

	set_ctf_id(p, fp, id);

	return (0);
}
示例#25
0
int
mdb_ctf_type_visit(mdb_ctf_id_t id, mdb_ctf_visit_f *func, void *arg)
{
	mdb_ctf_impl_t *idp = (mdb_ctf_impl_t *)&id;
	type_visit_t tv;
	int ret;

	tv.tv_cb = func;
	tv.tv_arg = arg;
	tv.tv_fp = idp->mci_fp;
	tv.tv_base_offset = 0;
	tv.tv_base_depth = 0;
	tv.tv_min_depth = 0;

	ret = ctf_type_visit(idp->mci_fp, idp->mci_id, type_cb, &tv);

	if (ret == CTF_ERR)
		return (set_errno(ctf_to_errno(ctf_errno(idp->mci_fp))));

	return (ret);
}
示例#26
0
static void
ctfsrc_function(ctf_idname_t *idn)
{
	ctf_funcinfo_t *cfi = &idn->ci_funcinfo;
	char name[MAX_NAMELEN] = "unknown_t";

	(void) ctf_type_name(g_fp, cfi->ctc_return, name, sizeof (name));

	(void) printf("extern %s %s(", name, idn->ci_name);

	if (cfi->ctc_argc != 0) {
		ctfdump_fargs_grow(cfi->ctc_argc);
		if (ctf_func_args(g_fp, idn->ci_symidx,
		    g_nfargc, g_fargc) == CTF_ERR) {
			ctfdump_fatal("failed to get arguments for function "
			    "%s: %s\n", idn->ci_name,
			    ctf_errmsg(ctf_errno(g_fp)));
		}

		for (size_t i = 0; i < cfi->ctc_argc; i++) {
			ctf_id_t aid = g_fargc[i];

			name[0] = '\0';

			(void) ctf_type_name(g_fp, aid, name, sizeof (name));

			(void) printf("%s%s", name,
			    i + 1 == cfi->ctc_argc ? "" : ", ");
		}
	} else {
		if (!(cfi->ctc_flags & CTF_FUNC_VARARG))
			(void) printf("void");
	}

	if (cfi->ctc_flags & CTF_FUNC_VARARG)
		(void) printf("%s...", cfi->ctc_argc == 0 ? "" : ", ");

	(void) printf(");\n");
}
示例#27
0
int
mdb_ctf_member_iter(mdb_ctf_id_t id, mdb_ctf_member_f *cb, void *data)
{
	mdb_ctf_impl_t *idp = (mdb_ctf_impl_t *)&id;
	member_iter_t mi;
	int ret;

	/* resolve the type in case there's a forward declaration */
	if ((ret = mdb_ctf_type_resolve(id, &id)) != 0)
		return (ret);

	mi.mi_cb = cb;
	mi.mi_arg = data;
	mi.mi_fp = idp->mci_fp;

	ret = ctf_member_iter(idp->mci_fp, idp->mci_id, member_iter_cb, &mi);

	if (ret == CTF_ERR)
		return (set_errno(ctf_to_errno(ctf_errno(idp->mci_fp))));

	return (ret);
}
示例#28
0
/*
 * Lookup the dynamic translator type tag for the specified probe argument and
 * assign the type to the specified node.  If the type is not yet defined, add
 * it to the "D" module's type container as a typedef for an unknown type.
 */
dt_node_t *
dt_probe_tag(dt_probe_t *prp, uint_t argn, dt_node_t *dnp)
{
	dtrace_hdl_t *dtp = prp->pr_pvp->pv_hdl;
	dtrace_typeinfo_t dtt;
	size_t len;
	char *tag;

	len = snprintf(NULL, 0, "__dtrace_%s___%s_arg%u",
	    prp->pr_pvp->pv_desc.dtvd_name, prp->pr_name, argn);

	tag = alloca(len + 1);

	(void) snprintf(tag, len + 1, "__dtrace_%s___%s_arg%u",
	    prp->pr_pvp->pv_desc.dtvd_name, prp->pr_name, argn);

	if (dtrace_lookup_by_type(dtp, DTRACE_OBJ_DDEFS, tag, &dtt) != 0) {
		dtt.dtt_object = DTRACE_OBJ_DDEFS;
		dtt.dtt_ctfp = DT_DYN_CTFP(dtp);
		dtt.dtt_type = ctf_add_typedef(DT_DYN_CTFP(dtp),
		    CTF_ADD_ROOT, tag, DT_DYN_TYPE(dtp));

		if (dtt.dtt_type == CTF_ERR ||
		    ctf_update(dtt.dtt_ctfp) == CTF_ERR) {
			xyerror(D_UNKNOWN, "cannot define type %s: %s\n",
			    tag, ctf_errmsg(ctf_errno(dtt.dtt_ctfp)));
		}
	}

	bzero(dnp, sizeof (dt_node_t));
	dnp->dn_kind = DT_NODE_TYPE;

	dt_node_type_assign(dnp, dtt.dtt_ctfp, dtt.dtt_type, B_FALSE);
	dt_node_attr_assign(dnp, _dtrace_defattr);

	return (dnp);
}
示例#29
0
int
main(int argc, char *argv[])
{
	int c, fd, err;
	const char *ufile = NULL, *parent = NULL;

	g_progname = basename(argv[0]);
	while ((c = getopt(argc, argv, ":dfhlp:sStu:")) != -1) {
		switch (c) {
		case 'd':
			g_dump |= CTFDUMP_OBJECTS;
			break;
		case 'f':
			g_dump |= CTFDUMP_FUNCTIONS;
			break;
		case 'h':
			g_dump |= CTFDUMP_HEADER;
			break;
		case 'l':
			g_dump |= CTFDUMP_LABELS;
			break;
		case 'p':
			parent = optarg;
			break;
		case 's':
			g_dump |= CTFDUMP_STRINGS;
			break;
		case 'S':
			g_dump |= CTFDUMP_STATS;
			break;
		case 't':
			g_dump |= CTFDUMP_TYPES;
			break;
		case 'u':
			g_dump |= CTFDUMP_OUTPUT;
			ufile = optarg;
			break;
		case '?':
			ctfdump_usage("Unknown option: -%c\n", optopt);
			return (2);
		case ':':
			ctfdump_usage("Option -%c requires an operand\n",
			    optopt);
			return (2);
		}
	}

	argc -= optind;
	argv += optind;

	/*
	 * Dump all information by default.
	 */
	if (g_dump == 0)
		g_dump = CTFDUMP_DEFAULT;

	if (argc != 1) {
		ctfdump_usage("no file to dump\n");
		return (2);
	}

	if ((fd = open(argv[0], O_RDONLY)) < 0)
		ctfdump_fatal("failed to open file %s: %s\n", argv[0],
		    strerror(errno));

	g_fp = ctf_fdopen(fd, &err);
	if (g_fp == NULL)
		ctfdump_fatal("failed to open file %s: %s\n", argv[0],
		    ctf_errmsg(err));

	if (parent != NULL) {
		ctf_file_t *pfp = ctf_open(parent, &err);

		if (pfp == NULL)
			ctfdump_fatal("failed to open parent file %s: %s\n",
			    parent, ctf_errmsg(err));
		if (ctf_import(g_fp, pfp) != 0)
			ctfdump_fatal("failed to import parent %s: %s\n",
			    parent, ctf_errmsg(ctf_errno(g_fp)));
	}

	/*
	 * If stats is set, we must run through everything exect CTFDUMP_OUTPUT.
	 * We also do CTFDUMP_STATS last as a result.
	 */
	if (g_dump & CTFDUMP_HEADER)
		ctfdump_header();

	if (g_dump & (CTFDUMP_LABELS | CTFDUMP_STATS))
		ctfdump_labels();

	if (g_dump & (CTFDUMP_OBJECTS | CTFDUMP_STATS))
		ctfdump_objects();

	if (g_dump & (CTFDUMP_FUNCTIONS | CTFDUMP_STATS))
		ctfdump_functions();

	if (g_dump & (CTFDUMP_TYPES | CTFDUMP_STATS))
		ctfdump_types();

	if (g_dump & (CTFDUMP_STRINGS | CTFDUMP_STATS))
		ctfdump_strings();

	if (g_dump & CTFDUMP_STATS)
		ctfdump_stats();

	if (g_dump & CTFDUMP_OUTPUT)
		ctfdump_output(ufile);

	return (g_exit);
}
示例#30
0
static int
ctfdump_types_cb(ctf_id_t id, boolean_t root, void *arg)
{
	int kind, i, count;
	ctf_id_t ref;
	char name[512], ienc[128];
	const char *encn;
	ctf_funcinfo_t ctc;
	ctf_arinfo_t ar;
	ctf_encoding_t cte;
	ssize_t size;

	if ((kind = ctf_type_kind(g_fp, id)) == CTF_ERR)
		ctfdump_fatal("encountered malformed ctf, type %s does not "
		    "have a kind: %s\n", name, ctf_errmsg(ctf_errno(g_fp)));

	if (ctf_type_name(g_fp, id, name, sizeof (name)) == NULL) {
		if (ctf_errno(g_fp) != ECTF_NOPARENT)
			ctfdump_fatal("type %lu missing name: %s\n", id,
			    ctf_errmsg(ctf_errno(g_fp)));
		(void) snprintf(name, sizeof (name), "(unknown %s)",
		    ctf_kind_name(g_fp, kind));
	}

	g_stats.cs_ntypes[kind]++;
	if (root == B_TRUE)
		ctfdump_printf(CTFDUMP_TYPES, "  <%lu> ", id);
	else
		ctfdump_printf(CTFDUMP_TYPES, "  [%lu] ", id);

	switch (kind) {
	case CTF_K_UNKNOWN:
		break;
	case CTF_K_INTEGER:
		if (ctf_type_encoding(g_fp, id, &cte) == CTF_ERR)
			ctfdump_fatal("failed to get encoding information "
			    "for %s: %s\n", name, ctf_errmsg(ctf_errno(g_fp)));
		ctfdump_intenc_name(&cte, ienc, sizeof (ienc));
		ctfdump_printf(CTFDUMP_TYPES,
		    "%s encoding=%s offset=%u bits=%u",
		    name, ienc, cte.cte_offset, cte.cte_bits);
		break;
	case CTF_K_FLOAT:
		if (ctf_type_encoding(g_fp, id, &cte) == CTF_ERR)
			ctfdump_fatal("failed to get encoding information "
			    "for %s: %s\n", name, ctf_errmsg(ctf_errno(g_fp)));
		if (cte.cte_format < 1 || cte.cte_format > 12)
			encn = "unknown";
		else
			encn = ctfdump_fpenc[cte.cte_format];
		ctfdump_printf(CTFDUMP_TYPES, "%s encoding=%s offset=%u "
		    "bits=%u", name, encn, cte.cte_offset, cte.cte_bits);
		break;
	case CTF_K_POINTER:
		if ((ref = ctf_type_reference(g_fp, id)) == CTF_ERR)
			ctfdump_fatal("failed to get reference type for %s: "
			    "%s\n", name, ctf_errmsg(ctf_errno(g_fp)));
		ctfdump_printf(CTFDUMP_TYPES, "%s refers to %lu", name,
		    ref);
		break;
	case CTF_K_ARRAY:
		if (ctf_array_info(g_fp, id, &ar) == CTF_ERR)
			ctfdump_fatal("failed to get array information for "
			    "%s: %s\n", name, ctf_errmsg(ctf_errno(g_fp)));
		ctfdump_printf(CTFDUMP_TYPES, "%s contents: %lu, index: %lu",
		    name, ar.ctr_contents, ar.ctr_index);
		break;
	case CTF_K_FUNCTION:
		if (ctf_func_info_by_id(g_fp, id, &ctc) == CTF_ERR)
			ctfdump_fatal("failed to get function info for %s: "
			    "%s\n", name, ctf_errmsg(ctf_errno(g_fp)));
		if (ctc.ctc_argc > 0) {
			ctfdump_fargs_grow(ctc.ctc_argc);
			if (ctf_func_args_by_id(g_fp, id, g_nfargc, g_fargc) ==
			    CTF_ERR)
				ctfdump_fatal("failed to get function "
				    "arguments for %s: %s\n", name,
				    ctf_errmsg(ctf_errno(g_fp)));
		}
		ctfdump_printf(CTFDUMP_TYPES,
		    "%s returns: %lu args: (", name, ctc.ctc_return);
		for (i = 0; i < ctc.ctc_argc; i++) {
			ctfdump_printf(CTFDUMP_TYPES, "%lu%s", g_fargc[i],
			    i + 1 == ctc.ctc_argc ? "" : ", ");
		}
		if (ctc.ctc_flags & CTF_FUNC_VARARG)
			ctfdump_printf(CTFDUMP_TYPES, "%s...",
			    ctc.ctc_argc == 0 ? "" : ", ");
		ctfdump_printf(CTFDUMP_TYPES, ")");
		break;
	case CTF_K_STRUCT:
	case CTF_K_UNION:
		size = ctf_type_size(g_fp, id);
		if (size == CTF_ERR)
			ctfdump_fatal("failed to get size of %s: %s\n", name,
			    ctf_errmsg(ctf_errno(g_fp)));
		ctfdump_printf(CTFDUMP_TYPES, "%s (%d bytes)\n", name, size);
		count = 0;
		if (ctf_member_iter(g_fp, id, ctfdump_member_cb, &count) != 0)
			ctfdump_fatal("failed to iterate members of %s: %s\n",
			    name, ctf_errmsg(ctf_errno(g_fp)));
		if (kind == CTF_K_STRUCT) {
			g_stats.cs_nsmembs += count;
			g_stats.cs_nsmax = MAX(count, g_stats.cs_nsmax);
			g_stats.cs_structsz += size;
			g_stats.cs_sszmax = MAX(size, g_stats.cs_sszmax);
		} else {
			g_stats.cs_numembs += count;
			g_stats.cs_numax = MAX(count, g_stats.cs_numax);
			g_stats.cs_unionsz += size;
			g_stats.cs_uszmax = MAX(count, g_stats.cs_uszmax);
		}
		break;
	case CTF_K_ENUM:
		ctfdump_printf(CTFDUMP_TYPES, "%s\n", name);
		count = 0;
		if (ctf_enum_iter(g_fp, id, ctfdump_enum_cb, &count) != 0)
			ctfdump_fatal("failed to iterate enumerators of %s: "
			    "%s\n", name, ctf_errmsg(ctf_errno(g_fp)));
		g_stats.cs_nemembs += count;
		g_stats.cs_nemax = MAX(g_stats.cs_nemax, count);
		break;
	case CTF_K_FORWARD:
		ctfdump_printf(CTFDUMP_TYPES, "forward %s\n", name);
		break;
	case CTF_K_TYPEDEF:
		if ((ref = ctf_type_reference(g_fp, id)) == CTF_ERR)
			ctfdump_fatal("failed to get reference type for %s: "
			    "%s\n", name, ctf_errmsg(ctf_errno(g_fp)));
		ctfdump_printf(CTFDUMP_TYPES, "typedef %s refers to %lu", name,
		    ref);
		break;
	case CTF_K_VOLATILE:
		if ((ref = ctf_type_reference(g_fp, id)) == CTF_ERR)
			ctfdump_fatal("failed to get reference type for %s: "
			    "%s\n", name, ctf_errmsg(ctf_errno(g_fp)));
		ctfdump_printf(CTFDUMP_TYPES, "%s refers to %lu", name,
		    ref);
		break;
	case CTF_K_CONST:
		if ((ref = ctf_type_reference(g_fp, id)) == CTF_ERR)
			ctfdump_fatal("failed to get reference type for %s: "
			    "%s\n", name, ctf_errmsg(ctf_errno(g_fp)));
		ctfdump_printf(CTFDUMP_TYPES, "%s refers to %lu", name,
		    ref);
		break;
	case CTF_K_RESTRICT:
		if ((ref = ctf_type_reference(g_fp, id)) == CTF_ERR)
			ctfdump_fatal("failed to get reference type for %s: "
			    "%s\n", name, ctf_errmsg(ctf_errno(g_fp)));
		ctfdump_printf(CTFDUMP_TYPES, "%s refers to %lu", name,
		    ref);
		break;
	default:
		ctfdump_fatal("encountered unknown kind for type %s: %d\n",
		    name, kind);
	}

	ctfdump_printf(CTFDUMP_TYPES, "\n");

	return (0);
}