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 5c2580b93Sjhaslam * Common Development and Distribution License (the "License"). 6c2580b93Sjhaslam * You may not use this file except in compliance with the License. 77c478bd9Sstevel@tonic-gate * 87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 117c478bd9Sstevel@tonic-gate * and limitations under the License. 127c478bd9Sstevel@tonic-gate * 137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 187c478bd9Sstevel@tonic-gate * 197c478bd9Sstevel@tonic-gate * CDDL HEADER END 207c478bd9Sstevel@tonic-gate */ 217c478bd9Sstevel@tonic-gate /* 22c2580b93Sjhaslam * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 237c478bd9Sstevel@tonic-gate * Use is subject to license terms. 247c478bd9Sstevel@tonic-gate */ 257c478bd9Sstevel@tonic-gate 26*deef35fdSEric Schrock /* 27*deef35fdSEric Schrock * Copyright (c) 2011 by Delphix. All rights reserved. 28*deef35fdSEric Schrock */ 297c478bd9Sstevel@tonic-gate 307c478bd9Sstevel@tonic-gate #include <stdlib.h> 317c478bd9Sstevel@tonic-gate #include <strings.h> 327c478bd9Sstevel@tonic-gate #include <errno.h> 337c478bd9Sstevel@tonic-gate #include <unistd.h> 347c478bd9Sstevel@tonic-gate #include <assert.h> 357c478bd9Sstevel@tonic-gate 367c478bd9Sstevel@tonic-gate #include <dt_impl.h> 377c478bd9Sstevel@tonic-gate #include <dt_printf.h> 387c478bd9Sstevel@tonic-gate 397c478bd9Sstevel@tonic-gate static int 40*deef35fdSEric Schrock dt_strdata_add(dtrace_hdl_t *dtp, dtrace_recdesc_t *rec, void ***data, int *max) 41*deef35fdSEric Schrock { 42*deef35fdSEric Schrock int maxformat; 43*deef35fdSEric Schrock dtrace_fmtdesc_t fmt; 44*deef35fdSEric Schrock void *result; 45*deef35fdSEric Schrock 46*deef35fdSEric Schrock if (rec->dtrd_format == 0) 47*deef35fdSEric Schrock return (0); 48*deef35fdSEric Schrock 49*deef35fdSEric Schrock if (rec->dtrd_format <= *max && 50*deef35fdSEric Schrock (*data)[rec->dtrd_format - 1] != NULL) { 51*deef35fdSEric Schrock return (0); 52*deef35fdSEric Schrock } 53*deef35fdSEric Schrock 54*deef35fdSEric Schrock bzero(&fmt, sizeof (fmt)); 55*deef35fdSEric Schrock fmt.dtfd_format = rec->dtrd_format; 56*deef35fdSEric Schrock fmt.dtfd_string = NULL; 57*deef35fdSEric Schrock fmt.dtfd_length = 0; 58*deef35fdSEric Schrock 59*deef35fdSEric Schrock if (dt_ioctl(dtp, DTRACEIOC_FORMAT, &fmt) == -1) 60*deef35fdSEric Schrock return (dt_set_errno(dtp, errno)); 61*deef35fdSEric Schrock 62*deef35fdSEric Schrock if ((fmt.dtfd_string = dt_alloc(dtp, fmt.dtfd_length)) == NULL) 63*deef35fdSEric Schrock return (dt_set_errno(dtp, EDT_NOMEM)); 64*deef35fdSEric Schrock 65*deef35fdSEric Schrock if (dt_ioctl(dtp, DTRACEIOC_FORMAT, &fmt) == -1) { 66*deef35fdSEric Schrock free(fmt.dtfd_string); 67*deef35fdSEric Schrock return (dt_set_errno(dtp, errno)); 68*deef35fdSEric Schrock } 69*deef35fdSEric Schrock 70*deef35fdSEric Schrock while (rec->dtrd_format > (maxformat = *max)) { 71*deef35fdSEric Schrock int new_max = maxformat ? (maxformat << 1) : 1; 72*deef35fdSEric Schrock size_t nsize = new_max * sizeof (void *); 73*deef35fdSEric Schrock size_t osize = maxformat * sizeof (void *); 74*deef35fdSEric Schrock void **new_data = dt_zalloc(dtp, nsize); 75*deef35fdSEric Schrock 76*deef35fdSEric Schrock if (new_data == NULL) { 77*deef35fdSEric Schrock dt_free(dtp, fmt.dtfd_string); 78*deef35fdSEric Schrock return (dt_set_errno(dtp, EDT_NOMEM)); 79*deef35fdSEric Schrock } 80*deef35fdSEric Schrock 81*deef35fdSEric Schrock bcopy(*data, new_data, osize); 82*deef35fdSEric Schrock free(*data); 83*deef35fdSEric Schrock 84*deef35fdSEric Schrock *data = new_data; 85*deef35fdSEric Schrock *max = new_max; 86*deef35fdSEric Schrock } 87*deef35fdSEric Schrock 88*deef35fdSEric Schrock switch (rec->dtrd_action) { 89*deef35fdSEric Schrock case DTRACEACT_DIFEXPR: 90*deef35fdSEric Schrock result = fmt.dtfd_string; 91*deef35fdSEric Schrock break; 92*deef35fdSEric Schrock case DTRACEACT_PRINTA: 93*deef35fdSEric Schrock result = dtrace_printa_create(dtp, fmt.dtfd_string); 94*deef35fdSEric Schrock dt_free(dtp, fmt.dtfd_string); 95*deef35fdSEric Schrock break; 96*deef35fdSEric Schrock default: 97*deef35fdSEric Schrock result = dtrace_printf_create(dtp, fmt.dtfd_string); 98*deef35fdSEric Schrock dt_free(dtp, fmt.dtfd_string); 99*deef35fdSEric Schrock break; 100*deef35fdSEric Schrock } 101*deef35fdSEric Schrock 102*deef35fdSEric Schrock if (result == NULL) 103*deef35fdSEric Schrock return (-1); 104*deef35fdSEric Schrock 105*deef35fdSEric Schrock (*data)[rec->dtrd_format - 1] = result; 106*deef35fdSEric Schrock 107*deef35fdSEric Schrock return (0); 108*deef35fdSEric Schrock } 109*deef35fdSEric Schrock 110*deef35fdSEric Schrock static int 1117c478bd9Sstevel@tonic-gate dt_epid_add(dtrace_hdl_t *dtp, dtrace_epid_t id) 1127c478bd9Sstevel@tonic-gate { 1137c478bd9Sstevel@tonic-gate dtrace_id_t max; 114*deef35fdSEric Schrock int rval, i; 1157c478bd9Sstevel@tonic-gate dtrace_eprobedesc_t *enabled, *nenabled; 1167c478bd9Sstevel@tonic-gate dtrace_probedesc_t *probe; 1177c478bd9Sstevel@tonic-gate 1187c478bd9Sstevel@tonic-gate while (id >= (max = dtp->dt_maxprobe) || dtp->dt_pdesc == NULL) { 1197c478bd9Sstevel@tonic-gate dtrace_id_t new_max = max ? (max << 1) : 1; 1207c478bd9Sstevel@tonic-gate size_t nsize = new_max * sizeof (void *); 1217c478bd9Sstevel@tonic-gate dtrace_probedesc_t **new_pdesc; 1227c478bd9Sstevel@tonic-gate dtrace_eprobedesc_t **new_edesc; 1237c478bd9Sstevel@tonic-gate 1247c478bd9Sstevel@tonic-gate if ((new_pdesc = malloc(nsize)) == NULL || 1257c478bd9Sstevel@tonic-gate (new_edesc = malloc(nsize)) == NULL) { 1267c478bd9Sstevel@tonic-gate free(new_pdesc); 1277c478bd9Sstevel@tonic-gate return (dt_set_errno(dtp, EDT_NOMEM)); 1287c478bd9Sstevel@tonic-gate } 1297c478bd9Sstevel@tonic-gate 1307c478bd9Sstevel@tonic-gate bzero(new_pdesc, nsize); 1317c478bd9Sstevel@tonic-gate bzero(new_edesc, nsize); 1327c478bd9Sstevel@tonic-gate 1337c478bd9Sstevel@tonic-gate if (dtp->dt_pdesc != NULL) { 1347c478bd9Sstevel@tonic-gate size_t osize = max * sizeof (void *); 1357c478bd9Sstevel@tonic-gate 1367c478bd9Sstevel@tonic-gate bcopy(dtp->dt_pdesc, new_pdesc, osize); 1377c478bd9Sstevel@tonic-gate free(dtp->dt_pdesc); 1387c478bd9Sstevel@tonic-gate 1397c478bd9Sstevel@tonic-gate bcopy(dtp->dt_edesc, new_edesc, osize); 1407c478bd9Sstevel@tonic-gate free(dtp->dt_edesc); 1417c478bd9Sstevel@tonic-gate } 1427c478bd9Sstevel@tonic-gate 1437c478bd9Sstevel@tonic-gate dtp->dt_pdesc = new_pdesc; 1447c478bd9Sstevel@tonic-gate dtp->dt_edesc = new_edesc; 1457c478bd9Sstevel@tonic-gate dtp->dt_maxprobe = new_max; 1467c478bd9Sstevel@tonic-gate } 1477c478bd9Sstevel@tonic-gate 1487c478bd9Sstevel@tonic-gate if (dtp->dt_pdesc[id] != NULL) 1497c478bd9Sstevel@tonic-gate return (0); 1507c478bd9Sstevel@tonic-gate 1517c478bd9Sstevel@tonic-gate if ((enabled = malloc(sizeof (dtrace_eprobedesc_t))) == NULL) 1527c478bd9Sstevel@tonic-gate return (dt_set_errno(dtp, EDT_NOMEM)); 1537c478bd9Sstevel@tonic-gate 1547c478bd9Sstevel@tonic-gate bzero(enabled, sizeof (dtrace_eprobedesc_t)); 1557c478bd9Sstevel@tonic-gate enabled->dtepd_epid = id; 1567c478bd9Sstevel@tonic-gate enabled->dtepd_nrecs = 1; 1577c478bd9Sstevel@tonic-gate 1587c478bd9Sstevel@tonic-gate if (dt_ioctl(dtp, DTRACEIOC_EPROBE, enabled) == -1) { 1597c478bd9Sstevel@tonic-gate rval = dt_set_errno(dtp, errno); 1607c478bd9Sstevel@tonic-gate free(enabled); 1617c478bd9Sstevel@tonic-gate return (rval); 1627c478bd9Sstevel@tonic-gate } 1637c478bd9Sstevel@tonic-gate 1647c478bd9Sstevel@tonic-gate if (DTRACE_SIZEOF_EPROBEDESC(enabled) != sizeof (*enabled)) { 1657c478bd9Sstevel@tonic-gate /* 1667c478bd9Sstevel@tonic-gate * There must be more than one action. Allocate the 1677c478bd9Sstevel@tonic-gate * appropriate amount of space and try again. 1687c478bd9Sstevel@tonic-gate */ 1697c478bd9Sstevel@tonic-gate if ((nenabled = 1707c478bd9Sstevel@tonic-gate malloc(DTRACE_SIZEOF_EPROBEDESC(enabled))) != NULL) 1717c478bd9Sstevel@tonic-gate bcopy(enabled, nenabled, sizeof (*enabled)); 1727c478bd9Sstevel@tonic-gate 1737c478bd9Sstevel@tonic-gate free(enabled); 1747c478bd9Sstevel@tonic-gate 1757c478bd9Sstevel@tonic-gate if ((enabled = nenabled) == NULL) 1767c478bd9Sstevel@tonic-gate return (dt_set_errno(dtp, EDT_NOMEM)); 1777c478bd9Sstevel@tonic-gate 1787c478bd9Sstevel@tonic-gate rval = dt_ioctl(dtp, DTRACEIOC_EPROBE, enabled); 1797c478bd9Sstevel@tonic-gate 1807c478bd9Sstevel@tonic-gate if (rval == -1) { 1817c478bd9Sstevel@tonic-gate rval = dt_set_errno(dtp, errno); 1827c478bd9Sstevel@tonic-gate free(enabled); 1837c478bd9Sstevel@tonic-gate return (rval); 1847c478bd9Sstevel@tonic-gate } 1857c478bd9Sstevel@tonic-gate } 1867c478bd9Sstevel@tonic-gate 1877c478bd9Sstevel@tonic-gate if ((probe = malloc(sizeof (dtrace_probedesc_t))) == NULL) { 1887c478bd9Sstevel@tonic-gate free(enabled); 1897c478bd9Sstevel@tonic-gate return (dt_set_errno(dtp, EDT_NOMEM)); 1907c478bd9Sstevel@tonic-gate } 1917c478bd9Sstevel@tonic-gate 1927c478bd9Sstevel@tonic-gate probe->dtpd_id = enabled->dtepd_probeid; 1937c478bd9Sstevel@tonic-gate 1947c478bd9Sstevel@tonic-gate if (dt_ioctl(dtp, DTRACEIOC_PROBES, probe) == -1) { 1957c478bd9Sstevel@tonic-gate rval = dt_set_errno(dtp, errno); 1967c478bd9Sstevel@tonic-gate goto err; 1977c478bd9Sstevel@tonic-gate } 1987c478bd9Sstevel@tonic-gate 1997c478bd9Sstevel@tonic-gate for (i = 0; i < enabled->dtepd_nrecs; i++) { 2007c478bd9Sstevel@tonic-gate dtrace_recdesc_t *rec = &enabled->dtepd_rec[i]; 2017c478bd9Sstevel@tonic-gate 202*deef35fdSEric Schrock if (DTRACEACT_ISPRINTFLIKE(rec->dtrd_action)) { 203*deef35fdSEric Schrock if (dt_strdata_add(dtp, rec, &dtp->dt_formats, 204*deef35fdSEric Schrock &dtp->dt_maxformat) != 0) { 205*deef35fdSEric Schrock rval = -1; 2067c478bd9Sstevel@tonic-gate goto err; 2077c478bd9Sstevel@tonic-gate } 208*deef35fdSEric Schrock } else if (rec->dtrd_action == DTRACEACT_DIFEXPR) { 209*deef35fdSEric Schrock if (dt_strdata_add(dtp, rec, 210*deef35fdSEric Schrock (void ***)&dtp->dt_strdata, 211*deef35fdSEric Schrock &dtp->dt_maxstrdata) != 0) { 212*deef35fdSEric Schrock rval = -1; 2137c478bd9Sstevel@tonic-gate goto err; 2147c478bd9Sstevel@tonic-gate } 2157c478bd9Sstevel@tonic-gate } 2167c478bd9Sstevel@tonic-gate 2177c478bd9Sstevel@tonic-gate } 2187c478bd9Sstevel@tonic-gate 2197c478bd9Sstevel@tonic-gate dtp->dt_pdesc[id] = probe; 2207c478bd9Sstevel@tonic-gate dtp->dt_edesc[id] = enabled; 2217c478bd9Sstevel@tonic-gate 2227c478bd9Sstevel@tonic-gate return (0); 2237c478bd9Sstevel@tonic-gate 2247c478bd9Sstevel@tonic-gate err: 2257c478bd9Sstevel@tonic-gate /* 2267c478bd9Sstevel@tonic-gate * If we failed, free our allocated probes. Note that if we failed 2277c478bd9Sstevel@tonic-gate * while allocating formats, we aren't going to free formats that 2287c478bd9Sstevel@tonic-gate * we have already allocated. This is okay; these formats are 2297c478bd9Sstevel@tonic-gate * hanging off of dt_formats and will therefore not be leaked. 2307c478bd9Sstevel@tonic-gate */ 2317c478bd9Sstevel@tonic-gate free(enabled); 2327c478bd9Sstevel@tonic-gate free(probe); 2337c478bd9Sstevel@tonic-gate return (rval); 2347c478bd9Sstevel@tonic-gate } 2357c478bd9Sstevel@tonic-gate 2367c478bd9Sstevel@tonic-gate int 2377c478bd9Sstevel@tonic-gate dt_epid_lookup(dtrace_hdl_t *dtp, dtrace_epid_t epid, 2387c478bd9Sstevel@tonic-gate dtrace_eprobedesc_t **epdp, dtrace_probedesc_t **pdp) 2397c478bd9Sstevel@tonic-gate { 2407c478bd9Sstevel@tonic-gate int rval; 2417c478bd9Sstevel@tonic-gate 2427c478bd9Sstevel@tonic-gate if (epid >= dtp->dt_maxprobe || dtp->dt_pdesc[epid] == NULL) { 2437c478bd9Sstevel@tonic-gate if ((rval = dt_epid_add(dtp, epid)) != 0) 2447c478bd9Sstevel@tonic-gate return (rval); 2457c478bd9Sstevel@tonic-gate } 2467c478bd9Sstevel@tonic-gate 2477c478bd9Sstevel@tonic-gate assert(epid < dtp->dt_maxprobe); 2487c478bd9Sstevel@tonic-gate assert(dtp->dt_edesc[epid] != NULL); 2497c478bd9Sstevel@tonic-gate assert(dtp->dt_pdesc[epid] != NULL); 2507c478bd9Sstevel@tonic-gate *epdp = dtp->dt_edesc[epid]; 2517c478bd9Sstevel@tonic-gate *pdp = dtp->dt_pdesc[epid]; 2527c478bd9Sstevel@tonic-gate 2537c478bd9Sstevel@tonic-gate return (0); 2547c478bd9Sstevel@tonic-gate } 2557c478bd9Sstevel@tonic-gate 2567c478bd9Sstevel@tonic-gate void 2577c478bd9Sstevel@tonic-gate dt_epid_destroy(dtrace_hdl_t *dtp) 2587c478bd9Sstevel@tonic-gate { 2597c478bd9Sstevel@tonic-gate size_t i; 2607c478bd9Sstevel@tonic-gate 2617c478bd9Sstevel@tonic-gate assert((dtp->dt_pdesc != NULL && dtp->dt_edesc != NULL && 2627c478bd9Sstevel@tonic-gate dtp->dt_maxprobe > 0) || (dtp->dt_pdesc == NULL && 2637c478bd9Sstevel@tonic-gate dtp->dt_edesc == NULL && dtp->dt_maxprobe == 0)); 2647c478bd9Sstevel@tonic-gate 2657c478bd9Sstevel@tonic-gate if (dtp->dt_pdesc == NULL) 2667c478bd9Sstevel@tonic-gate return; 2677c478bd9Sstevel@tonic-gate 2687c478bd9Sstevel@tonic-gate for (i = 0; i < dtp->dt_maxprobe; i++) { 2697c478bd9Sstevel@tonic-gate if (dtp->dt_edesc[i] == NULL) { 2707c478bd9Sstevel@tonic-gate assert(dtp->dt_pdesc[i] == NULL); 2717c478bd9Sstevel@tonic-gate continue; 2727c478bd9Sstevel@tonic-gate } 2737c478bd9Sstevel@tonic-gate 2747c478bd9Sstevel@tonic-gate assert(dtp->dt_pdesc[i] != NULL); 2757c478bd9Sstevel@tonic-gate free(dtp->dt_edesc[i]); 2767c478bd9Sstevel@tonic-gate free(dtp->dt_pdesc[i]); 2777c478bd9Sstevel@tonic-gate } 2787c478bd9Sstevel@tonic-gate 2797c478bd9Sstevel@tonic-gate free(dtp->dt_pdesc); 2807c478bd9Sstevel@tonic-gate dtp->dt_pdesc = NULL; 2817c478bd9Sstevel@tonic-gate 2827c478bd9Sstevel@tonic-gate free(dtp->dt_edesc); 2837c478bd9Sstevel@tonic-gate dtp->dt_edesc = NULL; 2847c478bd9Sstevel@tonic-gate dtp->dt_maxprobe = 0; 2857c478bd9Sstevel@tonic-gate } 2867c478bd9Sstevel@tonic-gate 2877c478bd9Sstevel@tonic-gate void * 2887c478bd9Sstevel@tonic-gate dt_format_lookup(dtrace_hdl_t *dtp, int format) 2897c478bd9Sstevel@tonic-gate { 2907c478bd9Sstevel@tonic-gate if (format == 0 || format > dtp->dt_maxformat) 2917c478bd9Sstevel@tonic-gate return (NULL); 2927c478bd9Sstevel@tonic-gate 2937c478bd9Sstevel@tonic-gate if (dtp->dt_formats == NULL) 2947c478bd9Sstevel@tonic-gate return (NULL); 2957c478bd9Sstevel@tonic-gate 2967c478bd9Sstevel@tonic-gate return (dtp->dt_formats[format - 1]); 2977c478bd9Sstevel@tonic-gate } 2987c478bd9Sstevel@tonic-gate 2997c478bd9Sstevel@tonic-gate void 3007c478bd9Sstevel@tonic-gate dt_format_destroy(dtrace_hdl_t *dtp) 3017c478bd9Sstevel@tonic-gate { 3027c478bd9Sstevel@tonic-gate int i; 3037c478bd9Sstevel@tonic-gate 3047c478bd9Sstevel@tonic-gate for (i = 0; i < dtp->dt_maxformat; i++) { 3057c478bd9Sstevel@tonic-gate if (dtp->dt_formats[i] != NULL) 3067c478bd9Sstevel@tonic-gate dt_printf_destroy(dtp->dt_formats[i]); 3077c478bd9Sstevel@tonic-gate } 3087c478bd9Sstevel@tonic-gate 3097c478bd9Sstevel@tonic-gate free(dtp->dt_formats); 3107c478bd9Sstevel@tonic-gate dtp->dt_formats = NULL; 3117c478bd9Sstevel@tonic-gate } 3127c478bd9Sstevel@tonic-gate 3137c478bd9Sstevel@tonic-gate static int 3147c478bd9Sstevel@tonic-gate dt_aggid_add(dtrace_hdl_t *dtp, dtrace_aggid_t id) 3157c478bd9Sstevel@tonic-gate { 3167c478bd9Sstevel@tonic-gate dtrace_id_t max; 3177c478bd9Sstevel@tonic-gate dtrace_epid_t epid; 3187c478bd9Sstevel@tonic-gate int rval; 3197c478bd9Sstevel@tonic-gate 3207c478bd9Sstevel@tonic-gate while (id >= (max = dtp->dt_maxagg) || dtp->dt_aggdesc == NULL) { 3217c478bd9Sstevel@tonic-gate dtrace_id_t new_max = max ? (max << 1) : 1; 3227c478bd9Sstevel@tonic-gate size_t nsize = new_max * sizeof (void *); 3237c478bd9Sstevel@tonic-gate dtrace_aggdesc_t **new_aggdesc; 3247c478bd9Sstevel@tonic-gate 3257c478bd9Sstevel@tonic-gate if ((new_aggdesc = malloc(nsize)) == NULL) 3267c478bd9Sstevel@tonic-gate return (dt_set_errno(dtp, EDT_NOMEM)); 3277c478bd9Sstevel@tonic-gate 3287c478bd9Sstevel@tonic-gate bzero(new_aggdesc, nsize); 3297c478bd9Sstevel@tonic-gate 3307c478bd9Sstevel@tonic-gate if (dtp->dt_aggdesc != NULL) { 3317c478bd9Sstevel@tonic-gate bcopy(dtp->dt_aggdesc, new_aggdesc, 3327c478bd9Sstevel@tonic-gate max * sizeof (void *)); 3337c478bd9Sstevel@tonic-gate free(dtp->dt_aggdesc); 3347c478bd9Sstevel@tonic-gate } 3357c478bd9Sstevel@tonic-gate 3367c478bd9Sstevel@tonic-gate dtp->dt_aggdesc = new_aggdesc; 3377c478bd9Sstevel@tonic-gate dtp->dt_maxagg = new_max; 3387c478bd9Sstevel@tonic-gate } 3397c478bd9Sstevel@tonic-gate 3407c478bd9Sstevel@tonic-gate if (dtp->dt_aggdesc[id] == NULL) { 3417c478bd9Sstevel@tonic-gate dtrace_aggdesc_t *agg, *nagg; 3427c478bd9Sstevel@tonic-gate 3437c478bd9Sstevel@tonic-gate if ((agg = malloc(sizeof (dtrace_aggdesc_t))) == NULL) 3447c478bd9Sstevel@tonic-gate return (dt_set_errno(dtp, EDT_NOMEM)); 3457c478bd9Sstevel@tonic-gate 3467c478bd9Sstevel@tonic-gate bzero(agg, sizeof (dtrace_aggdesc_t)); 3477c478bd9Sstevel@tonic-gate agg->dtagd_id = id; 3487c478bd9Sstevel@tonic-gate agg->dtagd_nrecs = 1; 3497c478bd9Sstevel@tonic-gate 3507c478bd9Sstevel@tonic-gate if (dt_ioctl(dtp, DTRACEIOC_AGGDESC, agg) == -1) { 3517c478bd9Sstevel@tonic-gate rval = dt_set_errno(dtp, errno); 3527c478bd9Sstevel@tonic-gate free(agg); 3537c478bd9Sstevel@tonic-gate return (rval); 3547c478bd9Sstevel@tonic-gate } 3557c478bd9Sstevel@tonic-gate 3567c478bd9Sstevel@tonic-gate if (DTRACE_SIZEOF_AGGDESC(agg) != sizeof (*agg)) { 3577c478bd9Sstevel@tonic-gate /* 3587c478bd9Sstevel@tonic-gate * There must be more than one action. Allocate the 3597c478bd9Sstevel@tonic-gate * appropriate amount of space and try again. 3607c478bd9Sstevel@tonic-gate */ 3617c478bd9Sstevel@tonic-gate if ((nagg = malloc(DTRACE_SIZEOF_AGGDESC(agg))) != NULL) 3627c478bd9Sstevel@tonic-gate bcopy(agg, nagg, sizeof (*agg)); 3637c478bd9Sstevel@tonic-gate 3647c478bd9Sstevel@tonic-gate free(agg); 3657c478bd9Sstevel@tonic-gate 3667c478bd9Sstevel@tonic-gate if ((agg = nagg) == NULL) 3677c478bd9Sstevel@tonic-gate return (dt_set_errno(dtp, EDT_NOMEM)); 3687c478bd9Sstevel@tonic-gate 3697c478bd9Sstevel@tonic-gate rval = dt_ioctl(dtp, DTRACEIOC_AGGDESC, agg); 3707c478bd9Sstevel@tonic-gate 3717c478bd9Sstevel@tonic-gate if (rval == -1) { 3727c478bd9Sstevel@tonic-gate rval = dt_set_errno(dtp, errno); 3737c478bd9Sstevel@tonic-gate free(agg); 3747c478bd9Sstevel@tonic-gate return (rval); 3757c478bd9Sstevel@tonic-gate } 3767c478bd9Sstevel@tonic-gate } 3777c478bd9Sstevel@tonic-gate 37830ef842dSbmc /* 37930ef842dSbmc * If we have a uarg, it's a pointer to the compiler-generated 38030ef842dSbmc * statement; we'll use this value to get the name and 38130ef842dSbmc * compiler-generated variable ID for the aggregation. If 38230ef842dSbmc * we're grabbing an anonymous enabling, this pointer value 38330ef842dSbmc * is obviously meaningless -- and in this case, we can't 38430ef842dSbmc * provide the compiler-generated aggregation information. 38530ef842dSbmc */ 386c2580b93Sjhaslam if (dtp->dt_options[DTRACEOPT_GRABANON] == DTRACEOPT_UNSET && 387c2580b93Sjhaslam agg->dtagd_rec[0].dtrd_uarg != NULL) { 3887c478bd9Sstevel@tonic-gate dtrace_stmtdesc_t *sdp; 3897c478bd9Sstevel@tonic-gate dt_ident_t *aid; 3907c478bd9Sstevel@tonic-gate 3910b38a8bdSahl sdp = (dtrace_stmtdesc_t *)(uintptr_t) 3920b38a8bdSahl agg->dtagd_rec[0].dtrd_uarg; 3937c478bd9Sstevel@tonic-gate aid = sdp->dtsd_aggdata; 3947c478bd9Sstevel@tonic-gate agg->dtagd_name = aid->di_name; 39530ef842dSbmc agg->dtagd_varid = aid->di_id; 39630ef842dSbmc } else { 39730ef842dSbmc agg->dtagd_varid = DTRACE_AGGVARIDNONE; 3987c478bd9Sstevel@tonic-gate } 3997c478bd9Sstevel@tonic-gate 4007c478bd9Sstevel@tonic-gate if ((epid = agg->dtagd_epid) >= dtp->dt_maxprobe || 4017c478bd9Sstevel@tonic-gate dtp->dt_pdesc[epid] == NULL) { 4027c478bd9Sstevel@tonic-gate if ((rval = dt_epid_add(dtp, epid)) != 0) { 4037c478bd9Sstevel@tonic-gate free(agg); 4047c478bd9Sstevel@tonic-gate return (rval); 4057c478bd9Sstevel@tonic-gate } 4067c478bd9Sstevel@tonic-gate } 4077c478bd9Sstevel@tonic-gate 4087c478bd9Sstevel@tonic-gate dtp->dt_aggdesc[id] = agg; 4097c478bd9Sstevel@tonic-gate } 4107c478bd9Sstevel@tonic-gate 4117c478bd9Sstevel@tonic-gate return (0); 4127c478bd9Sstevel@tonic-gate } 4137c478bd9Sstevel@tonic-gate 4147c478bd9Sstevel@tonic-gate int 4157c478bd9Sstevel@tonic-gate dt_aggid_lookup(dtrace_hdl_t *dtp, dtrace_aggid_t aggid, 4167c478bd9Sstevel@tonic-gate dtrace_aggdesc_t **adp) 4177c478bd9Sstevel@tonic-gate { 4187c478bd9Sstevel@tonic-gate int rval; 4197c478bd9Sstevel@tonic-gate 4207c478bd9Sstevel@tonic-gate if (aggid >= dtp->dt_maxagg || dtp->dt_aggdesc[aggid] == NULL) { 4217c478bd9Sstevel@tonic-gate if ((rval = dt_aggid_add(dtp, aggid)) != 0) 4227c478bd9Sstevel@tonic-gate return (rval); 4237c478bd9Sstevel@tonic-gate } 4247c478bd9Sstevel@tonic-gate 4257c478bd9Sstevel@tonic-gate assert(aggid < dtp->dt_maxagg); 4267c478bd9Sstevel@tonic-gate assert(dtp->dt_aggdesc[aggid] != NULL); 4277c478bd9Sstevel@tonic-gate *adp = dtp->dt_aggdesc[aggid]; 4287c478bd9Sstevel@tonic-gate 4297c478bd9Sstevel@tonic-gate return (0); 4307c478bd9Sstevel@tonic-gate } 4317c478bd9Sstevel@tonic-gate 4327c478bd9Sstevel@tonic-gate void 4337c478bd9Sstevel@tonic-gate dt_aggid_destroy(dtrace_hdl_t *dtp) 4347c478bd9Sstevel@tonic-gate { 4357c478bd9Sstevel@tonic-gate size_t i; 4367c478bd9Sstevel@tonic-gate 4377c478bd9Sstevel@tonic-gate assert((dtp->dt_aggdesc != NULL && dtp->dt_maxagg != 0) || 4387c478bd9Sstevel@tonic-gate (dtp->dt_aggdesc == NULL && dtp->dt_maxagg == 0)); 4397c478bd9Sstevel@tonic-gate 4407c478bd9Sstevel@tonic-gate if (dtp->dt_aggdesc == NULL) 4417c478bd9Sstevel@tonic-gate return; 4427c478bd9Sstevel@tonic-gate 4437c478bd9Sstevel@tonic-gate for (i = 0; i < dtp->dt_maxagg; i++) { 4447c478bd9Sstevel@tonic-gate if (dtp->dt_aggdesc[i] != NULL) 4457c478bd9Sstevel@tonic-gate free(dtp->dt_aggdesc[i]); 4467c478bd9Sstevel@tonic-gate } 4477c478bd9Sstevel@tonic-gate 4487c478bd9Sstevel@tonic-gate free(dtp->dt_aggdesc); 4497c478bd9Sstevel@tonic-gate dtp->dt_aggdesc = NULL; 4507c478bd9Sstevel@tonic-gate dtp->dt_maxagg = 0; 4517c478bd9Sstevel@tonic-gate } 452*deef35fdSEric Schrock 453*deef35fdSEric Schrock const char * 454*deef35fdSEric Schrock dt_strdata_lookup(dtrace_hdl_t *dtp, int idx) 455*deef35fdSEric Schrock { 456*deef35fdSEric Schrock if (idx == 0 || idx > dtp->dt_maxstrdata) 457*deef35fdSEric Schrock return (NULL); 458*deef35fdSEric Schrock 459*deef35fdSEric Schrock if (dtp->dt_strdata == NULL) 460*deef35fdSEric Schrock return (NULL); 461*deef35fdSEric Schrock 462*deef35fdSEric Schrock return (dtp->dt_strdata[idx - 1]); 463*deef35fdSEric Schrock } 464*deef35fdSEric Schrock 465*deef35fdSEric Schrock void 466*deef35fdSEric Schrock dt_strdata_destroy(dtrace_hdl_t *dtp) 467*deef35fdSEric Schrock { 468*deef35fdSEric Schrock int i; 469*deef35fdSEric Schrock 470*deef35fdSEric Schrock for (i = 0; i < dtp->dt_maxstrdata; i++) { 471*deef35fdSEric Schrock free(dtp->dt_strdata[i]); 472*deef35fdSEric Schrock } 473*deef35fdSEric Schrock 474*deef35fdSEric Schrock free(dtp->dt_strdata); 475*deef35fdSEric Schrock dtp->dt_strdata = NULL; 476*deef35fdSEric Schrock } 477