Print this page
4474 DTrace Userland CTF Support
4475 DTrace userland Keyword
4476 DTrace tests should be better citizens
4479 pid provider types
4480 dof emulation missing checks
Reviewed by: Bryan Cantrill <bryan@joyent.com>

@@ -19,12 +19,12 @@
  * CDDL HEADER END
  */
 
 /*
  * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2011, Joyent Inc. All rights reserved.
- * Copyright (c) 2012 by Delphix. All rights reserved.
+ * Copyright (c) 2013, Joyent Inc. All rights reserved.
+ * Copyright (c) 2013 by Delphix. All rights reserved.
  */
 
 /*
  * DTrace D Language Parser
  *

@@ -190,11 +190,11 @@
 int
 dt_type_lookup(const char *s, dtrace_typeinfo_t *tip)
 {
         static const char delimiters[] = " \t\n\r\v\f*`";
         dtrace_hdl_t *dtp = yypcb->pcb_hdl;
-        const char *p, *q, *end, *obj;
+        const char *p, *q, *r, *end, *obj;
 
         for (p = s, end = s + strlen(s); *p != '\0'; p = q) {
                 while (isspace(*p))
                         p++;    /* skip leading whitespace prior to token */
 

@@ -218,12 +218,27 @@
                          * after q.  This is the type name without the object.
                          */
                         bcopy(s, type, (size_t)(p - s));
                         bcopy(q + 1, type + (size_t)(p - s), strlen(q + 1) + 1);
 
-                        if (strchr(q + 1, '`') != NULL)
-                                return (dt_set_errno(dtp, EDT_BADSCOPE));
+                        /*
+                         * There may be at most three delimeters. The second
+                         * delimeter is usually used to distinguish the type
+                         * within a given module, however, there could be a link
+                         * map id on the scene in which case that delimeter
+                         * would be the third. We determine presence of the lmid
+                         * if it rouglhly meets the from LM[0-9]
+                         */
+                        if ((r = strchr(q + 1, '`')) != NULL &&
+                            ((r = strchr(r + 1, '`')) != NULL)) {
+                                if (strchr(r + 1, '`') != NULL)
+                                        return (dt_set_errno(dtp,
+                                            EDT_BADSCOPE));
+                                if (q[1] != 'L' || q[2] != 'M')
+                                        return (dt_set_errno(dtp,
+                                            EDT_BADSCOPE));
+                        }
 
                         return (dtrace_lookup_by_type(dtp, object, type, tip));
                 }
         }
 

@@ -249,10 +264,11 @@
 {
         dtrace_hdl_t *dtp = yypcb->pcb_hdl;
         ctf_file_t *ctfp = tip->dtt_ctfp;
         ctf_id_t type = tip->dtt_type;
         ctf_id_t base = ctf_type_resolve(ctfp, type);
+        uint_t bflags = tip->dtt_flags;
 
         dt_module_t *dmp;
         ctf_id_t ptr;
 
         if ((ptr = ctf_type_pointer(ctfp, type)) != CTF_ERR ||

@@ -280,10 +296,11 @@
         }
 
         tip->dtt_object = dmp->dm_name;
         tip->dtt_ctfp = dmp->dm_ctfp;
         tip->dtt_type = ptr;
+        tip->dtt_flags = bflags;
 
         return (0);
 }
 
 const char *

@@ -383,11 +400,11 @@
 
 void
 dt_node_promote(dt_node_t *lp, dt_node_t *rp, dt_node_t *dnp)
 {
         dt_type_promote(lp, rp, &dnp->dn_ctfp, &dnp->dn_type);
-        dt_node_type_assign(dnp, dnp->dn_ctfp, dnp->dn_type);
+        dt_node_type_assign(dnp, dnp->dn_ctfp, dnp->dn_type, B_FALSE);
         dt_node_attr_assign(dnp, dt_attr_min(lp->dn_attr, rp->dn_attr));
 }
 
 const char *
 dt_node_name(const dt_node_t *dnp, char *buf, size_t len)

