summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src')
-rw-r--r--usr/src/cmd/dtrace/test/tst/common/include/tst.includefirst.ksh76
-rw-r--r--usr/src/lib/libdtrace/common/dt_cc.c38
-rw-r--r--usr/src/pkg/manifests/system-dtrace-tests.mf2
3 files changed, 114 insertions, 2 deletions
diff --git a/usr/src/cmd/dtrace/test/tst/common/include/tst.includefirst.ksh b/usr/src/cmd/dtrace/test/tst/common/include/tst.includefirst.ksh
new file mode 100644
index 0000000000..b8240d6436
--- /dev/null
+++ b/usr/src/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 <<EOF
+inline int foobar = $expexit;
+#pragma D binding "1.0" foobar
+EOF
+ cat > $secondinc/lib.d <<EOF
+inline int foobar = 42;
+#pragma D binding "1.0" foobar
+EOF
+}
+
+clean()
+{
+ rm -rf $firstinc
+ rm -rf $secondinc
+}
+
+fail()
+{
+ echo "$@"
+ clean
+ exit 1
+}
+
+setup_include
+
+dtrace -L$firstinc -L$secondinc -e -n 'BEGIN{ exit(foobar) }'
+[[ $? != 0 ]] && fail "Failed to compile with same file in include path twice"
+dtrace -L$firstinc -L$secondinc -n 'BEGIN{ exit(foobar) }'
+status=$?
+[[ $status != $expexit ]] && fail "Exited with unexpected status code: $status"
+clean
+exit 0
diff --git a/usr/src/lib/libdtrace/common/dt_cc.c b/usr/src/lib/libdtrace/common/dt_cc.c
index d972aba4f7..56ea585320 100644
--- a/usr/src/lib/libdtrace/common/dt_cc.c
+++ b/usr/src/lib/libdtrace/common/dt_cc.c
@@ -1927,12 +1927,13 @@ static int
dt_load_libs_dir(dtrace_hdl_t *dtp, const char *path)
{
struct dirent *dp;
- const char *p;
+ const char *p, *end;
DIR *dirp;
char fname[PATH_MAX];
FILE *fp;
void *rv;
+ dt_lib_depend_t *dld;
if ((dirp = opendir(path)) == NULL) {
dt_dprintf("skipping lib dir %s: %s\n", path, strerror(errno));
@@ -1953,6 +1954,25 @@ dt_load_libs_dir(dtrace_hdl_t *dtp, const char *path)
continue;
}
+ /*
+ * Skip files whose name match an already processed library
+ */
+ for (dld = dt_list_next(&dtp->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)
return (-1); /* preserve dt_errno */
@@ -2056,7 +2076,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;
@@ -2064,6 +2091,13 @@ 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 */
diff --git a/usr/src/pkg/manifests/system-dtrace-tests.mf b/usr/src/pkg/manifests/system-dtrace-tests.mf
index 56f0f98c2c..529c89e39e 100644
--- a/usr/src/pkg/manifests/system-dtrace-tests.mf
+++ b/usr/src/pkg/manifests/system-dtrace-tests.mf
@@ -63,6 +63,7 @@ dir path=opt/SUNWdtrt/tst/common/exit
dir path=opt/SUNWdtrt/tst/common/fbtprovider
dir path=opt/SUNWdtrt/tst/common/funcs
dir path=opt/SUNWdtrt/tst/common/grammar
+dir path=opt/SUNWdtrt/tst/common/include
dir path=opt/SUNWdtrt/tst/common/inline
dir path=opt/SUNWdtrt/tst/common/io
dir path=opt/SUNWdtrt/tst/common/ip
@@ -841,6 +842,7 @@ file path=opt/SUNWdtrt/tst/common/grammar/err.D_ADDROF_LVAL.d mode=0444
file path=opt/SUNWdtrt/tst/common/grammar/err.D_EMPTY.empty.d mode=0444
file path=opt/SUNWdtrt/tst/common/grammar/tst.clauses.d mode=0444
file path=opt/SUNWdtrt/tst/common/grammar/tst.stmts.d mode=0444
+file path=opt/SUNWdtrt/tst/common/include/tst.includefirst.ksh mode=0444
file path=opt/SUNWdtrt/tst/common/inline/err.D_DECL_IDRED.redef1.d mode=0444
file path=opt/SUNWdtrt/tst/common/inline/err.D_DECL_IDRED.redef2.d mode=0444
file path=opt/SUNWdtrt/tst/common/inline/err.D_IDENT_UNDEF.recur.d mode=0444