/* * value_to_name - translate an address into a string + offset * * mod_lock locking is not needed fro the modules list because * modctl structures are never unlinked from the &modules list. */ ulong_t value_to_name(uintptr_t value, char *symbol) { struct modctl *modp = &modules; ulong_t offset; char *name; DPRINTF1("value_to_name: Looking for %p\n", (void *)value); do { if (modp->mod_mp && (name = kobj_searchsym(modp->mod_mp, value, &offset))) { (void) strcpy(symbol, modp->mod_modname); (void) strcat(symbol, ":"); (void) strcat(symbol, name); return (offset); } } while ((modp = modp->mod_next) != &modules); *symbol = (char)0; return ((ulong_t)-1l); }
/*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 }
/*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); } }