@@ -652,11 +669,12 @@
 
         dnp->dn_attr = attr;
 }
 
 void
-dt_node_type_assign(dt_node_t *dnp, ctf_file_t *fp, ctf_id_t type)
+dt_node_type_assign(dt_node_t *dnp, ctf_file_t *fp, ctf_id_t type,
+    boolean_t user)
 {
         ctf_id_t base = ctf_type_resolve(fp, type);
         uint_t kind = ctf_type_kind(fp, base);
         ctf_encoding_t e;
 

@@ -684,10 +702,13 @@
                 dnp->dn_flags |= DT_NF_REF;
         else if (yypcb != NULL && fp == DT_DYN_CTFP(yypcb->pcb_hdl) &&
             type == DT_DYN_TYPE(yypcb->pcb_hdl))
                 dnp->dn_flags |= DT_NF_REF;
 
+        if (user)
+                dnp->dn_flags |= DT_NF_USERLAND;
+
         dnp->dn_flags |= DT_NF_COOKED;
         dnp->dn_ctfp = fp;
         dnp->dn_type = type;
 }
 

@@ -721,10 +742,11 @@
 
 size_t
 dt_node_type_size(const dt_node_t *dnp)
 {
         ctf_id_t base;
+        dtrace_hdl_t *dtp = yypcb->pcb_hdl;
 
         if (dnp->dn_kind == DT_NODE_STRING)
                 return (strlen(dnp->dn_string) + 1);
 
         if (dt_node_is_dynamic(dnp) && dnp->dn_ident != NULL)

@@ -733,10 +755,24 @@
         base = ctf_type_resolve(dnp->dn_ctfp, dnp->dn_type);
 
         if (ctf_type_kind(dnp->dn_ctfp, base) == CTF_K_FORWARD)
                 return (0);
 
+        /*
+         * Here we have a 32-bit user pointer that is being used with a 64-bit
+         * kernel. When we're using it and its tagged as a userland reference --
+         * then we need to keep it as a 32-bit pointer. However, if we are
+         * referring to it as a kernel address, eg. being used after a copyin()
+         * then we need to make sure that we actually return the kernel's size
+         * of a pointer, 8 bytes.
+         */
+        if (ctf_type_kind(dnp->dn_ctfp, base) == CTF_K_POINTER &&
+            ctf_getmodel(dnp->dn_ctfp) == CTF_MODEL_ILP32 &&
+            !(dnp->dn_flags & DT_NF_USERLAND) &&
+            dtp->dt_conf.dtc_ctfmodel == CTF_MODEL_LP64)
+                        return (8);
+
         return (ctf_type_size(dnp->dn_ctfp, dnp->dn_type));
 }
 
 /*
  * Determine if the specified parse tree node references an identifier of the

@@ -1219,11 +1255,11 @@
 
         for (; i < sizeof (dtp->dt_ints) / sizeof (dtp->dt_ints[0]); i += n) {
                 if (value <= dtp->dt_ints[i].did_limit) {
                         dt_node_type_assign(dnp,
                             dtp->dt_ints[i].did_ctfp,
-                            dtp->dt_ints[i].did_type);
+                            dtp->dt_ints[i].did_type, B_FALSE);
 
                         /*
                          * If a prefix character is present in macro text, add
                          * in the corresponding operator node (see dt_lex.l).
                          */

@@ -1254,11 +1290,11 @@
                 longjmp(yypcb->pcb_jmpbuf, EDT_NOMEM);
 
         dnp = dt_node_alloc(DT_NODE_STRING);
         dnp->dn_op = DT_TOK_STRING;
         dnp->dn_string = string;
-        dt_node_type_assign(dnp, DT_STR_CTFP(dtp), DT_STR_TYPE(dtp));
+        dt_node_type_assign(dnp, DT_STR_CTFP(dtp), DT_STR_TYPE(dtp), B_FALSE);
 
         return (dnp);
 }
 
 dt_node_t *

