1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * CDDL HEADER START 3*7c478bd9Sstevel@tonic-gate * 4*7c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*7c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*7c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*7c478bd9Sstevel@tonic-gate * with the License. 8*7c478bd9Sstevel@tonic-gate * 9*7c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*7c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*7c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 12*7c478bd9Sstevel@tonic-gate * and limitations under the License. 13*7c478bd9Sstevel@tonic-gate * 14*7c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*7c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*7c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*7c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*7c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*7c478bd9Sstevel@tonic-gate * 20*7c478bd9Sstevel@tonic-gate * CDDL HEADER END 21*7c478bd9Sstevel@tonic-gate */ 22*7c478bd9Sstevel@tonic-gate /* 23*7c478bd9Sstevel@tonic-gate * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 24*7c478bd9Sstevel@tonic-gate * Use is subject to license terms. 25*7c478bd9Sstevel@tonic-gate */ 26*7c478bd9Sstevel@tonic-gate 27*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 28*7c478bd9Sstevel@tonic-gate 29*7c478bd9Sstevel@tonic-gate #include <unistd.h> 30*7c478bd9Sstevel@tonic-gate #include <strings.h> 31*7c478bd9Sstevel@tonic-gate #include <stdlib.h> 32*7c478bd9Sstevel@tonic-gate #include <errno.h> 33*7c478bd9Sstevel@tonic-gate #include <assert.h> 34*7c478bd9Sstevel@tonic-gate 35*7c478bd9Sstevel@tonic-gate #include <dt_impl.h> 36*7c478bd9Sstevel@tonic-gate #include <dt_printf.h> 37*7c478bd9Sstevel@tonic-gate 38*7c478bd9Sstevel@tonic-gate dtrace_prog_t * 39*7c478bd9Sstevel@tonic-gate dtrace_program_create(dtrace_hdl_t *dtp) 40*7c478bd9Sstevel@tonic-gate { 41*7c478bd9Sstevel@tonic-gate dtrace_prog_t *pgp = calloc(1, sizeof (dtrace_prog_t)); 42*7c478bd9Sstevel@tonic-gate 43*7c478bd9Sstevel@tonic-gate if (pgp != NULL) 44*7c478bd9Sstevel@tonic-gate dt_list_append(&dtp->dt_programs, pgp); 45*7c478bd9Sstevel@tonic-gate else 46*7c478bd9Sstevel@tonic-gate (void) dt_set_errno(dtp, EDT_NOMEM); 47*7c478bd9Sstevel@tonic-gate 48*7c478bd9Sstevel@tonic-gate return (pgp); 49*7c478bd9Sstevel@tonic-gate } 50*7c478bd9Sstevel@tonic-gate 51*7c478bd9Sstevel@tonic-gate void 52*7c478bd9Sstevel@tonic-gate dtrace_program_destroy(dtrace_hdl_t *dtp, dtrace_prog_t *pgp) 53*7c478bd9Sstevel@tonic-gate { 54*7c478bd9Sstevel@tonic-gate dt_stmt_t *stp, *next; 55*7c478bd9Sstevel@tonic-gate 56*7c478bd9Sstevel@tonic-gate for (stp = dt_list_next(&pgp->dp_stmts); stp != NULL; stp = next) { 57*7c478bd9Sstevel@tonic-gate next = dt_list_next(stp); 58*7c478bd9Sstevel@tonic-gate dtrace_stmt_destroy(stp->ds_desc); 59*7c478bd9Sstevel@tonic-gate free(stp); 60*7c478bd9Sstevel@tonic-gate } 61*7c478bd9Sstevel@tonic-gate 62*7c478bd9Sstevel@tonic-gate dt_list_delete(&dtp->dt_programs, pgp); 63*7c478bd9Sstevel@tonic-gate free(pgp); 64*7c478bd9Sstevel@tonic-gate } 65*7c478bd9Sstevel@tonic-gate 66*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 67*7c478bd9Sstevel@tonic-gate void 68*7c478bd9Sstevel@tonic-gate dtrace_program_info(dtrace_hdl_t *dtp, dtrace_prog_t *pgp, 69*7c478bd9Sstevel@tonic-gate dtrace_proginfo_t *pip) 70*7c478bd9Sstevel@tonic-gate { 71*7c478bd9Sstevel@tonic-gate dt_stmt_t *stp; 72*7c478bd9Sstevel@tonic-gate dtrace_actdesc_t *ap; 73*7c478bd9Sstevel@tonic-gate dtrace_ecbdesc_t *last = NULL; 74*7c478bd9Sstevel@tonic-gate 75*7c478bd9Sstevel@tonic-gate if (pip == NULL) 76*7c478bd9Sstevel@tonic-gate return; 77*7c478bd9Sstevel@tonic-gate 78*7c478bd9Sstevel@tonic-gate bzero(pip, sizeof (dtrace_proginfo_t)); 79*7c478bd9Sstevel@tonic-gate 80*7c478bd9Sstevel@tonic-gate if (dt_list_next(&pgp->dp_stmts) != NULL) { 81*7c478bd9Sstevel@tonic-gate pip->dpi_descattr = _dtrace_maxattr; 82*7c478bd9Sstevel@tonic-gate pip->dpi_stmtattr = _dtrace_maxattr; 83*7c478bd9Sstevel@tonic-gate } else { 84*7c478bd9Sstevel@tonic-gate pip->dpi_descattr = _dtrace_defattr; 85*7c478bd9Sstevel@tonic-gate pip->dpi_stmtattr = _dtrace_defattr; 86*7c478bd9Sstevel@tonic-gate } 87*7c478bd9Sstevel@tonic-gate 88*7c478bd9Sstevel@tonic-gate for (stp = dt_list_next(&pgp->dp_stmts); stp; stp = dt_list_next(stp)) { 89*7c478bd9Sstevel@tonic-gate dtrace_ecbdesc_t *edp = stp->ds_desc->dtsd_ecbdesc; 90*7c478bd9Sstevel@tonic-gate 91*7c478bd9Sstevel@tonic-gate if (edp == last) 92*7c478bd9Sstevel@tonic-gate continue; 93*7c478bd9Sstevel@tonic-gate last = edp; 94*7c478bd9Sstevel@tonic-gate 95*7c478bd9Sstevel@tonic-gate pip->dpi_descattr = 96*7c478bd9Sstevel@tonic-gate dt_attr_min(stp->ds_desc->dtsd_descattr, pip->dpi_descattr); 97*7c478bd9Sstevel@tonic-gate 98*7c478bd9Sstevel@tonic-gate pip->dpi_stmtattr = 99*7c478bd9Sstevel@tonic-gate dt_attr_min(stp->ds_desc->dtsd_stmtattr, pip->dpi_stmtattr); 100*7c478bd9Sstevel@tonic-gate 101*7c478bd9Sstevel@tonic-gate /* 102*7c478bd9Sstevel@tonic-gate * If there aren't any actions, account for the fact that 103*7c478bd9Sstevel@tonic-gate * recording the epid will generate a record. 104*7c478bd9Sstevel@tonic-gate */ 105*7c478bd9Sstevel@tonic-gate if (edp->dted_action == NULL) 106*7c478bd9Sstevel@tonic-gate pip->dpi_recgens++; 107*7c478bd9Sstevel@tonic-gate 108*7c478bd9Sstevel@tonic-gate for (ap = edp->dted_action; ap != NULL; ap = ap->dtad_next) { 109*7c478bd9Sstevel@tonic-gate if (ap->dtad_kind == DTRACEACT_SPECULATE) { 110*7c478bd9Sstevel@tonic-gate pip->dpi_speculations++; 111*7c478bd9Sstevel@tonic-gate continue; 112*7c478bd9Sstevel@tonic-gate } 113*7c478bd9Sstevel@tonic-gate 114*7c478bd9Sstevel@tonic-gate if (DTRACEACT_ISAGG(ap->dtad_kind)) { 115*7c478bd9Sstevel@tonic-gate pip->dpi_recgens -= ap->dtad_arg; 116*7c478bd9Sstevel@tonic-gate pip->dpi_aggregates++; 117*7c478bd9Sstevel@tonic-gate continue; 118*7c478bd9Sstevel@tonic-gate } 119*7c478bd9Sstevel@tonic-gate 120*7c478bd9Sstevel@tonic-gate if (DTRACEACT_ISDESTRUCTIVE(ap->dtad_kind)) 121*7c478bd9Sstevel@tonic-gate continue; 122*7c478bd9Sstevel@tonic-gate 123*7c478bd9Sstevel@tonic-gate if (ap->dtad_kind == DTRACEACT_DIFEXPR && 124*7c478bd9Sstevel@tonic-gate ap->dtad_difo->dtdo_rtype.dtdt_kind == 125*7c478bd9Sstevel@tonic-gate DIF_TYPE_CTF && 126*7c478bd9Sstevel@tonic-gate ap->dtad_difo->dtdo_rtype.dtdt_size == 0) 127*7c478bd9Sstevel@tonic-gate continue; 128*7c478bd9Sstevel@tonic-gate 129*7c478bd9Sstevel@tonic-gate pip->dpi_recgens++; 130*7c478bd9Sstevel@tonic-gate } 131*7c478bd9Sstevel@tonic-gate } 132*7c478bd9Sstevel@tonic-gate } 133*7c478bd9Sstevel@tonic-gate 134*7c478bd9Sstevel@tonic-gate int 135*7c478bd9Sstevel@tonic-gate dtrace_program_exec(dtrace_hdl_t *dtp, dtrace_prog_t *pgp, 136*7c478bd9Sstevel@tonic-gate dtrace_proginfo_t *pip) 137*7c478bd9Sstevel@tonic-gate { 138*7c478bd9Sstevel@tonic-gate void *dof; 139*7c478bd9Sstevel@tonic-gate int n, err; 140*7c478bd9Sstevel@tonic-gate 141*7c478bd9Sstevel@tonic-gate dtrace_program_info(dtp, pgp, pip); 142*7c478bd9Sstevel@tonic-gate 143*7c478bd9Sstevel@tonic-gate if ((dof = dtrace_dof_create(dtp, pgp, DTRACE_D_STRIP)) == NULL) 144*7c478bd9Sstevel@tonic-gate return (-1); 145*7c478bd9Sstevel@tonic-gate 146*7c478bd9Sstevel@tonic-gate n = dt_ioctl(dtp, DTRACEIOC_ENABLE, dof); 147*7c478bd9Sstevel@tonic-gate dtrace_dof_destroy(dtp, dof); 148*7c478bd9Sstevel@tonic-gate 149*7c478bd9Sstevel@tonic-gate if (n == -1) { 150*7c478bd9Sstevel@tonic-gate switch (errno) { 151*7c478bd9Sstevel@tonic-gate case EINVAL: 152*7c478bd9Sstevel@tonic-gate err = EDT_DIFINVAL; 153*7c478bd9Sstevel@tonic-gate break; 154*7c478bd9Sstevel@tonic-gate case EFAULT: 155*7c478bd9Sstevel@tonic-gate err = EDT_DIFFAULT; 156*7c478bd9Sstevel@tonic-gate break; 157*7c478bd9Sstevel@tonic-gate case E2BIG: 158*7c478bd9Sstevel@tonic-gate err = EDT_DIFSIZE; 159*7c478bd9Sstevel@tonic-gate break; 160*7c478bd9Sstevel@tonic-gate default: 161*7c478bd9Sstevel@tonic-gate err = errno; 162*7c478bd9Sstevel@tonic-gate } 163*7c478bd9Sstevel@tonic-gate 164*7c478bd9Sstevel@tonic-gate return (dt_set_errno(dtp, err)); 165*7c478bd9Sstevel@tonic-gate } 166*7c478bd9Sstevel@tonic-gate 167*7c478bd9Sstevel@tonic-gate if (pip != NULL) 168*7c478bd9Sstevel@tonic-gate pip->dpi_matches += n; 169*7c478bd9Sstevel@tonic-gate 170*7c478bd9Sstevel@tonic-gate return (0); 171*7c478bd9Sstevel@tonic-gate } 172*7c478bd9Sstevel@tonic-gate 173*7c478bd9Sstevel@tonic-gate void 174*7c478bd9Sstevel@tonic-gate dtrace_ecbdesc_hold(dtrace_ecbdesc_t *edp) 175*7c478bd9Sstevel@tonic-gate { 176*7c478bd9Sstevel@tonic-gate edp->dted_refcnt++; 177*7c478bd9Sstevel@tonic-gate } 178*7c478bd9Sstevel@tonic-gate 179*7c478bd9Sstevel@tonic-gate void 180*7c478bd9Sstevel@tonic-gate dtrace_ecbdesc_release(dtrace_ecbdesc_t *edp) 181*7c478bd9Sstevel@tonic-gate { 182*7c478bd9Sstevel@tonic-gate dtrace_difo_t *dp; 183*7c478bd9Sstevel@tonic-gate 184*7c478bd9Sstevel@tonic-gate if (--edp->dted_refcnt > 0) 185*7c478bd9Sstevel@tonic-gate return; 186*7c478bd9Sstevel@tonic-gate 187*7c478bd9Sstevel@tonic-gate if ((dp = edp->dted_pred.dtpdd_difo) != NULL) 188*7c478bd9Sstevel@tonic-gate dtrace_difo_release(dp); 189*7c478bd9Sstevel@tonic-gate 190*7c478bd9Sstevel@tonic-gate assert(edp->dted_action == NULL); 191*7c478bd9Sstevel@tonic-gate free(edp); 192*7c478bd9Sstevel@tonic-gate } 193*7c478bd9Sstevel@tonic-gate 194*7c478bd9Sstevel@tonic-gate dtrace_ecbdesc_t * 195*7c478bd9Sstevel@tonic-gate dtrace_ecbdesc_create(dtrace_hdl_t *dtp, const dtrace_probedesc_t *pdp) 196*7c478bd9Sstevel@tonic-gate { 197*7c478bd9Sstevel@tonic-gate dtrace_ecbdesc_t *edp; 198*7c478bd9Sstevel@tonic-gate 199*7c478bd9Sstevel@tonic-gate if ((edp = malloc(sizeof (dtrace_ecbdesc_t))) == NULL) { 200*7c478bd9Sstevel@tonic-gate (void) dt_set_errno(dtp, EDT_NOMEM); 201*7c478bd9Sstevel@tonic-gate return (NULL); 202*7c478bd9Sstevel@tonic-gate } 203*7c478bd9Sstevel@tonic-gate 204*7c478bd9Sstevel@tonic-gate bzero(edp, sizeof (dtrace_ecbdesc_t)); 205*7c478bd9Sstevel@tonic-gate edp->dted_probe = *pdp; 206*7c478bd9Sstevel@tonic-gate dtrace_ecbdesc_hold(edp); 207*7c478bd9Sstevel@tonic-gate 208*7c478bd9Sstevel@tonic-gate return (edp); 209*7c478bd9Sstevel@tonic-gate } 210*7c478bd9Sstevel@tonic-gate 211*7c478bd9Sstevel@tonic-gate dtrace_stmtdesc_t * 212*7c478bd9Sstevel@tonic-gate dtrace_stmt_create(dtrace_hdl_t *dtp, dtrace_ecbdesc_t *edp) 213*7c478bd9Sstevel@tonic-gate { 214*7c478bd9Sstevel@tonic-gate dtrace_stmtdesc_t *sdp; 215*7c478bd9Sstevel@tonic-gate 216*7c478bd9Sstevel@tonic-gate if ((sdp = malloc(sizeof (dtrace_stmtdesc_t))) == NULL) { 217*7c478bd9Sstevel@tonic-gate (void) dt_set_errno(dtp, EDT_NOMEM); 218*7c478bd9Sstevel@tonic-gate return (NULL); 219*7c478bd9Sstevel@tonic-gate } 220*7c478bd9Sstevel@tonic-gate 221*7c478bd9Sstevel@tonic-gate bzero(sdp, sizeof (dtrace_stmtdesc_t)); 222*7c478bd9Sstevel@tonic-gate dtrace_ecbdesc_hold(edp); 223*7c478bd9Sstevel@tonic-gate sdp->dtsd_ecbdesc = edp; 224*7c478bd9Sstevel@tonic-gate sdp->dtsd_descattr = _dtrace_defattr; 225*7c478bd9Sstevel@tonic-gate sdp->dtsd_stmtattr = _dtrace_defattr; 226*7c478bd9Sstevel@tonic-gate 227*7c478bd9Sstevel@tonic-gate return (sdp); 228*7c478bd9Sstevel@tonic-gate } 229*7c478bd9Sstevel@tonic-gate 230*7c478bd9Sstevel@tonic-gate dtrace_actdesc_t * 231*7c478bd9Sstevel@tonic-gate dtrace_stmt_action(dtrace_hdl_t *dtp, dtrace_stmtdesc_t *sdp) 232*7c478bd9Sstevel@tonic-gate { 233*7c478bd9Sstevel@tonic-gate dtrace_actdesc_t *new; 234*7c478bd9Sstevel@tonic-gate dtrace_ecbdesc_t *edp = sdp->dtsd_ecbdesc; 235*7c478bd9Sstevel@tonic-gate 236*7c478bd9Sstevel@tonic-gate if ((new = malloc(sizeof (dtrace_actdesc_t))) == NULL) { 237*7c478bd9Sstevel@tonic-gate (void) dt_set_errno(dtp, EDT_NOMEM); 238*7c478bd9Sstevel@tonic-gate return (NULL); 239*7c478bd9Sstevel@tonic-gate } 240*7c478bd9Sstevel@tonic-gate 241*7c478bd9Sstevel@tonic-gate if (sdp->dtsd_action_last != NULL) { 242*7c478bd9Sstevel@tonic-gate assert(sdp->dtsd_action != NULL); 243*7c478bd9Sstevel@tonic-gate assert(sdp->dtsd_action_last->dtad_next == NULL); 244*7c478bd9Sstevel@tonic-gate sdp->dtsd_action_last->dtad_next = new; 245*7c478bd9Sstevel@tonic-gate } else { 246*7c478bd9Sstevel@tonic-gate dtrace_actdesc_t *ap = edp->dted_action; 247*7c478bd9Sstevel@tonic-gate 248*7c478bd9Sstevel@tonic-gate assert(sdp->dtsd_action == NULL); 249*7c478bd9Sstevel@tonic-gate sdp->dtsd_action = new; 250*7c478bd9Sstevel@tonic-gate 251*7c478bd9Sstevel@tonic-gate while (ap != NULL && ap->dtad_next != NULL) 252*7c478bd9Sstevel@tonic-gate ap = ap->dtad_next; 253*7c478bd9Sstevel@tonic-gate 254*7c478bd9Sstevel@tonic-gate if (ap == NULL) 255*7c478bd9Sstevel@tonic-gate edp->dted_action = new; 256*7c478bd9Sstevel@tonic-gate else 257*7c478bd9Sstevel@tonic-gate ap->dtad_next = new; 258*7c478bd9Sstevel@tonic-gate } 259*7c478bd9Sstevel@tonic-gate 260*7c478bd9Sstevel@tonic-gate sdp->dtsd_action_last = new; 261*7c478bd9Sstevel@tonic-gate bzero(new, sizeof (dtrace_actdesc_t)); 262*7c478bd9Sstevel@tonic-gate new->dtad_uarg = (uintptr_t)sdp; 263*7c478bd9Sstevel@tonic-gate 264*7c478bd9Sstevel@tonic-gate return (new); 265*7c478bd9Sstevel@tonic-gate } 266*7c478bd9Sstevel@tonic-gate 267*7c478bd9Sstevel@tonic-gate int 268*7c478bd9Sstevel@tonic-gate dtrace_stmt_add(dtrace_hdl_t *dtp, dtrace_prog_t *pgp, dtrace_stmtdesc_t *sdp) 269*7c478bd9Sstevel@tonic-gate { 270*7c478bd9Sstevel@tonic-gate dt_stmt_t *stp = malloc(sizeof (dt_stmt_t)); 271*7c478bd9Sstevel@tonic-gate 272*7c478bd9Sstevel@tonic-gate if (stp == NULL) 273*7c478bd9Sstevel@tonic-gate return (dt_set_errno(dtp, EDT_NOMEM)); 274*7c478bd9Sstevel@tonic-gate 275*7c478bd9Sstevel@tonic-gate dt_list_append(&pgp->dp_stmts, stp); 276*7c478bd9Sstevel@tonic-gate stp->ds_desc = sdp; 277*7c478bd9Sstevel@tonic-gate 278*7c478bd9Sstevel@tonic-gate return (0); 279*7c478bd9Sstevel@tonic-gate } 280*7c478bd9Sstevel@tonic-gate 281*7c478bd9Sstevel@tonic-gate int 282*7c478bd9Sstevel@tonic-gate dtrace_stmt_iter(dtrace_hdl_t *dtp, dtrace_prog_t *pgp, 283*7c478bd9Sstevel@tonic-gate dtrace_stmt_f *func, void *data) 284*7c478bd9Sstevel@tonic-gate { 285*7c478bd9Sstevel@tonic-gate dt_stmt_t *stp, *next; 286*7c478bd9Sstevel@tonic-gate int status = 0; 287*7c478bd9Sstevel@tonic-gate 288*7c478bd9Sstevel@tonic-gate for (stp = dt_list_next(&pgp->dp_stmts); stp != NULL; stp = next) { 289*7c478bd9Sstevel@tonic-gate next = dt_list_next(stp); 290*7c478bd9Sstevel@tonic-gate if ((status = func(dtp, pgp, stp->ds_desc, data)) != 0) 291*7c478bd9Sstevel@tonic-gate break; 292*7c478bd9Sstevel@tonic-gate } 293*7c478bd9Sstevel@tonic-gate 294*7c478bd9Sstevel@tonic-gate return (status); 295*7c478bd9Sstevel@tonic-gate } 296*7c478bd9Sstevel@tonic-gate 297*7c478bd9Sstevel@tonic-gate void 298*7c478bd9Sstevel@tonic-gate dtrace_stmt_destroy(dtrace_stmtdesc_t *sdp) 299*7c478bd9Sstevel@tonic-gate { 300*7c478bd9Sstevel@tonic-gate dtrace_ecbdesc_t *edp = sdp->dtsd_ecbdesc; 301*7c478bd9Sstevel@tonic-gate 302*7c478bd9Sstevel@tonic-gate /* 303*7c478bd9Sstevel@tonic-gate * We need to remove any actions that we have on this ECB, and 304*7c478bd9Sstevel@tonic-gate * remove our hold on the ECB itself. 305*7c478bd9Sstevel@tonic-gate */ 306*7c478bd9Sstevel@tonic-gate if (sdp->dtsd_action != NULL) { 307*7c478bd9Sstevel@tonic-gate dtrace_actdesc_t *last = sdp->dtsd_action_last; 308*7c478bd9Sstevel@tonic-gate dtrace_actdesc_t *ap, *next; 309*7c478bd9Sstevel@tonic-gate 310*7c478bd9Sstevel@tonic-gate assert(last != NULL); 311*7c478bd9Sstevel@tonic-gate 312*7c478bd9Sstevel@tonic-gate for (ap = edp->dted_action; ap != NULL; ap = ap->dtad_next) { 313*7c478bd9Sstevel@tonic-gate if (ap == sdp->dtsd_action) 314*7c478bd9Sstevel@tonic-gate break; 315*7c478bd9Sstevel@tonic-gate 316*7c478bd9Sstevel@tonic-gate if (ap->dtad_next == sdp->dtsd_action) 317*7c478bd9Sstevel@tonic-gate break; 318*7c478bd9Sstevel@tonic-gate } 319*7c478bd9Sstevel@tonic-gate 320*7c478bd9Sstevel@tonic-gate assert(ap != NULL); 321*7c478bd9Sstevel@tonic-gate 322*7c478bd9Sstevel@tonic-gate if (ap == edp->dted_action) { 323*7c478bd9Sstevel@tonic-gate edp->dted_action = last->dtad_next; 324*7c478bd9Sstevel@tonic-gate } else { 325*7c478bd9Sstevel@tonic-gate ap->dtad_next = last->dtad_next; 326*7c478bd9Sstevel@tonic-gate } 327*7c478bd9Sstevel@tonic-gate 328*7c478bd9Sstevel@tonic-gate /* 329*7c478bd9Sstevel@tonic-gate * We have now removed our action list from its ECB; we can 330*7c478bd9Sstevel@tonic-gate * safely destroy the list. 331*7c478bd9Sstevel@tonic-gate */ 332*7c478bd9Sstevel@tonic-gate last->dtad_next = NULL; 333*7c478bd9Sstevel@tonic-gate 334*7c478bd9Sstevel@tonic-gate for (ap = sdp->dtsd_action; ap != NULL; ap = next) { 335*7c478bd9Sstevel@tonic-gate dtrace_difo_t *dp; 336*7c478bd9Sstevel@tonic-gate 337*7c478bd9Sstevel@tonic-gate assert(ap->dtad_uarg == (uintptr_t)sdp); 338*7c478bd9Sstevel@tonic-gate 339*7c478bd9Sstevel@tonic-gate if ((dp = ap->dtad_difo) != NULL) 340*7c478bd9Sstevel@tonic-gate dtrace_difo_release(dp); 341*7c478bd9Sstevel@tonic-gate 342*7c478bd9Sstevel@tonic-gate next = ap->dtad_next; 343*7c478bd9Sstevel@tonic-gate free(ap); 344*7c478bd9Sstevel@tonic-gate } 345*7c478bd9Sstevel@tonic-gate } 346*7c478bd9Sstevel@tonic-gate 347*7c478bd9Sstevel@tonic-gate if (sdp->dtsd_fmtdata != NULL) 348*7c478bd9Sstevel@tonic-gate dt_printf_destroy(sdp->dtsd_fmtdata); 349*7c478bd9Sstevel@tonic-gate 350*7c478bd9Sstevel@tonic-gate dtrace_ecbdesc_release(sdp->dtsd_ecbdesc); 351*7c478bd9Sstevel@tonic-gate free(sdp); 352*7c478bd9Sstevel@tonic-gate } 353