svn commit: r267941 - in head: cddl/contrib/opensolaris/cmd/dtrace cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf cddl/contrib/opensolaris/common/ctf cddl/contrib/opensolaris/lib/libdtrac...

Rui Paulo rpaulo at FreeBSD.org
Thu Jun 26 23:21:15 UTC 2014


Author: rpaulo
Date: Thu Jun 26 23:21:11 2014
New Revision: 267941
URL: http://svnweb.freebsd.org/changeset/base/267941

Log:
  MFV illumos
  
  4474 DTrace Userland CTF Support
  4475 DTrace userland Keyword
  4476 DTrace tests should be better citizens
  4479 pid provider types
  4480 dof emulation is missing checks
  
  MFC after:	2 weeks

Added:
  head/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/uctf/
     - copied from r266989, vendor/illumos/dist/cmd/dtrace/test/tst/common/uctf/
Modified:
  head/cddl/contrib/opensolaris/cmd/dtrace/dtrace.c
  head/cddl/contrib/opensolaris/common/ctf/ctf_open.c
  head/cddl/contrib/opensolaris/common/ctf/ctf_types.c
  head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_as.c
  head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_cc.c
  head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_decl.c
  head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_decl.h
  head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_dis.c
  head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_error.c
  head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_grammar.y
  head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_ident.c
  head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_impl.h
  head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_lex.l
  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_parser.c
  head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_parser.h
  head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_pid.c
  head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_pid.h
  head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_print.c
  head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_printf.c
  head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_provider.c
  head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_xlator.c
  head/cddl/contrib/opensolaris/lib/libdtrace/common/dtrace.h
  head/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c
  head/sys/cddl/contrib/opensolaris/uts/common/sys/ctf_api.h
  head/sys/cddl/contrib/opensolaris/uts/common/sys/dtrace.h
Directory Properties:
  head/cddl/contrib/opensolaris/   (props changed)
  head/sys/cddl/contrib/opensolaris/   (props changed)

Modified: head/cddl/contrib/opensolaris/cmd/dtrace/dtrace.c
==============================================================================
--- head/cddl/contrib/opensolaris/cmd/dtrace/dtrace.c	Thu Jun 26 22:38:06 2014	(r267940)
+++ head/cddl/contrib/opensolaris/cmd/dtrace/dtrace.c	Thu Jun 26 23:21:11 2014	(r267941)
@@ -25,6 +25,7 @@
  */
 /*
  * Copyright (c) 2012 by Delphix. All rights reserved.
+ * Copyright (c) 2013, Joyent, Inc. All rights reserved.
  */
 
 #include <sys/types.h>
