FreeBSD/cddl/contrib/opensolaris/lib/libdtrace/common/dt_pragma.c
/*
 * The #pragma depends_on directive can be used to express a dependency on a
 * module, provider or library which if not present will cause processing to
 * abort.
 */
The #pragma depends_on directive can be used to express a dependency on a
module, provider or library which if not present will cause processing to
abort.
The #pragma depends_on directive can be used to express a dependency on a module provider or library which if not present will cause processing to abort .
static void
dt_pragma_depends(const char *prname, dt_node_t *cnp)
{
	dtrace_hdl_t *dtp = yypcb->pcb_hdl;
	dt_node_t *nnp = cnp ? cnp->dn_list : NULL;
	int found;
	dt_lib_depend_t *dld;
	char lib[MAXPATHLEN];
	size_t plen;
	char *provs, *cpy, *tok;
	if (cnp == NULL || nnp == NULL ||
	    cnp->dn_kind != DT_NODE_IDENT || nnp->dn_kind != DT_NODE_IDENT) {
		xyerror(D_PRAGMA_MALFORM, "malformed #pragma %s "
		    "<class> <name>\n", prname);
	}
	if (strcmp(cnp->dn_string, "provider") == 0) {
		provs = NULL;
		if (sysctlbyname("debug.dtrace.providers", NULL, &plen, NULL, 0) ||
		    ((provs = dt_alloc(dtp, plen)) == NULL) ||
		    sysctlbyname("debug.dtrace.providers", provs, &plen, NULL, 0))
			found = dt_provider_lookup(dtp, nnp->dn_string) != NULL;
		else {
			found = B_FALSE;
			for (cpy = provs; (tok = strsep(&cpy, " ")) != NULL; )
				if (strcmp(tok, nnp->dn_string) == 0) {
					found = B_TRUE;
					break;
				}
			if (found == B_FALSE)
				found = dt_provider_lookup(dtp,
				    nnp->dn_string) != NULL;
		}
		if (provs != NULL)
			dt_free(dtp, provs);
	} 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);
			dt_pragma_depends_finddep(dtp, nnp->dn_string, lib,
			    sizeof (lib));
			dld = dt_lib_depend_lookup(&dtp->dt_lib_dep,
			    dtp->dt_filetag);
			assert(dld != NULL);
			if ((dt_lib_depend_add(dtp, &dld->dtld_dependencies,
			    lib)) != 0) {
				xyerror(D_PRAGMA_DEPEND,
				    "failed to add dependency %s:%s\n", lib,
				    dtrace_errmsg(dtp, dtrace_errno(dtp)));
			}
		} else {
			if (dtp->dt_filetag == NULL)
				xyerror(D_PRAGMA_DEPEND, "main program may "
				    "not explicitly depend on a library");
			dld = dt_lib_depend_lookup(&dtp->dt_lib_dep,
			    dtp->dt_filetag);
			assert(dld != NULL);
			dt_pragma_depends_finddep(dtp, nnp->dn_string, lib,
			    sizeof (lib));
			dld = dt_lib_depend_lookup(&dtp->dt_lib_dep_sorted,
			    lib);
			assert(dld != NULL);
			if (!dld->dtld_loaded)
				xyerror(D_PRAGMA_DEPEND, "program requires "
				    "library \"%s\" which failed to load",
				    lib);
		}
		found = B_TRUE;
	} else {
		xyerror(D_PRAGMA_INVAL, "invalid class %s "
		    "specified by #pragma %s\n", cnp->dn_string, prname);
	}
	if (!found) {
		xyerror(D_PRAGMA_DEPEND, "program requires %s %s\n",
		    cnp->dn_string, nnp->dn_string);
	}
}
static void dt_pragma_depends ( const char * prname , dt_node_t * cnp ) { dtrace_hdl_t * dtp = yypcb -> pcb_hdl ; dt_node_t * nnp = cnp ? cnp -> dn_list : NULL ; int found ; dt_lib_depend_t * dld ; char lib [ MAXPATHLEN ] ; size_t plen ; char * provs , * cpy , * tok ; if ( cnp == NULL || nnp == NULL || cnp -> dn_kind != DT_NODE_IDENT || nnp -> dn_kind != DT_NODE_IDENT ) { xyerror ( D_PRAGMA_MALFORM , " " " \n " , prname ) ; } if ( strcmp ( cnp -> dn_string , " " ) == 0 ) { provs = NULL ; if ( sysctlbyname ( " " , NULL , & plen , NULL , 0 ) || ( ( provs = dt_alloc ( dtp , plen ) ) == NULL ) || sysctlbyname ( " " , provs , & plen , NULL , 0 ) ) found = dt_provider_lookup ( dtp , nnp -> dn_string ) != NULL ; else { found = B_FALSE ; for ( cpy = provs ; ( tok = strsep ( & cpy , " " ) ) != NULL ; ) if ( strcmp ( tok , nnp -> dn_string ) == 0 ) { found = B_TRUE ; break ; } if ( found == B_FALSE ) found = dt_provider_lookup ( dtp , nnp -> dn_string ) != NULL ; } if ( provs != NULL ) dt_free ( dtp , provs ) ; } else if ( strcmp ( cnp -> dn_string , " " ) == 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 , " " ) == 0 ) { if ( yypcb -> pcb_cflags & DTRACE_C_CTL ) { assert ( dtp -> dt_filetag != NULL ) ; dt_pragma_depends_finddep ( dtp , nnp -> dn_string , lib , sizeof ( lib ) ) ; dld = dt_lib_depend_lookup ( & dtp -> dt_lib_dep , dtp -> dt_filetag ) ; assert ( dld != NULL ) ; if ( ( dt_lib_depend_add ( dtp , & dld -> dtld_dependencies , lib ) ) != 0 ) { xyerror ( D_PRAGMA_DEPEND , " \n " , lib , dtrace_errmsg ( dtp , dtrace_errno ( dtp ) ) ) ; } } else { if ( dtp -> dt_filetag == NULL ) xyerror ( D_PRAGMA_DEPEND , " " " " ) ; dld = dt_lib_depend_lookup ( & dtp -> dt_lib_dep , dtp -> dt_filetag ) ; assert ( dld != NULL ) ; dt_pragma_depends_finddep ( dtp , nnp -> dn_string , lib , sizeof ( lib ) ) ; dld = dt_lib_depend_lookup ( & dtp -> dt_lib_dep_sorted , lib ) ; assert ( dld != NULL ) ; if ( ! dld -> dtld_loaded ) xyerror ( D_PRAGMA_DEPEND , " " " \" \" " , lib ) ; } found = B_TRUE ; } else { xyerror ( D_PRAGMA_INVAL , " " " \n " , cnp -> dn_string , prname ) ; } if ( ! found ) { xyerror ( D_PRAGMA_DEPEND , " \n " , cnp -> dn_string , nnp -> dn_string ) ; } }
The #pragma depends_on directive can be used to express a dependency on a
 module, provider or library which if not present will cause processing to
 abort.
The #pragma depends_on directive can be used to express a dependency on a module provider or library which if not present will cause processing to abort .
/*
		 * First try to get the provider list using the
		 * debug.dtrace.providers sysctl, since that'll work even if
		 * we're not running as root.
		 */ /*
			 * By this point we have already performed a topological
			 * sort of the dependencies; we process this directive
			 * as satisfied as long as the dependency was properly
			 * loaded.
			 */