Example #1
0
static void
profile_create(hrtime_t interval, const char *name, int kind)
{
	profile_probe_t *prof;
	int nr_frames = PROF_ARTIFICIAL_FRAMES + dtrace_mach_aframes();

	if (profile_aframes)
		nr_frames = profile_aframes;

	if (interval < profile_interval_min)
		return;

	if (dtrace_probe_lookup(profile_id, NULL, NULL, name) != 0)
		return;

	atomic_inc_32(&profile_total);
	if (profile_total > profile_max) {
		atomic_dec_32(&profile_total);
		return;
	}

	prof = kmem_zalloc(sizeof (profile_probe_t), KM_SLEEP);
	(void) strcpy(prof->prof_name, name);
	prof->prof_interval = interval;
	prof->prof_cyclic = CYCLIC_NONE;
	prof->prof_kind = kind;
	prof->prof_id = dtrace_probe_create(profile_id,
	    NULL, NULL, name, nr_frames, prof);
}
Example #2
0
static void
profile_create(hrtime_t interval, const char *name, int kind)
{
	profile_probe_t *prof;

	if (interval < profile_interval_min)
		return;

	if (dtrace_probe_lookup(profile_id, NULL, NULL, name) != 0)
		return;

	atomic_add_32(&profile_total, 1);
	if (profile_total > profile_max) {
		atomic_add_32(&profile_total, -1);
		return;
	}

	if (PROF_TICK == kind)
		prof = kmem_zalloc(sizeof (profile_probe_t), KM_SLEEP);
	else
		prof = kmem_zalloc(sizeof (profile_probe_t) + NCPU*sizeof(profile_probe_percpu_t), KM_SLEEP);

	(void) strlcpy(prof->prof_name, name, sizeof(prof->prof_name));
	prof->prof_interval = interval;
	prof->prof_cyclic = CYCLIC_NONE;
	prof->prof_kind = kind;
	prof->prof_id = dtrace_probe_create(profile_id,
	    NULL, NULL, name,
	    profile_aframes ? profile_aframes : PROF_ARTIFICIAL_FRAMES, prof);
}
Example #3
0
/*ARGSUSED*/
static void
machtrace_provide(void *arg, const dtrace_probedesc_t *desc)
{
#pragma unused(arg) /* __APPLE__ */
    
	int i;

	if (desc != NULL)
		return;

	machtrace_init(mach_trap_table, &machtrace_sysent);

	for (i = 0; i < NSYSCALL; i++) {
		
		if (machtrace_sysent[i].stsy_underlying == NULL)
			continue;

		if (dtrace_probe_lookup(machtrace_id, NULL,
					mach_syscall_name_table[i], "entry") != 0)
			continue;

		(void) dtrace_probe_create(machtrace_id, NULL, mach_syscall_name_table[i],
					   "entry", MACHTRACE_ARTIFICIAL_FRAMES,
					   (void *)((uintptr_t)SYSTRACE_ENTRY(i)));
		(void) dtrace_probe_create(machtrace_id, NULL, mach_syscall_name_table[i],
					   "return", MACHTRACE_ARTIFICIAL_FRAMES,
					   (void *)((uintptr_t)SYSTRACE_RETURN(i)));

		machtrace_sysent[i].stsy_entry = DTRACE_IDNONE;
		machtrace_sysent[i].stsy_return = DTRACE_IDNONE;
	}
}
Example #4
0
static void
sdt_create_probe(struct sdt_probe *probe)
{
	struct sdt_provider *prov;
	char mod[DTRACE_MODNAMELEN];
	char func[DTRACE_FUNCNAMELEN];
	char name[DTRACE_NAMELEN];
	const char *from;
	char *to;
	size_t len;

	if (probe->version != (int)sizeof(*probe)) {
		printf("ignoring probe %p, version %u expected %u\n",
		    probe, probe->version, (int)sizeof(*probe));
		return;
	}

	TAILQ_FOREACH(prov, &sdt_prov_list, prov_entry)
		if (strcmp(prov->name, probe->prov->name) == 0)
			break;

	KASSERT(prov != NULL, ("probe defined without a provider"));

	/* If no module name was specified, use the module filename. */
	if (*probe->mod == 0) {
		len = strlcpy(mod, probe->sdtp_lf->filename, sizeof(mod));
		if (len > 3 && strcmp(mod + len - 3, ".ko") == 0)
			mod[len - 3] = '\0';
	} else
		strlcpy(mod, probe->mod, sizeof(mod));

	/*
	 * Unfortunately this is necessary because the Solaris DTrace
	 * code mixes consts and non-consts with casts to override
	 * the incompatibilies. On FreeBSD, we use strict warnings
	 * in the C compiler, so we have to respect const vs non-const.
	 */
	strlcpy(func, probe->func, sizeof(func));
	if (func[0] == '\0')
		strcpy(func, "none");

	from = probe->name;
	to = name;
	for (len = 0; len < (sizeof(name) - 1) && *from != '\0';
	    len++, from++, to++) {
		if (from[0] == '_' && from[1] == '_') {
			*to = '-';
			from++;
		} else
			*to = *from;
	}
	*to = '\0';

	if (dtrace_probe_lookup(prov->id, mod, func, name) != DTRACE_IDNONE)
		return;

	(void)dtrace_probe_create(prov->id, mod, func, name, 1, probe);
}
Example #5
0
void dt_perf_provide(void *arg, const dtrace_probedesc_t *desc)
{
	if (dtrace_probe_lookup(dt_perf_id, "dt_perf", NULL, "invoke") != 0)
		return;

	invoke_pid = dtrace_probe_create(dt_perf_id,
				  "dt_perf", NULL, "invoke", 0, NULL);
	result_pid = dtrace_probe_create(dt_perf_id,
				  "dt_perf", NULL, "result", 0, NULL);
}
/*ARGSUSED*/
static void
lockstat_provide(void *arg, const dtrace_probedesc_t *desc)
{
	int i = 0;

	for (i = 0; lockstat_probes[i].lsp_func != NULL; i++) {
		lockstat_probe_t *probe = &lockstat_probes[i];

		if (dtrace_probe_lookup(lockstat_id, "genunix",
		    probe->lsp_func, probe->lsp_name) != 0)
			continue;

		ASSERT(!probe->lsp_id);
		probe->lsp_id = dtrace_probe_create(lockstat_id,
		    "genunix", probe->lsp_func, probe->lsp_name,
		    1, probe);
	}
}
Example #7
0
/*ARGSUSED*/
static void
lockstat_provide(void *arg, const dtrace_probedesc_t *desc)
{
#pragma unused(arg, desc) /* __APPLE__ */
    
	int i = 0;

	for (i = 0; lockstat_probes[i].lsp_func != NULL; i++) {
		lockstat_probe_t *probe = &lockstat_probes[i];

		if (dtrace_probe_lookup(lockstat_id, "mach_kernel",
		    probe->lsp_func, probe->lsp_name) != 0)
			continue;

		ASSERT(!probe->lsp_id);
		probe->lsp_id = dtrace_probe_create(lockstat_id,
		    "mach_kernel", probe->lsp_func, probe->lsp_name,
		    LOCKSTAT_AFRAMES, probe);
	}
}
Example #8
0
static void
systrace_provide(void *arg, dtrace_probedesc_t *desc)
{
    int i;

    if (desc != NULL)
        return;

    for (i = 0; i < MAXSYSCALL; i++) {
        if (dtrace_probe_lookup(systrace_id, MODNAME,
                                uglyhack.pp_syscallnames[i], "entry") != 0)
            continue;

        (void) dtrace_probe_create(systrace_id, MODNAME, uglyhack.pp_syscallnames[i],
                                   "entry", SYSTRACE_ARTIFICIAL_FRAMES,
                                   (void *)((uintptr_t)SYSTRACE_ENTRY(i)));
        (void) dtrace_probe_create(systrace_id, MODNAME, uglyhack.pp_syscallnames[i],
                                   "return", SYSTRACE_ARTIFICIAL_FRAMES,
                                   (void *)((uintptr_t)SYSTRACE_RETURN(i)));
    }
}
Example #9
0
static void
systrace_provide(void *arg, const dtrace_probedesc_t *desc)
{
    int i;

    if (desc != NULL)
        return;

    for (i = 0; i < MAXSYSCALL; i++) {
        if (dtrace_probe_lookup(systrace_id, NULL,
                                SYSCALLNAMES[i], "entry") != 0)
            continue;

        (void) dtrace_probe_create(systrace_id, NULL,
                                   SYSCALLNAMES[i], "entry", SYSTRACE_ARTIFICIAL_FRAMES,
                                   (void *)(intptr_t)SYSTRACE_ENTRY(i));
        (void) dtrace_probe_create(systrace_id, NULL,
                                   SYSCALLNAMES[i], "return", SYSTRACE_ARTIFICIAL_FRAMES,
                                   (void *)(intptr_t)SYSTRACE_RETURN(i));
    }
}
Example #10
0
/*ARGSUSED*/
static void
systrace_provide(void *arg, const dtrace_probedesc_t *desc)
{
#pragma unused(arg) /* __APPLE__ */
	int i;

	if (desc != NULL)
		return;

	systrace_init(sysent, &systrace_sysent);
#ifdef _SYSCALL32_IMPL
	systrace_init(sysent32, &systrace_sysent32);
#endif

	for (i = 0; i < NSYSCALL; i++) {
		if (systrace_sysent[i].stsy_underlying == NULL)
			continue;

		if (dtrace_probe_lookup(systrace_id, NULL,
		    syscallnames[i], "entry") != 0)
			continue;

		(void) dtrace_probe_create(systrace_id, NULL, syscallnames[i],
		    "entry", SYSTRACE_ARTIFICIAL_FRAMES,
		    (void *)((uintptr_t)SYSTRACE_ENTRY(i)));
		(void) dtrace_probe_create(systrace_id, NULL, syscallnames[i],
		    "return", SYSTRACE_ARTIFICIAL_FRAMES,
		    (void *)((uintptr_t)SYSTRACE_RETURN(i)));

		systrace_sysent[i].stsy_entry = DTRACE_IDNONE;
		systrace_sysent[i].stsy_return = DTRACE_IDNONE;
#ifdef _SYSCALL32_IMPL
		systrace_sysent32[i].stsy_entry = DTRACE_IDNONE;
		systrace_sysent32[i].stsy_return = DTRACE_IDNONE;
#endif
	}
}
Example #11
0
static void
dtnfsclient_provide(void *arg, dtrace_probedesc_t *desc)
{
	int i;

	if (desc != NULL)
		return;

	/*
	 * Register access cache probes.
	 */
	if (dtrace_probe_lookup(dtnfsclient_id, dtnfsclient_accesscache_str,
	    dtnfsclient_flush_str, dtnfsclient_done_str) == 0) {
		nfsclient_accesscache_flush_done_id = dtrace_probe_create(
		    dtnfsclient_id, dtnfsclient_accesscache_str,
		    dtnfsclient_flush_str, dtnfsclient_done_str, 0, NULL);
	}
	if (dtrace_probe_lookup(dtnfsclient_id, dtnfsclient_accesscache_str,
	    dtnfsclient_get_str, dtnfsclient_hit_str) == 0) {
		nfsclient_accesscache_get_hit_id = dtrace_probe_create(
		    dtnfsclient_id, dtnfsclient_accesscache_str,
		    dtnfsclient_get_str, dtnfsclient_hit_str, 0, NULL);
	}
	if (dtrace_probe_lookup(dtnfsclient_id, dtnfsclient_accesscache_str,
	    dtnfsclient_get_str, dtnfsclient_miss_str) == 0) {
		nfsclient_accesscache_get_miss_id = dtrace_probe_create(
		    dtnfsclient_id, dtnfsclient_accesscache_str,
		    dtnfsclient_get_str, dtnfsclient_miss_str, 0, NULL);
	}
	if (dtrace_probe_lookup(dtnfsclient_id, dtnfsclient_accesscache_str,
	    dtnfsclient_load_str, dtnfsclient_done_str) == 0) {
		nfsclient_accesscache_load_done_id = dtrace_probe_create(
		    dtnfsclient_id, dtnfsclient_accesscache_str,
		    dtnfsclient_load_str, dtnfsclient_done_str, 0, NULL);
	}

	/*
	 * Register attribute cache probes.
	 */
	if (dtrace_probe_lookup(dtnfsclient_id, dtnfsclient_attrcache_str,
	    dtnfsclient_flush_str, dtnfsclient_done_str) == 0) {
		nfsclient_attrcache_flush_done_id = dtrace_probe_create(
		    dtnfsclient_id, dtnfsclient_attrcache_str,
		    dtnfsclient_flush_str, dtnfsclient_done_str, 0, NULL);
	}
	if (dtrace_probe_lookup(dtnfsclient_id, dtnfsclient_attrcache_str,
	    dtnfsclient_get_str, dtnfsclient_hit_str) == 0) {
		nfsclient_attrcache_get_hit_id = dtrace_probe_create(
		    dtnfsclient_id, dtnfsclient_attrcache_str,
		    dtnfsclient_get_str, dtnfsclient_hit_str, 0, NULL);
	}
	if (dtrace_probe_lookup(dtnfsclient_id, dtnfsclient_attrcache_str,
	    dtnfsclient_get_str, dtnfsclient_miss_str) == 0) {
		nfsclient_attrcache_get_miss_id = dtrace_probe_create(
		    dtnfsclient_id, dtnfsclient_attrcache_str,
		    dtnfsclient_get_str, dtnfsclient_miss_str, 0, NULL);
	}
	if (dtrace_probe_lookup(dtnfsclient_id, dtnfsclient_attrcache_str,
	    dtnfsclient_load_str, dtnfsclient_done_str) == 0) {
		nfsclient_attrcache_load_done_id = dtrace_probe_create(
		    dtnfsclient_id, dtnfsclient_attrcache_str,
		    dtnfsclient_load_str, dtnfsclient_done_str, 0, NULL);
	}

	/*
	 * Register NFSv2 RPC procedures; note sparseness check for each slot
	 * in the NFSv3 procnum-indexed array.
	 */
	for (i = 0; i < NFS_NPROCS; i++) {
		if (dtnfsclient_rpcs[i].nr_v2_name != NULL &&
		    dtrace_probe_lookup(dtnfsclient_id, dtnfsclient_nfs2_str,
		    dtnfsclient_rpcs[i].nr_v2_name, dtnfsclient_start_str) ==
		    0) {
			dtnfsclient_rpcs[i].nr_v2_id_start =
			    dtrace_probe_create(dtnfsclient_id,
			    dtnfsclient_nfs2_str,
			    dtnfsclient_rpcs[i].nr_v2_name,
			    dtnfsclient_start_str, 0,
			    &nfsclient_nfs2_start_probes[i]);
		}
		if (dtnfsclient_rpcs[i].nr_v2_name != NULL &&
		    dtrace_probe_lookup(dtnfsclient_id, dtnfsclient_nfs2_str,
		    dtnfsclient_rpcs[i].nr_v2_name, dtnfsclient_done_str) ==
		    0) {
			dtnfsclient_rpcs[i].nr_v2_id_done = 
			    dtrace_probe_create(dtnfsclient_id,
			    dtnfsclient_nfs2_str,
			    dtnfsclient_rpcs[i].nr_v2_name,
			    dtnfsclient_done_str, 0,
			    &nfsclient_nfs2_done_probes[i]);
		}
	}

	/*
	 * Register NFSv3 RPC procedures.
	 */
	for (i = 0; i < NFS_NPROCS; i++) {
		if (dtrace_probe_lookup(dtnfsclient_id, dtnfsclient_nfs3_str,
		    dtnfsclient_rpcs[i].nr_v3_name, dtnfsclient_start_str) ==
		    0) {
			dtnfsclient_rpcs[i].nr_v3_id_start =
			    dtrace_probe_create(dtnfsclient_id,
			    dtnfsclient_nfs3_str,
			    dtnfsclient_rpcs[i].nr_v3_name,
			    dtnfsclient_start_str, 0,
			    &nfsclient_nfs3_start_probes[i]);
		}
		if (dtrace_probe_lookup(dtnfsclient_id, dtnfsclient_nfs3_str,
		    dtnfsclient_rpcs[i].nr_v3_name, dtnfsclient_done_str) ==
		    0) {
			dtnfsclient_rpcs[i].nr_v3_id_done = 
			    dtrace_probe_create(dtnfsclient_id,
			    dtnfsclient_nfs3_str,
			    dtnfsclient_rpcs[i].nr_v3_name,
			    dtnfsclient_done_str, 0,
			    &nfsclient_nfs3_done_probes[i]);
		}
	}
}
Example #12
0
/*ARGSUSED*/
static void
__sdt_provide_module(void *arg, struct modctl *ctl)
{
#pragma unused(arg)
	struct module *mp = (struct module *)ctl->mod_address;
	char *modname = ctl->mod_modname;
	sdt_probedesc_t *sdpd;
	sdt_probe_t *sdp, *old;
	sdt_provider_t *prov;
	int len;

	/*
	 * One for all, and all for one:  if we haven't yet registered all of
	 * our providers, we'll refuse to provide anything.
	 */
	for (prov = sdt_providers; prov->sdtp_name != NULL; prov++) {
		if (prov->sdtp_id == DTRACE_PROVNONE)
			return;
	}

	if (!mp || mp->sdt_nprobes != 0 || (sdpd = mp->sdt_probes) == NULL)
		return;

	for (sdpd = mp->sdt_probes; sdpd != NULL; sdpd = sdpd->sdpd_next) {
	    const char *name = sdpd->sdpd_name, *func;
	    char *nname;
		int i, j;
		dtrace_id_t id;

		for (prov = sdt_providers; prov->sdtp_prefix != NULL; prov++) {
			const char *prefpart, *prefix = prov->sdtp_prefix;

			if ((prefpart = strstr(name, prefix))) {
				name = prefpart + strlen(prefix);
				break;
			}
		}

		nname = kmem_alloc(len = strlen(name) + 1, KM_SLEEP);

		for (i = 0, j = 0; name[j] != '\0'; i++) {
			if (name[j] == '_' && name[j + 1] == '_') {
				nname[i] = '-';
				j += 2;
			} else {
				nname[i] = name[j++];
			}
		}

		nname[i] = '\0';

		sdp = kmem_zalloc(sizeof (sdt_probe_t), KM_SLEEP);
		sdp->sdp_loadcnt = ctl->mod_loadcnt;
		sdp->sdp_ctl = ctl;
		sdp->sdp_name = nname;
		sdp->sdp_namelen = len;
		sdp->sdp_provider = prov;

		func = sdpd->sdpd_func;

		if (func == NULL)
			func = "<unknown>";

		/*
		 * We have our provider.  Now create the probe.
		 */
		if ((id = dtrace_probe_lookup(prov->sdtp_id, modname,
		    func, nname)) != DTRACE_IDNONE) {
			old = dtrace_probe_arg(prov->sdtp_id, id);
			ASSERT(old != NULL);

			sdp->sdp_next = old->sdp_next;
			sdp->sdp_id = id;
			old->sdp_next = sdp;
		} else {
			sdp->sdp_id = dtrace_probe_create(prov->sdtp_id,
			    modname, func, nname, SDT_AFRAMES, sdp);

			mp->sdt_nprobes++;
		}

#if 0		
		printf ("__sdt_provide_module:  sdpd=0x%p  sdp=0x%p  name=%s, id=%d\n", sdpd, sdp, nname, sdp->sdp_id);
#endif		

		sdp->sdp_hashnext =
		    sdt_probetab[SDT_ADDR2NDX(sdpd->sdpd_offset)];
		sdt_probetab[SDT_ADDR2NDX(sdpd->sdpd_offset)] = sdp;

		sdp->sdp_patchval = SDT_PATCHVAL;
		sdp->sdp_patchpoint = (sdt_instr_t *)sdpd->sdpd_offset;
		sdp->sdp_savedval = *sdp->sdp_patchpoint;
	}
}
Example #13
0
/**
 * @callback_method_impl{dtrace_pops_t,dtps_provide}
 */