@@ -513,6 +514,7 @@ static void
 print_probe_info(const dtrace_probeinfo_t *p)
 {
 	char buf[BUFSIZ];
+	char *user;
 	int i;
 
 	oprintf("\n\tProbe Description Attributes\n");
@@ -536,10 +538,14 @@ print_probe_info(const dtrace_probeinfo_
 	oprintf("\n\tArgument Types\n");
 
 	for (i = 0; i < p->dtp_argc; i++) {
+		if (p->dtp_argv[i].dtt_flags & DTT_FL_USER)
+			user = "userland ";
+		else
+			user = "";
 		if (ctf_type_name(p->dtp_argv[i].dtt_ctfp,
 		    p->dtp_argv[i].dtt_type, buf, sizeof (buf)) == NULL)
 			(void) strlcpy(buf, "(unknown)", sizeof (buf));
-		oprintf("\t\targs[%d]: %s\n", i, buf);
+		oprintf("\t\targs[%d]: %s%s\n", i, user, buf);
 	}
 
 	if (p->dtp_argc == 0)

Modified: head/cddl/contrib/opensolaris/common/ctf/ctf_open.c
==============================================================================
--- head/cddl/contrib/opensolaris/common/ctf/ctf_open.c	Thu Jun 26 22:38:06 2014	(r267940)
+++ head/cddl/contrib/opensolaris/common/ctf/ctf_open.c	Thu Jun 26 23:21:11 2014	(r267941)
@@ -25,7 +25,7 @@
  * Use is subject to license terms.
  */
 /*
- * Copyright (c) 2012, Joyent, Inc.  All rights reserved.
+ * Copyright (c) 2013, Joyent, Inc.  All rights reserved.
  */
 
 #include <ctf_impl.h>
@@ -788,6 +788,92 @@ bad:
 }
 
 /*
+ * Dupliate a ctf_file_t and its underlying section information into a new
+ * container. This works by copying the three ctf_sect_t's of the original
+ * container if they exist and passing those into ctf_bufopen. To copy those, we
+ * mmap anonymous memory with ctf_data_alloc and bcopy the data across. It's not
+ * the cheapest thing, but it's what we've got.
+ */
+ctf_file_t *
+ctf_dup(ctf_file_t *ofp)
+{
+	ctf_file_t *fp;
+	ctf_sect_t ctfsect, symsect, strsect;
+	ctf_sect_t *ctp, *symp, *strp;
+	void *cbuf, *symbuf, *strbuf;
+	int err;
+
+	cbuf = symbuf = strbuf = NULL;
+	/*
+	 * The ctfsect isn't allowed to not exist, but the symbol and string
+	 * section might not. We only need to copy the data of the section, not
+	 * the name, as ctf_bufopen will take care of that.
+	 */
+	bcopy(&ofp->ctf_data, &ctfsect, sizeof (ctf_sect_t));
+	cbuf = ctf_data_alloc(ctfsect.cts_size);
+	if (cbuf == NULL) {
+		(void) ctf_set_errno(ofp, ECTF_MMAP);
+		return (NULL);
+	}
+
+	bcopy(ctfsect.cts_data, cbuf, ctfsect.cts_size);
+	ctf_data_protect(cbuf, ctfsect.cts_size);
+	ctfsect.cts_data = cbuf;
+	ctfsect.cts_offset = 0;
+	ctp = &ctfsect;
+
+	if (ofp->ctf_symtab.cts_data != NULL) {
+		bcopy(&ofp->ctf_symtab, &symsect, sizeof (ctf_sect_t));
+		symbuf = ctf_data_alloc(symsect.cts_size);
+		if (symbuf == NULL) {
+			(void) ctf_set_errno(ofp, ECTF_MMAP);
+			goto err;
+		}
+		bcopy(symsect.cts_data, symbuf, symsect.cts_size);
+		ctf_data_protect(symbuf, symsect.cts_size);
+		symsect.cts_data = symbuf;
+		symsect.cts_offset = 0;
+		symp = &symsect;
+	} else {
+		symp = NULL;
+	}
+
+	if (ofp->ctf_strtab.cts_data != NULL) {
+		bcopy(&ofp->ctf_strtab, &strsect, sizeof (ctf_sect_t));
+		strbuf = ctf_data_alloc(strsect.cts_size);
+		if (strbuf == NULL) {
+			(void) ctf_set_errno(ofp, ECTF_MMAP);
+			goto err;
+		}
+		bcopy(strsect.cts_data, strbuf, strsect.cts_size);
+		ctf_data_protect(strbuf, strsect.cts_size);
+		strsect.cts_data = strbuf;
+		strsect.cts_offset = 0;
+		strp = &strsect;
+	} else {
+		strp = NULL;
+	}
+
+	fp = ctf_bufopen(ctp, symp, strp, &err);
+	if (fp == NULL) {
+		(void) ctf_set_errno(ofp, err);
+		goto err;
+	}
+
+	fp->ctf_flags |= LCTF_MMAP;
+
+	return (fp);
+
+err:
+	ctf_data_free(cbuf, ctfsect.cts_size);
+	if (symbuf != NULL)
+		ctf_data_free(symbuf, symsect.cts_size);
+	if (strbuf != NULL)
+		ctf_data_free(strbuf, strsect.cts_size);
+	return (NULL);
+}
+
+/*
  * Close the specified CTF container and free associated data structures.  Note
  * that ctf_close() is a reference counted operation: if the specified file is
  * the parent of other active containers, its reference count will be greater

Modified: head/cddl/contrib/opensolaris/common/ctf/ctf_types.c
==============================================================================
--- head/cddl/contrib/opensolaris/common/ctf/ctf_types.c	Thu Jun 26 22:38:06 2014	(r267940)
+++ head/cddl/contrib/opensolaris/common/ctf/ctf_types.c	Thu Jun 26 23:21:11 2014	(r267941)
@@ -25,8 +25,6 @@
  * Use is subject to license terms.
  */
 
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
 #include <ctf_impl.h>
 
 ssize_t
@@ -199,8 +197,9 @@ ctf_type_resolve(ctf_file_t *fp, ctf_id_
  * Lookup the given type ID and print a string name for it into buf.  Return
  * the actual number of bytes (not including \0) needed to format the name.
  */
-ssize_t
-ctf_type_lname(ctf_file_t *fp, ctf_id_t type, char *buf, size_t len)
+static ssize_t
+ctf_type_qlname(ctf_file_t *fp, ctf_id_t type, char *buf, size_t len,
+    const char *qname)
 {
 	ctf_decl_t cd;
 	ctf_decl_node_t *cdp;
@@ -255,6 +254,8 @@ ctf_type_lname(ctf_file_t *fp, ctf_id_t 
 			case CTF_K_INTEGER:
 			case CTF_K_FLOAT:
 			case CTF_K_TYPEDEF:
+				if (qname != NULL)
+					ctf_decl_sprintf(&cd, "%s`", qname);
 				ctf_decl_sprintf(&cd, "%s", name);
 				break;
 			case CTF_K_POINTER:
@@ -268,13 +269,22 @@ ctf_type_lname(ctf_file_t *fp, ctf_id_t 
 				break;
 			case CTF_K_STRUCT:
 			case CTF_K_FORWARD:
-				ctf_decl_sprintf(&cd, "struct %s", name);
+				ctf_decl_sprintf(&cd, "struct ");
+				if (qname != NULL)
+					ctf_decl_sprintf(&cd, "%s`", qname);
+				ctf_decl_sprintf(&cd, "%s", name);
 				break;
 			case CTF_K_UNION:
-				ctf_decl_sprintf(&cd, "union %s", name);
+				ctf_decl_sprintf(&cd, "union ");
+				if (qname != NULL)
+					ctf_decl_sprintf(&cd, "%s`", qname);
+				ctf_decl_sprintf(&cd, "%s", name);
 				break;
 			case CTF_K_ENUM:
-				ctf_decl_sprintf(&cd, "enum %s", name);
+				ctf_decl_sprintf(&cd, "enum ");
+				if (qname != NULL)
+					ctf_decl_sprintf(&cd, "%s`", qname);
+				ctf_decl_sprintf(&cd, "%s", name);
 				break;
 			case CTF_K_VOLATILE:
 				ctf_decl_sprintf(&cd, "volatile");
@@ -301,6 +311,12 @@ ctf_type_lname(ctf_file_t *fp, ctf_id_t 
 	return (cd.cd_len);
 }
 
+ssize_t
+ctf_type_lname(ctf_file_t *fp, ctf_id_t type, char *buf, size_t len)
+{
+	return (ctf_type_qlname(fp, type, buf, len, NULL));
+}
+
 /*
  * Lookup the given type ID and print a string name for it into buf.  If buf
  * is too small, return NULL: the ECTF_NAMELEN error is set on 'fp' for us.
@@ -308,10 +324,19 @@ ctf_type_lname(ctf_file_t *fp, ctf_id_t 
 char *
 ctf_type_name(ctf_file_t *fp, ctf_id_t type, char *buf, size_t len)
 {
-	ssize_t rv = ctf_type_lname(fp, type, buf, len);
+	ssize_t rv = ctf_type_qlname(fp, type, buf, len, NULL);
+	return (rv >= 0 && rv < len ? buf : NULL);
+}
+
+char *
+ctf_type_qname(ctf_file_t *fp, ctf_id_t type, char *buf, size_t len,
+    const char *qname)
+{
+	ssize_t rv = ctf_type_qlname(fp, type, buf, len, qname);
 	return (rv >= 0 && rv < len ? buf : NULL);
 }
 
+
 /*
  * Resolve the type down to a base type node, and then return the size
  * of the type storage in bytes.

Modified: head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_as.c
==============================================================================
--- head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_as.c	Thu Jun 26 22:38:06 2014	(r267940)
+++ head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_as.c	Thu Jun 26 23:21:11 2014	(r267941)
@@ -23,8 +23,10 @@
  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
-
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
+/*
+ * Copyright (c) 2013 by Delphix. All rights reserved.
+ * Copyright (c) 2013 Joyent, Inc. All rights reserved.
+ */
 
 #include <sys/types.h>
 #include <strings.h>
@@ -125,7 +127,7 @@ dt_copyvar(dt_idhash_t *dhp, dt_ident_t 
 		dvp->dtdv_flags |= DIFV_F_MOD;
 
 	bzero(&dn, sizeof (dn));
-	dt_node_type_assign(&dn, idp->di_ctfp, idp->di_type);
+	dt_node_type_assign(&dn, idp->di_ctfp, idp->di_type, B_FALSE);
 	dt_node_diftype(pcb->pcb_hdl, &dn, &dvp->dtdv_type);
 
 	idp->di_flags &= ~(DT_IDFLG_DIFR | DT_IDFLG_DIFW);

Modified: head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_cc.c
==============================================================================
--- head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_cc.c	Thu Jun 26 22:38:06 2014	(r267940)
+++ head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_cc.c	Thu Jun 26 23:21:11 2014	(r267941)
@@ -21,7 +21,7 @@
 
 /*
  * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2011, Joyent Inc. All rights reserved.
+ * Copyright (c) 2013, Joyent Inc. All rights reserved.
  * Copyright (c) 2012 by Delphix. All rights reserved.
  */
 
@@ -663,6 +663,8 @@ dt_action_printflike(dtrace_hdl_t *dtp, 
 static void
 dt_action_trace(dtrace_hdl_t *dtp, dt_node_t *dnp, dtrace_stmtdesc_t *sdp)
 {
+	int ctflib;
+
 	dtrace_actdesc_t *ap = dt_stmt_action(dtp, sdp);
 	boolean_t istrace = (dnp->dn_ident->di_id == DT_ACT_TRACE);
 	const char *act = istrace ?  "trace" : "print";
@@ -694,7 +696,10 @@ dt_action_trace(dtrace_hdl_t *dtp, dt_no
 	 * like arrays and function pointers that can't be resolved by
 	 * ctf_type_lookup().  This is later processed by dtrace_dof_create()
 	 * and turned into a reference into the string table so that we can
-	 * get the type information when we process the data after the fact.
+	 * get the type information when we process the data after the fact.  In
+	 * the case where we are referring to userland CTF data, we also need to
+	 * to identify which ctf container in question we care about and encode
+	 * that within the name.
 	 */
 	if (dnp->dn_ident->di_id == DT_ACT_PRINT) {
 		dt_node_t *dret;
@@ -705,11 +710,27 @@ dt_action_trace(dtrace_hdl_t *dtp, dt_no
 		dmp = dt_module_lookup_by_ctf(dtp, dret->dn_ctfp);
 
 		n = snprintf(NULL, 0, "%s`%ld", dmp->dm_name, dret->dn_type) + 1;
+		if (dmp->dm_pid != 0) {
+			ctflib = dt_module_getlibid(dtp, dmp, dret->dn_ctfp);
+			assert(ctflib >= 0);
+			n = snprintf(NULL, 0, "%s`%d`%ld", dmp->dm_name,
+			    ctflib, dret->dn_type) + 1;
+		} else {
+			n = snprintf(NULL, 0, "%s`%ld", dmp->dm_name,
+			    dret->dn_type) + 1;
+		}
 		sdp->dtsd_strdata = dt_alloc(dtp, n);
 		if (sdp->dtsd_strdata == NULL)
 			longjmp(yypcb->pcb_jmpbuf, EDT_NOMEM);
 		(void) snprintf(sdp->dtsd_strdata, n, "%s`%ld", dmp->dm_name,
 		    dret->dn_type);
+		if (dmp->dm_pid != 0) {
+			(void) snprintf(sdp->dtsd_strdata, n, "%s`%d`%ld",
+			    dmp->dm_name, ctflib, dret->dn_type);
+		} else {
+			(void) snprintf(sdp->dtsd_strdata, n, "%s`%ld",
+			    dmp->dm_name, dret->dn_type);
+		}
 	}
 
 	ap->dtad_difo = dt_as(yypcb);

Modified: head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_decl.c
==============================================================================
--- head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_decl.c	Thu Jun 26 22:38:06 2014	(r267940)
+++ head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_decl.c	Thu Jun 26 23:21:11 2014	(r267941)
@@ -21,7 +21,8 @@
  */
 /*
  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
- * Copyright (c) 2012 by Delphix. All rights reserved.
+ * Copyright (c) 2013 by Delphix. All rights reserved.
+ * Copyright (c) 2013 Joyent, Inc. All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -779,7 +780,7 @@ dt_decl_enumerator(char *s, dt_node_t *d
 	yyintdecimal = 0;
 
 	dnp = dt_node_int(value);
-	dt_node_type_assign(dnp, dsp->ds_ctfp, dsp->ds_type);
+	dt_node_type_assign(dnp, dsp->ds_ctfp, dsp->ds_type, B_FALSE);
 
 	if ((inp = malloc(sizeof (dt_idnode_t))) == NULL)
 		longjmp(yypcb->pcb_jmpbuf, EDT_NOMEM);
@@ -821,6 +822,8 @@ dt_decl_type(dt_decl_t *ddp, dtrace_type
 	char *name;
 	int rv;
 
+	tip->dtt_flags = 0;
+
 	/*
 	 * Based on our current #include depth and decl stack depth, determine
 	 * which dynamic CTF module and scope to use when adding any new types.
@@ -828,6 +831,9 @@ dt_decl_type(dt_decl_t *ddp, dtrace_type
 	dmp = yypcb->pcb_idepth ? dtp->dt_cdefs : dtp->dt_ddefs;
 	flag = yypcb->pcb_dstack.ds_next ? CTF_ADD_NONROOT : CTF_ADD_ROOT;
 
+	if (ddp->dd_attr & DT_DA_USER)
+		tip->dtt_flags = DTT_FL_USER;
+
 	/*
 	 * If we have already cached a CTF type for this decl, then we just
 	 * return the type information for the cached type.

Modified: head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_decl.h
==============================================================================
--- head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_decl.h	Thu Jun 26 22:38:06 2014	(r267940)
+++ head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_decl.h	Thu Jun 26 23:21:11 2014	(r267941)
@@ -23,12 +23,14 @@
  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
+/*
+ * Copyright (c) 2013 by Delphix. All rights reserved.
+ * Copyright (c) 2013 Joyent, Inc. All rights reserved.
+ */
 
 #ifndef	_DT_DECL_H
 #define	_DT_DECL_H
 
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
 #include <sys/types.h>
 #include <libctf.h>
 #include <dtrace.h>
@@ -59,6 +61,7 @@ typedef struct dt_decl {
 #define	DT_DA_RESTRICT	0x0040		/* qualify type as restrict */
 #define	DT_DA_VOLATILE	0x0080		/* qualify type as volatile */
 #define	DT_DA_PAREN	0x0100		/* parenthesis tag */
+#define	DT_DA_USER	0x0200		/* user-land type specifier */
 
 typedef enum dt_dclass {
 	DT_DC_DEFAULT,			/* no storage class specified */

Modified: head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_dis.c
==============================================================================
--- head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_dis.c	Thu Jun 26 22:38:06 2014	(r267940)
+++ head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_dis.c	Thu Jun 26 23:21:11 2014	(r267941)
@@ -26,7 +26,8 @@
  */
 
 /*
- * Copyright (c) 2012 by Delphix. All rights reserved.
+ * Copyright (c) 2013 by Delphix. All rights reserved.
+ * Copyright (c) 2013 Joyent, Inc. All rights reserved.
  */
 
 #include <strings.h>
@@ -312,9 +313,10 @@ dt_dis_typestr(const dtrace_diftype_t *t
 		(void) snprintf(ckind, sizeof (ckind), "0x%x", t->dtdt_ckind);
 	}
 
-	if (t->dtdt_flags & DIF_TF_BYREF) {
-		(void) snprintf(buf, len, "%s (%s) by ref (size %lu)",
-		    kind, ckind, (ulong_t)t->dtdt_size);
+	if (t->dtdt_flags & (DIF_TF_BYREF | DIF_TF_BYUREF)) {
+		(void) snprintf(buf, len, "%s (%s) by %sref (size %lu)",
+		    kind, ckind, (t->dtdt_flags & DIF_TF_BYUREF) ? "user " : "",
+		    (ulong_t)t->dtdt_size);
 	} else {
 		(void) snprintf(buf, len, "%s (%s) (size %lu)",
 		    kind, ckind, (ulong_t)t->dtdt_size);

Modified: head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_error.c
==============================================================================
--- head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_error.c	Thu Jun 26 22:38:06 2014	(r267940)
+++ head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_error.c	Thu Jun 26 23:21:11 2014	(r267941)
@@ -111,7 +111,8 @@ static const struct {
 	{ EDT_BADAGGVAR, "Invalid aggregation variable identifier" },
 	{ EDT_OVERSION,	"Client requested deprecated version of library" },
 	{ EDT_ENABLING_ERR, "Failed to enable probe" },
-	{ EDT_NOPROBES, "No probe sites found for declared provider" }
+	{ EDT_NOPROBES, "No probe sites found for declared provider" },
+	{ EDT_CANTLOAD, "Failed to load module" },
 };
 
 static const int _dt_nerr = sizeof (_dt_errlist) / sizeof (_dt_errlist[0]);

Modified: head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_grammar.y
==============================================================================
--- head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_grammar.y	Thu Jun 26 22:38:06 2014	(r267940)
+++ head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_grammar.y	Thu Jun 26 23:21:11 2014	(r267941)
@@ -23,8 +23,10 @@
  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
-
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
+/*
+ * Copyright (c) 2013 by Delphix. All rights reserved.
+ * Copyright (c) 2013, Joyent, Inc. All rights reserved.
+ */
 
 #include <dt_impl.h>
 
@@ -102,6 +104,7 @@
 %token	DT_KEY_TYPEDEF
 %token	DT_KEY_UNION
 %token	DT_KEY_UNSIGNED
+%token	DT_KEY_USERLAND
 %token	DT_KEY_VOID
 %token	DT_KEY_VOLATILE
 %token	DT_KEY_WHILE
@@ -633,6 +636,7 @@ type_specifier:	DT_KEY_VOID { $$ = dt_de
 	|	DT_KEY_DOUBLE { $$ = dt_decl_spec(CTF_K_FLOAT, DUP("double")); }
 	|	DT_KEY_SIGNED { $$ = dt_decl_attr(DT_DA_SIGNED); }
 	|	DT_KEY_UNSIGNED { $$ = dt_decl_attr(DT_DA_UNSIGNED); }
+	|	DT_KEY_USERLAND { $$ = dt_decl_attr(DT_DA_USER); }
 	|	DT_KEY_STRING {
 			$$ = dt_decl_spec(CTF_K_TYPEDEF, DUP("string"));
 		}

Modified: head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_ident.c
==============================================================================
--- head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_ident.c	Thu Jun 26 22:38:06 2014	(r267940)
+++ head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_ident.c	Thu Jun 26 23:21:11 2014	(r267941)
@@ -22,6 +22,8 @@
 /*
  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
+ * Copyright (c) 2013 by Delphix. All rights reserved.
+ * Copyright (c) 2013 Joyent, Inc. All rights reserved.
  */
 
 #pragma ident	"%Z%%M%	%I%	%E% SMI"
@@ -104,7 +106,7 @@ dt_idcook_sign(dt_node_t *dnp, dt_ident_
 		}
 	}
 
-	dt_node_type_assign(dnp, idp->di_ctfp, idp->di_type);
+	dt_node_type_assign(dnp, idp->di_ctfp, idp->di_type, B_FALSE);
 }
 
 /*
@@ -163,7 +165,7 @@ dt_idcook_assc(dt_node_t *dnp, dt_ident_
 		if (argc != 0)
 			isp->dis_args[argc - 1].dn_list = NULL;
 
-		dt_node_type_assign(dnp, idp->di_ctfp, idp->di_type);
+		dt_node_type_assign(dnp, idp->di_ctfp, idp->di_type, B_FALSE);
 
 	} else {
 		dt_idcook_sign(dnp, idp, argc, args,
@@ -304,7 +306,7 @@ dt_idcook_func(dt_node_t *dnp, dt_ident_
 			}
 
 			dt_node_type_assign(&isp->dis_args[i],
-			    dtt.dtt_ctfp, dtt.dtt_type);
+			    dtt.dtt_ctfp, dtt.dtt_type, B_FALSE);
 		}
 	}
 
@@ -391,7 +393,9 @@ dt_idcook_args(dt_node_t *dnp, dt_ident_
 
 		dt_node_type_assign(dnp,
 		    prp->pr_argv[ap->dn_value].dtt_ctfp,
-		    prp->pr_argv[ap->dn_value].dtt_type);
+		    prp->pr_argv[ap->dn_value].dtt_type,
+		    prp->pr_argv[ap->dn_value].dtt_flags & DTT_FL_USER ?
+		    B_TRUE : B_FALSE);
 
 	} else if ((dxp = dt_xlator_lookup(dtp,
 	    nnp, xnp, DT_XLATE_FUZZY)) != NULL || (
@@ -419,7 +423,8 @@ dt_idcook_args(dt_node_t *dnp, dt_ident_
 		dnp->dn_ident->di_ctfp = xidp->di_ctfp;
 		dnp->dn_ident->di_type = xidp->di_type;
 
-		dt_node_type_assign(dnp, DT_DYN_CTFP(dtp), DT_DYN_TYPE(dtp));
+		dt_node_type_assign(dnp, DT_DYN_CTFP(dtp), DT_DYN_TYPE(dtp),
+		    B_FALSE);
 
 	} else {
 		xyerror(D_ARGS_XLATOR, "translator for %s[%lld] from %s to %s "
@@ -465,7 +470,7 @@ dt_idcook_regs(dt_node_t *dnp, dt_ident_
 	idp->di_ctfp = dtt.dtt_ctfp;
 	idp->di_type = dtt.dtt_type;
 
-	dt_node_type_assign(dnp, idp->di_ctfp, idp->di_type);
+	dt_node_type_assign(dnp, idp->di_ctfp, idp->di_type, B_FALSE);
 }
 
 /*ARGSUSED*/
@@ -487,7 +492,7 @@ dt_idcook_type(dt_node_t *dnp, dt_ident_
 		idp->di_type = dtt.dtt_type;
 	}
 
-	dt_node_type_assign(dnp, idp->di_ctfp, idp->di_type);
+	dt_node_type_assign(dnp, idp->di_ctfp, idp->di_type, B_FALSE);
 }
 
 /*ARGSUSED*/
@@ -495,7 +500,7 @@ static void
 dt_idcook_thaw(dt_node_t *dnp, dt_ident_t *idp, int argc, dt_node_t *args)
 {
 	if (idp->di_ctfp != NULL && idp->di_type != CTF_ERR)
-		dt_node_type_assign(dnp, idp->di_ctfp, idp->di_type);
+		dt_node_type_assign(dnp, idp->di_ctfp, idp->di_type, B_FALSE);
 }
 
 static void

Modified: head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_impl.h
==============================================================================
--- head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_impl.h	Thu Jun 26 22:38:06 2014	(r267940)
+++ head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_impl.h	Thu Jun 26 23:21:11 2014	(r267941)
@@ -146,6 +146,10 @@ typedef struct dt_module {
 	caddr_t dm_reloc_offset;	/* Symbol relocation offset. */
 	uintptr_t *dm_sec_offsets;
 #endif
+	pid_t dm_pid;		/* pid for this module */
+	uint_t dm_nctflibs;	/* number of ctf children libraries */
+	ctf_file_t **dm_libctfp; /* process library ctf pointers */
+	char **dm_libctfn;	/* names of process ctf containers */
 } dt_module_t;
 
 #define	DT_DM_LOADED	0x1	/* module symbol and type data is loaded */
@@ -536,7 +540,8 @@ enum {
 	EDT_BADAGGVAR,		/* invalid aggregation variable identifier */
 	EDT_OVERSION,		/* client is requesting deprecated version */
 	EDT_ENABLING_ERR,	/* failed to enable probe */
-	EDT_NOPROBES		/* no probes sites for declared provider */
+	EDT_NOPROBES,		/* no probes sites for declared provider */
+	EDT_CANTLOAD		/* failed to load a module */
 };
 
 /*

Modified: head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_lex.l
==============================================================================
--- head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_lex.l	Thu Jun 26 22:38:06 2014	(r267940)
+++ head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_lex.l	Thu Jun 26 23:21:11 2014	(r267941)
@@ -23,6 +23,10 @@
 /*
  * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
  */
+/*
+ * Copyright (c) 2013 by Delphix. All rights reserved.
+ * Copyright (c) 2013, Joyent, Inc. All rights reserved.
+ */
 
 #include <string.h>
 #include <stdlib.h>
@@ -93,13 +97,17 @@ static void unput(int);
 %}
 
 %e 1500		/* maximum nodes */
-%p 3700		/* maximum positions */
+%p 4900		/* maximum positions */
 %n 600		/* maximum states */
+%a 3000		/* maximum transitions */
 
 %s S0 S1 S2 S3 S4
 
 RGX_AGG		"@"[a-zA-Z_][0-9a-zA-Z_]*
 RGX_PSPEC	[-$:a-zA-Z_.?*\\\[\]!][-$:0-9a-zA-Z_.`?*\\\[\]!]*
+RGX_ALTIDENT	[a-zA-Z_][0-9a-zA-Z_]*
+RGX_LMID	LM[0-9a-fA-F]+`
+RGX_MOD_IDENT	[a-zA-Z_`][0-9a-z.A-Z_`]*`
 RGX_IDENT	[a-zA-Z_`][0-9a-zA-Z_`]*
 RGX_INT		([0-9]+|0[xX][0-9A-Fa-f]+)[uU]?[lL]?[lL]?
 RGX_FP		([0-9]+("."?)[0-9]*|"."[0-9]+)((e|E)("+"|-)?[0-9]+)?[fFlL]?
@@ -169,6 +177,7 @@ if (yypcb->pcb_token != 0) {
 <S0>typedef	return (DT_KEY_TYPEDEF);
 <S0>union	return (DT_KEY_UNION);
 <S0>unsigned	return (DT_KEY_UNSIGNED);
+<S0>userland	return (DT_KEY_USERLAND);
 <S0>void	return (DT_KEY_VOID);
 <S0>volatile	return (DT_KEY_VOLATILE);
 <S0>while	return (DT_KEY_WHILE);
@@ -347,7 +356,9 @@ if (yypcb->pcb_token != 0) {
 			return (DT_TOK_INT);
 		}
 
-<S0>{RGX_IDENT}	{
+<S0>{RGX_IDENT} |
+<S0>{RGX_MOD_IDENT}{RGX_IDENT} |
+<S0>{RGX_MOD_IDENT} {
 			return (id_or_type(yytext));
 		}
 

Modified: head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_module.c
==============================================================================
--- head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_module.c	Thu Jun 26 22:38:06 2014	(r267940)
+++ head/cddl/contrib/opensolaris/lib/libdtrace/common/dt_module.c	Thu Jun 26 23:21:11 2014	(r267941)
@@ -22,6 +22,9 @@
 /*
  * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
  */
+/*
+ * Copyright (c) 2013, Joyent, Inc.  All rights reserved.
+ */
 
 #include <sys/types.h>
 #if defined(sun)
@@ -50,6 +53,7 @@
 #include <dirent.h>
 #if !defined(sun)
 #include <fcntl.h>
+#include <libproc_compat.h>
 #endif
 
 #include <dt_strtab.h>
@@ -462,6 +466,9 @@ static const dt_modops_t dt_modops_64 = 
 dt_module_t *
 dt_module_create(dtrace_hdl_t *dtp, const char *name)
 {
+	long pid;
+	char *eptr;
+	dt_ident_t *idp;
 	uint_t h = dt_strtab_hash(name, NULL) % dtp->dt_modbuckets;
 	dt_module_t *dmp;
 
@@ -485,6 +492,32 @@ dt_module_create(dtrace_hdl_t *dtp, cons
 	else
 		dmp->dm_ops = &dt_modops_32;
 
+	/*
+	 * Modules for userland processes are special. They always refer to a
+	 * specific process and have a copy of their CTF data from a specific
+	 * instant in time. Any dt_module_t that begins with 'pid' is a module
+	 * for a specific process, much like how any probe description that
+	 * begins with 'pid' is special. pid123 refers to process 123. A module
+	 * that is just 'pid' refers specifically to pid$target. This is
+	 * generally done as D does not currently allow for macros to be
+	 * evaluated when working with types.
+	 */
+	if (strncmp(dmp->dm_name, "pid", 3) == 0) {
+		errno = 0;
+		if (dmp->dm_name[3] == '\0') {
+			idp = dt_idhash_lookup(dtp->dt_macros, "target");
+			if (idp != NULL && idp->di_id != 0)
+				dmp->dm_pid = idp->di_id;
+		} else {
+			pid = strtol(dmp->dm_name + 3, &eptr, 10);
+			if (errno == 0 && *eptr == '\0')
+				dmp->dm_pid = (pid_t)pid;
+			else
+				dt_dprintf("encountered malformed pid "
+				    "module: %s\n", dmp->dm_name);
+		}
+	}
+
 	return (dmp);
 }
 
@@ -554,12 +587,169 @@ dt_module_load_sect(dtrace_hdl_t *dtp, d
 	return (0);
 }
 
+typedef struct dt_module_cb_arg {
+	struct ps_prochandle *dpa_proc;
+	dtrace_hdl_t *dpa_dtp;
+	dt_module_t *dpa_dmp;
+	uint_t dpa_count;
+} dt_module_cb_arg_t;
+
+/* ARGSUSED */
+static int
+dt_module_load_proc_count(void *arg, const prmap_t *prmap, const char *obj)
+{
+	ctf_file_t *fp;
+	dt_module_cb_arg_t *dcp = arg;
+
+	/* Try to grab a ctf container if it exists */
+	fp = Pname_to_ctf(dcp->dpa_proc, obj);
+	if (fp != NULL)
+		dcp->dpa_count++;
+	return (0);
+}
+
+/* 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);
+}
+
+/*
+ * We've been asked to load data that belongs to another process. As such we're
+ * going to pgrab it at this instant, load everything that we might ever care
+ * about, and then drive on. The reason for this is that the process that we're
+ * interested in might be changing. As long as we have grabbed it, then this
+ * can't be a problem for us.
+ *
+ * For now, we're actually going to punt on most things and just try to get CTF
+ * data, nothing else. Basically this is only useful as a source of type
+ * information, we can't go and do the stacktrace lookups, etc.
+ */
+static int
+dt_module_load_proc(dtrace_hdl_t *dtp, dt_module_t *dmp)
+{
+	struct ps_prochandle *p;
+	dt_module_cb_arg_t arg;
+
+	/*
+	 * Note that on success we do not release this hold. We must hold this
+	 * for our life time.
+	 */
+	p = dt_proc_grab(dtp, dmp->dm_pid, 0, PGRAB_RDONLY | PGRAB_FORCE);
+	if (p == NULL) {
+		dt_dprintf("failed to grab pid: %d\n", (int)dmp->dm_pid);
+		return (dt_set_errno(dtp, EDT_CANTLOAD));
+	}
+	dt_proc_lock(dtp, p);
+
+	arg.dpa_proc = p;
+	arg.dpa_dtp = dtp;
+	arg.dpa_dmp = dmp;
+	arg.dpa_count = 0;
+	if (Pobject_iter_resolved(p, dt_module_load_proc_count, &arg) != 0) {
+		dt_dprintf("failed to iterate objects\n");
+		dt_proc_release(dtp, p);
+		return (dt_set_errno(dtp, EDT_CANTLOAD));
+	}
+
+	if (arg.dpa_count == 0) {
+		dt_dprintf("no ctf data present\n");
+		dt_proc_unlock(dtp, p);
+		dt_proc_release(dtp, p);
+		return (dt_set_errno(dtp, EDT_CANTLOAD));
+	}
+
+	dmp->dm_libctfp = malloc(sizeof (ctf_file_t *) * arg.dpa_count);
+	if (dmp->dm_libctfp == NULL) {
+		dt_proc_unlock(dtp, p);
+		dt_proc_release(dtp, p);
+		return (dt_set_errno(dtp, EDT_NOMEM));
+	}
+	bzero(dmp->dm_libctfp, sizeof (ctf_file_t *) * arg.dpa_count);
+
+	dmp->dm_libctfn = malloc(sizeof (char *) * arg.dpa_count);
+	if (dmp->dm_libctfn == NULL) {
+		free(dmp->dm_libctfp);
+		dt_proc_unlock(dtp, p);
+		dt_proc_release(dtp, p);
+		return (dt_set_errno(dtp, EDT_NOMEM));
+	}
+	bzero(dmp->dm_libctfn, sizeof (char *) * arg.dpa_count);
+
+	dmp->dm_nctflibs = arg.dpa_count;
+
+	arg.dpa_count = 0;
+	if (Pobject_iter_resolved(p, dt_module_load_proc_build, &arg) != 0) {
+		dt_proc_unlock(dtp, p);
+		dt_module_unload(dtp, dmp);
+		dt_proc_release(dtp, p);
+		return (dt_set_errno(dtp, EDT_CANTLOAD));
+	}
+	assert(arg.dpa_count == dmp->dm_nctflibs);
+	dt_dprintf("loaded %d ctf modules for pid %d\n", arg.dpa_count,
+	    (int)dmp->dm_pid);
+
+	dt_proc_unlock(dtp, p);
+	dt_proc_release(dtp, p);
+	dmp->dm_flags |= DT_DM_LOADED;
+
+	return (0);
+}
+
 int
 dt_module_load(dtrace_hdl_t *dtp, dt_module_t *dmp)
 {
 	if (dmp->dm_flags & DT_DM_LOADED)
 		return (0); /* module is already loaded */
 
+	if (dmp->dm_pid != 0)
+		return (dt_module_load_proc(dtp, dmp));
+
 	dmp->dm_ctdata.cts_name = ".SUNW_ctf";
 	dmp->dm_ctdata.cts_type = SHT_PROGBITS;
 	dmp->dm_ctdata.cts_flags = 0;
@@ -645,6 +835,14 @@ dt_module_load(dtrace_hdl_t *dtp, dt_mod
 	return (0);
 }
 
+int
+dt_module_hasctf(dtrace_hdl_t *dtp, dt_module_t *dmp)
+{
+	if (dmp->dm_pid != 0 && dmp->dm_nctflibs > 0)
+		return (1);
+	return (dt_module_getctf(dtp, dmp) != NULL);
+}
+
 ctf_file_t *
 dt_module_getctf(dtrace_hdl_t *dtp, dt_module_t *dmp)
 {
@@ -718,6 +916,8 @@ err:
 void
 dt_module_unload(dtrace_hdl_t *dtp, dt_module_t *dmp)
 {
+	int i;
+
 	ctf_close(dmp->dm_ctfp);
 	dmp->dm_ctfp = NULL;
 
@@ -733,6 +933,17 @@ dt_module_unload(dtrace_hdl_t *dtp, dt_m
 	}
 #endif
 
+	if (dmp->dm_libctfp != NULL) {
+		for (i = 0; i < dmp->dm_nctflibs; i++) {
+			ctf_close(dmp->dm_libctfp[i]);
+			free(dmp->dm_libctfn[i]);
+		}
+		free(dmp->dm_libctfp);
+		free(dmp->dm_libctfn);
+		dmp->dm_libctfp = NULL;
+		dmp->dm_nctflibs = 0;
+	}
+
 	bzero(&dmp->dm_ctdata, sizeof (ctf_sect_t));
 	bzero(&dmp->dm_symtab, sizeof (ctf_sect_t));
 	bzero(&dmp->dm_strtab, sizeof (ctf_sect_t));
@@ -778,6 +989,8 @@ dt_module_unload(dtrace_hdl_t *dtp, dt_m
 	(void) elf_end(dmp->dm_elf);
 	dmp->dm_elf = NULL;
 
+	dmp->dm_pid = 0;
+
 	dmp->dm_flags &= ~DT_DM_LOADED;
 }
 
@@ -866,6 +1079,34 @@ dt_module_modelname(dt_module_t *dmp)
 		return ("32-bit");
 }
 
+/* ARGSUSED */
+int
+dt_module_getlibid(dtrace_hdl_t *dtp, dt_module_t *dmp, const ctf_file_t *fp)
+{
+	int i;
+
+	for (i = 0; i < dmp->dm_nctflibs; i++) {
+		if (dmp->dm_libctfp[i] == fp)
+			return (i);
+	}
+
+	return (-1);
+}
+
+/* ARGSUSED */
+ctf_file_t *
+dt_module_getctflib(dtrace_hdl_t *dtp, dt_module_t *dmp, const char *name)
+{
+	int i;
+
+	for (i = 0; i < dmp->dm_nctflibs; i++) {
+		if (strcmp(dmp->dm_libctfn[i], name) == 0)
+			return (dmp->dm_libctfp[i]);
+	}
+
+	return (NULL);
+}
+
 /*
  * Update our module cache by adding an entry for the specified module 'name'.
  * We create the dt_module_t and populate it using /system/object/<name>/.
@@ -1294,8 +1535,10 @@ dtrace_lookup_by_type(dtrace_hdl_t *dtp,
 	dt_module_t *dmp;
 	int found = 0;
 	ctf_id_t id;
-	uint_t n;
+	uint_t n, i;
 	int justone;
+	ctf_file_t *fp;
+	char *buf, *p, *q;
 
 	uint_t mask = 0; /* mask of dt_module flags to match */
 	uint_t bits = 0; /* flag bits that must be present */
@@ -1310,7 +1553,6 @@ dtrace_lookup_by_type(dtrace_hdl_t *dtp,
 			return (-1); /* dt_errno is set for us */
 		n = 1;
 		justone = 1;
-
 	} else {
 		if (object == DTRACE_OBJ_KMODS)
 			mask = bits = DT_DM_KERNEL;
@@ -1334,7 +1576,7 @@ dtrace_lookup_by_type(dtrace_hdl_t *dtp,
 		 * module.  If our search was scoped to only one module then
 		 * return immediately leaving dt_errno unmodified.
 		 */
-		if (dt_module_getctf(dtp, dmp) == NULL) {
+		if (dt_module_hasctf(dtp, dmp) == 0) {
 			if (justone)
 				return (-1);
 			continue;
@@ -1346,13 +1588,38 @@ dtrace_lookup_by_type(dtrace_hdl_t *dtp,
 		 * 'tip' and keep going in the hope that we will locate the
 		 * underlying structure definition.  Otherwise just return.
 		 */
-		if ((id = ctf_lookup_by_name(dmp->dm_ctfp, name)) != CTF_ERR) {
+		if (dmp->dm_pid == 0) {
+			id = ctf_lookup_by_name(dmp->dm_ctfp, name);
+			fp = dmp->dm_ctfp;
+		} else {
+			if ((p = strchr(name, '`')) != NULL) {
+				buf = strdup(name);
+				if (buf == NULL)
+					return (dt_set_errno(dtp, EDT_NOMEM));
+				p = strchr(buf, '`');
+				if ((q = strchr(p + 1, '`')) != NULL)
+					p = q;
+				*p = '\0';
+				fp = dt_module_getctflib(dtp, dmp, buf);
+				if (fp == NULL || (id = ctf_lookup_by_name(fp,
+				    p + 1)) == CTF_ERR)
+					id = CTF_ERR;
+				free(buf);
+			} else {
+				for (i = 0; i < dmp->dm_nctflibs; i++) {
+					fp = dmp->dm_libctfp[i];
+					id = ctf_lookup_by_name(fp, name);
+					if (id != CTF_ERR)
+						break;
+				}
+			}
+		}
+		if (id != CTF_ERR) {
 			tip->dtt_object = dmp->dm_name;
-			tip->dtt_ctfp = dmp->dm_ctfp;
+			tip->dtt_ctfp = fp;
 			tip->dtt_type = id;
-
-			if (ctf_type_kind(dmp->dm_ctfp, ctf_type_resolve(
-			    dmp->dm_ctfp, id)) != CTF_K_FORWARD)
+			if (ctf_type_kind(fp, ctf_type_resolve(fp, id)) !=
+			    CTF_K_FORWARD)
 				return (0);

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***


More information about the svn-src-all mailing list