@@ -1330,11 +1366,12 @@
         }
 
         dnp = dt_node_alloc(DT_NODE_TYPE);
         dnp->dn_op = DT_TOK_IDENT;
         dnp->dn_string = name;
-        dt_node_type_assign(dnp, dtt.dtt_ctfp, dtt.dtt_type);
+
+        dt_node_type_assign(dnp, dtt.dtt_ctfp, dtt.dtt_type, dtt.dtt_flags);
 
         if (dtt.dtt_ctfp == dtp->dt_cdefs->dm_ctfp ||
             dtt.dtt_ctfp == dtp->dt_ddefs->dm_ctfp)
                 dt_node_attr_assign(dnp, _dtrace_defattr);
         else

@@ -1574,11 +1611,12 @@
                  * to ensure it is fully initialized before looking at it.
                  */
                 bzero(&idn, sizeof (dt_node_t));
 
                 if (idp != NULL && idp->di_type != CTF_ERR)
-                        dt_node_type_assign(&idn, idp->di_ctfp, idp->di_type);
+                        dt_node_type_assign(&idn, idp->di_ctfp, idp->di_type,
+                            B_FALSE);
                 else if (idp != NULL)
                         (void) dt_ident_cook(&idn, idp, NULL);
 
                 if (assc) {
                         if (class == DT_DC_THIS) {

@@ -1783,11 +1821,11 @@
                 xyerror(D_UNKNOWN, "failed to determine offset of %s: %s\n",
                     name, ctf_errmsg(ctf_errno(dtt.dtt_ctfp)));
         }
 
         bzero(&dn, sizeof (dn));
-        dt_node_type_assign(&dn, dtt.dtt_ctfp, ctm.ctm_type);
+        dt_node_type_assign(&dn, dtt.dtt_ctfp, ctm.ctm_type, B_FALSE);
 
         if (dn.dn_flags & DT_NF_BITFIELD) {
                 xyerror(D_OFFSETOF_BITFIELD,
                     "cannot take offset of a bit-field: %s\n", name);
         }

@@ -1839,11 +1877,12 @@
                         xyerror(D_SIZEOF_TYPE, "cannot apply sizeof to an "
                             "operand of unknown size\n");
                 }
 
                 dt_node_type_assign(cp, dtp->dt_ddefs->dm_ctfp,
-                    ctf_lookup_by_name(dtp->dt_ddefs->dm_ctfp, "size_t"));
+                    ctf_lookup_by_name(dtp->dt_ddefs->dm_ctfp, "size_t"),
+                    B_FALSE);
 
                 cp->dn_kind = DT_NODE_INT;
                 cp->dn_op = DT_TOK_INT;
                 cp->dn_value = size;
 

@@ -1917,21 +1956,21 @@
 
                 switch (op) {
                 case DT_TOK_LOR:
                         dnp->dn_value = l || r;
                         dt_node_type_assign(dnp,
-                            DT_INT_CTFP(dtp), DT_INT_TYPE(dtp));
+                            DT_INT_CTFP(dtp), DT_INT_TYPE(dtp), B_FALSE);
                         break;
                 case DT_TOK_LXOR:
                         dnp->dn_value = (l != 0) ^ (r != 0);
                         dt_node_type_assign(dnp,
-                            DT_INT_CTFP(dtp), DT_INT_TYPE(dtp));
+                            DT_INT_CTFP(dtp), DT_INT_TYPE(dtp), B_FALSE);
                         break;
                 case DT_TOK_LAND:
                         dnp->dn_value = l && r;
                         dt_node_type_assign(dnp,
-                            DT_INT_CTFP(dtp), DT_INT_TYPE(dtp));
+                            DT_INT_CTFP(dtp), DT_INT_TYPE(dtp), B_FALSE);
                         break;
                 case DT_TOK_BOR:
                         dnp->dn_value = l | r;
                         dt_node_promote(lp, rp, dnp);
                         break;

