From e8f6796ca89d06602fe49a8fd65c11ff2d9ebca2 Mon Sep 17 00:00:00 2001 From: pfg Date: Tue, 21 Aug 2012 21:06:07 +0000 Subject: [PATCH] MFC r238558: Dtrace: improve handling of library paths. Merge changes from illumos 906 dtrace depends_on pragma should search all library paths, not just the current one 949 dtrace should only include the first instance of a library found on its library path Obtained from: Illumos git-svn-id: svn://svn.freebsd.org/base/stable/9@239536 ccf9f872-aa2e-dd11-9fc8-001c23d0bc1f --- .../tst/common/include/tst.includefirst.ksh | 76 +++++++++++++++++ .../tst/common/pragma/tst.libdepsepdir.ksh | 76 +++++++++++++++++ .../opensolaris/lib/libdtrace/common/dt_cc.c | 82 ++++++++++++++++--- .../lib/libdtrace/common/dt_pragma.c | 42 ++++++++-- 4 files changed, 254 insertions(+), 22 deletions(-) create mode 100644 cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/include/tst.includefirst.ksh create mode 100644 cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pragma/tst.libdepsepdir.ksh diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/include/tst.includefirst.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/include/tst.includefirst.ksh new file mode 100644 index 000000000..b8240d643 --- /dev/null +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/include/tst.includefirst.ksh @@ -0,0 +1,76 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# + +# +# Copyright (c) 2011, Joyent Inc. All rights reserved. +# Use is subject to license terms. +# + +# +# This test verifies that we only use the first entry of a file with a given +# name in the library path +# + +if [ $# != 1 ]; then + echo expected one argument: '<'dtrace-path'>' + exit 2 +fi + +firstinc=${TMPDIR:-/tmp}/firstinc.$$ +secondinc=${TMPDIR:-/tmp}/secondinc.$$ +expexit=23 + +setup_include() +{ + mkdir $firstinc + mkdir $secondinc + cat > $firstinc/lib.d < $secondinc/lib.d <' + exit 2 +fi + +libdira=${TMPDIR:-/tmp}/libdepa.$$ +libdirb=${TMPDIR:-/tmp}/libdepb.$$ +libdirc=${TMPDIR:-/tmp}/libdepc.$$ +dtrace=$1 + +setup_libs() +{ + mkdir $libdira + mkdir $libdirb + mkdir $libdirc + cat > $libdira/liba.$$.d < $libdirb/libb.$$.d < $libdirb/libc.$$.d < $libdirb/libd.$$.d < $libdirc/libe.$$.d < $libdirc/libf.$$.d <dt_lib_dep); dld != NULL; + dld = dt_list_next(dld)) { + end = strrchr(dld->dtld_library, '/'); + /* dt_lib_depend_add ensures this */ + assert(end != NULL); + if (strcmp(end + 1, dp->d_name) == 0) + break; + } + + if (dld != NULL) { + dt_dprintf("skipping library %s, already processed " + "library with the same name: %s", dp->d_name, + dld->dtld_library); + continue; + } + dtp->dt_filetag = fname; if (dt_lib_depend_add(dtp, &dtp->dt_lib_dep, fname) != 0) - goto err; + return (-1); /* preserve dt_errno */ rv = dt_compile(dtp, DT_CTX_DPROG, DTRACE_PROBESPEC_NAME, NULL, @@ -2203,7 +2221,7 @@ dt_load_libs_dir(dtrace_hdl_t *dtp, const char *path) if (rv != NULL && dtp->dt_errno && (dtp->dt_errno != EDT_COMPILER || dtp->dt_errtag != dt_errtag(D_PRAGMA_DEPEND))) - goto err; + return (-1); /* preserve dt_errno */ if (dtp->dt_errno) dt_dprintf("error parsing library %s: %s\n", @@ -2214,6 +2232,27 @@ dt_load_libs_dir(dtrace_hdl_t *dtp, const char *path) } (void) closedir(dirp); + + return (0); +} + +/* + * Perform a topological sorting of all the libraries found across the entire + * dt_lib_path. Once sorted, compile each one in topological order to cache its + * inlines and translators, etc. We silently ignore any missing directories and + * other files found therein. We only fail (and thereby fail dt_load_libs()) if + * we fail to compile a library and the error is something other than #pragma D + * depends_on. Dependency errors are silently ignored to permit a library + * directory to contain libraries which may not be accessible depending on our + * privileges. + */ +static int +dt_load_libs_sort(dtrace_hdl_t *dtp) +{ + dtrace_prog_t *pgp; + FILE *fp; + dt_lib_depend_t *dld; + /* * Finish building the graph containing the library dependencies * and perform a topological sort to generate an ordered list @@ -2274,7 +2313,14 @@ dt_load_libs(dtrace_hdl_t *dtp) dtp->dt_cflags |= DTRACE_C_NOLIBS; - for (dirp = dt_list_next(&dtp->dt_lib_path); + /* + * /usr/lib/dtrace is always at the head of the list. The rest of the + * list is specified in the precedence order the user requested. Process + * everything other than the head first. DTRACE_C_NOLIBS has already + * been spcified so dt_vopen will ensure that there is always one entry + * in dt_lib_path. + */ + for (dirp = dt_list_next(dt_list_next(&dtp->dt_lib_path)); dirp != NULL; dirp = dt_list_next(dirp)) { if (dt_load_libs_dir(dtp, dirp->dir_path) != 0) { dtp->dt_cflags &= ~DTRACE_C_NOLIBS; @@ -2282,6 +2328,16 @@ dt_load_libs(dtrace_hdl_t *dtp) } } + /* Handle /usr/lib/dtrace */ + dirp = dt_list_next(&dtp->dt_lib_path); + if (dt_load_libs_dir(dtp, dirp->dir_path) != 0) { + dtp->dt_cflags &= ~DTRACE_C_NOLIBS; + return (-1); /* errno is set for us */ + } + + if (dt_load_libs_sort(dtp) < 0) + return (-1); /* errno is set for us */ + return (0); } diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_pragma.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_pragma.c index a9328ab06..00578f433 100644 --- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_pragma.c +++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_pragma.c @@ -21,7 +21,7 @@ /* * Copyright 2008 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright (c) 2011, Joyent Inc. All rights reserved. */ #pragma ident "%Z%%M% %I% %E% SMI" @@ -31,9 +31,13 @@ #if defined(sun) #include #endif +#include #include #include +#include +#include + #include #include #include @@ -201,6 +205,29 @@ dt_pragma_binding(const char *prname, dt_node_t *dnp) dtp->dt_globals->dh_defer = &dt_pragma_apply; } +static void +dt_pragma_depends_finddep(dtrace_hdl_t *dtp, const char *lname, char *lib, + size_t len) +{ + dt_dirpath_t *dirp; + struct stat sbuf; + int found = 0; + + for (dirp = dt_list_next(&dtp->dt_lib_path); dirp != NULL; + dirp = dt_list_next(dirp)) { + (void) snprintf(lib, len, "%s/%s", dirp->dir_path, lname); + + if (stat(lib, &sbuf) == 0) { + found = 1; + break; + } + } + + if (!found) + xyerror(D_PRAGMA_DEPEND, + "failed to find dependency in libpath: %s", lname); +} + /* * 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 @@ -230,16 +257,13 @@ dt_pragma_depends(const char *prname, dt_node_t *cnp) if (yypcb->pcb_cflags & DTRACE_C_CTL) { assert(dtp->dt_filetag != NULL); - /* - * We have the file we are working on in dtp->dt_filetag - * so find that node and add the dependency in. - */ + 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); - (void) snprintf(lib, sizeof (lib), "%s%s", - dld->dtld_libpath, nnp->dn_string); if ((dt_lib_depend_add(dtp, &dld->dtld_dependencies, lib)) != 0) { xyerror(D_PRAGMA_DEPEND, @@ -261,8 +285,8 @@ dt_pragma_depends(const char *prname, dt_node_t *cnp) dtp->dt_filetag); assert(dld != NULL); - (void) snprintf(lib, sizeof (lib), "%s%s", - dld->dtld_libpath, nnp->dn_string); + 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); -- 2.45.0