4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
22 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
27 * Copyright (c) 2011 by Delphix. All rights reserved.
37 #include <dt_printf.h>
40 dt_strdata_add(dtrace_hdl_t *dtp, dtrace_recdesc_t *rec, void ***data, int *max)
46 if (rec->dtrd_format == 0)
49 if (rec->dtrd_format <= *max &&
50 (*data)[rec->dtrd_format - 1] != NULL) {
54 bzero(&fmt, sizeof (fmt));
55 fmt.dtfd_format = rec->dtrd_format;
56 fmt.dtfd_string = NULL;
59 if (dt_ioctl(dtp, DTRACEIOC_FORMAT, &fmt) == -1)
60 return (dt_set_errno(dtp, errno));
62 if ((fmt.dtfd_string = dt_alloc(dtp, fmt.dtfd_length)) == NULL)
63 return (dt_set_errno(dtp, EDT_NOMEM));
65 if (dt_ioctl(dtp, DTRACEIOC_FORMAT, &fmt) == -1) {
66 free(fmt.dtfd_string);
67 return (dt_set_errno(dtp, errno));
70 while (rec->dtrd_format > (maxformat = *max)) {
71 int new_max = maxformat ? (maxformat << 1) : 1;
72 size_t nsize = new_max * sizeof (void *);
73 size_t osize = maxformat * sizeof (void *);
74 void **new_data = dt_zalloc(dtp, nsize);
76 if (new_data == NULL) {
77 dt_free(dtp, fmt.dtfd_string);
78 return (dt_set_errno(dtp, EDT_NOMEM));
81 bcopy(*data, new_data, osize);
88 switch (rec->dtrd_action) {
89 case DTRACEACT_DIFEXPR:
90 result = fmt.dtfd_string;
92 case DTRACEACT_PRINTA:
93 result = dtrace_printa_create(dtp, fmt.dtfd_string);
94 dt_free(dtp, fmt.dtfd_string);
97 result = dtrace_printf_create(dtp, fmt.dtfd_string);
98 dt_free(dtp, fmt.dtfd_string);
105 (*data)[rec->dtrd_format - 1] = result;
111 dt_epid_add(dtrace_hdl_t *dtp, dtrace_epid_t id)
115 dtrace_eprobedesc_t *enabled, *nenabled;
116 dtrace_probedesc_t *probe;
118 while (id >= (max = dtp->dt_maxprobe) || dtp->dt_pdesc == NULL) {
119 dtrace_id_t new_max = max ? (max << 1) : 1;
120 size_t nsize = new_max * sizeof (void *);
121 dtrace_probedesc_t **new_pdesc;
122 dtrace_eprobedesc_t **new_edesc;
124 if ((new_pdesc = malloc(nsize)) == NULL ||
125 (new_edesc = malloc(nsize)) == NULL) {
127 return (dt_set_errno(dtp, EDT_NOMEM));
130 bzero(new_pdesc, nsize);
131 bzero(new_edesc, nsize);
133 if (dtp->dt_pdesc != NULL) {
134 size_t osize = max * sizeof (void *);
136 bcopy(dtp->dt_pdesc, new_pdesc, osize);
139 bcopy(dtp->dt_edesc, new_edesc, osize);
143 dtp->dt_pdesc = new_pdesc;
144 dtp->dt_edesc = new_edesc;
145 dtp->dt_maxprobe = new_max;
148 if (dtp->dt_pdesc[id] != NULL)
151 if ((enabled = malloc(sizeof (dtrace_eprobedesc_t))) == NULL)
152 return (dt_set_errno(dtp, EDT_NOMEM));
154 bzero(enabled, sizeof (dtrace_eprobedesc_t));
155 enabled->dtepd_epid = id;
156 enabled->dtepd_nrecs = 1;
159 if (dt_ioctl(dtp, DTRACEIOC_EPROBE, enabled) == -1) {
161 if (dt_ioctl(dtp, DTRACEIOC_EPROBE, &enabled) == -1) {
163 rval = dt_set_errno(dtp, errno);
168 if (DTRACE_SIZEOF_EPROBEDESC(enabled) != sizeof (*enabled)) {
170 * There must be more than one action. Allocate the
171 * appropriate amount of space and try again.
174 malloc(DTRACE_SIZEOF_EPROBEDESC(enabled))) != NULL)
175 bcopy(enabled, nenabled, sizeof (*enabled));
179 if ((enabled = nenabled) == NULL)
180 return (dt_set_errno(dtp, EDT_NOMEM));
183 rval = dt_ioctl(dtp, DTRACEIOC_EPROBE, enabled);
185 rval = dt_ioctl(dtp, DTRACEIOC_EPROBE, &enabled);
189 rval = dt_set_errno(dtp, errno);
195 if ((probe = malloc(sizeof (dtrace_probedesc_t))) == NULL) {
197 return (dt_set_errno(dtp, EDT_NOMEM));
200 probe->dtpd_id = enabled->dtepd_probeid;
202 if (dt_ioctl(dtp, DTRACEIOC_PROBES, probe) == -1) {
203 rval = dt_set_errno(dtp, errno);
207 for (i = 0; i < enabled->dtepd_nrecs; i++) {
208 dtrace_recdesc_t *rec = &enabled->dtepd_rec[i];
210 if (DTRACEACT_ISPRINTFLIKE(rec->dtrd_action)) {
211 if (dt_strdata_add(dtp, rec, &dtp->dt_formats,
212 &dtp->dt_maxformat) != 0) {
216 } else if (rec->dtrd_action == DTRACEACT_DIFEXPR) {
217 if (dt_strdata_add(dtp, rec,
218 (void ***)&dtp->dt_strdata,
219 &dtp->dt_maxstrdata) != 0) {
227 dtp->dt_pdesc[id] = probe;
228 dtp->dt_edesc[id] = enabled;
234 * If we failed, free our allocated probes. Note that if we failed
235 * while allocating formats, we aren't going to free formats that
236 * we have already allocated. This is okay; these formats are
237 * hanging off of dt_formats and will therefore not be leaked.
245 dt_epid_lookup(dtrace_hdl_t *dtp, dtrace_epid_t epid,
246 dtrace_eprobedesc_t **epdp, dtrace_probedesc_t **pdp)
250 if (epid >= dtp->dt_maxprobe || dtp->dt_pdesc[epid] == NULL) {
251 if ((rval = dt_epid_add(dtp, epid)) != 0)
255 assert(epid < dtp->dt_maxprobe);
256 assert(dtp->dt_edesc[epid] != NULL);
257 assert(dtp->dt_pdesc[epid] != NULL);
258 *epdp = dtp->dt_edesc[epid];
259 *pdp = dtp->dt_pdesc[epid];
265 dt_epid_destroy(dtrace_hdl_t *dtp)
269 assert((dtp->dt_pdesc != NULL && dtp->dt_edesc != NULL &&
270 dtp->dt_maxprobe > 0) || (dtp->dt_pdesc == NULL &&
271 dtp->dt_edesc == NULL && dtp->dt_maxprobe == 0));
273 if (dtp->dt_pdesc == NULL)
276 for (i = 0; i < dtp->dt_maxprobe; i++) {
277 if (dtp->dt_edesc[i] == NULL) {
278 assert(dtp->dt_pdesc[i] == NULL);
282 assert(dtp->dt_pdesc[i] != NULL);
283 free(dtp->dt_edesc[i]);
284 free(dtp->dt_pdesc[i]);
288 dtp->dt_pdesc = NULL;
291 dtp->dt_edesc = NULL;
292 dtp->dt_maxprobe = 0;
296 dt_format_lookup(dtrace_hdl_t *dtp, int format)
298 if (format == 0 || format > dtp->dt_maxformat)
301 if (dtp->dt_formats == NULL)
304 return (dtp->dt_formats[format - 1]);
308 dt_format_destroy(dtrace_hdl_t *dtp)
312 for (i = 0; i < dtp->dt_maxformat; i++) {
313 if (dtp->dt_formats[i] != NULL)
314 dt_printf_destroy(dtp->dt_formats[i]);
317 free(dtp->dt_formats);
318 dtp->dt_formats = NULL;
322 dt_aggid_add(dtrace_hdl_t *dtp, dtrace_aggid_t id)
328 while (id >= (max = dtp->dt_maxagg) || dtp->dt_aggdesc == NULL) {
329 dtrace_id_t new_max = max ? (max << 1) : 1;
330 size_t nsize = new_max * sizeof (void *);
331 dtrace_aggdesc_t **new_aggdesc;
333 if ((new_aggdesc = malloc(nsize)) == NULL)
334 return (dt_set_errno(dtp, EDT_NOMEM));
336 bzero(new_aggdesc, nsize);
338 if (dtp->dt_aggdesc != NULL) {
339 bcopy(dtp->dt_aggdesc, new_aggdesc,
340 max * sizeof (void *));
341 free(dtp->dt_aggdesc);
344 dtp->dt_aggdesc = new_aggdesc;
345 dtp->dt_maxagg = new_max;
348 if (dtp->dt_aggdesc[id] == NULL) {
349 dtrace_aggdesc_t *agg, *nagg;
351 if ((agg = malloc(sizeof (dtrace_aggdesc_t))) == NULL)
352 return (dt_set_errno(dtp, EDT_NOMEM));
354 bzero(agg, sizeof (dtrace_aggdesc_t));
356 agg->dtagd_nrecs = 1;
359 if (dt_ioctl(dtp, DTRACEIOC_AGGDESC, agg) == -1) {
361 if (dt_ioctl(dtp, DTRACEIOC_AGGDESC, &agg) == -1) {
363 rval = dt_set_errno(dtp, errno);
368 if (DTRACE_SIZEOF_AGGDESC(agg) != sizeof (*agg)) {
370 * There must be more than one action. Allocate the
371 * appropriate amount of space and try again.
373 if ((nagg = malloc(DTRACE_SIZEOF_AGGDESC(agg))) != NULL)
374 bcopy(agg, nagg, sizeof (*agg));
378 if ((agg = nagg) == NULL)
379 return (dt_set_errno(dtp, EDT_NOMEM));
382 rval = dt_ioctl(dtp, DTRACEIOC_AGGDESC, agg);
384 rval = dt_ioctl(dtp, DTRACEIOC_AGGDESC, &agg);
388 rval = dt_set_errno(dtp, errno);
395 * If we have a uarg, it's a pointer to the compiler-generated
396 * statement; we'll use this value to get the name and
397 * compiler-generated variable ID for the aggregation. If
398 * we're grabbing an anonymous enabling, this pointer value
399 * is obviously meaningless -- and in this case, we can't
400 * provide the compiler-generated aggregation information.
402 if (dtp->dt_options[DTRACEOPT_GRABANON] == DTRACEOPT_UNSET &&
403 agg->dtagd_rec[0].dtrd_uarg != 0) {
404 dtrace_stmtdesc_t *sdp;
407 sdp = (dtrace_stmtdesc_t *)(uintptr_t)
408 agg->dtagd_rec[0].dtrd_uarg;
409 aid = sdp->dtsd_aggdata;
410 agg->dtagd_name = aid->di_name;
411 agg->dtagd_varid = aid->di_id;
413 agg->dtagd_varid = DTRACE_AGGVARIDNONE;
416 if ((epid = agg->dtagd_epid) >= dtp->dt_maxprobe ||
417 dtp->dt_pdesc[epid] == NULL) {
418 if ((rval = dt_epid_add(dtp, epid)) != 0) {
424 dtp->dt_aggdesc[id] = agg;
431 dt_aggid_lookup(dtrace_hdl_t *dtp, dtrace_aggid_t aggid,
432 dtrace_aggdesc_t **adp)
436 if (aggid >= dtp->dt_maxagg || dtp->dt_aggdesc[aggid] == NULL) {
437 if ((rval = dt_aggid_add(dtp, aggid)) != 0)
441 assert(aggid < dtp->dt_maxagg);
442 assert(dtp->dt_aggdesc[aggid] != NULL);
443 *adp = dtp->dt_aggdesc[aggid];
449 dt_aggid_destroy(dtrace_hdl_t *dtp)
453 assert((dtp->dt_aggdesc != NULL && dtp->dt_maxagg != 0) ||
454 (dtp->dt_aggdesc == NULL && dtp->dt_maxagg == 0));
456 if (dtp->dt_aggdesc == NULL)
459 for (i = 0; i < dtp->dt_maxagg; i++) {
460 if (dtp->dt_aggdesc[i] != NULL)
461 free(dtp->dt_aggdesc[i]);
464 free(dtp->dt_aggdesc);
465 dtp->dt_aggdesc = NULL;
470 dt_strdata_lookup(dtrace_hdl_t *dtp, int idx)
472 if (idx == 0 || idx > dtp->dt_maxstrdata)
475 if (dtp->dt_strdata == NULL)
478 return (dtp->dt_strdata[idx - 1]);
482 dt_strdata_destroy(dtrace_hdl_t *dtp)
486 for (i = 0; i < dtp->dt_maxstrdata; i++) {
487 free(dtp->dt_strdata[i]);
490 free(dtp->dt_strdata);
491 dtp->dt_strdata = NULL;