@@ -1944,52 +1983,52 @@
                         dt_node_promote(lp, rp, dnp);
                         break;
                 case DT_TOK_EQU:
                         dnp->dn_value = l == r;
                         dt_node_type_assign(dnp,
-                            DT_INT_CTFP(dtp), DT_INT_TYPE(dtp));
+                            DT_INT_CTFP(dtp), DT_INT_TYPE(dtp), B_FALSE);
                         break;
                 case DT_TOK_NEQ:
                         dnp->dn_value = l != r;
                         dt_node_type_assign(dnp,
-                            DT_INT_CTFP(dtp), DT_INT_TYPE(dtp));
+                            DT_INT_CTFP(dtp), DT_INT_TYPE(dtp), B_FALSE);
                         break;
                 case DT_TOK_LT:
                         dt_node_promote(lp, rp, dnp);
                         if (dnp->dn_flags & DT_NF_SIGNED)
                                 dnp->dn_value = (intmax_t)l < (intmax_t)r;
                         else
                                 dnp->dn_value = l < r;
                         dt_node_type_assign(dnp,
-                            DT_INT_CTFP(dtp), DT_INT_TYPE(dtp));
+                            DT_INT_CTFP(dtp), DT_INT_TYPE(dtp), B_FALSE);
                         break;
                 case DT_TOK_LE:
                         dt_node_promote(lp, rp, dnp);
                         if (dnp->dn_flags & DT_NF_SIGNED)
                                 dnp->dn_value = (intmax_t)l <= (intmax_t)r;
                         else
                                 dnp->dn_value = l <= r;
                         dt_node_type_assign(dnp,
-                            DT_INT_CTFP(dtp), DT_INT_TYPE(dtp));
+                            DT_INT_CTFP(dtp), DT_INT_TYPE(dtp), B_FALSE);
                         break;
                 case DT_TOK_GT:
                         dt_node_promote(lp, rp, dnp);
                         if (dnp->dn_flags & DT_NF_SIGNED)
                                 dnp->dn_value = (intmax_t)l > (intmax_t)r;
                         else
                                 dnp->dn_value = l > r;
                         dt_node_type_assign(dnp,
-                            DT_INT_CTFP(dtp), DT_INT_TYPE(dtp));
+                            DT_INT_CTFP(dtp), DT_INT_TYPE(dtp), B_FALSE);
                         break;
                 case DT_TOK_GE:
                         dt_node_promote(lp, rp, dnp);
                         if (dnp->dn_flags & DT_NF_SIGNED)
                                 dnp->dn_value = (intmax_t)l >= (intmax_t)r;
                         else
                                 dnp->dn_value = l >= r;
                         dt_node_type_assign(dnp,
-                            DT_INT_CTFP(dtp), DT_INT_TYPE(dtp));
+                            DT_INT_CTFP(dtp), DT_INT_TYPE(dtp), B_FALSE);
                         break;
                 case DT_TOK_LSH:
                         dnp->dn_value = l << r;
                         dt_node_type_propagate(lp, dnp);
                         dt_node_attr_assign(rp,

@@ -2226,11 +2265,11 @@
          * If the inline identifier is not defined, then create it with the
          * orphan flag set.  We do not insert the identifier into dt_globals
          * until we have successfully cooked the right-hand expression, below.
          */
         dnp = dt_node_alloc(DT_NODE_INLINE);
-        dt_node_type_assign(dnp, dtt.dtt_ctfp, dtt.dtt_type);
+        dt_node_type_assign(dnp, dtt.dtt_ctfp, dtt.dtt_type, B_FALSE);
         dt_node_attr_assign(dnp, _dtrace_defattr);
 
         if (dt_node_is_void(dnp)) {
                 xyerror(D_DECL_VOIDOBJ,
                     "cannot declare void inline: %s\n", dsp->ds_ident);

@@ -2381,11 +2420,12 @@
         dnp = dt_node_alloc(DT_NODE_MEMBER);
         dnp->dn_membname = name;
         dnp->dn_membexpr = expr;
 
         if (ddp != NULL)
-                dt_node_type_assign(dnp, dtt.dtt_ctfp, dtt.dtt_type);
+                dt_node_type_assign(dnp, dtt.dtt_ctfp, dtt.dtt_type,
+                    dtt.dtt_flags);
 
         return (dnp);
 }
 
 dt_node_t *

@@ -2412,14 +2452,14 @@
                 free(name);
                 longjmp(yypcb->pcb_jmpbuf, EDT_COMPILER);
         }
 
         bzero(&sn, sizeof (sn));
