Date: Sat, 6 Jun 2015 16:47:45 +0000 (UTC) From: Mark Johnston <markj@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r284085 - head/cddl/contrib/opensolaris/lib/libdtrace/common Message-ID: <201506061647.t56GljPD041378@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: markj Date: Sat Jun 6 16:47:45 2015 New Revision: 284085 URL: https://svnweb.freebsd.org/changeset/base/284085 Log: libdtrace: allow D libraries to declare dependencies on kernel modules The "depends_on module" pragma can be used to declare a dependency on a DTrace module, which for kernel probes corresponds to a KLD. Such dependencies cannot be checked if the KLD is compiled into the kernel. Therefore, allow a module dependency to be satisfied if either a kernel module or a KLD with the specified name is loaded. Differential Revision: https://reviews.freebsd.org/D2653 Reviewed by: gnn, rpaulo Reported by: gnn Modified: head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_impl.h head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_module.c head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_module.h head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_open.c head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_pragma.c Modified: head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_impl.h ============================================================================== --- head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_impl.h Sat Jun 6 16:45:59 2015 (r284084) +++ head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_impl.h Sat Jun 6 16:47:45 2015 (r284085) @@ -156,6 +156,21 @@ typedef struct dt_module { #define DT_DM_KERNEL 0x2 /* module is associated with a kernel object */ #define DT_DM_PRIMARY 0x4 /* module is a krtld primary kernel object */ +#ifdef __FreeBSD__ +/* + * A representation of a FreeBSD kernel module, used when checking module + * dependencies. This differs from dt_module_t, which refers to a KLD in the + * case of kernel probes. Since modules can be identified regardless of whether + * they've been compiled into the kernel, we use them to identify DTrace + * modules. + */ +typedef struct dt_kmodule { + struct dt_kmodule *dkm_next; /* hash table entry */ + char *dkm_name; /* string name of module */ + dt_module_t *dkm_module; /* corresponding KLD module */ +} dt_kmodule_t; +#endif + typedef struct dt_provmod { char *dp_name; /* name of provider module */ struct dt_provmod *dp_next; /* next module */ @@ -235,6 +250,9 @@ struct dtrace_hdl { dt_idhash_t *dt_tls; /* hash table of thread-local identifiers */ dt_list_t dt_modlist; /* linked list of dt_module_t's */ dt_module_t **dt_mods; /* hash table of dt_module_t's */ +#ifdef __FreeBSD__ + dt_kmodule_t **dt_kmods; /* hash table of dt_kmodule_t's */ +#endif uint_t dt_modbuckets; /* number of module hash buckets */ uint_t dt_nmods; /* number of modules in hash and list */ dt_provmod_t *dt_provmod; /* linked list of provider modules */ Modified: head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_module.c ============================================================================== --- head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_module.c Sat Jun 6 16:45:59 2015 (r284084) +++ head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_module.c Sat Jun 6 16:47:45 2015 (r284085) @@ -37,6 +37,7 @@ #else #include <sys/param.h> #include <sys/linker.h> +#include <sys/module.h> #include <sys/stat.h> #endif @@ -542,6 +543,22 @@ dt_module_lookup_by_ctf(dtrace_hdl_t *dt return (ctfp ? ctf_getspecific(ctfp) : NULL); } +#ifdef __FreeBSD__ +dt_kmodule_t * +dt_kmodule_lookup(dtrace_hdl_t *dtp, const char *name) +{ + uint_t h = dt_strtab_hash(name, NULL) % dtp->dt_modbuckets; + dt_kmodule_t *dkmp; + + for (dkmp = dtp->dt_kmods[h]; dkmp != NULL; dkmp = dkmp->dkm_next) { + if (strcmp(dkmp->dkm_name, name) == 0) + return (dkmp); + } + + return (NULL); +} +#endif + static int dt_module_load_sect(dtrace_hdl_t *dtp, dt_module_t *dmp, ctf_sect_t *ctsp) { @@ -1124,6 +1141,12 @@ dt_module_update(dtrace_hdl_t *dtp, stru char fname[MAXPATHLEN]; struct stat64 st; int fd, err, bits; +#ifdef __FreeBSD__ + struct module_stat ms; + dt_kmodule_t *dkmp; + uint_t h; + int modid; +#endif dt_module_t *dmp; const char *s; @@ -1270,6 +1293,33 @@ dt_module_update(dtrace_hdl_t *dtp, stru if (dmp->dm_info.objfs_info_primary) dmp->dm_flags |= DT_DM_PRIMARY; +#ifdef __FreeBSD__ + ms.version = sizeof(ms); + for (modid = kldfirstmod(k_stat->id); modid > 0; + modid = modnext(modid)) { + if (modstat(modid, &ms) != 0) { + dt_dprintf("modstat failed for id %d in %s: %s\n", + modid, k_stat->name, strerror(errno)); + continue; + } + if (dt_kmodule_lookup(dtp, ms.name) != NULL) + continue; + + dkmp = malloc(sizeof (*dkmp)); + if (dkmp == NULL) { + dt_dprintf("failed to allocate memory\n"); + dt_module_destroy(dtp, dmp); + return; + } + + h = dt_strtab_hash(ms.name, NULL) % dtp->dt_modbuckets; + dkmp->dkm_next = dtp->dt_kmods[h]; + dkmp->dkm_name = strdup(ms.name); + dkmp->dkm_module = dmp; + dtp->dt_kmods[h] = dkmp; + } +#endif + dt_dprintf("opened %d-bit module %s (%s) [%d]\n", bits, dmp->dm_name, dmp->dm_file, dmp->dm_modid); } Modified: head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_module.h ============================================================================== --- head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_module.h Sat Jun 6 16:45:59 2015 (r284084) +++ head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_module.h Sat Jun 6 16:47:45 2015 (r284085) @@ -44,6 +44,10 @@ extern void dt_module_destroy(dtrace_hdl extern dt_module_t *dt_module_lookup_by_name(dtrace_hdl_t *, const char *); extern dt_module_t *dt_module_lookup_by_ctf(dtrace_hdl_t *, ctf_file_t *); +#ifdef __FreeBSD__ +extern dt_kmodule_t *dt_kmodule_lookup(dtrace_hdl_t *, const char *); +#endif + extern int dt_module_hasctf(dtrace_hdl_t *, dt_module_t *); extern ctf_file_t *dt_module_getctf(dtrace_hdl_t *, dt_module_t *); extern dt_ident_t *dt_module_extern(dtrace_hdl_t *, dt_module_t *, Modified: head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_open.c ============================================================================== --- head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_open.c Sat Jun 6 16:45:59 2015 (r284084) +++ head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_open.c Sat Jun 6 16:47:45 2015 (r284085) @@ -1178,6 +1178,9 @@ alloc: #endif dtp->dt_modbuckets = _dtrace_strbuckets; dtp->dt_mods = calloc(dtp->dt_modbuckets, sizeof (dt_module_t *)); +#ifdef __FreeBSD__ + dtp->dt_kmods = calloc(dtp->dt_modbuckets, sizeof (dt_module_t *)); +#endif dtp->dt_provbuckets = _dtrace_strbuckets; dtp->dt_provs = calloc(dtp->dt_provbuckets, sizeof (dt_provider_t *)); dt_proc_hash_create(dtp); @@ -1199,6 +1202,7 @@ alloc: if (dtp->dt_mods == NULL || dtp->dt_provs == NULL || dtp->dt_procs == NULL || dtp->dt_ld_path == NULL || #ifdef __FreeBSD__ + dtp->dt_kmods == NULL || dtp->dt_objcopy_path == NULL || #endif dtp->dt_cpp_path == NULL || dtp->dt_cpp_argv == NULL) @@ -1621,6 +1625,10 @@ dtrace_close(dtrace_hdl_t *dtp) dtrace_prog_t *pgp; dt_xlator_t *dxp; dt_dirpath_t *dirp; +#ifdef __FreeBSD__ + dt_kmodule_t *dkm; + uint_t h; +#endif int i; if (dtp->dt_procs != NULL) @@ -1648,6 +1656,15 @@ dtrace_close(dtrace_hdl_t *dtp) if (dtp->dt_tls != NULL) dt_idhash_destroy(dtp->dt_tls); +#ifdef __FreeBSD__ + for (h = 0; h < dtp->dt_modbuckets; h++) + while ((dkm = dtp->dt_kmods[h]) != NULL) { + dtp->dt_kmods[h] = dkm->dkm_next; + free(dkm->dkm_name); + free(dkm); + } +#endif + while ((dmp = dt_list_next(&dtp->dt_modlist)) != NULL) dt_module_destroy(dtp, dmp); @@ -1697,6 +1714,9 @@ dtrace_close(dtrace_hdl_t *dtp) #endif free(dtp->dt_mods); +#ifdef __FreeBSD__ + free(dtp->dt_kmods); +#endif free(dtp->dt_provs); free(dtp); } Modified: head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_pragma.c ============================================================================== --- head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_pragma.c Sat Jun 6 16:45:59 2015 (r284084) +++ head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_pragma.c Sat Jun 6 16:47:45 2015 (r284085) @@ -278,6 +278,14 @@ dt_pragma_depends(const char *prname, dt } else if (strcmp(cnp->dn_string, "module") == 0) { dt_module_t *mp = dt_module_lookup_by_name(dtp, nnp->dn_string); found = mp != NULL && dt_module_getctf(dtp, mp) != NULL; +#ifdef __FreeBSD__ + if (!found) { + dt_kmodule_t *dkmp = dt_kmodule_lookup(dtp, + nnp->dn_string); + found = dkmp != NULL && + dt_module_getctf(dtp, dkmp->dkm_module) != NULL; + } +#endif } else if (strcmp(cnp->dn_string, "library") == 0) { if (yypcb->pcb_cflags & DTRACE_C_CTL) { assert(dtp->dt_filetag != NULL);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201506061647.t56GljPD041378>