static void     vboxDtPOps_Provide(void *pvProv, const dtrace_probedesc_t *pDtProbeDesc)
{
    PSUPDRVVDTPROVIDERCORE  pProv = (PSUPDRVVDTPROVIDERCORE)pvProv;
    AssertPtrReturnVoid(pProv);
    LOG_DTRACE(("%s: %p / %p pDtProbeDesc=%p\n", __FUNCTION__, pProv, pProv->TracerData.DTrace.idProvider, pDtProbeDesc));

    if (pDtProbeDesc)
        return;  /* We don't generate probes, so never mind these requests. */

    if (pProv->TracerData.DTrace.fZombie)
        return;

    dtrace_provider_id_t const idProvider = pProv->TracerData.DTrace.idProvider;
    AssertPtrReturnVoid(idProvider);

    AssertPtrReturnVoid(pProv->pHdr);
    AssertReturnVoid(pProv->pHdr->offProbeLocs != 0);
    uint32_t const  cProbeLocs    = pProv->pHdr->cbProbeLocs / sizeof(VTGPROBELOC);

    /* Need a buffer for extracting the function names and mangling them in
       case of collision. */
    size_t const cbFnNmBuf = _4K + _1K;
    char *pszFnNmBuf = (char *)RTMemAlloc(cbFnNmBuf);
    if (!pszFnNmBuf)
        return;

    /*
     * Itereate the probe location list and register all probes related to
     * this provider.
     */
    uint16_t const idxProv = (uint16_t)((PVTGDESCPROVIDER)((uintptr_t)pProv->pHdr + pProv->pHdr->offProviders) - pProv->pDesc);
    uint32_t idxProbeLoc;
    for (idxProbeLoc = 0; idxProbeLoc < cProbeLocs; idxProbeLoc++)
    {
        /* Skip probe location belonging to other providers or once that
           we've already reported. */
        PCVTGPROBELOC pProbeLocRO = &pProv->paProbeLocsRO[idxProbeLoc];
        PVTGDESCPROBE pProbeDesc  = pProbeLocRO->pProbe;
        if (pProbeDesc->idxProvider != idxProv)
            continue;

        uint32_t *pidProbe;
        if (!pProv->fUmod)
            pidProbe = (uint32_t *)&pProbeLocRO->idProbe;
        else
            pidProbe = &pProv->paR0ProbeLocs[idxProbeLoc].idProbe;
        if (*pidProbe != 0)
            continue;

        /* The function name may need to be stripped since we're using C++
           compilers for most of the code.  ASSUMES nobody are brave/stupid
           enough to use function pointer returns without typedef'ing
           properly them (e.g. signal). */
        const char *pszPrbName = vboxDtVtgGetString(pProv->pHdr, pProbeDesc->offName);
        const char *pszFunc    = pProbeLocRO->pszFunction;
        const char *psz        = strchr(pProbeLocRO->pszFunction, '(');
        size_t      cch;
        if (psz)
        {
            /* skip blanks preceeding the parameter parenthesis. */
            while (   (uintptr_t)psz > (uintptr_t)pProbeLocRO->pszFunction
                      && RT_C_IS_BLANK(psz[-1]))
                psz--;

            /* Find the start of the function name. */
            pszFunc = psz - 1;
            while ((uintptr_t)pszFunc > (uintptr_t)pProbeLocRO->pszFunction)
            {
                char ch = pszFunc[-1];
                if (!RT_C_IS_ALNUM(ch) && ch != '_' && ch != ':')
                    break;
                pszFunc--;
            }
            cch = psz - pszFunc;
        }
        else
            cch = strlen(pszFunc);
        RTStrCopyEx(pszFnNmBuf, cbFnNmBuf, pszFunc, cch);

        /* Look up the probe, if we have one in the same function, mangle
           the function name a little to avoid having to deal with having
           multiple location entries with the same probe ID. (lazy bird) */
        Assert(!*pidProbe);
        if (dtrace_probe_lookup(idProvider, pProv->pszModName, pszFnNmBuf, pszPrbName) != DTRACE_IDNONE)
        {
            RTStrPrintf(pszFnNmBuf+cch, cbFnNmBuf - cch, "-%u", pProbeLocRO->uLine);
            if (dtrace_probe_lookup(idProvider, pProv->pszModName, pszFnNmBuf, pszPrbName) != DTRACE_IDNONE)
            {
                unsigned iOrd = 2;
                while (iOrd < 128)
                {
                    RTStrPrintf(pszFnNmBuf+cch, cbFnNmBuf - cch, "-%u-%u", pProbeLocRO->uLine, iOrd);
                    if (dtrace_probe_lookup(idProvider, pProv->pszModName, pszFnNmBuf, pszPrbName) == DTRACE_IDNONE)
                        break;
                    iOrd++;
                }
                if (iOrd >= 128)
                {
                    LogRel(("VBoxDrv: More than 128 duplicate probe location instances %s at line %u in function %s [%s], probe %s\n",
                            pProbeLocRO->uLine, pProbeLocRO->pszFunction, pszFnNmBuf, pszPrbName));
                    continue;
                }
            }
        }

        /* Create the probe. */
        AssertCompile(sizeof(*pidProbe) == sizeof(dtrace_id_t));
        *pidProbe = dtrace_probe_create(idProvider, pProv->pszModName, pszFnNmBuf, pszPrbName,
                                        1 /*aframes*/, (void *)(uintptr_t)idxProbeLoc);
        pProv->TracerData.DTrace.cProvidedProbes++;
    }

    RTMemFree(pszFnNmBuf);
    LOG_DTRACE(("%s: returns\n", __FUNCTION__));
}
Example #14
0
/*ARGSUSED*/
static void
sdt_provide_module(void *arg, struct modctl *ctl)
{
# if defined(sun)
	struct module *mp = ctl->mod_mp;
	char *modname = ctl->mod_modname;
	sdt_probedesc_t *sdpd;
	sdt_probe_t *sdp, *old;
	sdt_provider_t *prov;

	/*
	 * One for all, and all for one:  if we haven't yet registered all of
	 * our providers, we'll refuse to provide anything.
	 */
	for (prov = sdt_providers; prov->sdtp_name != NULL; prov++) {
		if (prov->sdtp_id == DTRACE_PROVNONE)
			return;
	}

	if (mp->sdt_nprobes != 0 || (sdpd = mp->sdt_probes) == NULL)
		return;

	for (sdpd = mp->sdt_probes; sdpd != NULL; sdpd = sdpd->sdpd_next) {
		char *name = sdpd->sdpd_name, *func, *nname;
		int i, j, len;
		sdt_provider_t *prov;
		ulong_t offs;
		dtrace_id_t id;

		for (prov = sdt_providers; prov->sdtp_prefix != NULL; prov++) {
			char *prefix = prov->sdtp_prefix;

			if (strncmp(name, prefix, strlen(prefix)) == 0) {
				name += strlen(prefix);
				break;
			}
		}

		nname = kmem_alloc(len = strlen(name) + 1, KM_SLEEP);

		for (i = 0, j = 0; name[j] != '\0'; i++) {
			if (name[j] == '_' && name[j + 1] == '_') {
				nname[i] = '-';
				j += 2;
			} else {
				nname[i] = name[j++];
			}
		}

		nname[i] = '\0';

		sdp = kmem_zalloc(sizeof (sdt_probe_t), KM_SLEEP);
		sdp->sdp_loadcnt = ctl->mod_loadcnt;
		sdp->sdp_ctl = ctl;
		sdp->sdp_name = nname;
		sdp->sdp_namelen = len;
		sdp->sdp_provider = prov;

		func = kobj_searchsym(mp, sdpd->sdpd_offset, &offs);

		if (func == NULL)
			func = "<unknown>";

		/*
		 * We have our provider.  Now create the probe.
		 */
		if ((id = dtrace_probe_lookup(prov->sdtp_id, modname,
		    func, nname)) != DTRACE_IDNONE) {
			old = dtrace_probe_arg(prov->sdtp_id, id);
			ASSERT(old != NULL);

			sdp->sdp_next = old->sdp_next;
			sdp->sdp_id = id;
			old->sdp_next = sdp;
		} else {
			sdp->sdp_id = dtrace_probe_create(prov->sdtp_id,
			    modname, func, nname, 3, sdp);

			mp->sdt_nprobes++;
		}

		sdp->sdp_hashnext =
		    sdt_probetab[SDT_ADDR2NDX(sdpd->sdpd_offset)];
		sdt_probetab[SDT_ADDR2NDX(sdpd->sdpd_offset)] = sdp;

		sdp->sdp_patchval = SDT_PATCHVAL;
		sdp->sdp_patchpoint = (uint8_t *)sdpd->sdpd_offset;
		sdp->sdp_savedval = *sdp->sdp_patchpoint;
	}
# endif
}
Example #15
0
/*ARGSUSED*/
static void
sdt_provide_module(void *arg, struct modctl *ctl)
{
	struct module *mp = ctl->mod_mp;
	char *modname = ctl->mod_modname;
	int primary, nprobes = 0;
	sdt_probedesc_t *sdpd;
	sdt_probe_t *sdp, *old;
	uint32_t *tab;
	sdt_provider_t *prov;
	int len;

	/*
	 * One for all, and all for one:  if we haven't yet registered all of
	 * our providers, we'll refuse to provide anything.
	 */
	for (prov = sdt_providers; prov->sdtp_name != NULL; prov++) {
		if (prov->sdtp_id == DTRACE_PROVNONE)
			return;
	}

	if (mp->sdt_nprobes != 0 || (sdpd = mp->sdt_probes) == NULL)
		return;

	kobj_textwin_alloc(mp);

	/*
	 * Hack to identify unix/genunix/krtld.
	 */
	primary = vmem_contains(heap_arena, (void *)ctl,
	    sizeof (struct modctl)) == 0;

	/*
	 * If there hasn't been an sdt table allocated, we'll do so now.
	 */
	if (mp->sdt_tab == NULL) {
		for (; sdpd != NULL; sdpd = sdpd->sdpd_next) {
			nprobes++;
		}

		/*
		 * We could (should?) determine precisely the size of the
		 * table -- but a reasonable maximum will suffice.
		 */
		mp->sdt_size = nprobes * SDT_ENTRY_SIZE;
		mp->sdt_tab = kobj_texthole_alloc(mp->text, mp->sdt_size);

		if (mp->sdt_tab == NULL) {
			cmn_err(CE_WARN, "couldn't allocate SDT table "
			    "for module %s", modname);
			return;
		}
	}

	tab = (uint32_t *)mp->sdt_tab;

	for (sdpd = mp->sdt_probes; sdpd != NULL; sdpd = sdpd->sdpd_next) {
		char *name = sdpd->sdpd_name, *func, *nname;
		int i, j;
		sdt_provider_t *prov;
		ulong_t offs;
		dtrace_id_t id;

		for (prov = sdt_providers; prov->sdtp_prefix != NULL; prov++) {
			char *prefix = prov->sdtp_prefix;

			if (strncmp(name, prefix, strlen(prefix)) == 0) {
				name += strlen(prefix);
				break;
			}
		}

		nname = kmem_alloc(len = strlen(name) + 1, KM_SLEEP);

		for (i = 0, j = 0; name[j] != '\0'; i++) {
			if (name[j] == '_' && name[j + 1] == '_') {
				nname[i] = '-';
				j += 2;
			} else {
				nname[i] = name[j++];
			}
		}

		nname[i] = '\0';

		sdp = kmem_zalloc(sizeof (sdt_probe_t), KM_SLEEP);
		sdp->sdp_loadcnt = ctl->mod_loadcnt;
		sdp->sdp_primary = primary;
		sdp->sdp_ctl = ctl;
		sdp->sdp_name = nname;
		sdp->sdp_namelen = len;
		sdp->sdp_provider = prov;

		func = kobj_searchsym(mp, sdpd->sdpd_offset +
		    (uintptr_t)mp->text, &offs);

		if (func == NULL)
			func = "<unknown>";

		/*
		 * We have our provider.  Now create the probe.
		 */
		if ((id = dtrace_probe_lookup(prov->sdtp_id, modname,
		    func, nname)) != DTRACE_IDNONE) {
			old = dtrace_probe_arg(prov->sdtp_id, id);
			ASSERT(old != NULL);

			sdp->sdp_next = old->sdp_next;
			sdp->sdp_id = id;
			old->sdp_next = sdp;
		} else {
			sdp->sdp_id = dtrace_probe_create(prov->sdtp_id,
			    modname, func, nname, 1, sdp);

			mp->sdt_nprobes++;
		}

		sdp->sdp_patchval = SDT_CALL((uintptr_t)mp->text +
		    sdpd->sdpd_offset, tab);
		sdp->sdp_patchpoint = (uint32_t *)((uintptr_t)mp->textwin +
		    sdpd->sdpd_offset);
		sdp->sdp_savedval = *sdp->sdp_patchpoint;
		sdt_initialize(sdp, &tab);
	}
}
Example #16
0
void sdt_provide_module(void *arg, struct module *mp)
{
	char			*modname = mp->name;
	dtrace_mprovider_t	*prov;
	sdt_probedesc_t		*sdpd;
	sdt_probe_t		*sdp, *prv;
	int			idx, len;

	/*
	 * Nothing to do if the module SDT probes were already created.
	 */
	if (PDATA(mp)->sdt_probe_cnt != 0)
		return;

	/*
	 * Nothing to do if there are no SDT probes.
	 */
	if (mp->sdt_probec == 0)
		return;

	/*
	 * Do not provide any probes unless all SDT providers have been created
	 * for this meta-provider.
	 */
	for (prov = sdt_providers; prov->dtmp_name != NULL; prov++) {
		if (prov->dtmp_id == DTRACE_PROVNONE)
			return;
	}

	if (!sdt_provide_module_arch(arg, mp))
		return;

	for (idx = 0, sdpd = mp->sdt_probes; idx < mp->sdt_probec;
	     idx++, sdpd++) {
		char			*name = sdpd->sdpd_name, *nname;
		int			i, j;
		dtrace_mprovider_t	*prov;
		dtrace_id_t		id;

		for (prov = sdt_providers; prov->dtmp_pref != NULL; prov++) {
			char	*prefix = prov->dtmp_pref;
			int	len = strlen(prefix);

			if (strncmp(name, prefix, len) == 0) {
				name += len;
				break;
			}
		}

		nname = kmalloc(len = strlen(name) + 1, GFP_KERNEL);
		if (nname == NULL) {
			pr_warn("Unable to create probe %s: out-of-memory\n",
				name);
			continue;
		}

		for (i = j = 0; name[j] != '\0'; i++) {
			if (name[j] == '_' && name[j + 1] == '_') {
				nname[i] = '-';
				j += 2;
			} else
				nname[i] = name[j++];
		}

		nname[i] = '\0';

		sdp = kzalloc(sizeof(sdt_probe_t), GFP_KERNEL);
		if (sdp == NULL) {
			pr_warn("Unable to create probe %s: out-of-memory\n",
				nname);
			continue;
		}

		sdp->sdp_loadcnt = 1; /* FIXME */
		sdp->sdp_module = mp;
		sdp->sdp_name = nname;
		sdp->sdp_namelen = len;
		sdp->sdp_provider = prov;

		if ((id = dtrace_probe_lookup(prov->dtmp_id, modname,
					      sdpd->sdpd_func, nname)) !=
				DTRACE_IDNONE) {
			prv = dtrace_probe_arg(prov->dtmp_id, id);
			ASSERT(prv != NULL);

			sdp->sdp_next = prv->sdp_next;
			sdp->sdp_id = id;
			prv->sdp_next = sdp;
		} else {
			sdp->sdp_id = dtrace_probe_create(prov->dtmp_id,
							  modname,
							  sdpd->sdpd_func,
							  nname, SDT_AFRAMES,
							  sdp);
			PDATA(mp)->sdt_probe_cnt++;
		}

		sdp->sdp_hashnext = sdt_probetab[
					SDT_ADDR2NDX(sdpd->sdpd_offset)];
		sdt_probetab[SDT_ADDR2NDX(sdpd->sdpd_offset)] = sdp;

		sdp->sdp_patchpoint = (asm_instr_t *)sdpd->sdpd_offset;

		sdt_provide_probe_arch(sdp, mp, idx);
	}
}