-        dt_node_type_assign(&sn, src.dtt_ctfp, src.dtt_type);
+        dt_node_type_assign(&sn, src.dtt_ctfp, src.dtt_type, B_FALSE);
 
         bzero(&dn, sizeof (dn));
-        dt_node_type_assign(&dn, dst.dtt_ctfp, dst.dtt_type);
+        dt_node_type_assign(&dn, dst.dtt_ctfp, dst.dtt_type, B_FALSE);
 
         if (dt_xlator_lookup(dtp, &sn, &dn, DT_XLATE_EXACT) != NULL) {
                 xyerror(D_XLATE_REDECL,
                     "translator from %s to %s has already been declared\n",
                     dt_node_type_name(&sn, n1, sizeof (n1)),

@@ -2661,11 +2701,11 @@
                 if (idp->di_kind != DT_IDENT_ARRAY &&
                     idp->di_kind != DT_IDENT_AGG)
                         attr = dt_ident_cook(dnp, idp, NULL);
                 else {
                         dt_node_type_assign(dnp,
-                            DT_DYN_CTFP(dtp), DT_DYN_TYPE(dtp));
+                            DT_DYN_CTFP(dtp), DT_DYN_TYPE(dtp), B_FALSE);
                         attr = idp->di_attr;
                 }
 
                 free(dnp->dn_string);
                 dnp->dn_string = NULL;

@@ -2737,11 +2777,12 @@
                 dnp->dn_string = NULL;
                 dnp->dn_kind = DT_NODE_SYM;
                 dnp->dn_ident = idp;
                 dnp->dn_flags |= DT_NF_LVALUE;
 
-                dt_node_type_assign(dnp, dtt.dtt_ctfp, dtt.dtt_type);
+                dt_node_type_assign(dnp, dtt.dtt_ctfp, dtt.dtt_type,
+                    dtt.dtt_flags);
                 dt_node_attr_assign(dnp, _dtrace_symattr);
 
                 if (uref) {
                         idp->di_flags |= DT_IDFLG_USER;
                         dnp->dn_flags |= DT_NF_USERLAND;

@@ -2785,11 +2826,11 @@
                 if (idp->di_kind != DT_IDENT_ARRAY &&
                     idp->di_kind != DT_IDENT_AGG)
                         attr = dt_ident_cook(dnp, idp, NULL);
                 else {
                         dt_node_type_assign(dnp,
-                            DT_DYN_CTFP(dtp), DT_DYN_TYPE(dtp));
+                            DT_DYN_CTFP(dtp), DT_DYN_TYPE(dtp), B_FALSE);
                         attr = idp->di_attr;
                 }
 
                 free(dnp->dn_string);
                 dnp->dn_string = NULL;

@@ -2888,11 +2929,12 @@
         if (cp->dn_kind == DT_NODE_VAR && dt_ident_unref(cp->dn_ident)) {
                 if (dt_type_lookup("int64_t", &dtt) != 0)
                         xyerror(D_TYPE_ERR, "failed to lookup int64_t\n");
 
                 dt_ident_type_assign(cp->dn_ident, dtt.dtt_ctfp, dtt.dtt_type);
-                dt_node_type_assign(cp, dtt.dtt_ctfp, dtt.dtt_type);
+                dt_node_type_assign(cp, dtt.dtt_ctfp, dtt.dtt_type,
+                    dtt.dtt_flags);
         }
 
         if (cp->dn_kind == DT_NODE_VAR)
                 cp->dn_ident->di_flags |= idflags;
 

@@ -2905,11 +2947,12 @@
                 if ((idp = dt_node_resolve(cp, DT_IDENT_XLPTR)) != NULL) {
                         dt_xlator_t *dxp = idp->di_data;
 
                         dnp->dn_ident = &dxp->dx_souid;
                         dt_node_type_assign(dnp,
-                            dnp->dn_ident->di_ctfp, dnp->dn_ident->di_type);
+                            dnp->dn_ident->di_ctfp, dnp->dn_ident->di_type,
+                            cp->dn_flags & DT_NF_USERLAND);
                         break;
                 }
 
                 type = ctf_type_resolve(cp->dn_ctfp, cp->dn_type);
                 kind = ctf_type_kind(cp->dn_ctfp, type);

