1 1.1 darran /* 2 1.1 darran * CDDL HEADER START 3 1.1 darran * 4 1.1 darran * The contents of this file are subject to the terms of the 5 1.1 darran * Common Development and Distribution License (the "License"). 6 1.1 darran * You may not use this file except in compliance with the License. 7 1.1 darran * 8 1.1 darran * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 1.1 darran * or http://www.opensolaris.org/os/licensing. 10 1.1 darran * See the License for the specific language governing permissions 11 1.1 darran * and limitations under the License. 12 1.1 darran * 13 1.1 darran * When distributing Covered Code, include this CDDL HEADER in each 14 1.1 darran * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 1.1 darran * If applicable, add the following below this CDDL HEADER, with the 16 1.1 darran * fields enclosed by brackets "[]" replaced with your own identifying 17 1.1 darran * information: Portions Copyright [yyyy] [name of copyright owner] 18 1.1 darran * 19 1.1 darran * CDDL HEADER END 20 1.1 darran */ 21 1.1 darran 22 1.1 darran /* 23 1.1 darran * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 24 1.1 darran * Use is subject to license terms. 25 1.1 darran */ 26 1.3 christos /* 27 1.3 christos * Copyright (c) 2013, Joyent, Inc. All rights reserved. 28 1.3 christos */ 29 1.1 darran 30 1.1 darran #include <sys/types.h> 31 1.3 christos #ifdef illumos 32 1.1 darran #include <sys/sysmacros.h> 33 1.2 darran #endif 34 1.1 darran 35 1.1 darran #include <assert.h> 36 1.1 darran #include <limits.h> 37 1.1 darran #include <strings.h> 38 1.1 darran #include <stdlib.h> 39 1.3 christos #ifdef illumos 40 1.1 darran #include <alloca.h> 41 1.2 darran #endif 42 1.1 darran #include <unistd.h> 43 1.1 darran #include <errno.h> 44 1.1 darran 45 1.1 darran #include <dt_provider.h> 46 1.1 darran #include <dt_module.h> 47 1.1 darran #include <dt_string.h> 48 1.1 darran #include <dt_list.h> 49 1.3 christos #include <dt_pid.h> 50 1.3 christos #include <dtrace.h> 51 1.1 darran 52 1.1 darran static dt_provider_t * 53 1.1 darran dt_provider_insert(dtrace_hdl_t *dtp, dt_provider_t *pvp, uint_t h) 54 1.1 darran { 55 1.1 darran dt_list_append(&dtp->dt_provlist, pvp); 56 1.1 darran 57 1.1 darran pvp->pv_next = dtp->dt_provs[h]; 58 1.1 darran dtp->dt_provs[h] = pvp; 59 1.1 darran dtp->dt_nprovs++; 60 1.1 darran 61 1.1 darran return (pvp); 62 1.1 darran } 63 1.1 darran 64 1.1 darran dt_provider_t * 65 1.1 darran dt_provider_lookup(dtrace_hdl_t *dtp, const char *name) 66 1.1 darran { 67 1.1 darran uint_t h = dt_strtab_hash(name, NULL) % dtp->dt_provbuckets; 68 1.1 darran dtrace_providerdesc_t desc; 69 1.1 darran dt_provider_t *pvp; 70 1.1 darran 71 1.1 darran for (pvp = dtp->dt_provs[h]; pvp != NULL; pvp = pvp->pv_next) { 72 1.1 darran if (strcmp(pvp->pv_desc.dtvd_name, name) == 0) 73 1.1 darran return (pvp); 74 1.1 darran } 75 1.1 darran 76 1.1 darran if (strisglob(name) || name[0] == '\0') { 77 1.1 darran (void) dt_set_errno(dtp, EDT_NOPROV); 78 1.1 darran return (NULL); 79 1.1 darran } 80 1.1 darran 81 1.1 darran bzero(&desc, sizeof (desc)); 82 1.1 darran (void) strlcpy(desc.dtvd_name, name, DTRACE_PROVNAMELEN); 83 1.1 darran 84 1.1 darran if (dt_ioctl(dtp, DTRACEIOC_PROVIDER, &desc) == -1) { 85 1.1 darran (void) dt_set_errno(dtp, errno == ESRCH ? EDT_NOPROV : errno); 86 1.1 darran return (NULL); 87 1.1 darran } 88 1.1 darran 89 1.1 darran if ((pvp = dt_provider_create(dtp, name)) == NULL) 90 1.1 darran return (NULL); /* dt_errno is set for us */ 91 1.1 darran 92 1.1 darran bcopy(&desc, &pvp->pv_desc, sizeof (desc)); 93 1.1 darran pvp->pv_flags |= DT_PROVIDER_IMPL; 94 1.1 darran return (pvp); 95 1.1 darran } 96 1.1 darran 97 1.1 darran dt_provider_t * 98 1.1 darran dt_provider_create(dtrace_hdl_t *dtp, const char *name) 99 1.1 darran { 100 1.1 darran dt_provider_t *pvp; 101 1.1 darran 102 1.1 darran if ((pvp = dt_zalloc(dtp, sizeof (dt_provider_t))) == NULL) 103 1.1 darran return (NULL); 104 1.1 darran 105 1.1 darran (void) strlcpy(pvp->pv_desc.dtvd_name, name, DTRACE_PROVNAMELEN); 106 1.1 darran pvp->pv_probes = dt_idhash_create(pvp->pv_desc.dtvd_name, NULL, 0, 0); 107 1.1 darran pvp->pv_gen = dtp->dt_gen; 108 1.1 darran pvp->pv_hdl = dtp; 109 1.1 darran 110 1.1 darran if (pvp->pv_probes == NULL) { 111 1.1 darran dt_free(dtp, pvp); 112 1.1 darran (void) dt_set_errno(dtp, EDT_NOMEM); 113 1.1 darran return (NULL); 114 1.1 darran } 115 1.1 darran 116 1.1 darran pvp->pv_desc.dtvd_attr.dtpa_provider = _dtrace_prvattr; 117 1.1 darran pvp->pv_desc.dtvd_attr.dtpa_mod = _dtrace_prvattr; 118 1.1 darran pvp->pv_desc.dtvd_attr.dtpa_func = _dtrace_prvattr; 119 1.1 darran pvp->pv_desc.dtvd_attr.dtpa_name = _dtrace_prvattr; 120 1.1 darran pvp->pv_desc.dtvd_attr.dtpa_args = _dtrace_prvattr; 121 1.1 darran 122 1.1 darran return (dt_provider_insert(dtp, pvp, 123 1.1 darran dt_strtab_hash(name, NULL) % dtp->dt_provbuckets)); 124 1.1 darran } 125 1.1 darran 126 1.1 darran void 127 1.1 darran dt_provider_destroy(dtrace_hdl_t *dtp, dt_provider_t *pvp) 128 1.1 darran { 129 1.1 darran dt_provider_t **pp; 130 1.1 darran uint_t h; 131 1.1 darran 132 1.1 darran assert(pvp->pv_hdl == dtp); 133 1.1 darran 134 1.1 darran h = dt_strtab_hash(pvp->pv_desc.dtvd_name, NULL) % dtp->dt_provbuckets; 135 1.1 darran pp = &dtp->dt_provs[h]; 136 1.1 darran 137 1.1 darran while (*pp != NULL && *pp != pvp) 138 1.1 darran pp = &(*pp)->pv_next; 139 1.1 darran 140 1.1 darran assert(*pp != NULL && *pp == pvp); 141 1.1 darran *pp = pvp->pv_next; 142 1.1 darran 143 1.1 darran dt_list_delete(&dtp->dt_provlist, pvp); 144 1.1 darran dtp->dt_nprovs--; 145 1.1 darran 146 1.1 darran if (pvp->pv_probes != NULL) 147 1.1 darran dt_idhash_destroy(pvp->pv_probes); 148 1.1 darran 149 1.1 darran dt_node_link_free(&pvp->pv_nodes); 150 1.1 darran dt_free(dtp, pvp->pv_xrefs); 151 1.1 darran dt_free(dtp, pvp); 152 1.1 darran } 153 1.1 darran 154 1.1 darran int 155 1.1 darran dt_provider_xref(dtrace_hdl_t *dtp, dt_provider_t *pvp, id_t id) 156 1.1 darran { 157 1.1 darran size_t oldsize = BT_SIZEOFMAP(pvp->pv_xrmax); 158 1.1 darran size_t newsize = BT_SIZEOFMAP(dtp->dt_xlatorid); 159 1.1 darran 160 1.1 darran assert(id >= 0 && id < dtp->dt_xlatorid); 161 1.1 darran 162 1.1 darran if (newsize > oldsize) { 163 1.1 darran ulong_t *xrefs = dt_zalloc(dtp, newsize); 164 1.1 darran 165 1.1 darran if (xrefs == NULL) 166 1.1 darran return (-1); 167 1.1 darran 168 1.1 darran bcopy(pvp->pv_xrefs, xrefs, oldsize); 169 1.1 darran dt_free(dtp, pvp->pv_xrefs); 170 1.1 darran 171 1.1 darran pvp->pv_xrefs = xrefs; 172 1.1 darran pvp->pv_xrmax = dtp->dt_xlatorid; 173 1.1 darran } 174 1.1 darran 175 1.1 darran BT_SET(pvp->pv_xrefs, id); 176 1.1 darran return (0); 177 1.1 darran } 178 1.1 darran 179 1.1 darran static uint8_t 180 1.1 darran dt_probe_argmap(dt_node_t *xnp, dt_node_t *nnp) 181 1.1 darran { 182 1.1 darran uint8_t i; 183 1.1 darran 184 1.1 darran for (i = 0; nnp != NULL; i++) { 185 1.1 darran if (nnp->dn_string != NULL && 186 1.1 darran strcmp(nnp->dn_string, xnp->dn_string) == 0) 187 1.1 darran break; 188 1.1 darran else 189 1.1 darran nnp = nnp->dn_list; 190 1.1 darran } 191 1.1 darran 192 1.1 darran return (i); 193 1.1 darran } 194 1.1 darran 195 1.1 darran static dt_node_t * 196 1.1 darran dt_probe_alloc_args(dt_provider_t *pvp, int argc) 197 1.1 darran { 198 1.1 darran dt_node_t *args = NULL, *pnp = NULL, *dnp; 199 1.1 darran int i; 200 1.1 darran 201 1.1 darran for (i = 0; i < argc; i++, pnp = dnp) { 202 1.1 darran if ((dnp = dt_node_xalloc(pvp->pv_hdl, DT_NODE_TYPE)) == NULL) 203 1.1 darran return (NULL); 204 1.1 darran 205 1.1 darran dnp->dn_link = pvp->pv_nodes; 206 1.1 darran pvp->pv_nodes = dnp; 207 1.1 darran 208 1.1 darran if (args == NULL) 209 1.1 darran args = dnp; 210 1.1 darran else 211 1.1 darran pnp->dn_list = dnp; 212 1.1 darran } 213 1.1 darran 214 1.1 darran return (args); 215 1.1 darran } 216 1.1 darran 217 1.1 darran static size_t 218 1.1 darran dt_probe_keylen(const dtrace_probedesc_t *pdp) 219 1.1 darran { 220 1.1 darran return (strlen(pdp->dtpd_mod) + 1 + 221 1.1 darran strlen(pdp->dtpd_func) + 1 + strlen(pdp->dtpd_name) + 1); 222 1.1 darran } 223 1.1 darran 224 1.1 darran static char * 225 1.1 darran dt_probe_key(const dtrace_probedesc_t *pdp, char *s) 226 1.1 darran { 227 1.1 darran (void) snprintf(s, INT_MAX, "%s:%s:%s", 228 1.1 darran pdp->dtpd_mod, pdp->dtpd_func, pdp->dtpd_name); 229 1.1 darran return (s); 230 1.1 darran } 231 1.1 darran 232 1.1 darran /* 233 1.1 darran * If a probe was discovered from the kernel, ask dtrace(7D) for a description 234 1.1 darran * of each of its arguments, including native and translated types. 235 1.1 darran */ 236 1.1 darran static dt_probe_t * 237 1.1 darran dt_probe_discover(dt_provider_t *pvp, const dtrace_probedesc_t *pdp) 238 1.1 darran { 239 1.1 darran dtrace_hdl_t *dtp = pvp->pv_hdl; 240 1.1 darran char *name = dt_probe_key(pdp, alloca(dt_probe_keylen(pdp))); 241 1.1 darran 242 1.1 darran dt_node_t *xargs, *nargs; 243 1.1 darran dt_ident_t *idp; 244 1.1 darran dt_probe_t *prp; 245 1.1 darran 246 1.1 darran dtrace_typeinfo_t dtt; 247 1.1 darran int i, nc, xc; 248 1.1 darran 249 1.1 darran int adc = _dtrace_argmax; 250 1.1 darran dtrace_argdesc_t *adv = alloca(sizeof (dtrace_argdesc_t) * adc); 251 1.1 darran dtrace_argdesc_t *adp = adv; 252 1.1 darran 253 1.1 darran assert(strcmp(pvp->pv_desc.dtvd_name, pdp->dtpd_provider) == 0); 254 1.1 darran assert(pdp->dtpd_id != DTRACE_IDNONE); 255 1.1 darran 256 1.1 darran dt_dprintf("discovering probe %s:%s id=%d\n", 257 1.1 darran pvp->pv_desc.dtvd_name, name, pdp->dtpd_id); 258 1.1 darran 259 1.1 darran for (nc = -1, i = 0; i < adc; i++, adp++) { 260 1.1 darran bzero(adp, sizeof (dtrace_argdesc_t)); 261 1.1 darran adp->dtargd_ndx = i; 262 1.1 darran adp->dtargd_id = pdp->dtpd_id; 263 1.1 darran 264 1.1 darran if (dt_ioctl(dtp, DTRACEIOC_PROBEARG, adp) != 0) { 265 1.1 darran (void) dt_set_errno(dtp, errno); 266 1.1 darran return (NULL); 267 1.1 darran } 268 1.1 darran 269 1.1 darran if (adp->dtargd_ndx == DTRACE_ARGNONE) 270 1.1 darran break; /* all argument descs have been retrieved */ 271 1.1 darran 272 1.1 darran nc = MAX(nc, adp->dtargd_mapping); 273 1.1 darran } 274 1.1 darran 275 1.1 darran xc = i; 276 1.1 darran nc++; 277 1.1 darran 278 1.1 darran /* 279 1.3 christos * The pid provider believes in giving the kernel a break. No reason to 280 1.3 christos * give the kernel all the ctf containers that we're keeping ourselves 281 1.3 christos * just to get it back from it. So if we're coming from a pid provider 282 1.3 christos * probe and the kernel gave us no argument information we'll get some 283 1.3 christos * here. If for some crazy reason the kernel knows about our userland 284 1.3 christos * types then we just ignore this. 285 1.3 christos */ 286 1.3 christos if (xc == 0 && nc == 0 && 287 1.3 christos strncmp(pvp->pv_desc.dtvd_name, "pid", 3) == 0) { 288 1.3 christos nc = adc; 289 1.3 christos dt_pid_get_types(dtp, pdp, adv, &nc); 290 1.3 christos xc = nc; 291 1.3 christos } 292 1.3 christos 293 1.3 christos /* 294 1.1 darran * Now that we have discovered the number of native and translated 295 1.1 darran * arguments from the argument descriptions, allocate a new probe ident 296 1.1 darran * and corresponding dt_probe_t and hash it into the provider. 297 1.1 darran */ 298 1.1 darran xargs = dt_probe_alloc_args(pvp, xc); 299 1.1 darran nargs = dt_probe_alloc_args(pvp, nc); 300 1.1 darran 301 1.1 darran if ((xc != 0 && xargs == NULL) || (nc != 0 && nargs == NULL)) 302 1.1 darran return (NULL); /* dt_errno is set for us */ 303 1.1 darran 304 1.1 darran idp = dt_ident_create(name, DT_IDENT_PROBE, 305 1.1 darran DT_IDFLG_ORPHAN, pdp->dtpd_id, _dtrace_defattr, 0, 306 1.1 darran &dt_idops_probe, NULL, dtp->dt_gen); 307 1.1 darran 308 1.1 darran if (idp == NULL) { 309 1.1 darran (void) dt_set_errno(dtp, EDT_NOMEM); 310 1.1 darran return (NULL); 311 1.1 darran } 312 1.1 darran 313 1.1 darran if ((prp = dt_probe_create(dtp, idp, 2, 314 1.1 darran nargs, nc, xargs, xc)) == NULL) { 315 1.1 darran dt_ident_destroy(idp); 316 1.1 darran return (NULL); 317 1.1 darran } 318 1.1 darran 319 1.1 darran dt_probe_declare(pvp, prp); 320 1.1 darran 321 1.1 darran /* 322 1.1 darran * Once our new dt_probe_t is fully constructed, iterate over the 323 1.1 darran * cached argument descriptions and assign types to prp->pr_nargv[] 324 1.1 darran * and prp->pr_xargv[] and assign mappings to prp->pr_mapping[]. 325 1.1 darran */ 326 1.1 darran for (adp = adv, i = 0; i < xc; i++, adp++) { 327 1.1 darran if (dtrace_type_strcompile(dtp, 328 1.1 darran adp->dtargd_native, &dtt) != 0) { 329 1.1 darran dt_dprintf("failed to resolve input type %s " 330 1.1 darran "for %s:%s arg #%d: %s\n", adp->dtargd_native, 331 1.1 darran pvp->pv_desc.dtvd_name, name, i + 1, 332 1.1 darran dtrace_errmsg(dtp, dtrace_errno(dtp))); 333 1.1 darran 334 1.1 darran dtt.dtt_object = NULL; 335 1.1 darran dtt.dtt_ctfp = NULL; 336 1.1 darran dtt.dtt_type = CTF_ERR; 337 1.1 darran } else { 338 1.1 darran dt_node_type_assign(prp->pr_nargv[adp->dtargd_mapping], 339 1.3 christos dtt.dtt_ctfp, dtt.dtt_type, 340 1.3 christos dtt.dtt_flags & DTT_FL_USER ? B_TRUE : B_FALSE); 341 1.1 darran } 342 1.1 darran 343 1.1 darran if (dtt.dtt_type != CTF_ERR && (adp->dtargd_xlate[0] == '\0' || 344 1.1 darran strcmp(adp->dtargd_native, adp->dtargd_xlate) == 0)) { 345 1.1 darran dt_node_type_propagate(prp->pr_nargv[ 346 1.1 darran adp->dtargd_mapping], prp->pr_xargv[i]); 347 1.1 darran } else if (dtrace_type_strcompile(dtp, 348 1.1 darran adp->dtargd_xlate, &dtt) != 0) { 349 1.1 darran dt_dprintf("failed to resolve output type %s " 350 1.1 darran "for %s:%s arg #%d: %s\n", adp->dtargd_xlate, 351 1.1 darran pvp->pv_desc.dtvd_name, name, i + 1, 352 1.1 darran dtrace_errmsg(dtp, dtrace_errno(dtp))); 353 1.1 darran 354 1.1 darran dtt.dtt_object = NULL; 355 1.1 darran dtt.dtt_ctfp = NULL; 356 1.1 darran dtt.dtt_type = CTF_ERR; 357 1.1 darran } else { 358 1.1 darran dt_node_type_assign(prp->pr_xargv[i], 359 1.3 christos dtt.dtt_ctfp, dtt.dtt_type, B_FALSE); 360 1.1 darran } 361 1.1 darran 362 1.1 darran prp->pr_mapping[i] = adp->dtargd_mapping; 363 1.1 darran prp->pr_argv[i] = dtt; 364 1.1 darran } 365 1.1 darran 366 1.1 darran return (prp); 367 1.1 darran } 368 1.1 darran 369 1.1 darran /* 370 1.1 darran * Lookup a probe declaration based on a known provider and full or partially 371 1.1 darran * specified module, function, and name. If the probe is not known to us yet, 372 1.1 darran * ask dtrace(7D) to match the description and then cache any useful results. 373 1.1 darran */ 374 1.1 darran dt_probe_t * 375 1.1 darran dt_probe_lookup(dt_provider_t *pvp, const char *s) 376 1.1 darran { 377 1.1 darran dtrace_hdl_t *dtp = pvp->pv_hdl; 378 1.1 darran dtrace_probedesc_t pd; 379 1.1 darran dt_ident_t *idp; 380 1.1 darran size_t keylen; 381 1.1 darran char *key; 382 1.1 darran 383 1.1 darran if (dtrace_str2desc(dtp, DTRACE_PROBESPEC_NAME, s, &pd) != 0) 384 1.1 darran return (NULL); /* dt_errno is set for us */ 385 1.1 darran 386 1.1 darran keylen = dt_probe_keylen(&pd); 387 1.1 darran key = dt_probe_key(&pd, alloca(keylen)); 388 1.1 darran 389 1.1 darran /* 390 1.1 darran * If the probe is already declared, then return the dt_probe_t from 391 1.1 darran * the existing identifier. This could come from a static declaration 392 1.1 darran * or it could have been cached from an earlier call to this function. 393 1.1 darran */ 394 1.1 darran if ((idp = dt_idhash_lookup(pvp->pv_probes, key)) != NULL) 395 1.1 darran return (idp->di_data); 396 1.1 darran 397 1.1 darran /* 398 1.1 darran * If the probe isn't known, use the probe description computed above 399 1.1 darran * to ask dtrace(7D) to find the first matching probe. 400 1.1 darran */ 401 1.1 darran if (dt_ioctl(dtp, DTRACEIOC_PROBEMATCH, &pd) == 0) 402 1.1 darran return (dt_probe_discover(pvp, &pd)); 403 1.1 darran 404 1.1 darran if (errno == ESRCH || errno == EBADF) 405 1.1 darran (void) dt_set_errno(dtp, EDT_NOPROBE); 406 1.1 darran else 407 1.1 darran (void) dt_set_errno(dtp, errno); 408 1.1 darran 409 1.1 darran return (NULL); 410 1.1 darran } 411 1.1 darran 412 1.1 darran dt_probe_t * 413 1.1 darran dt_probe_create(dtrace_hdl_t *dtp, dt_ident_t *idp, int protoc, 414 1.1 darran dt_node_t *nargs, uint_t nargc, dt_node_t *xargs, uint_t xargc) 415 1.1 darran { 416 1.1 darran dt_module_t *dmp; 417 1.1 darran dt_probe_t *prp; 418 1.1 darran const char *p; 419 1.1 darran uint_t i; 420 1.1 darran 421 1.1 darran assert(idp->di_kind == DT_IDENT_PROBE); 422 1.1 darran assert(idp->di_data == NULL); 423 1.1 darran 424 1.1 darran /* 425 1.1 darran * If only a single prototype is given, set xargc/s to nargc/s to 426 1.1 darran * simplify subsequent use. Note that we can have one or both of nargs 427 1.1 darran * and xargs be specified but set to NULL, indicating a void prototype. 428 1.1 darran */ 429 1.1 darran if (protoc < 2) { 430 1.1 darran assert(xargs == NULL); 431 1.1 darran assert(xargc == 0); 432 1.1 darran xargs = nargs; 433 1.1 darran xargc = nargc; 434 1.1 darran } 435 1.1 darran 436 1.1 darran if ((prp = dt_alloc(dtp, sizeof (dt_probe_t))) == NULL) 437 1.1 darran return (NULL); 438 1.1 darran 439 1.1 darran prp->pr_pvp = NULL; 440 1.1 darran prp->pr_ident = idp; 441 1.1 darran 442 1.1 darran p = strrchr(idp->di_name, ':'); 443 1.1 darran assert(p != NULL); 444 1.1 darran prp->pr_name = p + 1; 445 1.1 darran 446 1.1 darran prp->pr_nargs = nargs; 447 1.1 darran prp->pr_nargv = dt_alloc(dtp, sizeof (dt_node_t *) * nargc); 448 1.1 darran prp->pr_nargc = nargc; 449 1.1 darran prp->pr_xargs = xargs; 450 1.1 darran prp->pr_xargv = dt_alloc(dtp, sizeof (dt_node_t *) * xargc); 451 1.1 darran prp->pr_xargc = xargc; 452 1.1 darran prp->pr_mapping = dt_alloc(dtp, sizeof (uint8_t) * xargc); 453 1.1 darran prp->pr_inst = NULL; 454 1.1 darran prp->pr_argv = dt_alloc(dtp, sizeof (dtrace_typeinfo_t) * xargc); 455 1.1 darran prp->pr_argc = xargc; 456 1.1 darran 457 1.1 darran if ((prp->pr_nargc != 0 && prp->pr_nargv == NULL) || 458 1.1 darran (prp->pr_xargc != 0 && prp->pr_xargv == NULL) || 459 1.1 darran (prp->pr_xargc != 0 && prp->pr_mapping == NULL) || 460 1.1 darran (prp->pr_argc != 0 && prp->pr_argv == NULL)) { 461 1.1 darran dt_probe_destroy(prp); 462 1.1 darran return (NULL); 463 1.1 darran } 464 1.1 darran 465 1.1 darran for (i = 0; i < xargc; i++, xargs = xargs->dn_list) { 466 1.1 darran if (xargs->dn_string != NULL) 467 1.1 darran prp->pr_mapping[i] = dt_probe_argmap(xargs, nargs); 468 1.1 darran else 469 1.1 darran prp->pr_mapping[i] = i; 470 1.1 darran 471 1.1 darran prp->pr_xargv[i] = xargs; 472 1.1 darran 473 1.1 darran if ((dmp = dt_module_lookup_by_ctf(dtp, 474 1.1 darran xargs->dn_ctfp)) != NULL) 475 1.1 darran prp->pr_argv[i].dtt_object = dmp->dm_name; 476 1.1 darran else 477 1.1 darran prp->pr_argv[i].dtt_object = NULL; 478 1.1 darran 479 1.1 darran prp->pr_argv[i].dtt_ctfp = xargs->dn_ctfp; 480 1.1 darran prp->pr_argv[i].dtt_type = xargs->dn_type; 481 1.1 darran } 482 1.1 darran 483 1.1 darran for (i = 0; i < nargc; i++, nargs = nargs->dn_list) 484 1.1 darran prp->pr_nargv[i] = nargs; 485 1.1 darran 486 1.1 darran idp->di_data = prp; 487 1.1 darran return (prp); 488 1.1 darran } 489 1.1 darran 490 1.1 darran void 491 1.1 darran dt_probe_declare(dt_provider_t *pvp, dt_probe_t *prp) 492 1.1 darran { 493 1.1 darran assert(prp->pr_ident->di_kind == DT_IDENT_PROBE); 494 1.1 darran assert(prp->pr_ident->di_data == prp); 495 1.1 darran assert(prp->pr_pvp == NULL); 496 1.1 darran 497 1.1 darran if (prp->pr_xargs != prp->pr_nargs) 498 1.1 darran pvp->pv_flags &= ~DT_PROVIDER_INTF; 499 1.1 darran 500 1.1 darran prp->pr_pvp = pvp; 501 1.1 darran dt_idhash_xinsert(pvp->pv_probes, prp->pr_ident); 502 1.1 darran } 503 1.1 darran 504 1.1 darran void 505 1.1 darran dt_probe_destroy(dt_probe_t *prp) 506 1.1 darran { 507 1.1 darran dt_probe_instance_t *pip, *pip_next; 508 1.1 darran dtrace_hdl_t *dtp; 509 1.1 darran 510 1.1 darran if (prp->pr_pvp != NULL) 511 1.1 darran dtp = prp->pr_pvp->pv_hdl; 512 1.1 darran else 513 1.1 darran dtp = yypcb->pcb_hdl; 514 1.1 darran 515 1.1 darran dt_node_list_free(&prp->pr_nargs); 516 1.1 darran dt_node_list_free(&prp->pr_xargs); 517 1.1 darran 518 1.1 darran dt_free(dtp, prp->pr_nargv); 519 1.1 darran dt_free(dtp, prp->pr_xargv); 520 1.1 darran 521 1.1 darran for (pip = prp->pr_inst; pip != NULL; pip = pip_next) { 522 1.1 darran pip_next = pip->pi_next; 523 1.3 christos dt_free(dtp, pip->pi_rname); 524 1.3 christos dt_free(dtp, pip->pi_fname); 525 1.1 darran dt_free(dtp, pip->pi_offs); 526 1.1 darran dt_free(dtp, pip->pi_enoffs); 527 1.1 darran dt_free(dtp, pip); 528 1.1 darran } 529 1.1 darran 530 1.1 darran dt_free(dtp, prp->pr_mapping); 531 1.1 darran dt_free(dtp, prp->pr_argv); 532 1.1 darran dt_free(dtp, prp); 533 1.1 darran } 534 1.1 darran 535 1.1 darran int 536 1.1 darran dt_probe_define(dt_provider_t *pvp, dt_probe_t *prp, 537 1.1 darran const char *fname, const char *rname, uint32_t offset, int isenabled) 538 1.1 darran { 539 1.1 darran dtrace_hdl_t *dtp = pvp->pv_hdl; 540 1.1 darran dt_probe_instance_t *pip; 541 1.1 darran uint32_t **offs; 542 1.1 darran uint_t *noffs, *maxoffs; 543 1.1 darran 544 1.1 darran assert(fname != NULL); 545 1.1 darran 546 1.1 darran for (pip = prp->pr_inst; pip != NULL; pip = pip->pi_next) { 547 1.1 darran if (strcmp(pip->pi_fname, fname) == 0 && 548 1.4 chs strcmp(pip->pi_rname, rname) == 0) 549 1.1 darran break; 550 1.1 darran } 551 1.1 darran 552 1.1 darran if (pip == NULL) { 553 1.1 darran if ((pip = dt_zalloc(dtp, sizeof (*pip))) == NULL) 554 1.1 darran return (-1); 555 1.1 darran 556 1.3 christos if ((pip->pi_offs = dt_zalloc(dtp, sizeof (uint32_t))) == NULL) 557 1.3 christos goto nomem; 558 1.1 darran 559 1.1 darran if ((pip->pi_enoffs = dt_zalloc(dtp, 560 1.3 christos sizeof (uint32_t))) == NULL) 561 1.3 christos goto nomem; 562 1.3 christos 563 1.3 christos if ((pip->pi_fname = strdup(fname)) == NULL) 564 1.3 christos goto nomem; 565 1.1 darran 566 1.4 chs if ((pip->pi_rname = strdup(rname)) == NULL) 567 1.3 christos goto nomem; 568 1.1 darran 569 1.1 darran pip->pi_noffs = 0; 570 1.1 darran pip->pi_maxoffs = 1; 571 1.1 darran pip->pi_nenoffs = 0; 572 1.1 darran pip->pi_maxenoffs = 1; 573 1.1 darran 574 1.1 darran pip->pi_next = prp->pr_inst; 575 1.1 darran 576 1.1 darran prp->pr_inst = pip; 577 1.1 darran } 578 1.1 darran 579 1.1 darran if (isenabled) { 580 1.1 darran offs = &pip->pi_enoffs; 581 1.1 darran noffs = &pip->pi_nenoffs; 582 1.1 darran maxoffs = &pip->pi_maxenoffs; 583 1.1 darran } else { 584 1.1 darran offs = &pip->pi_offs; 585 1.1 darran noffs = &pip->pi_noffs; 586 1.1 darran maxoffs = &pip->pi_maxoffs; 587 1.1 darran } 588 1.1 darran 589 1.1 darran if (*noffs == *maxoffs) { 590 1.1 darran uint_t new_max = *maxoffs * 2; 591 1.1 darran uint32_t *new_offs = dt_alloc(dtp, sizeof (uint32_t) * new_max); 592 1.1 darran 593 1.1 darran if (new_offs == NULL) 594 1.1 darran return (-1); 595 1.1 darran 596 1.1 darran bcopy(*offs, new_offs, sizeof (uint32_t) * *maxoffs); 597 1.1 darran 598 1.1 darran dt_free(dtp, *offs); 599 1.1 darran *maxoffs = new_max; 600 1.1 darran *offs = new_offs; 601 1.1 darran } 602 1.1 darran 603 1.1 darran dt_dprintf("defined probe %s %s:%s %s() +0x%x (%s)\n", 604 1.1 darran isenabled ? "(is-enabled)" : "", 605 1.1 darran pvp->pv_desc.dtvd_name, prp->pr_ident->di_name, fname, offset, 606 1.4 chs rname); 607 1.1 darran 608 1.1 darran assert(*noffs < *maxoffs); 609 1.1 darran (*offs)[(*noffs)++] = offset; 610 1.1 darran 611 1.1 darran return (0); 612 1.3 christos 613 1.3 christos nomem: 614 1.3 christos dt_free(dtp, pip->pi_fname); 615 1.3 christos dt_free(dtp, pip->pi_enoffs); 616 1.3 christos dt_free(dtp, pip->pi_offs); 617 1.3 christos dt_free(dtp, pip); 618 1.3 christos return (dt_set_errno(dtp, EDT_NOMEM)); 619 1.1 darran } 620 1.1 darran 621 1.1 darran /* 622 1.1 darran * Lookup the dynamic translator type tag for the specified probe argument and 623 1.1 darran * assign the type to the specified node. If the type is not yet defined, add 624 1.1 darran * it to the "D" module's type container as a typedef for an unknown type. 625 1.1 darran */ 626 1.1 darran dt_node_t * 627 1.1 darran dt_probe_tag(dt_probe_t *prp, uint_t argn, dt_node_t *dnp) 628 1.1 darran { 629 1.1 darran dtrace_hdl_t *dtp = prp->pr_pvp->pv_hdl; 630 1.1 darran dtrace_typeinfo_t dtt; 631 1.1 darran size_t len; 632 1.1 darran char *tag; 633 1.1 darran 634 1.1 darran len = snprintf(NULL, 0, "__dtrace_%s___%s_arg%u", 635 1.1 darran prp->pr_pvp->pv_desc.dtvd_name, prp->pr_name, argn); 636 1.1 darran 637 1.1 darran tag = alloca(len + 1); 638 1.1 darran 639 1.1 darran (void) snprintf(tag, len + 1, "__dtrace_%s___%s_arg%u", 640 1.1 darran prp->pr_pvp->pv_desc.dtvd_name, prp->pr_name, argn); 641 1.1 darran 642 1.1 darran if (dtrace_lookup_by_type(dtp, DTRACE_OBJ_DDEFS, tag, &dtt) != 0) { 643 1.1 darran dtt.dtt_object = DTRACE_OBJ_DDEFS; 644 1.1 darran dtt.dtt_ctfp = DT_DYN_CTFP(dtp); 645 1.1 darran dtt.dtt_type = ctf_add_typedef(DT_DYN_CTFP(dtp), 646 1.1 darran CTF_ADD_ROOT, tag, DT_DYN_TYPE(dtp)); 647 1.1 darran 648 1.1 darran if (dtt.dtt_type == CTF_ERR || 649 1.1 darran ctf_update(dtt.dtt_ctfp) == CTF_ERR) { 650 1.1 darran xyerror(D_UNKNOWN, "cannot define type %s: %s\n", 651 1.1 darran tag, ctf_errmsg(ctf_errno(dtt.dtt_ctfp))); 652 1.1 darran } 653 1.1 darran } 654 1.1 darran 655 1.1 darran bzero(dnp, sizeof (dt_node_t)); 656 1.1 darran dnp->dn_kind = DT_NODE_TYPE; 657 1.1 darran 658 1.3 christos dt_node_type_assign(dnp, dtt.dtt_ctfp, dtt.dtt_type, B_FALSE); 659 1.1 darran dt_node_attr_assign(dnp, _dtrace_defattr); 660 1.1 darran 661 1.1 darran return (dnp); 662 1.1 darran } 663 1.1 darran 664 1.1 darran /*ARGSUSED*/ 665 1.1 darran static int 666 1.1 darran dt_probe_desc(dtrace_hdl_t *dtp, const dtrace_probedesc_t *pdp, void *arg) 667 1.1 darran { 668 1.1 darran if (((dtrace_probedesc_t *)arg)->dtpd_id == DTRACE_IDNONE) { 669 1.1 darran bcopy(pdp, arg, sizeof (dtrace_probedesc_t)); 670 1.1 darran return (0); 671 1.1 darran } 672 1.1 darran 673 1.1 darran return (1); 674 1.1 darran } 675 1.1 darran 676 1.1 darran dt_probe_t * 677 1.1 darran dt_probe_info(dtrace_hdl_t *dtp, 678 1.1 darran const dtrace_probedesc_t *pdp, dtrace_probeinfo_t *pip) 679 1.1 darran { 680 1.1 darran int m_is_glob = pdp->dtpd_mod[0] == '\0' || strisglob(pdp->dtpd_mod); 681 1.1 darran int f_is_glob = pdp->dtpd_func[0] == '\0' || strisglob(pdp->dtpd_func); 682 1.1 darran int n_is_glob = pdp->dtpd_name[0] == '\0' || strisglob(pdp->dtpd_name); 683 1.1 darran 684 1.1 darran dt_probe_t *prp = NULL; 685 1.1 darran const dtrace_pattr_t *pap; 686 1.1 darran dt_provider_t *pvp; 687 1.1 darran dt_ident_t *idp; 688 1.1 darran 689 1.1 darran /* 690 1.1 darran * Attempt to lookup the probe in our existing cache for this provider. 691 1.1 darran * If none is found and an explicit probe ID was specified, discover 692 1.1 darran * that specific probe and cache its description and arguments. 693 1.1 darran */ 694 1.1 darran if ((pvp = dt_provider_lookup(dtp, pdp->dtpd_provider)) != NULL) { 695 1.1 darran size_t keylen = dt_probe_keylen(pdp); 696 1.1 darran char *key = dt_probe_key(pdp, alloca(keylen)); 697 1.1 darran 698 1.1 darran if ((idp = dt_idhash_lookup(pvp->pv_probes, key)) != NULL) 699 1.1 darran prp = idp->di_data; 700 1.1 darran else if (pdp->dtpd_id != DTRACE_IDNONE) 701 1.1 darran prp = dt_probe_discover(pvp, pdp); 702 1.1 darran } 703 1.1 darran 704 1.1 darran /* 705 1.1 darran * If no probe was found in our cache, convert the caller's partial 706 1.1 darran * probe description into a fully-formed matching probe description by 707 1.1 darran * iterating over up to at most two probes that match 'pdp'. We then 708 1.1 darran * call dt_probe_discover() on the resulting probe identifier. 709 1.1 darran */ 710 1.1 darran if (prp == NULL) { 711 1.1 darran dtrace_probedesc_t pd; 712 1.1 darran int m; 713 1.1 darran 714 1.1 darran bzero(&pd, sizeof (pd)); 715 1.1 darran pd.dtpd_id = DTRACE_IDNONE; 716 1.1 darran 717 1.1 darran /* 718 1.1 darran * Call dtrace_probe_iter() to find matching probes. Our 719 1.1 darran * dt_probe_desc() callback will produce the following results: 720 1.1 darran * 721 1.1 darran * m < 0 dtrace_probe_iter() found zero matches (or failed). 722 1.1 darran * m > 0 dtrace_probe_iter() found more than one match. 723 1.1 darran * m = 0 dtrace_probe_iter() found exactly one match. 724 1.1 darran */ 725 1.1 darran if ((m = dtrace_probe_iter(dtp, pdp, dt_probe_desc, &pd)) < 0) 726 1.1 darran return (NULL); /* dt_errno is set for us */ 727 1.1 darran 728 1.1 darran if ((pvp = dt_provider_lookup(dtp, pd.dtpd_provider)) == NULL) 729 1.1 darran return (NULL); /* dt_errno is set for us */ 730 1.1 darran 731 1.1 darran /* 732 1.1 darran * If more than one probe was matched, then do not report probe 733 1.1 darran * information if either of the following conditions is true: 734 1.1 darran * 735 1.1 darran * (a) The Arguments Data stability of the matched provider is 736 1.1 darran * less than Evolving. 737 1.1 darran * 738 1.1 darran * (b) Any description component that is at least Evolving is 739 1.1 darran * empty or is specified using a globbing expression. 740 1.1 darran * 741 1.1 darran * These conditions imply that providers that provide Evolving 742 1.1 darran * or better Arguments Data stability must guarantee that all 743 1.1 darran * probes with identical field names in a field of Evolving or 744 1.1 darran * better Name stability have identical argument signatures. 745 1.1 darran */ 746 1.1 darran if (m > 0) { 747 1.1 darran if (pvp->pv_desc.dtvd_attr.dtpa_args.dtat_data < 748 1.1 darran DTRACE_STABILITY_EVOLVING) { 749 1.1 darran (void) dt_set_errno(dtp, EDT_UNSTABLE); 750 1.1 darran return (NULL); 751 1.1 darran } 752 1.1 darran 753 1.1 darran 754 1.1 darran if (pvp->pv_desc.dtvd_attr.dtpa_mod.dtat_name >= 755 1.1 darran DTRACE_STABILITY_EVOLVING && m_is_glob) { 756 1.1 darran (void) dt_set_errno(dtp, EDT_UNSTABLE); 757 1.1 darran return (NULL); 758 1.1 darran } 759 1.1 darran 760 1.1 darran if (pvp->pv_desc.dtvd_attr.dtpa_func.dtat_name >= 761 1.1 darran DTRACE_STABILITY_EVOLVING && f_is_glob) { 762 1.1 darran (void) dt_set_errno(dtp, EDT_UNSTABLE); 763 1.1 darran return (NULL); 764 1.1 darran } 765 1.1 darran 766 1.1 darran if (pvp->pv_desc.dtvd_attr.dtpa_name.dtat_name >= 767 1.1 darran DTRACE_STABILITY_EVOLVING && n_is_glob) { 768 1.1 darran (void) dt_set_errno(dtp, EDT_UNSTABLE); 769 1.1 darran return (NULL); 770 1.1 darran } 771 1.1 darran } 772 1.1 darran 773 1.1 darran /* 774 1.1 darran * If we matched a probe exported by dtrace(7D), then discover 775 1.1 darran * the real attributes. Otherwise grab the static declaration. 776 1.1 darran */ 777 1.1 darran if (pd.dtpd_id != DTRACE_IDNONE) 778 1.1 darran prp = dt_probe_discover(pvp, &pd); 779 1.1 darran else 780 1.1 darran prp = dt_probe_lookup(pvp, pd.dtpd_name); 781 1.1 darran 782 1.1 darran if (prp == NULL) 783 1.1 darran return (NULL); /* dt_errno is set for us */ 784 1.1 darran } 785 1.1 darran 786 1.1 darran assert(pvp != NULL && prp != NULL); 787 1.1 darran 788 1.1 darran /* 789 1.1 darran * Compute the probe description attributes by taking the minimum of 790 1.1 darran * the attributes of the specified fields. If no provider is specified 791 1.1 darran * or a glob pattern is used for the provider, use Unstable attributes. 792 1.1 darran */ 793 1.1 darran if (pdp->dtpd_provider[0] == '\0' || strisglob(pdp->dtpd_provider)) 794 1.1 darran pap = &_dtrace_prvdesc; 795 1.1 darran else 796 1.1 darran pap = &pvp->pv_desc.dtvd_attr; 797 1.1 darran 798 1.1 darran pip->dtp_attr = pap->dtpa_provider; 799 1.1 darran 800 1.1 darran if (!m_is_glob) 801 1.1 darran pip->dtp_attr = dt_attr_min(pip->dtp_attr, pap->dtpa_mod); 802 1.1 darran if (!f_is_glob) 803 1.1 darran pip->dtp_attr = dt_attr_min(pip->dtp_attr, pap->dtpa_func); 804 1.1 darran if (!n_is_glob) 805 1.1 darran pip->dtp_attr = dt_attr_min(pip->dtp_attr, pap->dtpa_name); 806 1.1 darran 807 1.1 darran pip->dtp_arga = pap->dtpa_args; 808 1.1 darran pip->dtp_argv = prp->pr_argv; 809 1.1 darran pip->dtp_argc = prp->pr_argc; 810 1.1 darran 811 1.1 darran return (prp); 812 1.1 darran } 813 1.1 darran 814 1.1 darran int 815 1.1 darran dtrace_probe_info(dtrace_hdl_t *dtp, 816 1.1 darran const dtrace_probedesc_t *pdp, dtrace_probeinfo_t *pip) 817 1.1 darran { 818 1.1 darran return (dt_probe_info(dtp, pdp, pip) != NULL ? 0 : -1); 819 1.1 darran } 820 1.1 darran 821 1.1 darran /*ARGSUSED*/ 822 1.1 darran static int 823 1.1 darran dt_probe_iter(dt_idhash_t *ihp, dt_ident_t *idp, dt_probe_iter_t *pit) 824 1.1 darran { 825 1.1 darran const dt_probe_t *prp = idp->di_data; 826 1.1 darran 827 1.1 darran if (!dt_gmatch(prp->pr_name, pit->pit_pat)) 828 1.1 darran return (0); /* continue on and examine next probe in hash */ 829 1.1 darran 830 1.1 darran (void) strlcpy(pit->pit_desc.dtpd_name, prp->pr_name, DTRACE_NAMELEN); 831 1.1 darran pit->pit_desc.dtpd_id = idp->di_id; 832 1.1 darran pit->pit_matches++; 833 1.1 darran 834 1.1 darran return (pit->pit_func(pit->pit_hdl, &pit->pit_desc, pit->pit_arg)); 835 1.1 darran } 836 1.1 darran 837 1.1 darran int 838 1.1 darran dtrace_probe_iter(dtrace_hdl_t *dtp, 839 1.1 darran const dtrace_probedesc_t *pdp, dtrace_probe_f *func, void *arg) 840 1.1 darran { 841 1.1 darran const char *provider = pdp ? pdp->dtpd_provider : NULL; 842 1.1 darran dtrace_id_t id = DTRACE_IDNONE; 843 1.1 darran 844 1.1 darran dtrace_probedesc_t pd; 845 1.1 darran dt_probe_iter_t pit; 846 1.1 darran int cmd, rv; 847 1.1 darran 848 1.1 darran bzero(&pit, sizeof (pit)); 849 1.1 darran pit.pit_hdl = dtp; 850 1.1 darran pit.pit_func = func; 851 1.1 darran pit.pit_arg = arg; 852 1.1 darran pit.pit_pat = pdp ? pdp->dtpd_name : NULL; 853 1.1 darran 854 1.1 darran for (pit.pit_pvp = dt_list_next(&dtp->dt_provlist); 855 1.1 darran pit.pit_pvp != NULL; pit.pit_pvp = dt_list_next(pit.pit_pvp)) { 856 1.1 darran 857 1.1 darran if (pit.pit_pvp->pv_flags & DT_PROVIDER_IMPL) 858 1.1 darran continue; /* we'll get these later using dt_ioctl() */ 859 1.1 darran 860 1.1 darran if (!dt_gmatch(pit.pit_pvp->pv_desc.dtvd_name, provider)) 861 1.1 darran continue; 862 1.1 darran 863 1.1 darran (void) strlcpy(pit.pit_desc.dtpd_provider, 864 1.1 darran pit.pit_pvp->pv_desc.dtvd_name, DTRACE_PROVNAMELEN); 865 1.1 darran 866 1.1 darran if ((rv = dt_idhash_iter(pit.pit_pvp->pv_probes, 867 1.1 darran (dt_idhash_f *)dt_probe_iter, &pit)) != 0) 868 1.1 darran return (rv); 869 1.1 darran } 870 1.1 darran 871 1.1 darran if (pdp != NULL) 872 1.1 darran cmd = DTRACEIOC_PROBEMATCH; 873 1.1 darran else 874 1.1 darran cmd = DTRACEIOC_PROBES; 875 1.1 darran 876 1.1 darran for (;;) { 877 1.1 darran if (pdp != NULL) 878 1.1 darran bcopy(pdp, &pd, sizeof (pd)); 879 1.1 darran 880 1.1 darran pd.dtpd_id = id; 881 1.1 darran 882 1.1 darran if (dt_ioctl(dtp, cmd, &pd) != 0) 883 1.1 darran break; 884 1.1 darran else if ((rv = func(dtp, &pd, arg)) != 0) 885 1.1 darran return (rv); 886 1.1 darran 887 1.1 darran pit.pit_matches++; 888 1.1 darran id = pd.dtpd_id + 1; 889 1.1 darran } 890 1.1 darran 891 1.1 darran switch (errno) { 892 1.1 darran case ESRCH: 893 1.1 darran case EBADF: 894 1.1 darran return (pit.pit_matches ? 0 : dt_set_errno(dtp, EDT_NOPROBE)); 895 1.1 darran case EINVAL: 896 1.1 darran return (dt_set_errno(dtp, EDT_BADPGLOB)); 897 1.1 darran default: 898 1.1 darran return (dt_set_errno(dtp, errno)); 899 1.1 darran } 900 1.1 darran } 901