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