@@ -2925,11 +2968,12 @@
                 } else {
                         xyerror(D_DEREF_NONPTR,
                             "cannot dereference non-pointer type\n");
                 }
 
-                dt_node_type_assign(dnp, cp->dn_ctfp, type);
+                dt_node_type_assign(dnp, cp->dn_ctfp, type,
+                    cp->dn_flags & DT_NF_USERLAND);
                 base = ctf_type_resolve(cp->dn_ctfp, type);
                 kind = ctf_type_kind(cp->dn_ctfp, base);
 
                 if (kind == CTF_K_INTEGER && ctf_type_encoding(cp->dn_ctfp,
                     base, &e) == 0 && IS_VOID(e)) {

@@ -2982,11 +3026,12 @@
         case DT_TOK_LNEG:
                 if (!dt_node_is_scalar(cp)) {
                         xyerror(D_OP_SCALAR, "operator %s requires an operand "
                             "of scalar type\n", opstr(dnp->dn_op));
                 }
-                dt_node_type_assign(dnp, DT_INT_CTFP(dtp), DT_INT_TYPE(dtp));
+                dt_node_type_assign(dnp, DT_INT_CTFP(dtp), DT_INT_TYPE(dtp),
+                    B_FALSE);
                 break;
 
         case DT_TOK_ADDROF:
                 if (cp->dn_kind == DT_NODE_VAR || cp->dn_kind == DT_NODE_AGG) {
                         xyerror(D_ADDROF_VAR,

@@ -3015,14 +3060,12 @@
                 if (dt_type_pointer(&dtt) == -1) {
                         xyerror(D_TYPE_ERR, "cannot find type for \"&\": %s*\n",
                             dt_node_type_name(cp, n, sizeof (n)));
                 }
 
-                dt_node_type_assign(dnp, dtt.dtt_ctfp, dtt.dtt_type);
-
-                if (cp->dn_flags & DT_NF_USERLAND)
-                        dnp->dn_flags |= DT_NF_USERLAND;
+                dt_node_type_assign(dnp, dtt.dtt_ctfp, dtt.dtt_type,
+                    cp->dn_flags & DT_NF_USERLAND);
                 break;
 
         case DT_TOK_SIZEOF:
                 if (cp->dn_flags & DT_NF_BITFIELD) {
                         xyerror(D_SIZEOF_BITFIELD,

@@ -3033,21 +3076,23 @@
                         xyerror(D_SIZEOF_TYPE, "cannot apply sizeof to an "
                             "operand of unknown size\n");
                 }
 
                 dt_node_type_assign(dnp, dtp->dt_ddefs->dm_ctfp,
-                    ctf_lookup_by_name(dtp->dt_ddefs->dm_ctfp, "size_t"));
+                    ctf_lookup_by_name(dtp->dt_ddefs->dm_ctfp, "size_t"),
+                    B_FALSE);
                 break;
 
         case DT_TOK_STRINGOF:
                 if (!dt_node_is_scalar(cp) && !dt_node_is_pointer(cp) &&
                     !dt_node_is_strcompat(cp)) {
                         xyerror(D_STRINGOF_TYPE,
                             "cannot apply stringof to a value of type %s\n",
                             dt_node_type_name(cp, n, sizeof (n)));
                 }
-                dt_node_type_assign(dnp, DT_STR_CTFP(dtp), DT_STR_TYPE(dtp));
+                dt_node_type_assign(dnp, DT_STR_CTFP(dtp), DT_STR_TYPE(dtp),
+                    cp->dn_flags & DT_NF_USERLAND);
                 break;
 
         case DT_TOK_PREINC:
         case DT_TOK_POSTINC:
         case DT_TOK_PREDEC:

@@ -3236,11 +3281,12 @@
                 if (!dt_node_is_scalar(lp) || !dt_node_is_scalar(rp)) {
                         xyerror(D_OP_SCALAR, "operator %s requires operands "
                             "of scalar type\n", opstr(op));
                 }
 
-                dt_node_type_assign(dnp, DT_INT_CTFP(dtp), DT_INT_TYPE(dtp));
+                dt_node_type_assign(dnp, DT_INT_CTFP(dtp), DT_INT_TYPE(dtp),
+                    B_FALSE);
                 dt_node_attr_assign(dnp, dt_attr_min(lp->dn_attr, rp->dn_attr));
                 break;
 
         case DT_TOK_LT:
         case DT_TOK_LE:

@@ -3280,11 +3326,12 @@
                         rp->dn_kind = DT_NODE_INT;
                         rp->dn_flags |= DT_NF_COOKED;
                         rp->dn_op = DT_TOK_INT;
                         rp->dn_value = (intmax_t)val;
 
-                        dt_node_type_assign(rp, lp->dn_ctfp, lp->dn_type);
+                        dt_node_type_assign(rp, lp->dn_ctfp, lp->dn_type,
+                            B_FALSE);
                         dt_node_attr_assign(rp, _dtrace_symattr);
                 }
 
                 rp = dnp->dn_right = dt_node_cook(rp, DT_IDFLG_REF);
 

@@ -3312,11 +3359,12 @@
                             "incompatible types: \"%s\" %s \"%s\"\n",
                             dt_node_type_name(lp, n1, sizeof (n1)), opstr(op),
                             dt_node_type_name(rp, n2, sizeof (n2)));
                 }
 
