aboutsummaryrefslogtreecommitdiff
path: root/cddl/contrib/opensolaris/lib/libdtrace/common/dt_cc.c
diff options
context:
space:
mode:
Diffstat (limited to 'cddl/contrib/opensolaris/lib/libdtrace/common/dt_cc.c')
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dt_cc.c78
1 files changed, 67 insertions, 11 deletions
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_cc.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_cc.c
index d5423f634d6f..57009935f937 100644
--- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_cc.c
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_cc.c
@@ -22,6 +22,7 @@
/*
* 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.
*/
/*
@@ -663,18 +664,48 @@ static void
dt_action_trace(dtrace_hdl_t *dtp, dt_node_t *dnp, dtrace_stmtdesc_t *sdp)
{
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";
if (dt_node_is_void(dnp->dn_args)) {
- dnerror(dnp->dn_args, D_TRACE_VOID,
- "trace( ) may not be applied to a void expression\n");
+ dnerror(dnp->dn_args, istrace ? D_TRACE_VOID : D_PRINT_VOID,
+ "%s( ) may not be applied to a void expression\n", act);
}
- if (dt_node_is_dynamic(dnp->dn_args)) {
- dnerror(dnp->dn_args, D_TRACE_DYN,
- "trace( ) may not be applied to a dynamic expression\n");
+ if (dt_node_resolve(dnp->dn_args, DT_IDENT_XLPTR) != NULL) {
+ dnerror(dnp->dn_args, istrace ? D_TRACE_DYN : D_PRINT_DYN,
+ "%s( ) may not be applied to a translated pointer\n", act);
}
dt_cg(yypcb, dnp->dn_args);
+
+ /*
+ * The print() action behaves identically to trace(), except that it
+ * stores the CTF type of the argument (if present) within the DOF for
+ * the DIFEXPR action. To do this, we set the 'dtsd_strdata' to point
+ * to the fully-qualified CTF type ID for the result of the DIF
+ * action. We use the ID instead of the name to handles complex types
+ * 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.
+ */
+ if (dnp->dn_ident->di_id == DT_ACT_PRINT) {
+ dt_node_t *dret;
+ size_t n;
+ dt_module_t *dmp;
+
+ dret = yypcb->pcb_dret;
+ dmp = dt_module_lookup_by_ctf(dtp, dret->dn_ctfp);
+
+ 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);
+ }
+
ap->dtad_difo = dt_as(yypcb);
ap->dtad_kind = DTRACEACT_DIFEXPR;
}
@@ -685,7 +716,8 @@ dt_action_tracemem(dtrace_hdl_t *dtp, dt_node_t *dnp, dtrace_stmtdesc_t *sdp)
dtrace_actdesc_t *ap = dt_stmt_action(dtp, sdp);
dt_node_t *addr = dnp->dn_args;
- dt_node_t *size = dnp->dn_args->dn_list;
+ dt_node_t *max = dnp->dn_args->dn_list;
+ dt_node_t *size;
char n[DT_TYPE_NAMELEN];
@@ -697,17 +729,37 @@ dt_action_tracemem(dtrace_hdl_t *dtp, dt_node_t *dnp, dtrace_stmtdesc_t *sdp)
dt_node_type_name(addr, n, sizeof (n)));
}
- if (dt_node_is_posconst(size) == 0) {
- dnerror(size, D_TRACEMEM_SIZE, "tracemem( ) argument #2 must "
+ if (dt_node_is_posconst(max) == 0) {
+ dnerror(max, D_TRACEMEM_SIZE, "tracemem( ) argument #2 must "
"be a non-zero positive integral constant expression\n");
}
+ if ((size = max->dn_list) != NULL) {
+ if (size->dn_list != NULL) {
+ dnerror(size, D_TRACEMEM_ARGS, "tracemem ( ) prototype "
+ "mismatch: expected at most 3 args\n");
+ }
+
+ if (!dt_node_is_scalar(size)) {
+ dnerror(size, D_TRACEMEM_DYNSIZE, "tracemem ( ) "
+ "dynamic size (argument #3) must be of "
+ "scalar type\n");
+ }
+
+ dt_cg(yypcb, size);
+ ap->dtad_difo = dt_as(yypcb);
+ ap->dtad_difo->dtdo_rtype = dt_int_rtype;
+ ap->dtad_kind = DTRACEACT_TRACEMEM_DYNSIZE;
+
+ ap = dt_stmt_action(dtp, sdp);
+ }
+
dt_cg(yypcb, addr);
ap->dtad_difo = dt_as(yypcb);
- ap->dtad_kind = DTRACEACT_DIFEXPR;
+ ap->dtad_kind = DTRACEACT_TRACEMEM;
ap->dtad_difo->dtdo_rtype.dtdt_flags |= DIF_TF_BYREF;
- ap->dtad_difo->dtdo_rtype.dtdt_size = size->dn_value;
+ ap->dtad_difo->dtdo_rtype.dtdt_size = max->dn_value;
}
static void
@@ -1078,6 +1130,9 @@ dt_compile_fun(dtrace_hdl_t *dtp, dt_node_t *dnp, dtrace_stmtdesc_t *sdp)
case DT_ACT_PANIC:
dt_action_panic(dtp, dnp->dn_expr, sdp);
break;
+ case DT_ACT_PRINT:
+ dt_action_trace(dtp, dnp->dn_expr, sdp);
+ break;
case DT_ACT_PRINTA:
dt_action_printa(dtp, dnp->dn_expr, sdp);
break;
@@ -2489,7 +2544,8 @@ dt_compile(dtrace_hdl_t *dtp, int context, dtrace_probespec_t pspec, void *arg,
}
out:
- if (context != DT_CTX_DTYPE && DT_TREEDUMP_PASS(dtp, 3))
+ if (context != DT_CTX_DTYPE && yypcb->pcb_root != NULL &&
+ DT_TREEDUMP_PASS(dtp, 3))
dt_node_printr(yypcb->pcb_root, stderr, 0);
if (dtp->dt_cdefs_fd != -1 && (ftruncate64(dtp->dt_cdefs_fd, 0) == -1 ||