17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 57c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 67c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 77c478bd9Sstevel@tonic-gate * with the License. 87c478bd9Sstevel@tonic-gate * 97c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 107c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 117c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 127c478bd9Sstevel@tonic-gate * and limitations under the License. 137c478bd9Sstevel@tonic-gate * 147c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 157c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 167c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 177c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 187c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 197c478bd9Sstevel@tonic-gate * 207c478bd9Sstevel@tonic-gate * CDDL HEADER END 217c478bd9Sstevel@tonic-gate */ 227c478bd9Sstevel@tonic-gate /* 237c478bd9Sstevel@tonic-gate * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 247c478bd9Sstevel@tonic-gate * Use is subject to license terms. 257c478bd9Sstevel@tonic-gate */ 267c478bd9Sstevel@tonic-gate 277c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 287c478bd9Sstevel@tonic-gate 297c478bd9Sstevel@tonic-gate #include <unistd.h> 307c478bd9Sstevel@tonic-gate #include <strings.h> 317c478bd9Sstevel@tonic-gate #include <stdlib.h> 327c478bd9Sstevel@tonic-gate #include <errno.h> 337c478bd9Sstevel@tonic-gate #include <assert.h> 347c478bd9Sstevel@tonic-gate 357c478bd9Sstevel@tonic-gate #include <dt_impl.h> 36*1a7c1b72Smws #include <dt_program.h> 377c478bd9Sstevel@tonic-gate #include <dt_printf.h> 387c478bd9Sstevel@tonic-gate 397c478bd9Sstevel@tonic-gate dtrace_prog_t * 40*1a7c1b72Smws dt_program_create(dtrace_hdl_t *dtp) 417c478bd9Sstevel@tonic-gate { 42*1a7c1b72Smws dtrace_prog_t *pgp = dt_zalloc(dtp, sizeof (dtrace_prog_t)); 437c478bd9Sstevel@tonic-gate 447c478bd9Sstevel@tonic-gate if (pgp != NULL) 457c478bd9Sstevel@tonic-gate dt_list_append(&dtp->dt_programs, pgp); 467c478bd9Sstevel@tonic-gate else 477c478bd9Sstevel@tonic-gate (void) dt_set_errno(dtp, EDT_NOMEM); 487c478bd9Sstevel@tonic-gate 497c478bd9Sstevel@tonic-gate return (pgp); 507c478bd9Sstevel@tonic-gate } 517c478bd9Sstevel@tonic-gate 527c478bd9Sstevel@tonic-gate void 53*1a7c1b72Smws dt_program_destroy(dtrace_hdl_t *dtp, dtrace_prog_t *pgp) 547c478bd9Sstevel@tonic-gate { 557c478bd9Sstevel@tonic-gate dt_stmt_t *stp, *next; 56*1a7c1b72Smws uint_t i; 577c478bd9Sstevel@tonic-gate 587c478bd9Sstevel@tonic-gate for (stp = dt_list_next(&pgp->dp_stmts); stp != NULL; stp = next) { 597c478bd9Sstevel@tonic-gate next = dt_list_next(stp); 60*1a7c1b72Smws dtrace_stmt_destroy(dtp, stp->ds_desc); 61*1a7c1b72Smws dt_free(dtp, stp); 627c478bd9Sstevel@tonic-gate } 637c478bd9Sstevel@tonic-gate 64*1a7c1b72Smws for (i = 0; i < pgp->dp_xrefslen; i++) 65*1a7c1b72Smws dt_free(dtp, pgp->dp_xrefs[i]); 66*1a7c1b72Smws 67*1a7c1b72Smws dt_free(dtp, pgp->dp_xrefs); 687c478bd9Sstevel@tonic-gate dt_list_delete(&dtp->dt_programs, pgp); 69*1a7c1b72Smws dt_free(dtp, pgp); 707c478bd9Sstevel@tonic-gate } 717c478bd9Sstevel@tonic-gate 727c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 737c478bd9Sstevel@tonic-gate void 747c478bd9Sstevel@tonic-gate dtrace_program_info(dtrace_hdl_t *dtp, dtrace_prog_t *pgp, 757c478bd9Sstevel@tonic-gate dtrace_proginfo_t *pip) 767c478bd9Sstevel@tonic-gate { 777c478bd9Sstevel@tonic-gate dt_stmt_t *stp; 787c478bd9Sstevel@tonic-gate dtrace_actdesc_t *ap; 797c478bd9Sstevel@tonic-gate dtrace_ecbdesc_t *last = NULL; 807c478bd9Sstevel@tonic-gate 817c478bd9Sstevel@tonic-gate if (pip == NULL) 827c478bd9Sstevel@tonic-gate return; 837c478bd9Sstevel@tonic-gate 847c478bd9Sstevel@tonic-gate bzero(pip, sizeof (dtrace_proginfo_t)); 857c478bd9Sstevel@tonic-gate 867c478bd9Sstevel@tonic-gate if (dt_list_next(&pgp->dp_stmts) != NULL) { 877c478bd9Sstevel@tonic-gate pip->dpi_descattr = _dtrace_maxattr; 887c478bd9Sstevel@tonic-gate pip->dpi_stmtattr = _dtrace_maxattr; 897c478bd9Sstevel@tonic-gate } else { 907c478bd9Sstevel@tonic-gate pip->dpi_descattr = _dtrace_defattr; 917c478bd9Sstevel@tonic-gate pip->dpi_stmtattr = _dtrace_defattr; 927c478bd9Sstevel@tonic-gate } 937c478bd9Sstevel@tonic-gate 947c478bd9Sstevel@tonic-gate for (stp = dt_list_next(&pgp->dp_stmts); stp; stp = dt_list_next(stp)) { 957c478bd9Sstevel@tonic-gate dtrace_ecbdesc_t *edp = stp->ds_desc->dtsd_ecbdesc; 967c478bd9Sstevel@tonic-gate 977c478bd9Sstevel@tonic-gate if (edp == last) 987c478bd9Sstevel@tonic-gate continue; 997c478bd9Sstevel@tonic-gate last = edp; 1007c478bd9Sstevel@tonic-gate 1017c478bd9Sstevel@tonic-gate pip->dpi_descattr = 1027c478bd9Sstevel@tonic-gate dt_attr_min(stp->ds_desc->dtsd_descattr, pip->dpi_descattr); 1037c478bd9Sstevel@tonic-gate 1047c478bd9Sstevel@tonic-gate pip->dpi_stmtattr = 1057c478bd9Sstevel@tonic-gate dt_attr_min(stp->ds_desc->dtsd_stmtattr, pip->dpi_stmtattr); 1067c478bd9Sstevel@tonic-gate 1077c478bd9Sstevel@tonic-gate /* 1087c478bd9Sstevel@tonic-gate * If there aren't any actions, account for the fact that 1097c478bd9Sstevel@tonic-gate * recording the epid will generate a record. 1107c478bd9Sstevel@tonic-gate */ 1117c478bd9Sstevel@tonic-gate if (edp->dted_action == NULL) 1127c478bd9Sstevel@tonic-gate pip->dpi_recgens++; 1137c478bd9Sstevel@tonic-gate 1147c478bd9Sstevel@tonic-gate for (ap = edp->dted_action; ap != NULL; ap = ap->dtad_next) { 1157c478bd9Sstevel@tonic-gate if (ap->dtad_kind == DTRACEACT_SPECULATE) { 1167c478bd9Sstevel@tonic-gate pip->dpi_speculations++; 1177c478bd9Sstevel@tonic-gate continue; 1187c478bd9Sstevel@tonic-gate } 1197c478bd9Sstevel@tonic-gate 1207c478bd9Sstevel@tonic-gate if (DTRACEACT_ISAGG(ap->dtad_kind)) { 1217c478bd9Sstevel@tonic-gate pip->dpi_recgens -= ap->dtad_arg; 1227c478bd9Sstevel@tonic-gate pip->dpi_aggregates++; 1237c478bd9Sstevel@tonic-gate continue; 1247c478bd9Sstevel@tonic-gate } 1257c478bd9Sstevel@tonic-gate 1267c478bd9Sstevel@tonic-gate if (DTRACEACT_ISDESTRUCTIVE(ap->dtad_kind)) 1277c478bd9Sstevel@tonic-gate continue; 1287c478bd9Sstevel@tonic-gate 1297c478bd9Sstevel@tonic-gate if (ap->dtad_kind == DTRACEACT_DIFEXPR && 1307c478bd9Sstevel@tonic-gate ap->dtad_difo->dtdo_rtype.dtdt_kind == 1317c478bd9Sstevel@tonic-gate DIF_TYPE_CTF && 1327c478bd9Sstevel@tonic-gate ap->dtad_difo->dtdo_rtype.dtdt_size == 0) 1337c478bd9Sstevel@tonic-gate continue; 1347c478bd9Sstevel@tonic-gate 1357c478bd9Sstevel@tonic-gate pip->dpi_recgens++; 1367c478bd9Sstevel@tonic-gate } 1377c478bd9Sstevel@tonic-gate } 1387c478bd9Sstevel@tonic-gate } 1397c478bd9Sstevel@tonic-gate 1407c478bd9Sstevel@tonic-gate int 1417c478bd9Sstevel@tonic-gate dtrace_program_exec(dtrace_hdl_t *dtp, dtrace_prog_t *pgp, 1427c478bd9Sstevel@tonic-gate dtrace_proginfo_t *pip) 1437c478bd9Sstevel@tonic-gate { 1447c478bd9Sstevel@tonic-gate void *dof; 1457c478bd9Sstevel@tonic-gate int n, err; 1467c478bd9Sstevel@tonic-gate 1477c478bd9Sstevel@tonic-gate dtrace_program_info(dtp, pgp, pip); 1487c478bd9Sstevel@tonic-gate 1497c478bd9Sstevel@tonic-gate if ((dof = dtrace_dof_create(dtp, pgp, DTRACE_D_STRIP)) == NULL) 1507c478bd9Sstevel@tonic-gate return (-1); 1517c478bd9Sstevel@tonic-gate 1527c478bd9Sstevel@tonic-gate n = dt_ioctl(dtp, DTRACEIOC_ENABLE, dof); 1537c478bd9Sstevel@tonic-gate dtrace_dof_destroy(dtp, dof); 1547c478bd9Sstevel@tonic-gate 1557c478bd9Sstevel@tonic-gate if (n == -1) { 1567c478bd9Sstevel@tonic-gate switch (errno) { 1577c478bd9Sstevel@tonic-gate case EINVAL: 1587c478bd9Sstevel@tonic-gate err = EDT_DIFINVAL; 1597c478bd9Sstevel@tonic-gate break; 1607c478bd9Sstevel@tonic-gate case EFAULT: 1617c478bd9Sstevel@tonic-gate err = EDT_DIFFAULT; 1627c478bd9Sstevel@tonic-gate break; 1637c478bd9Sstevel@tonic-gate case E2BIG: 1647c478bd9Sstevel@tonic-gate err = EDT_DIFSIZE; 1657c478bd9Sstevel@tonic-gate break; 1667c478bd9Sstevel@tonic-gate default: 1677c478bd9Sstevel@tonic-gate err = errno; 1687c478bd9Sstevel@tonic-gate } 1697c478bd9Sstevel@tonic-gate 1707c478bd9Sstevel@tonic-gate return (dt_set_errno(dtp, err)); 1717c478bd9Sstevel@tonic-gate } 1727c478bd9Sstevel@tonic-gate 1737c478bd9Sstevel@tonic-gate if (pip != NULL) 1747c478bd9Sstevel@tonic-gate pip->dpi_matches += n; 1757c478bd9Sstevel@tonic-gate 1767c478bd9Sstevel@tonic-gate return (0); 1777c478bd9Sstevel@tonic-gate } 1787c478bd9Sstevel@tonic-gate 179*1a7c1b72Smws static void 180*1a7c1b72Smws dt_ecbdesc_hold(dtrace_ecbdesc_t *edp) 1817c478bd9Sstevel@tonic-gate { 1827c478bd9Sstevel@tonic-gate edp->dted_refcnt++; 1837c478bd9Sstevel@tonic-gate } 1847c478bd9Sstevel@tonic-gate 1857c478bd9Sstevel@tonic-gate void 186*1a7c1b72Smws dt_ecbdesc_release(dtrace_hdl_t *dtp, dtrace_ecbdesc_t *edp) 1877c478bd9Sstevel@tonic-gate { 1887c478bd9Sstevel@tonic-gate if (--edp->dted_refcnt > 0) 1897c478bd9Sstevel@tonic-gate return; 1907c478bd9Sstevel@tonic-gate 191*1a7c1b72Smws dt_difo_free(dtp, edp->dted_pred.dtpdd_difo); 1927c478bd9Sstevel@tonic-gate assert(edp->dted_action == NULL); 193*1a7c1b72Smws dt_free(dtp, edp); 1947c478bd9Sstevel@tonic-gate } 1957c478bd9Sstevel@tonic-gate 1967c478bd9Sstevel@tonic-gate dtrace_ecbdesc_t * 197*1a7c1b72Smws dt_ecbdesc_create(dtrace_hdl_t *dtp, const dtrace_probedesc_t *pdp) 1987c478bd9Sstevel@tonic-gate { 1997c478bd9Sstevel@tonic-gate dtrace_ecbdesc_t *edp; 2007c478bd9Sstevel@tonic-gate 201*1a7c1b72Smws if ((edp = dt_zalloc(dtp, sizeof (dtrace_ecbdesc_t))) == NULL) { 2027c478bd9Sstevel@tonic-gate (void) dt_set_errno(dtp, EDT_NOMEM); 2037c478bd9Sstevel@tonic-gate return (NULL); 2047c478bd9Sstevel@tonic-gate } 2057c478bd9Sstevel@tonic-gate 2067c478bd9Sstevel@tonic-gate edp->dted_probe = *pdp; 207*1a7c1b72Smws dt_ecbdesc_hold(edp); 2087c478bd9Sstevel@tonic-gate return (edp); 2097c478bd9Sstevel@tonic-gate } 2107c478bd9Sstevel@tonic-gate 2117c478bd9Sstevel@tonic-gate dtrace_stmtdesc_t * 2127c478bd9Sstevel@tonic-gate dtrace_stmt_create(dtrace_hdl_t *dtp, dtrace_ecbdesc_t *edp) 2137c478bd9Sstevel@tonic-gate { 2147c478bd9Sstevel@tonic-gate dtrace_stmtdesc_t *sdp; 2157c478bd9Sstevel@tonic-gate 216*1a7c1b72Smws if ((sdp = dt_zalloc(dtp, sizeof (dtrace_stmtdesc_t))) == NULL) 2177c478bd9Sstevel@tonic-gate return (NULL); 2187c478bd9Sstevel@tonic-gate 219*1a7c1b72Smws dt_ecbdesc_hold(edp); 2207c478bd9Sstevel@tonic-gate sdp->dtsd_ecbdesc = edp; 2217c478bd9Sstevel@tonic-gate sdp->dtsd_descattr = _dtrace_defattr; 2227c478bd9Sstevel@tonic-gate sdp->dtsd_stmtattr = _dtrace_defattr; 2237c478bd9Sstevel@tonic-gate 2247c478bd9Sstevel@tonic-gate return (sdp); 2257c478bd9Sstevel@tonic-gate } 2267c478bd9Sstevel@tonic-gate 2277c478bd9Sstevel@tonic-gate dtrace_actdesc_t * 2287c478bd9Sstevel@tonic-gate dtrace_stmt_action(dtrace_hdl_t *dtp, dtrace_stmtdesc_t *sdp) 2297c478bd9Sstevel@tonic-gate { 2307c478bd9Sstevel@tonic-gate dtrace_actdesc_t *new; 2317c478bd9Sstevel@tonic-gate dtrace_ecbdesc_t *edp = sdp->dtsd_ecbdesc; 2327c478bd9Sstevel@tonic-gate 233*1a7c1b72Smws if ((new = dt_alloc(dtp, sizeof (dtrace_actdesc_t))) == NULL) 2347c478bd9Sstevel@tonic-gate return (NULL); 2357c478bd9Sstevel@tonic-gate 2367c478bd9Sstevel@tonic-gate if (sdp->dtsd_action_last != NULL) { 2377c478bd9Sstevel@tonic-gate assert(sdp->dtsd_action != NULL); 2387c478bd9Sstevel@tonic-gate assert(sdp->dtsd_action_last->dtad_next == NULL); 2397c478bd9Sstevel@tonic-gate sdp->dtsd_action_last->dtad_next = new; 2407c478bd9Sstevel@tonic-gate } else { 2417c478bd9Sstevel@tonic-gate dtrace_actdesc_t *ap = edp->dted_action; 2427c478bd9Sstevel@tonic-gate 2437c478bd9Sstevel@tonic-gate assert(sdp->dtsd_action == NULL); 2447c478bd9Sstevel@tonic-gate sdp->dtsd_action = new; 2457c478bd9Sstevel@tonic-gate 2467c478bd9Sstevel@tonic-gate while (ap != NULL && ap->dtad_next != NULL) 2477c478bd9Sstevel@tonic-gate ap = ap->dtad_next; 2487c478bd9Sstevel@tonic-gate 2497c478bd9Sstevel@tonic-gate if (ap == NULL) 2507c478bd9Sstevel@tonic-gate edp->dted_action = new; 2517c478bd9Sstevel@tonic-gate else 2527c478bd9Sstevel@tonic-gate ap->dtad_next = new; 2537c478bd9Sstevel@tonic-gate } 2547c478bd9Sstevel@tonic-gate 2557c478bd9Sstevel@tonic-gate sdp->dtsd_action_last = new; 2567c478bd9Sstevel@tonic-gate bzero(new, sizeof (dtrace_actdesc_t)); 2577c478bd9Sstevel@tonic-gate new->dtad_uarg = (uintptr_t)sdp; 2587c478bd9Sstevel@tonic-gate 2597c478bd9Sstevel@tonic-gate return (new); 2607c478bd9Sstevel@tonic-gate } 2617c478bd9Sstevel@tonic-gate 2627c478bd9Sstevel@tonic-gate int 2637c478bd9Sstevel@tonic-gate dtrace_stmt_add(dtrace_hdl_t *dtp, dtrace_prog_t *pgp, dtrace_stmtdesc_t *sdp) 2647c478bd9Sstevel@tonic-gate { 265*1a7c1b72Smws dt_stmt_t *stp = dt_alloc(dtp, sizeof (dt_stmt_t)); 2667c478bd9Sstevel@tonic-gate 2677c478bd9Sstevel@tonic-gate if (stp == NULL) 268*1a7c1b72Smws return (-1); /* errno is set for us */ 2697c478bd9Sstevel@tonic-gate 2707c478bd9Sstevel@tonic-gate dt_list_append(&pgp->dp_stmts, stp); 2717c478bd9Sstevel@tonic-gate stp->ds_desc = sdp; 2727c478bd9Sstevel@tonic-gate 2737c478bd9Sstevel@tonic-gate return (0); 2747c478bd9Sstevel@tonic-gate } 2757c478bd9Sstevel@tonic-gate 2767c478bd9Sstevel@tonic-gate int 2777c478bd9Sstevel@tonic-gate dtrace_stmt_iter(dtrace_hdl_t *dtp, dtrace_prog_t *pgp, 2787c478bd9Sstevel@tonic-gate dtrace_stmt_f *func, void *data) 2797c478bd9Sstevel@tonic-gate { 2807c478bd9Sstevel@tonic-gate dt_stmt_t *stp, *next; 2817c478bd9Sstevel@tonic-gate int status = 0; 2827c478bd9Sstevel@tonic-gate 2837c478bd9Sstevel@tonic-gate for (stp = dt_list_next(&pgp->dp_stmts); stp != NULL; stp = next) { 2847c478bd9Sstevel@tonic-gate next = dt_list_next(stp); 2857c478bd9Sstevel@tonic-gate if ((status = func(dtp, pgp, stp->ds_desc, data)) != 0) 2867c478bd9Sstevel@tonic-gate break; 2877c478bd9Sstevel@tonic-gate } 2887c478bd9Sstevel@tonic-gate 2897c478bd9Sstevel@tonic-gate return (status); 2907c478bd9Sstevel@tonic-gate } 2917c478bd9Sstevel@tonic-gate 2927c478bd9Sstevel@tonic-gate void 293*1a7c1b72Smws dtrace_stmt_destroy(dtrace_hdl_t *dtp, dtrace_stmtdesc_t *sdp) 2947c478bd9Sstevel@tonic-gate { 2957c478bd9Sstevel@tonic-gate dtrace_ecbdesc_t *edp = sdp->dtsd_ecbdesc; 2967c478bd9Sstevel@tonic-gate 2977c478bd9Sstevel@tonic-gate /* 2987c478bd9Sstevel@tonic-gate * We need to remove any actions that we have on this ECB, and 2997c478bd9Sstevel@tonic-gate * remove our hold on the ECB itself. 3007c478bd9Sstevel@tonic-gate */ 3017c478bd9Sstevel@tonic-gate if (sdp->dtsd_action != NULL) { 3027c478bd9Sstevel@tonic-gate dtrace_actdesc_t *last = sdp->dtsd_action_last; 3037c478bd9Sstevel@tonic-gate dtrace_actdesc_t *ap, *next; 3047c478bd9Sstevel@tonic-gate 3057c478bd9Sstevel@tonic-gate assert(last != NULL); 3067c478bd9Sstevel@tonic-gate 3077c478bd9Sstevel@tonic-gate for (ap = edp->dted_action; ap != NULL; ap = ap->dtad_next) { 3087c478bd9Sstevel@tonic-gate if (ap == sdp->dtsd_action) 3097c478bd9Sstevel@tonic-gate break; 3107c478bd9Sstevel@tonic-gate 3117c478bd9Sstevel@tonic-gate if (ap->dtad_next == sdp->dtsd_action) 3127c478bd9Sstevel@tonic-gate break; 3137c478bd9Sstevel@tonic-gate } 3147c478bd9Sstevel@tonic-gate 3157c478bd9Sstevel@tonic-gate assert(ap != NULL); 3167c478bd9Sstevel@tonic-gate 317*1a7c1b72Smws if (ap == edp->dted_action) 3187c478bd9Sstevel@tonic-gate edp->dted_action = last->dtad_next; 319*1a7c1b72Smws else 3207c478bd9Sstevel@tonic-gate ap->dtad_next = last->dtad_next; 3217c478bd9Sstevel@tonic-gate 3227c478bd9Sstevel@tonic-gate /* 3237c478bd9Sstevel@tonic-gate * We have now removed our action list from its ECB; we can 3247c478bd9Sstevel@tonic-gate * safely destroy the list. 3257c478bd9Sstevel@tonic-gate */ 3267c478bd9Sstevel@tonic-gate last->dtad_next = NULL; 3277c478bd9Sstevel@tonic-gate 3287c478bd9Sstevel@tonic-gate for (ap = sdp->dtsd_action; ap != NULL; ap = next) { 3297c478bd9Sstevel@tonic-gate assert(ap->dtad_uarg == (uintptr_t)sdp); 330*1a7c1b72Smws dt_difo_free(dtp, ap->dtad_difo); 3317c478bd9Sstevel@tonic-gate next = ap->dtad_next; 332*1a7c1b72Smws dt_free(dtp, ap); 3337c478bd9Sstevel@tonic-gate } 3347c478bd9Sstevel@tonic-gate } 3357c478bd9Sstevel@tonic-gate 3367c478bd9Sstevel@tonic-gate if (sdp->dtsd_fmtdata != NULL) 3377c478bd9Sstevel@tonic-gate dt_printf_destroy(sdp->dtsd_fmtdata); 3387c478bd9Sstevel@tonic-gate 339*1a7c1b72Smws dt_ecbdesc_release(dtp, sdp->dtsd_ecbdesc); 340*1a7c1b72Smws dt_free(dtp, sdp); 3417c478bd9Sstevel@tonic-gate } 342