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 ***
_______________________________________________
[email protected] mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "[email protected]"

Reply via email to