-                dt_node_type_assign(dnp, DT_INT_CTFP(dtp), DT_INT_TYPE(dtp));
+                dt_node_type_assign(dnp, DT_INT_CTFP(dtp), DT_INT_TYPE(dtp),
+                    B_FALSE);
                 dt_node_attr_assign(dnp, dt_attr_min(lp->dn_attr, rp->dn_attr));
                 break;
 
         case DT_TOK_ADD:
         case DT_TOK_SUB: {

@@ -3360,11 +3408,11 @@
                             "types: \"%s\" %s \"%s\"\n",
                             dt_node_type_name(lp, n1, sizeof (n1)), opstr(op),
                             dt_node_type_name(rp, n2, sizeof (n2)));
                 }
 
-                dt_node_type_assign(dnp, ctfp, type);
+                dt_node_type_assign(dnp, ctfp, type, B_FALSE);
                 dt_node_attr_assign(dnp, dt_attr_min(lp->dn_attr, rp->dn_attr));
 
                 if (uref)
                         dnp->dn_flags |= DT_NF_USERLAND;
                 break;

@@ -3501,11 +3549,11 @@
                  * variable created by this compilation pass, reset the type of
                  * this variable to the type of the right-hand side.
                  */
                 if (lp->dn_kind == DT_NODE_VAR &&
                     dt_ident_unref(lp->dn_ident)) {
-                        dt_node_type_assign(lp, ctfp, type);
+                        dt_node_type_assign(lp, ctfp, type, B_FALSE);
                         dt_ident_type_assign(lp->dn_ident, ctfp, type);
 
                         if (uref) {
                                 lp->dn_flags |= DT_NF_USERLAND;
                                 lp->dn_ident->di_flags |= DT_IDFLG_USER;

@@ -3715,11 +3763,11 @@
                 }
 
                 type = ctf_type_resolve(ctfp, m.ctm_type);
                 kind = ctf_type_kind(ctfp, type);
 
-                dt_node_type_assign(dnp, ctfp, m.ctm_type);
+                dt_node_type_assign(dnp, ctfp, m.ctm_type, B_FALSE);
                 dt_node_attr_assign(dnp, lp->dn_attr);
 
                 if (op == DT_TOK_PTR && (kind != CTF_K_ARRAY ||
                     dt_node_is_string(dnp)))
                         dnp->dn_flags |= DT_NF_LVALUE; /* see K&R[A7.3.3] */

@@ -3841,11 +3889,12 @@
                             dt_node_type_name(rp, n1, sizeof (n1)),
                             dt_node_type_name(lp, n2, sizeof (n2)));
                 }
 
                 dnp->dn_ident = dt_xlator_ident(dxp, lp->dn_ctfp, lp->dn_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);
                 dt_node_attr_assign(dnp,
                     dt_attr_min(rp->dn_attr, dnp->dn_ident->di_attr));
                 break;
         }
 

