Exemplo n.º 1
0
static void
ctfdump_header(void)
{
	const ctf_header_t *hp;
	const char *parname, *parlabel;

	ctfdump_title(CTFDUMP_HEADER, "CTF Header");
	ctf_dataptr(g_fp, (const void **)&hp, NULL);
	ctfdump_printf(CTFDUMP_HEADER, "  cth_magic    = 0x%04x\n",
	    hp->cth_magic);
	ctfdump_printf(CTFDUMP_HEADER, "  cth_version  = %u\n",
	    hp->cth_version);
	ctfdump_printf(CTFDUMP_HEADER, "  cth_flags    = 0x%02x\n",
	    ctf_flags(g_fp));
	parname = ctf_parent_name(g_fp);
	parlabel = ctf_parent_label(g_fp);
	ctfdump_printf(CTFDUMP_HEADER, "  cth_parlabel = %s\n",
	    parlabel == NULL ? "(anon)" : parlabel);
	ctfdump_printf(CTFDUMP_HEADER, "  cth_parname  = %s\n",
	    parname == NULL ? "(anon)" : parname);
	ctfdump_printf(CTFDUMP_HEADER, "  cth_lbloff   = %u\n",
	    hp->cth_lbloff);
	ctfdump_printf(CTFDUMP_HEADER, "  cth_objtoff  = %u\n",
	    hp->cth_objtoff);
	ctfdump_printf(CTFDUMP_HEADER, "  cth_funcoff  = %u\n",
	    hp->cth_funcoff);
	ctfdump_printf(CTFDUMP_HEADER, "  cth_typeoff  = %u\n",
	    hp->cth_typeoff);
	ctfdump_printf(CTFDUMP_HEADER, "  cth_stroff   = %u\n",
	    hp->cth_stroff);
	ctfdump_printf(CTFDUMP_HEADER, "  cth_strlen   = %u\n",
	    hp->cth_strlen);
}
Exemplo n.º 2
0
ctf_file_t *
dt_module_getctf(dtrace_hdl_t *dtp, dt_module_t *dmp)
{
	const char *parent;
	dt_module_t *pmp;
	ctf_file_t *pfp;
	int model;

	if (dmp->dm_ctfp != NULL || dt_module_load(dtp, dmp) != 0)
		return (dmp->dm_ctfp);

	if (dmp->dm_ops == &dt_modops_64)
		model = CTF_MODEL_LP64;
	else
		model = CTF_MODEL_ILP32;

	/*
	 * If the data model of the module does not match our program data
	 * model, then do not permit CTF from this module to be opened and
	 * returned to the compiler.  If we support mixed data models in the
	 * future for combined kernel/user tracing, this can be removed.
	 */
	if (dtp->dt_conf.dtc_ctfmodel != model) {
		(void) dt_set_errno(dtp, EDT_DATAMODEL);
		return (NULL);
	}

	if (dmp->dm_ctdata.cts_size == 0) {
		(void) dt_set_errno(dtp, EDT_NOCTF);
		return (NULL);
	}

	dmp->dm_ctfp = ctf_bufopen(&dmp->dm_ctdata,
	    &dmp->dm_symtab, &dmp->dm_strtab, &dtp->dt_ctferr);

	if (dmp->dm_ctfp == NULL) {
		(void) dt_set_errno(dtp, EDT_CTF);
		return (NULL);
	}

	(void) ctf_setmodel(dmp->dm_ctfp, model);
	ctf_setspecific(dmp->dm_ctfp, dmp);

	if ((parent = ctf_parent_name(dmp->dm_ctfp)) != NULL) {
		if ((pmp = dt_module_create(dtp, parent)) == NULL ||
		    (pfp = dt_module_getctf(dtp, pmp)) == NULL) {
			if (pmp == NULL)
				(void) dt_set_errno(dtp, EDT_NOMEM);
			goto err;
		}

		if (ctf_import(dmp->dm_ctfp, pfp) == CTF_ERR) {
			dtp->dt_ctferr = ctf_errno(dmp->dm_ctfp);
			(void) dt_set_errno(dtp, EDT_CTF);
			goto err;
		}
	}

	dt_dprintf("loaded CTF container for %s (%p)\n",
	    dmp->dm_name, (void *)dmp->dm_ctfp);

	return (dmp->dm_ctfp);

err:
	ctf_close(dmp->dm_ctfp);
	dmp->dm_ctfp = NULL;
	return (NULL);
}
Exemplo n.º 3
0
ctf_file_t *
dt_module_getctf(dtrace_hdl_t *dtp, dt_module_t *dmp)
{
	const char *parent;
	dt_module_t *pmp;
	ctf_file_t *pfp;
	int model;

	if (dmp->dm_ctfp != NULL || dt_module_load(dtp, dmp) != 0)
		return (dmp->dm_ctfp);

	if (dmp->dm_ops == &dt_modops_macho_64)
		model = CTF_MODEL_LP64;
	else if (dmp->dm_ops == &dt_modops_macho_32)
		model = CTF_MODEL_ILP32;
	else
	if (dmp->dm_ops == &dt_modops_64)
		model = CTF_MODEL_LP64;
	else
		model = CTF_MODEL_ILP32;

	if (dmp->dm_ctdata.cts_size == 0) {
		(void) dt_set_errno(dtp, EDT_NOCTF);
		return (NULL);
	}

	dmp->dm_ctfp = ctf_bufopen(&dmp->dm_ctdata,
	    &dmp->dm_symtab, &dmp->dm_strtab, &dtp->dt_ctferr);

	if (dmp->dm_ctfp == NULL) {
		(void) dt_set_errno(dtp, EDT_CTF);
		return (NULL);
	}

	(void) ctf_setmodel(dmp->dm_ctfp, model);
	ctf_setspecific(dmp->dm_ctfp, dmp);

	if ((parent = ctf_parent_name(dmp->dm_ctfp)) != NULL) {
		if ((pmp = dt_module_create(dtp, parent)) == NULL ||
		    (pfp = dt_module_getctf(dtp, pmp)) == NULL) {
			if (pmp == NULL)
				(void) dt_set_errno(dtp, EDT_NOMEM);
			goto err;
		}

		if (ctf_import(dmp->dm_ctfp, pfp) == CTF_ERR) {
			dtp->dt_ctferr = ctf_errno(dmp->dm_ctfp);
			(void) dt_set_errno(dtp, EDT_CTF);
			goto err;
		}
	}

	dt_dprintf("loaded CTF container for %s (%p)\n",
	    dmp->dm_name, (void *)dmp->dm_ctfp);

	return (dmp->dm_ctfp);

err:
	ctf_close(dmp->dm_ctfp);
	dmp->dm_ctfp = NULL;
	return (NULL);
}
Exemplo n.º 4
0
/*ARGSUSED*/
static void
fbt_getargdesc(void *arg, dtrace_id_t id, void *parg, dtrace_argdesc_t *desc)
{
	fbt_probe_t *fbt = parg;
	struct modctl *ctl = fbt->fbtp_ctl;
	struct module *mp = ctl->mod_mp;
	ctf_file_t *fp = NULL, *pfp;
	ctf_funcinfo_t f;
	int error;
	ctf_id_t argv[32], type;
	int argc = sizeof (argv) / sizeof (ctf_id_t);
	const char *parent;

	if (!ctl->mod_loaded || (ctl->mod_loadcnt != fbt->fbtp_loadcnt))
		goto err;

	if (fbt->fbtp_roffset != 0 && desc->dtargd_ndx == 0) {
		(void) strlcpy(desc->dtargd_native, "int",
			       sizeof(desc->dtargd_native));
		return;
	}

	if ((fp = ctf_modopen(mp, &error)) == NULL) {
		/*
		 * We have no CTF information for this module -- and therefore
		 * no args[] information.
		 */
		goto err;
	}

	/*
	 * If we have a parent container, we must manually import it.
	 */
	if ((parent = ctf_parent_name(fp)) != NULL) {
		struct modctl *mp = &modules;
		struct modctl *mod = NULL;

		/*
		 * We must iterate over all modules to find the module that
		 * is our parent.
		 */
		do {
			if (strcmp(mp->mod_modname, parent) == 0) {
				mod = mp;
				break;
			}
		} while ((mp = mp->mod_next) != &modules);

		if (mod == NULL)
			goto err;

		if ((pfp = ctf_modopen(mod->mod_mp, &error)) == NULL) {
			goto err;
		}

		if (ctf_import(fp, pfp) != 0) {
			ctf_close(pfp);
			goto err;
		}

		ctf_close(pfp);
	}

	if (ctf_func_info(fp, fbt->fbtp_symndx, &f) == CTF_ERR)
		goto err;

	if (fbt->fbtp_roffset != 0) {
		if (desc->dtargd_ndx > 1)
			goto err;

		ASSERT(desc->dtargd_ndx == 1);
		type = f.ctc_return;
	} else {
		if (desc->dtargd_ndx + 1 > f.ctc_argc)
			goto err;

		if (ctf_func_args(fp, fbt->fbtp_symndx, argc, argv) == CTF_ERR)
			goto err;

		type = argv[desc->dtargd_ndx];
	}

	if (ctf_type_name(fp, type, desc->dtargd_native,
	    DTRACE_ARGTYPELEN) != NULL) {
		ctf_close(fp);
		return;
	}
err:
	if (fp != NULL)
		ctf_close(fp);

	desc->dtargd_ndx = DTRACE_ARGNONE;
}
Exemplo n.º 5
0
/*ARGSUSED*/
static void
instr_getargdesc(void *arg, dtrace_id_t id, void *parg, dtrace_argdesc_t *desc)
{
	instr_probe_t *fbt = parg;
	struct modctl *ctl = fbt->insp_ctl;
	struct module *mp = (struct module *) ctl;
	ctf_file_t *fp = NULL;
	ctf_funcinfo_t f;
//	int error;
	ctf_id_t argv[32], type;
	int argc = sizeof (argv) / sizeof (ctf_id_t);
//	const char *parent;

	if (mp->state != MODULE_STATE_LIVE ||
	    get_refcount(mp) != fbt->insp_loadcnt)
		return;

	if (fbt->insp_roffset != 0 && desc->dtargd_ndx == 0) {
		(void) strcpy(desc->dtargd_native, "int");
		return;
	}

# if 0
	if ((fp = ctf_modopen(mp, &error)) == NULL) {
		/*
		 * We have no CTF information for this module -- and therefore
		 * no args[] information.
		 */
		goto err;
	}
# endif

	//TODO();
	if (fp == NULL)
		goto err;
# if 0

	/*
	 * If we have a parent container, we must manually import it.
	 */
	if ((parent = ctf_parent_name(fp)) != NULL) {
		ctf_file_t *pfp;
		TODO();
		struct modctl *mod;

		/*
		 * We must iterate over all modules to find the module that
		 * is our parent.
		 */
		for (mod = &modules; mod != NULL; mod = mod->mod_next) {
			if (strcmp(mod->mod_filename, parent) == 0)
				break;
		}

		if (mod == NULL)
			goto err;

		if ((pfp = ctf_modopen(mod->mod_mp, &error)) == NULL)
			goto err;

		if (ctf_import(fp, pfp) != 0) {
			ctf_close(pfp);
			goto err;
		}

		ctf_close(pfp);
	}
# endif

	if (ctf_func_info(fp, fbt->insp_symndx, &f) == CTF_ERR)
		goto err;

	if (fbt->insp_roffset != 0) {
		if (desc->dtargd_ndx > 1)
			goto err;

		ASSERT(desc->dtargd_ndx == 1);
		type = f.ctc_return;
	} else {
		if (desc->dtargd_ndx + 1 > f.ctc_argc)
			goto err;

		if (ctf_func_args(fp, fbt->insp_symndx, argc, argv) == CTF_ERR)
			goto err;

		type = argv[desc->dtargd_ndx];
	}

	if (ctf_type_name(fp, type, desc->dtargd_native,
	    DTRACE_ARGTYPELEN) != NULL) {
		ctf_close(fp);
		return;
	}
err:
	if (fp != NULL)
		ctf_close(fp);

	desc->dtargd_ndx = DTRACE_ARGNONE;
}
Exemplo n.º 6
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, ":cdfhlp:sStu:")) != -1) {
		switch (c) {
		case 'c':
			g_dump |= CTFDUMP_SOURCE;
			break;
		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;

	if ((g_dump & CTFDUMP_SOURCE) && !!(g_dump & ~CTFDUMP_SOURCE)) {
		ctfdump_usage("-c must be specified on its own\n");
		return (2);
	}

	/*
	 * Dump all information except C source 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));

	/*
	 * Check to see if this file needs a parent. If it does not and we were
	 * given one, that should be an error. If it does need one and the
	 * parent is not specified, that is fine, we just won't know how to
	 * find child types. If we are given a parent, check at least that the
	 * labels match.
	 */
	if (ctf_parent_name(g_fp) == NULL) {
		if (parent != NULL)
			ctfdump_fatal("cannot use %s as a parent file, %s is "
			    "not a child\n", parent, argv[0]);
	} else if (parent != NULL) {
		const char *explabel, *label;
		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));

		/*
		 * Before we import the parent into the child, check that the
		 * labels match. While there is also the notion of the parent
		 * name, it's less straightforward to match that. Require that
		 * labels match.
		 */
		explabel = ctf_parent_label(g_fp);
		label = ctf_label_topmost(pfp);
		if (explabel == NULL || label == NULL ||
		    strcmp(explabel, label) != 0) {
			if (label == NULL)
				label = "<missing>";
			if (explabel == NULL)
				explabel = "<missing>";
			ctfdump_fatal("label mismatch between parent %s and "
			    "child %s, parent has %s, child expects %s\n",
			    parent, argv[0], label, explabel);
		}

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

	if (g_dump & CTFDUMP_SOURCE) {
		ctfdump_source();
		return (0);
	}

	/*
	 * 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);
}