static const prmap_t * dt_pid_fix_mod(dtrace_probedesc_t *pdp, struct ps_prochandle *P) { char m[MAXPATHLEN]; #if defined(sun) Lmid_t lmid = PR_LMID_EVERY; #else Lmid_t lmid = 0; #endif const char *obj; const prmap_t *pmp; #if defined(sun) /* * Pick apart the link map from the library name. */ if (strchr(pdp->dtpd_mod, '`') != NULL) { char *end; if (strncmp(pdp->dtpd_mod, "LM", 2) != 0 || !isdigit(pdp->dtpd_mod[2])) return (NULL); lmid = strtoul(&pdp->dtpd_mod[2], &end, 16); obj = end + 1; if (*end != '`' || strchr(obj, '`') != NULL) return (NULL); } else { obj = pdp->dtpd_mod; } #else obj = pdp->dtpd_mod; #endif if ((pmp = Plmid_to_map(P, lmid, obj)) == NULL) return (NULL); #if defined(sun) (void) Pobjname(P, pmp->pr_vaddr, m, sizeof (m)); if ((obj = strrchr(m, '/')) == NULL) obj = &m[0]; else obj++; (void) Plmid(P, pmp->pr_vaddr, &lmid); #endif dt_pid_objname(pdp->dtpd_mod, sizeof (pdp->dtpd_mod), lmid, obj); return (pmp); }
/* ARGSUSED */ static int dt_module_load_proc_build(void *arg, const prmap_t *prmap, const char *obj) { ctf_file_t *fp; char buf[MAXPATHLEN], *p; dt_module_cb_arg_t *dcp = arg; int count = dcp->dpa_count; Lmid_t lmid; fp = Pname_to_ctf(dcp->dpa_proc, obj); if (fp == NULL) return (0); fp = ctf_dup(fp); if (fp == NULL) return (0); dcp->dpa_dmp->dm_libctfp[count] = fp; /* * While it'd be nice to simply use objname here, because of our prior * actions we'll always get a resolved object name to its on disk file. * Like the pid provider, we need to tell a bit of a lie here. The type * that the user thinks of is in terms of the libraries they requested, * eg. libc.so.1, they don't care about the fact that it's * libc_hwcap.so.1. */ (void) Pobjname(dcp->dpa_proc, prmap->pr_vaddr, buf, sizeof (buf)); if ((p = strrchr(buf, '/')) == NULL) p = buf; else p++; /* * If for some reason we can't find a link map id for this module, which * would be really quite weird. We instead just say the link map id is * zero. */ if (Plmid(dcp->dpa_proc, prmap->pr_vaddr, &lmid) != 0) lmid = 0; if (lmid == 0) dcp->dpa_dmp->dm_libctfn[count] = strdup(p); else (void) asprintf(&dcp->dpa_dmp->dm_libctfn[count], "LM%x`%s", lmid, p); if (dcp->dpa_dmp->dm_libctfn[count] == NULL) return (1); ctf_setspecific(fp, dcp->dpa_dmp); dcp->dpa_count++; return (0); }
/* * Create labels for non-anon, non-heap mappings */ char * make_name(struct ps_prochandle *Pr, int lflag, uintptr_t addr, const char *mapname, char *buf, size_t bufsz) { const pstatus_t *Psp = Pstatus(Pr); struct stat statb; char path[PATH_MAX]; int len; if (lflag || Pstate(Pr) == PS_DEAD) { if (Pobjname(Pr, addr, buf, bufsz) != NULL) return (buf); } else { if (Pobjname_resolved(Pr, addr, buf, bufsz) != NULL) { /* Verify that the path exists */ if ((len = resolvepath(buf, buf, bufsz)) > 0) { buf[len] = '\0'; return (buf); } } } if (Pstate(Pr) == PS_DEAD || *mapname == '\0') return (NULL); /* first see if we can find a path via /proc */ (void) proc_snprintf(path, sizeof (path), "/proc/%d/path/%s", (int)Psp->pr_pid, mapname); len = readlink(path, buf, bufsz - 1); if (len >= 0) { buf[len] = '\0'; return (buf); } /* fall back to object information reported by /proc */ (void) proc_snprintf(path, sizeof (path), "/proc/%d/object/%s", (int)Psp->pr_pid, mapname); if (stat(path, &statb) == 0) { dev_t dev = statb.st_dev; ino_t ino = statb.st_ino; (void) snprintf(buf, bufsz, "dev:%lu,%lu ino:%lu", (ulong_t)major(dev), (ulong_t)minor(dev), ino); return (buf); } return (NULL); }