@@ -4006,11 +4055,11 @@
         if (dt_node_is_actfunc(lp) || dt_node_is_actfunc(rp)) {
                 xyerror(D_OP_ACT, "action cannot be "
                     "used in a conditional context\n");
         }
 
-        dt_node_type_assign(dnp, ctfp, type);
+        dt_node_type_assign(dnp, ctfp, type, B_FALSE);
         dt_node_attr_assign(dnp, dt_attr_min(dnp->dn_expr->dn_attr,
             dt_attr_min(lp->dn_attr, rp->dn_attr)));
 
         return (dnp);
 }

@@ -4039,11 +4088,12 @@
         if (dnp->dn_aggfun != NULL) {
                 dnp->dn_aggfun = dt_node_cook(dnp->dn_aggfun, DT_IDFLG_REF);
                 dt_node_attr_assign(dnp, dt_ident_cook(dnp,
                     dnp->dn_ident, &dnp->dn_aggtup));
         } else {
-                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);
                 dt_node_attr_assign(dnp, dnp->dn_ident->di_attr);
         }
 
         return (dnp);
 }

@@ -4241,11 +4291,12 @@
                             mnp->dn_membname, ctf_type_name(dxp->dx_dst_ctfp,
                             dxp->dx_dst_type, n1, sizeof (n1)));
                 }
 
                 (void) dt_node_cook(mnp, DT_IDFLG_REF);
-                dt_node_type_assign(mnp, dxp->dx_dst_ctfp, ctm.ctm_type);
+                dt_node_type_assign(mnp, dxp->dx_dst_ctfp, ctm.ctm_type,
+                    B_FALSE);
                 attr = dt_attr_min(attr, mnp->dn_attr);
 
                 if (dt_node_is_argcompat(mnp, mnp->dn_membexpr) == 0) {
                         xyerror(D_XLATE_INCOMPAT,
                             "translator member %s definition uses "

@@ -4260,11 +4311,11 @@
         dt_idstack_pop(&yypcb->pcb_globals, dxp->dx_locals);
 
         dxp->dx_souid.di_attr = attr;
         dxp->dx_ptrid.di_attr = attr;
 
-        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);
         dt_node_attr_assign(dnp, _dtrace_defattr);
 
         return (dnp);
 }
 

@@ -4553,11 +4604,13 @@
                 tp->dtdt_kind = DIF_TYPE_CTF;
                 tp->dtdt_ckind = ctf_type_kind(dnp->dn_ctfp,
                     ctf_type_resolve(dnp->dn_ctfp, dnp->dn_type));
         }
 
-        tp->dtdt_flags = (dnp->dn_flags & DT_NF_REF) ? DIF_TF_BYREF : 0;
+        tp->dtdt_flags = (dnp->dn_flags & DT_NF_REF) ?
+            (dnp->dn_flags & DT_NF_USERLAND) ? DIF_TF_BYUREF :
+            DIF_TF_BYREF : 0;
         tp->dtdt_pad = 0;
         tp->dtdt_size = ctf_type_size(dnp->dn_ctfp, dnp->dn_type);
 }
 
 void