diff options
Diffstat (limited to 'cddl/contrib/opensolaris/lib/libdtrace/common/dt_cc.c')
-rw-r--r-- | cddl/contrib/opensolaris/lib/libdtrace/common/dt_cc.c | 78 |
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 || |